From cdaea01dc806bbc51975a33b05d2244b966f1428 Mon Sep 17 00:00:00 2001 From: Robbie Harwood Date: Thu, 15 Aug 2019 16:32:06 -0400 Subject: [PATCH] Fix KCM client time offset propagation --- ...able-flag-instead-of-denying-request.patch | 7 +- Fix-KCM-client-time-offset-propagation.patch | 32 ++++ ...5_cc_remove_cred-for-remaining-types.patch | 30 ++-- ...ype-names-in-KDC-logs-human-readable.patch | 137 ++++++++------- Remove-3des-support.patch | 65 ++++--- ...beros-v4-support-vestiges-from-ccapi.patch | 60 +++---- Remove-PKINIT-draft-9-support.patch | 158 +++++++++--------- Simply-OpenSSL-PKCS7-decryption-code.patch | 85 +++++----- ...t-suite-to-avoid-single-DES-enctypes.patch | 11 +- Use-secure_getenv-where-appropriate.patch | 18 +- krb5.spec | 6 +- 11 files changed, 315 insertions(+), 294 deletions(-) create mode 100644 Fix-KCM-client-time-offset-propagation.patch diff --git a/Clear-forwardable-flag-instead-of-denying-request.patch b/Clear-forwardable-flag-instead-of-denying-request.patch index 7105d6c..05e4dbd 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 | 56 ++++----------------- + src/kdc/do_tgs_req.c | 58 +++++----------------- 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, 189 insertions(+), 114 deletions(-) + 8 files changed, 190 insertions(+), 115 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,9 +146,10 @@ 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/Fix-KCM-client-time-offset-propagation.patch b/Fix-KCM-client-time-offset-propagation.patch new file mode 100644 index 0000000..90b1900 --- /dev/null +++ b/Fix-KCM-client-time-offset-propagation.patch @@ -0,0 +1,32 @@ +From e299c5e9442ade8c0b47d122809f76f03b64e497 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 14 Aug 2019 13:52:27 -0400 +Subject: [PATCH] Fix KCM client time offset propagation + +An inverted status check in get_kdc_offset() would cause querying the +offset time from the ccache to always fail (silently) on KCM. Fix the +status check so that KCM can properly handle desync. + +ticket: 8826 (new) +tags: pullup +target_version: 1.17-next +target_verison: 1.16-next + +(cherry picked from commit 323abb6d1ebe5469d6c2167c29aa5d696d099b90) +--- + src/lib/krb5/ccache/cc_kcm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c +index 092ab7daf..fe93ca3dc 100644 +--- a/src/lib/krb5/ccache/cc_kcm.c ++++ b/src/lib/krb5/ccache/cc_kcm.c +@@ -583,7 +583,7 @@ get_kdc_offset(krb5_context context, krb5_ccache cache) + if (cache_call(context, cache, &req, FALSE) != 0) + goto cleanup; + time_offset = k5_input_get_uint32_be(&req.reply); +- if (!req.reply.status) ++ if (req.reply.status) + goto cleanup; + context->os_context.time_offset = time_offset; + context->os_context.usec_offset = 0; diff --git a/Implement-krb5_cc_remove_cred-for-remaining-types.patch b/Implement-krb5_cc_remove_cred-for-remaining-types.patch index b24aa05..b77a6e5 100644 --- a/Implement-krb5_cc_remove_cred-for-remaining-types.patch +++ b/Implement-krb5_cc_remove_cred-for-remaining-types.patch @@ -266,13 +266,25 @@ 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); @@ -285,22 +297,10 @@ index 8419f6ebf..98723fe2e 100644 + + /* The current key was unlinked, probably by a remove_cred call; move + * on to the next one. */ - 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 b6b57c9..abf5c29 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 | 131 +++++++++++++++++++++++---------------------- + src/kdc/kdc_util.c | 125 +++++++++++++++++++++++---------------------- src/kdc/kdc_util.h | 6 +-- - 3 files changed, 90 insertions(+), 89 deletions(-) + 3 files changed, 87 insertions(+), 86 deletions(-) diff --git a/src/kdc/kdc_log.c b/src/kdc/kdc_log.c index 4eec50373..b160ba21a 100644 @@ -132,57 +132,16 @@ 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) @@ -201,47 +160,85 @@ 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 * -+ktypes2str(krb5_enctype *ktype, int nktypes) ++rep_etypes2str(krb5_kdc_rep *rep) { - 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 9214ccb..1e258b9 100644 --- a/Remove-3des-support.patch +++ b/Remove-3des-support.patch @@ -74,7 +74,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 | 102 ++--- + src/lib/gssapi/krb5/k5unseal.c | 88 ++-- src/lib/gssapi/krb5/k5unsealiov.c | 38 +- src/lib/gssapi/krb5/util_crypt.c | 11 - .../api.current/chpass-principal-v2.exp | 4 +- @@ -105,7 +105,7 @@ their constants. src/tests/t_salt.py | 5 +- src/util/k5test.py | 10 - .../leash/htmlhelp/html/Encryption_Types.htm | 13 - - 95 files changed, 162 insertions(+), 4836 deletions(-) + 95 files changed, 155 insertions(+), 4829 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 @@ -5384,13 +5384,15 @@ 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); @@ -5399,33 +5401,9 @@ index 9b183bc33..f0cc4a680 100644 - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } -- -- (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 */ -+ + +- (void) memcpy(data_ptr, ptr-2, 8); + if (! (data_ptr = xmalloc(8 + plainlen))) { + if (sealalg != 0xffff) + xfree(plain); @@ -5434,25 +5412,40 @@ 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 47b013f..334ecff 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 | 223 +++----------------- + src/ccapi/test/test_ccapi_ccache.c | 227 +++----------------- 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, 98 insertions(+), 871 deletions(-) + 15 files changed, 100 insertions(+), 873 deletions(-) diff --git a/src/ccapi/common/cci_cred_union.c b/src/ccapi/common/cci_cred_union.c index 4c8981610..424a93dab 100644 @@ -760,29 +760,8 @@ 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 @@ -858,6 +837,29 @@ 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; @@ -892,8 +894,7 @@ 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"); - } @@ -902,9 +903,10 @@ 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 3a25343..94700c4 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 | 219 ++----- + .../preauth/pkinit/pkinit_crypto_openssl.c | 221 ++------ src/plugins/preauth/pkinit/pkinit_lib.c | 65 --- - src/plugins/preauth/pkinit/pkinit_srv.c | 543 ++++++------------ + src/plugins/preauth/pkinit/pkinit_srv.c | 531 +++++------------- src/plugins/preauth/pkinit/pkinit_trace.h | 4 - src/tests/t_pkinit.py | 6 +- - 10 files changed, 282 insertions(+), 814 deletions(-) + 10 files changed, 277 insertions(+), 809 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h index fe2ec0d31..b437fd53f 100644 @@ -214,18 +214,7 @@ 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, @@ -238,6 +227,18 @@ 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, @@ -355,20 +356,19 @@ index 58400d555..1a642139a 100644 - &req9->signedAuthPack.data, - &req9->signedAuthPack.length); - break; --#ifdef DEBUG_ASN1 ++ &req->signedAuthPack.data, ++ &req->signedAuthPack.length); ++ } ++ + #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,13 +556,7 @@ 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; @@ -571,6 +565,13 @@ 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; @@ -1040,47 +1041,38 @@ index 6aa646cc6..c44be9c74 100644 if (retval) { TRACE_PKINIT_SERVER_PADATA_VERIFY_FAIL(context); goto cleanup; -@@ -541,118 +513,88 @@ pkinit_server_verify_padata(krb5_context context, +@@ -541,117 +513,87 @@ 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); -+ 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) { +- if (retval) { - pkiDebug("failed to decode krb5_auth_pack\n"); -+ pkiDebug("bad dh parameters\n"); - goto cleanup; - } +- 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; ++ } + - /* 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; @@ -1096,10 +1088,17 @@ 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); -- if (retval) { ++ /* 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("unable to calculate AS REQ checksum\n"); -- goto cleanup; -- } ++ pkiDebug("bad dh parameters\n"); + goto cleanup; + } - if (cksum.length != auth_pack->pkAuthenticator.paChecksum.length || - k5_bcmp(cksum.contents, - auth_pack->pkAuthenticator.paChecksum.contents, @@ -1171,7 +1170,10 @@ 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; @@ -1182,35 +1184,24 @@ 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"); -- goto cleanup; ++ ftoken = auth_pack->pkAuthenticator.freshnessToken; ++ if (ftoken != NULL) { ++ retval = cb->check_freshness_token(context, rock, ftoken); ++ if (retval) + 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; @@ -1223,15 +1214,18 @@ 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"); } @@ -1420,7 +1414,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 - */ @@ -1430,7 +1424,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/Simply-OpenSSL-PKCS7-decryption-code.patch b/Simply-OpenSSL-PKCS7-decryption-code.patch index 973480e..94ef2a1 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 | 213 ++++++------------ - 1 file changed, 63 insertions(+), 150 deletions(-) + .../preauth/pkinit/pkinit_crypto_openssl.c | 211 +++++------------- + 1 file changed, 62 insertions(+), 149 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,6 +144,17 @@ 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; @@ -155,24 +166,13 @@ 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; -- if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) ++ goto cleanup; + 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; + goto cleanup; +- if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) + if (!EVP_DecryptInit(evp_ctx, evp_cipher, NULL, NULL) || + EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) <= 0) goto cleanup; @@ -212,7 +212,9 @@ index 5ff81d8cf..8aa2c5257 100644 - tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); - tkey = OPENSSL_malloc(tkeylen); - if (tkey == NULL) -- goto cleanup; ++ tkey = malloc(keylen); ++ if (tkey == NULL || !EVP_CIPHER_CTX_rand_key(evp_ctx, tkey)) + goto cleanup; - if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) - goto cleanup; - if (ek == NULL) { @@ -220,7 +222,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 @@ -233,29 +235,18 @@ index 5ff81d8cf..8aa2c5257 100644 - } - } - if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0) -+ 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; +- 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; -- 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; +- if (out == NULL) +- out=etmp; +- else +- BIO_push(out,etmp); +- etmp=NULL; + /* Allocate a plaintext buffer and decrypt data_body into it. */ + plaintext = malloc(data_body->length + blocksize); + if (plaintext == NULL) @@ -269,6 +260,19 @@ 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); @@ -285,11 +289,6 @@ 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 56aa947..a6ef987 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,115 +207,8 @@ set passes { +@@ -248,114 +207,7 @@ 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,12 +2041,11 @@ 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-secure_getenv-where-appropriate.patch b/Use-secure_getenv-where-appropriate.patch index 6d92f10..4775663 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 | 13 ++++--------- + src/plugins/preauth/pkinit/pkinit_identity.c | 11 +++-------- src/plugins/tls/k5tls/openssl.c | 2 +- src/util/profile/prof_file.c | 2 +- - 12 files changed, 20 insertions(+), 25 deletions(-) + 12 files changed, 19 insertions(+), 24 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,15 +29,9 @@ +@@ -29,16 +29,10 @@ * SUCH DAMAGES. */ @@ -192,16 +192,16 @@ index 8cd3fc640..b89c5d015 100644 -#include -#include -#include --#include ++#include "pkinit.h" + #include -#include --#include -- - #include "pkinit.h" -+#include -+#include + #include +-#include "pkinit.h" +- 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 fa766e1..ff8c2e1 100644 --- a/krb5.spec +++ b/krb5.spec @@ -18,7 +18,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.17 # for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces) -Release: 40%{?dist} +Release: 41%{?dist} # lookaside-cached sources; two downloads and a build artifact Source0: https://web.mit.edu/kerberos/dist/krb5/1.17/krb5-%{version}%{prerelease}.tar.gz @@ -119,6 +119,7 @@ Patch156: Fix-Coverity-defects-in-soft-pkcs11-test-code.patch Patch157: Skip-URI-tests-when-using-asan.patch Patch158: Fix-memory-leaks-in-soft-pkcs11-code.patch Patch159: Initialize-life-rlife-in-kdcpolicy-interface.patch +Patch160: Fix-KCM-client-time-offset-propagation.patch License: MIT URL: https://web.mit.edu/kerberos/www/ @@ -728,6 +729,9 @@ exit 0 %{_libdir}/libkadm5srv_mit.so.* %changelog +* Thu Aug 15 2019 Robbie Harwood - 1.17-41 +- Fix KCM client time offset propagation + * Fri Aug 09 2019 Robbie Harwood - 1.17-40 - Initialize life/rlife in kdcpolicy interface