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: | --- | |||
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 |