1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_ 6 #define QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_ 7 8 #include <cstdarg> 9 #include <cstddef> 10 #include <cstdint> 11 #include <utility> 12 #include <vector> 13 14 #include "absl/strings/string_view.h" 15 #include "openssl/evp.h" 16 #include "quiche/quic/core/crypto/crypto_framer.h" 17 #include "quiche/quic/core/crypto/quic_random.h" 18 #include "quiche/quic/core/quic_framer.h" 19 #include "quiche/quic/core/quic_packets.h" 20 #include "quiche/quic/test_tools/quic_test_utils.h" 21 22 namespace quic { 23 24 class ProofSource; 25 class ProofVerifier; 26 class ProofVerifyContext; 27 class QuicClock; 28 class QuicConfig; 29 class QuicCryptoClientStream; 30 class QuicCryptoServerConfig; 31 class QuicCryptoServerStreamBase; 32 class QuicCryptoStream; 33 class QuicServerId; 34 35 namespace test { 36 37 class PacketSavingConnection; 38 39 namespace crypto_test_utils { 40 41 // An interface for a source of callbacks. This is used for invoking 42 // callbacks asynchronously. 43 // 44 // Call the RunPendingCallbacks method regularly to run the callbacks from 45 // this source. 46 class CallbackSource { 47 public: ~CallbackSource()48 virtual ~CallbackSource() {} 49 50 // Runs pending callbacks from this source. If there is no pending 51 // callback, does nothing. 52 virtual void RunPendingCallbacks() = 0; 53 }; 54 55 // FakeClientOptions bundles together a number of options for configuring 56 // HandshakeWithFakeClient. 57 struct FakeClientOptions { 58 FakeClientOptions(); 59 ~FakeClientOptions(); 60 61 // If only_tls_versions is set, then the client will only use TLS for the 62 // crypto handshake. 63 bool only_tls_versions = false; 64 65 // If only_quic_crypto_versions is set, then the client will only use 66 // PROTOCOL_QUIC_CRYPTO for the crypto handshake. 67 bool only_quic_crypto_versions = false; 68 }; 69 70 // Returns a QuicCryptoServerConfig that is in a reasonable configuration to 71 // pass into HandshakeWithFakeServer. 72 std::unique_ptr<QuicCryptoServerConfig> CryptoServerConfigForTesting(); 73 74 // returns: the number of client hellos that the client sent. 75 int HandshakeWithFakeServer(QuicConfig* server_quic_config, 76 QuicCryptoServerConfig* crypto_config, 77 MockQuicConnectionHelper* helper, 78 MockAlarmFactory* alarm_factory, 79 PacketSavingConnection* client_conn, 80 QuicCryptoClientStreamBase* client, 81 std::string alpn); 82 83 // returns: the number of client hellos that the client sent. 84 int HandshakeWithFakeClient(MockQuicConnectionHelper* helper, 85 MockAlarmFactory* alarm_factory, 86 PacketSavingConnection* server_conn, 87 QuicCryptoServerStreamBase* server, 88 const QuicServerId& server_id, 89 const FakeClientOptions& options, std::string alpn); 90 91 // SetupCryptoServerConfigForTest configures |crypto_config| 92 // with sensible defaults for testing. 93 void SetupCryptoServerConfigForTest(const QuicClock* clock, QuicRandom* rand, 94 QuicCryptoServerConfig* crypto_config); 95 96 // Sends the handshake message |message| to stream |stream| with the perspective 97 // that the message is coming from |perspective|. 98 void SendHandshakeMessageToStream(QuicCryptoStream* stream, 99 const CryptoHandshakeMessage& message, 100 Perspective perspective); 101 102 // CommunicateHandshakeMessages moves messages from |client| to |server| and 103 // back until |clients|'s handshake has completed. 104 void CommunicateHandshakeMessages(PacketSavingConnection* client_conn, 105 QuicCryptoStream* client, 106 PacketSavingConnection* server_conn, 107 QuicCryptoStream* server); 108 109 // CommunicateHandshakeMessagesUntil: 110 // 1) Moves messages from |client| to |server| until |server_condition| is met. 111 // 2) Moves messages from |server| to |client| until |client_condition| is met. 112 // 3) For IETF QUIC, if `process_stream_data` is true, STREAM_FRAME within the 113 // packet containing crypto messages is also processed. 114 // 4) Returns true if both conditions are met. 115 // 5) Returns false if either connection is closed or there is no more packet to 116 // deliver before both conditions are met. 117 bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn, 118 QuicCryptoStream* client, 119 std::function<bool()> client_condition, 120 PacketSavingConnection* server_conn, 121 QuicCryptoStream* server, 122 std::function<bool()> server_condition, 123 bool process_stream_data); 124 125 // AdvanceHandshake attempts to moves messages from |client| to |server| and 126 // |server| to |client|. Returns the number of messages moved. 127 std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn, 128 QuicCryptoStream* client, 129 size_t client_i, 130 PacketSavingConnection* server_conn, 131 QuicCryptoStream* server, 132 size_t server_i); 133 134 // Returns the value for the tag |tag| in the tag value map of |message|. 135 std::string GetValueForTag(const CryptoHandshakeMessage& message, QuicTag tag); 136 137 // Returns a new |ProofSource| that serves up test certificates. 138 std::unique_ptr<ProofSource> ProofSourceForTesting(); 139 140 // Returns a new |ProofVerifier| that uses the QUIC testing root CA. 141 std::unique_ptr<ProofVerifier> ProofVerifierForTesting(); 142 143 // Returns the hostname used by the proof source and the proof verifier above. 144 std::string CertificateHostnameForTesting(); 145 146 // Returns a hash of the leaf test certificate. 147 uint64_t LeafCertHashForTesting(); 148 149 // Returns a |ProofVerifyContext| that must be used with the verifier 150 // returned by |ProofVerifierForTesting|. 151 std::unique_ptr<ProofVerifyContext> ProofVerifyContextForTesting(); 152 153 // Creates a minimal dummy reject message that will pass the client-config 154 // validation tests. This will include a server config, but no certs, proof 155 // source address token, or server nonce. 156 void FillInDummyReject(CryptoHandshakeMessage* rej); 157 158 // ParseTag returns a QuicTag from parsing |tagstr|. |tagstr| may either be 159 // in the format "EXMP" (i.e. ASCII format), or "#11223344" (an explicit hex 160 // format). It QUICHE_CHECK fails if there's a parse error. 161 QuicTag ParseTag(const char* tagstr); 162 163 // Message constructs a CHLO message from a provided vector of tag/value pairs. 164 // The first of each pair is the tag of a tag/value and is given as an argument 165 // to |ParseTag|. The second is the value of the tag/value pair and is either a 166 // hex dump, preceeded by a '#', or a raw value. If minimum_size_bytes is 167 // provided then the message will be padded to this minimum size. 168 // 169 // CreateCHLO( 170 // {{"NOCE", "#11223344"}, 171 // {"SNI", "www.example.com"}}, 172 // optional_minimum_size_bytes); 173 CryptoHandshakeMessage CreateCHLO( 174 std::vector<std::pair<std::string, std::string>> tags_and_values); 175 CryptoHandshakeMessage CreateCHLO( 176 std::vector<std::pair<std::string, std::string>> tags_and_values, 177 int minimum_size_bytes); 178 179 // MovePackets parses crypto handshake messages from packet number 180 // |*inout_packet_index| through to the last packet (or until a packet fails 181 // to decrypt) and has |dest_stream| process them. |*inout_packet_index| is 182 // updated with an index one greater than the last packet processed. For IETF 183 // QUIC, if `process_stream_data` is true, STREAM_FRAME within the packet 184 // containing crypto messages is also processed. 185 void MovePackets(PacketSavingConnection* source_conn, 186 size_t* inout_packet_index, QuicCryptoStream* dest_stream, 187 PacketSavingConnection* dest_conn, 188 Perspective dest_perspective, bool process_stream_data); 189 190 // Return an inchoate CHLO with some basic tag value pairs. 191 CryptoHandshakeMessage GenerateDefaultInchoateCHLO( 192 const QuicClock* clock, QuicTransportVersion version, 193 QuicCryptoServerConfig* crypto_config); 194 195 // Takes a inchoate CHLO, returns a full CHLO in |out| which can pass 196 // |crypto_config|'s validation. 197 void GenerateFullCHLO( 198 const CryptoHandshakeMessage& inchoate_chlo, 199 QuicCryptoServerConfig* crypto_config, QuicSocketAddress server_addr, 200 QuicSocketAddress client_addr, QuicTransportVersion transport_version, 201 const QuicClock* clock, 202 quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config, 203 QuicCompressedCertsCache* compressed_certs_cache, 204 CryptoHandshakeMessage* out); 205 206 void CompareClientAndServerKeys(QuicCryptoClientStreamBase* client, 207 QuicCryptoServerStreamBase* server); 208 209 // Return a CHLO nonce in hexadecimal. 210 std::string GenerateClientNonceHex(const QuicClock* clock, 211 QuicCryptoServerConfig* crypto_config); 212 213 // Return a CHLO PUBS in hexadecimal. 214 std::string GenerateClientPublicValuesHex(); 215 216 } // namespace crypto_test_utils 217 218 } // namespace test 219 220 } // namespace quic 221 222 #endif // QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_ 223