Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

verify_directly_issued_by compares encoded subjects rather than subject values #12361

Closed
wkral-netlync opened this issue Jan 29, 2025 · 6 comments
Labels
Stale waiting-on-reporter Issue is waiting on a reply from the reporter. It will be automatically cloesd if there is no reply.

Comments

@wkral-netlync
Copy link

In a certificate being verified the issuer name attributes are encoded using PRINTABLESTRING, while the issuer cert encodes it's subject name attributes with UTF8STRING. When using verify_directly_issued_by an exception is thrown:

ValueError: Issuer certificate subject does not match certificate issuer.

The comparison is done with the ANS.1 encoded values:

if self.raw.borrow_dependent().tbs_cert.issuer
!= issuer.raw.borrow_dependent().tbs_cert.subject
{
return Err(CryptographyError::from(
pyo3::exceptions::PyValueError::new_err(
"Issuer certificate subject does not match certificate issuer.",
),
));
};

I think that the comparison should follow the rules outlined in RFC 5280 Section 7.1 Internationalized Names in Distinguished Names which would ignore the ASN.1 encoding and compare the values.

The cause of the exception was difficult to find since two x509.Certificate objects subjects do compare positively in python:

untrusted.issuer == issuer.subject  # True
@alex
Copy link
Member

alex commented Jan 29, 2025

The behavior we have there matches what's in the CABF BRs https://cabforum.org/working-groups/server/baseline-requirements/documents/TLSBRv2.0.4.pdf at 7.1.4.1

@alex alex added the waiting-on-reporter Issue is waiting on a reply from the reporter. It will be automatically cloesd if there is no reply. label Jan 30, 2025
@wkral-netlync
Copy link
Author

wkral-netlync commented Jan 30, 2025

Reading through that portion of the CABF spec the relevant section seems to be:

For each CA Certificate in the Certification Path, the encoded content of the Subject
Distinguished Name field of a Certificate SHALL be byte‐for‐byte identical among all
Certificates whose Subject Distinguished Names can be compared as equal according to RFC
5280, Section 7.1, and including expired and revoked Certificates.

It clearly says byte-for-byte identical, but I find it slightly odd that it points to the same portion of the RFC that I did which states:

Conforming implementations MUST use the LDAP StringPrep profile
(including insignificant space handling), as specified in [RFC4518],
as the basis for comparison of distinguished name attributes encoded
in either PrintableString or UTF8String.

It seems a bit contradictory to me.

The CABF spec seems to only cover TLS Server Certificates, but there are many other x509 certificate chain use cases, and the reason I've been trying to use verify_directly_issued_by is because the x509.verification API only covers server certs and client certs and checks for the key usage attributes. I'm working with JWS RFC 7515 and CMS RFC 5652 and I think there are probably several other cases. It would be useful if cryptography could be used more generally for certificate chain verification without having to go deep into the hazmat portion of the library. This is especially true with PyOpenSSL having deprecated all of the x509 portions of it's library in favour of cryptography.

@alex
Copy link
Member

alex commented Jan 30, 2025 via email

@wkral-netlync
Copy link
Author

I understand and sympathize with that position and if I was able to control the certs being verified I'd author them with consistent encoding. Unfortunately these are production certificates in the wild and there are millions of them in this form.

RFC 5280 is published the way it is, and none of the revising RFCs seems to change this description of the conforming comparison functionality. There doesn't seem to be a way to support it in the python ecosystem without rolling your own verification using the hazmat portions of cryptography (I'm happy to be shown otherwise). Could there be an option to use StringPrep based comparison with adequate warnings about it being disfavoured?

Copy link

github-actions bot commented Feb 3, 2025

This issue has been waiting for a reporter response for 3 days. It will be auto-closed if no activity occurs in the next 5 days.

@github-actions github-actions bot added the Stale label Feb 3, 2025
Copy link

github-actions bot commented Feb 8, 2025

This issue has not received a reporter response and has been auto-closed. If the issue is still relevant please leave a comment and we can reopen it.

@github-actions github-actions bot closed this as completed Feb 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Stale waiting-on-reporter Issue is waiting on a reply from the reporter. It will be automatically cloesd if there is no reply.
Development

No branches or pull requests

2 participants