Code Analysis of the ChannelManager Class (CNG Example)
In the Cryptography Next Generation (CNG) secure communication example, the ChannelManager class provides the interprocess communication (IPC) infrastructure for the example.
The class is responsible for the following:
Creating, opening, closing, and disposing of named pipes.
Sending and receiving application control flags, channel names, digital signatures, cryptographic keys, and messages.
See Cryptography Next Generation (CNG) Secure Communication Example for an overview of the example and descriptions of the versions mentioned in this topic.
ChannelManager.cs File Contents
The ChannelManager.cs file contains the following classes and methods:
ChannelManager class:
Constructor: Creates a named pipe, and then waits for a connection at the other end of the pipe. If the named pipe is a pipe server, it waits for a client connection by calling the WaitForConnection method. If the named pipe is a pipe client, it waits for a named pipe server by calling the Connect method. The ChannelManager constructor does not return until a connection is made.
Dispose method: Implements the System.IDisposable interface by releasing its instantiated resources (Stream m_Stream) when the class goes out of scope.
ReadMessage method: Receives messages from pipe clients.
SendMessage method: Sends messages to pipe clients.
AppControl method: Used by Alice to send application control flags to Bob and Mallory. These flags synchronize the Version, fMallory and fVerbose states among the three command windows. AppControl is not involved with encryption or message transmission. It is purely an interapplication control mechanism. This method creates a temporary ChannelManager object that is disposed of after it is used.
SendChannelName method: Convenience method that handles sending a new channel name to a client. This method creates a temporary ChannelManager object that is disposed of after it is used.
ReceiveChannelName method: Convenience method that handles receiving a new channel name from a server. This method creates a temporary ChannelManager object that is disposed of after it is used.
ChannelManager Class Details
The Alice, Bob, and Mallory applications are connected by named pipes that are created by ChannelManager instances. Each application creates and disposes of two types of ChannelManager objects:
Long-term objects: Alice and Bob both create a long-term ChannelManager object at the start of their Run methods. They use this object to transmit sales contacts. Mallory creates two long-term ChannelManager objects in his Run method: one to communicate with Alice, and one to communicate with Bob. The channels are used to exchange cryptographic keys and encrypted messages. They persist until the end of the Run method, and are then disposed of.
Temporary objects: The AppControl, SendChannelName, and ReceiveChannelName methods create temporary ChannelManager objects to perform a specific task. The objects are then disposed of. Also, in versions 4 and 5, Alice sends Bob a private digital signature key by using a temporary ChannelManager object.
The ChannelManager class implements the System.IDisposable interface and manages both send and receive transmission modes.
The class provides the illusion of a dynamic exchange between Alice, Bob, and Mallory. In reality, a pipe can exist only in one mode at a time: It can be either a server or a client. Therefore, the Alice, Bob, and Mallory applications execute in a careful, linear manner. Each application expects pipes to open and close at specific times during the execution of the example. Communication is not asynchronous, although it may appear to be.
It may appear that a thread manager is managing threads in the background; however, no threading calls are employed. Interprocess timing is achieved only through the careful interleaving of send and receive calls between Alice, Bob, and Mallory. As a result, the three windows appear to communicate effortlessly, following the scenario discussed in the the CNG example overview.
One benefit of this implementation is synchronization, and the code is simple and linear. One drawback is a lack of robustness: If a pipe client fails to connect to the server, the server will stop responding. A better approach would be to use a multithreaded pipe server, which would handle such failures gracefully. However, to avoid complexity, the example does not take that approach.
The ChannelManager class is instantiated from the Alice, Bob, and Mallory Main methods and the Communicator class constructor in the Communicator.cs file.
Usage Details
The ChannelManager class is used in five different contexts: application control, channel name transmission, message transmission, digital signature key transmission, and public encryption key transmission. In the following list, these are discussed in the order in which they appear in the source code.
Application control: Alice calls the InitializeOptions method at the beginning of her Main method and receives session options from the user. These options (Version, fMallory, and fVerbose) are then sent to Bob and Mallory by the AppControl method. If the user decides to close the application by typing the letter "x", the AppControl method sends the string "exit" instead of the session options to Bob and Mallory.
Alice's AppControl method creates two temporary ChannelManager pipe servers, BobControlChannel and MalloryControlChannel.
Bob and Mallory's AppControl methods create temporary ChannelManager pipe clients and connect to their respective control channels.
Bob and Mallory receive the session options from Alice and immediately dispose of the temporary ChannelManager objects.
Channel name transmission: After the session options have been transmitted, Alice sends Bob a new channel name.
Alice uses the SendChannelName method, and Bob and Mallory use the ReceiveChannelName method. Each method creates a temporary ChannelManager pipe server or client. After the new channel name has been sent or received, the temporary ChannelManager instance is disposed of.
The security flaw occurs when Mallory intercepts the new channel name by calling ReceiveChannelName 200 milliseconds before Bob does. For a discussion of this security flaw, see Implementing a Man-in-the-Middle Attack (CNG Example).
Message transmission: After the session options and new channel name have been transmitted, Alice, Bob, and Mallory create Communicator objects. The Communicator constructors receive the name of the new channel sent in the previous step, and use it to create long-term ChannelManager instances. These objects are the only non-temporary ChannelManager instances. They persist until the last message is transmitted and received, and are then disposed of.
Not
The ChannelManager object that is created by Alice encapsulates a pipe server named AliceAndBobChannel. However, Mallory intercepts that name and sends a different channel name (AliceAndBobChannel1) to Bob. Bob passed this string as the name parameter to his Communicator constructor, creating a pipe client named AliceAndBobChannel1. This name change enables Mallory to impersonate Alice in his messages to Bob.
Digital signature key transmission: After Alice has created her Communicator object, the Version flag is examined. In version 3, she sends Bob a digital signature key through the PublicChannel named pipe, where it is intercepted by Mallory. In versions 4and 5, she creates a temporary, secret ChannelManager instance. This instance is then used to transmit a private digital signature key to Bob.
Not
Mallory does not know about this private named pipe because he is not given version 4 or 5 of the instant messaging (IM) software. Alice continues to use the long-term messaging ChannelManager object created in step 3 to send a fake digital signature to Bob. In versions 4 and 5, Bob's IM tool has been updated to ignore this object. However, Mallory thinks the signature is valid, and uses it to sign both his cryptographic keys and his messages. This proves to be his downfall.
Public encryption key transmission: The Version flag is examined again. In version 2 and later, the long-term messaging ChannelManager object created in step 3 is used to send and receive public encryption keys.
After the channel names, digital signatures, and cryptographic keys have been exchanged, Alice and Bob use the ChannelManager created in step 3 to transmit messages.
See Also
Reference
Concepts
Cryptography Next Generation (CNG) Secure Communication Example