krb5 commit: Add libkrb5 CAMMAC and auth-indicator functions
Greg Hudson
ghudson at mit.edu
Mon Jun 20 11:54:11 EDT 2016
https://github.com/krb5/krb5/commit/3563485fdb54024bd79a4491000c84943cc20ab9
commit 3563485fdb54024bd79a4491000c84943cc20ab9
Author: Matt Rogers <mrogers at redhat.com>
Date: Thu May 12 19:43:55 2016 -0400
Add libkrb5 CAMMAC and auth-indicator functions
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 at mit.edu: squash three commits; make k5_cammac_check_svcver()
a static helper]
ticket: 8425
src/include/k5-int.h | 6 +++
src/kdc/cammac.c | 21 ---------
src/kdc/kdc_util.h | 4 --
src/lib/krb5/krb/Makefile.in | 3 +
src/lib/krb5/krb/authdata_dec.c | 45 ++++++++++++++++++++
src/lib/krb5/krb/cammac_util.c | 86 +++++++++++++++++++++++++++++++++++++++
src/lib/krb5/libkrb5.exports | 2 +
src/tests/adata.c | 30 ++-----------
src/tests/t_authdata.py | 7 +++
9 files changed, 154 insertions(+), 50 deletions(-)
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 1d3667d..1cda50d 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -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"
diff --git a/src/kdc/cammac.c b/src/kdc/cammac.c
index 37926e5..8d18b16 100644
--- a/src/kdc/cammac.c
+++ b/src/kdc/cammac.c
@@ -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;
-}
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 137952d..bcf05fc 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -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 *,
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index 81eebb4..2c6ea5c 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -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 \
diff --git a/src/lib/krb5/krb/authdata_dec.c b/src/lib/krb5/krb/authdata_dec.c
index 80f5385..0d1c1c4 100644
--- a/src/lib/krb5/krb/authdata_dec.c
+++ b/src/lib/krb5/krb/authdata_dec.c
@@ -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
index 0000000..ab9da05
--- /dev/null
+++ b/src/lib/krb5/krb/cammac_util.c
@@ -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;
+}
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
index 2c5f181..e350c89 100644
--- a/src/lib/krb5/libkrb5.exports
+++ b/src/lib/krb5/libkrb5.exports
@@ -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
diff --git a/src/tests/adata.c b/src/tests/adata.c
index 77f1708..08bc16a 100644
--- a/src/tests/adata.c
+++ b/src/tests/adata.c
@@ -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);
diff --git a/src/tests/t_authdata.py b/src/tests/t_authdata.py
index 20c8bc6..5ce66d9 100644
--- a/src/tests/t_authdata.py
+++ b/src/tests/t_authdata.py
@@ -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])
More information about the cvs-krb5
mailing list