use RFC3961 checksums for CB/exts MIC
[moonshot.git] / moonshot / mech_eap / init_sec_context.c
index e99b479..a123626 100644 (file)
@@ -759,21 +759,45 @@ eapGssSmInitGssChannelBindings(OM_uint32 *minor,
                                OM_uint32 *smFlags)
 {
     OM_uint32 major;
-    gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
+    krb5_error_code code;
+    krb5_context krbContext;
+    krb5_data data;
+    krb5_checksum cksum;
+    gss_buffer_desc cksumBuffer;
 
-    if (chanBindings != GSS_C_NO_CHANNEL_BINDINGS)
-        buffer = chanBindings->application_data;
+    if (chanBindings == GSS_C_NO_CHANNEL_BINDINGS ||
+        chanBindings->application_data.length == 0)
+        return GSS_S_CONTINUE_NEEDED;
 
-    major = gssEapWrap(minor, ctx, TRUE, GSS_C_QOP_DEFAULT,
-                       &buffer, NULL, outputToken);
-    if (GSS_ERROR(major))
-        return major;
+    GSSEAP_KRB_INIT(&krbContext);
+
+    KRB_DATA_INIT(&data);
+
+    gssBufferToKrbData(&chanBindings->application_data, &data);
+
+    code = krb5_c_make_checksum(krbContext, ctx->checksumType,
+                                &ctx->rfc3961Key,
+                                KEY_USAGE_GSSEAP_CHBIND_MIC,
+                                &data, &cksum);
+    if (code != 0) {
+        *minor = code;
+        return GSS_S_FAILURE;
+    }
+
+    cksumBuffer.length = KRB_CHECKSUM_LENGTH(&cksum);
+    cksumBuffer.value  = KRB_CHECKSUM_DATA(&cksum);
 
-    GSSEAP_ASSERT(outputToken->value != NULL);
+    major = duplicateBuffer(minor, &cksumBuffer, outputToken);
+    if (GSS_ERROR(major)) {
+        krb5_free_checksum_contents(krbContext, &cksum);
+        return major;
+    }
 
     *minor = 0;
     *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL;
 
+    krb5_free_checksum_contents(krbContext, &cksum);
+
     return GSS_S_CONTINUE_NEEDED;
 }
 
@@ -803,7 +827,7 @@ eapGssSmInitInitiatorMIC(OM_uint32 *minor,
 
     return GSS_S_CONTINUE_NEEDED;
 }
+
 #ifdef GSSEAP_ENABLE_REAUTH
 static OM_uint32
 eapGssSmInitReauthCreds(OM_uint32 *minor,
@@ -918,7 +942,7 @@ static struct gss_eap_sm eapGssInitiatorSm[] = {
         ITOK_TYPE_NONE,
         ITOK_TYPE_GSS_CHANNEL_BINDINGS,
         GSSEAP_STATE_INITIATOR_EXTS,
-        SM_ITOK_FLAG_REQUIRED,
+        0,
         eapGssSmInitGssChannelBindings
     },
     {