diff --git a/Allow-client-canonicalization-in-non-krbtgt-AS-REP.patch b/Allow-client-canonicalization-in-non-krbtgt-AS-REP.patch new file mode 100644 index 0000000..4402203 --- /dev/null +++ b/Allow-client-canonicalization-in-non-krbtgt-AS-REP.patch @@ -0,0 +1,64 @@ +From 0bbb2104fd6c494552c9261137fac782941b6440 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Tue, 15 Oct 2019 20:41:49 +0300 +Subject: [PATCH] Allow client canonicalization in non-krbtgt AS-REP + +If a caller makes an AS-REQ with the canonicalize flag set (or with an +enterprise client principal or the anonymous flag), always allow the +KDC to change the client principal. Continue to restrict server name +changes to requests for TGS principals. + +Also remove the conditional for setting canon_ok for fully anonymous +requests. Both kinds of anonymous requests change the client +principal or realm, but neither kind changes the server principal or +realm, so this logic is no longer needed now that canon_ok only +applies to server name changes. + +[ghudson@mit.edu: clarified commit message; removed anonymous PKINIT +clause] + +ticket: 8843 (new) +(cherry picked from commit c6c19b1d35c6523cb7ed220c1f2e97e12e039293) +--- + src/lib/krb5/krb/get_in_tkt.c | 9 ++------- + src/tests/t_kdb.py | 3 +++ + 2 files changed, 5 insertions(+), 7 deletions(-) + +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 79dede2c6..9ee605888 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -230,17 +230,12 @@ verify_as_reply(krb5_context context, + if (canon_req) { + canon_ok = IS_TGS_PRINC(request->server) && + IS_TGS_PRINC(as_reply->enc_part2->server); +- if (!canon_ok && (request->kdc_options & KDC_OPT_REQUEST_ANONYMOUS)) { +- canon_ok = krb5_principal_compare_any_realm(context, +- as_reply->client, +- krb5_anonymous_principal()); +- } + } else + canon_ok = 0; + + if ((!canon_ok && +- (!krb5_principal_compare(context, as_reply->client, request->client) || +- !krb5_principal_compare(context, as_reply->enc_part2->server, request->server))) ++ !krb5_principal_compare(context, as_reply->enc_part2->server, request->server)) ++ || (!canon_req && !krb5_principal_compare(context, as_reply->client, request->client)) + || !krb5_principal_compare(context, as_reply->enc_part2->server, as_reply->ticket->server) + || (request->nonce != as_reply->enc_part2->nonce) + /* XXX check for extraneous flags */ +diff --git a/src/tests/t_kdb.py b/src/tests/t_kdb.py +index 7a082a5b9..cc5d2fc3c 100755 +--- a/src/tests/t_kdb.py ++++ b/src/tests/t_kdb.py +@@ -389,6 +389,9 @@ realm.run([kadminl, 'modprinc', '+requires_preauth', 'canon']) + realm.kinit('canon', password('canon')) + realm.kinit('alias', password('canon'), ['-C']) + ++# Test client name canonicalization in non-krbtgt AS reply ++realm.kinit('alias', password('canon'), ['-C', '-S', 'kadmin/changepw']) ++ + mark('LDAP password history') + + # Test password history. diff --git a/Clear-forwardable-flag-instead-of-denying-request.patch b/Clear-forwardable-flag-instead-of-denying-request.patch index fd8a240..88e3641 100644 --- a/Clear-forwardable-flag-instead-of-denying-request.patch +++ b/Clear-forwardable-flag-instead-of-denying-request.patch @@ -14,14 +14,14 @@ ticket: 7871 (cherry picked from commit 08e948cce2c79a3604066fcf7a64fc527456f83d) --- src/kdc/do_as_req.c | 19 ++------ - src/kdc/do_tgs_req.c | 58 +++++----------------- + src/kdc/do_tgs_req.c | 56 ++++----------------- src/kdc/kdc_util.c | 82 ++++++++++++++++++------------- src/kdc/kdc_util.h | 9 ++-- src/kdc/tgs_policy.c | 8 +-- src/tests/Makefile.in | 1 + src/tests/gcred.c | 28 ++++++++--- src/tests/t_kdcoptions.py | 100 ++++++++++++++++++++++++++++++++++++++ - 8 files changed, 190 insertions(+), 115 deletions(-) + 8 files changed, 189 insertions(+), 114 deletions(-) create mode 100644 src/tests/t_kdcoptions.py diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c @@ -146,10 +146,9 @@ index 587342a6c..1da099318 100644 - if (isflagset(request->kdc_options, KDC_OPT_REQUEST_ANONYMOUS) && - !isflagset(header_enc_tkt->flags, TKT_FLG_ANONYMOUS)) - clear(enc_tkt_reply.flags, TKT_FLG_ANONYMOUS); -- + - if (isflagset(request->kdc_options, KDC_OPT_POSTDATED)) { - setflag(enc_tkt_reply.flags, TKT_FLG_INVALID); -+ + if (isflagset(request->kdc_options, KDC_OPT_POSTDATED)) enc_tkt_reply.times.starttime = request->from; - } else diff --git a/Do-not-always-canonicalize-enterprise-principals.patch b/Do-not-always-canonicalize-enterprise-principals.patch new file mode 100644 index 0000000..fcaed36 --- /dev/null +++ b/Do-not-always-canonicalize-enterprise-principals.patch @@ -0,0 +1,113 @@ +From f1890cb3b09789e62c6711d79b032a7af0a09ea8 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Sat, 2 Nov 2019 13:32:32 +0100 +Subject: [PATCH] Do not always canonicalize enterprise principals + +When processing an AS request in the KDC, do not assume +KRB5_KDB_FLAG_CANONICALIZE for enterprise client names. This change +allows the KDB module to only canonicalize enterprise client names if +the canonicalize flag was set on the request, as Windows does. The +KDB module may check the principal type and apply canonicalization as +appropriate. + +[ghudson@mit.edu: edited comments; rewrote commit message] + +ticket: 8858 (new) +(cherry picked from commit 3f5955631a2056f8ec4d1ce73d9681fa7da061c2) +--- + src/include/kdb.h | 21 ++++++++++++--------- + src/kdc/do_as_req.c | 9 ++++----- + src/tests/t_kdb.py | 12 ++++++++++++ + 3 files changed, 28 insertions(+), 14 deletions(-) + +diff --git a/src/include/kdb.h b/src/include/kdb.h +index 7749cfc99..1dd37cdab 100644 +--- a/src/include/kdb.h ++++ b/src/include/kdb.h +@@ -1023,15 +1023,18 @@ typedef struct _kdb_vftabl { + * in-realm alias, fill in a different value for entries->princ than the + * one requested. + * +- * A module can return out-of-realm referrals if KRB5_KDB_FLAG_CANONICALIZE +- * is set. For AS request clients (KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY is +- * also set), the module should do so by simply filling in an out-of-realm +- * name in entries->princ and setting all other fields to NULL. Otherwise, +- * the module should return the entry for the cross-realm TGS of the +- * referred-to realm. For TGS referals, the module can also include +- * tl-data of type KRB5_TL_SERVER_REFERRAL containing ASN.1-encoded Windows +- * referral data as documented in draft-ietf-krb-wg-kerberos-referrals-11 +- * appendix A; this will be returned to the client as encrypted padata. ++ * A module can return a referral to another realm if ++ * KRB5_KDB_FLAG_CANONICALIZE is set, or if ++ * KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY is set and search_for->type is ++ * KRB5_NT_ENTERPRISE_PRINCIPAL. If KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY is ++ * set, the module should return a referral by simply filling in an ++ * out-of-realm name in (*entry)->princ and setting all other fields to ++ * NULL. Otherwise, the module should return the entry for the cross-realm ++ * TGS of the referred-to realm. For TGS referals, the module can also ++ * include tl-data of type KRB5_TL_SERVER_REFERRAL containing ASN.1-encoded ++ * Windows referral data as documented in ++ * draft-ietf-krb-wg-kerberos-referrals-11 appendix A; this will be ++ * returned to the client as encrypted padata. + */ + krb5_error_code (*get_principal)(krb5_context kcontext, + krb5_const_principal search_for, +diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c +index 8a96c12a9..02c0a8a1f 100644 +--- a/src/kdc/do_as_req.c ++++ b/src/kdc/do_as_req.c +@@ -585,15 +585,14 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt, + * of cross realm TGS entries. + */ + setflag(state->c_flags, KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY); +- /* +- * Note that according to the referrals draft we should +- * always canonicalize enterprise principal names. +- */ ++ /* Enterprise principals are implicitly alias-ok. */ + if (isflagset(state->request->kdc_options, KDC_OPT_CANONICALIZE) || + state->request->client->type == KRB5_NT_ENTERPRISE_PRINCIPAL) { +- setflag(state->c_flags, KRB5_KDB_FLAG_CANONICALIZE); + setflag(state->c_flags, KRB5_KDB_FLAG_ALIAS_OK); + } ++ if (isflagset(state->request->kdc_options, KDC_OPT_CANONICALIZE)) { ++ setflag(state->c_flags, KRB5_KDB_FLAG_CANONICALIZE); ++ } + if (include_pac_p(kdc_context, state->request)) { + setflag(state->c_flags, KRB5_KDB_FLAG_INCLUDE_PAC); + } +diff --git a/src/tests/t_kdb.py b/src/tests/t_kdb.py +index cc5d2fc3c..7271fcbbd 100755 +--- a/src/tests/t_kdb.py ++++ b/src/tests/t_kdb.py +@@ -340,11 +340,14 @@ ldap_modify('dn: krbPrincipalName=canon@KRBTEST.COM,cn=t1,cn=krb5\n' + 'changetype: modify\n' + 'add: krbPrincipalName\n' + 'krbPrincipalName: alias@KRBTEST.COM\n' ++ 'krbPrincipalName: ent@abc@KRBTEST.COM\n' + '-\n' + 'add: krbCanonicalName\n' + 'krbCanonicalName: canon@KRBTEST.COM\n') + realm.run([kadminl, 'getprinc', 'alias'], + expected_msg='Principal: canon@KRBTEST.COM\n') ++realm.run([kadminl, 'getprinc', 'ent\@abc'], ++ expected_msg='Principal: canon@KRBTEST.COM\n') + realm.run([kadminl, 'getprinc', 'canon'], + expected_msg='Principal: canon@KRBTEST.COM\n') + realm.run([kvno, 'alias', 'canon']) +@@ -389,6 +392,15 @@ realm.run([kadminl, 'modprinc', '+requires_preauth', 'canon']) + realm.kinit('canon', password('canon')) + realm.kinit('alias', password('canon'), ['-C']) + ++# Test enterprise alias with and without canonicalization. ++realm.kinit('ent@abc', password('canon'), ['-E', '-C']) ++realm.run([kvno, 'alias']) ++realm.klist('canon@KRBTEST.COM', 'alias@KRBTEST.COM') ++ ++realm.kinit('ent@abc', password('canon'), ['-E']) ++realm.run([kvno, 'alias']) ++realm.klist('ent\@abc@KRBTEST.COM', 'alias@KRBTEST.COM') ++ + # Test client name canonicalization in non-krbtgt AS reply + realm.kinit('alias', password('canon'), ['-C', '-S', 'kadmin/changepw']) + diff --git a/Don-t-warn-in-kadmin-when-no-policy-is-specified.patch b/Don-t-warn-in-kadmin-when-no-policy-is-specified.patch new file mode 100644 index 0000000..220c59f --- /dev/null +++ b/Don-t-warn-in-kadmin-when-no-policy-is-specified.patch @@ -0,0 +1,160 @@ +From aec16ed11477f08f477f915fb8119271d688711c Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Thu, 19 Dec 2019 17:49:05 -0500 +Subject: [PATCH] Don't warn in kadmin when no policy is specified + +Not having policy defined is a normal occurrence. While it's a useful +message to log in case it's unexpected, the current form is +unnecessarily alarmist. + +ticket: 8857 (new) +(cherry picked from commit 2ca842d5cbd5981ab5fa50e418359763c9f1a6d5) +--- + doc/admin/admin_commands/kadmin_local.rst | 2 +- + doc/admin/database.rst | 4 ++-- + doc/admin/install_kdc.rst | 6 +++--- + src/kadmin/cli/kadmin.c | 4 ++-- + src/man/kadmin.man | 2 +- + src/po/de.po | 8 ++++---- + src/po/mit-krb5.pot | 4 ++-- + 7 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/doc/admin/admin_commands/kadmin_local.rst b/doc/admin/admin_commands/kadmin_local.rst +index 71aa894f6..fafa61365 100644 +--- a/doc/admin/admin_commands/kadmin_local.rst ++++ b/doc/admin/admin_commands/kadmin_local.rst +@@ -419,7 +419,7 @@ Options: + Example:: + + kadmin: addprinc jennifer +- WARNING: no policy specified for "jennifer@ATHENA.MIT.EDU"; ++ No policy specified for "jennifer@ATHENA.MIT.EDU"; + defaulting to no policy. + Enter password for principal jennifer@ATHENA.MIT.EDU: + Re-enter password for principal jennifer@ATHENA.MIT.EDU: +diff --git a/doc/admin/database.rst b/doc/admin/database.rst +index cea60b009..8505fe1ec 100644 +--- a/doc/admin/database.rst ++++ b/doc/admin/database.rst +@@ -103,7 +103,7 @@ If you want to create a principal which is contained by a LDAP object, + all you need to do is:: + + kadmin: addprinc -x dn=cn=jennifer,dc=example,dc=com jennifer +- WARNING: no policy specified for "jennifer@ATHENA.MIT.EDU"; ++ No policy specified for "jennifer@ATHENA.MIT.EDU"; + defaulting to no policy. + Enter password for principal jennifer@ATHENA.MIT.EDU: <= Type the password. + Re-enter password for principal jennifer@ATHENA.MIT.EDU: <=Type it again. +@@ -114,7 +114,7 @@ If you want to create a principal under a specific LDAP container and + link to an existing LDAP object, all you need to do is:: + + kadmin: addprinc -x containerdn=dc=example,dc=com -x linkdn=cn=david,dc=example,dc=com david +- WARNING: no policy specified for "david@ATHENA.MIT.EDU"; ++ No policy specified for "david@ATHENA.MIT.EDU"; + defaulting to no policy. + Enter password for principal david@ATHENA.MIT.EDU: <= Type the password. + Re-enter password for principal david@ATHENA.MIT.EDU: <=Type it again. +diff --git a/doc/admin/install_kdc.rst b/doc/admin/install_kdc.rst +index 3bec59f96..157c6059e 100644 +--- a/doc/admin/install_kdc.rst ++++ b/doc/admin/install_kdc.rst +@@ -239,7 +239,7 @@ is created:: + + kadmin.local: addprinc admin/admin@ATHENA.MIT.EDU + +- WARNING: no policy specified for "admin/admin@ATHENA.MIT.EDU"; ++ No policy specified for "admin/admin@ATHENA.MIT.EDU"; + assigning "default". + Enter password for principal admin/admin@ATHENA.MIT.EDU: <= Enter a password. + Re-enter password for principal admin/admin@ATHENA.MIT.EDU: <= Type it again. +@@ -316,11 +316,11 @@ following:: + + shell% kadmin + kadmin: addprinc -randkey host/kerberos.mit.edu +- NOTICE: no policy specified for "host/kerberos.mit.edu@ATHENA.MIT.EDU"; assigning "default" ++ No policy specified for "host/kerberos.mit.edu@ATHENA.MIT.EDU"; assigning "default" + Principal "host/kerberos.mit.edu@ATHENA.MIT.EDU" created. + + kadmin: addprinc -randkey host/kerberos-1.mit.edu +- NOTICE: no policy specified for "host/kerberos-1.mit.edu@ATHENA.MIT.EDU"; assigning "default" ++ No policy specified for "host/kerberos-1.mit.edu@ATHENA.MIT.EDU"; assigning "default" + Principal "host/kerberos-1.mit.edu@ATHENA.MIT.EDU" created. + + It is not strictly necessary to have the master KDC server in the +diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c +index b4d1aad93..a6e858d82 100644 +--- a/src/kadmin/cli/kadmin.c ++++ b/src/kadmin/cli/kadmin.c +@@ -1229,13 +1229,13 @@ kadmin_addprinc(int argc, char *argv[]) + /* If the policy "default" exists, assign it. */ + if (policy_exists("default")) { + if (!script_mode) { +- fprintf(stderr, _("NOTICE: no policy specified for %s; " ++ fprintf(stderr, _("No policy specified for %s; " + "assigning \"default\"\n"), canon); + } + princ.policy = "default"; + mask |= KADM5_POLICY; + } else if (!script_mode) { +- fprintf(stderr, _("WARNING: no policy specified for %s; " ++ fprintf(stderr, _("No policy specified for %s; " + "defaulting to no policy\n"), canon); + } + } +diff --git a/src/man/kadmin.man b/src/man/kadmin.man +index 44859a378..b514fe279 100644 +--- a/src/man/kadmin.man ++++ b/src/man/kadmin.man +@@ -458,7 +458,7 @@ Example: + .nf + .ft C + kadmin: addprinc jennifer +-WARNING: no policy specified for "jennifer@ATHENA.MIT.EDU"; ++No policy specified for "jennifer@ATHENA.MIT.EDU"; + defaulting to no policy. + Enter password for principal jennifer@ATHENA.MIT.EDU: + Re\-enter password for principal jennifer@ATHENA.MIT.EDU: +diff --git a/src/po/de.po b/src/po/de.po +index 40e31da90..5d78bdded 100644 +--- a/src/po/de.po ++++ b/src/po/de.po +@@ -1690,16 +1690,16 @@ msgstr "WARNUNG: Richtlinie »%s« existiert nicht.\n" + + #: ../../src/kadmin/cli/kadmin.c:1230 + #, c-format +-msgid "NOTICE: no policy specified for %s; assigning \"default\"\n" ++msgid "No policy specified for %s; assigning \"default\"\n" + msgstr "" +-"HINWEIS: Für %s wurde keine Richtlinie angegeben, es wird »default« " ++"Für %s wurde keine Richtlinie angegeben, es wird »default« " + "zugewiesen\n" + + #: ../../src/kadmin/cli/kadmin.c:1235 + #, c-format +-msgid "WARNING: no policy specified for %s; defaulting to no policy\n" ++msgid "No policy specified for %s; defaulting to no policy\n" + msgstr "" +-"WARNUNG: Für %s wurde keine Richtlinie angegeben, es wird die Vorgabe " ++"Für %s wurde keine Richtlinie angegeben, es wird die Vorgabe " + "»keine\n" + "Richtlinie« verwandt.\n" + +diff --git a/src/po/mit-krb5.pot b/src/po/mit-krb5.pot +index 8cfbe9f3c..de1998d2f 100644 +--- a/src/po/mit-krb5.pot ++++ b/src/po/mit-krb5.pot +@@ -1645,12 +1645,12 @@ msgstr "" + + #: ../../src/kadmin/cli/kadmin.c:1228 + #, c-format +-msgid "NOTICE: no policy specified for %s; assigning \"default\"\n" ++msgid "No policy specified for %s; assigning \"default\"\n" + msgstr "" + + #: ../../src/kadmin/cli/kadmin.c:1234 + #, c-format +-msgid "WARNING: no policy specified for %s; defaulting to no policy\n" ++msgid "No policy specified for %s; defaulting to no policy\n" + msgstr "" + + #: ../../src/kadmin/cli/kadmin.c:1276 diff --git a/Implement-krb5_cc_remove_cred-for-remaining-types.patch b/Implement-krb5_cc_remove_cred-for-remaining-types.patch index 23f9965..65ddcf7 100644 --- a/Implement-krb5_cc_remove_cred-for-remaining-types.patch +++ b/Implement-krb5_cc_remove_cred-for-remaining-types.patch @@ -266,25 +266,13 @@ index 8419f6ebf..98723fe2e 100644 - * with the time offsets, skip it. */ - while (krcursor->keys[krcursor->currkey] == krcursor->princ_id || - krcursor->keys[krcursor->currkey] == krcursor->offsets_id) { -- krcursor->currkey++; -- /* Check if we have now reached the end */ -- if (krcursor->currkey >= krcursor->numkeys) -- return KRB5_CC_END; -- } + /* Read the key; the right size buffer will be allocated and + * returned. */ + psize = keyctl_read_alloc(krcursor->keys[krcursor->currkey], + &payload); + if (psize != -1) { + krcursor->currkey++; - -- /* Read the key; the right size buffer will be allocated and returned. */ -- psize = keyctl_read_alloc(krcursor->keys[krcursor->currkey], &payload); -- if (psize == -1) { -- DEBUG_PRINT(("Error reading key %d: %s\n", -- krcursor->keys[krcursor->currkey], -- strerror(errno))); -- return KRB5_FCC_NOFILE; ++ + /* Unmarshal the cred using the file ccache version 4 format. */ + ret = k5_unmarshal_cred(payload, psize, 4, creds); + free(payload); @@ -297,10 +285,22 @@ index 8419f6ebf..98723fe2e 100644 + + /* The current key was unlinked, probably by a remove_cred call; move + * on to the next one. */ -+ krcursor->currkey++; + krcursor->currkey++; +- /* Check if we have now reached the end */ +- if (krcursor->currkey >= krcursor->numkeys) +- return KRB5_CC_END; } -- krcursor->currkey++; +- /* Read the key; the right size buffer will be allocated and returned. */ +- psize = keyctl_read_alloc(krcursor->keys[krcursor->currkey], &payload); +- if (psize == -1) { +- DEBUG_PRINT(("Error reading key %d: %s\n", +- krcursor->keys[krcursor->currkey], +- strerror(errno))); +- return KRB5_FCC_NOFILE; +- } +- krcursor->currkey++; +- - /* Unmarshal the credential using the file ccache version 4 format. */ - ret = k5_unmarshal_cred(payload, psize, 4, creds); - free(payload); diff --git a/Make-etype-names-in-KDC-logs-human-readable.patch b/Make-etype-names-in-KDC-logs-human-readable.patch index 462de34..451e554 100644 --- a/Make-etype-names-in-KDC-logs-human-readable.patch +++ b/Make-etype-names-in-KDC-logs-human-readable.patch @@ -12,9 +12,9 @@ ticket: 8772 (new) (cherry picked from commit a649279727490687d54becad91fde8cf7429d951) --- src/kdc/kdc_log.c | 42 +++++++-------- - src/kdc/kdc_util.c | 125 +++++++++++++++++++++++---------------------- + src/kdc/kdc_util.c | 131 +++++++++++++++++++++++---------------------- src/kdc/kdc_util.h | 6 +-- - 3 files changed, 87 insertions(+), 86 deletions(-) + 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 @@ -132,16 +132,57 @@ index 0155c28c6..f5c581c82 100644 - * 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) @@ -160,85 +201,47 @@ index 0155c28c6..f5c581c82 100644 + name = "des-ede3-cbc-EnvOID"; + else + return krb5_enctype_to_name(ktype, FALSE, buf, buflen); - --/* -- * 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) ++ + if (strlcpy(name, buf, buflen) >= buflen) + return ENOMEM; + return 0; -+} - --void --ktypes2str(char *s, size_t len, int nktypes, krb5_enctype *ktype) -+char * -+ktypes2str(krb5_enctype *ktype, int nktypes) - { -+ struct k5buf buf; - int i; -- char stmp[D_LEN(krb5_enctype) + 1]; -- char *p; -+ char name[64]; - -- if (nktypes < 0 -- || len < (sizeof(" etypes {...}") + D_LEN(int))) { -- *s = '\0'; -- return; -- } -+ if (nktypes < 0) -+ return NULL; - -- snprintf(s, len, "%d etypes {", nktypes); -+ k5_buf_init_dynamic(&buf); -+ k5_buf_add_fmt(&buf, "%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); -+ enctype_name(ktype[i], name, sizeof(name)); -+ k5_buf_add_fmt(&buf, "%s%s(%ld)", i ? ", " : "", name, (long)ktype[i]); - } -- 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; -+ k5_buf_add(&buf, "}"); -+ return buf.data; } -void -rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep) +char * -+rep_etypes2str(krb5_kdc_rep *rep) ++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; - -- snprintf(s, len, "etypes {rep=%ld", (long)rep->enc_part.enctype); ++ + k5_buf_init_dynamic(&buf); + k5_buf_add(&buf, "etypes {rep="); + enctype_name(rep->enc_part.enctype, name, sizeof(name)); diff --git a/Remove-3des-support.patch b/Remove-3des-support.patch index b3d12d0..dd68008 100644 --- a/Remove-3des-support.patch +++ b/Remove-3des-support.patch @@ -76,7 +76,7 @@ their constants. src/lib/gssapi/krb5/gssapiP_krb5.h | 6 +- src/lib/gssapi/krb5/k5seal.c | 35 +- src/lib/gssapi/krb5/k5sealiov.c | 27 +- - src/lib/gssapi/krb5/k5unseal.c | 88 ++-- + src/lib/gssapi/krb5/k5unseal.c | 102 ++--- src/lib/gssapi/krb5/k5unsealiov.c | 38 +- src/lib/gssapi/krb5/util_crypt.c | 11 - .../api.current/chpass-principal-v2.exp | 4 +- @@ -107,7 +107,7 @@ their constants. src/tests/t_salt.py | 5 +- src/util/k5test.py | 10 - .../leash/htmlhelp/html/Encryption_Types.htm | 13 - - 96 files changed, 157 insertions(+), 4831 deletions(-) + 96 files changed, 164 insertions(+), 4838 deletions(-) delete mode 100644 src/lib/crypto/builtin/des/ISSUES delete mode 100644 src/lib/crypto/builtin/des/Makefile.in delete mode 100644 src/lib/crypto/builtin/des/d3_aead.c @@ -5401,15 +5401,13 @@ index 9b183bc33..f0cc4a680 100644 + if (signalg != SGN_ALG_HMAC_MD5) { *minor_status = 0; return(GSS_S_DEFECTIVE_TOKEN); -+ } - +- - case SGN_ALG_HMAC_SHA1_DES3_KD: - case SGN_ALG_HMAC_MD5: - /* compute the checksum of the message */ - - /* 8 = bytes of token body to be checksummed according to spec */ -+ /* compute the checksum of the message */ - +- - if (! (data_ptr = xmalloc(8 + plainlen))) { - if (sealalg != 0xffff) - xfree(plain); @@ -5418,9 +5416,33 @@ index 9b183bc33..f0cc4a680 100644 - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } -+ /* 8 = bytes of token body to be checksummed according to spec */ - +- - (void) memcpy(data_ptr, ptr-2, 8); +- +- (void) memcpy(data_ptr+8, plain, plainlen); +- +- plaind.length = 8 + plainlen; +- plaind.data = data_ptr; +- code = krb5_k_make_checksum(context, md5cksum.checksum_type, +- ctx->seq, sign_usage, +- &plaind, &md5cksum); +- xfree(data_ptr); +- +- if (code) { +- if (toktype == KG_TOK_SEAL_MSG) +- gssalloc_free(token.value); +- *minor_status = code; +- return(GSS_S_FAILURE); +- } +- +- code = k5_bcmp(md5cksum.contents, ptr + 14, cksum_len); +- break; + } + ++ /* compute the checksum of the message */ ++ ++ /* 8 = bytes of token body to be checksummed according to spec */ ++ + if (! (data_ptr = xmalloc(8 + plainlen))) { + if (sealalg != 0xffff) + xfree(plain); @@ -5429,40 +5451,25 @@ index 9b183bc33..f0cc4a680 100644 + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } - -- (void) memcpy(data_ptr+8, plain, plainlen); ++ + (void) memcpy(data_ptr, ptr-2, 8); - -- plaind.length = 8 + plainlen; -- plaind.data = data_ptr; -- code = krb5_k_make_checksum(context, md5cksum.checksum_type, -- ctx->seq, sign_usage, -- &plaind, &md5cksum); -- xfree(data_ptr); ++ + (void) memcpy(data_ptr+8, plain, plainlen); - -- if (code) { -- if (toktype == KG_TOK_SEAL_MSG) -- gssalloc_free(token.value); -- *minor_status = code; -- return(GSS_S_FAILURE); -- } ++ + plaind.length = 8 + plainlen; + plaind.data = data_ptr; + code = krb5_k_make_checksum(context, md5cksum.checksum_type, + ctx->seq, sign_usage, + &plaind, &md5cksum); + xfree(data_ptr); - -- code = k5_bcmp(md5cksum.contents, ptr + 14, cksum_len); -- break; ++ + if (code) { + if (toktype == KG_TOK_SEAL_MSG) + gssalloc_free(token.value); + *minor_status = code; + return(GSS_S_FAILURE); - } - ++ } ++ + code = k5_bcmp(md5cksum.contents, ptr + 14, cksum_len); + krb5_free_checksum_contents(context, &md5cksum); diff --git a/Remove-Kerberos-v4-support-vestiges-from-ccapi.patch b/Remove-Kerberos-v4-support-vestiges-from-ccapi.patch index 93dc484..09280f0 100644 --- a/Remove-Kerberos-v4-support-vestiges-from-ccapi.patch +++ b/Remove-Kerberos-v4-support-vestiges-from-ccapi.patch @@ -9,7 +9,7 @@ Subject: [PATCH] Remove Kerberos v4 support vestiges from ccapi src/ccapi/lib/ccapi_v2.c | 34 +-- src/ccapi/lib/win/OldCC/ccapi.h | 20 -- src/ccapi/server/ccs_ccache.c | 69 +----- - src/ccapi/test/test_ccapi_ccache.c | 227 +++----------------- + src/ccapi/test/test_ccapi_ccache.c | 223 +++----------------- src/ccapi/test/test_ccapi_constants.c | 2 - src/ccapi/test/test_ccapi_context.c | 3 - src/ccapi/test/test_ccapi_v2.c | 89 -------- @@ -20,7 +20,7 @@ Subject: [PATCH] Remove Kerberos v4 support vestiges from ccapi src/windows/kfwlogon/kfwlogon.h | 2 +- src/windows/leashdll/leash-int.h | 2 +- src/windows/lib/cacheapi.h | 53 +---- - 15 files changed, 100 insertions(+), 873 deletions(-) + 15 files changed, 98 insertions(+), 871 deletions(-) diff --git a/src/ccapi/common/cci_cred_union.c b/src/ccapi/common/cci_cred_union.c index 4c8981610..424a93dab 100644 @@ -760,8 +760,29 @@ index a0fd84af1..fe63e6710 100644 - cc_ccache_destroy(ccache); - ccache = NULL; - } -- -- ++ // replace v5 only ccache's principal ++ if (!err) { ++ err = cc_context_create_new_ccache(context, cc_credentials_v5, ++ "foo@BAZ.ORG", &ccache); ++ } ++ if (!err) { ++ check_once_cc_ccache_set_principal( ++ ccache, cc_credentials_v5, "foo/BAZ@BAR.ORG", ccNoError, ++ "replace v5 only ccache's principal (empty ccache)"); ++ } ++ else { ++ log_error( ++ "cc_context_create_new_ccache failed, can't complete test"); ++ failure_count++; ++ } + ++ // bad params ++ if (!err) { ++ check_once_cc_ccache_set_principal(ccache, cc_credentials_v5, ++ NULL, ccErrBadParam, ++ "NULL principal"); ++ } + - // empty ccache - - // replace v5 only ccache's principal @@ -837,29 +858,6 @@ index a0fd84af1..fe63e6710 100644 - // replace v4 only ccache's principal - - // add v5 principal to v4 only ccache -+ // replace v5 only ccache's principal -+ if (!err) { -+ err = cc_context_create_new_ccache(context, cc_credentials_v5, -+ "foo@BAZ.ORG", &ccache); -+ } -+ if (!err) { -+ check_once_cc_ccache_set_principal( -+ ccache, cc_credentials_v5, "foo/BAZ@BAR.ORG", ccNoError, -+ "replace v5 only ccache's principal (empty ccache)"); -+ } -+ else { -+ log_error( -+ "cc_context_create_new_ccache failed, can't complete test"); -+ failure_count++; -+ } -+ -+ // bad params -+ if (!err) { -+ check_once_cc_ccache_set_principal(ccache, cc_credentials_v5, -+ NULL, ccErrBadParam, -+ "NULL principal"); -+ } -+ + if (ccache) { + cc_ccache_destroy(ccache); + ccache = NULL; @@ -894,7 +892,8 @@ index a0fd84af1..fe63e6710 100644 } if (!err) { - check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, &time_offset, ccNoError, "offset set for v5 but not v4"); -- } ++ check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, &time_offset, ccNoError, "offset set for v5"); + } - if (!err) { - check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4, &time_offset, ccErrTimeOffsetNotSet, "asking for v4 offset when only v5 is set"); - } @@ -903,10 +902,9 @@ index a0fd84af1..fe63e6710 100644 - } - if (!err) { - check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4, &time_offset, ccNoError, "asking for v4 offset when v4 and v5 are set"); -+ check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, &time_offset, ccNoError, "offset set for v5"); - } - +- } - + check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, NULL, ccErrBadParam, "NULL time_offset out param"); - check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4_v5, &time_offset, ccErrBadCredentialsVersion, "v4_v5 creds_vers in param (invalid)"); diff --git a/Remove-PKINIT-draft-9-support.patch b/Remove-PKINIT-draft-9-support.patch index 2ac0254..c5b45f2 100644 --- a/Remove-PKINIT-draft-9-support.patch +++ b/Remove-PKINIT-draft-9-support.patch @@ -15,12 +15,12 @@ ticket: 8817 (new) src/plugins/preauth/pkinit/pkinit_accessor.h | 6 - src/plugins/preauth/pkinit/pkinit_clnt.c | 231 +++----- src/plugins/preauth/pkinit/pkinit_crypto.h | 1 - - .../preauth/pkinit/pkinit_crypto_openssl.c | 221 ++------ + .../preauth/pkinit/pkinit_crypto_openssl.c | 219 ++----- src/plugins/preauth/pkinit/pkinit_lib.c | 65 --- - src/plugins/preauth/pkinit/pkinit_srv.c | 531 +++++------------- + src/plugins/preauth/pkinit/pkinit_srv.c | 543 ++++++------------ src/plugins/preauth/pkinit/pkinit_trace.h | 4 - src/tests/t_pkinit.py | 6 +- - 10 files changed, 277 insertions(+), 809 deletions(-) + 10 files changed, 282 insertions(+), 814 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h index fe2ec0d31..b437fd53f 100644 @@ -214,7 +214,18 @@ index 58400d555..1a642139a 100644 - auth_pack.clientDHNonce.length = 0; - auth_pack.clientPublicValue = &info; - auth_pack.supportedKDFs = (krb5_data **)supported_kdf_alg_ids; -- ++ memset(&info, 0, sizeof(info)); ++ memset(&auth_pack, 0, sizeof(auth_pack)); ++ auth_pack.pkAuthenticator.ctime = ctsec; ++ auth_pack.pkAuthenticator.cusec = cusec; ++ auth_pack.pkAuthenticator.nonce = nonce; ++ auth_pack.pkAuthenticator.paChecksum = *cksum; ++ if (!reqctx->opts->disable_freshness) ++ auth_pack.pkAuthenticator.freshnessToken = reqctx->freshness_token; ++ auth_pack.clientDHNonce.length = 0; ++ auth_pack.clientPublicValue = &info; ++ auth_pack.supportedKDFs = (krb5_data **)supported_kdf_alg_ids; + - /* add List of CMS algorithms */ - retval = create_krb5_supportedCMSTypes(context, plgctx->cryptoctx, - reqctx->cryptoctx, @@ -227,18 +238,6 @@ index 58400d555..1a642139a 100644 - pkiDebug("as_req: unrecognized pa_type = %d\n", - (int)reqctx->pa_type); - retval = -1; -+ memset(&info, 0, sizeof(info)); -+ memset(&auth_pack, 0, sizeof(auth_pack)); -+ auth_pack.pkAuthenticator.ctime = ctsec; -+ auth_pack.pkAuthenticator.cusec = cusec; -+ auth_pack.pkAuthenticator.nonce = nonce; -+ auth_pack.pkAuthenticator.paChecksum = *cksum; -+ if (!reqctx->opts->disable_freshness) -+ auth_pack.pkAuthenticator.freshnessToken = reqctx->freshness_token; -+ auth_pack.clientDHNonce.length = 0; -+ auth_pack.clientPublicValue = &info; -+ auth_pack.supportedKDFs = (krb5_data **)supported_kdf_alg_ids; -+ + /* add List of CMS algorithms */ + retval = create_krb5_supportedCMSTypes(context, plgctx->cryptoctx, + reqctx->cryptoctx, @@ -356,19 +355,20 @@ index 58400d555..1a642139a 100644 - &req9->signedAuthPack.data, - &req9->signedAuthPack.length); - break; -+ &req->signedAuthPack.data, -+ &req->signedAuthPack.length); -+ } -+ - #ifdef DEBUG_ASN1 +-#ifdef DEBUG_ASN1 - print_buffer_bin((unsigned char *)req9->signedAuthPack.data, - req9->signedAuthPack.length, - "/tmp/client_signed_data_draft9"); +-#endif ++ &req->signedAuthPack.data, ++ &req->signedAuthPack.length); + } ++ ++#ifdef DEBUG_ASN1 + print_buffer_bin((unsigned char *)req->signedAuthPack.data, + req->signedAuthPack.length, + "/tmp/client_signed_data"); - #endif -- } ++#endif + krb5_free_data(context, coded_auth_pack); if (retval) { @@ -556,7 +556,13 @@ index 8aa2c5257..8c7fd0cca 100644 - goto cleanup2; - PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, - V_ASN1_OBJECT, oid_copy); -- ++ /* create a content-type attr */ ++ oid_copy = OBJ_dup(oid); ++ if (oid_copy == NULL) ++ goto cleanup2; ++ PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, ++ V_ASN1_OBJECT, oid_copy); + - /* create the signature over signed attributes. get DER encoded value */ - /* This is the place where smartcard signature needs to be calculated */ - sk = p7si->auth_attr; @@ -565,13 +571,6 @@ index 8aa2c5257..8c7fd0cca 100644 - if (abuf == NULL) - goto cleanup2; - } /* signed attributes */ -+ /* create a content-type attr */ -+ oid_copy = OBJ_dup(oid); -+ if (oid_copy == NULL) -+ goto cleanup2; -+ PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, -+ V_ASN1_OBJECT, oid_copy); -+ + /* create the signature over signed attributes. get DER encoded value */ + /* This is the place where smartcard signature needs to be calculated */ + sk = p7si->auth_attr; @@ -1041,38 +1040,47 @@ index 6aa646cc6..c44be9c74 100644 if (retval) { TRACE_PKINIT_SERVER_PADATA_VERIFY_FAIL(context); goto cleanup; -@@ -541,117 +513,87 @@ pkinit_server_verify_padata(krb5_context context, +@@ -541,118 +513,88 @@ pkinit_server_verify_padata(krb5_context context, #endif OCTETDATA_TO_KRB5DATA(&authp_data, &k5data); - switch ((int)data->pa_type) { - case KRB5_PADATA_PK_AS_REQ: - retval = k5int_decode_krb5_auth_pack(&k5data, &auth_pack); -- if (retval) { -- pkiDebug("failed to decode krb5_auth_pack\n"); -- goto cleanup; -- } -- -- retval = krb5_check_clockskew(context, -- auth_pack->pkAuthenticator.ctime); -- if (retval) -- goto cleanup; + retval = k5int_decode_krb5_auth_pack(&k5data, &auth_pack); + if (retval) { + pkiDebug("failed to decode krb5_auth_pack\n"); + goto cleanup; + } - ++ ++ retval = krb5_check_clockskew(context, auth_pack->pkAuthenticator.ctime); ++ if (retval) ++ goto cleanup; ++ ++ /* check dh parameters */ ++ if (auth_pack->clientPublicValue != NULL) { ++ retval = server_check_dh(context, plgctx->cryptoctx, ++ reqctx->cryptoctx, plgctx->idctx, ++ &auth_pack->clientPublicValue->algorithm.parameters, ++ plgctx->opts->dh_min_bits); + if (retval) { +- pkiDebug("failed to decode krb5_auth_pack\n"); ++ pkiDebug("bad dh parameters\n"); + goto cleanup; + } +- +- retval = krb5_check_clockskew(context, +- auth_pack->pkAuthenticator.ctime); +- if (retval) +- goto cleanup; +- - /* check dh parameters */ - if (auth_pack->clientPublicValue != NULL) { - retval = server_check_dh(context, plgctx->cryptoctx, - reqctx->cryptoctx, plgctx->idctx, - &auth_pack->clientPublicValue->algorithm.parameters, - plgctx->opts->dh_min_bits); -+ retval = krb5_check_clockskew(context, auth_pack->pkAuthenticator.ctime); -+ if (retval) -+ goto cleanup; - +- - if (retval) { - pkiDebug("bad dh parameters\n"); - goto cleanup; @@ -1088,17 +1096,10 @@ index 6aa646cc6..c44be9c74 100644 - der_req = cb->request_body(context, rock); - retval = krb5_c_make_checksum(context, CKSUMTYPE_NIST_SHA, NULL, - 0, der_req, &cksum); -+ /* check dh parameters */ -+ if (auth_pack->clientPublicValue != NULL) { -+ retval = server_check_dh(context, plgctx->cryptoctx, -+ reqctx->cryptoctx, plgctx->idctx, -+ &auth_pack->clientPublicValue->algorithm.parameters, -+ plgctx->opts->dh_min_bits); - if (retval) { +- if (retval) { - pkiDebug("unable to calculate AS REQ checksum\n"); -+ pkiDebug("bad dh parameters\n"); - goto cleanup; - } +- goto cleanup; +- } - if (cksum.length != auth_pack->pkAuthenticator.paChecksum.length || - k5_bcmp(cksum.contents, - auth_pack->pkAuthenticator.paChecksum.contents, @@ -1170,10 +1171,7 @@ index 6aa646cc6..c44be9c74 100644 - if (!valid_kdcPkId) - pkiDebug("kdcPkId in AS_REQ does not match KDC's cert" - "RFC says to ignore and proceed\n"); -+ retval = KRB5KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED; -+ goto cleanup; -+ } - +- - } - /* remember the decoded auth_pack for verify_padata routine */ - reqctx->rcv_auth_pack = auth_pack; @@ -1184,24 +1182,35 @@ index 6aa646cc6..c44be9c74 100644 - retval = k5int_decode_krb5_auth_pack_draft9(&k5data, &auth_pack9); - if (retval) { - pkiDebug("failed to decode krb5_auth_pack_draft9\n"); -+ ftoken = auth_pack->pkAuthenticator.freshnessToken; -+ if (ftoken != NULL) { -+ retval = cb->check_freshness_token(context, rock, ftoken); -+ if (retval) - goto cleanup; +- goto cleanup; - } - if (auth_pack9->clientPublicValue != NULL) { - retval = server_check_dh(context, plgctx->cryptoctx, - reqctx->cryptoctx, plgctx->idctx, - &auth_pack9->clientPublicValue->algorithm.parameters, - plgctx->opts->dh_min_bits); -+ valid_freshness_token = TRUE; -+ } - +- - if (retval) { - pkiDebug("bad dh parameters\n"); - goto cleanup; - } +- } +- /* remember the decoded auth_pack for verify_padata routine */ +- reqctx->rcv_auth_pack9 = auth_pack9; +- auth_pack9 = NULL; +- break; ++ retval = KRB5KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED; ++ goto cleanup; + } + ++ ftoken = auth_pack->pkAuthenticator.freshnessToken; ++ if (ftoken != NULL) { ++ retval = cb->check_freshness_token(context, rock, ftoken); ++ if (retval) ++ goto cleanup; ++ valid_freshness_token = TRUE; ++ } ++ + /* check if kdcPkId present and match KDC's subjectIdentifier */ + if (reqp->kdcPkId.data != NULL) { + int valid_kdcPkId = 0; @@ -1214,18 +1223,15 @@ index 6aa646cc6..c44be9c74 100644 + if (!valid_kdcPkId) { + pkiDebug("kdcPkId in AS_REQ does not match KDC's cert; " + "RFC says to ignore and proceed\n"); - } -- /* remember the decoded auth_pack for verify_padata routine */ -- reqctx->rcv_auth_pack9 = auth_pack9; -- auth_pack9 = NULL; -- break; - } ++ } ++ } + /* remember the decoded auth_pack for verify_padata routine */ + reqctx->rcv_auth_pack = auth_pack; + auth_pack = NULL; - ++ if (is_signed) { retval = check_log_freshness(context, plgctx, request, + valid_freshness_token); @@ -682,21 +624,13 @@ cleanup: pkiDebug("pkinit_create_edata failed\n"); } @@ -1414,7 +1420,7 @@ index 6aa646cc6..c44be9c74 100644 } - pkiDebug("%s: return checksum instead of nonce = %d\n", - __FUNCTION__, fixed_keypack); -- + - /* if this is an RFC reply or draft9 client requested a checksum - * in the reply instead of the nonce, create an RFC-style keypack - */ @@ -1424,7 +1430,7 @@ index 6aa646cc6..c44be9c74 100644 - retval = ENOMEM; - goto cleanup; - } - +- - retval = krb5_c_make_checksum(context, 0, - encrypting_key, KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM, - req_pkt, &key_pack->asChecksum); diff --git a/Simplify-krb5_dbe_def_search_enctype.patch b/Simplify-krb5_dbe_def_search_enctype.patch index f98922e..aefeeed 100644 --- a/Simplify-krb5_dbe_def_search_enctype.patch +++ b/Simplify-krb5_dbe_def_search_enctype.patch @@ -16,8 +16,8 @@ kvno. (cherry picked from commit fcfb0e47c995a7e9f956c3716be3175f44ad26e0) --- - src/lib/kdb/kdb_default.c | 117 +++++++++++++++----------------------- - 1 file changed, 45 insertions(+), 72 deletions(-) + src/lib/kdb/kdb_default.c | 111 +++++++++++++++----------------------- + 1 file changed, 42 insertions(+), 69 deletions(-) diff --git a/src/lib/kdb/kdb_default.c b/src/lib/kdb/kdb_default.c index a1021f13a..231a0d8b4 100644 @@ -59,18 +59,27 @@ index a1021f13a..231a0d8b4 100644 - krb5_key_data *datap; - krb5_error_code ret; - krb5_boolean saw_non_permitted = FALSE; -- -- ret = 0; -- if (ktype != -1 && !krb5_is_permitted_enctype(kcontext, ktype)) -- return KRB5_KDB_NO_PERMITTED_KEY; -- -- if (kvno == -1 && stype == -1 && ktype == -1) -- kvno = 0; + krb5_key_data *kd; + krb5_int32 db_salttype; + krb5_boolean saw_non_permitted = FALSE; + int i; +- ret = 0; +- if (ktype != -1 && !krb5_is_permitted_enctype(kcontext, ktype)) ++ *kd_out = NULL; ++ ++ if (enctype != -1 && !krb5_is_permitted_enctype(context, enctype)) + return KRB5_KDB_NO_PERMITTED_KEY; ++ if (ent->n_key_data == 0) ++ return KRB5_KDB_NO_MATCHING_KEY; + +- if (kvno == -1 && stype == -1 && ktype == -1) +- kvno = 0; ++ /* Match the highest kvno if kvno is 0. Key data is sorted in descending ++ * order of kvno. */ ++ if (kvno == 0) ++ kvno = ent->key_data[0].key_data_kvno; + - if (kvno == 0) { - /* Get the max key version */ - for (i = 0; i < dbentp->n_key_data; i++) { @@ -79,7 +88,10 @@ index a1021f13a..231a0d8b4 100644 - } - } - } -+ *kd_out = NULL; ++ for (i = *start; i < ent->n_key_data; i++) { ++ kd = &ent->key_data[i]; ++ db_salttype = (kd->key_data_ver > 1) ? kd->key_data_type[1] : ++ KRB5_KDB_SALTTYPE_NORMAL; - maxkvno = -1; - idx = -1; @@ -104,28 +116,13 @@ index a1021f13a..231a0d8b4 100644 - continue; - } - if (stype >= 0 && db_stype != stype) -+ if (enctype != -1 && !krb5_is_permitted_enctype(context, enctype)) -+ return KRB5_KDB_NO_PERMITTED_KEY; -+ if (ent->n_key_data == 0) -+ return KRB5_KDB_NO_MATCHING_KEY; -+ -+ /* Match the highest kvno if kvno is 0. Key data is sorted in descending -+ * order of kvno. */ -+ if (kvno == 0) -+ kvno = ent->key_data[0].key_data_kvno; -+ -+ for (i = *start; i < ent->n_key_data; i++) { -+ kd = &ent->key_data[i]; -+ db_salttype = (kd->key_data_ver > 1) ? kd->key_data_type[1] : -+ KRB5_KDB_SALTTYPE_NORMAL; -+ + /* Match this entry against the arguments. Stop searching if we have + * passed the entries for the requested kvno. */ + if (enctype != -1 && kd->key_data_type[0] != enctype) -+ continue; -+ if (salttype >= 0 && db_salttype != salttype) continue; - if (kvno >= 0 && dbentp->key_data[i].key_data_kvno != kvno) ++ if (salttype >= 0 && db_salttype != salttype) ++ continue; + if (kvno >= 0 && kd->key_data_kvno < kvno) + break; + if (kvno >= 0 && kd->key_data_kvno != kvno) diff --git a/Simply-OpenSSL-PKCS7-decryption-code.patch b/Simply-OpenSSL-PKCS7-decryption-code.patch index 35f9e28..4190846 100644 --- a/Simply-OpenSSL-PKCS7-decryption-code.patch +++ b/Simply-OpenSSL-PKCS7-decryption-code.patch @@ -11,8 +11,8 @@ a larger refactoring] (cherry picked from commit 210356653a2f963ffe9a8a1b1627c64fb8ca7a3d) --- - .../preauth/pkinit/pkinit_crypto_openssl.c | 211 +++++------------- - 1 file changed, 62 insertions(+), 149 deletions(-) + .../preauth/pkinit/pkinit_crypto_openssl.c | 213 ++++++------------ + 1 file changed, 63 insertions(+), 150 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c index 5ff81d8cf..8aa2c5257 100644 @@ -144,17 +144,6 @@ index 5ff81d8cf..8aa2c5257 100644 - X509_ALGOR *enc_alg=NULL; - STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; - PKCS7_RECIP_INFO *ri=NULL; -- -- p7->state=PKCS7_S_HEADER; -- -- rsk=p7->d.enveloped->recipientinfo; -- enc_alg=p7->d.enveloped->enc_data->algorithm; -- data_body=p7->d.enveloped->enc_data->enc_data; -- evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); -- if (evp_cipher == NULL) { -- PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); -- goto cleanup; -- } + krb5_error_code ret; + int ok = 0, plaintext_len = 0, final_len; + unsigned int keylen = 0, eklen = 0, blocksize; @@ -166,13 +155,24 @@ index 5ff81d8cf..8aa2c5257 100644 + STACK_OF(PKCS7_RECIP_INFO) *rsk = p7->d.enveloped->recipientinfo; + PKCS7_RECIP_INFO *ri = NULL; +- p7->state=PKCS7_S_HEADER; ++ *data_out = NULL; ++ *len_out = 0; + +- rsk=p7->d.enveloped->recipientinfo; +- enc_alg=p7->d.enveloped->enc_data->algorithm; +- data_body=p7->d.enveloped->enc_data->enc_data; +- evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); +- if (evp_cipher == NULL) { +- PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); +- goto cleanup; +- } +- - if ((etmp=BIO_new(BIO_f_cipher())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); - goto cleanup; - } -+ *data_out = NULL; -+ *len_out = 0; - +- - /* It was encrypted, we need to decrypt the secret key - * with the private key */ + p7->state = PKCS7_S_HEADER; @@ -195,14 +195,14 @@ index 5ff81d8cf..8aa2c5257 100644 - if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0) + evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); + if (evp_cipher == NULL) -+ goto cleanup; + goto cleanup; +- if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) + keylen = EVP_CIPHER_key_length(evp_cipher); + blocksize = EVP_CIPHER_block_size(evp_cipher); + + evp_ctx = EVP_CIPHER_CTX_new(); + if (evp_ctx == NULL) - goto cleanup; -- if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) ++ goto cleanup; + if (!EVP_DecryptInit(evp_ctx, evp_cipher, NULL, NULL) || + EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) <= 0) goto cleanup; @@ -212,9 +212,7 @@ index 5ff81d8cf..8aa2c5257 100644 - tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); - tkey = OPENSSL_malloc(tkeylen); - if (tkey == NULL) -+ tkey = malloc(keylen); -+ if (tkey == NULL || !EVP_CIPHER_CTX_rand_key(evp_ctx, tkey)) - goto cleanup; +- goto cleanup; - if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) - goto cleanup; - if (ek == NULL) { @@ -222,7 +220,7 @@ index 5ff81d8cf..8aa2c5257 100644 - eklen = tkeylen; - tkey = NULL; - } - +- - if (eklen != (unsigned)EVP_CIPHER_CTX_key_length(evp_ctx)) { - /* Some S/MIME clients don't use the same key - * and effective key length. The key length is @@ -235,18 +233,29 @@ index 5ff81d8cf..8aa2c5257 100644 - } - } - if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0) -- goto cleanup; -+ /* Decrypt the secret key with the private key. */ -+ ret = pkinit_decode_data(context, id_cryptoctx, -+ ASN1_STRING_get0_data(ri->enc_key), -+ ASN1_STRING_length(ri->enc_key), &ek, &eklen); -+ use_key = (ret || eklen != keylen) ? tkey : ek; ++ tkey = malloc(keylen); ++ if (tkey == NULL || !EVP_CIPHER_CTX_rand_key(evp_ctx, tkey)) + goto cleanup; - if (out == NULL) - out=etmp; - else - BIO_push(out,etmp); - etmp=NULL; ++ /* Decrypt the secret key with the private key. */ ++ ret = pkinit_decode_data(context, id_cryptoctx, ++ ASN1_STRING_get0_data(ri->enc_key), ++ ASN1_STRING_length(ri->enc_key), &ek, &eklen); ++ use_key = (ret || eklen != keylen) ? tkey : ek; + +- if (data_body->length > 0) +- bio = BIO_new_mem_buf(data_body->data, data_body->length); +- else { +- bio=BIO_new(BIO_s_mem()); +- BIO_set_mem_eof_return(bio,0); +- } +- BIO_push(out,bio); +- bio=NULL; + /* Allocate a plaintext buffer and decrypt data_body into it. */ + plaintext = malloc(data_body->length + blocksize); + if (plaintext == NULL) @@ -260,19 +269,6 @@ index 5ff81d8cf..8aa2c5257 100644 + goto cleanup; + plaintext_len += final_len; -- if (data_body->length > 0) -- bio = BIO_new_mem_buf(data_body->data, data_body->length); -- else { -- bio=BIO_new(BIO_s_mem()); -- BIO_set_mem_eof_return(bio,0); -- } -- BIO_push(out,bio); -- bio=NULL; -+ *len_out = plaintext_len; -+ *data_out = plaintext; -+ plaintext = NULL; -+ ok = 1; - - if (0) { - cleanup: - if (out != NULL) BIO_free_all(out); @@ -289,6 +285,11 @@ index 5ff81d8cf..8aa2c5257 100644 - OPENSSL_free(tkey); - } - return(out); ++ *len_out = plaintext_len; ++ *data_out = plaintext; ++ plaintext = NULL; ++ ok = 1; ++ +cleanup: + EVP_CIPHER_CTX_free(evp_ctx); + zapfree(plaintext, plaintext_len); diff --git a/Update-test-suite-to-avoid-single-DES-enctypes.patch b/Update-test-suite-to-avoid-single-DES-enctypes.patch index fe79d58..042bc1b 100644 --- a/Update-test-suite-to-avoid-single-DES-enctypes.patch +++ b/Update-test-suite-to-avoid-single-DES-enctypes.patch @@ -1931,7 +1931,7 @@ index c061d764e..e8adee234 100644 } { all-enctypes -@@ -248,114 +207,7 @@ set passes { +@@ -248,115 +207,8 @@ set passes { {allow_weak_crypto(server)=false} {dummy=[verbose -log "all default enctypes"]} } @@ -1960,8 +1960,8 @@ index c061d764e..e8adee234 100644 - {dummy=[verbose -log \ - "DES3 TGT, KDC permitting only des-cbc-crc"]} - } --} -- + } + -# des.md5-tgt is set as unused, since it won't trigger the error case -# if SUPPORT_DESMD5 isn't honored. - @@ -2041,11 +2041,12 @@ index c061d764e..e8adee234 100644 - {master_key_type=aes256-cts-hmac-sha1-96} - {dummy=[verbose -log "AES via TCP"]} - } - } +-} -# {supported_enctypes=des-cbc-md5:normal des-cbc-crc:normal twofish256-hmac-sha1:normal } - +- # This shouldn't be necessary on dejagnu-1.4 and later, but 1.3 seems # to need it because its runtest.exp doesn't deal with PASS at all. + if [info exists PASS] { @@ -1095,7 +947,7 @@ proc setup_kerberos_db { standalone } { global REALMNAME KDB5_UTIL KADMIN_LOCAL KEY global tmppwd hostname diff --git a/Use-backported-version-of-OpenSSL-3-KDF-interface.patch b/Use-backported-version-of-OpenSSL-3-KDF-interface.patch index 4a24a89..28bd9f9 100644 --- a/Use-backported-version-of-OpenSSL-3-KDF-interface.patch +++ b/Use-backported-version-of-OpenSSL-3-KDF-interface.patch @@ -5,9 +5,9 @@ Subject: [PATCH] Use backported version of OpenSSL-3 KDF interface --- src/configure.in | 4 + - src/lib/crypto/krb/derive.c | 346 +++++++++++++----- - .../preauth/pkinit/pkinit_crypto_openssl.c | 257 +++++++------ - 3 files changed, 423 insertions(+), 184 deletions(-) + src/lib/crypto/krb/derive.c | 356 +++++++++++++----- + .../preauth/pkinit/pkinit_crypto_openssl.c | 257 ++++++++----- + 3 files changed, 428 insertions(+), 189 deletions(-) diff --git a/src/configure.in b/src/configure.in index 1df6f18fc..3bd5e683d 100644 @@ -56,8 +56,6 @@ index 6707a7308..915a173dd 100644 + const krb5_data *label, const krb5_data *context) { - size_t blocksize, keybytes, n; -- krb5_error_code ret; -- krb5_data block = empty_data(); + krb5_error_code ret = KRB5_CRYPTO_INTERNAL; + EVP_KDF_CTX *ctx = NULL; + const EVP_MD *digest; @@ -97,9 +95,7 @@ index 6707a7308..915a173dd 100644 + EVP_KDF_CTX_free(ctx); + return ret; +} - -- blocksize = enc->block_size; -- keybytes = enc->keybytes; ++ +static krb5_error_code +openssl_kbkdf_feedback_cmac(const struct krb5_enc_provider *enc, + krb5_key inkey, krb5_data *outrnd, @@ -145,10 +141,7 @@ index 6707a7308..915a173dd 100644 + EVP_KDF_CTX_free(ctx); + return ret; +} - -- if (blocksize == 1) -- return KRB5_BAD_ENCTYPE; -- if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes) ++ +static krb5_error_code +openssl_krb5kdf(const struct krb5_enc_provider *enc, krb5_key inkey, + krb5_data *outrnd, const krb5_data *in_constant) @@ -159,11 +152,9 @@ index 6707a7308..915a173dd 100644 + + if (inkey->keyblock.length != enc->keylength || + outrnd->length != enc->keybytes) { - return KRB5_CRYPTO_INTERNAL; ++ return KRB5_CRYPTO_INTERNAL; + } - -- /* Allocate encryption data buffer. */ -- ret = alloc_data(&block, blocksize); ++ + if (enc->encrypt == krb5int_aes_encrypt && enc->keylength == 16) + cipher = EVP_aes_128_cbc(); + else if (enc->encrypt == krb5int_aes_encrypt && enc->keylength == 32) @@ -188,29 +179,14 @@ index 6707a7308..915a173dd 100644 + + ret = 0; +done: - if (ret) -- return ret; ++ if (ret) + zap(outrnd->data, outrnd->length); + EVP_KDF_CTX_free(ctx); + return ret; +} - -- /* Initialize the input block. */ -- if (in_constant->length == blocksize) { -- memcpy(block.data, in_constant->data, blocksize); -- } else { -- krb5int_nfold(in_constant->length * 8, -- (unsigned char *) in_constant->data, -- blocksize * 8, (unsigned char *) block.data); -- } ++ +#else /* OSSL_KDFS */ - -- /* Loop encrypting the blocks until enough key bytes are generated. */ -- n = 0; -- while (n < keybytes) { -- ret = encrypt_block(enc, inkey, &block); -- if (ret) -- goto cleanup; ++ +/* + * NIST SP800-108 KDF in counter mode (section 5.1). + * Parameters: @@ -227,27 +203,34 @@ index 6707a7308..915a173dd 100644 + const krb5_data *context) +{ + krb5_crypto_iov iov[5]; -+ krb5_error_code ret; + krb5_error_code ret; +- krb5_data block = empty_data(); + krb5_data prf; + unsigned char ibuf[4], lbuf[4]; -- if ((keybytes - n) <= blocksize) { -- memcpy(outrnd->data + n, block.data, (keybytes - n)); -- break; -- } +- blocksize = enc->block_size; +- keybytes = enc->keybytes; +- +- if (blocksize == 1) +- return KRB5_BAD_ENCTYPE; +- if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes) + if (hash == NULL || outrnd->length > hash->hashsize) -+ return KRB5_CRYPTO_INTERNAL; + return KRB5_CRYPTO_INTERNAL; -- memcpy(outrnd->data + n, block.data, blocksize); -- n += blocksize; -- } -+ /* Allocate encryption data buffer. */ + /* Allocate encryption data buffer. */ +- ret = alloc_data(&block, blocksize); + ret = alloc_data(&prf, hash->hashsize); -+ if (ret) -+ return ret; + if (ret) + return ret; --cleanup: -- zapfree(block.data, blocksize); +- /* Initialize the input block. */ +- if (in_constant->length == blocksize) { +- memcpy(block.data, in_constant->data, blocksize); +- } else { +- krb5int_nfold(in_constant->length * 8, +- (unsigned char *) in_constant->data, +- blocksize * 8, (unsigned char *) block.data); +- } + /* [i]2: four-byte big-endian binary string giving the block counter (1) */ + iov[0].flags = KRB5_CRYPTO_TYPE_DATA; + iov[0].data = make_data(ibuf, sizeof(ibuf)); @@ -265,7 +248,25 @@ index 6707a7308..915a173dd 100644 + iov[4].flags = KRB5_CRYPTO_TYPE_DATA; + iov[4].data = make_data(lbuf, sizeof(lbuf)); + store_32_be(outrnd->length * 8, lbuf); -+ + +- /* Loop encrypting the blocks until enough key bytes are generated. */ +- n = 0; +- while (n < keybytes) { +- ret = encrypt_block(enc, inkey, &block); +- if (ret) +- goto cleanup; +- +- if ((keybytes - n) <= blocksize) { +- memcpy(outrnd->data + n, block.data, (keybytes - n)); +- break; +- } +- +- memcpy(outrnd->data + n, block.data, blocksize); +- n += blocksize; +- } +- +-cleanup: +- zapfree(block.data, blocksize); + ret = krb5int_hmac(hash, inkey, iov, 5, &prf); + if (!ret) + memcpy(outrnd->data, prf.data, outrnd->length); @@ -286,7 +287,7 @@ index 6707a7308..915a173dd 100644 { size_t blocksize, keybytes, n; krb5_crypto_iov iov[6]; -@@ -204,57 +349,95 @@ cleanup: +@@ -204,56 +349,94 @@ cleanup: return ret; } @@ -299,54 +300,28 @@ index 6707a7308..915a173dd 100644 - * - * There are no uses requiring more than a single PRF invocation. - */ --krb5_error_code --k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash, -- krb5_key inkey, krb5_data *outrnd, -- const krb5_data *label, const krb5_data *context) +static krb5_error_code +builtin_derive_random_rfc3961(const struct krb5_enc_provider *enc, + krb5_key inkey, krb5_data *outrnd, + const krb5_data *in_constant) - { -- krb5_crypto_iov iov[5]; ++{ + size_t blocksize, keybytes, n; - krb5_error_code ret; -- krb5_data prf; -- unsigned char ibuf[4], lbuf[4]; ++ krb5_error_code ret; + krb5_data block = empty_data(); - -- if (hash == NULL || outrnd->length > hash->hashsize) ++ + blocksize = enc->block_size; + keybytes = enc->keybytes; + + if (blocksize == 1) + return KRB5_BAD_ENCTYPE; + if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes) - return KRB5_CRYPTO_INTERNAL; - - /* Allocate encryption data buffer. */ -- ret = alloc_data(&prf, hash->hashsize); ++ return KRB5_CRYPTO_INTERNAL; ++ ++ /* Allocate encryption data buffer. */ + ret = alloc_data(&block, blocksize); - if (ret) - return ret; - -- /* [i]2: four-byte big-endian binary string giving the block counter (1) */ -- iov[0].flags = KRB5_CRYPTO_TYPE_DATA; -- iov[0].data = make_data(ibuf, sizeof(ibuf)); -- store_32_be(1, ibuf); -- /* Label */ -- iov[1].flags = KRB5_CRYPTO_TYPE_DATA; -- iov[1].data = *label; -- /* 0x00: separator byte */ -- iov[2].flags = KRB5_CRYPTO_TYPE_DATA; -- iov[2].data = make_data("", 1); -- /* Context */ -- iov[3].flags = KRB5_CRYPTO_TYPE_DATA; -- iov[3].data = *context; -- /* [L]2: four-byte big-endian binary string giving the output length */ -- iov[4].flags = KRB5_CRYPTO_TYPE_DATA; -- iov[4].data = make_data(lbuf, sizeof(lbuf)); -- store_32_be(outrnd->length * 8, lbuf); ++ if (ret) ++ return ret; ++ + /* Initialize the input block. */ + if (in_constant->length == blocksize) { + memcpy(block.data, in_constant->data, blocksize); @@ -355,11 +330,7 @@ index 6707a7308..915a173dd 100644 + (unsigned char *) in_constant->data, + blocksize * 8, (unsigned char *) block.data); + } - -- ret = krb5int_hmac(hash, inkey, iov, 5, &prf); -- if (!ret) -- memcpy(outrnd->data, prf.data, outrnd->length); -- zapfree(prf.data, prf.length); ++ + /* Loop encrypting the blocks until enough key bytes are generated. */ + n = 0; + while (n < keybytes) { @@ -378,15 +349,19 @@ index 6707a7308..915a173dd 100644 + +cleanup: + zapfree(block.data, blocksize); - return ret; - } ++ return ret; ++} +#endif /* OSSL_KDFS */ + -+krb5_error_code -+k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash, -+ krb5_key inkey, krb5_data *outrnd, -+ const krb5_data *label, const krb5_data *context) -+{ + krb5_error_code + k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash, + krb5_key inkey, krb5_data *outrnd, + const krb5_data *label, const krb5_data *context) + { +- krb5_crypto_iov iov[5]; +- krb5_error_code ret; +- krb5_data prf; +- unsigned char ibuf[4], lbuf[4]; +#ifdef OSSL_KDFS + return openssl_kbdkf_counter_hmac(hash, inkey, outrnd, label, context); +#else @@ -394,7 +369,9 @@ index 6707a7308..915a173dd 100644 + context); +#endif +} -+ + +- if (hash == NULL || outrnd->length > hash->hashsize) +- return KRB5_CRYPTO_INTERNAL; +static krb5_error_code +k5_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc, + krb5_key inkey, krb5_data *outrnd, @@ -406,7 +383,35 @@ index 6707a7308..915a173dd 100644 + return builtin_sp800_108_feedback_cmac(enc, inkey, outrnd, in_constant); +#endif +} -+ + +- /* Allocate encryption data buffer. */ +- ret = alloc_data(&prf, hash->hashsize); +- if (ret) +- return ret; +- +- /* [i]2: four-byte big-endian binary string giving the block counter (1) */ +- iov[0].flags = KRB5_CRYPTO_TYPE_DATA; +- iov[0].data = make_data(ibuf, sizeof(ibuf)); +- store_32_be(1, ibuf); +- /* Label */ +- iov[1].flags = KRB5_CRYPTO_TYPE_DATA; +- iov[1].data = *label; +- /* 0x00: separator byte */ +- iov[2].flags = KRB5_CRYPTO_TYPE_DATA; +- iov[2].data = make_data("", 1); +- /* Context */ +- iov[3].flags = KRB5_CRYPTO_TYPE_DATA; +- iov[3].data = *context; +- /* [L]2: four-byte big-endian binary string giving the output length */ +- iov[4].flags = KRB5_CRYPTO_TYPE_DATA; +- iov[4].data = make_data(lbuf, sizeof(lbuf)); +- store_32_be(outrnd->length * 8, lbuf); +- +- ret = krb5int_hmac(hash, inkey, iov, 5, &prf); +- if (!ret) +- memcpy(outrnd->data, prf.data, outrnd->length); +- zapfree(prf.data, prf.length); +- return ret; +static krb5_error_code +k5_derive_random_rfc3961(const struct krb5_enc_provider *enc, + krb5_key inkey, krb5_data *outrnd, @@ -417,10 +422,9 @@ index 6707a7308..915a173dd 100644 +#else + return builtin_derive_random_rfc3961(enc, inkey, outrnd, in_constant); +#endif -+} + } krb5_error_code - krb5int_derive_random(const struct krb5_enc_provider *enc, @@ -266,10 +449,9 @@ krb5int_derive_random(const struct krb5_enc_provider *enc, switch (alg) { @@ -464,7 +468,11 @@ index 52976895b..dd718c2be 100644 + krb5_error_code ret = KRB5_CRYPTO_INTERNAL; + EVP_KDF_CTX *ctx = NULL; + const EVP_MD *digest; -+ + +-/* pkinit_alg_agility_kdf() -- +- * This function generates a key using the KDF described in +- * draft_ietf_krb_wg_pkinit_alg_agility-04.txt. The algorithm is +- * described as follows: + /* RFC 8636 defines a SHA384 variant, but we don't use it. */ + if (hash_bytes == 20) { + digest = EVP_sha1(); @@ -476,11 +484,7 @@ index 52976895b..dd718c2be 100644 + krb5_set_error_message(context, ret, "Bad hash type for SSKDF"); + goto done; + } - --/* pkinit_alg_agility_kdf() -- -- * This function generates a key using the KDF described in -- * draft_ietf_krb_wg_pkinit_alg_agility-04.txt. The algorithm is -- * described as follows: ++ + ctx = EVP_KDF_CTX_new_id(EVP_KDF_SS); + if (!ctx) { + oerr(context, ret, _("Failed to instantiate SSKDF")); diff --git a/Use-secure_getenv-where-appropriate.patch b/Use-secure_getenv-where-appropriate.patch index 1adc322..d8f5832 100644 --- a/Use-secure_getenv-where-appropriate.patch +++ b/Use-secure_getenv-where-appropriate.patch @@ -15,10 +15,10 @@ ticket: 8800 src/lib/krb5/os/trace.c | 2 +- src/lib/krb5/rcache/rc_base.c | 4 ++-- src/lib/krb5/rcache/rc_io.c | 4 ++-- - src/plugins/preauth/pkinit/pkinit_identity.c | 11 +++-------- + src/plugins/preauth/pkinit/pkinit_identity.c | 13 ++++--------- src/plugins/tls/k5tls/openssl.c | 2 +- src/util/profile/prof_file.c | 2 +- - 12 files changed, 19 insertions(+), 24 deletions(-) + 12 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c index 3f6b53651..5531a10fb 100644 @@ -184,7 +184,7 @@ diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/ index 8cd3fc640..b89c5d015 100644 --- a/src/plugins/preauth/pkinit/pkinit_identity.c +++ b/src/plugins/preauth/pkinit/pkinit_identity.c -@@ -29,16 +29,10 @@ +@@ -29,15 +29,9 @@ * SUCH DAMAGES. */ @@ -192,16 +192,16 @@ index 8cd3fc640..b89c5d015 100644 -#include -#include -#include -+#include "pkinit.h" - #include +-#include -#include - #include - --#include "pkinit.h" +-#include - + #include "pkinit.h" ++#include ++#include + static void free_list(char **list) - { @@ -430,7 +424,8 @@ process_option_identity(krb5_context context, switch (idtype) { case IDTYPE_ENVVAR: diff --git a/krb5.spec b/krb5.spec index 8dcf4f6..1931d29 100644 --- a/krb5.spec +++ b/krb5.spec @@ -18,7 +18,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.17.1 # for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces) -Release: 2%{?dist} +Release: 3%{?dist} # rharwood has trust path to signing key and verifies on check-in Source0: https://web.mit.edu/kerberos/dist/krb5/1.17/krb5-%{version}%{prerelease}.tar.gz @@ -115,6 +115,9 @@ Patch167: Fix-minor-errors-in-softpkcs11.patch Patch168: Update-test-suite-cert-message-digest-to-sha256.patch Patch169: Use-backported-version-of-OpenSSL-3-KDF-interface.patch Patch170: krb5-1.17post6-FIPS-with-PRNG-and-RADIUS-and-MD4.patch +Patch171: Don-t-warn-in-kadmin-when-no-policy-is-specified.patch +Patch172: Allow-client-canonicalization-in-non-krbtgt-AS-REP.patch +Patch173: Do-not-always-canonicalize-enterprise-principals.patch License: MIT URL: https://web.mit.edu/kerberos/www/ @@ -688,6 +691,10 @@ exit 0 %{_libdir}/libkadm5srv_mit.so.* %changelog +* Fri Jan 03 2020 Robbie Harwood - 1.17.1-3 +- Don't warn in kadmin when no policy is specified +- Do not always canonicalize enterprise principals + * Fri Dec 13 2019 Robbie Harwood - 1.17.1-2 - Enable the LMDB backend for the KDB