Context Establishment

The two communicating peers must establish a security context over which they can use per-message services. The initiator calls initSecContext on its context, which returns a token to the application. The initiator's application transports the context token to the acceptor's application. The acceptor's application calls acceptSecContext on the acceptor's context, specifying the context token received from the initiator. Depending on the underlying mechanism and the optional services selected by the initiator, the acceptSecContext can produce a token which the acceptor's application has to forward to the initiator's application; the initiator's application then calls initSecContext one more time with the received token.

Indeed, multiple calls can be made to both initSecContext and acceptSecContext and multiple tokens exchanged between the two peers during context establishment. Therefore, context establishment is typically accomplished in a programming construct in which initSecContext or acceptSecContext is called in a loop until the context is established.

Being the initiator, foo's side of the context establishment can be coded as:
byte array[] inToken = null; // The input token is null for the first call

int inTokenLen = 0;

do {

  byte array[] outToken = fooContext.initSecContext(inToken, 0, inTokenLen);

  if (outToken != null) send(outToken); // transport token to acceptor

  inToken = receive(); // receive token from acceptor

  inTokenLen = inToken.length;

} while (!fooContext.isEstablished());
The acceptor code for establishing context can be coded:
do {

  byte array[] inToken = receive(); // receive token from initiator

  byte array[] outToken = serverAcceptorContext.acceptSecContext(inToken, 0, inToken.length);

  if (outToken != null) send(outToken); // transport token to initiator

} while (!isEstablished());