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

verified certificate chain #31

Open
cunyx opened this issue Jul 5, 2019 · 3 comments
Open

verified certificate chain #31

cunyx opened this issue Jul 5, 2019 · 3 comments

Comments

@cunyx
Copy link

cunyx commented Jul 5, 2019

Thank you for providing the modularcrypto tools!

To get access to the verified certificate chain of TLS connections,
I tried to edit oscrypto for openssl >= 1.1.0 with

https://build.opensuse.org/package/view_file/home:cunix:pythondevel/python-oscrypto/verified_chain__attribute_added.patch

What are the chances to see something similar in your upstream code?

@wbond
Copy link
Owner

wbond commented Jul 5, 2019

I'm not familiar with this OpenSSL API - it sounds like it would return the same thing as the intermediates would, as long as the connection was verified?

@wbond
Copy link
Owner

wbond commented Jul 5, 2019

On a high level, I'm trying to keep oscrypto as cross-platform as possible. The idea being that you can build something on top of oscrypto and it will be portable across operating systems. With that goal in mind, ideally whatever features are added I'd like to find a corollary on Windows, Mac and Linux.

Based on that, if the verified chain is a form of the intermediates that have been verified, it may be possible to emulate this on other platforms by only returning the intermediates if the connection was verified?

@cunyx
Copy link
Author

cunyx commented Jul 5, 2019

Thanks for the answers!

On a high level, I'm trying to keep oscrypto as cross-platform as possible. The idea being that you can build something on top of oscrypto and it will be portable across operating systems. With that goal in mind, ideally whatever features are added I'd like to find a corollary on Windows, Mac and Linux.

That is very reasonable and my hope is, someone else has the knowledge and equipment to implement the Windows and Mac side of things.

Based on that, if the verified chain is a form of the intermediates that have been verified, it may be possible to emulate this on other platforms by only returning the intermediates if the connection was verified?

Being no expert, as I understand
https://www.openssl.org/docs/man1.1.0/man3/SSL_get0_verified_chain.html
SSL_get_peer_cert_chain, which is used for the intermediates attribute,
provides the certificates sent by the server without any validation.

These often don't include the root certificate, that must be trusted and therefore already be available on the client.

When openssl tries to build a certificate path from the peer's end-entity certificate to one of the trust anchors configured by the client, it might use the intermediates as hints to find a valid path faster, but it might ignore them, if it can build a chain directly to a trusted certificate or with other available certs as intermediates.

Something your browser might do with
https://incomplete-chain.badssl.com/

Consequently, the chain provided by SSL_get0_verified_chain often contains the intermediates, but not necessarily. The root of the CA is added most of the time.

Speculating, openssl might complete the handshake successfully if it finds a trusted path on another way, although the intermediates sent by the server are not complete, wrongly configured or if an attacker was able to replace the intermediates on the fly.

Therefore, in my opinion, it won't be a good idea to present the "intermediates" as (part of the) "verified_chain" without checks, because there is no guarantee, that they are incorporated into the verified and trusted chain and it might even be impossible to build a (trusted) chain with the certificates from SSL_get_peer_cert_chain although openssl didn't throw an error.

At least this is my understanding of
pyca/pyopenssl#740 (comment)
https://bugs.python.org/issue18233#msg293577
and the following messages in the bug.

A "workaround", where something like SSL_get0_verified_chain is not available, might be to use your certvalidator with the provided intermediates to find a trusted chain and copy the result into "verified_chain".

But I'm not sure if this is guaranteed to be the same chain that the crypto library uses, because with many (sometimes cross signed) root and intermediate certificates multiple trusted paths might exist and it depends on the crypto implementation which one is found first and in use to secure the connection.

This solution can only show "a" valid chain, not necessarily "the" (used) verified chain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants