Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The DecryptMessage (Schannel) function decrypts a message. Some packages don't encrypt and decrypt messages but rather perform and check an integrity hash.
Use this function with the Schannel security support provider (SSP) to signal a request from a message sender for a renegotiation (redo) of the connection attributes or for a shutdown of the connection.
Note
You can call EncryptMessage (Schannel) and DecryptMessage (Schannel) at the same time from two different threads in a single security support provider interface (SSPI) context if one thread is encrypting and the other is decrypting. If more than one thread is encrypting, or more than one thread is decrypting, each thread should obtain a unique context.
Syntax
SECURITY_STATUS SEC_Entry DecryptMessage(
_In_ PCtxtHandle phContext,
_Inout_ PSecBufferDesc pMessage,
_In_ ULONG MessageSeqNo,
_Out_ PULONG pfQOP
);
Parameters
phContext [in]
A handle to the security context to use for decrypting the message.
pMessage [in, out]
A pointer to a SecBufferDesc structure. On input, the structure references one or more SecBuffer structures. One of these buffers can be of type SECBUFFER_DATA. That buffer contains the encrypted message. The function decrypts the encrypted message in place, overwriting the original contents of its buffer.
When you use the Schannel SSP with contexts that aren't connection oriented, the structure must contain four SecBuffer structures on input. Exactly one buffer must be of type SECBUFFER_DATA and contain an encrypted message, which the function decrypts in place. The remaining buffers are used for output and must be of type SECBUFFER_EMPTY. For connection-oriented contexts, you must supply a SECBUFFER_DATA type buffer, as noted for nonconnection-oriented contexts. Additionally, you must supply a second SECBUFFER_TOKEN type buffer that contains a security token.
MessageSeqNo [in]
The sequence number expected by the transport application, if any. If the transport application doesn't maintain sequence numbers, set this parameter to zero.
When you use the Schannel SSP, set this parameter to zero. The Schannel SSP doesn't use sequence numbers.
pfQOP [out]
A pointer to a variable of type ULONG that receives package-specific flags that indicate the quality of protection.
When you use the Schannel SSP, don't use this parameter. Set it to NULL.
This parameter can be the following flag.
| Value | Meaning |
|---|---|
| SECQOP_WRAP_NO_ENCRYPT | The message wasn't encrypted, but the function produced a header or trailer. Note: KERB_WRAP_NO_ENCRYPT has the same value and the same meaning. |
Return value
If the function verifies that the message is received in the correct sequence, it returns SEC_E_OK.
If the function fails to decrypt the message, it returns one of the following error codes.
| Return code | Description |
|---|---|
| SEC_E_INVALID_HANDLE | The phContext parameter specifies an invalid context handle. Used with the Schannel SSP. |
| SEC_E_INVALID_TOKEN | The buffers are of the wrong type or no buffer of type SECBUFFER_DATA is found. Used with the Schannel SSP. |
| SEC_E_MESSAGE_ALTERED | The message is altered. Used with the Schannel SSP. |
| SEC_E_OUT_OF_SEQUENCE | The message isn't received in the correct sequence. |
| SEC_I_CONTEXT_EXPIRED | The message sender finishes using the connection and initiates a shutdown. For information about initiating or recognizing a shutdown, see Shutting Down an Schannel Connection. Used with the Schannel SSP. |
| SEC_I_RENEGOTIATE | The remote party requires a new handshake sequence or the application initiates a shutdown. Return to the negotiation loop and call AcceptSecurityContext (Schannel) or InitializeSecurityContext (Schannel), passing the same buffer as modified by DecryptMessage, ensuring that the SecBuffer type is set to SECBUFFER_TOKEN. |
Remarks
Sometimes an application reads data from the remote party, attempts to decrypt it by using DecryptMessage (Schannel), and discovers that DecryptMessage (Schannel) succeeds but the output buffers are empty. This behavior is normal, and applications must be able to handle it.
When you use the Schannel SSP, the DecryptMessage (General) function returns SEC_I_CONTEXT_EXPIRED when the message sender shuts down the connection. For information about initiating or recognizing a shutdown, see Shutting Down an Schannel Connection.
If you're using TLS 1.0, you might need to call this function multiple times, adjusting the input buffer on each call, to decrypt a whole message.
The DecryptMessage (Schannel) function returns SEC_I_RENEGOTIATE when it receives a post-handshake TLS protocol message other than application data. Once DecryptMessage (Schannel) returns SEC_I_RENEGOTIATE, any further EncryptMessage() and DecryptMessage() calls fail with SEC_E_CONTEXT_EXPIRED. An application handles this situation by calling AcceptSecurityContext (Schannel) (server side) or InitializeSecurityContext (Schannel) (client side) and passing the same buffer as modified by DecryptMessage, ensuring that the SecBuffer type is set to SECBUFFER_TOKEN. Note that DecryptMessage doesn't always return an SECBUFFER_EXTRA buffer when SEC_I_RENEGOTIATE is returned. After this initial call returns a value, proceed as though your application is creating a new connection. Then the application can continue calling EncryptMessage() and DecryptMessage(). For more information, see Creating an Schannel Security Context.
Requirements
| Requirement | Value |
|---|---|
| Minimum supported client | Windows XP [desktop apps only] |
| Minimum supported server | Windows Server 2003 [desktop apps only] |
| Header | Sspi.h (include Security.h) |
| Library | Secur32.lib |
| DLL | Secur32.dll |