cache the checksumtype and use MIT private API
authorLuke Howard <lukeh@padl.com>
Fri, 10 Sep 2010 21:18:21 +0000 (23:18 +0200)
committerLuke Howard <lukeh@padl.com>
Fri, 10 Sep 2010 21:18:21 +0000 (23:18 +0200)
mech_eap/accept_sec_context.c
mech_eap/export_sec_context.c
mech_eap/gssapiP_eap.h
mech_eap/import_sec_context.c
mech_eap/init_sec_context.c
mech_eap/unwrap_iov.c
mech_eap/util.h
mech_eap/util_krb.c
mech_eap/util_oid.c
mech_eap/wrap_iov.c

index 6208341..9de9821 100644 (file)
@@ -219,9 +219,6 @@ static OM_uint32
 acceptReady(OM_uint32 *minor, gss_ctx_id_t ctx)
 {
     OM_uint32 major;
-    krb5_context krbContext;
-
-    GSSEAP_KRB_INIT(&krbContext);
 
     /* Cache encryption type derived from selected mechanism OID */
     major = gssEapOidToEnctype(minor, ctx->mechanismUsed, &ctx->encryptionType);
@@ -230,7 +227,12 @@ acceptReady(OM_uint32 *minor, gss_ctx_id_t ctx)
 
     if (ctx->encryptionType != ENCTYPE_NULL &&
         ctx->acceptorCtx.eapPolInterface->eapKeyAvailable) {
-        major = gssEapDeriveRFC3961Key(minor,
+        major = rfc3961EncTypeToChecksumType(minor, ctx->encryptionType,
+                                             &ctx->checksumType);
+        if (GSS_ERROR(major))
+            return major;
+
+        major = gssEapDeriveRfc3961Key(minor,
                                        ctx->acceptorCtx.eapPolInterface->eapKeyData,
                                        ctx->acceptorCtx.eapPolInterface->eapKeyDataLen,
                                        ctx->encryptionType,
index 7f57fc9..cf3ffb0 100644 (file)
@@ -96,7 +96,7 @@ gssEapExportSecContext(OM_uint32 *minor,
 
     length  = 16;                               /* version, state, flags, etc */
     length += 4 + ctx->mechanismUsed->length;   /* mechanismUsed */
-    length += 8 + key.length;                   /* rfc3961Key.value */
+    length += 12 + key.length;                  /* rfc3961Key.value */
     length += 4 + initiatorName.length;         /* initiatorName.value */
     length += 4 + acceptorName.length;          /* acceptorName.value */
     length += 24 + sequenceSize(ctx->seqState); /* seqState */
@@ -120,8 +120,9 @@ gssEapExportSecContext(OM_uint32 *minor,
     store_uint32_be(ctx->gssFlags,         &p[12]);
     p = store_oid(ctx->mechanismUsed,      &p[16]);
 
-    store_uint32_be(ctx->encryptionType,   &p[0]);
-    p = store_buffer(&key,                 &p[4], FALSE);
+    store_uint32_be(ctx->checksumType,     &p[0]);
+    store_uint32_be(ctx->encryptionType,   &p[4]);
+    p = store_buffer(&key,                 &p[8], FALSE);
 
     p = store_buffer(&initiatorName,       p, FALSE);
     p = store_buffer(&acceptorName,        p, FALSE);
index 3826d70..54b68d4 100644 (file)
@@ -135,6 +135,7 @@ struct gss_ctx_id_struct {
     OM_uint32 flags;
     OM_uint32 gssFlags;
     gss_OID mechanismUsed;
+    krb5_cksumtype checksumType;
     krb5_enctype encryptionType;
     krb5_keyblock rfc3961Key;
     gss_name_t initiatorName;
index a64a618..13f0ae2 100644 (file)
@@ -98,6 +98,8 @@ static OM_uint32
 importKerberosKey(OM_uint32 *minor,
                   unsigned char **pBuf,
                   size_t *pRemain,
+                  krb5_cksumtype *checksumType,
+                  krb5_enctype *pEncryptionType,
                   krb5_keyblock *key)
 {
     unsigned char *p = *pBuf;
@@ -106,25 +108,26 @@ importKerberosKey(OM_uint32 *minor,
     OM_uint32 length;
     gss_buffer_desc tmp;
 
-    if (remain < 8) {
+    if (remain < 12) {
         *minor = ERANGE;
         return GSS_S_DEFECTIVE_TOKEN;
     }
 
-    encryptionType = load_uint32_be(&p[0]);
-    length         = load_uint32_be(&p[4]);
+    *checksumType  = load_uint32_be(&p[0]);
+    encryptionType = load_uint32_be(&p[4]);
+    length         = load_uint32_be(&p[8]);
 
     if ((length != 0) != (encryptionType != ENCTYPE_NULL)) {
         *minor = ERANGE;
         return GSS_S_DEFECTIVE_TOKEN;
     }
 
-    if (remain - 8 < length) {
+    if (remain - 12 < length) {
         *minor = ERANGE;
         return GSS_S_DEFECTIVE_TOKEN;
     }
 
-    if (load_buffer(&p[8], length, &tmp) == NULL) {
+    if (load_buffer(&p[12], length, &tmp) == NULL) {
         *minor = ENOMEM;
         return GSS_S_FAILURE;
     }
@@ -133,8 +136,9 @@ importKerberosKey(OM_uint32 *minor,
     KRB_KEY_LENGTH(key) = tmp.length;
     KRB_KEY_DATA(key)   = (unsigned char *)tmp.value;
 
-    *pBuf    += 8 + length;
-    *pRemain -= 8 + length;
+    *pBuf    += 12 + length;
+    *pRemain -= 12 + length;
+    *pEncryptionType = encryptionType;
 
     *minor = 0;
     return GSS_S_COMPLETE;
@@ -213,12 +217,13 @@ gssEapImportContext(OM_uint32 *minor,
     if (GSS_ERROR(major))
         return major;
 
-    major = importKerberosKey(minor, &p, &remain, &ctx->rfc3961Key);
+    major = importKerberosKey(minor, &p, &remain,
+                              &ctx->checksumType,
+                              &ctx->encryptionType,
+                              &ctx->rfc3961Key);
     if (GSS_ERROR(major))
         return major;
 
-    ctx->encryptionType = KRB_KEY_TYPE(&ctx->rfc3961Key);
-
     major = importName(minor, &p, &remain, &ctx->initiatorName);
     if (GSS_ERROR(major))
         return major;
index 67bc962..a54a3cb 100644 (file)
@@ -238,9 +238,6 @@ initReady(OM_uint32 *minor, gss_ctx_id_t ctx)
     OM_uint32 major;
     const unsigned char *key;
     size_t keyLength;
-    krb5_context krbContext;
-
-    GSSEAP_KRB_INIT(&krbContext);
 
     /* Cache encryption type derived from selected mechanism OID */
     major = gssEapOidToEnctype(minor, ctx->mechanismUsed, &ctx->encryptionType);
@@ -251,7 +248,12 @@ initReady(OM_uint32 *minor, gss_ctx_id_t ctx)
         eap_key_available(ctx->initiatorCtx.eap)) {
         key = eap_get_eapKeyData(ctx->initiatorCtx.eap, &keyLength);
 
-        major = gssEapDeriveRFC3961Key(minor, key, keyLength,
+        major = rfc3961EncTypeToChecksumType(minor, ctx->encryptionType,
+                                             &ctx->checksumType);
+        if (GSS_ERROR(major))
+            return major;
+
+        major = gssEapDeriveRfc3961Key(minor, key, keyLength,
                                        ctx->encryptionType, &ctx->rfc3961Key);
         if (GSS_ERROR(major))
             return major;
index ae33843..a1f3dbc 100644 (file)
@@ -209,7 +209,7 @@ unwrapToken(OM_uint32 *minor,
             store_uint16_be(0, ptr + 4);
             store_uint16_be(0, ptr + 6);
 
-            code = gssEapVerify(krbContext, 0, rrc,
+            code = gssEapVerify(krbContext, ctx->checksumType, rrc,
                                 &ctx->rfc3961Key, keyUsage,
                                 iov, iov_count, &valid);
             if (code != 0 || valid == FALSE) {
@@ -228,7 +228,7 @@ unwrapToken(OM_uint32 *minor,
             goto defective;
         seqnum = load_uint64_be(ptr + 8);
 
-        code = gssEapVerify(krbContext, 0, 0,
+        code = gssEapVerify(krbContext, ctx->checksumType, 0,
                             &ctx->rfc3961Key, keyUsage,
                             iov, iov_count, &valid);
         if (code != 0 || valid == FALSE) {
index 6f420d2..9933615 100644 (file)
@@ -198,7 +198,7 @@ int
 gssEapAllocIov(gss_iov_buffer_t iov, size_t size);
 
 OM_uint32
-gssEapDeriveRFC3961Key(OM_uint32 *minor,
+gssEapDeriveRfc3961Key(OM_uint32 *minor,
                        const unsigned char *key,
                        size_t keyLength,
                        krb5_enctype enctype,
@@ -208,6 +208,11 @@ gssEapDeriveRFC3961Key(OM_uint32 *minor,
 OM_uint32
 gssEapKerberosInit(OM_uint32 *minor, krb5_context *context);
 
+OM_uint32
+rfc3961EncTypeToChecksumType(OM_uint32 *minor,
+                             krb5_enctype etype,
+                             krb5_cksumtype *cksumtype);
+
 #define GSSEAP_KRB_INIT(ctx) do {                   \
         OM_uint32 tmpMajor;                         \
         tmpMajor  = gssEapKerberosInit(minor, ctx); \
index 9118e3d..2836e1a 100644 (file)
@@ -81,7 +81,7 @@ gssEapKerberosInit(OM_uint32 *minor, krb5_context *context)
  * where random-to-key and prf are defined in RFC 3961.
  */
 OM_uint32
-gssEapDeriveRFC3961Key(OM_uint32 *minor,
+gssEapDeriveRfc3961Key(OM_uint32 *minor,
                        const unsigned char *key,
                        size_t keyLength,
                        krb5_enctype enctype,
@@ -171,3 +171,22 @@ cleanup:
     *minor = code;
     return (code == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
 }
+
+extern krb5_error_code
+krb5int_c_mandatory_cksumtype(krb5_context, krb5_enctype, krb5_cksumtype *);
+
+OM_uint32
+rfc3961EncTypeToChecksumType(OM_uint32 *minor,
+                             krb5_enctype etype,
+                             krb5_cksumtype *cksumtype)
+{
+    krb5_context krbContext;
+
+    GSSEAP_KRB_INIT(&krbContext);
+
+    *minor = krb5int_c_mandatory_cksumtype(krbContext, etype, cksumtype);
+    if (*minor != 0)
+        return GSS_S_FAILURE;
+
+    return GSS_S_COMPLETE;
+}
index 903aa35..9586689 100644 (file)
@@ -168,24 +168,6 @@ decomposeOid(OM_uint32 *minor,
     return GSS_S_COMPLETE;
 }
 
-#if 0
-OM_uint32
-gssEapReleaseOid(OM_uint32 *minor, gss_OID *oid)
-{
-    OM_uint32 major;
-
-    major = gss_internal_release_oid(minor, oid);
-    if (major == GSS_S_CONTINUE_NEEDED) {
-        GSSEAP_FREE(oid->elements);
-        GSSEAP_FREE(oid);
-        *oid = GSS_C_NO_OID;
-        major = GSS_S_COMPLETE;
-    }
-
-    return major;
-}
-#endif
-
 OM_uint32
 duplicateOidSet(OM_uint32 *minor,
                 const gss_OID_set src,
index ec360e6..41d7754 100644 (file)
@@ -270,7 +270,7 @@ gssEapWrapOrGetMIC(OM_uint32 *minor,
         }
         store_uint64_be(ctx->sendSeq, outbuf + 8);
 
-        code = gssEapSign(krbContext, 0, /* 0 == pick from crypto */
+        code = gssEapSign(krbContext, ctx->checksumType,
                           rrc, &ctx->rfc3961Key, keyUsage,
                           iov, iov_count);
         if (code != 0)