Encrypting a Message
The following example shows a message being encrypted before it is sent to a remote computer over the secure connection.
The example assumes that a SecHandle variable named phContext
and a SOCKET named s
are initialized. For the declarations and initiations of these variables, see Using SSPI with a Windows Sockets Client and Using SSPI with a Windows Sockets Server. This example includes calls to functions in Secur32.lib, which must be included among the link libraries.
//--------------------------------------------------------------------
// Declare and initialize local variables.
SecPkgContext_StreamSizes Sizes;
SECURITY_STATUS scRet;
SecBufferDesc Message;
SecBuffer Buffers[4];
SecBuffer *pDataBuffer;
PBYTE pbIoBuffer;
DWORD cbIoBuffer;
DWORD cbIoBufferLength;
PBYTE pbMessage;
DWORD cbMessage;
//--------------------------------------------------------------------
// Get the stream encryption sizes. This needs to
// be done once per connection.
// phContext must have been initialized during the handshake process.
scRet = QueryContextAttributes(
phContext,
SECPKG_ATTR_STREAM_SIZES,
&Sizes);
if(FAILED(scRet))
{
MyHandleError("Error reading SECPKG_ATTR_STREAM_SIZES");
}
//--------------------------------------------------------------------
// Allocate a working buffer. The plaintext sent to EncryptMessage
// can never be more than 'Sizes.cbMaximumMessage', so a buffer
// size of Sizes.cbMaximumMessage plus the header and trailer sizes
// is sufficient for the longest message.
cbIoBufferLength = Sizes.cbHeader +
Sizes.cbMaximumMessage +
Sizes.cbTrailer;
if(!(pbIoBuffer = malloc((BYTE *), cbIoBufferLength)))
{
MyHandleError("Out of memory");
}
//--------------------------------------------------------------------
// Create a plaintext message to be encrypted offset into the data
// buffer by "header size" bytes. This allows encryption in place.
pbMessage = pbIoBuffer + Sizes.cbHeader;
StringCbPrintfA(pbMessage,
cbIoBufferLength - Sizes.cbHeader,
"This is the plaintext message.");
cbMessage = strlen(pbMessage);
//--------------------------------------------------------------------
// Encrypt the plaintext message.
Buffers[0].pvBuffer = pbIoBuffer;
Buffers[0].cbBuffer = Sizes.cbHeader;
Buffers[0].BufferType = SECBUFFER_STREAM_HEADER;
Buffers[1].pvBuffer = pbMessage;
Buffers[1].cbBuffer = cbMessage;
Buffers[1].BufferType = SECBUFFER_DATA;
Buffers[2].pvBuffer = pbMessage + cbMessage;
Buffers[2].cbBuffer = Sizes.cbTrailer;
Buffers[2].BufferType = SECBUFFER_STREAM_TRAILER;
Buffers[3].BufferType = SECBUFFER_EMPTY;
Message.ulVersion = SECBUFFER_VERSION;
Message.cBuffers = 4;
Message.pBuffers = Buffers;
scRet = EncryptMessage(phContext, 0, &Message, 0);
if(FAILED(scRet))
{
MyHandleError("Error returned by EncryptMessage.");
}
//--------------------------------------------------------------------
// Send the encrypted data.
if(!(SendMsg(
s,
pbIoBuffer,
Buffers[0].cbBuffer + Buffers[1].cbBuffer +
Buffers[2].cbBuffer)))
{
MyHandleError("SendMsg failed.");
}