Bug 2114766 - MIT krb5 client does not set "supportedCMSTypes" for pkinit and therefore Heimdal KDC uses SHA1 for CMS signature [fedora-rawhide]
Summary: MIT krb5 client does not set "supportedCMSTypes" for pkinit and therefore Hei...
Alias: None
Product: Fedora
Classification: Fedora
Component: krb5
Version: 37
Hardware: Unspecified
OS: Unspecified
Target Milestone: ---
Assignee: Julien Rische
QA Contact: Fedora Extras Quality Assurance
Depends On: 2027125 2068935
Blocks: 2106296
TreeView+ depends on / blocked
Reported: 2022-08-03 08:47 UTC by Julien Rische
Modified: 2023-01-13 14:44 UTC (History)
13 users (show)

Fixed In Version: krb5-1.20.1-3.fc38
Doc Type: If docs needed, set a value
Doc Text:
Clone Of: 2068935
Last Closed: 2023-01-13 14:44:00 UTC
Type: Bug

Attachments (Terms of Use)

System ID Private Priority Status Summary Last Updated
Fedora Package Sources krb5 pull-request 27 0 None None None 2022-11-23 18:52:09 UTC
Github krb5 krb5 pull 1254 0 None Merged Set SHA-2 as supportedCMSTypes instead of 3DES 2022-08-03 08:47:33 UTC
Red Hat Issue Tracker FREEIPA-8610 0 None None None 2022-08-03 08:53:37 UTC

Description Julien Rische 2022-08-03 08:47:33 UTC
+++ This bug was initially created as a clone of Bug #2068935 +++

Description of problem:
The following test "/Sanity/heimdal-sanity/" failed when the MIT client try to do PKINIT with Heimdal KDC. 

The problem is that MIT krb5 does not set "supportedCMSTypes" for PKINIT and as a result, the Heimdall sets signature algorithm which uses SHA1.

The possible solution:
1  Modify Heimdal to use SHA-2 in case supportedCMSTypes is not provided by the client
2. Add "supportedCMSTypes" support into MIT krb5

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. Install Heimdal KDC
   kstash --random-key
   heimdal-kadmin --local init --realm-max-ticket-life=unlimited --realm-max-renewable-life=unlimited TEST.REDHAT.COM
   heimdal-kadmin --realm=TEST.REDHAT.COM --local add --password=alice --max-ticket-life=1d --max-renewable-life=1w --expiration-time=never --pw-expiration-time=never --policy=default --attributes=  alice.COM
   Generate certificates for client and KDC with the help of this script:
   ./make_pkinit_cert.sh ca ca
    server certs:
   ./make_pkinit_cert.sh kdc kdc CA=ca CN=$HostName REALM=TEST.REDHAT.COM CLIENT=$HostName
   client certs:
   ./make_pkinit_cert.sh client $krb5User CA=ca CN=$krb5User"
   ./make_pkinit_cert.sh client-sign $krb5User CA=ca CN=$krb5User REALM=TEST.REDHAT.COM CLIENT=$krb5User"
add pkinit options into heimdal-kdc.conf
      pkinit_identity = FILE:/tmp/kdc.pem,/tmp/kdckey.pem
      pkinit_anchors = FILE:/tmp/cacert.pem
   systemctl start heimdal-kdc


  allow-anonymous = yes
  pkinit_identity = FILE:/tmp/kdc.pem,/tmp/kdckey.pem
  pkinit_anchors = FILE:/tmp/cacert.pem
  enable-pkinit = yes
  enable-http = true

  require-preauth = true

2. Set MIT krb5
   sed -i "s/\[libdefaults\]/[libdefaults]\n default_realm = TEST.REDHAT.COM/" /etc/krb5.conf
   sed -i "s/\[realms\]/[realms]\n TEST.REDHAT.COM = {\n  kdc = $KDC_HostName\n  admin_server = $KDC_HostName\n }/" /etc/krb5.conf
   sed -i "s/\[domain_realm\]/[domain_realm]\n .$KDC_DomainName = TEST.REDHAT.COM\n $DKC_DomainName = TEST.REDHAT.COM/" /etc/krb5.conf

3. try kinit alice.COM (with -X parameters: X509_user_identity=FILE:/tmp/alice,pem,X509_anchors=FILE:/tmp/ca.pem) or anonymous pkinit

