Merge branch 'master' into tlv-mic tlv-mic
authorLuke Howard <lukeh@padl.com>
Thu, 19 May 2011 14:53:12 +0000 (16:53 +0200)
committerLuke Howard <lukeh@padl.com>
Thu, 19 May 2011 14:53:12 +0000 (16:53 +0200)
1  2 
moonshot/mech_eap/gssapiP_eap.h
moonshot/mech_eap/util_context.c

@@@ -58,6 -58,10 +58,10 @@@ typedef struct gss_any *gss_any_t
  #endif
  #include "gssapi_eap.h"
  
+ #ifndef HAVE_GSS_INQUIRE_ATTRS_FOR_MECH
+ typedef const gss_OID_desc *gss_const_OID;
+ #endif
  /* Kerberos headers */
  #include <krb5.h>
  
@@@ -141,7 -145,6 +145,7 @@@ struct gss_cred_id_struc
  
  #define CTX_FLAG_INITIATOR                  0x00000001
  #define CTX_FLAG_KRB_REAUTH                 0x00000002
 +#define CTX_FLAG_KRB_REAUTH_SUPPORTED       0x00000004
  
  #define CTX_IS_INITIATOR(ctx)               (((ctx)->flags & CTX_FLAG_INITIATOR) != 0)
  
@@@ -204,7 -207,6 +208,7 @@@ struct gss_ctx_id_struc
          #define reauthCtx            ctxU.reauth
  #endif
      } ctxU;
 +    gss_buffer_desc conversation;
  };
  
  #define TOK_FLAG_SENDER_IS_ACCEPTOR         0x01
