krb5 commit: Add ASN.1 encoder and decoder for CAMMAC

Greg Hudson ghudson at mit.edu
Fri Jul 10 02:37:08 EDT 2015


https://github.com/krb5/krb5/commit/6a06997f5f15ba81e196ac20c15b0ba17954ac6c
commit 6a06997f5f15ba81e196ac20c15b0ba17954ac6c
Author: Greg Hudson <ghudson at mit.edu>
Date:   Fri Oct 24 16:56:47 2014 -0400

    Add ASN.1 encoder and decoder for CAMMAC
    
    Add internal type declarations for krb5_verifier_mac and krb5_cammac.
    Add ASN.1 encoder and decoder functions and an internal free function
    for krb5_cammac.  Add ASN.1 tests for krb5_cammac as well as asn1c
    test vectors for Verifier and AD-CAMMAC.

 src/include/k5-int.h                 |   27 +++++++++++
 src/lib/krb5/asn.1/asn1_k_encode.c   |   27 +++++++++++
 src/lib/krb5/krb/kfree.c             |   25 ++++++++++
 src/lib/krb5/libkrb5.exports         |    3 +
 src/tests/asn.1/Makefile.in          |    3 +-
 src/tests/asn.1/cammac.asn1          |   30 ++++++++++++
 src/tests/asn.1/krb5_decode_test.c   |   13 +++++
 src/tests/asn.1/krb5_encode_test.c   |   10 ++++
 src/tests/asn.1/ktest.c              |   86 ++++++++++++++++++++++++++++++++++
 src/tests/asn.1/ktest.h              |    3 +
 src/tests/asn.1/ktest_equal.c        |   40 ++++++++++++++--
 src/tests/asn.1/ktest_equal.h        |    1 +
 src/tests/asn.1/make-vectors.c       |   61 +++++++++++++++++++++++-
 src/tests/asn.1/reference_encode.out |    2 +
 src/tests/asn.1/trval_reference.out  |   57 ++++++++++++++++++++++
 15 files changed, 382 insertions(+), 6 deletions(-)

diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index c14f7de..bde0842 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -844,6 +844,26 @@ typedef struct _krb5_iakerb_finished {
     krb5_checksum checksum;
 } krb5_iakerb_finished;
 
+typedef struct _krb5_verifier_mac {
+    krb5_principal princ;
+    krb5_kvno kvno;
+    krb5_enctype enctype;
+    krb5_checksum checksum;
+} krb5_verifier_mac;
+
+/*
+ * AD-CAMMAC's other-verifiers field is a sequence of Verifier, which is an
+ * extensible choice with only one selection, Verifier-MAC.  For the time being
+ * we will represent this field directly as an array of krb5_verifier_mac.
+ * That will have to change if other selections are added.
+ */
+typedef struct _krb5_cammac {
+    krb5_authdata **elements;
+    krb5_verifier_mac *kdc_verifier;
+    krb5_verifier_mac *svc_verifier;
+    krb5_verifier_mac **other_verifiers;
+} krb5_cammac;
+
 krb5_pa_data *
 krb5int_find_pa_data(krb5_context, krb5_pa_data *const *, krb5_preauthtype);
 /* Does not return a copy; original padata sequence responsible for freeing*/
@@ -920,6 +940,7 @@ void k5_free_pa_otp_challenge(krb5_context context,
                               krb5_pa_otp_challenge *val);
 void k5_free_pa_otp_req(krb5_context context, krb5_pa_otp_req *val);
 void k5_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val);
+void k5_free_cammac(krb5_context context, krb5_cammac *val);
 
 /* #include "krb5/wordsize.h" -- comes in through base-defs.h. */
 #include "com_err.h"
@@ -1470,6 +1491,9 @@ encode_krb5_pa_otp_enc_req(const krb5_data *, krb5_data **);
 krb5_error_code
 encode_krb5_kkdcp_message(const krb5_kkdcp_message *, krb5_data **);
 
+krb5_error_code
+encode_krb5_cammac(const krb5_cammac *, krb5_data **);
+
 /*************************************************************************
  * End of prototypes for krb5_encode.c
  *************************************************************************/
