/* * OCSP * (C) 2012 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #ifndef BOTAN_OCSP_H_ #define BOTAN_OCSP_H_ #include #include #include #include namespace Botan { class Certificate_Store; namespace OCSP { /** * An OCSP request. */ class BOTAN_PUBLIC_API(2,0) Request final { public: /** * Create an OCSP request. * @param issuer_cert issuer certificate * @param subject_cert subject certificate */ 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 */ std::vector BER_encode() const; /** * @return Base64-encoded OCSP request */ std::string base64_encode() const; /** * @return issuer certificate */ const X509_Certificate& issuer() const { return m_issuer; } /** * @return subject certificate */ const X509_Certificate& subject() const { throw Not_Implemented("Method have been deprecated"); } const std::vector& issuer_key_hash() const { return m_certid.issuer_key_hash(); } private: X509_Certificate m_issuer; CertID m_certid; }; /** * OCSP response status. * * see https://tools.ietf.org/html/rfc6960#section-4.2.1 */ enum class Response_Status_Code { Successful = 0, Malformed_Request = 1, Internal_Error = 2, Try_Later = 3, Sig_Required = 5, Unauthorized = 6 }; /** * OCSP response. * * Note this class is only usable as an OCSP client */ class BOTAN_PUBLIC_API(2,0) Response final { public: /** * Creates an empty OCSP response. */ Response() = default; /** * Create a fake OCSP response from a given status code. * @param status the status code the check functions will return */ Response(Certificate_Status_Code status); /** * Parses an OCSP response. * @param response_bits response bits received */ Response(const std::vector& response_bits) : Response(response_bits.data(), response_bits.size()) {} /** * Parses an OCSP response. * @param response_bits response bits received * @param response_bits_len length of response in bytes */ Response(const uint8_t response_bits[], size_t response_bits_len); /** * Check signature and return status * The optional cert_path is the (already validated!) certificate path of * the end entity which is being inquired about * @param trust_roots list of certstores containing trusted roots * @param cert_path optionally, the (already verified!) certificate path for the certificate * this is an OCSP response for. This is necessary to find the correct intermediate CA in * some cases. */ Certificate_Status_Code check_signature(const std::vector& trust_roots, const std::vector>& cert_path = {}) const; /** * Verify that issuer's key signed this response * @param issuer certificate of issuer * @return if signature valid OCSP_SIGNATURE_OK else an error code */ Certificate_Status_Code verify_signature(const X509_Certificate& issuer) const; /** * @return the status of the response */ Response_Status_Code status() const { return m_status; } /** * @return the time this OCSP response was supposedly produced at */ const X509_Time& produced_at() const { return m_produced_at; } /** * @return DN of signer, if provided in response (may be empty) */ const X509_DN& signer_name() const { return m_signer_name; } /** * @return key hash, if provided in response (may be empty) */ const std::vector& signer_key_hash() const { return m_key_hash; } const std::vector& raw_bits() const { return m_response_bits; } /** * Searches the OCSP response for issuer and subject certificate. * @param issuer issuer certificate * @param subject subject certificate * @param ref_time the reference time * @param max_age the maximum age the response should be considered valid * if next_update is not set * @return OCSP status code, possible values: * CERT_IS_REVOKED, * OCSP_NOT_YET_VALID, * OCSP_HAS_EXPIRED, * OCSP_IS_TOO_OLD, * OCSP_RESPONSE_GOOD, * OCSP_BAD_STATUS, * OCSP_CERT_NOT_LISTED */ Certificate_Status_Code status_for(const X509_Certificate& issuer, const X509_Certificate& subject, std::chrono::system_clock::time_point ref_time = std::chrono::system_clock::now(), std::chrono::seconds max_age = std::chrono::seconds::zero()) const; /** * @return the certificate chain, if provided in response */ const std::vector &certificates() const { return m_certs; } private: Response_Status_Code m_status; std::vector m_response_bits; X509_Time m_produced_at; X509_DN m_signer_name; std::vector m_key_hash; std::vector m_tbs_bits; AlgorithmIdentifier m_sig_algo; std::vector m_signature; std::vector m_certs; std::vector m_responses; Certificate_Status_Code m_dummy_response_status; }; #if defined(BOTAN_HAS_HTTP_UTIL) /** * Makes an online OCSP request via HTTP and returns the OCSP response. * @param issuer issuer certificate * @param subject_serial the subject's serial number * @param ocsp_responder the OCSP responder to query * @param trusted_roots trusted roots for the OCSP response * @param timeout a timeout on the HTTP request * @return OCSP response */ BOTAN_PUBLIC_API(2,1) Response online_check(const X509_Certificate& issuer, const BigInt& subject_serial, const std::string& ocsp_responder, Certificate_Store* trusted_roots, std::chrono::milliseconds timeout = std::chrono::milliseconds(3000)); /** * Makes an online OCSP request via HTTP and returns the OCSP response. * @param issuer issuer certificate * @param subject subject certificate * @param trusted_roots trusted roots for the OCSP response * @param timeout a timeout on the HTTP request * @return OCSP response */ BOTAN_PUBLIC_API(2,0) Response online_check(const X509_Certificate& issuer, const X509_Certificate& subject, Certificate_Store* trusted_roots, std::chrono::milliseconds timeout = std::chrono::milliseconds(3000)); #endif } } #endif