krb5 commit: Add CAMMAC handling to the authdata framework

Greg Hudson ghudson at mit.edu
Mon Jun 20 11:54:13 EDT 2016


https://github.com/krb5/krb5/commit/f4f619e7905d762204695dd66450e586c183c9fd
commit f4f619e7905d762204695dd66450e586c183c9fd
Author: Matt Rogers <mrogers at redhat.com>
Date:   Thu May 12 20:14:01 2016 -0400

    Add CAMMAC handling to the authdata framework
    
    Handle CAMMAC contained authdata similarly to KDC-issued authdata, where
    it is verified before passing to the import function.
    
    [ghudson at mit.edu: fix memory leak and reduce copying in
    extract_cammac()]
    
    ticket: 8425

 src/include/krb5/authdata_plugin.h |    3 +-
 src/lib/krb5/krb/authdata.c        |   77 ++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 1 deletions(-)

diff --git a/src/include/krb5/authdata_plugin.h b/src/include/krb5/authdata_plugin.h
index 3399eea..5bb95fa 100644
--- a/src/include/krb5/authdata_plugin.h
+++ b/src/include/krb5/authdata_plugin.h
@@ -55,8 +55,9 @@ typedef krb5_error_code
 #define AD_USAGE_TGS_REQ        0x02
 #define AD_USAGE_AP_REQ         0x04
 #define AD_USAGE_KDC_ISSUED     0x08
-#define AD_USAGE_MASK           0x0F
 #define AD_INFORMATIONAL        0x10
+#define AD_CAMMAC_PROTECTED     0x20
+#define AD_USAGE_MASK           0x2F
 
 struct _krb5_authdata_context;
 
diff --git a/src/lib/krb5/krb/authdata.c b/src/lib/krb5/krb/authdata.c
index fb8beb3..f2c66bd 100644
--- a/src/lib/krb5/krb/authdata.c
+++ b/src/lib/krb5/krb/authdata.c
@@ -536,6 +536,72 @@ k5_get_kdc_issued_authdata(krb5_context kcontext,
     return code;
 }
 
+/* Decode and verify each CAMMAC and collect the resulting authdata,
+ * ignoring those that failed verification. */
+static krb5_error_code
+extract_cammacs(krb5_context kcontext, krb5_authdata **cammacs,
+                const krb5_keyblock *key, krb5_authdata ***ad_out)
+{
+    krb5_error_code ret;
+    krb5_authdata **list = NULL, **elements = NULL, **new_list;
+    size_t i, n_elements, count = 0;
+
+    *ad_out = NULL;
+
+    for (i = 0; cammacs != NULL && cammacs[i] != NULL; i++) {
+        ret = k5_unwrap_cammac_svc(kcontext, cammacs[i], key, &elements);
+        if (ret && ret != KRB5KRB_AP_ERR_BAD_INTEGRITY)
+            goto cleanup;
+        ret = 0;
+
+        /* Add the verified elements to list and free the container array. */
+        for (n_elements = 0; elements[n_elements] != NULL; n_elements++);
+        new_list = realloc(list, (count + n_elements + 1) * sizeof(list));
+        if (new_list == NULL) {
+            ret = ENOMEM;
+            goto cleanup;
+        }
+        list = new_list;
+        memcpy(list + count, elements, n_elements * sizeof(list));
+        count += n_elements;
+        list[count] = NULL;
+        free(elements);
+        elements = NULL;
+    }
+
+    *ad_out = list;
+    list = NULL;
+
+cleanup:
+    krb5_free_authdata(kcontext, list);
+    krb5_free_authdata(kcontext, elements);
+    return ret;
+}
+
+/* Retrieve verified CAMMAC contained elements. */
+static krb5_error_code
+get_cammac_authdata(krb5_context kcontext, const krb5_ap_req *ap_req,
+                    const krb5_keyblock *key, krb5_authdata ***elems_out)
+{
+    krb5_error_code ret = 0;
+    krb5_authdata **ticket_authdata, **cammacs, **elements;
+
+    *elems_out = NULL;
+
+    ticket_authdata = ap_req->ticket->enc_part2->authorization_data;
+    ret = krb5_find_authdata(kcontext, ticket_authdata, NULL,
+                             KRB5_AUTHDATA_CAMMAC, &cammacs);
+    if (ret || cammacs == NULL)
+        return ret;
+
+    ret = extract_cammacs(kcontext, cammacs, key, &elements);
+    if (!ret)
+        *elems_out = elements;
+
+    krb5_free_authdata(kcontext, cammacs);
+    return ret;
+}
+
 krb5_error_code
 krb5int_authdata_verify(krb5_context kcontext,
                         krb5_authdata_context context,
@@ -550,12 +616,17 @@ krb5int_authdata_verify(krb5_context kcontext,
     krb5_authdata **ticket_authdata;
     krb5_principal kdc_issuer = NULL;
     krb5_authdata **kdc_issued_authdata = NULL;
+    krb5_authdata **cammac_authdata = NULL;
 
     authen_authdata = (*auth_context)->authentp->authorization_data;
     ticket_authdata = ap_req->ticket->enc_part2->authorization_data;
     k5_get_kdc_issued_authdata(kcontext, ap_req,
                                &kdc_issuer, &kdc_issued_authdata);
 
+    code = get_cammac_authdata(kcontext, ap_req, key, &cammac_authdata);
+    if (code)
+        goto cleanup;
+
     for (i = 0; i < context->n_modules; i++) {
         struct _krb5_authdata_context_module *module = &context->modules[i];
         krb5_authdata **authdata = NULL;
@@ -577,6 +648,11 @@ krb5int_authdata_verify(krb5_context kcontext,
             kdc_issued_flag = TRUE;
         }
 
+        if (cammac_authdata != NULL && (module->flags & AD_CAMMAC_PROTECTED)) {
+            authdata = cammac_authdata;
+            kdc_issued_flag = TRUE;
+        }
+
         if (authdata == NULL) {
             krb5_boolean ticket_usage = FALSE;
             krb5_boolean authen_usage = FALSE;
@@ -628,6 +704,7 @@ krb5int_authdata_verify(krb5_context kcontext,
             break;
     }
 
+cleanup:
     krb5_free_principal(kcontext, kdc_issuer);
     krb5_free_authdata(kcontext, kdc_issued_authdata);
 


More information about the cvs-krb5 mailing list