krb5 commit: Add PAC full checksums

ghudson at mit.edu ghudson at mit.edu
Tue Jan 24 03:02:54 EST 2023


https://github.com/krb5/krb5/commit/4602a10dbe380d75d1ec00f7d34479ac9d503735
commit 4602a10dbe380d75d1ec00f7d34479ac9d503735
Author: Greg Hudson <ghudson at mit.edu>
Date:   Thu Dec 22 03:05:23 2022 -0500

    Add PAC full checksums
    
    A paper by Tom Tervoort noted that computing the PAC privsvr checksum
    over only the server checksum is vulnerable to collision attacks
    (CVE-2022-37967).  In response, Microsoft has added a second KDC
    checksum over the full contents of the PAC.  Generate and verify full
    KDC checksums in PACs for service tickets.  Update the t_pac.c ticket
    test case to use a ticket issued by a recent version of Active
    Directory (provided by Stefan Metzmacher).
    
    ticket: 9084 (new)

 doc/appdev/refs/macros/index.rst |   1 +
 src/include/krb5/krb5.hin        |   1 +
 src/lib/krb5/krb/pac.c           |  92 +++++++++++----------
 src/lib/krb5/krb/pac_sign.c      | 146 +++++++++++++++++++--------------
 src/lib/krb5/krb/t_pac.c         | 171 +++++++++++++++++++++++----------------
 src/tests/t_authdata.py          |   4 +-
 6 files changed, 240 insertions(+), 175 deletions(-)

diff --git a/doc/appdev/refs/macros/index.rst b/doc/appdev/refs/macros/index.rst
index a0d4f2670..db9891838 100644
--- a/doc/appdev/refs/macros/index.rst
+++ b/doc/appdev/refs/macros/index.rst
@@ -248,6 +248,7 @@ Public
    KRB5_PAC_SERVER_CHECKSUM.rst
    KRB5_PAC_TICKET_CHECKSUM.rst
    KRB5_PAC_UPN_DNS_INFO.rst
+   KRB5_PAC_FULL_CHECKSUM.rst
    KRB5_PADATA_AFS3_SALT.rst
    KRB5_PADATA_AP_REQ.rst
    KRB5_PADATA_AS_CHECKSUM.rst
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index c0194c3c9..c89b7405b 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -8158,6 +8158,7 @@ krb5_verify_authdata_kdc_issued(krb5_context context,
 #define KRB5_PAC_TICKET_CHECKSUM   16 /**< Ticket checksum */
 #define KRB5_PAC_ATTRIBUTES_INFO   17 /**< PAC attributes */
 #define KRB5_PAC_REQUESTOR         18 /**< PAC requestor SID */
+#define KRB5_PAC_FULL_CHECKSUM     19 /**< KDC full checksum */
 
 struct krb5_pac_data;
 /** PAC data structure to convey authorization information */
diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
index f6c4373de..954482e0c 100644
--- a/src/lib/krb5/krb/pac.c
+++ b/src/lib/krb5/krb/pac.c
@@ -490,7 +490,8 @@ zero_signature(krb5_context context, const krb5_pac pac, krb5_ui_4 type,
     size_t i;
 
     assert(type == KRB5_PAC_SERVER_CHECKSUM ||
-           type == KRB5_PAC_PRIVSVR_CHECKSUM);
+           type == KRB5_PAC_PRIVSVR_CHECKSUM ||
+           type == KRB5_PAC_FULL_CHECKSUM);
     assert(data->length >= pac->data.length);
 
     for (i = 0; i < pac->pac->cBuffers; i++) {
@@ -557,17 +558,17 @@ verify_checksum(krb5_context context, const krb5_pac pac, uint32_t buffer_type,
 }
 
 static krb5_error_code
-verify_server_checksum(krb5_context context, const krb5_pac pac,
-                       const krb5_keyblock *server)
+verify_pac_checksums(krb5_context context, const krb5_pac pac,
+                     krb5_boolean expect_full_checksum,
+                     const krb5_keyblock *server, const krb5_keyblock *privsvr)
 {
     krb5_error_code ret;
-    krb5_data copy;             /* PAC with zeroed checksums */
+    krb5_data copy, server_checksum;
 
+    /* Make a copy of the PAC with zeroed out server and privsvr checksums. */
     ret = krb5int_copy_data_contents(context, &pac->data, &copy);
     if (ret)
         return ret;
-
-    /* Zero out both checksum buffers */
     ret = zero_signature(context, pac, KRB5_PAC_SERVER_CHECKSUM, &copy);
     if (ret)
         goto cleanup;
@@ -575,32 +576,46 @@ verify_server_checksum(krb5_context context, const krb5_pac pac,
     if (ret)
         goto cleanup;
 
-    ret = verify_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM, server,
-                          KRB5_KEYUSAGE_APP_DATA_CKSUM, &copy);
+    if (server != NULL) {
+        /* Verify the server checksum over the PAC copy. */
+        ret = verify_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM, server,
+                              KRB5_KEYUSAGE_APP_DATA_CKSUM, &copy);
+    }
 
-cleanup:
-    free(copy.data);
-    return ret;
-}
+    if (privsvr != NULL && expect_full_checksum) {
+        /* Zero the full checksum buffer in the copy and verify the full
+         * checksum over the copy with all three checksums zeroed. */
+        ret = zero_signature(context, pac, KRB5_PAC_FULL_CHECKSUM, &copy);
+        if (ret)
+            goto cleanup;
+        ret = verify_checksum(context, pac, KRB5_PAC_FULL_CHECKSUM, privsvr,
+                              KRB5_KEYUSAGE_APP_DATA_CKSUM, &copy);
+        if (ret)
+            goto cleanup;
+    }
 
-static krb5_error_code
-verify_kdc_checksum(krb5_context context, const krb5_pac pac,
-                    const krb5_keyblock *privsvr)
-{
-    krb5_error_code ret;
-    krb5_data server_checksum;
+    if (privsvr != NULL) {
+        /* Verify the privsvr checksum over the server checksum. */
+        ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_SERVER_CHECKSUM,
+                                   &server_checksum);
+        if (ret)
+            return ret;
+        if (server_checksum.length < PAC_SIGNATURE_DATA_LENGTH)
+            return KRB5_BAD_MSIZE;
+        server_checksum.data += PAC_SIGNATURE_DATA_LENGTH;
+        server_checksum.length -= PAC_SIGNATURE_DATA_LENGTH;
 
-    ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_SERVER_CHECKSUM,
-                               &server_checksum);
-    if (ret)
-        return ret;
-    if (server_checksum.length < PAC_SIGNATURE_DATA_LENGTH)
-        return KRB5_BAD_MSIZE;
-    server_checksum.data += PAC_SIGNATURE_DATA_LENGTH;
-    server_checksum.length -= PAC_SIGNATURE_DATA_LENGTH;
+        ret = verify_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM, privsvr,
+                              KRB5_KEYUSAGE_APP_DATA_CKSUM, &server_checksum);
+        if (ret)
+            goto cleanup;
+    }
+
+    pac->verified = TRUE;
 
