diff options
author | lloyd <[email protected]> | 2014-04-05 13:13:17 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2014-04-05 13:13:17 +0000 |
commit | aa3af43218106e184398f667f82110bb069abf8a (patch) | |
tree | cc602bc3e58a7b8fb364b3f31d373234c12459fb | |
parent | c286fc7584039edc117f2f25c1fca1d1903b79d3 (diff) |
Fix an OCSP response decoding bug, we were not decoding KeyID properly.
Also prioritize checking the status code before the dates, as
otherwise an attacker could substitue a valid but expired response
which marked the cert as revoked and we would still just return
OCSP_EXPIRED. Obviously they can still play this game with an old
(valid) OCSP response, but no point making it easy.
-rw-r--r-- | doc/relnotes/1_11_9.rst | 4 | ||||
-rw-r--r-- | src/lib/cert/x509/ocsp.cpp | 9 |
2 files changed, 9 insertions, 4 deletions
diff --git a/doc/relnotes/1_11_9.rst b/doc/relnotes/1_11_9.rst index 604c0d60e..8d9f17666 100644 --- a/doc/relnotes/1_11_9.rst +++ b/doc/relnotes/1_11_9.rst @@ -1,6 +1,10 @@ Version 1.11.9, Not Yet Released ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * Fixed a bug in OCSP response decoding which would cause an error + when attempting to decode responses from some widely used + responders. + * An implementation of HMAC_DRBG RNG from NIST SP800-90A has been added. Like the X9.31 PRNG implementation, it uses another underlying RNG for seeding material. diff --git a/src/lib/cert/x509/ocsp.cpp b/src/lib/cert/x509/ocsp.cpp index d848e9608..fe14588e9 100644 --- a/src/lib/cert/x509/ocsp.cpp +++ b/src/lib/cert/x509/ocsp.cpp @@ -170,7 +170,7 @@ Response::Response(const Certificate_Store& trusted_roots, .decode_optional(name, ASN1_Tag(1), ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) - .decode_optional_string(key_hash, ASN1_Tag(2), + .decode_optional_string(key_hash, OCTET_STRING, 2, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) .decode(produced_at) @@ -203,15 +203,16 @@ Certificate_Status_Code Response::status_for(const X509_Certificate& issuer, { X509_Time current_time(std::chrono::system_clock::now()); + if(response.cert_status() == 1) + return Certificate_Status_Code::CERT_IS_REVOKED; + if(response.this_update() > current_time) return Certificate_Status_Code::OCSP_NOT_YET_VALID; if(response.next_update().time_is_set() && current_time > response.next_update()) return Certificate_Status_Code::OCSP_EXPIRED; - if(response.cert_status() == 1) - return Certificate_Status_Code::CERT_IS_REVOKED; - else if(response.cert_status() == 0) + if(response.cert_status() == 0) return Certificate_Status_Code::OCSP_RESPONSE_GOOD; else return Certificate_Status_Code::OCSP_BAD_STATUS; |