]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Add libkrb5 CAMMAC and auth-indicator functions
authorMatt Rogers <mrogers@redhat.com>
Thu, 12 May 2016 23:43:55 +0000 (19:43 -0400)
committerGreg Hudson <ghudson@mit.edu>
Fri, 17 Jun 2016 17:28:56 +0000 (13:28 -0400)
Add k5_unwrap_cammac_svc() and k5_authind_decode() internal functions
to libkrb5, for use by test programs and the forthcoming
auth-indicator authdata module.  Remove the unused
cammac_check_svcver() from the KDC code.  Modify tests/adata.c to use
the new functions, and add a test case to t_authdata.py for multiple
indicator values.

[ghudson@mit.edu: squash three commits; make k5_cammac_check_svcver()
a static helper]

ticket: 8425

src/include/k5-int.h
src/kdc/cammac.c
src/kdc/kdc_util.h
src/lib/krb5/krb/Makefile.in
src/lib/krb5/krb/authdata_dec.c
src/lib/krb5/krb/cammac_util.c [new file with mode: 0644]
src/lib/krb5/libkrb5.exports
src/tests/adata.c
src/tests/t_authdata.py

index 1d3667dfb08ba6e16c631ce6fb8c21d815b99883..1cda50db4540a2e969adb391180b60931474532a 100644 (file)
@@ -956,6 +956,12 @@ void k5_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val);
 void k5_free_cammac(krb5_context context, krb5_cammac *val);
 void k5_free_secure_cookie(krb5_context context, krb5_secure_cookie *val);
 
+krb5_error_code
+k5_unwrap_cammac_svc(krb5_context context, const krb5_authdata *ad,
+                     const krb5_keyblock *key, krb5_authdata ***adata_out);
+krb5_error_code
+k5_authind_decode(const krb5_authdata *ad, krb5_data ***indicators);
+
 /* #include "krb5/wordsize.h" -- comes in through base-defs.h. */
 #include "com_err.h"
 #include "k5-plugin.h"
index 37926e53c60aa8a603d7e9d36e336e7c26aed553..8d18b16e3d6e0378d5f9090afb31587d7f1101e5 100644 (file)
@@ -171,24 +171,3 @@ cleanup:
     krb5_free_data(context, der_enctkt);
     return valid;
 }
-
-/* Return true if cammac's service verifier is valid for server_key. */
-krb5_boolean
-cammac_check_svcver(krb5_context context, krb5_cammac *cammac,
-                    krb5_keyblock *server_key)
-{
-    krb5_error_code ret;
-    krb5_verifier_mac *ver = cammac->svc_verifier;
-    krb5_boolean valid = FALSE;
-    krb5_data *der_authdata = NULL;
-
-    if (ver == NULL)
-        return FALSE;
-    ret = encode_krb5_authdata(cammac->elements, &der_authdata);
-    if (ret)
-        return FALSE;
-    ret = krb5_c_verify_checksum(context, server_key, KRB5_KEYUSAGE_CAMMAC,
-                                 der_authdata, &ver->checksum, &valid);
-    krb5_free_data(context, der_authdata);
-    return valid;
-}
index 137952d5c1c4957aa64f17ca610d805deaeec290..bcf05fc2779fadc46891e55872f820a2ec8bf726 100644 (file)
@@ -137,10 +137,6 @@ krb5_boolean
 cammac_check_kdcver(krb5_context context, krb5_cammac *cammac,
                     krb5_enc_tkt_part *enc_tkt, krb5_db_entry *krbtgt);
 