-    return verify_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM, privsvr,
-                           KRB5_KEYUSAGE_APP_DATA_CKSUM, &server_checksum);
+cleanup:
+    free(copy.data);
+    return ret;
 }
 
 /* Per MS-PAC 2.8.3, tickets encrypted to TGS and password change principals
@@ -628,6 +643,7 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
     krb5_authdata **authdata, *orig, **ifrel = NULL, **recoded_ifrel = NULL;
     uint8_t z = 0;
     krb5_authdata zpac = { KV5M_AUTHDATA, KRB5_AUTHDATA_WIN2K_PAC, 1, &z };
+    krb5_boolean is_service_tkt;
     size_t i, j;
 
     *pac_out = NULL;
@@ -669,7 +685,8 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
     if (ret)
         goto cleanup;
 
-    if (privsvr != NULL && k5_pac_should_have_ticket_signature(server_princ)) {
+    is_service_tkt = k5_pac_should_have_ticket_signature(server_princ);
+    if (privsvr != NULL && is_service_tkt) {
         /* To check the PAC ticket signatures, re-encode the ticket with the
          * PAC contents replaced by a single zero. */
         orig = ifrel[j];
@@ -693,8 +710,9 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
             goto cleanup;
     }
 
-    ret = krb5_pac_verify_ext(context, pac, enc_tkt->times.authtime, NULL,
-                              server, privsvr, FALSE);
+    ret = verify_pac_checksums(context, pac, is_service_tkt, server, privsvr);
+    if (ret)
+        goto cleanup;
 
     *pac_out = pac;
     pac = NULL;
@@ -730,14 +748,8 @@ krb5_pac_verify_ext(krb5_context context,
 {
     krb5_error_code ret;
 
-    if (server != NULL) {
-        ret = verify_server_checksum(context, pac, server);
-        if (ret != 0)
-            return ret;
-    }
-
-    if (privsvr != NULL) {
-        ret = verify_kdc_checksum(context, pac, privsvr);
+    if (server != NULL || privsvr != NULL) {
+        ret = verify_pac_checksums(context, pac, FALSE, server, privsvr);
         if (ret != 0)
             return ret;
     }
@@ -749,8 +761,6 @@ krb5_pac_verify_ext(krb5_context context,
             return ret;
     }
 
-    pac->verified = TRUE;
-
     return 0;
 }
 
diff --git a/src/lib/krb5/krb/pac_sign.c b/src/lib/krb5/krb/pac_sign.c
index 0f9581abb..8ea61ac17 100644
--- a/src/lib/krb5/krb/pac_sign.c
+++ b/src/lib/krb5/krb/pac_sign.c
@@ -187,26 +187,41 @@ k5_pac_encode_header(krb5_context context, krb5_pac pac)
     return 0;
 }
 
-krb5_error_code KRB5_CALLCONV
-krb5_pac_sign(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
-              krb5_const_principal principal, const krb5_keyblock *server_key,
-              const krb5_keyblock *privsvr_key, krb5_data *data)
+/* Find the buffer of type buftype in pac and write within it a checksum of
+ * type cksumtype over data.  Set *cksum_out to the checksum. */
+static krb5_error_code
+compute_pac_checksum(krb5_context context, krb5_pac pac, uint32_t buftype,
+                     const krb5_keyblock *key, krb5_cksumtype cksumtype,
+                     const krb5_data *data, krb5_data *cksum_out)
 {
-    return krb5_pac_sign_ext(context, pac, authtime, principal, server_key,
-                             privsvr_key, FALSE, data);
+    krb5_error_code ret;
+    krb5_data buf;
+    krb5_crypto_iov iov[2];
+
+    ret = k5_pac_locate_buffer(context, pac, buftype, &buf);
+    if (ret)
+        return ret;
+
+    assert(buf.length > PAC_SIGNATURE_DATA_LENGTH);
+    *cksum_out = make_data(buf.data + PAC_SIGNATURE_DATA_LENGTH,
+                           buf.length - PAC_SIGNATURE_DATA_LENGTH);
+    iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+    iov[0].data = *data;
+    iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+    iov[1].data = *cksum_out;
+    return krb5_c_make_checksum_iov(context, cksumtype, key,
+                                    KRB5_KEYUSAGE_APP_DATA_CKSUM, iov, 2);
 }
 
-krb5_error_code KRB5_CALLCONV
-krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
-                  krb5_const_principal principal,
-                  const krb5_keyblock *server_key,
-                  const krb5_keyblock *privsvr_key, krb5_boolean with_realm,
-                  krb5_data *data)
+static krb5_error_code
+sign_pac(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
+         krb5_const_principal principal, const krb5_keyblock *server_key,
+         const krb5_keyblock *privsvr_key, krb5_boolean with_realm,
+         krb5_boolean is_service_tkt, krb5_data *data)
 {
     krb5_error_code ret;
-    krb5_data server_cksum, privsvr_cksum;
+    krb5_data full_cksum, server_cksum, privsvr_cksum;
     krb5_cksumtype server_cksumtype, privsvr_cksumtype;
-    krb5_crypto_iov iov[2];
 
     data->length = 0;
     data->data = NULL;
@@ -214,67 +229,53 @@ krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
     if (principal != NULL) {
         ret = k5_insert_client_info(context, pac, authtime, principal,
                                     with_realm);
-        if (ret != 0)
+        if (ret)
             return ret;
     }
 
-    /* Create zeroed buffers for both checksums */
+    /* Create zeroed buffers for all checksums. */
     ret = k5_insert_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM,
                              server_key, &server_cksumtype);
