Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / net / quic / test_tools / crypto_test_utils.cc
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 #include "net/quic/test_tools/crypto_test_utils.h"
6
7 #include "net/quic/crypto/channel_id.h"
8 #include "net/quic/crypto/common_cert_set.h"
9 #include "net/quic/crypto/crypto_handshake.h"
10 #include "net/quic/crypto/quic_crypto_server_config.h"
11 #include "net/quic/crypto/quic_decrypter.h"
12 #include "net/quic/crypto/quic_encrypter.h"
13 #include "net/quic/crypto/quic_random.h"
14 #include "net/quic/quic_clock.h"
15 #include "net/quic/quic_crypto_client_stream.h"
16 #include "net/quic/quic_crypto_server_stream.h"
17 #include "net/quic/quic_crypto_stream.h"
18 #include "net/quic/quic_server_id.h"
19 #include "net/quic/test_tools/quic_connection_peer.h"
20 #include "net/quic/test_tools/quic_test_utils.h"
21 #include "net/quic/test_tools/simple_quic_framer.h"
22
23 using base::StringPiece;
24 using std::make_pair;
25 using std::pair;
26 using std::string;
27 using std::vector;
28
29 namespace net {
30 namespace test {
31
32 namespace {
33
34 const char kServerHostname[] = "test.example.com";
35 const uint16 kServerPort = 80;
36
37 // CryptoFramerVisitor is a framer visitor that records handshake messages.
38 class CryptoFramerVisitor : public CryptoFramerVisitorInterface {
39  public:
40   CryptoFramerVisitor()
41       : error_(false) {
42   }
43
44   virtual void OnError(CryptoFramer* framer) OVERRIDE { error_ = true; }
45
46   virtual void OnHandshakeMessage(
47       const CryptoHandshakeMessage& message) OVERRIDE {
48     messages_.push_back(message);
49   }
50
51   bool error() const {
52     return error_;
53   }
54
55   const vector<CryptoHandshakeMessage>& messages() const {
56     return messages_;
57   }
58
59  private:
60   bool error_;
61   vector<CryptoHandshakeMessage> messages_;
62 };
63
64 // MovePackets parses crypto handshake messages from packet number
65 // |*inout_packet_index| through to the last packet (or until a packet fails to
66 // decrypt) and has |dest_stream| process them. |*inout_packet_index| is updated
67 // with an index one greater than the last packet processed.
68 void MovePackets(PacketSavingConnection* source_conn,
69                  size_t *inout_packet_index,
70                  QuicCryptoStream* dest_stream,
71                  PacketSavingConnection* dest_conn) {
72   SimpleQuicFramer framer(source_conn->supported_versions());
73   CryptoFramer crypto_framer;
74   CryptoFramerVisitor crypto_visitor;
75
76   // In order to properly test the code we need to perform encryption and
77   // decryption so that the crypters latch when expected. The crypters are in
78   // |dest_conn|, but we don't want to try and use them there. Instead we swap
79   // them into |framer|, perform the decryption with them, and then swap them
80   // back.
81   QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
82
83   crypto_framer.set_visitor(&crypto_visitor);
84
85   size_t index = *inout_packet_index;
86   for (; index < source_conn->encrypted_packets_.size(); index++) {
87     if (!framer.ProcessPacket(*source_conn->encrypted_packets_[index])) {
88       // The framer will be unable to decrypt forward-secure packets sent after
89       // the handshake is complete. Don't treat them as handshake packets.
90       break;
91     }
92
93     for (vector<QuicStreamFrame>::const_iterator
94          i =  framer.stream_frames().begin();
95          i != framer.stream_frames().end(); ++i) {
96       scoped_ptr<string> frame_data(i->GetDataAsString());
97       ASSERT_TRUE(crypto_framer.ProcessInput(*frame_data));
98       ASSERT_FALSE(crypto_visitor.error());
99     }
100   }
101   *inout_packet_index = index;
102
103   QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
104
105   ASSERT_EQ(0u, crypto_framer.InputBytesRemaining());
106
107   for (vector<CryptoHandshakeMessage>::const_iterator
108        i = crypto_visitor.messages().begin();
109        i != crypto_visitor.messages().end(); ++i) {
110     dest_stream->OnHandshakeMessage(*i);
111   }
112 }
113
114 // HexChar parses |c| as a hex character. If valid, it sets |*value| to the
115 // value of the hex character and returns true. Otherwise it returns false.
116 bool HexChar(char c, uint8* value) {
117   if (c >= '0' && c <= '9') {
118     *value = c - '0';
119     return true;
120   }
121   if (c >= 'a' && c <= 'f') {
122     *value = c - 'a' + 10;
123     return true;
124   }
125   if (c >= 'A' && c <= 'F') {
126     *value = c - 'A' + 10;
127     return true;
128   }
129   return false;
130 }
131
132 // A ChannelIDSource that works in asynchronous mode unless the |callback|
133 // argument to GetChannelIDKey is NULL.
134 class AsyncTestChannelIDSource : public ChannelIDSource,
135                                  public CryptoTestUtils::CallbackSource {
136  public:
137   // Takes ownership of |sync_source|, a synchronous ChannelIDSource.
138   explicit AsyncTestChannelIDSource(ChannelIDSource* sync_source)
139       : sync_source_(sync_source) {}
140   virtual ~AsyncTestChannelIDSource() {}
141
142   // ChannelIDSource implementation.
143   virtual QuicAsyncStatus GetChannelIDKey(
144       const string& hostname,
145       scoped_ptr<ChannelIDKey>* channel_id_key,
146       ChannelIDSourceCallback* callback) OVERRIDE {
147     // Synchronous mode.
148     if (!callback) {
149       return sync_source_->GetChannelIDKey(hostname, channel_id_key, NULL);
150     }
151
152     // Asynchronous mode.
153     QuicAsyncStatus status =
154         sync_source_->GetChannelIDKey(hostname, &channel_id_key_, NULL);
155     if (status != QUIC_SUCCESS) {
156       return QUIC_FAILURE;
157     }
158     callback_.reset(callback);
159     return QUIC_PENDING;
160   }
161
162   // CallbackSource implementation.
163   virtual void RunPendingCallbacks() OVERRIDE {
164     if (callback_.get()) {
165       callback_->Run(&channel_id_key_);
166       callback_.reset();
167     }
168   }
169
170  private:
171   scoped_ptr<ChannelIDSource> sync_source_;
172   scoped_ptr<ChannelIDSourceCallback> callback_;
173   scoped_ptr<ChannelIDKey> channel_id_key_;
174 };
175
176 }  // anonymous namespace
177
178 CryptoTestUtils::FakeClientOptions::FakeClientOptions()
179     : dont_verify_certs(false),
180       channel_id_enabled(false),
181       channel_id_source_async(false) {
182 }
183
184 // static
185 int CryptoTestUtils::HandshakeWithFakeServer(
186     PacketSavingConnection* client_conn,
187     QuicCryptoClientStream* client) {
188   PacketSavingConnection* server_conn =
189       new PacketSavingConnection(true, client_conn->supported_versions());
190   TestSession server_session(server_conn, DefaultQuicConfig());
191   server_session.InitializeSession();
192   QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING,
193                                        QuicRandom::GetInstance());
194
195   SetupCryptoServerConfigForTest(
196       server_session.connection()->clock(),
197       server_session.connection()->random_generator(),
198       server_session.config(), &crypto_config);
199
200   QuicCryptoServerStream server(crypto_config, &server_session);
201   server_session.SetCryptoStream(&server);
202
203   // The client's handshake must have been started already.
204   CHECK_NE(0u, client_conn->packets_.size());
205
206   CommunicateHandshakeMessages(client_conn, client, server_conn, &server);
207
208   CompareClientAndServerKeys(client, &server);
209
210   return client->num_sent_client_hellos();
211 }
212
213 // static
214 int CryptoTestUtils::HandshakeWithFakeClient(
215     PacketSavingConnection* server_conn,
216     QuicCryptoServerStream* server,
217     const FakeClientOptions& options) {
218   PacketSavingConnection* client_conn = new PacketSavingConnection(false);
219   TestClientSession client_session(client_conn, DefaultQuicConfig());
220   QuicCryptoClientConfig crypto_config;
221
222   client_session.config()->SetDefaults();
223   crypto_config.SetDefaults();
224   if (!options.dont_verify_certs) {
225     // TODO(wtc): replace this with ProofVerifierForTesting() when we have
226     // a working ProofSourceForTesting().
227     crypto_config.SetProofVerifier(FakeProofVerifierForTesting());
228   }
229   bool is_https = false;
230   AsyncTestChannelIDSource* async_channel_id_source = NULL;
231   if (options.channel_id_enabled) {
232     is_https = true;
233
234     ChannelIDSource* source = ChannelIDSourceForTesting();
235     if (options.channel_id_source_async) {
236       async_channel_id_source = new AsyncTestChannelIDSource(source);
237       source = async_channel_id_source;
238     }
239     crypto_config.SetChannelIDSource(source);
240   }
241   QuicServerId server_id(kServerHostname, kServerPort, is_https,
242                          PRIVACY_MODE_DISABLED);
243   QuicCryptoClientStream client(server_id, &client_session,
244                                 ProofVerifyContextForTesting(),
245                                 &crypto_config);
246   client_session.SetCryptoStream(&client);
247
248   CHECK(client.CryptoConnect());
249   CHECK_EQ(1u, client_conn->packets_.size());
250
251   CommunicateHandshakeMessagesAndRunCallbacks(
252       client_conn, &client, server_conn, server, async_channel_id_source);
253
254   CompareClientAndServerKeys(&client, server);
255
256   if (options.channel_id_enabled) {
257     scoped_ptr<ChannelIDKey> channel_id_key;
258     QuicAsyncStatus status =
259         crypto_config.channel_id_source()->GetChannelIDKey(kServerHostname,
260                                                            &channel_id_key,
261                                                            NULL);
262     EXPECT_EQ(QUIC_SUCCESS, status);
263     EXPECT_EQ(channel_id_key->SerializeKey(),
264               server->crypto_negotiated_params().channel_id);
265     EXPECT_EQ(options.channel_id_source_async,
266               client.WasChannelIDSourceCallbackRun());
267   }
268
269   return client.num_sent_client_hellos();
270 }
271
272 // static
273 void CryptoTestUtils::SetupCryptoServerConfigForTest(
274     const QuicClock* clock,
275     QuicRandom* rand,
276     QuicConfig* config,
277     QuicCryptoServerConfig* crypto_config) {
278   config->SetDefaults();
279   QuicCryptoServerConfig::ConfigOptions options;
280   options.channel_id_enabled = true;
281   scoped_ptr<CryptoHandshakeMessage> scfg(
282       crypto_config->AddDefaultConfig(rand, clock, options));
283 }
284
285 // static
286 void CryptoTestUtils::CommunicateHandshakeMessages(
287     PacketSavingConnection* a_conn,
288     QuicCryptoStream* a,
289     PacketSavingConnection* b_conn,
290     QuicCryptoStream* b) {
291   CommunicateHandshakeMessagesAndRunCallbacks(a_conn, a, b_conn, b, NULL);
292 }
293
294 // static
295 void CryptoTestUtils::CommunicateHandshakeMessagesAndRunCallbacks(
296     PacketSavingConnection* a_conn,
297     QuicCryptoStream* a,
298     PacketSavingConnection* b_conn,
299     QuicCryptoStream* b,
300     CallbackSource* callback_source) {
301   size_t a_i = 0, b_i = 0;
302   while (!a->handshake_confirmed()) {
303     ASSERT_GT(a_conn->packets_.size(), a_i);
304     LOG(INFO) << "Processing " << a_conn->packets_.size() - a_i
305               << " packets a->b";
306     MovePackets(a_conn, &a_i, b, b_conn);
307     if (callback_source) {
308       callback_source->RunPendingCallbacks();
309     }
310
311     ASSERT_GT(b_conn->packets_.size(), b_i);
312     LOG(INFO) << "Processing " << b_conn->packets_.size() - b_i
313               << " packets b->a";
314     MovePackets(b_conn, &b_i, a, a_conn);
315     if (callback_source) {
316       callback_source->RunPendingCallbacks();
317     }
318   }
319 }
320
321 // static
322 pair<size_t, size_t> CryptoTestUtils::AdvanceHandshake(
323     PacketSavingConnection* a_conn,
324     QuicCryptoStream* a,
325     size_t a_i,
326     PacketSavingConnection* b_conn,
327     QuicCryptoStream* b,
328     size_t b_i) {
329   LOG(INFO) << "Processing " << a_conn->packets_.size() - a_i
330             << " packets a->b";
331   MovePackets(a_conn, &a_i, b, b_conn);
332
333   LOG(INFO) << "Processing " << b_conn->packets_.size() - b_i
334             << " packets b->a";
335   if (b_conn->packets_.size() - b_i == 2) {
336     LOG(INFO) << "here";
337   }
338   MovePackets(b_conn, &b_i, a, a_conn);
339
340   return make_pair(a_i, b_i);
341 }
342
343 // static
344 string CryptoTestUtils::GetValueForTag(const CryptoHandshakeMessage& message,
345                                        QuicTag tag) {
346   QuicTagValueMap::const_iterator it = message.tag_value_map().find(tag);
347   if (it == message.tag_value_map().end()) {
348     return string();
349   }
350   return it->second;
351 }
352
353 class MockCommonCertSets : public CommonCertSets {
354  public:
355   MockCommonCertSets(StringPiece cert, uint64 hash, uint32 index)
356       : cert_(cert.as_string()),
357         hash_(hash),
358         index_(index) {
359   }
360
361   virtual StringPiece GetCommonHashes() const OVERRIDE {
362     CHECK(false) << "not implemented";
363     return StringPiece();
364   }
365
366   virtual StringPiece GetCert(uint64 hash, uint32 index) const OVERRIDE {
367     if (hash == hash_ && index == index_) {
368       return cert_;
369     }
370     return StringPiece();
371   }
372
373   virtual bool MatchCert(StringPiece cert,
374                          StringPiece common_set_hashes,
375                          uint64* out_hash,
376                          uint32* out_index) const OVERRIDE {
377     if (cert != cert_) {
378       return false;
379     }
380
381     if (common_set_hashes.size() % sizeof(uint64) != 0) {
382       return false;
383     }
384     bool client_has_set = false;
385     for (size_t i = 0; i < common_set_hashes.size(); i += sizeof(uint64)) {
386       uint64 hash;
387       memcpy(&hash, common_set_hashes.data() + i, sizeof(hash));
388       if (hash == hash_) {
389         client_has_set = true;
390         break;
391       }
392     }
393
394     if (!client_has_set) {
395       return false;
396     }
397
398     *out_hash = hash_;
399     *out_index = index_;
400     return true;
401   }
402
403  private:
404   const string cert_;
405   const uint64 hash_;
406   const uint32 index_;
407 };
408
409 CommonCertSets* CryptoTestUtils::MockCommonCertSets(StringPiece cert,
410                                                     uint64 hash,
411                                                     uint32 index) {
412   return new class MockCommonCertSets(cert, hash, index);
413 }
414
415 void CryptoTestUtils::CompareClientAndServerKeys(
416     QuicCryptoClientStream* client,
417     QuicCryptoServerStream* server) {
418   const QuicEncrypter* client_encrypter(
419       client->session()->connection()->encrypter(ENCRYPTION_INITIAL));
420   const QuicDecrypter* client_decrypter(
421       client->session()->connection()->decrypter());
422   const QuicEncrypter* client_forward_secure_encrypter(
423       client->session()->connection()->encrypter(ENCRYPTION_FORWARD_SECURE));
424   const QuicDecrypter* client_forward_secure_decrypter(
425       client->session()->connection()->alternative_decrypter());
426   const QuicEncrypter* server_encrypter(
427       server->session()->connection()->encrypter(ENCRYPTION_INITIAL));
428   const QuicDecrypter* server_decrypter(
429       server->session()->connection()->decrypter());
430   const QuicEncrypter* server_forward_secure_encrypter(
431       server->session()->connection()->encrypter(ENCRYPTION_FORWARD_SECURE));
432   const QuicDecrypter* server_forward_secure_decrypter(
433       server->session()->connection()->alternative_decrypter());
434
435   StringPiece client_encrypter_key = client_encrypter->GetKey();
436   StringPiece client_encrypter_iv = client_encrypter->GetNoncePrefix();
437   StringPiece client_decrypter_key = client_decrypter->GetKey();
438   StringPiece client_decrypter_iv = client_decrypter->GetNoncePrefix();
439   StringPiece client_forward_secure_encrypter_key =
440       client_forward_secure_encrypter->GetKey();
441   StringPiece client_forward_secure_encrypter_iv =
442       client_forward_secure_encrypter->GetNoncePrefix();
443   StringPiece client_forward_secure_decrypter_key =
444       client_forward_secure_decrypter->GetKey();
445   StringPiece client_forward_secure_decrypter_iv =
446       client_forward_secure_decrypter->GetNoncePrefix();
447   StringPiece server_encrypter_key = server_encrypter->GetKey();
448   StringPiece server_encrypter_iv = server_encrypter->GetNoncePrefix();
449   StringPiece server_decrypter_key = server_decrypter->GetKey();
450   StringPiece server_decrypter_iv = server_decrypter->GetNoncePrefix();
451   StringPiece server_forward_secure_encrypter_key =
452       server_forward_secure_encrypter->GetKey();
453   StringPiece server_forward_secure_encrypter_iv =
454       server_forward_secure_encrypter->GetNoncePrefix();
455   StringPiece server_forward_secure_decrypter_key =
456       server_forward_secure_decrypter->GetKey();
457   StringPiece server_forward_secure_decrypter_iv =
458       server_forward_secure_decrypter->GetNoncePrefix();
459
460   StringPiece client_subkey_secret =
461       client->crypto_negotiated_params().subkey_secret;
462   StringPiece server_subkey_secret =
463       server->crypto_negotiated_params().subkey_secret;
464
465
466   const char kSampleLabel[] = "label";
467   const char kSampleContext[] = "context";
468   const size_t kSampleOutputLength = 32;
469   string client_key_extraction;
470   string server_key_extraction;
471   EXPECT_TRUE(client->ExportKeyingMaterial(kSampleLabel,
472                                            kSampleContext,
473                                            kSampleOutputLength,
474                                            &client_key_extraction));
475   EXPECT_TRUE(server->ExportKeyingMaterial(kSampleLabel,
476                                            kSampleContext,
477                                            kSampleOutputLength,
478                                            &server_key_extraction));
479
480   CompareCharArraysWithHexError("client write key",
481                                 client_encrypter_key.data(),
482                                 client_encrypter_key.length(),
483                                 server_decrypter_key.data(),
484                                 server_decrypter_key.length());
485   CompareCharArraysWithHexError("client write IV",
486                                 client_encrypter_iv.data(),
487                                 client_encrypter_iv.length(),
488                                 server_decrypter_iv.data(),
489                                 server_decrypter_iv.length());
490   CompareCharArraysWithHexError("server write key",
491                                 server_encrypter_key.data(),
492                                 server_encrypter_key.length(),
493                                 client_decrypter_key.data(),
494                                 client_decrypter_key.length());
495   CompareCharArraysWithHexError("server write IV",
496                                 server_encrypter_iv.data(),
497                                 server_encrypter_iv.length(),
498                                 client_decrypter_iv.data(),
499                                 client_decrypter_iv.length());
500   CompareCharArraysWithHexError("client forward secure write key",
501                                 client_forward_secure_encrypter_key.data(),
502                                 client_forward_secure_encrypter_key.length(),
503                                 server_forward_secure_decrypter_key.data(),
504                                 server_forward_secure_decrypter_key.length());
505   CompareCharArraysWithHexError("client forward secure write IV",
506                                 client_forward_secure_encrypter_iv.data(),
507                                 client_forward_secure_encrypter_iv.length(),
508                                 server_forward_secure_decrypter_iv.data(),
509                                 server_forward_secure_decrypter_iv.length());
510   CompareCharArraysWithHexError("server forward secure write key",
511                                 server_forward_secure_encrypter_key.data(),
512                                 server_forward_secure_encrypter_key.length(),
513                                 client_forward_secure_decrypter_key.data(),
514                                 client_forward_secure_decrypter_key.length());
515   CompareCharArraysWithHexError("server forward secure write IV",
516                                 server_forward_secure_encrypter_iv.data(),
517                                 server_forward_secure_encrypter_iv.length(),
518                                 client_forward_secure_decrypter_iv.data(),
519                                 client_forward_secure_decrypter_iv.length());
520   CompareCharArraysWithHexError("subkey secret",
521                                 client_subkey_secret.data(),
522                                 client_subkey_secret.length(),
523                                 server_subkey_secret.data(),
524                                 server_subkey_secret.length());
525   CompareCharArraysWithHexError("sample key extraction",
526                                 client_key_extraction.data(),
527                                 client_key_extraction.length(),
528                                 server_key_extraction.data(),
529                                 server_key_extraction.length());
530 }
531
532 // static
533 QuicTag CryptoTestUtils::ParseTag(const char* tagstr) {
534   const size_t len = strlen(tagstr);
535   CHECK_NE(0u, len);
536
537   QuicTag tag = 0;
538
539   if (tagstr[0] == '#') {
540     CHECK_EQ(static_cast<size_t>(1 + 2*4), len);
541     tagstr++;
542
543     for (size_t i = 0; i < 8; i++) {
544       tag <<= 4;
545
546       uint8 v = 0;
547       CHECK(HexChar(tagstr[i], &v));
548       tag |= v;
549     }
550
551     return tag;
552   }
553
554   CHECK_LE(len, 4u);
555   for (size_t i = 0; i < 4; i++) {
556     tag >>= 8;
557     if (i < len) {
558       tag |= static_cast<uint32>(tagstr[i]) << 24;
559     }
560   }
561
562   return tag;
563 }
564
565 // static
566 CryptoHandshakeMessage CryptoTestUtils::Message(const char* message_tag, ...) {
567   va_list ap;
568   va_start(ap, message_tag);
569
570   CryptoHandshakeMessage message = BuildMessage(message_tag, ap);
571   va_end(ap);
572   return message;
573 }
574
575 // static
576 CryptoHandshakeMessage CryptoTestUtils::BuildMessage(const char* message_tag,
577                                                      va_list ap) {
578   CryptoHandshakeMessage msg;
579   msg.set_tag(ParseTag(message_tag));
580
581   for (;;) {
582     const char* tagstr = va_arg(ap, const char*);
583     if (tagstr == NULL) {
584       break;
585     }
586
587     if (tagstr[0] == '$') {
588       // Special value.
589       const char* const special = tagstr + 1;
590       if (strcmp(special, "padding") == 0) {
591         const int min_bytes = va_arg(ap, int);
592         msg.set_minimum_size(min_bytes);
593       } else {
594         CHECK(false) << "Unknown special value: " << special;
595       }
596
597       continue;
598     }
599
600     const QuicTag tag = ParseTag(tagstr);
601     const char* valuestr = va_arg(ap, const char*);
602
603     size_t len = strlen(valuestr);
604     if (len > 0 && valuestr[0] == '#') {
605       valuestr++;
606       len--;
607
608       CHECK_EQ(0u, len % 2);
609       scoped_ptr<uint8[]> buf(new uint8[len/2]);
610
611       for (size_t i = 0; i < len/2; i++) {
612         uint8 v = 0;
613         CHECK(HexChar(valuestr[i*2], &v));
614         buf[i] = v << 4;
615         CHECK(HexChar(valuestr[i*2 + 1], &v));
616         buf[i] |= v;
617       }
618
619       msg.SetStringPiece(
620           tag, StringPiece(reinterpret_cast<char*>(buf.get()), len/2));
621       continue;
622     }
623
624     msg.SetStringPiece(tag, valuestr);
625   }
626
627   // The CryptoHandshakeMessage needs to be serialized and parsed to ensure
628   // that any padding is included.
629   scoped_ptr<QuicData> bytes(CryptoFramer::ConstructHandshakeMessage(msg));
630   scoped_ptr<CryptoHandshakeMessage> parsed(
631       CryptoFramer::ParseMessage(bytes->AsStringPiece()));
632   CHECK(parsed.get());
633
634   return *parsed;
635 }
636
637 }  // namespace test
638 }  // namespace net