OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_crypto_client_stream.h" | 5 #include "net/quic/quic_crypto_client_stream.h" |
6 | 6 |
7 #include "net/quic/crypto/crypto_protocol.h" | 7 #include "net/quic/crypto/crypto_protocol.h" |
| 8 #include "net/quic/crypto/quic_random.h" |
| 9 #include "net/quic/quic_clock.h" |
8 #include "net/quic/quic_protocol.h" | 10 #include "net/quic/quic_protocol.h" |
| 11 #include "net/quic/quic_session.h" |
| 12 |
| 13 using base::StringPiece; |
9 | 14 |
10 namespace net { | 15 namespace net { |
11 | 16 |
12 QuicCryptoClientStream::QuicCryptoClientStream(QuicSession* session) | 17 QuicCryptoClientStream::QuicCryptoClientStream(QuicSession* session) |
13 : QuicCryptoStream(session) { | 18 : QuicCryptoStream(session) { |
14 } | 19 } |
15 | 20 |
16 | 21 |
17 void QuicCryptoClientStream::OnHandshakeMessage( | 22 void QuicCryptoClientStream::OnHandshakeMessage( |
18 const CryptoHandshakeMessage& message) { | 23 const CryptoHandshakeMessage& message) { |
19 // Do not process handshake messages after the handshake is complete. | 24 // Do not process handshake messages after the handshake is complete. |
20 if (handshake_complete()) { | 25 if (handshake_complete()) { |
21 CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE); | 26 CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE); |
22 return; | 27 return; |
23 } | 28 } |
24 | 29 |
25 if (message.tag != kSHLO) { | 30 if (message.tag != kSHLO) { |
26 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); | 31 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); |
27 return; | 32 return; |
28 } | 33 } |
29 | 34 |
30 // TODO(rch): correctly validate the message | 35 // TODO(rch): correctly validate the message |
31 SetHandshakeComplete(QUIC_NO_ERROR); | 36 SetHandshakeComplete(QUIC_NO_ERROR); |
32 return; | 37 return; |
33 } | 38 } |
34 | 39 |
| 40 bool QuicCryptoClientStream::CryptoConnect() { |
| 41 CryptoHandshakeMessage message; |
| 42 if (!FillClientHelloMessage(&message)) { |
| 43 return false; |
| 44 } |
| 45 SendHandshakeMessage(message); |
| 46 return true; |
| 47 } |
| 48 |
| 49 // Generates the connection nonce. |
| 50 void QuicCryptoClientStream::GenerateNonce() { |
| 51 // a 4-byte timestamp + 28 random bytes. |
| 52 nonce_.reserve(kNonceSize); |
| 53 nonce_.resize(kNonceSize); |
| 54 QuicTime::Delta now = |
| 55 session()->connection()->clock()->NowAsDeltaSinceUnixEpoch(); |
| 56 uint32 gmt_unix_time = now.ToSeconds(); |
| 57 const size_t time_size = sizeof(gmt_unix_time); |
| 58 memcpy(&nonce_[0], &gmt_unix_time, time_size); |
| 59 QuicRandom::GetInstance()->RandBytes(&nonce_[time_size], |
| 60 kNonceSize - time_size); |
| 61 } |
| 62 |
| 63 bool QuicCryptoClientStream::FillClientHelloMessage( |
| 64 CryptoHandshakeMessage* message) { |
| 65 message->tag = kCHLO; |
| 66 |
| 67 StringPiece value; |
| 68 |
| 69 // Version must be 0. |
| 70 version_ = 0; |
| 71 value.set(&version_, sizeof(version_)); |
| 72 message->tag_value_map[kVERS] = value.as_string(); |
| 73 |
| 74 // Key exchange methods. |
| 75 key_exchange_.resize(2); |
| 76 key_exchange_[0] = kC255; |
| 77 key_exchange_[1] = kP256; |
| 78 value.set(&key_exchange_[0], |
| 79 key_exchange_.size() * sizeof(key_exchange_[0])); |
| 80 message->tag_value_map[kKEXS] = value.as_string(); |
| 81 |
| 82 // Authenticated encryption algorithms. |
| 83 aead_.resize(2); |
| 84 aead_[0] = kAESG; |
| 85 aead_[1] = kAESH; |
| 86 value.set(&aead_[0], aead_.size() * sizeof(aead_[0])); |
| 87 message->tag_value_map[kAEAD] = value.as_string(); |
| 88 |
| 89 // Congestion control feedback types. |
| 90 congestion_control_.resize(2); |
| 91 congestion_control_[0] = kQBIC; |
| 92 congestion_control_[1] = kINAR; |
| 93 value.set(&congestion_control_[0], |
| 94 congestion_control_.size() * sizeof(congestion_control_[0])); |
| 95 message->tag_value_map[kCGST] = value.as_string(); |
| 96 |
| 97 // Idle connection state lifetime. |
| 98 idle_connection_state_lifetime_ = 300; // 300 seconds. |
| 99 value.set(&idle_connection_state_lifetime_, |
| 100 sizeof(idle_connection_state_lifetime_)); |
| 101 message->tag_value_map[kICSL] = value.as_string(); |
| 102 |
| 103 // Keepalive timeout. |
| 104 keepalive_timeout_ = 0; // Don't send keepalive probes. |
| 105 value.set(&keepalive_timeout_, sizeof(keepalive_timeout_)); |
| 106 message->tag_value_map[kKATO] = value.as_string(); |
| 107 |
| 108 // Connection nonce. |
| 109 GenerateNonce(); |
| 110 if (nonce_.empty()) { |
| 111 return false; |
| 112 } |
| 113 message->tag_value_map[kNONC] = nonce_; |
| 114 |
| 115 // Server name indication. |
| 116 // TODO(wtc): if server_hostname_ is a DNS name, store it in |
| 117 // message->tag_value_map[kSNI]. |
| 118 |
| 119 return true; |
| 120 } |
| 121 |
35 } // namespace net | 122 } // namespace net |
OLD | NEW |