@@ -1643,6 +1667,9 @@ decode_krb5_pa_otp_enc_req(const krb5_data *, krb5_data **);
 krb5_error_code
 decode_krb5_kkdcp_message(const krb5_data *, krb5_kkdcp_message **);
 
+krb5_error_code
+decode_krb5_cammac(const krb5_data *, krb5_cammac **);
+
 struct _krb5_key_data;          /* kdb.h */
 
 struct ldap_seqof_key_data {
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index 25b825c..e173797 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -1766,3 +1766,30 @@ DEFSEQTYPE(kkdcp_message, krb5_kkdcp_message,
            kkdcp_message_fields);
 MAKE_ENCODER(encode_krb5_kkdcp_message, kkdcp_message);
 MAKE_DECODER(decode_krb5_kkdcp_message, kkdcp_message);
+
+DEFFIELD(vmac_0, krb5_verifier_mac, princ, 0, opt_principal);
+DEFFIELD(vmac_1, krb5_verifier_mac, kvno, 1, opt_kvno);
+DEFFIELD(vmac_2, krb5_verifier_mac, enctype, 2, opt_int32);
+DEFFIELD(vmac_3, krb5_verifier_mac, checksum, 3, checksum);
+static const struct atype_info *vmac_fields[] = {
+    &k5_atype_vmac_0, &k5_atype_vmac_1, &k5_atype_vmac_2, &k5_atype_vmac_3
+};
+DEFSEQTYPE(vmac, krb5_verifier_mac, vmac_fields);
+DEFPTRTYPE(vmac_ptr, vmac);
+DEFOPTIONALZEROTYPE(opt_vmac_ptr, vmac_ptr);
+DEFNONEMPTYNULLTERMSEQOFTYPE(vmacs, vmac_ptr);
+DEFPTRTYPE(vmacs_ptr, vmacs);
+DEFOPTIONALEMPTYTYPE(opt_vmacs_ptr, vmacs_ptr);
+
+DEFFIELD(cammac_0, krb5_cammac, elements, 0, auth_data_ptr);
+DEFFIELD(cammac_1, krb5_cammac, kdc_verifier, 1, opt_vmac_ptr);
+DEFFIELD(cammac_2, krb5_cammac, svc_verifier, 2, opt_vmac_ptr);
+DEFFIELD(cammac_3, krb5_cammac, other_verifiers, 3, opt_vmacs_ptr);
+static const struct atype_info *cammac_fields[] = {
+    &k5_atype_cammac_0, &k5_atype_cammac_1, &k5_atype_cammac_2,
+    &k5_atype_cammac_3
+};
+DEFSEQTYPE(cammac, krb5_cammac, cammac_fields);
+
+MAKE_ENCODER(encode_krb5_cammac, cammac);
+MAKE_DECODER(decode_krb5_cammac, cammac);
diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c
index f86c619..26200da 100644
--- a/src/lib/krb5/krb/kfree.c
+++ b/src/lib/krb5/krb/kfree.c
@@ -831,3 +831,28 @@ k5_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val)
     free(val->kerb_message.data);
     free(val);
 }
+
+static void
+free_vmac(krb5_context context, krb5_verifier_mac *val)
+{
+    if (val == NULL)
+        return;
+    krb5_free_principal(context, val->princ);
+    krb5_free_checksum_contents(context, &val->checksum);
+}
+
+void
+k5_free_cammac(krb5_context context, krb5_cammac *val)
+{
+    krb5_verifier_mac **vp;
+
+    if (val == NULL)
+        return;
+    krb5_free_authdata(context, val->elements);
+    free_vmac(context, val->kdc_verifier);
+    free_vmac(context, val->svc_verifier);
+    for (vp = val->other_verifiers; vp != NULL && *vp != NULL; vp++)
+        free_vmac(context, *vp);
+    free(val->other_verifiers);
+    free(val);
+}
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
index c119a34..e25158c 100644
--- a/src/lib/krb5/libkrb5.exports
+++ b/src/lib/krb5/libkrb5.exports
@@ -8,6 +8,7 @@ decode_krb5_as_rep
 decode_krb5_as_req
 decode_krb5_authdata
 decode_krb5_authenticator
