botan
botan copied to clipboard
X509_Certificate fails to parse a RSA-PSS certificate that was not signed by another RSA-PSS cert
This PEM is parsed by OpenSSL 3.0.5 5 Jul 2022 (Library: OpenSSL 3.0.5 5 Jul 2022)
With botan 2.19.1 I am getting
$ botan cert_info entity1.in
X509_Certificate parsing failed CERTIFICATE decoding failed with Algorithm identifier mismatch
-----BEGIN CERTIFICATE-----
MIICejCCAiCgAwIBAgIUV0s7Xb9pXE7I6lWKig4O9ueBIVIwCgYIKoZIzj0EAwIw
JDEQMA4GA1UECgwHRXhhbXBsZTEQMA4GA1UEAwwHUm9vdCBDQTAeFw0yMjA3MzEw
OTU4NDFaFw0yODAxMjEwOTU4NDFaMCQxEDAOBgNVBAoMB0V4YW1wbGUxEDAOBgNV
BAMMB0VudGl0eTEwggEgMAsGCSqGSIb3DQEBCgOCAQ8AMIIBCgKCAQEA8zrekcNd
SrAKCNCepmHDAO78Dm0CbiZ+lP5hXVgp7vfAiY9lyKZyXRSEARgsQuNoLYb1GQ5y
1oAyvH9rqYYC9GX3F50ekCztrtGF3p6z2m/JaUAoz7ZQLQ95Lg4ML+28WDYjOs9V
p/Gu8GiaAcsv/z1hK0u0PfmqLyUTIN3EM03RjaESr7n3M2LBu5AZ07/EbaXjzHWh
OZmIZA7yODQrTyz2ZlZ1l3WfSIFCT089gy8BsTrtaM6nUr8kgbCtmnskoqxjnGKW
9ScdXBkS1iN4/O/nGsGvnQJparNRYuhlCIOG7ryRS46adr4+CUZ+LKlPWoPRSuUZ
qAyQ8h0EopzTQQIDAQABo2cwZTAdBgNVHQ4EFgQU6X2N+z9A1NQk56YfTnwFf70D
ZpkwDgYDVR0PAQH/BAQDAgPIMBMGA1UdJQQMMAoGCCsGAQUFBwMCMB8GA1UdIwQY
MBaAFHB3/cqCukn4QdaxBagNY2jfDNG6MAoGCCqGSM49BAMCA0gAMEUCIQCLU/Lc
3LdhS0tPc6SdkqJlXVW7DMDeACL0TPNNySC5xQIgInZTKRNF+kMEkHKJJ75k6uot
4wHDgdgqE7Yk62nW0VQ=
-----END CERTIFICATE-----
openssl x509 -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
57:4b:3b:5d:bf:69:5c:4e:c8:ea:55:8a:8a:0e:0e:f6:e7:81:21:52
Signature Algorithm: ecdsa-with-SHA256
Issuer: O = Example, CN = Root CA
Validity
Not Before: Jul 31 09:58:41 2022 GMT
Not After : Jan 21 09:58:41 2028 GMT
Subject: O = Example, CN = Entity1
Subject Public Key Info:
Public Key Algorithm: rsassaPss
Public-Key: (2048 bit)
Modulus:
00:f3:3a:de:91:c3:5d:4a:b0:0a:08:d0:9e:a6:61:
c3:00:ee:fc:0e:6d:02:6e:26:7e:94:fe:61:5d:58:
29:ee:f7:c0:89:8f:65:c8:a6:72:5d:14:84:01:18:
2c:42:e3:68:2d:86:f5:19:0e:72:d6:80:32:bc:7f:
6b:a9:86:02:f4:65:f7:17:9d:1e:90:2c:ed:ae:d1:
85:de:9e:b3:da:6f:c9:69:40:28:cf:b6:50:2d:0f:
79:2e:0e:0c:2f:ed:bc:58:36:23:3a:cf:55:a7:f1:
ae:f0:68:9a:01:cb:2f:ff:3d:61:2b:4b:b4:3d:f9:
aa:2f:25:13:20:dd:c4:33:4d:d1:8d:a1:12:af:b9:
f7:33:62:c1:bb:90:19:d3:bf:c4:6d:a5:e3:cc:75:
a1:39:99:88:64:0e:f2:38:34:2b:4f:2c:f6:66:56:
75:97:75:9f:48:81:42:4f:4f:3d:83:2f:01:b1:3a:
ed:68:ce:a7:52:bf:24:81:b0:ad:9a:7b:24:a2:ac:
63:9c:62:96:f5:27:1d:5c:19:12:d6:23:78:fc:ef:
e7:1a:c1:af:9d:02:69:6a:b3:51:62:e8:65:08:83:
86:ee:bc:91:4b:8e:9a:76:be:3e:09:46:7e:2c:a9:
4f:5a:83:d1:4a:e5:19:a8:0c:90:f2:1d:04:a2:9c:
d3:41
Exponent: 65537 (0x10001)
No PSS parameter restrictions
X509v3 extensions:
X509v3 Subject Key Identifier:
E9:7D:8D:FB:3F:40:D4:D4:24:E7:A6:1F:4E:7C:05:7F:BD:03:66:99
X509v3 Key Usage: critical
Digital Signature, Non Repudiation, Key Agreement
X509v3 Extended Key Usage:
TLS Web Client Authentication
X509v3 Authority Key Identifier:
70:77:FD:CA:82:BA:49:F8:41:D6:B1:05:A8:0D:63:68:DF:0C:D1:BA
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
30:45:02:21:00:8b:53:f2:dc:dc:b7:61:4b:4b:4f:73:a4:9d:
92:a2:65:5d:55:bb:0c:c0:de:00:22:f4:4c:f3:4d:c9:20:b9:
c5:02:20:22:76:53:29:13:45:fa:43:04:90:72:89:27:be:64:
ea:ea:2d:e3:01:c3:81:d8:2a:13:b6:24:eb:69:d6:d1:54
Thanks for the report. The check added in efa5004354 looks to be incorrect.
I remember we (@neusdan) had long discussions about implementing this check in the first place. I revisited the code now. This seems to be the relevant section of RFC 4055:
When the RSA private key owner wishes to limit the use of the public key exclusively to RSASSA-PSS, then the id-RSASSA-PSS object identifier MUST be used in the algorithm field within the subject public key information, and, if present, the parameters field MUST contain RSASSA-PSS-params.
If "the private key owner" means the public key corresponding to the cert to be parsed, then the check is implemented clearly wrong, as it checks against the signer's signature algorithm. Effectively, the check prevents mixed algorithm certificate chains, which are completely valid. I see no way we can implement a check in this way and certainly not in certificate parsing. I doubt if the section was meant to force a check to be implemented at all. This is a good case where RFCs could phrase things more clearly, e.g., to prevent implementations missing important bits.