blob: ea1908d27c558b586b5fdceeec14766757b33aa6 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef QUICHE_QUIC_CORE_CRYPTO_WEB_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
#define QUICHE_QUIC_CORE_CRYPTO_WEB_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
#include <vector>
#include "absl/strings/string_view.h"
#include "quiche/quic/core/crypto/certificate_view.h"
#include "quiche/quic/core/crypto/proof_verifier.h"
#include "quiche/quic/core/quic_clock.h"
#include "quiche/quic/platform/api/quic_export.h"
namespace quic {
// Represents a fingerprint of an X.509 certificate in a format based on
// https://w3c.github.io/webrtc-pc/#dom-rtcdtlsfingerprint.
// TODO(vasilvv): remove this once all consumers of this API use
// WebTransportHash.
struct QUIC_EXPORT_PRIVATE CertificateFingerprint {
static constexpr char kSha256[] = "sha-256";
// An algorithm described by one of the names in
// https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
std::string algorithm;
// Hex-encoded, colon-separated fingerprint of the certificate. For example,
// "12:3d:5b:71:8c:54:df:85:7e:bd:e3:7c:66:da:f9:db:6a:94:8f:85:cb:6e:44:7f:09:3e:05:f2:dd:d4:f7:86"
std::string fingerprint;
};
// Represents a fingerprint of an X.509 certificate in a format based on
// https://w3c.github.io/webtransport/#dictdef-webtransporthash.
struct QUIC_EXPORT_PRIVATE WebTransportHash {
static constexpr char kSha256[] = "sha-256";
// An algorithm described by one of the names in
// https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
std::string algorithm;
// Raw bytes of the hash.
std::string value;
};
// WebTransportFingerprintProofVerifier verifies the server leaf certificate
// against a supplied list of certificate fingerprints following the procedure
// described in the WebTransport specification. The certificate is deemed
// trusted if it matches a fingerprint in the list, has expiry dates that are
// not too long and has not expired. Only the leaf is checked, the rest of the
// chain is ignored. Reference specification:
// https://wicg.github.io/web-transport/#dom-quictransportconfiguration-server_certificate_fingerprints
class QUIC_EXPORT_PRIVATE WebTransportFingerprintProofVerifier
: public ProofVerifier {
public:
// Note: the entries in this list may be logged into a UMA histogram, and thus
// should not be renumbered.
enum class Status {
kValidCertificate = 0,
kUnknownFingerprint = 1,
kCertificateParseFailure = 2,
kExpiryTooLong = 3,
kExpired = 4,
kInternalError = 5,
kDisallowedKeyAlgorithm = 6,
kMaxValue = kDisallowedKeyAlgorithm,
};
class QUIC_EXPORT_PRIVATE Details : public ProofVerifyDetails {
public:
explicit Details(Status status) : status_(status) {}
Status status() const { return status_; }
ProofVerifyDetails* Clone() const override;
private:
const Status status_;
};
// |clock| is used to check if the certificate has expired. It is not owned
// and must outlive the object. |max_validity_days| is the maximum time for
// which the certificate is allowed to be valid.
WebTransportFingerprintProofVerifier(const QuicClock* clock,
int max_validity_days);
// Adds a certificate fingerprint to be trusted. The fingerprints are
// case-insensitive and are validated internally; the function returns true if
// the validation passes.
bool AddFingerprint(CertificateFingerprint fingerprint);
bool AddFingerprint(WebTransportHash hash);
// ProofVerifier implementation.
QuicAsyncStatus VerifyProof(
const std::string& hostname, const uint16_t port,
const std::string& server_config, QuicTransportVersion transport_version,
absl::string_view chlo_hash, const std::vector<std::string>& certs,
const std::string& cert_sct, const std::string& signature,
const ProofVerifyContext* context, std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* details,
std::unique_ptr<ProofVerifierCallback> callback) override;
QuicAsyncStatus VerifyCertChain(
const std::string& hostname, const uint16_t port,
const std::vector<std::string>& certs, const std::string& ocsp_response,
const std::string& cert_sct, const ProofVerifyContext* context,
std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details,
uint8_t* out_alert,
std::unique_ptr<ProofVerifierCallback> callback) override;
std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override;
protected:
virtual bool IsKeyTypeAllowedByPolicy(const CertificateView& certificate);
private:
bool HasKnownFingerprint(absl::string_view der_certificate);
bool HasValidExpiry(const CertificateView& certificate);
bool IsWithinValidityPeriod(const CertificateView& certificate);
const QuicClock* clock_; // Unowned.
const int max_validity_days_;
const QuicTime::Delta max_validity_;
std::vector<WebTransportHash> hashes_;
};
} // namespace quic
#endif // QUICHE_QUIC_CORE_CRYPTO_WEB_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_