+decode_krb5_cammac
 decode_krb5_cred
 decode_krb5_enc_cred_part
 decode_krb5_enc_data
@@ -56,6 +57,7 @@ encode_krb5_as_rep
 encode_krb5_as_req
 encode_krb5_authdata
 encode_krb5_authenticator
+encode_krb5_cammac
 encode_krb5_checksum
 encode_krb5_cred
 encode_krb5_enc_cred_part
@@ -114,6 +116,7 @@ k5_etypes_contains
 k5_expand_path_tokens
 k5_expand_path_tokens_extra
 k5_free_algorithm_identifier
+k5_free_cammac
 k5_free_otp_tokeninfo
 k5_free_kkdcp_message
 k5_free_pa_otp_challenge
diff --git a/src/tests/asn.1/Makefile.in b/src/tests/asn.1/Makefile.in
index 112a55e..6d766ed 100644
--- a/src/tests/asn.1/Makefile.in
+++ b/src/tests/asn.1/Makefile.in
@@ -8,7 +8,8 @@ SRCS= $(srcdir)/krb5_encode_test.c $(srcdir)/krb5_decode_test.c \
 	$(srcdir)/trval.c $(srcdir)/t_trval.c
 
 ASN1SRCS= $(srcdir)/krb5.asn1 $(srcdir)/pkix.asn1 $(srcdir)/otp.asn1 \
-	$(srcdir)/pkinit.asn1 $(srcdir)/pkinit-agility.asn1
+	$(srcdir)/pkinit.asn1 $(srcdir)/pkinit-agility.asn1 \
+	$(srcdir)/cammac.asn1
 
 all:: krb5_encode_test krb5_decode_test krb5_decode_leak t_trval
 
diff --git a/src/tests/asn.1/cammac.asn1 b/src/tests/asn.1/cammac.asn1
new file mode 100644
index 0000000..2fc9976
--- /dev/null
+++ b/src/tests/asn.1/cammac.asn1
@@ -0,0 +1,30 @@
+KerberosV5CAMMAC DEFINITIONS EXPLICIT TAGS ::= BEGIN
+
+IMPORTS
+      AuthorizationData, PrincipalName, Checksum, UInt32, Int32
+        FROM KerberosV5Spec2 { iso(1) identified-organization(3)
+          dod(6) internet(1) security(5) kerberosV5(2)
+          modules(4) krb5spec2(2) };
+          -- as defined in RFC 4120.
+
+AD-CAMMAC                   ::= SEQUENCE {
+      elements              [0] AuthorizationData,
+      kdc-verifier          [1] Verifier-MAC OPTIONAL,
+      svc-verifier          [2] Verifier-MAC OPTIONAL,
+      other-verifiers       [3] SEQUENCE (SIZE (1..MAX))
+                                OF Verifier OPTIONAL
+}
+
+Verifier             ::= CHOICE {
+      mac            Verifier-MAC,
+      ...
+}
+
+Verifier-MAC         ::= SEQUENCE {
+      identifier     [0] PrincipalName OPTIONAL,
+      kvno           [1] UInt32 OPTIONAL,
+      enctype        [2] Int32 OPTIONAL,
+      mac            [3] Checksum
+}
+
+END
diff --git a/src/tests/asn.1/krb5_decode_test.c b/src/tests/asn.1/krb5_decode_test.c
index 4d1acfa..1a99b0e 100644
--- a/src/tests/asn.1/krb5_decode_test.c
+++ b/src/tests/asn.1/krb5_decode_test.c
@@ -1085,6 +1085,19 @@ int main(argc, argv)
         decode_run("kkdcp_message","","30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 98 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A!
 0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A1 0A 1B 08 6B 72 62 35 64 61 74 61",decode_krb5_kkdcp_message,ktest_equal_kkdcp_message,ktest_free_kkdcp_message);
     }
 
