diff --git a/Add-function-and-enctype-flag-for-deprecations.patch b/Add-function-and-enctype-flag-for-deprecations.patch new file mode 100644 index 0000000..ee1628b --- /dev/null +++ b/Add-function-and-enctype-flag-for-deprecations.patch @@ -0,0 +1,183 @@ +From e0c8eb1bf93e0591e363e414378c70c255a6e6b6 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 15 Jan 2019 16:16:57 -0500 +Subject: [PATCH] Add function and enctype flag for deprecations + +krb5int_c_deprecated_enctype() checks for the ETYPE_DEPRECATED flag on +enctypes. All ENCTYPE_WEAK enctypes are currently deprecated; not all +deprecated enctypes are considered weak. Deprecations follow RFC 6649 +and RFC 8429. + +(cherry picked from commit 484a6e7712f9b66e782b2520f07b0883889e116f) +--- + src/include/k5-int.h | 1 + + src/lib/crypto/krb/crypto_int.h | 9 ++++++++- + src/lib/crypto/krb/enctype_util.c | 7 +++++++ + src/lib/crypto/krb/etypes.c | 19 ++++++++++--------- + src/lib/crypto/libk5crypto.exports | 1 + + src/lib/krb5_32.def | 3 +++ + 6 files changed, 30 insertions(+), 10 deletions(-) + +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 8f9329c59..255cee822 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -2077,6 +2077,7 @@ krb5_get_tgs_ktypes(krb5_context, krb5_const_principal, krb5_enctype **); + krb5_boolean krb5_is_permitted_enctype(krb5_context, krb5_enctype); + + krb5_boolean KRB5_CALLCONV krb5int_c_weak_enctype(krb5_enctype); ++krb5_boolean KRB5_CALLCONV krb5int_c_deprecated_enctype(krb5_enctype); + krb5_error_code k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out); + + krb5_error_code krb5_kdc_rep_decrypt_proc(krb5_context, const krb5_keyblock *, +diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h +index e5099291e..6c1c77cac 100644 +--- a/src/lib/crypto/krb/crypto_int.h ++++ b/src/lib/crypto/krb/crypto_int.h +@@ -114,7 +114,14 @@ struct krb5_keytypes { + unsigned int ssf; + }; + +-#define ETYPE_WEAK 1 ++/* ++ * "Weak" means the enctype is believed to be vulnerable to practical attacks, ++ * and will be disabled unless allow_weak_crypto is set to true. "Deprecated" ++ * means the enctype has been deprecated by the IETF, and affects display and ++ * logging. ++ */ ++#define ETYPE_WEAK (1 << 0) ++#define ETYPE_DEPRECATED (1 << 1) + + extern const struct krb5_keytypes krb5int_enctypes_list[]; + extern const int krb5int_enctypes_length; +diff --git a/src/lib/crypto/krb/enctype_util.c b/src/lib/crypto/krb/enctype_util.c +index b1b40e7ec..e394f4e19 100644 +--- a/src/lib/crypto/krb/enctype_util.c ++++ b/src/lib/crypto/krb/enctype_util.c +@@ -51,6 +51,13 @@ krb5int_c_weak_enctype(krb5_enctype etype) + return (ktp != NULL && (ktp->flags & ETYPE_WEAK) != 0); + } + ++krb5_boolean KRB5_CALLCONV ++krb5int_c_deprecated_enctype(krb5_enctype etype) ++{ ++ const struct krb5_keytypes *ktp = find_enctype(etype); ++ return ktp != NULL && (ktp->flags & ETYPE_DEPRECATED) != 0; ++} ++ + krb5_error_code KRB5_CALLCONV + krb5_c_enctype_compare(krb5_context context, krb5_enctype e1, krb5_enctype e2, + krb5_boolean *similar) +diff --git a/src/lib/crypto/krb/etypes.c b/src/lib/crypto/krb/etypes.c +index 53d4a5c79..8f44c37e7 100644 +--- a/src/lib/crypto/krb/etypes.c ++++ b/src/lib/crypto/krb/etypes.c +@@ -33,6 +33,7 @@ + that the keytypes are all near each other. I'd rather not make + that assumption. */ + ++/* Deprecations come from RFC 6649 and RFC 8249. */ + const struct krb5_keytypes krb5int_enctypes_list[] = { + { ENCTYPE_DES_CBC_CRC, + "des-cbc-crc", { 0 }, "DES cbc mode with CRC-32", +@@ -42,7 +43,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_des_string_to_key, k5_rand2key_des, + krb5int_des_prf, + CKSUMTYPE_RSA_MD5_DES, +- ETYPE_WEAK, 56 }, ++ ETYPE_WEAK | ETYPE_DEPRECATED, 56 }, + { ENCTYPE_DES_CBC_MD4, + "des-cbc-md4", { 0 }, "DES cbc mode with RSA-MD4", + &krb5int_enc_des, &krb5int_hash_md4, +@@ -51,7 +52,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_des_string_to_key, k5_rand2key_des, + krb5int_des_prf, + CKSUMTYPE_RSA_MD4_DES, +- ETYPE_WEAK, 56 }, ++ ETYPE_WEAK | ETYPE_DEPRECATED, 56 }, + { ENCTYPE_DES_CBC_MD5, + "des-cbc-md5", { "des" }, "DES cbc mode with RSA-MD5", + &krb5int_enc_des, &krb5int_hash_md5, +@@ -60,7 +61,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_des_string_to_key, k5_rand2key_des, + krb5int_des_prf, + CKSUMTYPE_RSA_MD5_DES, +- ETYPE_WEAK, 56 }, ++ ETYPE_WEAK | ETYPE_DEPRECATED, 56 }, + { ENCTYPE_DES_CBC_RAW, + "des-cbc-raw", { 0 }, "DES cbc mode raw", + &krb5int_enc_des, NULL, +@@ -69,7 +70,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_des_string_to_key, k5_rand2key_des, + krb5int_des_prf, + 0, +- ETYPE_WEAK, 56 }, ++ ETYPE_WEAK | ETYPE_DEPRECATED, 56 }, + { ENCTYPE_DES3_CBC_RAW, + "des3-cbc-raw", { 0 }, "Triple DES cbc mode raw", + &krb5int_enc_des3, NULL, +@@ -78,7 +79,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_dk_string_to_key, k5_rand2key_des3, + NULL, /*PRF*/ + 0, +- ETYPE_WEAK, 112 }, ++ ETYPE_WEAK | ETYPE_DEPRECATED, 112 }, + + { ENCTYPE_DES3_CBC_SHA1, + "des3-cbc-sha1", { "des3-hmac-sha1", "des3-cbc-sha1-kd" }, +@@ -89,7 +90,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_dk_string_to_key, k5_rand2key_des3, + krb5int_dk_prf, + CKSUMTYPE_HMAC_SHA1_DES3, +- 0 /*flags*/, 112 }, ++ ETYPE_DEPRECATED, 112 }, + + { ENCTYPE_DES_HMAC_SHA1, + "des-hmac-sha1", { 0 }, "DES with HMAC/sha1", +@@ -99,7 +100,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_dk_string_to_key, k5_rand2key_des, + NULL, /*PRF*/ + 0, +- ETYPE_WEAK, 56 }, ++ ETYPE_WEAK | ETYPE_DEPRECATED, 56 }, + + /* rc4-hmac uses a 128-bit key, but due to weaknesses in the RC4 cipher, we + * consider its strength degraded and assign it an SSF value of 64. */ +@@ -113,7 +114,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key, + k5_rand2key_direct, krb5int_arcfour_prf, + CKSUMTYPE_HMAC_MD5_ARCFOUR, +- 0 /*flags*/, 64 }, ++ ETYPE_DEPRECATED, 64 }, + { ENCTYPE_ARCFOUR_HMAC_EXP, + "arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" }, + "Exportable ArcFour with HMAC/md5", +@@ -124,7 +125,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key, + k5_rand2key_direct, krb5int_arcfour_prf, + CKSUMTYPE_HMAC_MD5_ARCFOUR, +- ETYPE_WEAK, 40 ++ ETYPE_WEAK | ETYPE_DEPRECATED, 40 + }, + + { ENCTYPE_AES128_CTS_HMAC_SHA1_96, +diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports +index 82eb5f30c..90afdf5f7 100644 +--- a/src/lib/crypto/libk5crypto.exports ++++ b/src/lib/crypto/libk5crypto.exports +@@ -109,3 +109,4 @@ k5_allow_weak_pbkdf2iter + krb5_c_prfplus + krb5_c_derive_prfplus + k5_enctype_to_ssf ++krb5int_c_deprecated_enctype +diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def +index c35022931..e6a487593 100644 +--- a/src/lib/krb5_32.def ++++ b/src/lib/krb5_32.def +@@ -487,3 +487,6 @@ EXPORTS + encode_krb5_pa_spake @444 ; PRIVATE + decode_krb5_pa_spake @445 ; PRIVATE + k5_free_pa_spake @446 ; PRIVATE ++ ++; new in 1.18 ++ krb5int_c_deprecated_enctype @450 ; PRIVATE diff --git a/Avoid-allocating-a-register-in-zap-assembly.patch b/Avoid-allocating-a-register-in-zap-assembly.patch new file mode 100644 index 0000000..71677ca --- /dev/null +++ b/Avoid-allocating-a-register-in-zap-assembly.patch @@ -0,0 +1,55 @@ +From 77b1ce65e7777395cee5a79e4068ff4340fcc680 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 3 Jan 2019 17:19:32 +0100 +Subject: [PATCH] Avoid allocating a register in zap() assembly + +See https://bugs.llvm.org/show_bug.cgi?id=15495 + +Also add explicit_bzero() (glibc, FreeBSD) and explicit_memset() +(NetBSD) as alternatives. + +[ghudson@mit.edu: added explicit_bzero() and explicit_memset()] + +(cherry picked from commit 7391e8b541061d0f584193b4a53365b64364b0e8) +--- + src/configure.in | 2 +- + src/include/k5-platform.h | 6 +++++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/configure.in b/src/configure.in +index 93aec682e..7c309a26b 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -421,7 +421,7 @@ AC_PROG_LEX + AC_C_CONST + AC_HEADER_DIRENT + AC_FUNC_STRERROR_R +-AC_CHECK_FUNCS(strdup setvbuf seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strptime geteuid setenv unsetenv getenv gmtime_r localtime_r bswap16 bswap64 mkstemp getusershell access getcwd srand48 srand srandom stat strchr strerror timegm) ++AC_CHECK_FUNCS(strdup setvbuf seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strptime geteuid setenv unsetenv getenv gmtime_r localtime_r bswap16 bswap64 mkstemp getusershell access getcwd srand48 srand srandom stat strchr strerror timegm explicit_bzero explicit_memset) + + AC_CHECK_FUNC(mkstemp, + [MKSTEMP_ST_OBJ= +diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h +index 997b655e1..1fcd68e8c 100644 +--- a/src/include/k5-platform.h ++++ b/src/include/k5-platform.h +@@ -1023,6 +1023,10 @@ static inline void zap(void *ptr, size_t len) + if (len > 0) + memset_s(ptr, len, 0, len); + } ++#elif defined(HAVE_EXPLICIT_BZERO) ++# define zap(ptr, len) explicit_bzero(ptr, len) ++#elif defined(HAVE_EXPLICIT_MEMSET) ++# define zap(ptr, len) explicit_memset(ptr, 0, len) + #elif defined(__GNUC__) || defined(__clang__) + /* + * Use an asm statement which declares a memory clobber to force the memset to +@@ -1032,7 +1036,7 @@ static inline void zap(void *ptr, size_t len) + { + if (len > 0) + memset(ptr, 0, len); +- __asm__ __volatile__("" : : "r" (ptr) : "memory"); ++ __asm__ __volatile__("" : : "g" (ptr) : "memory"); + } + #else + /* diff --git a/In-kpropd-debug-log-proper-ticket-enctype-names.patch b/In-kpropd-debug-log-proper-ticket-enctype-names.patch new file mode 100644 index 0000000..6090842 --- /dev/null +++ b/In-kpropd-debug-log-proper-ticket-enctype-names.patch @@ -0,0 +1,28 @@ +From d2990ce023e000e1628007a5d24aad5a5abdb0a3 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 15 Jan 2019 13:41:16 -0500 +Subject: [PATCH] In kpropd, debug-log proper ticket enctype names + +This change replaces the last call of krb5_enctype_to_string() in our +sources with krb5_enctype_to_name(), ensuring that we log consistently +to users using readily discoverable strings. + +(cherry picked from commit 30e12a2ecdf7e2a034a91626a03b5c9909e4c68d) +--- + src/kprop/kpropd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c +index 4cc035dc6..0c7bffa24 100644 +--- a/src/kprop/kpropd.c ++++ b/src/kprop/kpropd.c +@@ -1279,7 +1279,8 @@ kerberos_authenticate(krb5_context context, int fd, krb5_principal *clientp, + exit(1); + } + +- retval = krb5_enctype_to_string(*etype, etypebuf, sizeof(etypebuf)); ++ retval = krb5_enctype_to_name(*etype, FALSE, etypebuf, ++ sizeof(etypebuf)); + if (retval) { + com_err(progname, retval, _("while unparsing ticket etype")); + exit(1); diff --git a/In-rd_req_dec-always-log-non-permitted-enctypes.patch b/In-rd_req_dec-always-log-non-permitted-enctypes.patch new file mode 100644 index 0000000..787ce20 --- /dev/null +++ b/In-rd_req_dec-always-log-non-permitted-enctypes.patch @@ -0,0 +1,54 @@ +From e595f7a4c1c95aadcb1bc3ea2bb88fce66fb826b Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 14 Jan 2019 17:14:42 -0500 +Subject: [PATCH] In rd_req_dec, always log non-permitted enctypes + +The buffer specified in negotiate_etype() is too small for use with +the AES enctypes when used with krb5_enctype_to_string(), so switch to +using krb5_enctype_to_name(). + +(cherry picked from commit bf75ebf583a51bf00005a96d17924818d19377be) +--- + src/lib/krb5/krb/rd_req_dec.c | 5 ++--- + src/tests/gssapi/t_enctypes.py | 5 +++-- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c +index 4cd429a11..e75192fee 100644 +--- a/src/lib/krb5/krb/rd_req_dec.c ++++ b/src/lib/krb5/krb/rd_req_dec.c +@@ -864,9 +864,8 @@ negotiate_etype(krb5_context context, + if (permitted == FALSE) { + char enctype_name[30]; + +- if (krb5_enctype_to_string(desired_etypes[i], +- enctype_name, +- sizeof(enctype_name)) == 0) ++ if (krb5_enctype_to_name(desired_etypes[i], FALSE, enctype_name, ++ sizeof(enctype_name)) == 0) + k5_setmsg(context, KRB5_NOPERM_ETYPE, + _("Encryption type %s not permitted"), enctype_name); + return KRB5_NOPERM_ETYPE; +diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py +index ee43ff028..5d9f80e04 100755 +--- a/src/tests/gssapi/t_enctypes.py ++++ b/src/tests/gssapi/t_enctypes.py +@@ -85,7 +85,8 @@ test('both aes128', 'aes128-cts', 'aes128-cts', + # If only the acceptor constrains the permitted session enctypes to + # aes128, subkey negotiation fails because the acceptor considers the + # aes256 session key to be non-permitted. +-test_err('acc aes128', None, 'aes128-cts', 'Encryption type not permitted') ++test_err('acc aes128', None, 'aes128-cts', ++ 'Encryption type aes256-cts-hmac-sha1-96 not permitted') + + # If the initiator constrains the permitted session enctypes to des3, + # no acceptor subkey will be generated because we can't upgrade to a +@@ -128,7 +129,7 @@ test('upgrade init des3+rc4', 'des3 rc4', None, + # is only for the sake of the kernel, since we could upgrade to an + # aes128 subkey, but it's the current semantics.) + test_err('upgrade acc aes128', None, 'aes128-cts', +- 'Encryption type ArcFour with HMAC/md5 not permitted') ++ 'Encryption type arcfour-hmac not permitted') + + # If the acceptor permits rc4 but prefers aes128, it will negotiate an + # upgrade to aes128. diff --git a/Make-etype-names-in-KDC-logs-human-readable.patch b/Make-etype-names-in-KDC-logs-human-readable.patch new file mode 100644 index 0000000..2761ba3 --- /dev/null +++ b/Make-etype-names-in-KDC-logs-human-readable.patch @@ -0,0 +1,296 @@ +From b999ade3996817ccb9c9362e4c06dd236e4a854b Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 8 Jan 2019 17:42:35 -0500 +Subject: [PATCH] Make etype names in KDC logs human-readable + +Introduce enctype_name() as a wrapper over krb5_enctype_to_name for +converting between registered constants and names. Adjust signatures +and rewrite ktypes2str() and rep_etypes2str() to operate on dynamic +buffers. + +ticket: 8772 (new) +(cherry picked from commit a649279727490687d54becad91fde8cf7429d951) +--- + src/kdc/kdc_log.c | 42 +++++++-------- + src/kdc/kdc_util.c | 131 +++++++++++++++++++++++---------------------- + src/kdc/kdc_util.h | 6 +-- + 3 files changed, 90 insertions(+), 89 deletions(-) + +diff --git a/src/kdc/kdc_log.c b/src/kdc/kdc_log.c +index 4eec50373..b160ba21a 100644 +--- a/src/kdc/kdc_log.c ++++ b/src/kdc/kdc_log.c +@@ -65,7 +65,7 @@ log_as_req(krb5_context context, + { + const char *fromstring = 0; + char fromstringbuf[70]; +- char ktypestr[128]; ++ char *ktypestr = NULL; + const char *cname2 = cname ? cname : ""; + const char *sname2 = sname ? sname : ""; + +@@ -74,26 +74,29 @@ log_as_req(krb5_context context, + fromstringbuf, sizeof(fromstringbuf)); + if (!fromstring) + fromstring = ""; +- ktypes2str(ktypestr, sizeof(ktypestr), +- request->nktypes, request->ktype); ++ ++ ktypestr = ktypes2str(request->ktype, request->nktypes); + + if (status == NULL) { + /* success */ +- char rep_etypestr[128]; +- rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply); ++ char *rep_etypestr = rep_etypes2str(reply); + krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %u, %s, " + "%s for %s"), +- ktypestr, fromstring, (unsigned int)authtime, +- rep_etypestr, cname2, sname2); ++ ktypestr ? ktypestr : "", fromstring, ++ (unsigned int)authtime, ++ rep_etypestr ? rep_etypestr : "", cname2, sname2); ++ free(rep_etypestr); + } else { + /* fail */ + krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: %s: %s for %s%s%s"), +- ktypestr, fromstring, status, +- cname2, sname2, emsg ? ", " : "", emsg ? emsg : ""); ++ ktypestr ? ktypestr : "", fromstring, status, cname2, ++ sname2, emsg ? ", " : "", emsg ? emsg : ""); + } + krb5_db_audit_as_req(context, request, + local_addr->address, remote_addr->address, + client, server, authtime, errcode); ++ ++ free(ktypestr); + } + + /* +@@ -122,10 +125,9 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from, + unsigned int c_flags, + const char *status, krb5_error_code errcode, const char *emsg) + { +- char ktypestr[128]; ++ char *ktypestr = NULL, *rep_etypestr = NULL; + const char *fromstring = 0; + char fromstringbuf[70]; +- char rep_etypestr[128]; + char *cname = NULL, *sname = NULL, *altcname = NULL; + char *logcname = NULL, *logsname = NULL, *logaltcname = NULL; + +@@ -134,11 +136,6 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from, + fromstringbuf, sizeof(fromstringbuf)); + if (!fromstring) + fromstring = ""; +- ktypes2str(ktypestr, sizeof(ktypestr), request->nktypes, request->ktype); +- if (!errcode) +- rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply); +- else +- rep_etypestr[0] = 0; + + unparse_and_limit(ctx, cprinc, &cname); + logcname = (cname != NULL) ? cname : ""; +@@ -151,10 +148,14 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from, + name (useful), and doesn't log ktypestr (probably not + important). */ + if (errcode != KRB5KDC_ERR_SERVER_NOMATCH) { ++ ktypestr = ktypes2str(request->ktype, request->nktypes); ++ rep_etypestr = rep_etypes2str(reply); + krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %u, %s%s " + "%s for %s%s%s"), +- ktypestr, fromstring, status, (unsigned int)authtime, +- rep_etypestr, !errcode ? "," : "", logcname, logsname, ++ ktypestr ? ktypestr : "", fromstring, status, ++ (unsigned int)authtime, ++ rep_etypestr ? rep_etypestr : "", ++ !errcode ? "," : "", logcname, logsname, + errcode ? ", " : "", errcode ? emsg : ""); + if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) + krb5_klog_syslog(LOG_INFO, +@@ -171,9 +172,8 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from, + fromstring, status, (unsigned int)authtime, + logcname, logsname, logaltcname); + +- /* OpenSolaris: audit_krb5kdc_tgs_req(...) or +- audit_krb5kdc_tgs_req_2ndtktmm(...) */ +- ++ free(rep_etypestr); ++ free(ktypestr); + krb5_free_unparsed_name(ctx, cname); + krb5_free_unparsed_name(ctx, sname); + krb5_free_unparsed_name(ctx, altcname); +diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c +index 0155c28c6..f5c581c82 100644 +--- a/src/kdc/kdc_util.c ++++ b/src/kdc/kdc_util.c +@@ -1043,84 +1043,87 @@ void limit_string(char *name) + return; + } + +-/* +- * L10_2 = log10(2**x), rounded up; log10(2) ~= 0.301. +- */ +-#define L10_2(x) ((int)(((x * 301) + 999) / 1000)) +- +-/* +- * Max length of sprintf("%ld") for an int of type T; includes leading +- * minus sign and terminating NUL. +- */ +-#define D_LEN(t) (L10_2(sizeof(t) * CHAR_BIT) + 2) +- +-void +-ktypes2str(char *s, size_t len, int nktypes, krb5_enctype *ktype) ++/* Wrapper of krb5_enctype_to_name() to include the PKINIT types. */ ++static krb5_error_code ++enctype_name(krb5_enctype ktype, char *buf, size_t buflen) + { +- int i; +- char stmp[D_LEN(krb5_enctype) + 1]; +- char *p; ++ char *name; + +- if (nktypes < 0 +- || len < (sizeof(" etypes {...}") + D_LEN(int))) { +- *s = '\0'; +- return; +- } ++ if (buflen == 0) ++ return EINVAL; ++ *buf = '\0'; /* ensure these are always valid C-strings */ + +- snprintf(s, len, "%d etypes {", nktypes); +- for (i = 0; i < nktypes; i++) { +- snprintf(stmp, sizeof(stmp), "%s%ld", i ? " " : "", (long)ktype[i]); +- if (strlen(s) + strlen(stmp) + sizeof("}") > len) +- break; +- strlcat(s, stmp, len); +- } +- if (i < nktypes) { +- /* +- * We broke out of the loop. Try to truncate the list. +- */ +- p = s + strlen(s); +- while (p - s + sizeof("...}") > len) { +- while (p > s && *p != ' ' && *p != '{') +- *p-- = '\0'; +- if (p > s && *p == ' ') { +- *p-- = '\0'; +- continue; +- } +- } +- strlcat(s, "...", len); +- } +- strlcat(s, "}", len); +- return; ++ /* rfc4556 recommends that clients wishing to indicate support for these ++ * pkinit algorithms include them in the etype field of the AS-REQ. */ ++ if (ktype == ENCTYPE_DSA_SHA1_CMS) ++ name = "id-dsa-with-sha1-CmsOID"; ++ else if (ktype == ENCTYPE_MD5_RSA_CMS) ++ name = "md5WithRSAEncryption-CmsOID"; ++ else if (ktype == ENCTYPE_SHA1_RSA_CMS) ++ name = "sha-1WithRSAEncryption-CmsOID"; ++ else if (ktype == ENCTYPE_RC2_CBC_ENV) ++ name = "rc2-cbc-EnvOID"; ++ else if (ktype == ENCTYPE_RSA_ENV) ++ name = "rsaEncryption-EnvOID"; ++ else if (ktype == ENCTYPE_RSA_ES_OAEP_ENV) ++ name = "id-RSAES-OAEP-EnvOID"; ++ else if (ktype == ENCTYPE_DES3_CBC_ENV) ++ name = "des-ede3-cbc-EnvOID"; ++ else ++ return krb5_enctype_to_name(ktype, FALSE, buf, buflen); ++ ++ if (strlcpy(name, buf, buflen) >= buflen) ++ return ENOMEM; ++ return 0; + } + +-void +-rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep) ++char * ++ktypes2str(krb5_enctype *ktype, int nktypes) + { +- char stmp[sizeof("ses=") + D_LEN(krb5_enctype)]; ++ struct k5buf buf; ++ int i; ++ char name[64]; + +- if (len < (3 * D_LEN(krb5_enctype) +- + sizeof("etypes {rep= tkt= ses=}"))) { +- *s = '\0'; +- return; ++ if (nktypes < 0) ++ return NULL; ++ ++ k5_buf_init_dynamic(&buf); ++ k5_buf_add_fmt(&buf, "%d etypes {", nktypes); ++ for (i = 0; i < nktypes; i++) { ++ enctype_name(ktype[i], name, sizeof(name)); ++ k5_buf_add_fmt(&buf, "%s%s(%ld)", i ? ", " : "", name, (long)ktype[i]); + } ++ k5_buf_add(&buf, "}"); ++ return buf.data; ++} + +- snprintf(s, len, "etypes {rep=%ld", (long)rep->enc_part.enctype); ++char * ++rep_etypes2str(krb5_kdc_rep *rep) ++{ ++ struct k5buf buf; ++ char name[64]; ++ krb5_enctype etype; ++ ++ k5_buf_init_dynamic(&buf); ++ k5_buf_add(&buf, "etypes {rep="); ++ enctype_name(rep->enc_part.enctype, name, sizeof(name)); ++ k5_buf_add_fmt(&buf, "%s(%ld)", name, (long)rep->enc_part.enctype); + + if (rep->ticket != NULL) { +- snprintf(stmp, sizeof(stmp), +- " tkt=%ld", (long)rep->ticket->enc_part.enctype); +- strlcat(s, stmp, len); ++ etype = rep->ticket->enc_part.enctype; ++ enctype_name(etype, name, sizeof(name)); ++ k5_buf_add_fmt(&buf, ", tkt=%s(%ld)", name, (long)etype); + } + +- if (rep->ticket != NULL +- && rep->ticket->enc_part2 != NULL +- && rep->ticket->enc_part2->session != NULL) { +- snprintf(stmp, sizeof(stmp), " ses=%ld", +- (long)rep->ticket->enc_part2->session->enctype); +- strlcat(s, stmp, len); ++ if (rep->ticket != NULL && rep->ticket->enc_part2 != NULL && ++ rep->ticket->enc_part2->session != NULL) { ++ etype = rep->ticket->enc_part2->session->enctype; ++ enctype_name(etype, name, sizeof(name)); ++ k5_buf_add_fmt(&buf, ", ses=%s(%ld)", name, (long)etype); + } +- strlcat(s, "}", len); +- return; ++ ++ k5_buf_add(&buf, "}"); ++ return buf.data; + } + + static krb5_error_code +diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h +index 6ec645fc3..25077cbf5 100644 +--- a/src/kdc/kdc_util.h ++++ b/src/kdc/kdc_util.h +@@ -110,11 +110,9 @@ select_session_keytype (kdc_realm_t *kdc_active_realm, + + void limit_string (char *name); + +-void +-ktypes2str(char *s, size_t len, int nktypes, krb5_enctype *ktype); ++char *ktypes2str(krb5_enctype *ktype, int nktypes); + +-void +-rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep); ++char *rep_etypes2str(krb5_kdc_rep *rep); + + /* authind.c */ + krb5_boolean diff --git a/Mark-deprecated-enctypes-when-used.patch b/Mark-deprecated-enctypes-when-used.patch new file mode 100644 index 0000000..cb74384 --- /dev/null +++ b/Mark-deprecated-enctypes-when-used.patch @@ -0,0 +1,250 @@ +From 1d1db003481768092410dc36a41e240c48a136e0 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Thu, 10 Jan 2019 16:34:54 -0500 +Subject: [PATCH] Mark deprecated enctypes when used + +Preface ETYPE_DEPRECATED enctypes with "DEPRECATED:" in klist output, +KDC logs, and kadmin interactions. Also complain in krb5kdc when the +stash file has a deprecated enctype or a deprecated enctype is +requested with -k. + +ticket: 8773 (new) +(cherry picked from commit 8d8e68283b599e680f9fe45eff8af397e827bd6c) +--- + src/clients/klist/klist.c | 14 ++++++++++---- + src/kadmin/cli/kadmin.c | 6 +++++- + src/kdc/kdc_util.c | 9 +++++++++ + src/kdc/main.c | 19 +++++++++++++++++++ + src/tests/gssapi/t_enctypes.py | 15 +++++++++------ + src/tests/t_keyrollover.py | 8 +++++--- + src/tests/t_sesskeynego.py | 4 ++-- + 7 files changed, 59 insertions(+), 16 deletions(-) + +diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c +index 70adb54e8..8c307151a 100644 +--- a/src/clients/klist/klist.c ++++ b/src/clients/klist/klist.c +@@ -571,11 +571,17 @@ static char * + etype_string(krb5_enctype enctype) + { + static char buf[100]; +- krb5_error_code ret; ++ char *bp = buf; ++ size_t deplen, buflen = sizeof(buf); + +- ret = krb5_enctype_to_name(enctype, FALSE, buf, sizeof(buf)); +- if (ret) +- snprintf(buf, sizeof(buf), "etype %d", enctype); ++ if (krb5int_c_deprecated_enctype(enctype)) { ++ deplen = strlcpy(bp, "DEPRECATED:", buflen); ++ buflen -= deplen; ++ bp += deplen; ++ } ++ ++ if (krb5_enctype_to_name(enctype, FALSE, bp, buflen)) ++ snprintf(bp, buflen, "etype %d", enctype); + return buf; + } + +diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c +index ed581ee79..cc74921bf 100644 +--- a/src/kadmin/cli/kadmin.c ++++ b/src/kadmin/cli/kadmin.c +@@ -1451,12 +1451,16 @@ kadmin_getprinc(int argc, char *argv[]) + for (i = 0; i < dprinc.n_key_data; i++) { + krb5_key_data *key_data = &dprinc.key_data[i]; + char enctype[BUFSIZ], salttype[BUFSIZ]; ++ char *deprecated = ""; + + if (krb5_enctype_to_name(key_data->key_data_type[0], FALSE, + enctype, sizeof(enctype))) + snprintf(enctype, sizeof(enctype), _(""), + key_data->key_data_type[0]); +- printf("Key: vno %d, %s", key_data->key_data_kvno, enctype); ++ if (krb5int_c_deprecated_enctype(key_data->key_data_type[0])) ++ deprecated = "DEPRECATED:"; ++ printf("Key: vno %d, %s%s", key_data->key_data_kvno, deprecated, ++ enctype); + if (key_data->key_data_ver > 1 && + key_data->key_data_type[1] != KRB5_KDB_SALTTYPE_NORMAL) { + if (krb5_salttype_to_string(key_data->key_data_type[1], +diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c +index f5c581c82..96c88edc1 100644 +--- a/src/kdc/kdc_util.c ++++ b/src/kdc/kdc_util.c +@@ -1048,11 +1048,20 @@ static krb5_error_code + enctype_name(krb5_enctype ktype, char *buf, size_t buflen) + { + char *name; ++ size_t len; + + if (buflen == 0) + return EINVAL; + *buf = '\0'; /* ensure these are always valid C-strings */ + ++ if (krb5int_c_deprecated_enctype(ktype)) { ++ len = strlcpy(buf, "DEPRECATED:", buflen); ++ if (len >= buflen) ++ return ENOMEM; ++ buflen -= len; ++ buf += len; ++ } ++ + /* rfc4556 recommends that clients wishing to indicate support for these + * pkinit algorithms include them in the etype field of the AS-REQ. */ + if (ktype == ENCTYPE_DSA_SHA1_CMS) +diff --git a/src/kdc/main.c b/src/kdc/main.c +index 663fd6303..60092a0df 100644 +--- a/src/kdc/main.c ++++ b/src/kdc/main.c +@@ -210,12 +210,23 @@ init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm, + char *svalue = NULL; + const char *hierarchy[4]; + krb5_kvno mkvno = IGNORE_VNO; ++ char ename[32]; + + memset(rdp, 0, sizeof(kdc_realm_t)); + if (!realm) { + kret = EINVAL; + goto whoops; + } ++ ++ if (def_enctype != ENCTYPE_UNKNOWN && ++ krb5int_c_deprecated_enctype(def_enctype)) { ++ if (krb5_enctype_to_name(def_enctype, FALSE, ename, sizeof(ename))) ++ ename[0] = '\0'; ++ fprintf(stderr, ++ _("Requested master password enctype %s in %s is DEPRECATED!"), ++ ename, realm); ++ } ++ + hierarchy[0] = KRB5_CONF_REALMS; + hierarchy[1] = realm; + hierarchy[3] = NULL; +@@ -370,6 +381,14 @@ init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm, + goto whoops; + } + ++ if (krb5int_c_deprecated_enctype(rdp->realm_mkey.enctype)) { ++ if (krb5_enctype_to_name(rdp->realm_mkey.enctype, FALSE, ename, ++ sizeof(ename))) ++ ename[0] = '\0'; ++ fprintf(stderr, _("Stash file %s uses DEPRECATED enctype %s!"), ++ rdp->realm_stash, ename); ++ } ++ + if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc, + &rdp->realm_mkey))) { + kdc_err(rdp->realm_context, kret, +diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py +index 5d9f80e04..ca3d32d21 100755 +--- a/src/tests/gssapi/t_enctypes.py ++++ b/src/tests/gssapi/t_enctypes.py +@@ -9,8 +9,11 @@ from k5test import * + aes256 = 'aes256-cts-hmac-sha1-96' + aes128 = 'aes128-cts-hmac-sha1-96' + des3 = 'des3-cbc-sha1' ++d_des3 = 'DEPRECATED:des3-cbc-sha1' + des3raw = 'des3-cbc-raw' ++d_des3raw = 'DEPRECATED:des3-cbc-raw' + rc4 = 'arcfour-hmac' ++d_rc4 = 'DEPRECATED:arcfour-hmac' + + # These tests make assumptions about the default enctype lists, so set + # them explicitly rather than relying on the library defaults. +@@ -92,7 +95,7 @@ test_err('acc aes128', None, 'aes128-cts', + # no acceptor subkey will be generated because we can't upgrade to a + # CFX enctype. + test('init des3', 'des3', None, +- tktenc=aes256, tktsession=des3, ++ tktenc=aes256, tktsession=d_des3, + proto='rfc1964', isubkey=des3raw, asubkey=None) + + # Force the ticket session key to be rc4, so we can test some subkey +@@ -103,7 +106,7 @@ realm.run([kadminl, 'setstr', realm.host_princ, 'session_enctypes', 'rc4']) + # [aes256 aes128 des3] and the acceptor should upgrade to an aes256 + # subkey. + test('upgrade noargs', None, None, +- tktenc=aes256, tktsession=rc4, ++ tktenc=aes256, tktsession=d_rc4, + proto='cfx', isubkey=rc4, asubkey=aes256) + + # If the initiator won't permit rc4 as a session key, it won't be able +@@ -113,14 +116,14 @@ test_err('upgrade init aes', 'aes', None, 'no support for encryption type') + # If the initiator permits rc4 but prefers aes128, it will send an + # upgrade list of [aes128] and the acceptor will upgrade to aes128. + test('upgrade init aes128+rc4', 'aes128-cts rc4', None, +- tktenc=aes256, tktsession=rc4, ++ tktenc=aes256, tktsession=d_rc4, + proto='cfx', isubkey=rc4, asubkey=aes128) + + # If the initiator permits rc4 but prefers des3, it will send an + # upgrade list of [des3], but the acceptor won't generate a subkey + # because des3 isn't a CFX enctype. + test('upgrade init des3+rc4', 'des3 rc4', None, +- tktenc=aes256, tktsession=rc4, ++ tktenc=aes256, tktsession=d_rc4, + proto='rfc1964', isubkey=rc4, asubkey=None) + + # If the acceptor permits only aes128, subkey negotiation will fail +@@ -134,14 +137,14 @@ test_err('upgrade acc aes128', None, 'aes128-cts', + # If the acceptor permits rc4 but prefers aes128, it will negotiate an + # upgrade to aes128. + test('upgrade acc aes128 rc4', None, 'aes128-cts rc4', +- tktenc=aes256, tktsession=rc4, ++ tktenc=aes256, tktsession=d_rc4, + proto='cfx', isubkey=rc4, asubkey=aes128) + + # In this test, the initiator and acceptor each prefer an AES enctype + # to rc4, but they can't agree on which one, so no subkey is + # generated. + test('upgrade mismatch', 'aes128-cts rc4', 'aes256-cts rc4', +- tktenc=aes256, tktsession=rc4, ++ tktenc=aes256, tktsession=d_rc4, + proto='rfc1964', isubkey=rc4, asubkey=None) + + success('gss_krb5_set_allowable_enctypes tests') +diff --git a/src/tests/t_keyrollover.py b/src/tests/t_keyrollover.py +index 7c8d828f0..4af6804f2 100755 +--- a/src/tests/t_keyrollover.py ++++ b/src/tests/t_keyrollover.py +@@ -22,8 +22,9 @@ realm.run([kvno, princ1]) + realm.run([kadminl, 'purgekeys', realm.krbtgt_princ]) + # Make sure an old TGT fails after purging old TGS key. + realm.run([kvno, princ2], expected_code=1) +-msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): des-cbc-crc, des-cbc-crc' % \ +- (realm.realm, realm.realm) ++ddes = "DEPRECATED:des-cbc-crc" ++msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): %s, %s' % \ ++ (realm.realm, realm.realm, ddes, ddes) + realm.run([klist, '-e'], expected_msg=msg) + + # Check that new key actually works. +@@ -48,7 +49,8 @@ realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts', + realm.krbtgt_princ]) + realm.run([kadminl, 'modprinc', '-kvno', '1', realm.krbtgt_princ]) + out = realm.run([kadminl, 'getprinc', realm.krbtgt_princ]) +-if 'vno 1, aes256' not in out or 'vno 1, des3' not in out: ++if 'vno 1, aes256-cts' not in out or \ ++ 'vno 1, DEPRECATED:des3-cbc-sha1' not in out: + fail('keyrollover: setup for TGS enctype test failed') + # Now present the DES3 ticket to the KDC and make sure it's rejected. + realm.run([kvno, realm.host_princ], expected_code=1) +diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py +index 448092387..da02f224a 100755 +--- a/src/tests/t_sesskeynego.py ++++ b/src/tests/t_sesskeynego.py +@@ -62,11 +62,11 @@ test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96') + # 3b: Negotiate rc4-hmac session key when principal only has aes256 long-term. + realm.run([kadminl, 'setstr', 'server', 'session_enctypes', + 'rc4-hmac,aes128-cts,aes256-cts']) +-test_kvno(realm, 'arcfour-hmac', 'aes256-cts-hmac-sha1-96') ++test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96') + + # 3c: Test des-cbc-crc default assumption. + realm.run([kadminl, 'delstr', 'server', 'session_enctypes']) +-test_kvno(realm, 'des-cbc-crc', 'aes256-cts-hmac-sha1-96') ++test_kvno(realm, 'DEPRECATED:des-cbc-crc', 'aes256-cts-hmac-sha1-96') + realm.stop() + + # Last go: test that we can disable the des-cbc-crc assumption diff --git a/krb5.spec b/krb5.spec index 8da9d25..5ed1f33 100644 --- a/krb5.spec +++ b/krb5.spec @@ -18,7 +18,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.17 # for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces) -Release: 2 +Release: 3%{?dist} # lookaside-cached sources; two downloads and a build artifact Source0: https://web.mit.edu/kerberos/dist/krb5/1.16/krb5-%{version}%{prerelease}.tar.gz @@ -65,6 +65,12 @@ Patch89: In-FIPS-mode-add-plaintext-fallback-for-RC4-usages-a.patch Patch90: Add-tests-for-KCM-ccache-type.patch Patch92: Address-some-optimized-out-memset-calls.patch Patch93: Use-openssl-s-PRNG-in-FIPS-mode.patch +Patch94: Avoid-allocating-a-register-in-zap-assembly.patch +Patch95: In-rd_req_dec-always-log-non-permitted-enctypes.patch +Patch96: In-kpropd-debug-log-proper-ticket-enctype-names.patch +Patch97: Add-function-and-enctype-flag-for-deprecations.patch +Patch98: Make-etype-names-in-KDC-logs-human-readable.patch +Patch99: Mark-deprecated-enctypes-when-used.patch License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -712,6 +718,9 @@ exit 0 %{_libdir}/libkadm5srv_mit.so.* %changelog +* Thu Jan 17 2019 Robbie Harwood - 1.17-3 +- enctype logging and explicit_bzero() + * Tue Jan 08 2019 Robbie Harwood - 1.17-2 - New upstream version (1.17)