chromium/third_party/boringssl/src/pki/ocsp.cc

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ocsp.h"

#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/mem.h>
#include <openssl/pool.h>
#include <openssl/sha.h>
#include "cert_errors.h"
#include "extended_key_usage.h"
#include "parsed_certificate.h"
#include "revocation_util.h"
#include "string_util.h"
#include "verify_name_match.h"
#include "verify_signed_data.h"

BSSL_NAMESPACE_BEGIN

OCSPCertID::OCSPCertID() = default;
OCSPCertID::~OCSPCertID() = default;

OCSPSingleResponse::OCSPSingleResponse() = default;
OCSPSingleResponse::~OCSPSingleResponse() = default;

OCSPResponseData::OCSPResponseData() = default;
OCSPResponseData::~OCSPResponseData() = default;

OCSPResponse::OCSPResponse() = default;
OCSPResponse::~OCSPResponse() = default;

// CertID ::= SEQUENCE {
//    hashAlgorithm           AlgorithmIdentifier,
//    issuerNameHash          OCTET STRING, -- Hash of issuer's DN
//    issuerKeyHash           OCTET STRING, -- Hash of issuer's public key
//    serialNumber            CertificateSerialNumber
// }
bool ParseOCSPCertID(der::Input raw_tlv, OCSPCertID *out) {}

namespace {

// Parses |raw_tlv| to extract an OCSP RevokedInfo (RFC 6960) and stores the
// result in the OCSPCertStatus |out|. Returns whether the parsing was
// successful.
//
// RevokedInfo ::= SEQUENCE {
//      revocationTime              GeneralizedTime,
//      revocationReason    [0]     EXPLICIT CRLReason OPTIONAL
// }
bool ParseRevokedInfo(der::Input raw_tlv, OCSPCertStatus *out) {}

// Parses |raw_tlv| to extract an OCSP CertStatus (RFC 6960) and stores the
// result in the OCSPCertStatus |out|. Returns whether the parsing was
// successful.
//
// CertStatus ::= CHOICE {
//      good        [0]     IMPLICIT NULL,
//      revoked     [1]     IMPLICIT RevokedInfo,
//      unknown     [2]     IMPLICIT UnknownInfo
// }
//
// UnknownInfo ::= NULL
bool ParseCertStatus(der::Input raw_tlv, OCSPCertStatus *out) {}

// Writes the hash of |value| as an OCTET STRING to |cbb|, using |hash_type| as
// the algorithm. Returns true on success.
bool AppendHashAsOctetString(const EVP_MD *hash_type, CBB *cbb,
                             der::Input value) {}

}  // namespace

// SingleResponse ::= SEQUENCE {
//      certID                       CertID,
//      certStatus                   CertStatus,
//      thisUpdate                   GeneralizedTime,
//      nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
//      singleExtensions   [1]       EXPLICIT Extensions OPTIONAL
// }
bool ParseOCSPSingleResponse(der::Input raw_tlv, OCSPSingleResponse *out) {}

namespace {

// Parses |raw_tlv| to extract a ResponderID (RFC 6960) and stores the
// result in the ResponderID |out|. Returns whether the parsing was successful.
//
// ResponderID ::= CHOICE {
//      byName               [1] Name,
//      byKey                [2] KeyHash
// }
bool ParseResponderID(der::Input raw_tlv, OCSPResponseData::ResponderID *out) {}

}  // namespace

// ResponseData ::= SEQUENCE {
//      version              [0] EXPLICIT Version DEFAULT v1,
//      responderID              ResponderID,
//      producedAt               GeneralizedTime,
//      responses                SEQUENCE OF SingleResponse,
//      responseExtensions   [1] EXPLICIT Extensions OPTIONAL
// }
bool ParseOCSPResponseData(der::Input raw_tlv, OCSPResponseData *out) {}

namespace {

// Parses |raw_tlv| to extract a BasicOCSPResponse (RFC 6960) and stores the
// result in the OCSPResponse |out|. Returns whether the parsing was
// successful.
//
// BasicOCSPResponse       ::= SEQUENCE {
//      tbsResponseData      ResponseData,
//      signatureAlgorithm   AlgorithmIdentifier,
//      signature            BIT STRING,
//      certs            [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
// }
bool ParseBasicOCSPResponse(der::Input raw_tlv, OCSPResponse *out) {}

}  // namespace

// OCSPResponse ::= SEQUENCE {
//      responseStatus         OCSPResponseStatus,
//      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL
// }
//
// ResponseBytes ::=       SEQUENCE {
//      responseType   OBJECT IDENTIFIER,
//      response       OCTET STRING
// }
bool ParseOCSPResponse(der::Input raw_tlv, OCSPResponse *out) {}