+    /****************************************************************/
+    /* decode_krb5_cammac */
+    {
+        setup(krb5_cammac,ktest_make_minimal_cammac);
+        decode_run("cammac","(optionals NULL)","30 12 A0 10 30 0E 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31",decode_krb5_cammac,ktest_equal_cammac,k5_free_cammac);
+        ktest_empty_cammac(&ref);
+    }
+    {
+        setup(krb5_cammac,ktest_make_maximal_cammac);
+        decode_run("cammac","","30 81 F2 A0 1E 30 1C 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31 30 0C A0 03 02 01 02 A1 05 04 03 61 64 32 A1 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 6B 64 63 A2 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 73 76 63 A3 52 30 50 30 13 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 31 30 39 A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 32",decode_krb5_cammac,ktest_equal_cammac,k5_free_cammac);
+        ktest_empty_cammac(&ref);
+    }
+
 #ifndef DISABLE_PKINIT
 
     /****************************************************************/
diff --git a/src/tests/asn.1/krb5_encode_test.c b/src/tests/asn.1/krb5_encode_test.c
index 6c142a2..633d8a9 100644
--- a/src/tests/asn.1/krb5_encode_test.c
+++ b/src/tests/asn.1/krb5_encode_test.c
@@ -741,6 +741,16 @@ main(argc, argv)
         encode_run(info, "kkdcp_message", "", encode_krb5_kkdcp_message);
         ktest_empty_kkdcp_message(&info);
     }
+    /* encode_krb5_cammac */
+    {
+        krb5_cammac req;
+        ktest_make_minimal_cammac(&req);
+        encode_run(req, "cammac", "(optionals NULL)", encode_krb5_cammac);
+        ktest_empty_cammac(&req);
+        ktest_make_maximal_cammac(&req);
+        encode_run(req, "cammac", "", encode_krb5_cammac);
+        ktest_empty_cammac(&req);
+    }
 #ifndef DISABLE_PKINIT
     /****************************************************************/
     /* encode_krb5_pa_pk_as_req */
diff --git a/src/tests/asn.1/ktest.c b/src/tests/asn.1/ktest.c
index e4b3764..340b6bd 100644
--- a/src/tests/asn.1/ktest.c
+++ b/src/tests/asn.1/ktest.c
@@ -950,6 +950,65 @@ ktest_make_sample_kkdcp_message(krb5_kkdcp_message *p)
     p->dclocator_hint = 0;
 }
 
+static krb5_authdata *
+make_ad_element(krb5_authdatatype ad_type, const char *str)
+{
+    krb5_authdata *ad;
+
+    ad = ealloc(sizeof(*ad));
+    ad->ad_type = ad_type;
+    ad->length = strlen(str);
+    ad->contents = ealloc(ad->length);
+    memcpy(ad->contents, str, ad->length);
+    return ad;
+}
+
+static krb5_verifier_mac *
+make_vmac(krb5_boolean include_princ, krb5_kvno kvno, krb5_enctype enctype,
+          const char *cksumstr)
+{
+    krb5_verifier_mac *vmac;
+
+    vmac = ealloc(sizeof(*vmac));
+    if (include_princ) {
+        ktest_make_sample_principal(&vmac->princ);
+        (void)krb5_set_principal_realm(NULL, vmac->princ, "");
+    } else {
+        vmac->princ = NULL;
+    }
+    vmac->kvno = kvno;
+    vmac->enctype = enctype;
+    vmac->checksum.checksum_type = 1;
+    vmac->checksum.length = strlen(cksumstr);
+    vmac->checksum.contents = ealloc(vmac->checksum.length);
+    memcpy(vmac->checksum.contents, cksumstr, vmac->checksum.length);
+    return vmac;
+}
+
+void
+ktest_make_minimal_cammac(krb5_cammac *p)
+{
+    memset(p, 0, sizeof(*p));
+    p->elements = ealloc(2 * sizeof(*p->elements));
+    p->elements[0] = make_ad_element(1, "ad1");
+    p->elements[1] = NULL;
+}
+
+void
+ktest_make_maximal_cammac(krb5_cammac *p)
+{
+    p->elements = ealloc(3 * sizeof(*p->elements));
+    p->elements[0] = make_ad_element(1, "ad1");
+    p->elements[1] = make_ad_element(2, "ad2");
+    p->elements[2] = NULL;
+    p->kdc_verifier = make_vmac(TRUE, 5, 16, "cksumkdc");
+    p->svc_verifier = make_vmac(TRUE, 5, 16, "cksumsvc");
+    p->other_verifiers = ealloc(3 * sizeof(*p->other_verifiers));
+    p->other_verifiers[0] = make_vmac(FALSE, 0, 0, "cksum1");
+    p->other_verifiers[1] = make_vmac(TRUE, 5, 16, "cksum2");
+    p->other_verifiers[2] = NULL;
+}
+
 /****************************************************************/
 /* destructors */
 
