Bug 2060798
| Summary: | SHA-1 no longer available for CMS digest during PKINIT | |||
|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 9 | Reporter: | Luca Miccini <lmiccini> | |
| Component: | krb5 | Assignee: | Julien Rische <jrische> | |
| Status: | CLOSED ERRATA | QA Contact: | Filip Dvorak <fdvorak> | |
| Severity: | high | Docs Contact: | Jan Fiala <jafiala> | |
| Priority: | high | |||
| Version: | 9.0 | CC: | abokovoy, cllang, dciabrin, dpal, fdvorak, fhanzelk, ftrivino, gfialova, inikolch, jafiala, jrische, jvilicic, michele, mpolovka, mrhodes, njohnston, pasik, pmendezh, pvlasin, rcritten, spoore, ssorce, tscherf | |
| Target Milestone: | rc | Keywords: | Triaged | |
| Target Release: | --- | Flags: | pm-rhel:
mirror+
|
|
| Hardware: | x86_64 | |||
| OS: | Linux | |||
| Whiteboard: | ||||
| Fixed In Version: | krb5-1.19.1-15.el9_0 | Doc Type: | Known Issue | |
| Doc Text: |
.The DEFAULT:SHA1 subpolicy has to be set on RHEL 9 clients for PKINIT to work against AD KDCs
The SHA-1 digest algorithm has been deprecated in RHEL 9, and CMS messages for Public Key Cryptography for initial authentication (PKINIT) are now signed with the stronger SHA-256 algorithm.
However, the Active Directory (AD) Kerberos Distribution Center (KDC) still uses the SHA-1 digest algorithm to sign CMS messages. As a result, RHEL 9 Kerberos clients fail to authenticate users by using PKINIT against an AD KDC.
To work around the problem, enable support for the SHA-1 algorithm on your RHEL 9 systems with the following command:
[literal]
----
# update-crypto-policies --set DEFAULT:SHA1
----
|
Story Points: | --- | |
| Clone Of: | ||||
| : | 2064823 2065401 2066316 2066319 2067121 (view as bug list) | Environment: | ||
| Last Closed: | 2022-05-17 15:54:14 UTC | Type: | Bug | |
| Regression: | --- | Mount Type: | --- | |
| Documentation: | --- | CRM: | ||
| Verified Versions: | Category: | --- | ||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | ||
| Cloudforms Team: | --- | Target Upstream Version: | ||
| Embargoed: | ||||
| Bug Depends On: | ||||
| Bug Blocks: | 2057471, 2064823, 2065401, 2066316, 2066319, 2067121, 2067971, 2124308, 2124310 | |||
|
Description
Luca Miccini
2022-03-04 10:09:33 UTC
This sounds like https://lists.fedorahosted.org/archives/list/freeipa-users@lists.fedorahosted.org/thread/KSD3NNVQY7JFDL7DDJCVIYDLR4AXP4R2/ I'm moving this to krb5 to let Julien to investigate. Perhaps we need to change a way we export certificates for PKINIT on IPA side but let's get through krb5 first. Please note that krb5 needs some changes to work with openssl 3.0.1 in RHEL 9 too. RFC4556:
3.1.1. Required Algorithms
All PKINIT implementations MUST support the following algorithms:
o AS reply key enctypes: aes128-cts-hmac-sha1-96 and aes256-cts-
hmac-sha1-96 [RFC3962].
o Signature algorithm: sha-1WithRSAEncryption [RFC3370].
o AS reply key delivery method: the Diffie-Hellman key delivery
method, as described in Section 3.2.3.1.
In addition, implementations of this specification MUST be capable of
processing the Extended Key Usage (EKU) extension and the id-pkinit-
san (as defined in Section 3.2.2) otherName of the Subject
Alternative Name (SAN) extension in X.509 certificates [RFC3280].
RFC8636 allows algorithm agility for PKINIT KDFs:
6. KDF Agility
Section 3.2.3.1 of [RFC4556] is updated to define additional key
derivation functions (KDFs) to derive a Kerberos protocol key based
on the secret value generated by the Diffie-Hellman key exchange.
Section 3.2.1 of [RFC4556] is updated to add a new field to the
AuthPack structure to indicate which new KDFs are supported by the
client. Section 3.2.3 of [RFC4556] is updated to add a new field to
the DHRepInfo structure to indicate which KDF is selected by the KDC.
The KDF algorithm described in this document (based on [SP80056A])
can be implemented using any cryptographic hash function.
A new KDF for PKINIT usage is identified by an object identifier.
The following KDF object identifiers are defined:
id-pkinit OBJECT IDENTIFIER ::=
{ iso(1) identified-organization(3) dod(6) internet(1)
security(5) kerberosv5(2) pkinit (3) }
-- Defined in RFC 4556 and quoted here for the reader.
id-pkinit-kdf OBJECT IDENTIFIER ::= { id-pkinit kdf(6) }
-- PKINIT KDFs
id-pkinit-kdf-ah-sha1 OBJECT IDENTIFIER
::= { id-pkinit-kdf sha1(1) }
-- SP800-56A ASN.1 structured hash-based KDF using SHA-1
id-pkinit-kdf-ah-sha256 OBJECT IDENTIFIER
::= { id-pkinit-kdf sha256(2) }
-- SP800-56A ASN.1 structured hash-based KDF using SHA-256
id-pkinit-kdf-ah-sha512 OBJECT IDENTIFIER
::= { id-pkinit-kdf sha512(3) }
-- SP800-56A ASN.1 structured hash-based KDF using SHA-512
id-pkinit-kdf-ah-sha384 OBJECT IDENTIFIER
::= { id-pkinit-kdf sha384(4) }
-- SP800-56A ASN.1 structured hash-based KDF using SHA-384
Where id-pkinit is defined in [RFC4556]. All key derivation
functions specified above use the one-step key derivation method
described in Section 5.8.2.1 of [SP80056A], choosing the ASN.1 format
for FixedInfo, and Section 4.1 of [SP80056C], choosing option 1 for
the auxiliary function H. id-pkinit-kdf-ah-sha1 uses SHA-1 [RFC6234]
as the hash function. id-pkinit-kdf-ah-sha256, id-pkinit-kdf-ah-
sha356, and id-pkinit-kdf-ah-sha512 use SHA-256 [RFC6234], SHA-384
[RFC6234], and SHA-512 [RFC6234], respectively.
MIT Kerberos support SHA-1, SHA-256, SHA-512 but does not use SHA-384:
(in src/plugins/preauth/pkinit/pkinit_crypto_openssl.c):
/* Return the OpenSSL descriptor for the given RFC 5652 OID specified in RFC
* 8636. RFC 8636 defines a SHA384 variant, but we don't use it. */
static const EVP_MD *
algid_to_md(const krb5_data *alg_id)
{
if (data_eq(*alg_id, sha1_id))
return EVP_sha1();
if (data_eq(*alg_id, sha256_id))
return EVP_sha256();
if (data_eq(*alg_id, sha512_id))
return EVP_sha512();
return NULL;
}
The failure message comes from pkini_as_rep_parse() function on the client side:
/*
* Parse PA-PK-AS-REP message. Optionally evaluates the message's
* certificate chain.
* Optionally returns various components.
*/
....
switch(kdc_reply->choice) {
case choice_pa_pk_as_rep_dhInfo:
pkiDebug("as_rep: DH key transport algorithm\n");
#ifdef DEBUG_ASN1
print_buffer_bin(kdc_reply->u.dh_Info.dhSignedData.data,
kdc_reply->u.dh_Info.dhSignedData.length, "/tmp/client_kdc_signeddata");
#endif
if ((retval = cms_signeddata_verify(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_SERVER,
reqctx->opts->require_crl_checking,
(unsigned char *)
kdc_reply->u.dh_Info.dhSignedData.data,
kdc_reply->u.dh_Info.dhSignedData.length,
(unsigned char **)&dh_data.data,
&dh_data.length,
NULL, NULL, NULL)) != 0) {
pkiDebug("failed to verify pkcs7 signed data\n");
TRACE_PKINIT_CLIENT_REP_DH_FAIL(context); <---- this is the '[2406] 1646386032.615666: PKINIT client could not verify DH reply' message
goto cleanup;
}
TRACE_PKINIT_CLIENT_REP_DH(context);
break;
....
Luca, Ade, could you please use on the client side
update-crypto-policies --set DEFAULT:SHA-1
and retry kinit attempt on the client side?
I think there is a typo and it should be "update-crypto-policies --set DEFAULT:SHA1" I am trying it now, will report back "update-crypto-policies --set DEFAULT:SHA1" + reboot seems to be OK as workaround, thanks! We found that cms_signeddata_create() method, used by both PKINIT client and PKINIT KDC modules, hard-codes SHA-1 as a digest algorithm and uses sha1WithRSAEncryption without any alternatives. Since KDC internally has access to SHA-1 (we have to, for reasons unrelated), it was able to generate the response but on the client side PKINIT client operates in the environment where SHA-1 is disabled, it cannot verify it. This is a generic CMS SignedData message, so it can be made flexible to use actually supported algorithm. The 'other' side which consumes this CMS SignedData message is passing it to OpenSSL's CMS_verify() function which should handle any of supported algorithms. After a closer look at RFC8636[1] and comparison with the current MIT Kerberos implementation, we realized it was partially implemented: * KDC agility (section 6): Implemented[2] * PK Authenticator checksum agility (section 3): Supposed to rely on KDF agility, but currently only using SHA-1[3][4][5]. * CMS digest algorithm agility (section 4): Not implemented[6]. In case of KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED error, the KDC should provide a list of supported algorithms to the client. * X.509 certificate signer algorithm agility (section 5): Not implemented. The KDC_ERR_DIGEST_IN_CERT_NOT_ACCEPTED error is defined[7], but never used. The section 7 "Interoperability" describes the behavior between an old client and a KDC implementing algorithm agility and the opposite. In these cases, they fallback to SHA1-based functions, making it necessary in this kind of situations. For now, I will provide a patch using the following OpenSSL function to allow use of SHA-1 signatures in a library context: int ossl_ctx_legacy_digest_signatures_allowed_set(OSSL_LIB_CTX *libctx, int allow, int loadconfig) The actions to take in order to achieve full support of algorithm agility for PKINIT will be discussed upstream. [1] https://datatracker.ietf.org/doc/html/rfc8636 [2] https://github.com/krb5/krb5/blob/krb5-1.19.2-final/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c#L2353 [3] https://github.com/krb5/krb5/blob/krb5-1.19.2-final/src/plugins/preauth/pkinit/pkinit_srv.c#L549 [4] https://github.com/krb5/krb5/blob/krb5-1.19.2-final/src/plugins/preauth/pkinit/pkinit_clnt.c#L122 [5] https://github.com/krb5/krb5/blob/krb5-1.19.2-final/src/plugins/preauth/pkinit/pkinit_clnt.c#L718 [6] https://github.com/krb5/krb5/blob/krb5-1.19.2-final/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c#L1683 [7] https://github.com/krb5/krb5/blob/master/src/include/k5-int.h#L406 Note that for normal use (non FIPS), the users that need pkinit interop with an older server should be able to set crypto-policies to LEGACY and have it working. That is the mechanism we made available for those cases where SHA-1 signatures are still needed in a deployment. Looking at Heimdal implementation, it is already defaulting to SHA-256 for signature and digest algorithm since 2009: https://github.com/heimdal/heimdal/commit/c4c71cc41a2763a23867c7c6a041d1f4f1ebcbf7 https://github.com/heimdal/heimdal/blob/master/lib/hx509/crypto.c#L1513-L1523 the use of the defaults is triggered in sig_process() when a passed-in digest_alg in the context is NULL and the certificate where it would otherwise be picked up is NULL too: https://github.com/heimdal/heimdal/blob/master/lib/hx509/cms.c#L1283-L1291 and https://github.com/heimdal/heimdal/blob/master/lib/hx509/crypto.c#L2644-L2649 This means we can move to default in MIT Kerberos to use SHA-256 in the created CMS signeddata for both client and KDC parts of the PKINIT preauth method. We still need to be able to verify SHA-1 signatures sent by the clients in both normal and FIPS mode as this is explicitly allowed by SP 800-131Ar2[1] table 8. [1] https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf Upstream PR for using SHA-256 instead of SHA-1 for PKINIT CMS digest/signature: https://github.com/krb5/krb5/pull/1243 Hello Julien, I'm Josip, and I am responsible for the Enhancement Release Note for this Bugzilla. Could you please see if the following note correctly summarizes what customers should know about this issue? Take care, Josip ------------------ Title: Anonymous PKINIT CMS messages are now signed with SHA-2 instead of SHA-1 Content: Because the SHA-1 digest algorithm has been deprecated in RHEL 9, CMS messages for anonymous PKINIT are now signed with the stronger SHA-2 algorithm. With the release of RHEL 7.9 and RHEL 8.7, SHA-2 will be used by default in RHEL 7 and RHEL 8 as well. Older Kerberos Key Distribution Centers (KDCs) on RHEL 7.8 and earlier, or RHEL 8.6 and earlier, still use the SHA-1 digest algorithm to sign CMS messages. If you need interoperability with these older KDCs, enable support for the SHA-1 algorithm on your RHEL 9 servers with the following command: # update-crypto-policies --set DEFAULT:SHA1 Hello Josip, I think this is a good summary, yes. Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory (new packages: krb5), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2022:3951 |