diff options
-rw-r--r-- | src/cert/ocsp/info.txt | 1 | ||||
-rw-r--r-- | src/cert/ocsp/ocsp.cpp | 37 | ||||
-rw-r--r-- | src/cert/ocsp/ocsp.h | 7 |
3 files changed, 42 insertions, 3 deletions
diff --git a/src/cert/ocsp/info.txt b/src/cert/ocsp/info.txt index 9f99b30fd..914f2b654 100644 --- a/src/cert/ocsp/info.txt +++ b/src/cert/ocsp/info.txt @@ -3,4 +3,5 @@ define OCSP 20131128 <requires> x509 sha1 +http_util </requires> diff --git a/src/cert/ocsp/ocsp.cpp b/src/cert/ocsp/ocsp.cpp index 8b6d500f5..d894abc97 100644 --- a/src/cert/ocsp/ocsp.cpp +++ b/src/cert/ocsp/ocsp.cpp @@ -6,6 +6,7 @@ */ #include <botan/ocsp.h> +#include <botan/certstor.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/x509_ext.h> @@ -13,6 +14,7 @@ #include <botan/base64.h> #include <botan/pubkey.h> #include <botan/x509path.h> +#include <botan/http_util.h> #include <memory> namespace Botan { @@ -72,7 +74,10 @@ void check_signature(const std::vector<byte>& tbs_response, const Certificate_Store& trusted_roots, const std::vector<X509_Certificate>& certs) { - if(trusted_roots.certificate_known(certs[0])) + if(certs.size() < 1) + throw std::invalid_argument("Short cert chain for check_signature"); + + if(trusted_roots.certificate_known(certs[0])) // directly signed by return check_signature(tbs_response, sig_algo, signature, certs[0]); // Otherwise attempt to chain the signing cert to a trust root @@ -88,7 +93,7 @@ void check_signature(const std::vector<byte>& tbs_response, if(!result.successful_validation()) throw std::runtime_error("Certificate validation failure: " + result.result_string()); - if(!trusted_roots.certificate_known(result.trust_root())) + if(!trusted_roots.certificate_known(result.trust_root())) // not needed anymore? throw std::runtime_error("Certificate chain roots in unknown/untrusted CA"); const std::vector<X509_Certificate>& cert_path = result.cert_path(); @@ -130,6 +135,9 @@ Response::Response(const Certificate_Store& trusted_roots, response_outer.decode(resp_status, ENUMERATED, UNIVERSAL); + if(resp_status != 0) + throw std::runtime_error("OCSP response status " + std::to_string(resp_status)); + if(response_outer.more_items()) { BER_Decoder response_bytes = @@ -199,6 +207,31 @@ bool Response::affirmative_response_for(const X509_Certificate& issuer, return false; } +Response online_check(const X509_Certificate& issuer, + const X509_Certificate& subject, + const Certificate_Store& trusted_roots) + { + const std::string responder_url = subject.ocsp_responder(); + + if(responder_url == "") + throw std::runtime_error("No OCSP responder specified"); + + OCSP::Request req(issuer, subject); + + auto http = HTTP::POST_sync(responder_url, + "application/ocsp-request", + req.BER_encode()); + + if(http.status_code() != 200) + throw std::runtime_error("HTTP error: " + http.status_message()); + + // Check the MIME type? + + OCSP::Response response(trusted_roots, http.body()); + + return response; + } + } } diff --git a/src/cert/ocsp/ocsp.h b/src/cert/ocsp/ocsp.h index ad2d2cf81..ec86b434e 100644 --- a/src/cert/ocsp/ocsp.h +++ b/src/cert/ocsp/ocsp.h @@ -9,10 +9,11 @@ #define BOTAN_OCSP_H__ #include <botan/ocsp_types.h> -#include <botan/certstor.h> namespace Botan { +class Certificate_Store; + namespace OCSP { class BOTAN_DLL Request @@ -48,6 +49,10 @@ class BOTAN_DLL Response std::vector<SingleResponse> m_responses; }; +BOTAN_DLL Response online_check(const X509_Certificate& issuer, + const X509_Certificate& subject, + const Certificate_Store& trusted_roots); + } } |