Platform SDK: Logon Authentication |
The following example code shows an encrypted message being received and decrypted.
The example assumes that a SecHandle variable named phContext and a SOCKET structure 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 code also uses the function ReceiveMsg and HandleError. Code for these functions can be seen in Utility Functions for Windows Sockets Client and Server.
SSPI functions are shown as available through the global SecurityFunctionTable structure g_SecurityFunc.
SecPkgContext_StreamSizes Sizes; SECURITY_STATUS scRet; SecBufferDesc Message; SecBuffer Buffers[4]; SecBuffer *pDataBuffer; SecBuffer *pExtraBuffer; SecBuffer ExtraBuffer; PBYTE pbIoBuffer; DWORD cbIoBuffer; DWORD cbIoBufferLength; //-------------------------------------------------------------------- // Get stream encryption properties. scRet = g_SecurityFunc.QueryContextAttributes( phContext, SECPKG_ATTR_STREAM_SIZES, &Sizes); if(scRet != SEC_E_OK) { HandleError("Error reading SECPKG_ATTR_STREAM_SIZES\n"); } //-------------------------------------------------------------------- // Allocate a working buffer. The plaintext sent to EncryptMessage // should never be more than 'Sizes.cbMaximumMessage', so a buffer // size of this plus the header and trailer sizes should be safe. cbIoBufferLength = Sizes.cbHeader + Sizes.cbMaximumMessage + Sizes.cbTrailer; pbIoBuffer = LocalAlloc(LMEM_FIXED, cbIoBufferLength); if(pbIoBuffer == NULL) { HandleError("Error: Out of memory"); } //-------------------------------------------------------------------- // Attempt to decrypt the data in the i/o buffer. Buffers[0].pvBuffer = pbIoBuffer; Buffers[0].cbBuffer = cbIoBuffer; Buffers[0].BufferType = SECBUFFER_DATA; Buffers[1].BufferType = SECBUFFER_EMPTY; Buffers[2].BufferType = SECBUFFER_EMPTY; Buffers[3].BufferType = SECBUFFER_EMPTY; Message.ulVersion = SECBUFFER_VERSION; Message.cBuffers = 4; Message.pBuffers = Buffers; scRet = g_SecurityFunc.DecryptMessage( phContext, &Message, 0, NULL); if(scRet == SEC_E_INCOMPLETE_MESSAGE) { //-------------------------------------------------------------------- // The input buffer contains only a fragment of an // encrypted record. Read some more data from the server // and then try the decryption again. continue; } if(scRet != SEC_E_OK && scRet != SEC_I_RENEGOTIATE) { HandleError("Error returned by DecryptMessage"); } //-------------------------------------------------------------------- // Locate data. pDataBuffer = NULL; pExtraBuffer = NULL; while(!pDataBuffer && i < 4) { if(Buffers[i].BufferType == SECBUFFER_DATA) { pDataBuffer = &Buffers[i]; } i++; } if(pDataBuffer) { //-------------------------------------------------------------------- // Display or otherwise process the decrypted data. // ... }