@@ -1099,6 +1158,8 @@ ktest_destroy_principal(krb5_principal *p)
 {
     int i;
 
+    if (*p == NULL)
+        return;
     for (i=0; i<(*p)->length; i++)
         ktest_empty_data(&(*p)->data[i]);
     ktest_empty_data(&(*p)->realm);
@@ -1755,3 +1816,28 @@ ktest_empty_kkdcp_message(krb5_kkdcp_message *p)
     ktest_empty_data(&p->target_domain);
     p->dclocator_hint = -1;
 }
+
+static void
+destroy_verifier_mac(krb5_verifier_mac **vmac)
+{
+    if (*vmac == NULL)
+        return;
+    ktest_destroy_principal(&(*vmac)->princ);
+    ktest_empty_checksum(&(*vmac)->checksum);
+    free(*vmac);
+    *vmac = NULL;
+}
+
+void
+ktest_empty_cammac(krb5_cammac *p)
+{
+    krb5_verifier_mac **vmacp;
+
+    ktest_destroy_authorization_data(&p->elements);
+    destroy_verifier_mac(&p->kdc_verifier);
+    destroy_verifier_mac(&p->svc_verifier);
+    for (vmacp = p->other_verifiers; vmacp != NULL && *vmacp != NULL; vmacp++)
+        destroy_verifier_mac(vmacp);
+    free(p->other_verifiers);
+    p->other_verifiers = NULL;
+}
diff --git a/src/tests/asn.1/ktest.h b/src/tests/asn.1/ktest.h
index a9ebb77..9c11040 100644
--- a/src/tests/asn.1/ktest.h
+++ b/src/tests/asn.1/ktest.h
@@ -121,6 +121,8 @@ void ktest_make_sample_ldap_seqof_key_data(ldap_seqof_key_data *p);
 #endif
 
 void ktest_make_sample_kkdcp_message(krb5_kkdcp_message *p);
+void ktest_make_minimal_cammac(krb5_cammac *p);
+void ktest_make_maximal_cammac(krb5_cammac *p);
 
 /*----------------------------------------------------------------------*/
 
@@ -204,6 +206,7 @@ void ktest_empty_ldap_seqof_key_data(krb5_context, ldap_seqof_key_data *p);
 #endif
 
 void ktest_empty_kkdcp_message(krb5_kkdcp_message *p);
+void ktest_empty_cammac(krb5_cammac *p);
 
 extern krb5_context test_context;
 extern char *sample_principal_name;
