]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Don't issue session keys with deprecated enctypes 1283/head
authorGreg Hudson <ghudson@mit.edu>
Fri, 16 Dec 2022 23:31:07 +0000 (18:31 -0500)
committerGreg Hudson <ghudson@mit.edu>
Mon, 23 Jan 2023 23:41:42 +0000 (18:41 -0500)
A paper by Tom Tervoort noted that rc4-hmac pre-hashes the input for
its checksum and GSS operations before applying HMAC, and is therefore
potentially vulnerable to hash collision attacks if a protocol
contains a restricted signing oracle.

In light of these potential attacks, begin the functional deprecation
of DES3 and RC4 by disallowing their use as session key enctypes by
default.  Add the variables allow_des3 and allow_rc4 in case
negotiability of these enctypes for session keys needs to be turned
back on, with the expectation that in future releases the enctypes
will be more comprehensively deprecated.

ticket: 9081

doc/admin/conf_files/krb5_conf.rst
doc/admin/enctypes.rst
src/include/k5-int.h
src/kdc/kdc_util.c
src/lib/krb5/krb/get_in_tkt.c
src/lib/krb5/krb/init_ctx.c
src/tests/gssapi/t_enctypes.py
src/tests/t_etype_info.py
src/tests/t_sesskeynego.py
src/util/k5test.py

index f22d5db11b4b4f670e54083d8605ed19f5eac5af..ecdf917501523ab514ead0a2a49393b1dea4214d 100644 (file)
@@ -95,6 +95,18 @@ Additionally, krb5.conf may include any of the relations described in
 
 The libdefaults section may contain any of the following relations:
 
+**allow_des3**
+    Permit the KDC to issue tickets with des3-cbc-sha1 session keys.
+    In future releases, this flag will allow des3-cbc-sha1 to be used
+    at all.  The default value for this tag is false.  (Added in
+    release 1.21.)
+
+**allow_rc4**
+    Permit the KDC to issue tickets with arcfour-hmac session keys.
+    In future releases, this flag will allow arcfour-hmac to be used
+    at all.  The default value for this tag is false.  (Added in
+    release 1.21.)
+
 **allow_weak_crypto**
     If this flag is set to false, then weak encryption types (as noted
     in :ref:`Encryption_types` in :ref:`kdc.conf(5)`) will be filtered
index 694922c0d98b8059e2a53709b00a2b0ea3cd3db8..dce19ad43e63d1f8bfe141710f6e5e96e732d80d 100644 (file)
@@ -48,12 +48,15 @@ Session key selection
 The KDC chooses the session key enctype by taking the intersection of
 its **permitted_enctypes** list, the list of long-term keys for the
 most recent kvno of the service, and the client's requested list of
-enctypes.
+enctypes.  Starting in krb5-1.21, all services are assumed to support
+aes256-cts-hmac-sha1-96; also, des3-cbc-sha1 and arcfour-hmac session
+keys will not be issued by default.
 
 Starting in krb5-1.11, it is possible to set a string attribute on a
 service principal to control what session key enctypes the KDC may
-issue for service tickets for that principal.  See :ref:`set_string`
-in :ref:`kadmin(1)` for details.
+issue for service tickets for that principal, overriding the service's
+long-term keys and the assumption of aes256-cts-hmac-sha1-96 support.
+See :ref:`set_string` in :ref:`kadmin(1)` for details.
 
 
 Choosing enctypes for a service
@@ -87,6 +90,20 @@ affect how enctypes are chosen.
     acceptable risk for your environment and the weak enctypes are
     required for backward compatibility.
 
+**allow_des3**
+    was added in release 1.21 and defaults to *false*.  Unless this
+    flag is set to *true*, the KDC will not issue tickets with
+    des3-cbc-sha1 session keys.  In a future release, this flag will
+    control whether des3-cbc-sha1 is permitted in similar fashion to
+    weak enctypes.
+
+**allow_rc4**
+    was added in release 1.21 and defaults to *false*.  Unless this
+    flag is set to *true*, the KDC will not issue tickets with
+    arcfour-hmac session keys.  In a future release, this flag will
+    control whether arcfour-hmac is permitted in similar fashion to
+    weak enctypes.
+
 **permitted_enctypes**
     controls the set of enctypes that a service will permit for
     session keys and for ticket and authenticator encryption.  The KDC
index 1d1c8293f40f19239827ba79091c597d29d37dd1..2f7791b775dff08a5fba53ef79772810eb41d6d4 100644 (file)
@@ -180,6 +180,8 @@ typedef unsigned char   u_char;
  * matches the variable name.  Keep these alphabetized. */
 #define KRB5_CONF_ACL_FILE                     "acl_file"
 #define KRB5_CONF_ADMIN_SERVER                 "admin_server"