-krb5_boolean
-cammac_check_svcver(krb5_context context, krb5_cammac *cammac,
-                    krb5_keyblock *server_key);
-
 /* do_as_req.c */
 void
 process_as_req (krb5_kdc_req *, krb5_data *,
index 81eebb4d0bf2d0b9800d75b68f9d5f4b3e140731..2c6ea5cd090be1754b982cc7be235f56041b6588 100644 (file)
@@ -18,6 +18,7 @@ STLIBOBJS= \
        allow_weak.o    \
        appdefault.o    \
        auth_con.o      \
+       cammac_util.o   \
        authdata.o      \
        authdata_exp.o  \
        authdata_enc.o  \
@@ -128,6 +129,7 @@ OBJS=       $(OUTPRE)addr_comp.$(OBJEXT)    \
        $(OUTPRE)allow_weak.$(OBJEXT)   \
        $(OUTPRE)appdefault.$(OBJEXT)   \
        $(OUTPRE)auth_con.$(OBJEXT)     \
+       $(OUTPRE)cammac_util.$(OBJEXT)  \
        $(OUTPRE)authdata.$(OBJEXT)     \
        $(OUTPRE)authdata_exp.$(OBJEXT) \
        $(OUTPRE)authdata_enc.$(OBJEXT) \
@@ -237,6 +239,7 @@ SRCS=       $(srcdir)/addr_comp.c   \
        $(srcdir)/addr_srch.c   \
        $(srcdir)/appdefault.c  \
        $(srcdir)/auth_con.c    \
+       $(srcdir)/cammac_util.c \
        $(srcdir)/authdata.c    \
        $(srcdir)/authdata_exp.c        \
        $(srcdir)/authdata_enc.c        \
index 80f53853f84bfdebc47cf58b3eeabbabbc023e62..0d1c1c4d681e5cf0ac79db5f2f07012f370b32d0 100644 (file)
@@ -249,3 +249,48 @@ krb5_verify_authdata_kdc_issued(krb5_context context,
 
     return 0;
 }
+
+/*
+ * Decode authentication indicator strings from authdata and return as an
+ * allocated array of krb5_data pointers.  The caller must initialize
+ * *indicators to NULL for the first call, and successive calls will reallocate
+ * and append to the indicators array.
+ */
+krb5_error_code
+k5_authind_decode(const krb5_authdata *ad, krb5_data ***indicators)
+{
+    krb5_error_code ret = 0;
+    krb5_data der_ad, **strdata = NULL, **ai_list = *indicators;
+    size_t count, scount;
+
+    if (ad == NULL || ad->ad_type != KRB5_AUTHDATA_AUTH_INDICATOR)
+        goto cleanup;
+
+    /* Count existing auth indicators. */
+    for (count = 0; ai_list != NULL && ai_list[count] != NULL; count++);
+
+    der_ad = make_data(ad->contents, ad->length);
+    ret = decode_utf8_strings(&der_ad, &strdata);
+    if (ret)
+        return ret;
+
+    /* Count new auth indicators. */
+    for (scount = 0; strdata[scount] != NULL; scount++);
+
+    ai_list = realloc(ai_list, (count + scount + 1) * sizeof(*ai_list));
+    if (ai_list == NULL) {
+        ret = ENOMEM;
+        goto cleanup;
+    }
+    *indicators = ai_list;
+
+    /* Steal decoder-allocated pointers and free the container array. */
+    memcpy(ai_list + count, strdata, scount * sizeof(*strdata));
+    ai_list[count + scount] = NULL;
+    free(strdata);
+    strdata = NULL;
+
+cleanup:
+    k5_free_data_ptr_list(strdata);
+    return ret;
+}
diff --git a/src/lib/krb5/krb/cammac_util.c b/src/lib/krb5/krb/cammac_util.c
new file mode 100644 (file)
index 0000000..ab9da05
--- /dev/null
@@ -0,0 +1,86 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* cammac_util.c - CAMMAC related functions */
+/*
+ * Copyright (C) 2016 by Red Hat, Inc.
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "k5-int.h"
+
+/* Return 0 if cammac's service verifier is valid for server_key. */
+static krb5_error_code
+check_svcver(krb5_context context, const krb5_cammac *cammac,
+             const krb5_keyblock *server_key)
+{
+    krb5_error_code ret;
+    krb5_boolean valid = FALSE;
+    krb5_verifier_mac *ver = cammac->svc_verifier;
+    krb5_data *der_authdata = NULL;
+
+    if (ver == NULL)
+        return EINVAL;
+
+    ret = encode_krb5_authdata(cammac->elements, &der_authdata);
+    if (ret)
+        return ret;
+
+    ret = krb5_c_verify_checksum(context, server_key, KRB5_KEYUSAGE_CAMMAC,
+                                 der_authdata, &ver->checksum, &valid);
+    if (!ret && !valid)
+        ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+
+    krb5_free_data(context, der_authdata);
+    return ret;
+}
+
+/* Decode and verify CAMMAC authdata using the svc verifier,
+ * and return the contents as an allocated array of authdata pointers. */
+krb5_error_code
+k5_unwrap_cammac_svc(krb5_context context, const krb5_authdata *ad,
+                     const krb5_keyblock *key, krb5_authdata ***adata_out)
+{
+    krb5_data ad_data;
+    krb5_error_code ret;
+    krb5_cammac *cammac = NULL;
+
+    *adata_out = NULL;
+
+    ad_data = make_data(ad->contents, ad->length);
+    ret = decode_krb5_cammac(&ad_data, &cammac);
+    if (ret)
+        return ret;
+
+    ret = check_svcver(context, cammac, key);
+    if (!ret) {
+        *adata_out = cammac->elements;
+        cammac->elements = NULL;
+    }
+
+    k5_free_cammac(context, cammac);
+    return ret;
+}
index 2c5f1815c1e73f3ce922a4569474687b88c7d35e..e350c89f994090d0ce5e917ada09afd4559ece63 100644 (file)
@@ -113,6 +113,7 @@ initialize_krb5_error_table
 initialize_k5e1_error_table
 initialize_kv5m_error_table
 initialize_prof_error_table
+k5_authind_decode
 k5_build_conf_principals
 k5_ccselect_free_context
 k5_change_error_message_code
@@ -145,6 +146,7 @@ k5_plugin_register
 k5_plugin_register_dyn
 k5_unmarshal_cred
 k5_unmarshal_princ
+k5_unwrap_cammac_svc
 k5_zapfree_pa_data
 krb524_convert_creds_kdc
 krb524_init_ets
index 77f170894603f2b9056572f8baebf034e0071f9e..08bc16a9ea069a95508bbaedb0261b518720a8ec 100644 (file)
@@ -146,28 +146,6 @@ make_authdata(const char *typestr, const char *contents)
     return ad;
 }
 