diff --git a/src/tests/asn.1/ktest_equal.c b/src/tests/asn.1/ktest_equal.c
index 39c35b5..7ecdbcd 100644
--- a/src/tests/asn.1/ktest_equal.c
+++ b/src/tests/asn.1/ktest_equal.c
@@ -729,7 +729,7 @@ ktest_equal_array_of_data(int length, krb5_data *ref, krb5_data *var)
 {
     int i,p = TRUE;
 
-    if (ref == var) return TRUE;
+    if (length == 0 || ref == var) return TRUE;
     else if (ref == NULL || var == NULL) return FALSE;
     for (i=0; i<(length); i++) {
         p = p && ktest_equal_data(&(ref[i]),&(var[i]));
@@ -743,7 +743,7 @@ ktest_equal_array_of_octet(unsigned int length, krb5_octet *ref,
 {
     unsigned int i, p = TRUE;
 
-    if (ref == var) return TRUE;
+    if (length == 0 || ref == var) return TRUE;
     else if (ref == NULL || var == NULL) return FALSE;
     for (i=0; i<length; i++)
         p = p && (ref[i] == var[i]);
@@ -755,7 +755,7 @@ ktest_equal_array_of_char(unsigned int length, char *ref, char *var)
 {
     unsigned int i, p = TRUE;
 
-    if (ref == var) return TRUE;
+    if (length == 0 || ref == var) return TRUE;
     else if (ref == NULL || var == NULL) return FALSE;
     for (i=0; i<length; i++)
         p = p && (ref[i] == var[i]);
@@ -767,7 +767,7 @@ ktest_equal_array_of_enctype(int length, krb5_enctype *ref, krb5_enctype *var)
 {
     int i, p = TRUE;
 
-    if (ref == var) return TRUE;
+    if (length == 0 || ref == var) return TRUE;
     else if (ref == NULL || var == NULL) return FALSE;
     for (i=0; i<length; i++)
         p = p && (ref[i] == var[i]);
@@ -1051,3 +1051,35 @@ ktest_equal_kkdcp_message(krb5_kkdcp_message *ref, krb5_kkdcp_message *var)
     p = p && (ref->dclocator_hint == var->dclocator_hint);
     return p;
 }
+
+static int
+vmac_eq(krb5_verifier_mac *ref, krb5_verifier_mac *var)
+{
+    int p = TRUE;
+    if (ref == var) return TRUE;
+    else if (ref == NULL || var == NULL) return FALSE;
+    p = p && ptr_equal(princ, ktest_equal_principal_data);
+    p = p && scalar_equal(kvno);
+    p = p && scalar_equal(enctype);
+    p = p && struct_equal(checksum, ktest_equal_checksum);
+    return p;
+}
+
+static int
+vmac_list_eq(krb5_verifier_mac **ref, krb5_verifier_mac **var)
+{
+    array_compare(vmac_eq);
+}
+
+int
+ktest_equal_cammac(krb5_cammac *ref, krb5_cammac *var)
+{
+    int p = TRUE;
+    if (ref == var) return TRUE;
+    else if (ref == NULL || var == NULL) return FALSE;
+    p = p && ptr_equal(elements, ktest_equal_authorization_data);
+    p = p && ptr_equal(kdc_verifier, vmac_eq);
+    p = p && ptr_equal(svc_verifier, vmac_eq);
+    p = p && ptr_equal(other_verifiers, vmac_list_eq);
+    return p;
+}
diff --git a/src/tests/asn.1/ktest_equal.h b/src/tests/asn.1/ktest_equal.h
index 491653f..6d04246 100644
--- a/src/tests/asn.1/ktest_equal.h
+++ b/src/tests/asn.1/ktest_equal.h
@@ -147,5 +147,6 @@ generic(ktest_equal_reply_key_pack_draft9, krb5_reply_key_pack_draft9);
 
 int ktest_equal_kkdcp_message(krb5_kkdcp_message *ref,
                               krb5_kkdcp_message *var);
+int ktest_equal_cammac(krb5_cammac *ref, krb5_cammac *var);
 
 #endif
diff --git a/src/tests/asn.1/make-vectors.c b/src/tests/asn.1/make-vectors.c
index c5aa5b3..3cb8a45 100644
--- a/src/tests/asn.1/make-vectors.c
+++ b/src/tests/asn.1/make-vectors.c
@@ -28,7 +28,7 @@
  * This program generates test vectors using asn1c, to be included in other
  * test programs which exercise the krb5 ASN.1 encoder and decoder functions.
  * It is intended to be used via "make test-vectors".  Currently, test vectors
- * are only generated for OTP preauth objects.
+ * are only generated for a subset of newer ASN.1 objects.
  */
 
 #include <PrincipalName.h>
@@ -39,6 +39,7 @@
 #include <PA-OTP-CHALLENGE.h>
 #include <PA-OTP-REQUEST.h>
 #include <PA-OTP-ENC-REQUEST.h>
+#include <AD-CAMMAC.h>
 
 static unsigned char buf[8192];
 static size_t buf_pos;
@@ -125,6 +126,48 @@ static PA_OTP_REQUEST_t request_2 = { { "\x60\0\0\0", 4, 0 }, &nonce,
 /* PA-OTP-ENC-REQUEST */
 static PA_OTP_ENC_REQUEST_t enc_request = { { "krb5data", 8 } };
 
+/*
+ * There is no ASN.1 name for a single authorization data element, so asn1c
+ * declares it as "struct Member" in an inner scope.  This structure must be
+ * laid out identically to that one.
+ */
+struct ad_element {
+    Int32_t ad_type;
+    OCTET_STRING_t ad_data;
+    asn_struct_ctx_t _asn_ctx;
+};
+
+/* Authorization data elements and lists, for use in CAMMAC */
+static struct ad_element ad_1 = { 1, { "ad1", 3 } };
+static struct ad_element ad_2 = { 2, { "ad2", 3 } };
+static struct ad_element *adlist_1[] = { &ad_1 };
+static struct ad_element *adlist_2[] = { &ad_1, &ad_2 };
+
+/* Minimal Verifier */
+static Verifier_t verifier_1 = { Verifier_PR_mac,
+                                 { { NULL, NULL, NULL,
+                                     { 1, { "cksum1", 6 } } } } };
+
+/* Maximal Verifier */
+static Int32_t enctype = 16;
+static Verifier_t verifier_2 = { Verifier_PR_mac,
+                                 { { &princ, &kvno, &enctype,
+                                     { 1, { "cksum2", 6 } } } } };
+
+/* Minimal CAMMAC */
+static AD_CAMMAC_t cammac_1 = { { { (void *)adlist_1, 1, 1 } },
+                                NULL, NULL, NULL };
+
+/* Maximal CAMMAC */
+static Verifier_MAC_t vmac_1 = { &princ, &kvno, &enctype,
+                                 { 1, { "cksumkdc", 8 } } };
+static Verifier_MAC_t vmac_2 = { &princ, &kvno, &enctype,
+                                 { 1, { "cksumsvc", 8 } } };
+static Verifier_t *verifiers[] = { &verifier_1, &verifier_2 };
+static struct other_verifiers overfs = { { verifiers, 2, 2 } };
+static AD_CAMMAC_t cammac_2 = { { { (void *)adlist_2, 2, 2 } },
+                                &vmac_1, &vmac_2, &overfs };
+
 static int
 consume(const void *data, size_t size, void *dummy)
 {
@@ -213,6 +256,22 @@ main()
     der_encode(&asn_DEF_PA_OTP_ENC_REQUEST, &enc_request, consume, NULL);
     printbuf();
 
+    printf("\nMinimal Verifier:\n");
+    der_encode(&asn_DEF_Verifier, &verifier_1, consume, NULL);
+    printbuf();
+
+    printf("\nMaximal Verifier:\n");
+    der_encode(&asn_DEF_Verifier, &verifier_2, consume, NULL);
+    printbuf();
+
+    printf("\nMinimal AD-CAMMAC:\n");
+    der_encode(&asn_DEF_AD_CAMMAC, &cammac_1, consume, NULL);
+    printbuf();
+
+    printf("\nMaximal AD-CAMMAC:\n");
+    der_encode(&asn_DEF_AD_CAMMAC, &cammac_2, consume, NULL);
+    printbuf();
+
     printf("\n");
     return 0;
 }
diff --git a/src/tests/asn.1/reference_encode.out b/src/tests/asn.1/reference_encode.out
index b737da3..491fd57 100644
--- a/src/tests/asn.1/reference_encode.out
+++ b/src/tests/asn.1/reference_encode.out
@@ -69,3 +69,5 @@ encode_krb5_pa_otp_req(optionals NULL): 30 2C 80 05 00 00 00 00 00 A2 23 A0 03 0
 encode_krb5_pa_otp_req: 30 81 B9 80 05 00 60 00 00 00 81 05 6E 6F 6E 63 65 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 0B 06 09 60 86 48 01 65 03 04 02 01 84 02 03 E8 85 05 66 72 6F 67 73 86 0A 6D 79 66 69 72 73 74 70 69 6E 87 05 68 61 72 6B 21 88 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 89 03 33 34 36 8A 01 02 8B 09 79 6F 75 72 74 6F 6B 65 6E 8C 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 8D 0B 45 78 61 6D 70 6C 65 63 6F 72 70
 encode_krb5_pa_otp_enc_req: 30 0A 80 08 6B 72 62 35 64 61 74 61
 encode_krb5_kkdcp_message: 30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 98 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 0!
 5 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A1 0A 1B 08 6B 72 62 35 64 61 74 61
+encode_krb5_cammac(optionals NULL): 30 12 A0 10 30 0E 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31
+encode_krb5_cammac: 30 81 F2 A0 1E 30 1C 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31 30 0C A0 03 02 01 02 A1 05 04 03 61 64 32 A1 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 6B 64 63 A2 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 73 76 63 A3 52 30 50 30 13 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 31 30 39 A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 32
diff --git a/src/tests/asn.1/trval_reference.out b/src/tests/asn.1/trval_reference.out
index 599580c..ec3f17c 100644
--- a/src/tests/asn.1/trval_reference.out
+++ b/src/tests/asn.1/trval_reference.out
@@ -1515,3 +1515,60 @@ encode_krb5_kkdcp_message:
       17 04 15 6b 72 62 41 53 4e 2e 31 20 74 65 73 74     ...krbASN.1 test
       20 6d 65 73 73 61 67 65                              message
 .  [1] [General string] "krb5data"
+
+encode_krb5_cammac(optionals NULL):
+
+[Sequence/Sequence Of]
+.  [0] [Sequence/Sequence Of]
+.  .  [Sequence/Sequence Of]
+.  .  .  [0] [Integer] 1
+.  .  .  [1] [Octet String] "ad1"
+
+encode_krb5_cammac:
+
+[Sequence/Sequence Of]
+.  [0] [Sequence/Sequence Of]
+.  .  [Sequence/Sequence Of]
+.  .  .  [0] [Integer] 1
+.  .  .  [1] [Octet String] "ad1"
+.  .  [Sequence/Sequence Of]
+.  .  .  [0] [Integer] 2
+.  .  .  [1] [Octet String] "ad2"
+.  [1] [Sequence/Sequence Of]
+.  .  [0] [Sequence/Sequence Of]
+.  .  .  [0] [Integer] 1
+.  .  .  [1] [Sequence/Sequence Of]
+.  .  .  .  [General string] "hftsai"
+.  .  .  .  [General string] "extra"
+.  .  [1] [Integer] 5
+.  .  [2] [Integer] 16
+.  .  [3] [Sequence/Sequence Of]
+.  .  .  [0] [Integer] 1
+.  .  .  [1] [Octet String] "cksumkdc"
+.  [2] [Sequence/Sequence Of]
+.  .  [0] [Sequence/Sequence Of]
+.  .  .  [0] [Integer] 1
+.  .  .  [1] [Sequence/Sequence Of]
+.  .  .  .  [General string] "hftsai"
+.  .  .  .  [General string] "extra"
+.  .  [1] [Integer] 5
+.  .  [2] [Integer] 16
+.  .  [3] [Sequence/Sequence Of]
+.  .  .  [0] [Integer] 1
+.  .  .  [1] [Octet String] "cksumsvc"
+.  [3] [Sequence/Sequence Of]
+.  .  [Sequence/Sequence Of]
+.  .  .  [3] [Sequence/Sequence Of]
+.  .  .  .  [0] [Integer] 1
+.  .  .  .  [1] [Octet String] "cksum1"
+.  .  [Sequence/Sequence Of]
+.  .  .  [0] [Sequence/Sequence Of]
+.  .  .  .  [0] [Integer] 1
+.  .  .  .  [1] [Sequence/Sequence Of]
+.  .  .  .  .  [General string] "hftsai"
+.  .  .  .  .  [General string] "extra"
+.  .  .  [1] [Integer] 5
+.  .  .  [2] [Integer] 16
+.  .  .  [3] [Sequence/Sequence Of]
+.  .  .  .  [0] [Integer] 1
+.  .  .  .  [1] [Octet String] "cksum2"


More information about the cvs-krb5 mailing list