Per-message Services

Having established a security context, the two communicating peers can now exchange secure messages over the established context. Either of the two parties can be the originator of a secure message irrespective of their role (initiator or acceptor) in the context establishment process. A message is made secure by computing a cryptographic message integrity code (MIC) over the message. The message can also be encrypted for privacy.

JGSS provides two sets of methods, the wrap and the getMIC methods, for securing messages. A wrap method computes a MIC and optionally encrypts the message. It returns a token that contains both the MIC and ciphertext (if the message was encrypted) or the original plain text (if the message was not encrypted). The caller specifies , using the MessageProp input whether or not the message is to be encrypted. A getMIC method, on the other hand, only computes a MIC over the message. The token it returns is made up entirely of the computed MIC and does not include the original message. Therefore, in addition to transporting the MIC token to the peer, the peer must somehow be made aware of the original message so that it can verify the MIC.

Here is how foo might wrap a message for delivery to superSecureServer:
byte array[] message = "Ready to roll!".getBytes();

MessageProp mprop = new MessageProp(true); // foo wants the message encrypted, too

byte array[] wrappedMessage = fooContext.wrap(message, 0, message.length, mprop);

send(wrappedMessage); // transfer the wrapped message to superSecureServer
Here is how superSecureServer might obtain a MIC for delivery to foo:
byte array[] message = "You bet!".getBytes();

MessageProp mprop = null; // superSecureServer is content with the default quality of protection

byte array[] mic = serverAcceptorContext.getMIC(message, 0, message.length, mprop);

send(mic); // send the MIC to foo. foo will also require the original message to verify the MIC

The receiver of a wrapped message uses the unwrap method to decode the message. The method verifies the cryptographic MIC embedded in the message and returns the original message over which the MIC was computed by the sender. If the message was encrypted, the unwrap method decrypts the message before verifying the MIC and returning the original plain text message. The receiver of a MIC token uses the verifyMIC method to verify the MIC over a given a message.

The peer applications use their own protocol to deliver JGSS context and message tokens to each other. They should also define a protocol for determining the type of a given message token, that is, whether the token is a MIC or a wrapped message. For example, part of such a protocol may be as simple (and rigid) as that used by Simple Authentication And Security Layer (SASL) GSSAPI applications in which the context acceptor is always the first to send a per-message (wrapped) token following context establishment.

superSecureServer unwraps the wrapped token received from foo:
MessageProp mprop = new MessageProp(false); 

byte array[] plaintextFromFoo = serverAcceptorContext.unwrap(wrappedTokenFromFoo, 0, wrappedTokenFromFoo.length, mprop);

// superSecureServer can now examine mprop to determine the message properties (such as whether the message was encrypted) applied by foo.
foo verifies the MIC received from superSecureServer thus:
MessageProp mprop = new MessageProp(false); 

fooContext.verifyMIC(micFromFoo, 0, micFromFoo.length, messageFromFoo, 0, messageFromFoo.length, mprop);

// foo can now examine mprop to determine the message properties applied by superSecureServer. In particular, it can assert that the message was not encrypted because getMIC should never encrypt a message.