@@@ -70,7 -70,8 +70,8 @@@ gssEapAllocContext(OM_uint32 *minor
                      GSS_C_INTEG_FLAG    |   /* integrity */
                      GSS_C_CONF_FLAG     |   /* confidentiality */
                      GSS_C_SEQUENCE_FLAG |   /* sequencing */
-                     GSS_C_REPLAY_FLAG;      /* replay detection */
+                     GSS_C_REPLAY_FLAG|      /* replay detection */
+       GSS_C_MUTUAL_FLAG; /*xxx big hack */
  
      *pCtx = ctx;
  
@@@ -130,7 -131,6 +131,7 @@@ gssEapReleaseContext(OM_uint32 *minor
      gssEapReleaseOid(&tmpMinor, &ctx->mechanismUsed);
      sequenceFree(&tmpMinor, &ctx->seqState);
      gssEapReleaseCred(&tmpMinor, &ctx->defaultCred);
 +    gss_release_buffer(&tmpMinor, &ctx->conversation);
  
      GSSEAP_MUTEX_DESTROY(&ctx->mutex);
  
  }
  
  OM_uint32
 -gssEapMakeToken(OM_uint32 *minor,
 -                gss_ctx_id_t ctx,
 -                const gss_buffer_t innerToken,
 -                enum gss_eap_token_type tokenType,
 -                gss_buffer_t outputToken)
 +gssEapContextTime(OM_uint32 *minor,
 +                  gss_ctx_id_t context_handle,
 +                  OM_uint32 *time_rec)
  {
 -    unsigned char *p;
 +    *minor = 0;
  
 -    outputToken->length = tokenSize(ctx->mechanismUsed, innerToken->length);
 -    outputToken->value = GSSEAP_MALLOC(outputToken->length);
 -    if (outputToken->value == NULL) {
 -        *minor = ENOMEM;
 -        return GSS_S_FAILURE;
 -    }
 +    if (context_handle->expiryTime == 0) {
 +        *time_rec = GSS_C_INDEFINITE;
 +    } else {
 +        time_t now, lifetime;
  
 -    p = (unsigned char *)outputToken->value;
 -    makeTokenHeader(ctx->mechanismUsed, innerToken->length, &p, tokenType);
 -    memcpy(p, innerToken->value, innerToken->length);
 +        time(&now);
 +        lifetime = context_handle->expiryTime - now;
 +        if (lifetime <= 0) {
 +            *time_rec = 0;
 +            return GSS_S_CONTEXT_EXPIRED;
 +        }
 +        *time_rec = lifetime;
 +    }
  
 -    *minor = 0;
      return GSS_S_COMPLETE;
  }
  
  OM_uint32
 -gssEapVerifyToken(OM_uint32 *minor,
 -                  gss_ctx_id_t ctx,
 -                  const gss_buffer_t inputToken,
 -                  enum gss_eap_token_type *actualToken,
 -                  gss_buffer_t innerInputToken)
 +gssEapGetConversationMIC(OM_uint32 *minor,
 +                         gss_ctx_id_t ctx,
 +                         gss_buffer_t convMIC)
  {
      OM_uint32 major;
 -    size_t bodySize;
 -    unsigned char *p = (unsigned char *)inputToken->value;
 -    gss_OID_desc oidBuf;
 -    gss_OID oid;
 +    gss_iov_buffer_desc iov[2];
  
 -    if (ctx->mechanismUsed != GSS_C_NO_OID) {
 -        oid = ctx->mechanismUsed;
 -    } else {
 -        oidBuf.elements = NULL;
 -        oidBuf.length = 0;
 -        oid = &oidBuf;
 -    }
 +    iov[0].type = GSS_IOV_BUFFER_TYPE_DATA;
 +    iov[0].buffer = ctx->conversation;
  
 -    major = verifyTokenHeader(minor, oid, &bodySize, &p,
 -                              inputToken->length, actualToken);
 +    iov[1].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE;
 +    iov[1].buffer.length = 0;
 +    iov[1].buffer.value = NULL;
 +
 +    major = gssEapWrapOrGetMIC(minor, ctx, FALSE, NULL, iov, 2, TOK_TYPE_MIC);
      if (GSS_ERROR(major))
          return major;
  
 -    if (ctx->mechanismUsed == GSS_C_NO_OID) {
 -        major = gssEapCanonicalizeOid(minor, oid, 0, &ctx->mechanismUsed);
 -        if (GSS_ERROR(major))
 -            return major;
 -    }
 -
 -    innerInputToken->length = bodySize;
 -    innerInputToken->value = p;
 +    *convMIC = iov[1].buffer;
  
      *minor = 0;
      return GSS_S_COMPLETE;
  }
  
  OM_uint32
 -gssEapContextTime(OM_uint32 *minor,
 -                  gss_ctx_id_t context_handle,
 -                  OM_uint32 *time_rec)
 +gssEapVerifyConversationMIC(OM_uint32 *minor,
 +                            gss_ctx_id_t ctx,
 +                            const gss_buffer_t convMIC)
  {
 -    *minor = 0;
 +    OM_uint32 major;
 +    gss_iov_buffer_desc iov[3];
 +    int confState;
 +    size_t tokenHeaderLength;
  
 -    if (context_handle->expiryTime == 0) {
 -        *time_rec = GSS_C_INDEFINITE;
 -    } else {
 -        time_t now, lifetime;
 +    if (convMIC == GSS_C_NO_BUFFER || convMIC->length < 16) {
 +        *minor = GSSEAP_TOK_TRUNC;
 +        return GSS_S_BAD_SIG;
 +    }
  
 -        time(&now);
 -        lifetime = context_handle->expiryTime - now;
 -        if (lifetime <= 0) {
 -            *time_rec = 0;
 -            return GSS_S_CONTEXT_EXPIRED;
 -        }
 -        *time_rec = lifetime;
 +    iov[0].type = GSS_IOV_BUFFER_TYPE_DATA;
 +    iov[0].buffer = ctx->conversation;
 +
 +    /*
 +     * The conversation state already includes the MIC and its
 +     * TLV header, as well as a header for emiting a subsequent
 +     * token. These should not be included as input to verifyMIC.
 +     */
 +    tokenHeaderLength = ITOK_HEADER_LENGTH + convMIC->length
 +        + 2 + ctx->mechanismUsed->length + 2;
 +    assert(ctx->conversation.length >= tokenHeaderLength);
 +    iov[0].buffer.length -= tokenHeaderLength;
 +
 +    iov[1].type = GSS_IOV_BUFFER_TYPE_HEADER;
 +    iov[1].buffer.length = 16;
 +    iov[1].buffer.value = convMIC->value;
 +
 +    iov[2].type = GSS_IOV_BUFFER_TYPE_TRAILER;
 +    iov[2].buffer.length = convMIC->length - 16;
 +    iov[2].buffer.value = (unsigned char *)convMIC->value + 16;
 +
 +    major = gssEapUnwrapOrVerifyMIC(minor, ctx, &confState, NULL,
 +                                    iov, 3, TOK_TYPE_MIC);
 +
 +
 +    return major;
 +}
 +
 +OM_uint32
 +gssEapMakeTokenChannelBindings(OM_uint32 *minor,
 +                               gss_ctx_id_t ctx,
 +                               gss_channel_bindings_t userChanBindings,
 +                               gss_buffer_t inputToken,
 +                               gss_channel_bindings_t wireChanBindings)
 +{
 +    gss_buffer_t wireData = &wireChanBindings->application_data;
 +    unsigned char *p;
 +    size_t tokenHeaderLength = 0;
 +
 +    memset(wireChanBindings, 0, sizeof(*wireChanBindings));
 +
 +    if (!CTX_IS_INITIATOR(ctx)) {
 +        assert(inputToken != GSS_C_NO_BUFFER);
 +
 +        tokenHeaderLength = ITOK_HEADER_LENGTH + inputToken->length +
 +            2 + ctx->mechanismUsed->length + 2;
 +        assert(ctx->conversation.length >= tokenHeaderLength);
      }
  
 +    wireData->length = ctx->conversation.length - tokenHeaderLength;
 +
 +    if (userChanBindings != GSS_C_NO_CHANNEL_BINDINGS)
 +        wireData->length += userChanBindings->application_data.length;
 +
 +    wireData->value = GSSEAP_MALLOC(wireData->length);
 +    if (wireData->value == NULL) {
 +        *minor = ENOMEM;
 +        return GSS_S_FAILURE;
 +    }
 +
 +    p = (unsigned char *)wireData->value;
 +
 +    memcpy(p, ctx->conversation.value, ctx->conversation.length - tokenHeaderLength);
 +    p += ctx->conversation.length - tokenHeaderLength;
 +
 +    if (userChanBindings != GSS_C_NO_CHANNEL_BINDINGS) {
 +        memcpy(p, userChanBindings->application_data.value,
 +               userChanBindings->application_data.length);
 +        p += userChanBindings->application_data.length;
 +    }
 +
 +    *minor = 0;
      return GSS_S_COMPLETE;
  }