Once it has been received, a wrapped message must be unwrapped with gss_unwrap(). gss_unwrap() automatically verifies the message against the MIC that is embedded with the wrapped message. If the sender did not wrap the message but used gss_get_mic() to produce a MIC, then the received message can be verified against that MIC with gss_verify_mic(). In this latter case the acceptor must arrange to receive both the message and its MIC.
OM_uint32 gss_unwrap ( OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int *conf_state gss_qop_t *qop_state)
The status code returned by the underlying security mechanism.
The context under which this message will be sent.
The wrapped message. This argument must be in the form of a gss_buffer_desc object; see Strings and Similar Data. Must be freed up with gss_release_buffer() when you have finished with it.
The buffer for the unwrapped wrapped message. After the application is done with the unwrapped message, it must release this buffer with gss_release_buffer(). This argument is also a gss_buffer_desc object.
A flag that indicates whether confidentiality was applied or not. If non-zero, then confidentiality, message origin authentication, and integrity services were applied. If zero, only message-origin authentication and integrity were applied. Specify NULL if not required.
The QOP (Quality of Protection) used. This is the cryptographic algorithm used in generating the MIC and doing the encryption. Specify NULL if not required.
gss_unwrap() returns GSS_S_COMPLETE if the message was successfully unwrapped. If it cannot verify the message against its MIC, it returns GSS_S_BAD_SIG.
If a message has been unwrapped, or if it was never wrapped in the first place, it can be verified with gss_verify_mic(). gss_verify_mic() looks like this:
OM_uint32 gss_verify_mic ( OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t qop_state)
The status code returned by the underlying mechanism.
The context under which the message will be sent.
The received message. This argument must be in the form of a gss_buffer_desc object; see Strings and Similar Data. Must be freed up with gss_release_buffer() when you have finished with it.
The token containing the received MIC. This argument must be in the form of a gss_buffer_desc object; see Strings and Similar Data. This buffer must be freed up with gss_release_buffer() when the application has finished with it.
The QOP (Quality of Protection) that was applied in generating the MIC. Specify NULL if not required.
gss_verify_mic() returns GSS_S_COMPLETE if the message was successfully verified. If it cannot verify the message against its MIC, it returns GSS_S_BAD_SIG.
After the recipient has unwrapped or verified the transmitted message, it might want to send a confirmation to the sender. This means sending back a MIC for that message. Consider the case of a message that was not wrapped by the sender, but only tagged with a MIC with gss_get_mic(). The process, illustrated in Figure 1–14, is as follows:
The initiator tags the message with gss_get_mic().
The initiator sends the message and MIC to the acceptor.
The acceptor verifies the message with gss_verify_mic().
The acceptor sends the MIC back to the initiator.
The initiator verifies the received MIC against the original message with gss_verify_mic().
In the case of wrapped data, the gss_unwrap() function never produces a separate MIC, so the recipient must generate it from the received (and unwrapped) message. The process, illustrated in Figure 1–15, is as follows:
The initiator wraps the message with gss_wrap().
The initiator sends the wrapped message.
The acceptor unwraps the message with gss_unwrap().
The acceptor calls gss_get_mic() to produce a MIC for the unwrapped message.
The acceptor sends the derived MIC to the initiator.
The initiator compares the received MIC against the original message with gss_verify_mic().