From 6edc33b16120feece5a26cd8da6a61b77243cc69 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 28 Sep 2021 12:57:58 +0300 Subject: [PATCH] Handle redirect on AIA issuer fetch IB-7006 Signed-off-by: Raul Metsma --- src/crypto/OCSP.cpp | 29 +++++++++++++++++++---------- src/crypto/X509Cert.cpp | 2 +- src/crypto/X509CertStore.cpp | 4 +++- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/crypto/OCSP.cpp b/src/crypto/OCSP.cpp index e4220dccd..9405d9523 100644 --- a/src/crypto/OCSP.cpp +++ b/src/crypto/OCSP.cpp @@ -299,15 +299,6 @@ void OCSP::verifyResponse(const X509Cert &cert) const if(!resp) THROW("Failed to verify OCSP response."); - // Find issuer before OCSP validation to activate region TSL - X509Cert issuer = X509CertStore::instance()->findIssuer(cert, X509CertStore::CA); - if(!issuer) - { - Exception e(EXCEPTION_PARAMS("Certificate status: unknown")); - e.setCode(Exception::CertificateUnknown); - throw e; - } - time_t t = util::date::ASN1TimeToTime_t(producedAt()); SCOPE(X509_STORE, store, X509CertStore::createStore(X509CertStore::OCSP, &t)); STACK_OF(X509) *stack = sk_X509_new_null(); @@ -322,8 +313,26 @@ void OCSP::verifyResponse(const X509Cert &cert) const //all checks enabled fails trust bit check, cant use OCSP_NOEXPLICIT instead using OCSP_NOCHECKS int result = OCSP_basic_verify(basic.get(), stack, store.get(), OCSP_NOCHECKS); sk_X509_free(stack); - if(result <= 0) + if(result != 1) + { + unsigned long err = ERR_get_error(); + if(ERR_GET_LIB(err) == ERR_LIB_OCSP && ERR_GET_REASON(err) == OCSP_R_CERTIFICATE_VERIFY_ERROR) + { + Exception e(EXCEPTION_PARAMS("Certificate status: unknown")); + e.setCode(Exception::CertificateUnknown); + throw e; + } THROW_OPENSSLEXCEPTION("Failed to verify OCSP response."); + } + + // Find issuer before OCSP validation to activate region TSL + X509Cert issuer = X509CertStore::instance()->findIssuer(cert, X509CertStore::CA); + if(!issuer) + { + Exception e(EXCEPTION_PARAMS("Certificate status: unknown")); + e.setCode(Exception::CertificateUnknown); + throw e; + } int status = V_OCSP_CERTSTATUS_UNKNOWN; for(int i = 0, count = OCSP_resp_count(basic.get()); i < count; ++i) diff --git a/src/crypto/X509Cert.cpp b/src/crypto/X509Cert.cpp index 4879d15e1..7abfca353 100644 --- a/src/crypto/X509Cert.cpp +++ b/src/crypto/X509Cert.cpp @@ -235,7 +235,7 @@ X509Cert::X509Cert(const vector &bytes, Format format) X509Cert::X509Cert(const unsigned char *bytes, size_t size, Format format) { if(!bytes || size == 0) - THROW("No bytes given to parse X509."); + return; if(format == Der) { const unsigned char *p = bytes; diff --git a/src/crypto/X509CertStore.cpp b/src/crypto/X509CertStore.cpp index 7ed86b6bd..2d0ab27c7 100644 --- a/src/crypto/X509CertStore.cpp +++ b/src/crypto/X509CertStore.cpp @@ -165,7 +165,9 @@ X509Cert X509CertStore::issuerFromAIA(const X509Cert &cert) const } if(url.empty()) return X509Cert(); - Connect::Result result = Connect(url, "GET", 0, {}).exec(); + Connect::Result result = Connect(url, "GET").exec(); + if(result.isRedirect()) + result = Connect(result.headers["Location"], "GET").exec(); return X509Cert((const unsigned char*)result.content.c_str(), result.content.size()); }