Re: [openssl-dev] [openssl.org #2634] Cross-signed certs rejected by OpenSSL because root cert not base of chain
On 25/02/15 13:18, Matt Caswell wrote: > This is not a bug as such in OpenSSL but an addition to the existing > verify algorithm. As such this won't be backported to released versions > (which only receive bug fixes). It will however be in OpenSSL 1.1.0. I should add that OpenSSL 1.0.2 does already have the X509_V_FLAG_TRUSTED_FIRST flag (-trusted_first option to s_client) that does a very similar job in a slightly different way. However, it is not the default like the new commits. Matt ___ openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [openssl.org #2634] Cross-signed certs rejected by OpenSSL because root cert not base of chain
On 24/02/15 21:28, na...@sitetruth.com via RT wrote: > This is an old bug from 2011, generated originally by someone who put a > self-signed cert in their cert chain. Until now, it's been ignored. > It's become a big problem now that Verisign cross-signed one of their > major root certs (VeriSign Class 3 Public Primary Certification > Authority - G5). Their root cert is thus no longer the base of a > chain, and is rejected by OpenSSL. This bug now comes up if you use > Mozilla's root cert store with Python. It's affecting some major > web sites and systems which use OpenSSL are struggling to deal > with this defect. Your description of this issue isn't quite right I think. There are actually two different certificates for "VeriSign Class 3 Public Primary Certification Authority - G5" - an old one and a new one. I've attached them both. If you look at each certificate you will notice that the modulus/SubjectKeyIdentifier/Subject are the same in both. In other words the private/public keys are the same and the certificate is issued to the same Subject. However the issuers are different. For the old one: Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority and the new one: Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 For the new one, the issuer is the same as the subject - this is as self signed certificate and is a true root in its own right. Its not the case that suddenly the "root cert is no longer the base of the chain". Because both certificates have the same subject and have the same keys - both can be used to form valid certificate chains. The difference is that before, normally, there would only ever be one way to make a chain. Now, with CAs issuing certs like this, there is more than one way. OpenSSL only supports one way of making a chain (its only ever needed one way). The algorithm works something like this: Take the certificate provided by the remote peer. Try and build as long a chain as possible from the untrusted certificates provided by that remote peer. If we can build a full chain (all the way back to a self-signed root) from untrusted certificates, look to see if we have the same root in our trust store. If so, replace the untrusted root, with our trusted root. We have a complete (and trusted) chain. If we can't build a full chain from the peer provided certs, see if we can add certs from our trust store. Keep adding them until we get to a root. If we successfully end up with a trusted root then we have a complete (and trusted) chain. Anything else means we don't have a trusted chain. Where servers provide all the certs up to and including the cert in verisign-old.pem, then OpenSSL will will try to complete that chain by looking in its trust store for the issuer of that cert, i.e. Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority If it doesn't find it then it has failed to build the chain and stops. However there is an alternative chain that could be built, i.e. if we modified the behaviour so that OpenSSL starts knocking off certs off the top of the chain provided by the peer, we could look to see if we have an alternative cert for that issuer in our store. If we find one then we have found an alternative chain. I have today pushed to the master branch in git a series of commits that do just that. See commits: da084a5ec6 15dba5be6a 25690b7f5f fa7b01115b You may also wish to look at RT tickets 3621 and 3637 which are relevant here. This is not a bug as such in OpenSSL but an addition to the existing verify algorithm. As such this won't be backported to released versions (which only receive bug fixes). It will however be in OpenSSL 1.1.0. > The problem can be reproduced with the OpenSSL command line client, > but only on some platforms. See the comments in the Python bug report: > > "I have determined that s_client is buggy. It will always load the > system certs *if and only if* you also pass it a valid custom CA cert > (which is the reverse of what's expected)." > > "Antione closed this, as a not python error, as > if you do not pass a valid certificate to openssl s_client > it will not read the system certificates, which is clearly > utterly surprising and nuts." > > So three different development teams now agree it's an OpenSSL bug. This is a completely separate issue and *is* a bug in s_client. I have just pulled together a fix for this which is going through review at the moment. This will be applied to master, 1.0.2 and 1.0.1. I will close RT 2634, as I think it is largely addressed by the latest commits in master. Matt verisign-new.pem Description: application/x509-ca-cert verisign-old.pem Description: application/x509-ca-cert ___ openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/open
Re: [openssl-dev] [openssl.org #2634] Cross-signed certs rejected by OpenSSL because root cert not base of chain
On 24/02/15 21:28, na...@sitetruth.com via RT wrote: > This is an old bug from 2011, generated originally by someone who put a > self-signed cert in their cert chain. Until now, it's been ignored. > It's become a big problem now that Verisign cross-signed one of their > major root certs (VeriSign Class 3 Public Primary Certification > Authority - G5). Their root cert is thus no longer the base of a > chain, and is rejected by OpenSSL. This bug now comes up if you use > Mozilla's root cert store with Python. It's affecting some major > web sites and systems which use OpenSSL are struggling to deal > with this defect. Your description of this issue isn't quite right I think. There are actually two different certificates for "VeriSign Class 3 Public Primary Certification Authority - G5" - an old one and a new one. I've attached them both. If you look at each certificate you will notice that the modulus/SubjectKeyIdentifier/Subject are the same in both. In other words the private/public keys are the same and the certificate is issued to the same Subject. However the issuers are different. For the old one: Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority and the new one: Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 For the new one, the issuer is the same as the subject - this is as self signed certificate and is a true root in its own right. Its not the case that suddenly the "root cert is no longer the base of the chain". Because both certificates have the same subject and have the same keys - both can be used to form valid certificate chains. The difference is that before, normally, there would only ever be one way to make a chain. Now, with CAs issuing certs like this, there is more than one way. OpenSSL only supports one way of making a chain (its only ever needed one way). The algorithm works something like this: Take the certificate provided by the remote peer. Try and build as long a chain as possible from the untrusted certificates provided by that remote peer. If we can build a full chain (all the way back to a self-signed root) from untrusted certificates, look to see if we have the same root in our trust store. If so, replace the untrusted root, with our trusted root. We have a complete (and trusted) chain. If we can't build a full chain from the peer provided certs, see if we can add certs from our trust store. Keep adding them until we get to a root. If we successfully end up with a trusted root then we have a complete (and trusted) chain. Anything else means we don't have a trusted chain. Where servers provide all the certs up to and including the cert in verisign-old.pem, then OpenSSL will will try to complete that chain by looking in its trust store for the issuer of that cert, i.e. Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority If it doesn't find it then it has failed to build the chain and stops. However there is an alternative chain that could be built, i.e. if we modified the behaviour so that OpenSSL starts knocking off certs off the top of the chain provided by the peer, we could look to see if we have an alternative cert for that issuer in our store. If we find one then we have found an alternative chain. I have today pushed to the master branch in git a series of commits that do just that. See commits: da084a5ec6 15dba5be6a 25690b7f5f fa7b01115b You may also wish to look at RT tickets 3621 and 3637 which are relevant here. This is not a bug as such in OpenSSL but an addition to the existing verify algorithm. As such this won't be backported to released versions (which only receive bug fixes). It will however be in OpenSSL 1.1.0. > The problem can be reproduced with the OpenSSL command line client, > but only on some platforms. See the comments in the Python bug report: > > "I have determined that s_client is buggy. It will always load the > system certs *if and only if* you also pass it a valid custom CA cert > (which is the reverse of what's expected)." > > "Antione closed this, as a not python error, as > if you do not pass a valid certificate to openssl s_client > it will not read the system certificates, which is clearly > utterly surprising and nuts." > > So three different development teams now agree it's an OpenSSL bug. This is a completely separate issue and *is* a bug in s_client. I have just pulled together a fix for this which is going through review at the moment. This will be applied to master, 1.0.2 and 1.0.1. I will close RT 2634, as I think it is largely addressed by the latest commits in master. Matt verisign-new.pem Description: application/x509-ca-cert verisign-old.pem Description: application/x509-ca-cert ___ openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/opens
[openssl-dev] [openssl.org #2634] Cross-signed certs rejected by OpenSSL because root cert not base of chain
This is an old bug from 2011, generated originally by someone who put a self-signed cert in their cert chain. Until now, it's been ignored. It's become a big problem now that Verisign cross-signed one of their major root certs (VeriSign Class 3 Public Primary Certification Authority - G5). Their root cert is thus no longer the base of a chain, and is rejected by OpenSSL. This bug now comes up if you use Mozilla's root cert store with Python. It's affecting some major web sites and systems which use OpenSSL are struggling to deal with this defect. I reported the bug for Python: http://bugs.python.org/issue23476 and the Python developers blame this OpenSSL bug. There's code there to reproduce the bug. Ubuntu has a workaround: https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/1014640 which involves modifying the cert file. (The order of the certificates in the cert file may be significant. Not sure about this.) The developers of the "request" add-on for Python's HTTP client have a different workaround, also involving using a different certificate bundle. https://github.com/kennethreitz/requests/issues/2455 See also this proposed patch from 2012: http://rt.openssl.org/Ticket/Display.html?id=2732 "2634: Fail to verify server with a trusted CA root in the middle of the chain". The problem can be reproduced with the OpenSSL command line client, but only on some platforms. See the comments in the Python bug report: "I have determined that s_client is buggy. It will always load the system certs *if and only if* you also pass it a valid custom CA cert (which is the reverse of what's expected)." "Antione closed this, as a not python error, as if you do not pass a valid certificate to openssl s_client it will not read the system certificates, which is clearly utterly surprising and nuts." So three different development teams now agree it's an OpenSSL bug. John Nagle ___ openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev