diff options
author | Jack Lloyd <[email protected]> | 2017-03-07 10:18:48 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-03-07 10:18:48 -0500 |
commit | b532e453086c4d5072561dcd7d596aa1b0299cb7 (patch) | |
tree | 658cb4abf0149467e1a26f5612e6172930bf01ad | |
parent | 76fb731331fc380f41d76a0788b22b3d7216fd82 (diff) | |
parent | 9048a00464a1dcbcaa793fb3b76382589114d05f (diff) |
Merge GH #901 Allow OCSP requests without the full subject certificate
-rw-r--r-- | doc/manual/x509.rst | 24 | ||||
-rw-r--r-- | src/lib/x509/ocsp.cpp | 37 | ||||
-rw-r--r-- | src/lib/x509/ocsp.h | 12 | ||||
-rw-r--r-- | src/lib/x509/ocsp_types.cpp | 6 | ||||
-rw-r--r-- | src/lib/x509/ocsp_types.h | 2 | ||||
-rw-r--r-- | src/lib/x509/x509path.cpp | 2 | ||||
-rw-r--r-- | src/tests/test_ocsp.cpp | 10 |
7 files changed, 69 insertions, 24 deletions
diff --git a/doc/manual/x509.rst b/doc/manual/x509.rst index 9ec8112ea..58ad1d0ca 100644 --- a/doc/manual/x509.rst +++ b/doc/manual/x509.rst @@ -698,10 +698,15 @@ the subject's issuing certificate. .. cpp:class:: OCSP::Request .. cpp:function:: OCSP::Request(const X509_Certificate& issuer_cert, \ - const X509_Certificate& subject_cert) + const BigInt& subject_serial) Create a new OCSP request + .. cpp:function:: OCSP::Request(const X509_Certificate& issuer_cert, \ + const X509_Certificate& subject_cert) + + Variant of the above, using serial number from ``subject_cert``. + .. cpp:function:: std::vector<byte> BER_encode() const Encode the current OCSP request as a binary string. @@ -783,11 +788,18 @@ Appendix A for details. A basic implementation of this is the function was compiled in; check by testing for the macro ``BOTAN_HAS_HTTP_UTIL``. .. cpp:function:: OCSP::Response online_check(const X509_Certificate& issuer, \ + const BigInt& subject_serial, \ + const std::string& ocsp_responder, \ + const Certificate_Store* trusted_roots) + + Assemble a OCSP request for serial number ``subject_serial`` and attempt to request + it to responder at URI ``ocsp_responder`` over a new HTTP socket, parses and returns + the response. If trusted_roots is not null, then the response is additionally + validated using OCSP response API ``check_signature``. Otherwise, this call must be + performed later by the application. + +.. cpp:function:: OCSP::Response online_check(const X509_Certificate& issuer, \ const X509_Certificate& subject, \ const Certificate_Store* trusted_roots) - Attempts to contact the OCSP responder specified in the subject certificate - over a new HTTP socket, parses and returns the response. If trusted_roots is - not null, then the response is additionally validated using OCSP response API - ``check_signature``. Otherwise, this call must be performed later by the - application. + Variant of the above but uses serial number and OCSP responder URI from ``subject``. diff --git a/src/lib/x509/ocsp.cpp b/src/lib/x509/ocsp.cpp index 964299f64..be8e6ed1d 100644 --- a/src/lib/x509/ocsp.cpp +++ b/src/lib/x509/ocsp.cpp @@ -53,13 +53,19 @@ void decode_optional_list(BER_Decoder& ber, Request::Request(const X509_Certificate& issuer_cert, const X509_Certificate& subject_cert) : m_issuer(issuer_cert), - m_subject(subject_cert), - m_certid(m_issuer, m_subject) + m_certid(m_issuer, BigInt::decode(subject_cert.serial_number())) { if(subject_cert.issuer_dn() != issuer_cert.subject_dn()) throw Invalid_Argument("Invalid cert pair to OCSP::Request (mismatched issuer,subject args?)"); } +Request::Request(const X509_Certificate& issuer_cert, + const BigInt& subject_serial) : + m_issuer(issuer_cert), + m_certid(m_issuer, subject_serial) + { + } + std::vector<uint8_t> Request::BER_encode() const { return DER_Encoder().start_cons(SEQUENCE) @@ -275,17 +281,16 @@ Certificate_Status_Code Response::status_for(const X509_Certificate& issuer, #if defined(BOTAN_HAS_HTTP_UTIL) Response online_check(const X509_Certificate& issuer, - const X509_Certificate& subject, + const BigInt& subject_serial, + const std::string& ocsp_responder, Certificate_Store* trusted_roots) { - const std::string responder_url = subject.ocsp_responder(); + if(ocsp_responder.empty()) + throw Invalid_Argument("No OCSP responder specified"); - if(responder_url.empty()) - throw Exception("No OCSP responder specified"); + OCSP::Request req(issuer, subject_serial); - OCSP::Request req(issuer, subject); - - auto http = HTTP::POST_sync(responder_url, + auto http = HTTP::POST_sync(ocsp_responder, "application/ocsp-request", req.BER_encode()); @@ -304,6 +309,20 @@ Response online_check(const X509_Certificate& issuer, return response; } + +Response online_check(const X509_Certificate& issuer, + const X509_Certificate& subject, + Certificate_Store* trusted_roots) + { + if(subject.issuer_dn() != issuer.subject_dn()) + throw Invalid_Argument("Invalid cert pair to OCSP::online_check (mismatched issuer,subject args?)"); + + return online_check(issuer, + BigInt::decode(subject.serial_number()), + subject.ocsp_responder(), + trusted_roots); + } + #endif } diff --git a/src/lib/x509/ocsp.h b/src/lib/x509/ocsp.h index ff6a19567..881eee124 100644 --- a/src/lib/x509/ocsp.h +++ b/src/lib/x509/ocsp.h @@ -31,6 +31,9 @@ class BOTAN_DLL Request Request(const X509_Certificate& issuer_cert, const X509_Certificate& subject_cert); + Request(const X509_Certificate& issuer_cert, + const BigInt& subject_serial); + /** * @return BER-encoded OCSP request */ @@ -49,12 +52,12 @@ class BOTAN_DLL Request /** * @return subject certificate */ - const X509_Certificate& subject() const { return m_subject; } + const X509_Certificate& subject() const { throw Not_Implemented("Method have been deprecated"); } const std::vector<uint8_t>& issuer_key_hash() const { return m_certid.issuer_key_hash(); } private: - X509_Certificate m_issuer, m_subject; + X509_Certificate m_issuer; CertID m_certid; }; @@ -155,6 +158,11 @@ class BOTAN_DLL Response #if defined(BOTAN_HAS_HTTP_UTIL) +BOTAN_DLL Response online_check(const X509_Certificate& issuer, + const BigInt& subject_serial, + const std::string& ocsp_responder, + Certificate_Store* trusted_roots); + /** * Makes an online OCSP request via HTTP and returns the OCSP response. * @param issuer issuer certificate diff --git a/src/lib/x509/ocsp_types.cpp b/src/lib/x509/ocsp_types.cpp index c9d349a4b..470acffa6 100644 --- a/src/lib/x509/ocsp_types.cpp +++ b/src/lib/x509/ocsp_types.cpp @@ -17,7 +17,7 @@ namespace Botan { namespace OCSP { CertID::CertID(const X509_Certificate& issuer, - const X509_Certificate& subject) + const BigInt& subject_serial) { /* In practice it seems some responders, including, notably, @@ -27,8 +27,8 @@ CertID::CertID(const X509_Certificate& issuer, m_hash_id = AlgorithmIdentifier(hash->name(), AlgorithmIdentifier::USE_NULL_PARAM); m_issuer_key_hash = unlock(hash->process(issuer.subject_public_key_bitstring())); - m_issuer_dn_hash = unlock(hash->process(subject.raw_issuer_dn())); - m_subject_serial = BigInt::decode(subject.serial_number()); + m_issuer_dn_hash = unlock(hash->process(issuer.raw_subject_dn())); + m_subject_serial = subject_serial; } bool CertID::is_id_for(const X509_Certificate& issuer, diff --git a/src/lib/x509/ocsp_types.h b/src/lib/x509/ocsp_types.h index 1cbf207b8..be7ae716a 100644 --- a/src/lib/x509/ocsp_types.h +++ b/src/lib/x509/ocsp_types.h @@ -22,7 +22,7 @@ class BOTAN_DLL CertID final : public ASN1_Object CertID() {} CertID(const X509_Certificate& issuer, - const X509_Certificate& subject); + const BigInt& subject_serial); bool is_id_for(const X509_Certificate& issuer, const X509_Certificate& subject) const; diff --git a/src/lib/x509/x509path.cpp b/src/lib/x509/x509path.cpp index c70ecae7a..eeb75b279 100644 --- a/src/lib/x509/x509path.cpp +++ b/src/lib/x509/x509path.cpp @@ -275,7 +275,7 @@ PKIX::check_ocsp_online(const std::vector<std::shared_ptr<const X509_Certificate else { ocsp_response_futures.emplace_back(std::async(std::launch::async, [&]() -> std::shared_ptr<const OCSP::Response> { - OCSP::Request req(*issuer, *subject); + OCSP::Request req(*issuer, BigInt::decode(subject->serial_number())); auto http = HTTP::POST_sync(subject->ocsp_responder(), "application/ocsp-request", diff --git a/src/tests/test_ocsp.cpp b/src/tests/test_ocsp.cpp index 3fc1ad765..587977149 100644 --- a/src/tests/test_ocsp.cpp +++ b/src/tests/test_ocsp.cpp @@ -98,11 +98,17 @@ class OCSP_Tests : public Test result.test_success("Bad arguments rejected"); } - const Botan::OCSP::Request req(issuer, end_entity); + const std::string expected_request = "ME4wTKADAgEAMEUwQzBBMAkGBSsOAwIaBQAEFPLgavmFih2NcJtJGSN6qbUaKH5kBBRK3QYWG7z2aLV29YG2u2IaulqBLwIIQkg+DF+RYMY="; + const Botan::OCSP::Request req1(issuer, end_entity); + result.test_eq("Encoded OCSP request", + req1.base64_encode(), + expected_request); + + const Botan::OCSP::Request req2(issuer, BigInt::decode(end_entity.serial_number())); result.test_eq("Encoded OCSP request", - req.base64_encode(), + req2.base64_encode(), expected_request); return result; |