summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_config_factory_impl.cc
blob: 58b3b365681d2ae8c904f6f6f65d063f4497f1a9 (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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright 2019 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.

#include "net/third_party/quic/core/crypto/proof_source.h"
#include "net/third_party/quic/core/crypto/proof_verifier.h"

#include "net/third_party/quic/core/tls_client_handshaker.h"
#include "net/third_party/quic/core/tls_server_handshaker.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_config_factory_impl.h"

namespace blink {

namespace {

// Length of HKDF input keying material, equal to its number of bytes.
// https://tools.ietf.org/html/rfc5869#section-2.2.
const size_t kInputKeyingMaterialLength = 32;

// TODO(https://crbug.com/874300): Implement a secure QUIC handshake, meaning
// that both side's certificates are verified. This can be done by creating a
// P2PProofSource and P2PProofVerifier, and removing these objects once the
// TLS 1.3 handshake is implemented for QUIC.
// - The self signed certificate fingerprint matches the remote
//   fingerprint that was signaled.
// - The peer owns the certificate, by verifying the signature of the hash of
//   the handshake context.
//
// Ignores the peer's credentials (taken from quic/quartc).
class InsecureProofVerifier : public quic::ProofVerifier {
 public:
  InsecureProofVerifier() {}
  ~InsecureProofVerifier() override {}

  // ProofVerifier override.
  quic::QuicAsyncStatus VerifyProof(
      const quic::QuicString& hostname,
      const uint16_t port,
      const quic::QuicString& server_config,
      quic::QuicTransportVersion transport_version,
      quic::QuicStringPiece chlo_hash,
      const std::vector<quic::QuicString>& certs,
      const quic::QuicString& cert_sct,
      const quic::QuicString& signature,
      const quic::ProofVerifyContext* context,
      quic::QuicString* error_details,
      std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
      std::unique_ptr<quic::ProofVerifierCallback> callback) override {
    return quic::QUIC_SUCCESS;
  }

  quic::QuicAsyncStatus VerifyCertChain(
      const quic::QuicString& hostname,
      const std::vector<quic::QuicString>& certs,
      const quic::ProofVerifyContext* context,
      quic::QuicString* error_details,
      std::unique_ptr<quic::ProofVerifyDetails>* details,
      std::unique_ptr<quic::ProofVerifierCallback> callback) override {
    return quic::QUIC_SUCCESS;
  }

  std::unique_ptr<quic::ProofVerifyContext> CreateDefaultContext() override {
    return nullptr;
  }
};

}  // namespace

// Used by QuicCryptoServerConfig to provide dummy proof credentials
// (taken from quic/quartc).
class DummyProofSource : public quic::ProofSource {
 public:
  DummyProofSource() {}
  ~DummyProofSource() override {}

  // ProofSource override.
  void GetProof(const quic::QuicSocketAddress& server_addr,
                const quic::QuicString& hostname,
                const quic::QuicString& server_config,
                quic::QuicTransportVersion transport_version,
                quic::QuicStringPiece chlo_hash,
                std::unique_ptr<Callback> callback) override {
    quic::QuicCryptoProof proof;
    proof.signature = "Dummy signature";
    proof.leaf_cert_scts = "Dummy timestamp";
    callback->Run(true, GetCertChain(server_addr, hostname), proof,
                  nullptr /* details */);
  }

  quic::QuicReferenceCountedPointer<Chain> GetCertChain(
      const quic::QuicSocketAddress& server_address,
      const quic::QuicString& hostname) override {
    std::vector<quic::QuicString> certs;
    certs.push_back("Dummy cert");
    return quic::QuicReferenceCountedPointer<Chain>(
        new quic::ProofSource::Chain(certs));
  }
  void ComputeTlsSignature(
      const quic::QuicSocketAddress& server_address,
      const quic::QuicString& hostname,
      uint16_t signature_algorithm,
      quic::QuicStringPiece in,
      std::unique_ptr<SignatureCallback> callback) override {
    callback->Run(true, "Dummy signature");
  }
};

P2PQuicCryptoConfigFactoryImpl::P2PQuicCryptoConfigFactoryImpl(
    quic::QuicRandom* const random_generator)
    : random_generator_(random_generator) {}

std::unique_ptr<quic::QuicCryptoClientConfig>
P2PQuicCryptoConfigFactoryImpl::CreateClientCryptoConfig() {
  std::unique_ptr<quic::ProofVerifier> proof_verifier(
      new InsecureProofVerifier);
  return std::make_unique<quic::QuicCryptoClientConfig>(
      std::move(proof_verifier), quic::TlsClientHandshaker::CreateSslCtx());
}

std::unique_ptr<quic::QuicCryptoServerConfig>
P2PQuicCryptoConfigFactoryImpl::CreateServerCryptoConfig() {
  // Generate a random source address token secret every time since this is
  // a transient client.
  char source_address_token_secret[kInputKeyingMaterialLength];
  random_generator_->RandBytes(source_address_token_secret,
                               kInputKeyingMaterialLength);
  std::unique_ptr<quic::ProofSource> proof_source(new DummyProofSource);
  return std::make_unique<quic::QuicCryptoServerConfig>(
      quic::QuicString(source_address_token_secret, kInputKeyingMaterialLength),
      random_generator_, std::move(proof_source),
      quic::KeyExchangeSource::Default(),
      quic::TlsServerHandshaker::CreateSslCtx());
}

}  // namespace blink