krb5 commit: Mark deprecated enctypes when used

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/8d8e68283b599e680f9fe45eff8af397e827bd6c
commit 8d8e68283b599e680f9fe45eff8af397e827bd6c
Author: Robbie Harwood <[email protected]>
Date:   Thu Jan 10 16:34:54 2019 -0500

    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)

 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 70adb54..8c30715 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 ed581ee..cc74921 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 43dba15..f274109 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1060,11 +1060,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 408c723..16235d6 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 5d9f80e..ca3d32d 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 7c8d828..4af6804 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 4480923..da02f22 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.