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