+#define KRB5_CONF_ALLOW_DES3                   "allow_des3"
+#define KRB5_CONF_ALLOW_RC4                    "allow_rc4"
 #define KRB5_CONF_ALLOW_WEAK_CRYPTO            "allow_weak_crypto"
 #define KRB5_CONF_AUTH_TO_LOCAL                "auth_to_local"
 #define KRB5_CONF_AUTH_TO_LOCAL_NAMES          "auth_to_local_names"
@@ -1238,6 +1240,8 @@ struct _krb5_context {
     struct _kdb_log_context *kdblog_context;
 
     krb5_boolean allow_weak_crypto;
+    krb5_boolean allow_des3;
+    krb5_boolean allow_rc4;
     krb5_boolean ignore_acceptor_hostname;
     krb5_boolean enforce_ok_as_delegate;
     enum dns_canonhost dns_canonicalize_hostname;
index 0c846c1a8e9a204b1fa1da81546e25edac9880bd..932eeb88013a273409a503cae16e922218927826 100644 (file)
@@ -1032,6 +1032,16 @@ select_session_keytype(krb5_context context, krb5_db_entry *server,
         if (!krb5_is_permitted_enctype(context, ktype[i]))
             continue;
 
+        /*
+         * Prevent these deprecated enctypes from being used as session keys
+         * unless they are explicitly allowed.  In the future they will be more
+         * comprehensively disabled and eventually removed.
+         */
+        if (ktype[i] == ENCTYPE_DES3_CBC_SHA1 && !context->allow_des3)
+            continue;
+        if (ktype[i] == ENCTYPE_ARCFOUR_HMAC && !context->allow_rc4)
+            continue;
+
         if (dbentry_supports_enctype(context, server, ktype[i]))
             return ktype[i];
     }
index 1b420a3ac262b0a1a5e3b804e4e6f0324581aba0..ea089f0fcc524b7a555285fc477f0948f3416f0a 100644 (file)
@@ -1582,22 +1582,31 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
     (*prompter)(context, data, 0, banner, 0, 0);
 }
 
-/* Display a warning via the prompter if des3-cbc-sha1 was used for either the
- * reply key or the session key. */
+/* Display a warning via the prompter if a deprecated enctype was used for
+ * either the reply key or the session key. */
 static void
-warn_des3(krb5_context context, krb5_init_creds_context ctx,
-          krb5_enctype as_key_enctype)
+warn_deprecated(krb5_context context, krb5_init_creds_context ctx,
+                krb5_enctype as_key_enctype)
 {
-    const char *banner;
+    krb5_enctype etype;
+    char encbuf[128], banner[256];
 
-    if (as_key_enctype != ENCTYPE_DES3_CBC_SHA1 &&
-        ctx->cred.keyblock.enctype != ENCTYPE_DES3_CBC_SHA1)
-        return;
     if (ctx->prompter == NULL)
         return;
 
-    banner = _("Warning: encryption type des3-cbc-sha1 used for "
-               "authentication is weak and will be disabled");
+    if (krb5int_c_deprecated_enctype(as_key_enctype))
+        etype = as_key_enctype;
+    else if (krb5int_c_deprecated_enctype(ctx->cred.keyblock.enctype))
+        etype = ctx->cred.keyblock.enctype;
+    else
+        return;
+
+    if (krb5_enctype_to_name(etype, FALSE, encbuf, sizeof(encbuf)) != 0)
+        return;
+    snprintf(banner, sizeof(banner),
+             _("Warning: encryption type %s used for authentication is "
+               "deprecated and will be disabled"), encbuf);
+
     /* PROMPTER_INVOCATION */
     (*ctx->prompter)(context, ctx->prompter_data, NULL, banner, 0, NULL);
 }
@@ -1848,7 +1857,7 @@ init_creds_step_reply(krb5_context context,
     ctx->complete = TRUE;
     warn_pw_expiry(context, ctx->opt, ctx->prompter, ctx->prompter_data,
                    ctx->in_tkt_service, ctx->reply);
-    warn_des3(context, ctx, encrypting_key.enctype);
+    warn_deprecated(context, ctx, encrypting_key.enctype);
 
 cleanup:
     krb5_free_pa_data(context, kdc_padata);
index 87b486c53ff97838166c1558323312b889abfd35..a6c2bbeb54c4add791eeebadef6a82dd8e5bceeb 100644 (file)
@@ -221,6 +221,16 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
         goto cleanup;
     ctx->allow_weak_crypto = tmp;
 
+    retval = get_boolean(ctx, KRB5_CONF_ALLOW_DES3, 0, &tmp);
+    if (retval)
+        goto cleanup;
+    ctx->allow_des3 = tmp;
+
+    retval = get_boolean(ctx, KRB5_CONF_ALLOW_RC4, 0, &tmp);
+    if (retval)
+        goto cleanup;
+    ctx->allow_rc4 = tmp;
+
     retval = get_boolean(ctx, KRB5_CONF_IGNORE_ACCEPTOR_HOSTNAME, 0, &tmp);
     if (retval)
         goto cleanup;
index 7494d7fcdb30ddc765d348299953760ecfc1dade..f5f11842e21ba87dc4140449a9ae2e7853d13404 100755 (executable)
@@ -18,7 +18,8 @@ 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.
 supp='aes256-cts:normal aes128-cts:normal des3-cbc-sha1:normal rc4-hmac:normal'
-conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4'},
+conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4',
+                        'allow_des3': 'true', 'allow_rc4': 'true'},
         'realms': {'$realm': {'supported_enctypes': supp}}}
 realm = K5Realm(krb5_conf=conf)
 shutil.copyfile(realm.ccache, os.path.join(realm.testdir, 'save'))
