CVE-2022-37966 kdc: Implement new Kerberos session key behaviour since ENC_HMAC_SHA1_...
authorAndrew Bartlett <abartlet@samba.org>
Tue, 1 Nov 2022 02:20:47 +0000 (15:20 +1300)
committerJoseph Sutton <josephsutton@catalyst.net.nz>
Wed, 3 May 2023 04:13:17 +0000 (16:13 +1200)
ENC_HMAC_SHA1_96_AES256_SK is a flag introduced for by Microsoft in this
CVE to indicate that additionally, AES session keys are available. We
set the etypes available for session keys depending on the encryption
types that are supported by the principal.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15219

Pair-Programmed-With: Joseph Sutton <josephsutton@catalyst.net.nz>

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
kdc/kerberos5.c
kdc/krb5tgs.c
kdc/misc.c
lib/hdb/hdb.asn1

index 21586a43c88da5e0f806583ccecad10682666640..ecca52cdcddbf23f89aa4dcdf5d8749ab1fb7da9 100644 (file)
@@ -384,6 +384,39 @@ _kdc_find_etype(astgs_request_t r, uint32_t flags,
     return ret;
 }
 
+/*
+ * The principal's session_etypes must be sorted in order of strength, with
+ * preferred etype first.
+*/
+krb5_error_code
+_kdc_find_session_etype(astgs_request_t r,
+                       krb5_enctype *etypes, size_t len,
+                       const hdb_entry *princ,
+                       krb5_enctype *ret_enctype)
+{
+    size_t i;
+
+    if (princ->session_etypes == NULL) {
+       /* The principal must have session etypes available. */
+       return KRB5KDC_ERR_ETYPE_NOSUPP;
+    }
+
+    /* Loop over the client's specified etypes. */
+    for (i = 0; i < len; ++i) {
+       size_t j;
+
+       /* Check that the server also supports the etype. */
+       for (j = 0; j < princ->session_etypes->len; ++j) {
+           if (princ->session_etypes->val[j] == etypes[i]) {
+               *ret_enctype = etypes[i];
+               return 0;
+           }
+       }
+    }
+
+    return KRB5KDC_ERR_ETYPE_NOSUPP;
+}
+
 krb5_error_code
 _kdc_make_anonymous_principalname (PrincipalName *pn)
 {
@@ -2206,14 +2239,19 @@ _kdc_as_rep(astgs_request_t r)
        goto out;
     }
 
+    /*
+     * This has to be here (not later), because we need to have r->sessionetype
+     * set prior to calling pa_pkinit_validate(), which in turn calls
+     * _kdc_pk_mk_pa_reply(), during padata validation.
+     */
+
     /*
      * Select an enctype for the to-be-issued ticket's session key using the
      * intersection of the client's requested enctypes and the server's (like a
      * root krbtgt, but not necessarily) etypes from its HDB entry.
      */
-    ret = _kdc_find_etype(r, (is_tgs ?  KFE_IS_TGS:0),
-                         b->etype.val, b->etype.len,
-                         &r->sessionetype, NULL, NULL);
+    ret = _kdc_find_session_etype(r, b->etype.val, b->etype.len,
+                                 r->server, &r->sessionetype);
     if (ret) {
        kdc_log(r->context, config, 4,
                "Client (%s) from %s has no common enctypes with KDC "
index 4f9d3c8ec2928900873b904f35c9ffdd051d565f..76f1210258679457b8db1c738c7a0b63e004312c 100644 (file)
@@ -1818,10 +1818,8 @@ server_lookup:
        } else {
            Key *skey;
 
-           ret = _kdc_find_etype(priv, krb5_principal_is_krbtgt(context, priv->server_princ)
-                                                            ? KFE_IS_TGS : 0,
-                                 b->etype.val, b->etype.len, &etype, NULL,
-                                 NULL);
+           ret = _kdc_find_session_etype(priv, b->etype.val, b->etype.len,
+                                         priv->server, &etype);
            if(ret) {
                kdc_log(context, config, 4,
                        "Server (%s) has no support for etypes", spn);
index 7db19e98362104d11a5d74a399999a925f5afb4b..477e4fabfb2cbc7c947f77e8d4578498a2f4e334 100644 (file)
@@ -301,9 +301,9 @@ _kdc_get_preferred_key(krb5_context context,
        }
     }
 
-    krb5_set_error_message(context, EINVAL,
+    krb5_set_error_message(context, ret = KRB5KDC_ERR_ETYPE_NOSUPP,
                           "No valid kerberos key found for %s", name);
-    return EINVAL; /* XXX */
+    return ret;
 }
 
 krb5_error_code
index abc75f742cc5b94a124193002c78822ad963c181..1a763de3d444b84c2092bb2436c2eeb0f60ff902 100644 (file)
@@ -237,7 +237,8 @@ HDB_entry ::= SEQUENCE {
        flags[10]       HDBFlags,
        etypes[11]      HDB-EncTypeList OPTIONAL,
        generation[12]  GENERATION OPTIONAL,
-        extensions[13]  HDB-extensions OPTIONAL
+        extensions[13]  HDB-extensions OPTIONAL,
+       session-etypes[14]      HDB-EncTypeList OPTIONAL
 }
 
 HDB_entry_alias ::= [APPLICATION 0] SEQUENCE {