-    if (ret != 0)
+    if (ret)
         return ret;
-
     ret = k5_insert_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM,
                              privsvr_key, &privsvr_cksumtype);
-    if (ret != 0)
+    if (ret)
         return ret;
+    if (is_service_tkt) {
+        ret = k5_insert_checksum(context, pac, KRB5_PAC_FULL_CHECKSUM,
+                                 privsvr_key, &privsvr_cksumtype);
+        if (ret)
+            return ret;
+    }
 
-    /* Now, encode the PAC header so that the checksums will include it */
+    /* Encode the PAC header so that the checksums will include it. */
     ret = k5_pac_encode_header(context, pac);
-    if (ret != 0)
-        return ret;
-
-    /* Generate the server checksum over the entire PAC */
-    ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_SERVER_CHECKSUM,
-                               &server_cksum);
-    if (ret != 0)
+    if (ret)
         return ret;
 
-    assert(server_cksum.length > PAC_SIGNATURE_DATA_LENGTH);
-
-    iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
-    iov[0].data = pac->data;
-
-    iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
-    iov[1].data.data = server_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
-    iov[1].data.length = server_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
+    if (is_service_tkt) {
+        /* Generate a full KDC checksum over the whole PAC. */
+        ret = compute_pac_checksum(context, pac, KRB5_PAC_FULL_CHECKSUM,
+                                   privsvr_key, privsvr_cksumtype,
+                                   &pac->data, &full_cksum);
+        if (ret)
+            return ret;
+    }
 
-    ret = krb5_c_make_checksum_iov(context, server_cksumtype,
-                                   server_key, KRB5_KEYUSAGE_APP_DATA_CKSUM,
-                                   iov, sizeof(iov)/sizeof(iov[0]));
-    if (ret != 0)
+    /* Generate the server checksum over the whole PAC, including the full KDC
+     * checksum if we added one. */
+    ret = compute_pac_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM,
+                               server_key, server_cksumtype, &pac->data,
+                               &server_cksum);
+    if (ret)
         return ret;
 
-    /* Generate the privsvr checksum over the server checksum buffer */
-    ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM,
+    /* Generate the privsvr checksum over the server checksum buffer. */
+    ret = compute_pac_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM,
+                               privsvr_key, privsvr_cksumtype, &server_cksum,
                                &privsvr_cksum);
-    if (ret != 0)
-        return ret;
-
-    assert(privsvr_cksum.length > PAC_SIGNATURE_DATA_LENGTH);
-
-    iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
-    iov[0].data.data = server_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
-    iov[0].data.length = server_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
-
-    iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
-    iov[1].data.data = privsvr_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
-    iov[1].data.length = privsvr_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
-
-    ret = krb5_c_make_checksum_iov(context, privsvr_cksumtype,
-                                   privsvr_key, KRB5_KEYUSAGE_APP_DATA_CKSUM,
-                                   iov, sizeof(iov)/sizeof(iov[0]));
-    if (ret != 0)
+    if (ret)
         return ret;
 
     data->data = k5memdup(pac->data.data, pac->data.length, &ret);
@@ -288,6 +289,26 @@ krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
     return 0;
 }
 
+krb5_error_code KRB5_CALLCONV
+krb5_pac_sign(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
+              krb5_const_principal principal, const krb5_keyblock *server_key,
+              const krb5_keyblock *privsvr_key, krb5_data *data)
+{
+    return sign_pac(context, pac, authtime, principal, server_key,
+                    privsvr_key, FALSE, FALSE, data);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
+                  krb5_const_principal principal,
+                  const krb5_keyblock *server_key,
+                  const krb5_keyblock *privsvr_key, krb5_boolean with_realm,
+                  krb5_data *data)
+{
+    return sign_pac(context, pac, authtime, principal, server_key, privsvr_key,
+                    with_realm, FALSE, data);
+}
+
 /* Add a signature over der_enc_tkt in privsvr to pac.  der_enc_tkt should be
  * encoded with a dummy PAC authdata element containing a single zero byte. */
 static krb5_error_code
@@ -359,6 +380,7 @@ krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part *enc_tkt,
     krb5_error_code ret;
     krb5_data *der_enc_tkt = NULL, pac_data = empty_data();
     krb5_authdata **list, *pac_ad;
+    krb5_boolean is_service_tkt;
     size_t count;
 
     /* Reallocate space for another authdata element in enc_tkt. */
@@ -377,7 +399,8 @@ krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part *enc_tkt,
     memmove(list + 1, list, (count + 1) * sizeof(*list));
     list[0] = pac_ad;
 