namespace {

// Checks that the |type| hash of |value| is equal to |hash|
bool VerifyHash(const EVP_MD *type, der::Input hash, der::Input value) {}

// Extracts the bytes of the SubjectPublicKey bit string given an SPKI. That is
// to say, the value of subjectPublicKey without the leading unused bit
// count octet.
//
// Returns true on success and fills |*spk_tlv| with the result.
//
// From RFC 5280, Section 4.1
//   SubjectPublicKeyInfo  ::=  SEQUENCE  {
//     algorithm            AlgorithmIdentifier,
//     subjectPublicKey     BIT STRING  }
//
//   AlgorithmIdentifier  ::=  SEQUENCE  {
//     algorithm               OBJECT IDENTIFIER,
//     parameters              ANY DEFINED BY algorithm OPTIONAL  }
//
bool GetSubjectPublicKeyBytes(der::Input spki_tlv, der::Input *spk_tlv) {}

// Checks the OCSPCertID |id| identifies |certificate|.
bool CheckCertIDMatchesCertificate(
    const OCSPCertID &id, const ParsedCertificate *certificate,
    const ParsedCertificate *issuer_certificate) {}

// TODO(eroman): Revisit how certificate parsing is used by this file. Ideally
// would either pass in the parsed bits, or have a better abstraction for lazily
// parsing.
std::shared_ptr<const ParsedCertificate> OCSPParseCertificate(
    std::string_view der) {}

// Checks that the ResponderID |id| matches the certificate |cert| either
// by verifying the name matches that of the certificate or that the hash
// matches the certificate's public key hash (RFC 6960, 4.2.2.3).
[[nodiscard]] bool CheckResponderIDMatchesCertificate(
    const OCSPResponseData::ResponderID &id, const ParsedCertificate *cert) {}

// Verifies that |responder_certificate| has been authority for OCSP signing,
// delegated to it by |issuer_certificate|.
//
// TODO(eroman): No revocation checks are done (see id-pkix-ocsp-nocheck in the
//     spec). extension).
//
// TODO(eroman): Not all properties of the certificate are verified, only the
//     signature and EKU. Can full RFC 5280 validation be used, or are there
//     compatibility concerns?
[[nodiscard]] bool VerifyAuthorizedResponderCert(
    const ParsedCertificate *responder_certificate,
    const ParsedCertificate *issuer_certificate) {}

[[nodiscard]] bool VerifyOCSPResponseSignatureGivenCert(
    const OCSPResponse &response, const ParsedCertificate *cert) {}

// Verifies that the OCSP response has a valid signature using
// |issuer_certificate|, or an authorized responder issued by
// |issuer_certificate| for OCSP signing.
[[nodiscard]] bool VerifyOCSPResponseSignature(
    const OCSPResponse &response, const OCSPResponseData &response_data,
    const ParsedCertificate *issuer_certificate) {}

// Parse ResponseData and return false if any unhandled critical extensions are
// found. No known critical ResponseData extensions exist.
bool ParseOCSPResponseDataExtensions(
    der::Input response_extensions,
    OCSPVerifyResult::ResponseStatus *response_details) {}

// Parse SingleResponse and return false if any unhandled critical extensions
// (other than the CT extension) are found. The CT-SCT extension is not required
// to be marked critical, but since it is handled by Chrome, we will overlook
// the flag setting.
bool ParseOCSPSingleResponseExtensions(
    der::Input single_extensions,
    OCSPVerifyResult::ResponseStatus *response_details) {}

// Loops through the OCSPSingleResponses to find the best match for |cert|.
OCSPRevocationStatus GetRevocationStatusForCert(
    const OCSPResponseData &response_data, const ParsedCertificate *cert,
    const ParsedCertificate *issuer_certificate,
    int64_t verify_time_epoch_seconds, std::optional<int64_t> max_age_seconds,
    OCSPVerifyResult::ResponseStatus *response_details) {}

OCSPRevocationStatus CheckOCSP(
    std::string_view raw_response, std::string_view certificate_der,
    const ParsedCertificate *certificate,
    std::string_view issuer_certificate_der,
    const ParsedCertificate *issuer_certificate,
    int64_t verify_time_epoch_seconds, std::optional<int64_t> max_age_seconds,
    OCSPVerifyResult::ResponseStatus *response_details) {}

}  // namespace

OCSPRevocationStatus CheckOCSP(
    std::string_view raw_response, std::string_view certificate_der,
    std::string_view issuer_certificate_der, int64_t verify_time_epoch_seconds,
    std::optional<int64_t> max_age_seconds,
    OCSPVerifyResult::ResponseStatus *response_details) {}

OCSPRevocationStatus CheckOCSP(
    std::string_view raw_response, const ParsedCertificate *certificate,
    const ParsedCertificate *issuer_certificate,
    int64_t verify_time_epoch_seconds, std::optional<int64_t> max_age_seconds,
    OCSPVerifyResult::ResponseStatus *response_details) {}

bool CreateOCSPRequest(const ParsedCertificate *cert,
                       const ParsedCertificate *issuer,
                       std::vector<uint8_t> *request_der) {}

// From RFC 2560 section A.1.1:
//
//    An OCSP request using the GET method is constructed as follows:
//
//    GET {url}/{url-encoding of base-64 encoding of the DER encoding of
//    the OCSPRequest}
std::optional<std::string> CreateOCSPGetURL(
    const ParsedCertificate *cert, const ParsedCertificate *issuer,
    std::string_view ocsp_responder_url) {}

BSSL_NAMESPACE_END