Skip to content

Commit

Permalink
Don't issue session keys with deprecated enctypes
Browse files Browse the repository at this point in the history
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
  • Loading branch information
greghudson committed Jan 23, 2023
1 parent 2cbd847 commit 1b57a4d
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 20 deletions.
12 changes: 12 additions & 0 deletions doc/admin/conf_files/krb5_conf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 20 additions & 3 deletions doc/admin/enctypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions src/include/k5-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions src/kdc/kdc_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
Expand Down
31 changes: 20 additions & 11 deletions src/lib/krb5/krb/get_in_tkt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions src/lib/krb5/krb/init_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion src/tests/gssapi/t_enctypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
# 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'))
Expand Down
2 changes: 1 addition & 1 deletion src/tests/t_etype_info.py
Original file line number Diff line number Diff line change
@@ -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)

Expand Down
28 changes: 26 additions & 2 deletions src/tests/t_sesskeynego.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def test_kvno(realm, expected_skey, expected_tkt):
'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)
Expand Down Expand Up @@ -54,10 +56,12 @@ def test_kvno(realm, expected_skey, expected_tkt):
'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.
Expand All @@ -67,4 +71,24 @@ def test_kvno(realm, expected_skey, expected_tkt):
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')
4 changes: 2 additions & 2 deletions src/util/k5test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1340,14 +1340,14 @@ def cross_realms(num, xtgts=None, args=None, **keywords):

# 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'}}}),
Expand Down

0 comments on commit 1b57a4d

Please sign in to comment.