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