some work on fast reauth
[mech_eap.orig] / init_sec_context.c
index b386c96..173f234 100644 (file)
@@ -234,25 +234,37 @@ initReady(OM_uint32 *minor, gss_ctx_id_t ctx)
     OM_uint32 major;
     const unsigned char *key;
     size_t keyLength;
+    krb5_enctype encryptionType;
+    int gotKey = 0;
 
     /* Cache encryption type derived from selected mechanism OID */
-    major = gssEapOidToEnctype(minor, ctx->mechanismUsed, &ctx->encryptionType);
+    major = gssEapOidToEnctype(minor, ctx->mechanismUsed, &encryptionType);
     if (GSS_ERROR(major))
         return major;
 
-    if (ctx->encryptionType != ENCTYPE_NULL &&
+    if (encryptionType != ENCTYPE_NULL &&
         eap_key_available(ctx->initiatorCtx.eap)) {
         key = eap_get_eapKeyData(ctx->initiatorCtx.eap, &keyLength);
 
-        major = gssEapDeriveRfc3961Key(minor, key, keyLength,
-                                       ctx->encryptionType, &ctx->rfc3961Key);
-        if (GSS_ERROR(major))
-            return major;
+        if (keyLength >= EAP_EMSK_LEN) {
+            major = gssEapDeriveRfc3961Key(minor,
+                                           &key[EAP_EMSK_LEN / 2],
+                                           EAP_EMSK_LEN / 2,
+                                           encryptionType,
+                                           &ctx->rfc3961Key);
+               if (GSS_ERROR(major))
+                   return major;
+
+            major = rfc3961ChecksumTypeForKey(minor, &ctx->rfc3961Key,
+                                              &ctx->checksumType);
+            if (GSS_ERROR(major))
+                return major;
+            gotKey++;
+        }
+    }
 
-        major = rfc3961ChecksumTypeForKey(minor, &ctx->rfc3961Key,
-                                           &ctx->checksumType);
-        if (GSS_ERROR(major))
-            return major;
+    if (gotKey) {
+        ctx->encryptionType = encryptionType;
     } else {
         /*
          * draft-howlett-eap-gss says that integrity/confidentialty should
@@ -301,11 +313,11 @@ eapGssSmInitIdentity(OM_uint32 *minor,
     else
         ctx->expiryTime = now + timeReq;
 
-    major = gss_duplicate_name(minor, cred->name, &ctx->initiatorName);
+    major = gssEapDuplicateName(minor, cred->name, &ctx->initiatorName);
     if (GSS_ERROR(major))
         return major;
 
-    major = gss_duplicate_name(minor, target, &ctx->acceptorName);
+    major = gssEapDuplicateName(minor, target, &ctx->acceptorName);
     if (GSS_ERROR(major))
         return major;
 
@@ -478,6 +490,23 @@ cleanup:
 }
 
 static OM_uint32
+eapGssSmInitKrbCred(OM_uint32 *minor,
+                    gss_cred_id_t cred,
+                    gss_ctx_id_t ctx,
+                    gss_name_t target,
+                    gss_OID mech,
+                    OM_uint32 reqFlags,
+                    OM_uint32 timeReq,
+                    gss_channel_bindings_t chanBindings,
+                    gss_buffer_t inputToken,
+                    gss_buffer_t outputToken)
+{
+    /* Called with already established context */
+    *minor = EINVAL;
+    return GSS_S_BAD_STATUS;
+}
+
+static OM_uint32
 eapGssSmInitEstablished(OM_uint32 *minor,
                         gss_cred_id_t cred,
                         gss_ctx_id_t ctx,
@@ -511,6 +540,7 @@ static struct gss_eap_initiator_sm {
     { TOK_TYPE_NONE,    TOK_TYPE_EAP_RESP,  eapGssSmInitIdentity            },
     { TOK_TYPE_EAP_REQ, TOK_TYPE_EAP_RESP,  eapGssSmInitAuthenticate        },
     { TOK_TYPE_NONE,    TOK_TYPE_GSS_CB,    eapGssSmInitGssChannelBindings  },
+    { TOK_TYPE_KRB_CRED,TOK_TYPE_NONE,      eapGssSmInitKrbCred             },
     { TOK_TYPE_NONE,    TOK_TYPE_NONE,      eapGssSmInitEstablished         },
 };
 
@@ -610,7 +640,7 @@ gss_init_sec_context(OM_uint32 *minor,
     if (ret_flags != NULL)
         *ret_flags = ctx->gssFlags;
     if (time_rec != NULL)
-        gss_context_time(&tmpMinor, ctx, time_rec);
+        gssEapContextTime(&tmpMinor, ctx, time_rec);
 
     assert(ctx->state == EAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED);