Add support for MS-PAC extended KDC signature (CVE-2022-37967)

Resolves: rhbz#2166001
Signed-off-by: Julien Rische <jrische@redhat.com>
This commit is contained in:
Julien Rische 2023-01-31 17:56:02 +01:00
parent ec957f5711
commit 7058594eab
2 changed files with 678 additions and 1 deletions

View File

@ -0,0 +1,672 @@
From 5801da1ddc3b0984ad6997bb7a692eac85ff7dd3 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 22 Dec 2022 03:05:23 -0500
Subject: [PATCH] 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 5f34dea5e8..3eeee25593 100644
--- a/doc/appdev/refs/macros/index.rst
+++ b/doc/appdev/refs/macros/index.rst
@@ -247,6 +247,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 fb9f2a366c..2ba4010514 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -8164,6 +8164,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 f6c4373de0..954482e0c7 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 0f9581abbb..8ea61ac17b 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 173bde7bab..81f1642ab0 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@CDOM.COM", &sprinc);
+ ret = krb5_parse_name(context, "administrator@W2022-L7.BASE", &cprinc);
+ if (ret)
+ err(context, ret, "krb5_parse_name");
+
+ ret = krb5_parse_name(context,
+ "cifs/w2022-118.w2022-l7.base@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 47ea9e4b47..e934799268 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.
--
2.39.1

View File

@ -10,7 +10,7 @@
#
# baserelease is what we have standardized across Fedora and what
# rpmdev-bumpspec knows how to handle.
%global baserelease 8
%global baserelease 9
# This should be e.g. beta1 or %%nil
%global pre_release %nil
@ -75,6 +75,7 @@ Patch13: 0013-downstream-Make-tests-compatible-with-sssd_krb5_loca.patch
Patch14: 0014-downstream-Include-missing-OpenSSL-FIPS-header.patch
Patch15: 0015-downstream-Do-not-set-root-as-ksu-file-owner.patch
Patch16: 0016-downstream-Allow-KRB5KDF-MD5-and-MD4-in-FIPS-mode.patch
Patch17: 0017-Add-PAC-full-checksums.patch
License: MIT
URL: https://web.mit.edu/kerberos/www/
@ -711,6 +712,10 @@ exit 0
%{_datarootdir}/%{name}-tests/
%changelog
* Tue Jan 31 2023 Julien Rische <jrische@redhat.com> - 1.20.1-9
- Add support for MS-PAC extended KDC signature (CVE-2022-37967)
- Resolves: rhbz#2166001
* Mon Jan 30 2023 Julien Rische <jrische@redhat.com> - 1.20.1-8
- Bypass FIPS restrictions to use KRB5KDF in case AES SHA-1 HMAC is enabled
- Lazily load MD4/5 from OpenSSL if using RADIUS or RC4 enctype in FIPS mode