summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h
blob: f597565051a315d0d7edaa872f2f3b338c128181 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// 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_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
#define QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_

#include <vector>

#include "absl/strings/string_view.h"
#include "quic/core/crypto/certificate_view.h"
#include "quic/core/crypto/proof_verifier.h"
#include "quic/core/quic_clock.h"

namespace quic {

// Represents a fingerprint of an X.509 certificate in a format based on
// https://w3c.github.io/webrtc-pc/#dom-rtcdtlsfingerprint.
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;
};

// Computes a SHA-256 fingerprint of the specified input formatted in the same
// format as CertificateFingerprint::fingerprint would contain.
QUIC_EXPORT_PRIVATE std::string ComputeSha256Fingerprint(
    absl::string_view input);

// 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,

    kMaxValue = kInternalError,
  };

  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);

  // 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;

 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<CertificateFingerprint> fingerprints_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_