For new encryption types and for RC4, encrypt the krb_cred message in
authorSam Hartman <hartmans@mit.edu>
Wed, 8 Jan 2003 02:20:42 +0000 (02:20 +0000)
committerSam Hartman <hartmans@mit.edu>
Wed, 8 Jan 2003 02:20:42 +0000 (02:20 +0000)
the initial gssapi token if credentials are being delegated.  For
consistency with Microsoft, we encrypt the credentials using the
session key not the subsession key.

Ticket: 1054

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15091 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/gssapi/krb5/ChangeLog
src/lib/gssapi/krb5/init_sec_context.c
src/lib/krb5/krb/ChangeLog
src/lib/krb5/krb/mk_req_ext.c

index 8fd4fb1623c027ee1dd13976b3a8699e9aa9d84f..506b95870a79a9573ecc883da1dcd7cad7a69c2e 100644 (file)
@@ -1,3 +1,10 @@
+2003-01-07  Sam Hartman  <hartmans@mit.edu>
+
+       * init_sec_context.c (make_gss_checksum): New function to
+       construct the checksum in the authenticator, used directly  or
+       indirectly depending on whether krb5_cred is encrypted.
+       (make_ap_req_v1): use it
+
 2003-01-07  Ken Raeburn  <raeburn@mit.edu>
 
        * Makefile.original: Deleted.
index 412266d818353f59c2692ab6fb21c27c24a55d6c..1fab732d2839695c21677a39fd61dcefd41e9e7a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000,2002 by the Massachusetts Institute of Technology.
+ * Copyright 2000,2002, 2003 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -138,95 +138,78 @@ cleanup:
            krb5_free_principal(context, in_creds.server);
     return code;
 }
