enctype logging and explicit_bzero()

This commit is contained in:
Robbie Harwood 2019-01-17 13:44:00 -05:00
parent 658f28f754
commit 1458a863a4
7 changed files with 876 additions and 1 deletions

View File

@ -0,0 +1,183 @@
From e0c8eb1bf93e0591e363e414378c70c255a6e6b6 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
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

View File

@ -0,0 +1,55 @@
From 77b1ce65e7777395cee5a79e4068ff4340fcc680 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
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
/*

View File

@ -0,0 +1,28 @@
From d2990ce023e000e1628007a5d24aad5a5abdb0a3 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
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);

View File

@ -0,0 +1,54 @@
From e595f7a4c1c95aadcb1bc3ea2bb88fce66fb826b Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
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.

View File

@ -0,0 +1,296 @@
From b999ade3996817ccb9c9362e4c06dd236e4a854b Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
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 : "<unknown client>";
const char *sname2 = sname ? sname : "<unknown server>";
@@ -74,26 +74,29 @@ log_as_req(krb5_context context,
fromstringbuf, sizeof(fromstringbuf));
if (!fromstring)
fromstring = "<unknown>";
- 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 = "<unknown>";
- 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 : "<unknown client>";
@@ -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

View File

@ -0,0 +1,250 @@
From 1d1db003481768092410dc36a41e240c48a136e0 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
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), _("<Encryption type 0x%x>"),
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

View File

@ -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 <rharwood@redhat.com> - 1.17-3
- enctype logging and explicit_bzero()
* Tue Jan 08 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-2
- New upstream version (1.17)