diff options
Diffstat (limited to 'src/libs/3rdparty/botan/src/lib/x509/ocsp.cpp')
-rw-r--r-- | src/libs/3rdparty/botan/src/lib/x509/ocsp.cpp | 354 |
1 files changed, 0 insertions, 354 deletions
diff --git a/src/libs/3rdparty/botan/src/lib/x509/ocsp.cpp b/src/libs/3rdparty/botan/src/lib/x509/ocsp.cpp deleted file mode 100644 index 115c4117ac..0000000000 --- a/src/libs/3rdparty/botan/src/lib/x509/ocsp.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/* -* OCSP -* (C) 2012,2013 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include <botan/ocsp.h> -#include <botan/certstor.h> -#include <botan/der_enc.h> -#include <botan/ber_dec.h> -#include <botan/x509_ext.h> -#include <botan/oids.h> -#include <botan/base64.h> -#include <botan/pubkey.h> -#include <botan/parsing.h> - -#if defined(BOTAN_HAS_HTTP_UTIL) - #include <botan/http_util.h> -#endif - -namespace Botan { - -namespace OCSP { - -namespace { - -// TODO: should this be in a header somewhere? -void decode_optional_list(BER_Decoder& ber, - ASN1_Tag tag, - std::vector<X509_Certificate>& output) - { - BER_Object obj = ber.get_next_object(); - - if(obj.is_a(tag, ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED)) == false) - { - ber.push_back(obj); - return; - } - - BER_Decoder list(obj); - - while(list.more_items()) - { - BER_Object certbits = list.get_next_object(); - X509_Certificate cert(certbits.bits(), certbits.length()); - output.push_back(std::move(cert)); - } - } - -} - -Request::Request(const X509_Certificate& issuer_cert, - const X509_Certificate& subject_cert) : - m_issuer(issuer_cert), - 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 - { - std::vector<uint8_t> output; - DER_Encoder(output).start_cons(SEQUENCE) - .start_cons(SEQUENCE) - .start_explicit(0) - .encode(static_cast<size_t>(0)) // version # - .end_explicit() - .start_cons(SEQUENCE) - .start_cons(SEQUENCE) - .encode(m_certid) - .end_cons() - .end_cons() - .end_cons() - .end_cons(); - - return output; - } - -std::string Request::base64_encode() const - { - return Botan::base64_encode(BER_encode()); - } - -Response::Response(Certificate_Status_Code status) - { - m_dummy_response_status = status; - } - -Response::Response(const uint8_t response_bits[], size_t response_bits_len) : - m_response_bits(response_bits, response_bits + response_bits_len) - { - m_dummy_response_status = Certificate_Status_Code::OCSP_RESPONSE_INVALID; - - BER_Decoder response_outer = BER_Decoder(m_response_bits).start_cons(SEQUENCE); - - size_t resp_status = 0; - - response_outer.decode(resp_status, ENUMERATED, UNIVERSAL); - - if(resp_status != 0) - throw Exception("OCSP response status " + std::to_string(resp_status)); - - if(response_outer.more_items()) - { - BER_Decoder response_bytes = - response_outer.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).start_cons(SEQUENCE); - - response_bytes.decode_and_check(OID("1.3.6.1.5.5.7.48.1.1"), - "Unknown response type in OCSP response"); - - BER_Decoder basicresponse = - BER_Decoder(response_bytes.get_next_octet_string()).start_cons(SEQUENCE); - - basicresponse.start_cons(SEQUENCE) - .raw_bytes(m_tbs_bits) - .end_cons() - .decode(m_sig_algo) - .decode(m_signature, BIT_STRING); - decode_optional_list(basicresponse, ASN1_Tag(0), m_certs); - - size_t responsedata_version = 0; - Extensions extensions; - - BER_Decoder(m_tbs_bits) - .decode_optional(responsedata_version, ASN1_Tag(0), - ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) - - .decode_optional(m_signer_name, ASN1_Tag(1), - ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) - - .decode_optional_string(m_key_hash, OCTET_STRING, 2, - ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) - - .decode(m_produced_at) - - .decode_list(m_responses) - - .decode_optional(extensions, ASN1_Tag(1), - ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)); - } - - response_outer.end_cons(); - } - -Certificate_Status_Code Response::verify_signature(const X509_Certificate& issuer) const - { - if (m_responses.empty()) - return m_dummy_response_status; - - try - { - std::unique_ptr<Public_Key> pub_key(issuer.subject_public_key()); - - const std::vector<std::string> sig_info = - split_on(OIDS::lookup(m_sig_algo.get_oid()), '/'); - - if(sig_info.size() != 2 || sig_info[0] != pub_key->algo_name()) - return Certificate_Status_Code::OCSP_RESPONSE_INVALID; - - std::string padding = sig_info[1]; - Signature_Format format = (pub_key->message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; - - PK_Verifier verifier(*pub_key, padding, format); - - if(verifier.verify_message(ASN1::put_in_sequence(m_tbs_bits), m_signature)) - return Certificate_Status_Code::OCSP_SIGNATURE_OK; - else - return Certificate_Status_Code::OCSP_SIGNATURE_ERROR; - } - catch(Exception&) - { - return Certificate_Status_Code::OCSP_SIGNATURE_ERROR; - } - } - -Certificate_Status_Code Response::check_signature(const std::vector<Certificate_Store*>& trusted_roots, - const std::vector<std::shared_ptr<const X509_Certificate>>& ee_cert_path) const - { - if (m_responses.empty()) - return m_dummy_response_status; - - std::shared_ptr<const X509_Certificate> signing_cert; - - for(size_t i = 0; i != trusted_roots.size(); ++i) - { - if(m_signer_name.empty() && m_key_hash.empty()) - return Certificate_Status_Code::OCSP_RESPONSE_INVALID; - - if(!m_signer_name.empty()) - { - signing_cert = trusted_roots[i]->find_cert(m_signer_name, std::vector<uint8_t>()); - if(signing_cert) - { - break; - } - } - - if(m_key_hash.size() > 0) - { - signing_cert = trusted_roots[i]->find_cert_by_pubkey_sha1(m_key_hash); - if(signing_cert) - { - break; - } - } - } - - if(!signing_cert && ee_cert_path.size() > 1) - { - // End entity cert is not allowed to sign their own OCSP request :) - for(size_t i = 1; i < ee_cert_path.size(); ++i) - { - // Check all CA certificates in the (assumed validated) EE cert path - if(!m_signer_name.empty() && ee_cert_path[i]->subject_dn() == m_signer_name) - { - signing_cert = ee_cert_path[i]; - break; - } - - if(m_key_hash.size() > 0 && ee_cert_path[i]->subject_public_key_bitstring_sha1() == m_key_hash) - { - signing_cert = ee_cert_path[i]; - break; - } - } - } - - if(!signing_cert && m_certs.size() > 0) - { - for(size_t i = 0; i < m_certs.size(); ++i) - { - // Check all CA certificates in the (assumed validated) EE cert path - if(!m_signer_name.empty() && m_certs[i].subject_dn() == m_signer_name) - { - signing_cert = std::make_shared<const X509_Certificate>(m_certs[i]); - break; - } - - if(m_key_hash.size() > 0 && m_certs[i].subject_public_key_bitstring_sha1() == m_key_hash) - { - signing_cert = std::make_shared<const X509_Certificate>(m_certs[i]); - break; - } - } - } - - if(!signing_cert) - return Certificate_Status_Code::OCSP_ISSUER_NOT_FOUND; - - if(!signing_cert->allowed_usage(CRL_SIGN) && - !signing_cert->allowed_extended_usage("PKIX.OCSPSigning")) - { - return Certificate_Status_Code::OCSP_RESPONSE_MISSING_KEYUSAGE; - } - - return this->verify_signature(*signing_cert); - } - -Certificate_Status_Code Response::status_for(const X509_Certificate& issuer, - const X509_Certificate& subject, - std::chrono::system_clock::time_point ref_time) const - { - if (m_responses.empty()) - return m_dummy_response_status; - - for(const auto& response : m_responses) - { - if(response.certid().is_id_for(issuer, subject)) - { - X509_Time x509_ref_time(ref_time); - - if(response.cert_status() == 1) - return Certificate_Status_Code::CERT_IS_REVOKED; - - if(response.this_update() > x509_ref_time) - return Certificate_Status_Code::OCSP_NOT_YET_VALID; - - if(response.next_update().time_is_set() && x509_ref_time > response.next_update()) - return Certificate_Status_Code::OCSP_HAS_EXPIRED; - - if(response.cert_status() == 0) - return Certificate_Status_Code::OCSP_RESPONSE_GOOD; - else - return Certificate_Status_Code::OCSP_BAD_STATUS; - } - } - - return Certificate_Status_Code::OCSP_CERT_NOT_LISTED; - } - -#if defined(BOTAN_HAS_HTTP_UTIL) - -Response online_check(const X509_Certificate& issuer, - const BigInt& subject_serial, - const std::string& ocsp_responder, - Certificate_Store* trusted_roots, - std::chrono::milliseconds timeout) - { - if(ocsp_responder.empty()) - throw Invalid_Argument("No OCSP responder specified"); - - OCSP::Request req(issuer, subject_serial); - - auto http = HTTP::POST_sync(ocsp_responder, - "application/ocsp-request", - req.BER_encode(), - 1, - timeout); - - http.throw_unless_ok(); - - // Check the MIME type? - - OCSP::Response response(http.body()); - - std::vector<Certificate_Store*> trusted_roots_vec; - trusted_roots_vec.push_back(trusted_roots); - - if(trusted_roots) - response.check_signature(trusted_roots_vec); - - return response; - } - - -Response online_check(const X509_Certificate& issuer, - const X509_Certificate& subject, - Certificate_Store* trusted_roots, - std::chrono::milliseconds timeout) - { - 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, - timeout); - } - -#endif - -} - -} |