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

Retrieve chain after certificate validation - what should API look like? #740

Closed
MerlijnWajer opened this issue Mar 13, 2018 · 10 comments · Fixed by #894
Closed

Retrieve chain after certificate validation - what should API look like? #740

MerlijnWajer opened this issue Mar 13, 2018 · 10 comments · Fixed by #894

Comments

@MerlijnWajer
Copy link

It would be nice if we could fetch and examine the chain after calling verify_certificate (Which calls X509_verify_cert). https://pyopenssl.org/en/stable/api/crypto.html#OpenSSL.crypto.X509StoreContext)

I'm wondering what you think the API should look like. Fetch the entire chain at once and return it to the user, or allows the user to actually iterate over the chain?

Here's an example that shows how to parse the chain after a X509_verify_cert call: https://github.com/openssl/openssl/blob/master/apps/verify.c#L243

I'm willing to implement this feature - I don't think it should be too hard, but it can be quite valuable.

@tiran
Copy link

tiran commented Mar 13, 2018

Are you interested in the chain returned by the peer or are you interested in the actual chain that has been used to verify the peer? These are two totally different things although they often look the same.

@MerlijnWajer
Copy link
Author

Good question. I am interested in the entire chain that was used the validate the certificate/peer - that is, the chain that was built with the certificates in my store. Not the chain returned by the peer.

@tiran
Copy link

tiran commented Mar 13, 2018

OpenSSL 1.1.0 introduced SSL_get0_verified_chain(). The feature is not available with LibreSSL and OpenSSL 1.0.2.

@MerlijnWajer
Copy link
Author

I'm confused. What if I am not doing any SSL/TLS and just want to use verify_certificate without a network connection? This is my (original) use case (I have a certificate, retrieve from disk or from nginx header) and I want to verify it and also access the chain that resulted from the verification. The API that I linked exists since 0.9.8 at least, so that should be compatible with most implementations.

@MerlijnWajer
Copy link
Author

Any other thoughts?

@MerlijnWajer
Copy link
Author

Bump :)

ShaneHarvey added a commit to ShaneHarvey/pyopenssl that referenced this issue Mar 3, 2020
Add X509StoreContext.get_verified_chain using X509_STORE_CTX_get1_chain.
Add Connection.get_verified_chain using SSL_get0_verified_chain if
available (ie OpenSSL 1.1+) and X509StoreContext.get_verified_chain
otherwise.
Fixes pyca#740.
@ShaneHarvey
Copy link
Contributor

ShaneHarvey commented Mar 3, 2020

I've added support for accessing a connection's verified peer certification chain in #894.

Edit: the API is chain = connection.get_verified_chain() which should be in the next release 20.0.

ShaneHarvey added a commit to ShaneHarvey/pyopenssl that referenced this issue Aug 5, 2020
Add X509StoreContext.get_verified_chain using X509_STORE_CTX_get1_chain.
Add Connection.get_verified_chain using SSL_get0_verified_chain if
available (ie OpenSSL 1.1+) and X509StoreContext.get_verified_chain
otherwise.
Fixes pyca#740.
reaperhulk pushed a commit that referenced this issue Aug 5, 2020
* Allow accessing a connection's verfied certificate chain

Add X509StoreContext.get_verified_chain using X509_STORE_CTX_get1_chain.
Add Connection.get_verified_chain using SSL_get0_verified_chain if
available (ie OpenSSL 1.1+) and X509StoreContext.get_verified_chain
otherwise.
Fixes #740.

* TLSv1_METHOD -> SSLv23_METHOD

* Use X509_up_ref instead of X509_dup

* Add _openssl_assert where appropriate

* SSL_get_peer_cert_chain should not be null

* Reformat with black

* Fix <OpenSSL.crypto.X509 object at 0x7fdbb59e8050> != <OpenSSL.crypto.X509 object at 0x7fdbb59daad0>

* Add Changelog entry

* Remove _add_chain
@MerlijnWajer
Copy link
Author

Thanks for that. I believe this is still only for a specific connection, as opposed to any certificate verification check, right?

@ShaneHarvey
Copy link
Contributor

It would be nice if we could fetch and examine the chain after calling verify_certificate (Which calls X509_verify_cert). https://pyopenssl.org/en/stable/api/crypto.html#OpenSSL.crypto.X509StoreContext)

Yes I also added X509StoreContext.get_verified_chain() which returns the verified chain:

def get_verified_chain(self):
"""
Verify a certificate in a context and return the complete validated
chain.
:raises X509StoreContextError: If an error occurred when validating a
certificate in the context. Sets ``certificate`` attribute to
indicate which certificate caused the error.
.. versionadded:: 20.0
"""

@MerlijnWajer
Copy link
Author

Great, thanks!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging a pull request may close this issue.

3 participants