Actual results:
# kinit -n'
[8501] 1648404167.147255: Matching WELLKNOWN/ANONYMOUS.COM in collection with result: -1765328243/Can't find client principal WELLKNOWN/ANONYMOUS.COM in cache collection
[8501] 1648404167.147256: Getting initial credentials for WELLKNOWN/ANONYMOUS.COM
[8501] 1648404167.147258: Sending unauthenticated request
[8501] 1648404167.147259: Sending request (213 bytes) to TEST.REDHAT.COM
[8501] 1648404167.147288: Sending DNS URI query for _kerberos.TEST.REDHAT.COM.
[8501] 1648404167.147289: No URI records found
[8501] 1648404167.147290: Sending DNS SRV query for _kerberos-master._udp.TEST.REDHAT.COM.
[8501] 1648404167.147291: Sending DNS SRV query for _kerberos-master._tcp.TEST.REDHAT.COM.
[8501] 1648404167.147292: No SRV records found
[8501] 1648404167.147293: Response was not from primary KDC
[8501] 1648404167.147294: Processing preauth types: PA-PK-AS-REP (17), PA-PKINIT-KX (147)
[8501] 1648404167.147295: Preauth module pkinit (147) (info) returned: 0/Success
[8501] 1648404167.147296: PKINIT OpenSSL error: Failed to verify CMS message
[8501] 1648404167.147297: PKINIT OpenSSL error: error:1700006B:CMS routines::content type not enveloped data
[8501] 1648404167.147298: PKINIT OpenSSL error: error:03000098:digital envelope routines::invalid digest
[8501] 1648404167.147299: PKINIT client could not verify DH reply
[8501] 1648404167.147300: Preauth module pkinit (17) (real) returned: -1765328320/Failed to verify CMS message: content type not enveloped data
[8501] 1648404167.147301: Produced preauth for next request: (empty)
[8501] 1648404167.147302: Salt derived from principal: WELLKNOWN:ANONYMOUSWELLKNOWNANONYMOUS
[8501] 1648404167.147303: Getting AS key, salt "WELLKNOWN:ANONYMOUSWELLKNOWNANONYMOUS", params "\x00\x00\x10\x00"
[8501] 1648404193.258727: AS key obtained from gak_fct: aes256-cts/39D4
[8501] 1648404193.258728: Retrying AS request with primary KDC
[8501] 1648404193.258729: Getting initial credentials for WELLKNOWN/ANONYMOUS.COM
[8501] 1648404193.258731: Sending unauthenticated request
[8501] 1648404193.258732: Sending request (213 bytes) to TEST.REDHAT.COM (primary)
[8501] 1648404193.258733: Sending DNS URI query for _kerberos.TEST.REDHAT.COM.
[8501] 1648404193.258734: No URI records found
[8501] 1648404193.258735: Sending DNS SRV query for _kerberos-master._udp.TEST.REDHAT.COM.
[8501] 1648404193.258736: Sending DNS SRV query for _kerberos-master._tcp.TEST.REDHAT.COM.
[8501] 1648404193.258737: No SRV records found
kinit: Password incorrect while getting initial credentials

Expected results:
kinit -n or kinit <user> with pkinit should pass

Additional info:
It works with DEFAULT:SHA1 crypto-policy

--- Additional comment from Julien Rische on 2022-03-28 06:55:54 UTC ---

The switch to SHA-256 as default digest algorithm in Heimdal[1] is not effective in practice for Kerberos clients which are not implementing algorithm agility for CMS. I think the current Heimdal implementation makes sense for backward compatibility, and setting the "supportedCMSTypes" field in MIT krb5 should be the way to go.

Until this is implemented, I am afraid RHEL9 clients have to enable SHA1 crypto sub-policy if they are authenticating against Heimdal KDC using PKINIT.

[1] https://github.com/heimdal/heimdal/commit/c4c71cc41a2763a23867c7c6a041d1f4f1ebcbf7

--- Additional comment from Julien Rische on 2022-05-31 08:42:26 UTC ---

To be more precise, the Heimdal KDC expects the attribute "supportedCMSTypes" to be set[1]. If not it falls back to one of these ciphers:

* des-ede3-cbc
* sha1-with-rsa-signature
* sha-1

All of them being unavailable on RHEL9.

[1] https://github.com/heimdal/heimdal/blob/heimdal-7.7.0/kdc/pkinit.c#L759-L776

--- Additional comment from Julien Rische on 2022-05-31 10:32:28 UTC ---

