Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
1.  The GSS-API: An Overview Programming Using the GSS-API Data Protection  Previous   Contents   Next 
   
 

Message Tagging With gss_get_mic()

Programs can use gss_get_mic() to add a cryptographic MIC to a message; the recipient can check this MIC to see if the received message is the same as the one that was sent by calling gss_verify_mic(). gss_get_mic() has the following form:

OM_uint32 gss_get_mic (
OM_uint32          *minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t          qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t       msg_token)
minor_status

The status code returned by the underlying mechanism.

context_handle

The context under which the message will be sent.

qop_req

A requested QOP (Quality of Protection). This is the cryptographic algorithm used in generating the MIC. For portability's sake, applications should specify the default QOP by setting this argument to GSS_C_QOP_DEFAULT whenever possible. (See Appendix C, Specifying an OID on specifying a non-default QOP.)

message_buffer

The message to be tagged with a MIC. 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.

msg_token

The token containing the message and its MIC. This must be freed up with gss_release_buffer() when you have finished with it.

Note that gss_get_mic() produces separate output for the message and the MIC. (This is different from gss_wrap(), which bundles them together as output.) This separation means that a sender application must arrange to send both the message and its MIC. More significantly, the receiving application must be able to receive and distinguish the message and the MIC. Ways to ensure the proper processing of message and MIC include:

  • Through program control (that is, state). A recipient application might know to call its receiving function twice, once to get a message, once to get the message's MIC.

  • Through flags. Sending and receiving functions can flag what kind of token they're including.

  • Through user-defined token structures that might include both message and MIC.

gss_get_mic() returns GSS_S_COMPLETE if it completes successfully. If the specified QOP is not valid, it returns GSS_S_BAD_QOP. For more information, see the gss_get_mic(3GSS) man page.

Message Wrapping With gss_wrap()

Messages can also be "wrapped" by the gss_wrap() function. Like gss_get_mic(), gss_wrap() provides a MIC; it also encrypts a given message, if confidentiality is requested (and permitted by the underlying mechanism). The message receiver "unwraps" the message with gss_unwrap(). gss_wrap() looks like this:

OM_uint32 gss_wrap (
OM_uint32          *minor_status,
const gss_ctx_id_t context_handle,
int                conf_req_flag,
gss_qop_t          qop_req
const gss_buffer_t input_message_buffer,
int                *conf_state,
gss_buffer_t       output_message_buffer )
minor_status

The status code returned by the underlying security mechanism.

context_handle

The context under which this message will be sent.

conf_req_flag

A flag for requesting the confidentiality service (encryption). If non-zero, both confidentiality and integrity are requested; if zero, only the integrity service is requested.

qop_req

A requested QOP (Quality of Protection). This is the cryptographic algorithm used in generating the MIC and doing the encryption. For portability's sake, applications should specify the default QOP by setting this argument to GSS_C_QOP_DEFAULT whenever possible. (See Appendix C, Specifying an OID on specifying a non-default QOP.)

input_message_buffer

The message to be wrapped. 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.

conf_state

A flag that, on the function's return, indicates whether confidentiality was applied or not. If non-zero, confidentiality, message origin authentication, and integrity services were applied. If zero, only message-origin authentication and integrity were applied. Specify NULL if not required.

output_message_buffer

The buffer for the wrapped message. After the application is done with the message, it must release this buffer with gss_release_buffer().

Unlike gss_get_mic(), gss_wrap() wraps the message and its MIC together in the outgoing message, so the function that transmits them need be called only once. On the other end, gss_unwrap() will extract the message (the MIC is not visible to the application).

gss_wrap() returns GSS_S_COMPLETE if the message was successfully wrapped. If the requested QOP was not valid, it returns GSS_S_BAD_QOP. "Sending the Data" (listing in "call_server()") shows an example of gss_wrap() being used. For more information, see the gss_wrap(3GSS) man page.

Wrap Size

Wrapping a message with gss_wrap() increases its size. Because the protected message packet must not be too big to "fit through" a given transportation protocol, the GSS-API provides a function, gss_wrap_size_limit(), that calculates the maximum size of a message that can be wrapped without becoming too large. The application can break up messages that exceed this size before calling gss_wrap(). It's a good idea to check the wrap-size limit before actually wrapping the message.

The amount of the size increase depends on two things:

  • Which QOP (Quality of Protection) algorithm is used for making the transformation. Since the default QOP can vary from one implementation of the GSS-API to another, a wrapped message can vary in size even if you do not specify a non-default QOP. This is shown in the following figure.

    Figure 1-12 Wrap Size (Different QOPs)

  • Whether confidentiality is invoked. Whether or not confidentiality is applied, gss_wrap() still increases the size of a message, because it embeds a MIC into the transmitted message. However, encrypting the message can further increase the size. The following figure shows how this works.

    Figure 1-13 Wrap Size (Confidentiality/No Confidentiality)

gss_wrap_size_limit() looks like this:

OM_uint32 gss_wrap_size_limit (
OM_uint32          *minor_status,
const gss_ctx_id_t context_handle,
int                conf_req_flag,
gss_qop_t          qop_req,
OM_uint32          req_output_size,
OM_uint32          *max_input_size)
minor_status

The status code returned by the underlying mechanism.

context_handle

The context under which the data is transmitted.

conf_req_flag

A flag for requesting the confidentiality service (encryption). If non-zero, both confidentiality and integrity are requested; if zero, only the integrity service is requested.

qop_req

A requested QOP (Quality of Protection). This is the cryptographic algorithm used in generating the MIC and doing the encryption. For portability's sake, applications should specify the default QOP by setting this argument to GSS_C_QOP_DEFAULT whenever possible. (See Appendix C, Specifying an OID on specifying a non-default QOP.)

req_output_size

The maximum size (as an int) of a data chunk that a given transport protocol can handle. You must provide this information yourself; since the GSS-API is protocol-independent, it has no way of knowing which protocol is being used.

max_input_size

Returned by the function, this is the maximum size of an unwrapped message that, when wrapped, will not exceed req_output_size.

gss_wrap_size_limit() returns GSS_S_COMPLETE if it completes successfully. If the specified QOP was not valid, it returns GSS_S_BAD_QOP. "call_server()" includes an example of gss_wrap_size_limit() being used to return the maximum original message size, both if confidentiality is used and if it is not used.

Successful completion of this call does not necessarily guarantee that gss_wrap() will be able to protect a message of length max_input_size bytes, since this ability can depend on the availability of system resources at the time that gss_wrap() is called. For more information, see the gss_wrap_size_limit(3GSS) man page.

Unwrapping and Verification

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.

gss_unwrap()

gss_unwrap() looks like this:
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)

 
 
 
  Previous   Contents   Next