aboutsummaryrefslogtreecommitdiffstats
path: root/src/cert/ocsp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2013-11-29 19:53:57 +0000
committerlloyd <[email protected]>2013-11-29 19:53:57 +0000
commit17952f5ed03bbc0000e486f390d86c6905efd86c (patch)
treefe4cf2ae4bc2e49ae4b68700fe82f327656808e1 /src/cert/ocsp
parentd8be6170619382d622abfd5a0540f315b2aa015d (diff)
Move OCSP to x509 subdir as they are quite entangled
Diffstat (limited to 'src/cert/ocsp')
-rw-r--r--src/cert/ocsp/info.txt7
-rw-r--r--src/cert/ocsp/ocsp.cpp252
-rw-r--r--src/cert/ocsp/ocsp.h61
-rw-r--r--src/cert/ocsp/ocsp_types.cpp121
-rw-r--r--src/cert/ocsp/ocsp_types.h67
5 files changed, 0 insertions, 508 deletions
diff --git a/src/cert/ocsp/info.txt b/src/cert/ocsp/info.txt
deleted file mode 100644
index 914f2b654..000000000
--- a/src/cert/ocsp/info.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-define OCSP 20131128
-
-<requires>
-x509
-sha1
-http_util
-</requires>
diff --git a/src/cert/ocsp/ocsp.cpp b/src/cert/ocsp/ocsp.cpp
deleted file mode 100644
index 2ea413e76..000000000
--- a/src/cert/ocsp/ocsp.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
-* OCSP
-* (C) 2012,2013 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#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/x509path.h>
-#include <botan/http_util.h>
-#include <memory>
-
-namespace Botan {
-
-namespace OCSP {
-
-namespace {
-
-void decode_optional_list(BER_Decoder& ber,
- ASN1_Tag tag,
- std::vector<X509_Certificate>& output)
- {
- BER_Object obj = ber.get_next_object();
-
- if(obj.type_tag != tag || obj.class_tag != (CONTEXT_SPECIFIC | CONSTRUCTED))
- {
- ber.push_back(obj);
- return;
- }
-
- BER_Decoder list(obj.value);
-
- while(list.more_items())
- {
- BER_Object certbits = list.get_next_object();
- X509_Certificate cert(unlock(certbits.value));
- output.push_back(std::move(cert));
- }
- }
-
-void check_signature(const std::vector<byte>& tbs_response,
- const AlgorithmIdentifier& sig_algo,
- const std::vector<byte>& signature,
- const X509_Certificate& cert)
- {
- std::unique_ptr<Public_Key> pub_key(cert.subject_public_key());
-
- const std::vector<std::string> sig_info =
- split_on(OIDS::lookup(sig_algo.oid), '/');
-
- if(sig_info.size() != 2 || sig_info[0] != pub_key->algo_name())
- throw std::runtime_error("Information in OCSP response does not match cert");
-
- 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(tbs_response), signature))
- throw std::runtime_error("Signature on OCSP response does not verify");
- }
-
-void check_signature(const std::vector<byte>& tbs_response,
- const AlgorithmIdentifier& sig_algo,
- const std::vector<byte>& signature,
- const Certificate_Store& trusted_roots,
- const std::vector<X509_Certificate>& certs)
- {
- if(certs.size() < 1)
- throw std::invalid_argument("Short cert chain for check_signature");
-
- if(trusted_roots.certificate_known(certs[0]))
- return check_signature(tbs_response, sig_algo, signature, certs[0]);
-
- // Otherwise attempt to chain the signing cert to a trust root
-
- if(!certs[0].allowed_usage("PKIX.OCSPSigning"))
- throw std::runtime_error("OCSP response cert does not allow OCSP signing");
-
- auto result = x509_path_validate(certs, Path_Validation_Restrictions(), trusted_roots);
-
- if(!result.successful_validation())
- throw std::runtime_error("Certificate validation failure: " + result.result_string());
-
- 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();
-
- check_signature(tbs_response, sig_algo, signature, cert_path[0]);
- }
-
-}
-
-std::vector<byte> Request::BER_encode() const
- {
- CertID certid(m_issuer, m_subject);
-
- return DER_Encoder().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(certid)
- .end_cons()
- .end_cons()
- .end_cons()
- .end_cons().get_contents_unlocked();
- }
-
-std::string Request::base64_encode() const
- {
- return Botan::base64_encode(BER_encode());
- }
-
-Response::Response(const Certificate_Store& trusted_roots,
- const std::vector<byte>& response_bits)
- {
- BER_Decoder response_outer = BER_Decoder(response_bits).start_cons(SEQUENCE);
-
- size_t resp_status = 0;
-
- 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 =
- 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);
-
- std::vector<byte> tbs_bits;
- AlgorithmIdentifier sig_algo;
- std::vector<byte> signature;
- std::vector<X509_Certificate> certs;
-
- basicresponse.start_cons(SEQUENCE)
- .raw_bytes(tbs_bits)
- .end_cons()
- .decode(sig_algo)
- .decode(signature, BIT_STRING);
- decode_optional_list(basicresponse, ASN1_Tag(0), certs);
-
- size_t responsedata_version = 0;
- X509_DN name;
- std::vector<byte> key_hash;
- X509_Time produced_at;
- Extensions extensions;
-
- BER_Decoder(tbs_bits)
- .decode_optional(responsedata_version, ASN1_Tag(0),
- ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
-
- .decode_optional(name, ASN1_Tag(1),
- ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
-
- .decode_optional_string(key_hash, ASN1_Tag(2),
- ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
-
- .decode(produced_at)
-
- .decode_list(m_responses)
-
- .decode_optional(extensions, ASN1_Tag(1),
- ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC));
-
- if(certs.empty())
- {
- if(auto cert = trusted_roots.find_cert(name, std::vector<byte>()))
- certs.push_back(*cert);
- else
- throw std::runtime_error("Could not find certificate that signed OCSP response");
- }
-
- check_signature(tbs_bits, sig_algo, signature, trusted_roots, certs);
- }
-
- response_outer.end_cons();
- }
-
-Certificate_Status_Code Response::status_for(const X509_Certificate& issuer,
- const X509_Certificate& subject) const
- {
- for(const auto& response : m_responses)
- {
- if(response.certid().is_id_for(issuer, subject))
- {
- X509_Time current_time(std::chrono::system_clock::now());
-
- 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)
- return Certificate_Status_Code::OCSP_RESPONSE_GOOD;
- else
- return Certificate_Status_Code::OCSP_BAD_STATUS;
- }
- }
-
- return Certificate_Status_Code::OCSP_CERT_NOT_LISTED;
- }
-
-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
deleted file mode 100644
index 0c40bc282..000000000
--- a/src/cert/ocsp/ocsp.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-* OCSP
-* (C) 2012 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#ifndef BOTAN_OCSP_H__
-#define BOTAN_OCSP_H__
-
-#include <botan/cert_status.h>
-#include <botan/ocsp_types.h>
-
-namespace Botan {
-
-class Certificate_Store;
-
-namespace OCSP {
-
-class BOTAN_DLL Request
- {
- public:
- Request(const X509_Certificate& issuer_cert,
- const X509_Certificate& subject_cert) :
- m_issuer(issuer_cert),
- m_subject(subject_cert)
- {}
-
- std::vector<byte> BER_encode() const;
-
- std::string base64_encode() const;
-
- const X509_Certificate& issuer() const { return m_issuer; }
-
- const X509_Certificate& subject() const { return m_subject; }
- private:
- X509_Certificate m_issuer, m_subject;
- };
-
-class BOTAN_DLL Response
- {
- public:
- Response(const Certificate_Store& trusted_roots,
- const std::vector<byte>& response);
-
- Certificate_Status_Code status_for(const X509_Certificate& issuer,
- const X509_Certificate& subject) const;
-
- private:
- std::vector<SingleResponse> m_responses;
- };
-
-BOTAN_DLL Response online_check(const X509_Certificate& issuer,
- const X509_Certificate& subject,
- const Certificate_Store& trusted_roots);
-
-}
-
-}
-
-#endif
diff --git a/src/cert/ocsp/ocsp_types.cpp b/src/cert/ocsp/ocsp_types.cpp
deleted file mode 100644
index be41499ee..000000000
--- a/src/cert/ocsp/ocsp_types.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-* OCSP subtypes
-* (C) 2012 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/ocsp_types.h>
-#include <botan/der_enc.h>
-#include <botan/ber_dec.h>
-#include <botan/x509_ext.h>
-#include <botan/lookup.h>
-#include <botan/hash.h>
-#include <botan/oids.h>
-#include <memory>
-
-namespace Botan {
-
-namespace OCSP {
-
-CertID::CertID(const X509_Certificate& issuer,
- const X509_Certificate& subject)
- {
- /*
- In practice it seems some responders, including, notably,
- ocsp.verisign.com, will reject anything but SHA-1 here
- */
- std::unique_ptr<HashFunction> hash(get_hash("SHA-160"));
-
- m_hash_id = AlgorithmIdentifier(hash->name(), AlgorithmIdentifier::USE_NULL_PARAM);
- m_issuer_key_hash = unlock(hash->process(extract_key_bitstr(issuer)));
- m_issuer_dn_hash = unlock(hash->process(subject.raw_issuer_dn()));
- m_subject_serial = BigInt::decode(subject.serial_number());
- }
-
-std::vector<byte> CertID::extract_key_bitstr(const X509_Certificate& cert) const
- {
- const auto key_bits = cert.subject_public_key_bits();
-
- AlgorithmIdentifier public_key_algid;
- std::vector<byte> public_key_bitstr;
-
- BER_Decoder(key_bits)
- .decode(public_key_algid)
- .decode(public_key_bitstr, BIT_STRING);
-
- return public_key_bitstr;
- }
-
-bool CertID::is_id_for(const X509_Certificate& issuer,
- const X509_Certificate& subject) const
- {
- try
- {
- if(BigInt::decode(subject.serial_number()) != m_subject_serial)
- return false;
-
- std::unique_ptr<HashFunction> hash(get_hash(OIDS::lookup(m_hash_id.oid)));
-
- if(m_issuer_dn_hash != unlock(hash->process(subject.raw_issuer_dn())))
- return false;
-
- if(m_issuer_key_hash != unlock(hash->process(extract_key_bitstr(issuer))))
- return false;
- }
- catch(...)
- {
- return false;
- }
-
- return true;
- }
-
-void CertID::encode_into(class DER_Encoder& to) const
- {
- to.start_cons(SEQUENCE)
- .encode(m_hash_id)
- .encode(m_issuer_dn_hash, OCTET_STRING)
- .encode(m_issuer_key_hash, OCTET_STRING)
- .encode(m_subject_serial)
- .end_cons();
- }
-
-void CertID::decode_from(class BER_Decoder& from)
- {
- from.start_cons(SEQUENCE)
- .decode(m_hash_id)
- .decode(m_issuer_dn_hash, OCTET_STRING)
- .decode(m_issuer_key_hash, OCTET_STRING)
- .decode(m_subject_serial)
- .end_cons();
-
- }
-
-void SingleResponse::encode_into(class DER_Encoder&) const
- {
- throw std::runtime_error("Not implemented (SingleResponse::encode_into)");
- }
-
-void SingleResponse::decode_from(class BER_Decoder& from)
- {
- BER_Object cert_status;
- Extensions extensions;
-
- from.start_cons(SEQUENCE)
- .decode(m_certid)
- .get_next(cert_status)
- .decode(m_thisupdate)
- .decode_optional(m_nextupdate, ASN1_Tag(0),
- ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED))
- .decode_optional(extensions,
- ASN1_Tag(1),
- ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED))
- .end_cons();
-
- m_cert_status = cert_status.type_tag;
- }
-
-}
-
-}
diff --git a/src/cert/ocsp/ocsp_types.h b/src/cert/ocsp/ocsp_types.h
deleted file mode 100644
index f693600ea..000000000
--- a/src/cert/ocsp/ocsp_types.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* OCSP subtypes
-* (C) 2012 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#ifndef BOTAN_OCSP_TYPES_H__
-#define BOTAN_OCSP_TYPES_H__
-
-#include <botan/x509cert.h>
-#include <botan/asn1_time.h>
-#include <botan/bigint.h>
-
-namespace Botan {
-
-namespace OCSP {
-
-class BOTAN_DLL CertID : public ASN1_Object
- {
- public:
- CertID() {}
-
- CertID(const X509_Certificate& issuer,
- const X509_Certificate& subject);
-
- bool is_id_for(const X509_Certificate& issuer,
- const X509_Certificate& subject) const;
-
- void encode_into(class DER_Encoder& to) const override;
-
- void decode_from(class BER_Decoder& from) override;
- private:
- std::vector<byte> extract_key_bitstr(const X509_Certificate& cert) const;
-
- AlgorithmIdentifier m_hash_id;
- std::vector<byte> m_issuer_dn_hash;
- std::vector<byte> m_issuer_key_hash;
- BigInt m_subject_serial;
- };
-
-class BOTAN_DLL SingleResponse : public ASN1_Object
- {
- public:
- const CertID& certid() const { return m_certid; }
-
- size_t cert_status() const { return m_cert_status; }
-
- X509_Time this_update() const { return m_thisupdate; }
-
- X509_Time next_update() const { return m_thisupdate; }
-
- void encode_into(class DER_Encoder& to) const override;
-
- void decode_from(class BER_Decoder& from) override;
- private:
- CertID m_certid;
- size_t m_cert_status = 2; // unknown
- X509_Time m_thisupdate;
- X509_Time m_nextupdate;
- };
-
-}
-
-}
-
-#endif