According to RFC4556[1], the PKINIT client can either indicate supported CMS ciphers as etypes in the AS-REQ, or as OIDs in the "supportedCMSTypes" attribute of the AuthPack. All the available etypes for the first method are now referring to deprecated algorithms, hence the only way to advertise recent ciphers it to use "supportedCMSTypes".

This is actually what MIT krb5 is supposed to do because CMS-dedicated etypes are not used at all[2]. The "supportedCMSTypes" attribute is actually set in upstream project, but this section of the code was removed[3] in C9S/RHEL release because it was only populated with DES OID. A better approach would be to replace DES, by SHA2-based ciphers. This would allow proper integration with Heimdal.

[1] https://datatracker.ietf.org/doc/html/rfc4556#section-3.1.4
[2] https://github.com/krb5/krb5/blob/krb5-1.20-final/src/include/krb5/krb5.hin#L427-L433
[3] https://gitlab.com/redhat/centos-stream/rpms/krb5/-/blob/c9s/downstream-Remove-3des-support.patch#L5786-5793

--- Additional comment from Julien Rische on 2022-06-01 13:29:56 UTC ---

I have successfully run the test with heimdal-7.7.0-11.fc36 on RHEL-9.1.0-20220531.0 using a scratch build[1] using SHA-256 and SHA-512 as supportedCMSTypes.

I think this fix should be implemented upstream to replace DES3[2] by SHA-2, or at least implement a CMS digest list that would be more flexible to configure.

[1] http://brew-task-repos.usersys.redhat.com/repos/scratch/jrische/krb5/1.19.1/21.bz2068935.1.el9_0/x86_64/
[2] https://github.com/krb5/krb5/blob/krb5-1.20-final/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c#L5495

--- Additional comment from Julien Rische on 2022-06-01 20:28:28 UTC ---

Pull request:

--- Additional comment from Julien Rische on 2022-07-01 10:21:27 UTC ---

The following points were raised in the pull request[1]:

* The current upstream implementation set "supportedCMSTypes" with an algorithm which is unsupported by Heimdal, resulting in default digest and signature algorithms (sha256 and sha256WithRSAEncryption) being selected. Hence, the SHA-1 signature verification issue does not occur with upstream version.

* Under strict interpretation of RFC 4556 section 3.2.1 step 5[2], only signature algorithm OIDs are allowed in "supportedCMSTypes" (not digest algorithms).

* Test showed that AD is ignoring the content or "suuportedCMSTypes". Also, AD KDC does not support SHA2-based algorithms. Removing dependency on SHA-1 for AD interoperability would require implementing RFC 5349 (ECC for PKINIT)[3].

* Heimdal and OpenSSL are implementing the verification of CMS data signature in incompatible ways: OpenSSL seems to only be looking at the digest algorithm, not taking the signature one into account. As a consequence, when they are not relying on the same hashing algorithm (e.g. sha512 as digest and sha256WithRSAEncryption as signature), verification fails because the signature is compared to a different type of digest.

[1] https://github.com/krb5/krb5/pull/1254
[2] https://www.rfc-editor.org/rfc/rfc4556.html#page-12
[3] https://www.rfc-editor.org/rfc/rfc5349.html
[4] https://github.com/openssl/openssl/blob/openssl-3.0.1/crypto/cms/cms_sd.c#L788
[5] https://github.com/openssl/openssl/blob/openssl-3.0.1/crypto/cms/cms_sd.c#L963

--- Additional comment from Julien Rische on 2022-07-06 12:15:38 UTC ---

Postponed again because the CMS incompatibility issue is being discussed with Heimdal and OpenSSL teams:


Comment 1 Ben Cotton 2022-08-09 13:35:37 UTC
This bug appears to have been reported against 'rawhide' during the Fedora Linux 37 development cycle.
Changing version to 37.

Comment 2 Fedora Update System 2022-12-01 15:02:20 UTC
FEDORA-2022-8050ab2c35 has been submitted as an update to Fedora 38. https://bodhi.fedoraproject.org/updates/FEDORA-2022-8050ab2c35

Comment 3 Fedora Update System 2022-12-01 17:37:51 UTC
FEDORA-2022-311128dd7e has been submitted as an update to Fedora 38. https://bodhi.fedoraproject.org/updates/FEDORA-2022-311128dd7e

Comment 4 Fedora Update System 2022-12-07 13:28:59 UTC
FEDORA-2022-311128dd7e has been pushed to the Fedora 38 stable repository.
If problem still persists, please make note of it in this bug report.

Note You need to log in before you can comment on or make changes to this bug.