-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Allow verifying an x509 cert chain without making assertions about the subject name #10276
Comments
We don't yet support this use case. We intend to in the future. |
I've been thinking a bit about how to do this (since I'll also likely need it at some point for
|
Well, we should not be changing the build_server_verifier function. You should never verify a server cert without checking the subject is valid. This needs to be a new type of verifier. |
That makes sense. How does (Other meh names: |
What's teh difference between that and a client cert verifier? |
Hmm, not sure. My idea of a |
I don't think that's how a clientverifier would work -- imagine a webserver using client certs for auth. |
So in that case |
Yes, I think that's what you'd want, indeed. |
Just to give a public update: I've offered to do the work here. I'll try and get a PR up for this tonight. |
Just noting: there are other x509 certificates that don't actually have anything to do with webPKI. In our case we're looking for a generic way to verify certificate chains, with various constraints on the contents. It'd be nice if the project had a generic verifier as well. As-is, we're stuck with oscrypto/certvalidator or a fork. |
Could you say a bit more about your use case? There isn't exactly anything called "generic" chain verification; all chain verifiers perform verification modulo some kind of certificate profile (sometimes that profile is poorly defined or not well documented, but it's always there). In other words: are you verifying code-signing certs, S/MIME, etc.? Each of these has a profile (or profiles), and supporting each without exposing footguns requires some design consideration 🙂 |
If you look at the PyOpenSSL X509Store / X509StoreContext APIs ( https://www.pyopenssl.org/en/latest/api/crypto.html#x509store-objects ) those are probably the most flexible examples of asking "Does this certificate validate with this CA/CRL chain using the [openssl] polices I choose to set?". That level of flexibility does mean its full of footguns for someone to use and potentially whiff on ( for example, validating a server certificate is signed but not taking the extra step to validate the name is as expected ). @exFalso If you've got good examples you can share I bet that would be helpful for the PYCA devs in their feature planning :) |
@woodruffw @vEpiphyte sure I can expand. We're working with Intel SGX remote attestation, which requires a client of a remotely executing code to verify certain cryptographic evidence (it's essentially Intel signing off on the fact that a piece of code has been isolated and is running using encrypted memory). The remote code will present a certificate chain with a signature over a byteblob which contains further data about that running code. Part of the verification is the chain verification (there are quite a few more steps to it). Example API: https://api.portal.trustedservices.intel.com/content/documentation.html#pcs-certificate-v4-response Example trust_roots = [spec_dcap.dcapRootCaDer]
validation_context = ValidationContext(trust_roots)
validator = CertificateValidator(
pck_certs[0].as_bytes(),
intermediate_certs=map(lambda cert: cert.as_bytes(), pck_certs[1:]),
validation_context=validation_context,
)
validator.validate_usage({"digital_signature"}) (sidenote: I know the camelcase field is an eyesore, that comes from generated code ;) ) Example root certificate, this is the Intel SGX DCAP root:
The full verification requires a lot more steps. As you can see, this is a highly specialized use case, and implementing a separate specialized validator in an x509 library is unwarranted. Instead, a verifier for the overall chain integrity would suffice, and any additional checks we want to implement would be separate. However, this is currently not possible with Another completely different use-case is SPIFFE: https://github.com/spiffe/spiffe/blob/main/standards/X509-SVID.md, where again, the webPKI-specialized validator will not work. I would highly recommend not implementing these verifiers, but rather exposing the primitives (probably under hazmat) that allow library users to verify. |
Thanks for the additional context @exFalso! It looks like the Intel SGX certificate profile is defined here: https://download.01.org/intel-sgx/latest/dcap-latest/linux/docs/SGX_PCK_Certificate_CRL_Spec-1.4.pdf However, I agree that it probably doesn't make a ton of sense to expose a dedicated API for every X.509 profile on the planet 🙂. Having a building block validator under |
This worked, thank you! |
It's very similar to that code. root_x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, spec_dcap.dcapRootCaDer)
trust_store = OpenSSL.crypto.X509Store()
trust_store.add_cert(root_x509)
pck_x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, pck_certs[0].as_bytes())
intermediate_certs = map(lambda cert: OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert.as_bytes()), pck_certs[1:])
context = OpenSSL.crypto.X509StoreContext(trust_store, pck_x509, list(intermediate_certs))
context.verify_certificate() It is a lot more cumbersome to do additional checks like on |
Another non web use case is in verification of TPM certificates (e.g. Endorsement Key, which is signed by the TPM manufacturer; and Attestation Keys signed by the system manufacturer or owner). I think similar to the cases described by exFalso, path validation is relatively standard but the application needs to do additional checks on the leaf certificate e.g. checking the certificate policy and key usage extensions for the appropriate OIDs. The primitives needed to implement path validation on top of cryptography are all there, but there are a lot of opportunities to get it wrong too. |
FYI, for completeness, my use case for this functionality is certificate verification for XML Signature (which is used in SAML 2.0 and XAdES), and TSP (RFC 3161), also used in XAdES and other applications. |
Just to give a brief update here: the work in #10345 is pretty much done, and just needs to be deconflicted (and reviewed, of course). Once merged, that will expose Python APIs for "client" verification (i.e. path validation without subject assertions, with the expectation that the validating party will check the subjects or otherwise handle the chain appropriately subsequently). |
Thanks to all who worked on the X.509 verification support in version 42.
I am trying to use this API for verifying a signing certificate, and realizing that the API requires me to assert a subject name (DNS name or IP address) to get the validation output. The subject name is not defined/not relevant in this application.
How can I verify that a certificate is in the chain of trust without asserting on the subject name?
The text was updated successfully, but these errors were encountered: