aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-03-07 10:18:48 -0500
committerJack Lloyd <[email protected]>2017-03-07 10:18:48 -0500
commitb532e453086c4d5072561dcd7d596aa1b0299cb7 (patch)
tree658cb4abf0149467e1a26f5612e6172930bf01ad
parent76fb731331fc380f41d76a0788b22b3d7216fd82 (diff)
parent9048a00464a1dcbcaa793fb3b76382589114d05f (diff)
Merge GH #901 Allow OCSP requests without the full subject certificate
-rw-r--r--doc/manual/x509.rst24
-rw-r--r--src/lib/x509/ocsp.cpp37
-rw-r--r--src/lib/x509/ocsp.h12
-rw-r--r--src/lib/x509/ocsp_types.cpp6
-rw-r--r--src/lib/x509/ocsp_types.h2
-rw-r--r--src/lib/x509/x509path.cpp2
-rw-r--r--src/tests/test_ocsp.cpp10
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;