-
-static krb5_error_code
-make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
-    krb5_context context;
+struct gss_checksum_data {
     krb5_gss_ctx_id_rec *ctx;
     krb5_gss_cred_id_t cred;
-    krb5_creds *k_cred;
-    gss_channel_bindings_t chan_bindings;
-    gss_OID mech_type;
-    gss_buffer_t token;
+    krb5_checksum md5;
+    krb5_data checksum_data;
+};
+
+static krb5_error_code KRB5_CALLCONV
+make_gss_checksum (krb5_context context, krb5_auth_context auth_context,
+                  void *cksum_data, krb5_data **out)
 {
-    krb5_flags mk_req_flags = 0;
     krb5_error_code code;
-    krb5_data checksum_data;
-    krb5_checksum md5;
-    krb5_data ap_req;
+    krb5_int32 con_flags;
     unsigned char *ptr;
+    struct gss_checksum_data *data = cksum_data;
     krb5_data credmsg;
-    unsigned char *t;
-    int tlen;
-    krb5_int32 con_flags;
-
-    ap_req.data = 0;
-    checksum_data.data = 0;
+    data->checksum_data.data = 0;
     credmsg.data = 0;
-
-    /* build the checksum buffer */
-    /* compute the hash of the channel bindings */
-
-    if ((code = kg_checksum_channel_bindings(context, chan_bindings, &md5, 0)))
-        return(code);
-
-    krb5_auth_con_set_req_cksumtype(context, ctx->auth_context,
-                                   CKSUMTYPE_KG_CB);
-
     /* build the checksum field */
 
-    if (ctx->gss_flags & GSS_C_DELEG_FLAG) {
+    if (data->ctx->gss_flags & GSS_C_DELEG_FLAG) {
        /* first get KRB_CRED message, so we know its length */
 
        /* clear the time check flag that was set in krb5_auth_con_init() */
-       krb5_auth_con_getflags(context, ctx->auth_context, &con_flags);
-       krb5_auth_con_setflags(context, ctx->auth_context,
+       krb5_auth_con_getflags(context, auth_context, &con_flags);
+       krb5_auth_con_setflags(context, auth_context,
                               con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME);
 
-       code = krb5_fwd_tgt_creds(context, ctx->auth_context, 0,
-                                 cred->princ, ctx->there, cred->ccache, 1,
+       code = krb5_fwd_tgt_creds(context, auth_context, 0,
+                                 data->cred->princ, data->ctx->there,
+                                 data->cred->ccache, 1,
                                  &credmsg);
 
        /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */
-       krb5_auth_con_setflags(context, ctx->auth_context, con_flags);
+       krb5_auth_con_setflags(context, auth_context, con_flags);
 
        if (code) {
            /* don't fail here; just don't accept/do the delegation
                request */
-           ctx->gss_flags &= ~GSS_C_DELEG_FLAG;
+           data->ctx->gss_flags &= ~GSS_C_DELEG_FLAG;
 
-           checksum_data.length = 24;
+           data->checksum_data.length = 24;
        } else {
            if (credmsg.length+28 > KRB5_INT16_MAX) {
                krb5_free_data_contents(context, &credmsg);
                return(KRB5KRB_ERR_FIELD_TOOLONG);
            }
 
-           checksum_data.length = 28+credmsg.length;
+           data->checksum_data.length = 28+credmsg.length;
        }
     } else {
-       checksum_data.length = 24;
+       data->checksum_data.length = 24;
     }
 
     /* now allocate a buffer to hold the checksum data and
        (maybe) KRB_CRED msg */
 
-    if ((checksum_data.data =
-        (char *) xmalloc(checksum_data.length)) == NULL) {
+    if ((data->checksum_data.data =
+        (char *) xmalloc(data->checksum_data.length)) == NULL) {
        if (credmsg.data)
            krb5_free_data_contents(context, &credmsg);
        return(ENOMEM);
     }
 
-    ptr = checksum_data.data;
+    ptr = data->checksum_data.data;
 
-    TWRITE_INT(ptr, md5.length, 0);
-    TWRITE_STR(ptr, (unsigned char *) md5.contents, md5.length);
-    TWRITE_INT(ptr, ctx->gss_flags, 0);
+    TWRITE_INT(ptr, data->md5.length, 0);
+    TWRITE_STR(ptr, (unsigned char *) data->md5.contents, data->md5.length);
+    TWRITE_INT(ptr, data->ctx->gss_flags, 0);
 
     /* done with this, free it */
-    xfree(md5.contents);
+    xfree(data->md5.contents);
 
     if (credmsg.data) {
        TWRITE_INT16(ptr, KRB5_GSS_FOR_CREDS_OPTION, 0);
@@ -236,6 +219,60 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
        /* free credmsg data */
        krb5_free_data_contents(context, &credmsg);
     }
+    *out = &data->checksum_data;
+    return 0;
+}
+    
+static krb5_error_code
+make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
+    krb5_context context;
+    krb5_gss_ctx_id_rec *ctx;
+    krb5_gss_cred_id_t cred;
+    krb5_creds *k_cred;
+    gss_channel_bindings_t chan_bindings;
+    gss_OID mech_type;
+    gss_buffer_t token;
+{
+    krb5_flags mk_req_flags = 0;
+    krb5_error_code code;
+    struct gss_checksum_data cksum_struct;
+    krb5_checksum md5;
+    krb5_data ap_req;
+    krb5_data *checksum_data = NULL;
+    unsigned char *ptr;
+    unsigned char *t;
+    int tlen;
+
+
+    ap_req.data = 0;
+
+    /* compute the hash of the channel bindings */
+
+    if ((code = kg_checksum_channel_bindings(context, chan_bindings, &md5, 0)))
+        return(code);
+
+    krb5_auth_con_set_req_cksumtype(context, ctx->auth_context,
+                                   CKSUMTYPE_KG_CB);
+    cksum_struct.md5 = md5;
+    cksum_struct.ctx = ctx;
+    cksum_struct.cred = cred;
+    cksum_struct.checksum_data.data = NULL;
+    switch (k_cred->keyblock.enctype) {
+    case ENCTYPE_DES_CBC_CRC:
+    case ENCTYPE_DES_CBC_MD4:
+    case ENCTYPE_DES_CBC_MD5:
+    case ENCTYPE_DES3_CBC_SHA1:
+      code = make_gss_checksum(context, ctx->auth_context, &cksum_struct,
+                                &checksum_data);
+           if (code)
+               goto cleanup;
+       break;
+    default:
+       krb5_auth_con_set_checksum_func(context, ctx->auth_context,
+                                       make_gss_checksum, &cksum_struct);
+           break;
+    }
+
 
     /* call mk_req.  subkey and ap_req need to be used or destroyed */
 
@@ -245,7 +282,7 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
        mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED;
 
     if ((code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags,
-                                    &checksum_data, k_cred, &ap_req)))
+                                    checksum_data, k_cred, &ap_req)))
        goto cleanup;
 
    /* store the interesting stuff from creds and authent */
@@ -278,9 +315,7 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
 
    code = 0;
     
-cleanup:
-   if (checksum_data.data)
-       xfree(checksum_data.data);
+ cleanup:
    if (ap_req.data)
        krb5_free_data_contents(context, &ap_req);
 
index 997292fe40ba4fd182a84a2a214a6862af159418..b3fb0ddec2aa7ecf3a7755cdaba7b7e1ae8a85ae 100644 (file)
@@ -1,7 +1,7 @@
 2003-01-07  Sam Hartman  <hartmans@mit.edu>
 
        * mk_req_ext.c (krb5_mk_req_extended): Fix logic error in checksum function handling
-       
+       (krb5_mk_req_extended): For consistency with Microsoft, never use a subkey before calling the checksum callback
 
 2003-01-06  Sam Hartman  <hartmans@mit.edu>
 
index a6510019d18726f567db1a00eb345e82d984fe3b..1ed14a9226079fc56db723ccd02d4c8ef87c627e 100644 (file)
@@ -121,6 +121,15 @@ krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
        
 
     /* generate subkey if needed */
+    if (!in_data &&(*auth_context)->checksum_func) {
+       retval = (*auth_context)->checksum_func( context,
+                                                *auth_context,
+                                                (*auth_context)->checksum_func_data,
+                                                &in_data);
+       if (retval)
+           goto cleanup;
+    }
+
     if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey)) {
        /* Provide some more fodder for random number code.
           This isn't strong cryptographically; the point here is not
@@ -140,14 +149,6 @@ krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
            goto cleanup;
     }
 
-    if (!in_data &&(*auth_context)->checksum_func) {
-       retval = (*auth_context)->checksum_func( context,
-                                                *auth_context,
-                                                (*auth_context)->checksum_func_data,
-                                                &in_data);
-       if (retval)
-           goto cleanup_cksum;
-    }
 
     if (in_data) {