-    if (k5_pac_should_have_ticket_signature(server_princ)) {
+    is_service_tkt = k5_pac_should_have_ticket_signature(server_princ);
+    if (is_service_tkt) {
         ret = encode_krb5_enc_tkt_part(enc_tkt, &der_enc_tkt);
         if (ret)
             goto cleanup;
@@ -388,9 +411,8 @@ krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part *enc_tkt,
             goto cleanup;
     }
 
-    ret = krb5_pac_sign_ext(context, pac, enc_tkt->times.authtime,
-                            client_princ, server, privsvr, with_realm,
-                            &pac_data);
+    ret = sign_pac(context, pac, enc_tkt->times.authtime, client_princ, server,
+                   privsvr, with_realm, is_service_tkt, &pac_data);
     if (ret)
         goto cleanup;
 
diff --git a/src/lib/krb5/krb/t_pac.c b/src/lib/krb5/krb/t_pac.c
index 173bde7ba..81f1642ab 100644
--- a/src/lib/krb5/krb/t_pac.c
+++ b/src/lib/krb5/krb/t_pac.c
@@ -607,78 +607,102 @@ check_pac(krb5_context context, int index, const unsigned char *pdata,
 
 static const krb5_keyblock ticket_sig_krbtgt_key = {
     0, ENCTYPE_AES256_CTS_HMAC_SHA1_96,
-    32, U("\x7a\x58\x98\xd2\xaf\xa6\xaf\xc0\x6a\xce\x06\x04\x4b\xc2\x70\x84"
-          "\x9b\x8e\x0a\x6c\x4c\x07\xdc\x6f\xbb\x48\x43\xe1\xd2\xaa\x97\xf7")
+    32, U("\x03\x73\x81\xEC\x43\x96\x7B\xC2\xAC\x3D\xF5\x2A\xAE\x95\xA6\x8E"
+          "\xBE\x24\x58\xDB\xCE\x52\x28\x20\xAF\x5E\xB7\x04\xA2\x22\x71\x4F")
 };
 
 static const krb5_keyblock ticket_sig_server_key = {
-    0, ENCTYPE_ARCFOUR_HMAC,
-    16, U("\xed\x23\x11\x20\x7a\x21\x44\x20\xbf\xc0\x8d\x36\xf7\xf6\xb2\x3e")
+    0, ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+    32, U("\x11\x4A\x84\xE3\x14\x8F\xAA\xB1\xFA\x7B\x53\x51\xB2\x8A\xC2\xF1"
+          "\xFD\x19\x6D\x61\xE0\xF3\xF2\x3E\x1F\xDB\xD3\xC1\x79\x7D\xC1\xEE")
 };
 
+/* A ticket issued by an Active Directory KDC (Windows Server 2022), containing
+ * a PAC with a full checksum. */
 static const krb5_data ticket_data = {
-    .length = 972, .data =
-    "\x61\x82\x03\xC8\x30\x82\x03\xC4\xA0\x03\x02\x01\x05\xA1\x0A\x1B"
-    "\x08\x43\x44\x4F\x4D\x2E\x43\x4F\x4D\xA2\x0F\x30\x0D\xA0\x03\x02"
-    "\x01\x01\xA1\x06\x30\x04\x1B\x02\x73\x31\xA3\x82\x03\x9E\x30\x82"
-    "\x03\x9A\xA0\x03\x02\x01\x17\xA1\x03\x02\x01\x03\xA2\x82\x03\x8C"
-    "\x04\x82\x03\x88\x44\x31\x61\x20\x17\xC9\xFE\xBC\xAC\x46\xB5\x77"
-    "\xE9\x68\x04\x4C\x9B\x31\x91\x0C\xC1\xD4\xDD\xEF\xC7\x34\x20\x08"
-    "\x90\x91\xE8\x79\xE0\xB5\x03\x26\xA4\x65\xDE\xEC\x47\x03\x2A\x8F"
-    "\x61\xE7\x4D\x38\x5A\x42\x95\x5A\xF9\x2F\x41\x2C\x2A\x6E\x60\xA1"
-    "\xEB\x51\xB3\xBD\x4C\x00\x41\x2A\x44\x76\x08\x37\x1A\x51\xFD\x65"
-    "\x67\x7E\xBF\x3D\x90\x86\xE3\x9A\x54\x6B\x67\xA8\x08\x7A\x73\xCC"
-    "\xC3\xB7\x4B\xD5\x5C\x3A\x14\x6C\xC1\x5F\x54\x4B\x92\x55\xB4\xB7"
-    "\x92\x23\x3F\x53\x89\x47\x8E\x1F\x8B\xB9\xDB\x3B\x93\xE8\x70\xE4"
-    "\x24\xB8\x9D\xF0\x0E\x35\x28\xF8\x7A\x27\x5D\xF7\x25\x97\x9C\xF5"
-    "\x9F\x9F\x64\x04\xF2\xA3\xAB\x11\x15\xB6\xDA\x18\xD6\x46\xD5\xE6"
-    "\xB8\x08\xDE\x0A\x62\xFD\xF8\xAA\x52\x90\xD9\x67\x29\xB2\xCD\x06"
-    "\xB6\xB0\x50\x2B\x3F\x0F\xA3\xA5\xBF\xAA\x6E\x40\x03\xD6\x5F\x02"
-    "\xBC\xD8\x18\x47\x97\x09\xD7\xE4\x96\x3B\xCB\xEB\x92\x2C\x3C\x49"
-    "\xFF\x1F\x71\xE0\x52\x94\x0F\x8B\x9F\xB8\x2A\xBB\x9C\xE2\xA3\xDD"
-    "\x38\x89\xE2\xB1\x0B\x9E\x1F\x7A\xB3\xE3\xD2\xB0\x94\xDC\x87\xBE"
-    "\x37\xA6\xD3\xB3\x29\x35\x9A\x72\xC3\x7A\xF1\xA9\xE6\xC5\xD1\x26"
-    "\x83\x65\x44\x17\xBA\x55\xA8\x5E\x94\x26\xED\xE9\x8A\x93\x11\x5D"
-    "\x7E\x20\x1B\x9C\x15\x9E\x13\x37\x03\x4D\xDD\x99\x51\xD8\x66\x29"
-    "\x6A\xB9\xFB\x49\xFE\x52\x78\xDA\x86\x85\xA9\xA3\xB9\xEF\xEC\xAD"
-    "\x35\xA6\x8D\xAC\x0F\x75\x22\xBB\x0B\x49\x1C\x13\x52\x40\xC9\x52"
-    "\x69\x09\x54\xD1\x0F\x94\x3F\x22\x48\x67\xB0\x96\x28\xAA\xE6\x28"
-    "\xD9\x0C\x08\xEF\x51\xED\x15\x5E\xA2\x53\x59\xA5\x03\xB4\x06\x20"
-    "\x3D\xCC\xB4\xC5\xF8\x8C\x73\x67\xA3\x21\x3D\x19\xCD\xD4\x12\x28"
-    "\xD2\x93\xDE\x0D\xF0\x71\x10\x50\xD6\x33\x35\x04\x11\x64\x43\x39"
-    "\xC3\xDF\x96\xE3\x66\xE3\x85\xCA\xE7\x67\x14\x3A\xF0\x43\xAA\xBB"
-    "\xD4\x1D\xB5\x24\xB5\x74\x90\x25\xA7\x87\x7E\xDB\xD3\x83\x8A\x3A"
-    "\x69\xA8\x2D\xAF\xB7\xB8\xF3\xDC\x13\xAF\x45\x61\x3F\x59\x39\x7E"
-    "\x69\xDE\x0C\x04\xF1\x10\x6B\xB4\x56\xFA\x21\x9F\x72\x2B\x60\x86"
-    "\xE3\x23\x0E\xC4\x51\xF6\xBE\xD8\xE1\x5F\xEE\x73\x4C\x17\x4C\x2C"
-    "\x1B\xFB\x9F\x1F\x7A\x3B\x07\x5B\x8E\xF1\x01\xAC\xD6\x30\x94\x8A"
-    "\x5D\x22\x6F\x08\xCE\xED\x5E\xB6\xDB\x86\x8C\x87\xEB\x8D\x91\xFF"
-    "\x0A\x86\x30\xBD\xC0\xF8\x25\xE7\xAE\x24\x35\xF2\xFC\xE5\xFD\x1B"
-    "\xB0\x05\x4A\xA3\xE5\xEB\x2E\x05\xAD\x99\x67\x49\x87\xE6\xB3\x87"
-    "\x82\xA4\x59\xA7\x6E\xDD\xF2\xB6\x66\xE8\xF7\x70\xF5\xBD\xC9\x0E"
-    "\xFA\x9C\x79\x84\xD4\x9B\x05\x0E\xBB\xF5\xDB\xEF\xFC\xCC\x26\xF2"
-    "\x93\xCF\xD2\x04\x3C\xA9\x2C\x65\x42\x97\x86\xD8\x38\x0A\x1E\xF6"
-    "\xD6\xCA\x30\xB5\x1A\xEC\xFB\xBA\x3B\x84\x57\xB0\xFD\xFB\xE6\xBC"
-    "\xF2\x76\xF6\x4C\xBB\xAB\xB1\x31\xA1\x27\x7C\xE6\xE6\x81\xB6\xCE"
-    "\x84\x86\x40\xB6\x40\x33\xC4\xF8\xB4\x15\xCF\xAA\xA5\x51\x78\xB9"
-    "\x8B\x50\x25\xB2\x88\x86\x96\x72\x8C\x71\x4D\xB5\x3A\x94\x86\x77"
-    "\x0E\x95\x9B\x16\x93\xEF\x3A\x11\x79\xBA\x83\xF7\x74\xD3\x8D\xBA"
-    "\x15\xE1\x2C\x04\x57\xA8\x92\x1E\x9D\x00\x8E\x20\xFD\x30\x70\xE7"
-    "\xF5\x65\x2F\x19\x0C\x94\xBA\x03\x71\x12\x96\xCD\xC8\xB4\x96\xDB"
-    "\xCE\x19\xC2\xDF\x3C\xC2\xF6\x3D\x53\xED\x98\xA5\x41\x72\x2A\x22"
-    "\x7B\xF3\x2B\x17\x6C\xE1\x39\x7D\xAE\x9B\x11\xF9\xC1\xA6\x9E\x9F"
-    "\x89\x3C\x12\xAA\x94\x74\xA7\x4F\x70\xE8\xB9\xDE\x04\xF0\x9D\x39"
-    "\x24\x2D\x92\xE8\x46\x2D\x2E\xF0\x40\x66\x1A\xD9\x27\xF9\x98\xF1"
-    "\x81\x1D\x70\x62\x63\x30\x6D\xCD\x84\x04\x5F\xFA\x83\xD3\xEC\x8D"
-    "\x86\xFB\x40\x61\xC1\x8A\x45\xFF\x7B\xD9\xD4\x18\x61\x7F\x51\xE3"
-    "\xFC\x1E\x18\xF0\xAF\xC6\x18\x2C\xE1\x6D\x5D\xF9\x62\xFC\x20\xA3"
-    "\xB2\x8A\x5F\xE5\xBB\x29\x0F\x99\x63\x07\x88\x38\x3A\x3B\x73\x2A"
-    "\x6D\xDA\x3D\xA8\x0D\x8F\x56\x41\x89\x82\xE5\xB8\x61\x00\x64\x7D"
-    "\x17\x0C\xCE\x03\x55\x8F\xF4\x5B\x0D\x50\xF2\xEB\x05\x67\xBE\xDB"
-    "\x7B\x75\xC5\xEA\xA1\xAB\x1D\xB0\x3C\x6D\x42\x08\x0B\x9A\x45\x20"
-    "\xA8\x8F\xE5\x67\x47\x30\xDE\x93\x5F\x43\x05\xEB\xA8\x2D\x80\xF5"
-    "\x1A\xB8\x4A\x4E\x42\x2D\x0B\x7A\xDC\x46\x20\x2D\x13\x17\xDD\x4B"
-    "\x94\x96\xAA\x1F\x06\x0C\x1F\x62\x07\x9C\x40\xA1"
+    .length = 1307, .data =
+    "\x61\x82\x05\x17\x30\x82\x05\x13\xA0\x03\x02\x01\x05\xA1\x0F\x1B"
+    "\x0D\x57\x32\x30\x32\x32\x2D\x4C\x37\x2E\x42\x41\x53\x45\xA2\x2A"
+    "\x30\x28\xA0\x03\x02\x01\x01\xA1\x21\x30\x1F\x1B\x04\x63\x69\x66"
+    "\x73\x1B\x17\x77\x32\x30\x32\x32\x2D\x31\x31\x38\x2E\x77\x32\x30"
+    "\x32\x32\x2D\x6C\x37\x2E\x62\x61\x73\x65\xA3\x82\x04\xCD\x30\x82"
+    "\x04\xC9\xA0\x03\x02\x01\x12\xA1\x03\x02\x01\x05\xA2\x82\x04\xBB"
+    "\x04\x82\x04\xB7\x44\x5C\x7B\x5A\x3F\x2E\xA3\x50\x34\xDE\xB0\x69"
+    "\x23\x2D\x47\x89\x2C\xC0\xA3\xF9\xDD\x70\xAA\xA5\x1E\xFE\x74\xE5"
+    "\x19\xA2\x4F\x65\x6C\x9E\x00\xB4\x60\x00\x7C\x0C\x29\x43\x31\x99"
+    "\x77\x02\x73\xED\xB9\x40\xF5\xD2\xD1\xC9\x20\x0F\xE3\x38\xF9\xCC"
+    "\x5E\x2A\xBD\x1F\x91\x66\x1A\xD8\x2A\x80\x3C\x2C\x00\x3C\x1E\xC9"
+    "\x2A\x29\x19\x19\x96\x18\x54\x03\x97\x8F\x1D\x5F\xDB\xE9\x66\x68"
+    "\xCD\xB1\xD5\x00\x35\x69\x49\x45\xF1\x6A\x78\x7B\x37\x71\x87\x14"
+    "\x1C\x98\x4D\x69\xCB\x1B\xD8\xF5\xA3\xD8\x53\x4A\x75\x76\x62\xBA"
+    "\x6C\x3F\xEA\x8B\x97\x21\xCA\x8A\x46\x4B\x38\xDA\x09\x9F\x5A\xC8"
+    "\x38\xFF\x34\x97\x5B\xA2\xE5\xBA\xC9\x87\x17\xD8\x08\x05\x7A\x83"
+    "\x04\xD6\x02\x8E\x9B\x18\xB6\x40\x1A\xF7\x47\x25\x24\x3E\x37\x1E"
+    "\xF6\xC1\x3A\x1F\xCA\xB3\x43\x5A\xAE\x94\x83\x31\xAF\xFB\xEE\xED"
+    "\x46\x71\xEF\xE2\x37\x37\x15\xFE\x1B\x0B\x9E\xF8\x3E\x0C\x43\x96"
+    "\xB6\x0A\x04\x78\xF8\x5E\xAA\x33\x1F\xE2\x07\x5A\x8D\xC4\x4E\x32"
+    "\x6D\xD6\xA0\xC5\xEA\x3D\x12\x59\xD4\x41\x40\x4E\xA1\xD8\xBE\xED"
+    "\x17\xCB\x68\xCC\x59\xCB\x53\xB2\x0E\x58\x8A\xA9\x33\x7F\x6F\x2B"
+    "\x37\x89\x08\x44\xBA\xC7\x67\x17\xBB\x91\xF7\xC3\x0F\x00\xF8\xAA"
+    "\xA1\x33\xA6\x08\x47\xCA\xFA\xE8\x49\x27\x45\x46\xF1\xC1\xC3\x5F"
+    "\xE2\x45\x0A\x7D\x64\x52\x8C\x2E\xE1\xDE\xFF\xB2\x64\xEC\x69\x98"
+    "\x15\xDF\x9E\xB1\xEB\xD6\x9D\x08\x06\x4E\x73\xC1\x0B\x71\x21\x05"
+    "\x9E\xBC\xA2\x17\xCF\xB3\x70\xF4\xEF\xB8\x69\xA9\x94\x27\xFD\x5E"
+    "\x72\xB1\x2D\xD2\x20\x1B\x57\x80\xAB\x38\x97\xCF\x22\x68\x4F\xB8"
+    "\xB7\x17\x53\x25\x67\x0B\xED\xD1\x58\x20\x0D\x45\xF9\x09\xFA\xE7"
+    "\x61\x3E\xDB\xC2\x59\x7B\x3A\x3B\x59\x81\x51\xAA\xA4\x81\xF4\x96"
+    "\x3B\xE1\x6F\x6F\xF4\x8E\x68\x9E\xBA\x1E\x0F\xF2\x44\x68\x11\xFC"
+    "\x2B\x5F\xBE\xF2\xEA\x07\x80\xB9\xCA\x9E\x41\xBD\x2F\x81\xF5\x11"
+    "\x2A\x12\xF3\x4F\xD6\x12\x16\x0F\x21\x90\xF1\xD3\x1E\xF1\xA4\x94"
+    "\x46\xEA\x30\xF3\x84\x06\xC1\xA4\x51\xFC\x43\x35\xBD\xEF\x4D\x89"
+    "\x1D\xA5\x44\xB2\x69\xC4\x0F\xBF\x86\x01\x08\x44\x77\xD5\xB4\xB7"
+    "\x5C\x3F\xA7\xD4\x2F\x39\x73\x85\x88\xEE\xB1\x64\x1D\x80\x6C\xEE"
+    "\x6E\x31\x90\x92\x0D\xA1\xB7\xC4\x5C\xCC\xEE\x91\xC8\xCB\x11\x2D"
+    "\x4A\x1A\x7D\x43\x8F\xEB\x60\x09\xED\x1B\x07\x58\xBE\xBC\xBD\x29"
+    "\xF3\xB3\xA3\x4F\xC5\x8A\x30\x33\xB9\xA9\x9F\x43\x08\x27\x15\xC4"
+    "\x9C\x5D\x8E\xBD\x5C\x05\xC6\x05\x9C\x87\x60\x08\x1E\xE2\x52\xB8"
+    "\x45\x8D\x28\xB6\x2C\x15\x46\x74\x9F\x0E\xAA\x6B\x70\x3A\x2A\x55"
+    "\x45\x26\xB2\x58\x4D\x35\xA6\xF1\x96\xBE\x60\xB2\x71\x7B\xF8\x54"
+    "\xB9\x90\x21\x8E\xB9\x0F\x35\x98\x5E\x88\xEB\x1A\x53\xB4\x59\x7F"
+    "\xAF\x69\x1C\x61\x67\xF4\xF6\xBD\xAC\x24\xCD\xB7\xA9\x67\xE8\xA1"
+    "\x83\x85\x5F\x11\x74\x1F\xF7\x4C\x78\x36\xEF\x50\x74\x88\x58\x4B"
+    "\x1A\x9F\x84\x9A\x9A\x05\x92\xEC\x1D\xD5\xF3\xC4\x95\x51\x28\xE2"
+    "\x3F\x32\x87\xB2\xFD\x21\x27\x66\xE4\x6B\x85\x2F\xDC\x7B\xC0\x22"
+    "\xEB\x7A\x94\x20\x5A\x7B\xD3\x7A\xB9\x5B\xF8\x1A\x5A\x84\x4E\xA1"
+    "\x73\x41\x53\xD2\x60\xF7\x7C\xEE\x68\x59\x85\x80\xFC\x3D\x70\x4B"
+    "\x04\x32\xE7\xF2\xFD\xBD\xB3\xD9\x21\xE2\x37\x56\xA2\x16\xCC\xDE"
+    "\x8A\xD3\xBC\x71\xEF\x58\x19\x0E\x45\x8A\x5B\x53\xD6\x77\x30\x6A"
+    "\xA7\xF8\x68\x06\x4E\x07\xCA\xCE\x30\xD7\x35\xAB\x1A\xC7\x18\xD4"
+    "\xC6\x2F\x1A\xFF\xE9\x7A\x94\x0B\x76\x5E\x7E\x29\x0C\xE6\xD3\x3B"
+    "\x5B\x44\x96\xA8\xF1\x29\x23\x95\xD9\x79\xB3\x39\xFC\x76\xED\xE1"
+    "\x1E\x67\x4E\xF7\xE8\x7B\x7A\x12\x9E\xD8\x4B\x35\x09\x0A\xF2\xC1"
+    "\x63\x5B\xEE\xFD\x2A\xC2\xA6\x66\x30\x3C\x1F\x95\xAF\x65\x22\x95"
+    "\x14\x1D\xF5\xD5\xDC\x38\x79\x35\x1C\xCD\x24\x47\xE0\xFD\x08\xC8"
+    "\xF4\x15\x55\x9F\xD9\xC7\xAC\x3F\x67\xB3\x4F\xEB\x26\x7C\x8E\xD6"
+    "\x74\xB3\x0A\xCD\xE7\xFA\xBE\x7E\xA3\x3E\xEC\x61\x50\x77\x52\x56"
+    "\xCF\x90\x5D\x48\xFB\xD4\x2C\x6C\x61\x8B\xDD\x2B\xF5\x92\x1F\x30"
+    "\xBF\x3F\x80\x0D\x31\xDB\xB2\x0B\x7D\x84\xE3\xA6\x42\x7F\x00\x38"
+    "\x44\x02\xC5\xB8\xD9\x58\x29\x9D\x68\x5C\x32\x8B\x76\xAE\xED\x15"
+    "\xF9\x7C\xAE\x7B\xB6\x8E\xD6\x54\x24\xFF\xFA\x87\x05\xEF\x15\x08"
+    "\x5E\x4B\x21\xA2\x2F\x49\xE7\x0F\xC3\xD0\xB9\x49\x22\xEF\xD5\xCA"
+    "\xB2\x11\xF2\x17\xB6\x77\x24\x68\x76\xB2\x07\xF8\x0A\x73\xDD\x65"
+    "\x9C\x75\x64\xF7\xA1\xC6\x23\x08\x84\x72\x3E\x54\x2E\xEB\x9B\x40"
+    "\xA6\x83\x87\xEB\xB5\x00\x40\x4F\xE1\x72\x2A\x59\x3A\x06\x60\x29"
+    "\x7E\x25\x2F\xD8\x80\x40\x8C\x59\xCA\xCF\x8E\x44\xE4\x2D\x84\x7E"
+    "\xCB\xFD\x1E\x3B\xD5\xFF\x9A\xB9\x66\x93\x6D\x5E\xC8\xB7\x13\x26"
+    "\xD6\x38\x1B\x2B\xE1\x87\x96\x05\xD5\xF3\xAB\x68\xF7\x12\x62\x2C"
+    "\x58\xC1\xC9\x85\x3C\x72\xF1\x26\xEE\xC0\x09\x5F\x1D\x4B\xAC\x01"
+    "\x41\xC8\x12\xF8\xF3\x93\x43\x41\xFF\xEC\x0B\x80\xE2\xEE\x20\x85"
+    "\x25\xCD\x6C\x30\x8C\x0D\x24\x2E\xBA\x19\xEA\x28\x7F\xCF\xD5\x10"
+    "\x5C\xE9\xB2\x9D\x5F\x16\xE4\xC0\xF3\xCC\xD9\x68\x4A\x05\x08\x70"
+    "\x17\x26\xC8\x5C\x4A\xBF\x94\x6A\x0E\xD5\xDA\x67\x47\x4B\xAF\x44"
+    "\xE3\x94\xAA\x05\xDB\xA2\x49\x74\xFA\x5C\x69\xAB\x44\xB7\xF7\xBA"
+    "\xAE\x7A\x23\x87\xEB\x54\x7E\x80\xF1\x5B\x60\xA5\x93\xE5\xD4\x24"
+    "\x84\xF7\x0A\x16\x10\xBE\xE9\x4D\xD8\x6B\x15\x40\x5D\x74\xDA\x1B"
+    "\xFF\x2E\x4D\x17\x9D\x35\xF7\x0D\xCF\x66\x38\x0D\x8A\xE4\xDD\x6B"
+    "\xE1\x0F\x1F\xBD\xFD\x4F\x30\x37\x3F\x96\xB4\x92\x54\xD3\x9A\x7A"
+    "\xD1\x5B\x5B\xA9\x54\x16\xE6\x24\xAB\xD4\x23\x39\x7D\xD2\xC7\x09"
+    "\xFA\xD4\x86\x55\x4D\x60\xC2\x87\x67\x6B\xE6"
 };
 
 static void
@@ -686,7 +710,7 @@ test_pac_ticket_signature(krb5_context context)
 {
     krb5_error_code ret;
     krb5_ticket *ticket;
-    krb5_principal sprinc;
+    krb5_principal cprinc, sprinc;
     krb5_authdata **authdata1, **authdata2;
     krb5_pac pac, pac2, pac3;
     uint32_t *list;
@@ -701,7 +725,13 @@ test_pac_ticket_signature(krb5_context context)
     if (ret)
         err(context, ret, "while decrypting ticket");
 
-    ret = krb5_parse_name(context, "s1 at CDOM.COM", &sprinc);
+    ret = krb5_parse_name(context, "administrator at W2022-L7.BASE", &cprinc);
+    if (ret)
+        err(context, ret, "krb5_parse_name");
+
+    ret = krb5_parse_name(context,
+                          "cifs/w2022-118.w2022-l7.base at W2022-L7.BASE",
+                          &sprinc);
     if (ret)
         err(context, ret, "krb5_parse_name");
 
@@ -713,7 +743,7 @@ test_pac_ticket_signature(krb5_context context)
 
     /* In this test, the server is also the client. */
     ret = krb5_pac_verify(context, pac, ticket->enc_part2->times.authtime,
-                          ticket->server, NULL, NULL);
+                          cprinc, NULL, NULL);
     if (ret)
         err(context, ret, "while verifying PAC client info");
 
@@ -722,7 +752,7 @@ test_pac_ticket_signature(krb5_context context)
     ticket->enc_part2->authorization_data = NULL;
 
     ret = krb5_kdc_sign_ticket(context, ticket->enc_part2, pac, sprinc,
-                               sprinc, &ticket_sig_server_key,
+                               cprinc, &ticket_sig_server_key,
                                &ticket_sig_krbtgt_key, FALSE);
     if (ret)
         err(context, ret, "while signing ticket");
@@ -781,6 +811,7 @@ test_pac_ticket_signature(krb5_context context)
     krb5_pac_free(context, pac);
     krb5_pac_free(context, pac2);
     krb5_pac_free(context, pac3);
+    krb5_free_principal(context, cprinc);
     krb5_free_principal(context, sprinc);
     krb5_free_ticket(context, ticket);
 }
diff --git a/src/tests/t_authdata.py b/src/tests/t_authdata.py
index 97e2474bf..6a5af71d5 100644
--- a/src/tests/t_authdata.py
+++ b/src/tests/t_authdata.py
@@ -11,7 +11,7 @@ realm = K5Realm(krb5_conf=conf)
 # container.
 mark('baseline authdata')
 out = realm.run(['./adata', realm.host_princ])
-if '?128: [6, 7, 10, 16]' not in out or '^-42: Hello' not in out:
+if '?128: [6, 7, 10, 16, 19]' not in out or '^-42: Hello' not in out:
     fail('expected authdata not seen for basic request')
 
 # Requested authdata is copied into the ticket, with KDC-only types
@@ -243,7 +243,7 @@ out = realm.run(['./adata', '-p', realm.user_princ, 'service/2'])
 if '+97: [indcl]' not in out or '[inds1]' in out:
     fail('correct auth-indicator not seen for S4U2Proxy req')
 # Make sure a PAC with an S4U_DELEGATION_INFO(11) buffer is included.
-if '?128: [1, 6, 7, 10, 11, 16]' not in out:
+if '?128: [1, 6, 7, 10, 11, 16, 19]' not in out:
     fail('PAC with delegation info not seen for S4U2Proxy req')
 
 # Get another S4U2Proxy ticket including request-authdata.


More information about the cvs-krb5 mailing list