index c982508d8bc0edb1e3f8f4ff3523bb6d7ed1dc5a..38cf96ca8f92611695295f0eb6f5bffb73009079 100644 (file)
@@ -1,7 +1,7 @@
 from k5test import *
 
 supported_enctypes = 'aes128-cts des3-cbc-sha1 rc4-hmac'
-conf = {'libdefaults': {'allow_weak_crypto': 'true'},
+conf = {'libdefaults': {'allow_des3': 'true', 'allow_rc4': 'true'},
         'realms': {'$realm': {'supported_enctypes': supported_enctypes}}}
 realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf)
 
index 9024aee838e77bb26c505ec646ccc3bd0296eef7..5a213617b525da53c3ee85ddfc152a85f04dfd1c 100755 (executable)
@@ -25,6 +25,8 @@ conf3 = {'libdefaults': {
         'default_tkt_enctypes': 'aes128-cts',
         'default_tgs_enctypes': 'rc4-hmac,aes128-cts'}}
 conf4 = {'libdefaults': {'permitted_enctypes': 'aes256-cts'}}
+conf5 = {'libdefaults': {'allow_rc4': 'true'}}
+conf6 = {'libdefaults': {'allow_des3': 'true'}}
 # Test with client request and session_enctypes preferring aes128, but
 # aes256 long-term key.
 realm = K5Realm(krb5_conf=conf1, create_host=False, get_creds=False)
@@ -54,10 +56,12 @@ realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
            'aes128-cts,aes256-cts'])
 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.
+# 3b: Skip RC4 (as the KDC does not allow it for session keys by
+# default) and negotiate aes128-cts session key, with only an aes256
+# long-term service key.
 realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
            'rc4-hmac,aes128-cts,aes256-cts'])
-test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
+test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
 realm.stop()
 
 # 4: Check that permitted_enctypes is a default for session key enctypes.
@@ -67,4 +71,24 @@ realm.run([kvno, 'user'],
           expected_trace=('etypes requested in TGS request: aes256-cts',))
 realm.stop()
 
+# 5: allow_rc4 permits negotiation of rc4-hmac session key.
+realm = K5Realm(krb5_conf=conf5, create_host=False, get_creds=False)
+realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
+realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'rc4-hmac'])
+test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
+realm.stop()
+
+# 6: allow_des3 permits negotiation of des3-cbc-sha1 session key.
+realm = K5Realm(krb5_conf=conf6, create_host=False, get_creds=False)
+realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
+realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'des3-cbc-sha1'])
+test_kvno(realm, 'DEPRECATED:des3-cbc-sha1', 'aes256-cts-hmac-sha1-96')
+realm.stop()
+
+# 7: default config negotiates aes256-sha1 session key for RC4-only service.
+realm = K5Realm(create_host=False, get_creds=False)
+realm.run([kadminl, 'addprinc', '-randkey', '-e', 'rc4-hmac', 'server'])
+test_kvno(realm, 'aes256-cts-hmac-sha1-96', 'DEPRECATED:arcfour-hmac')
+realm.stop()
+
 success('sesskeynego')
index 2a86c5cdfc24c5c683dad0fd53fc1c2076a201e9..8e5f5ba8e9efd317bf9d40984cb7c57ef99f1cc5 100644 (file)
@@ -1340,14 +1340,14 @@ _passes = [
 
     # Exercise the DES3 enctype.
     ('des3', None,
-     {'libdefaults': {'permitted_enctypes': 'des3'}},
+     {'libdefaults': {'permitted_enctypes': 'des3 aes256-sha1'}},
      {'realms': {'$realm': {
                     'supported_enctypes': 'des3-cbc-sha1:normal',
                     'master_key_type': 'des3-cbc-sha1'}}}),
 
     # Exercise the arcfour enctype.
     ('arcfour', None,
-     {'libdefaults': {'permitted_enctypes': 'rc4'}},
+     {'libdefaults': {'permitted_enctypes': 'rc4 aes256-sha1'}},
      {'realms': {'$realm': {
                     'supported_enctypes': 'arcfour-hmac:normal',
                     'master_key_type': 'arcfour-hmac'}}}),