-/* Verify a CAMMAC's svc_verifier and return its contents. */
-static krb5_authdata **
-unwrap_cammac(krb5_authdata *ad, krb5_keyblock *tktkey)
-{
-    krb5_data *der_elements, ad_data = make_data(ad->contents, ad->length);
-    krb5_authdata **elements;
-    krb5_cammac *cammac;
-    krb5_boolean valid;
-
-    check(decode_krb5_cammac(&ad_data, &cammac));
-    check(encode_krb5_authdata(cammac->elements, &der_elements));
-    assert(cammac->svc_verifier != NULL);
-    krb5_c_verify_checksum(ctx, tktkey, KRB5_KEYUSAGE_CAMMAC, der_elements,
-                           &cammac->svc_verifier->checksum, &valid);
-    assert(valid);
-    elements = cammac->elements;
-    cammac->elements = NULL;
-    krb5_free_data(ctx, der_elements);
-    k5_free_cammac(ctx, cammac);
-    return elements;
-}
-
 static krb5_authdata **
 get_container_contents(krb5_authdata *ad, krb5_keyblock *skey,
                        krb5_keyblock *tktkey)
@@ -177,7 +155,7 @@ get_container_contents(krb5_authdata *ad, krb5_keyblock *skey,
     if (ad->ad_type == KRB5_AUTHDATA_KDC_ISSUED)
         check(krb5_verify_authdata_kdc_issued(ctx, skey, ad, NULL, &inner_ad));
     else if (ad->ad_type == KRB5_AUTHDATA_CAMMAC)
-        inner_ad = unwrap_cammac(ad, tktkey);
+        check(k5_unwrap_cammac_svc(ctx, ad, tktkey, &inner_ad));
     else
         check(krb5_decode_authdata_container(ctx, ad->ad_type, ad, &inner_ad));
     return inner_ad;
@@ -187,9 +165,11 @@ get_container_contents(krb5_authdata *ad, krb5_keyblock *skey,
 static void
 display_auth_indicator(krb5_authdata *ad)
 {
-    krb5_data **strs, **p, d = make_data(ad->contents, ad->length);
+    krb5_data **strs = NULL, **p;
+
+    check(k5_authind_decode(ad, &strs));
+    assert(strs != NULL);
 
-    check(decode_utf8_strings(&d, &strs));
     printf("[");
     for (p = strs; *p != NULL; p++) {
         printf("%.*s", (int)(*p)->length, (*p)->data);
index 20c8bc60de0f87d4e7517762d611663144b0ddf5..5ce66d9dec95eeed3e29cb6d306606283cf373e8 100644 (file)
@@ -115,6 +115,13 @@ out = realm.run(['./adata', 'krbtgt/FOREIGN'])
 if '+97: [indcl]' not in out:
     fail('auth-indicator not seen for AS req to cross-realm TGT')
 
+# Multiple indicators
+realm.kinit(realm.user_princ, password('user'),
+            ['-X', 'indicators=indcl indcl2 indcl3'])
+out = realm.run(['./adata', realm.krbtgt_princ])
+if '+97: [indcl, indcl2, indcl3]' not in out:
+    fail('multiple auth-indicators not seen for normal AS req')
+
 # AS request to local TGT (resulting creds are used for TGS tests)
 realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl'])
 out = realm.run(['./adata', realm.krbtgt_princ])