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_server_stream.h" | 5 #include "net/quic/quic_crypto_server_stream.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "crypto/secure_hash.h" | 8 #include "crypto/secure_hash.h" |
9 #include "net/quic/crypto/crypto_protocol.h" | 9 #include "net/quic/crypto/crypto_protocol.h" |
10 #include "net/quic/crypto/crypto_utils.h" | 10 #include "net/quic/crypto/crypto_utils.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 | 69 |
70 void QuicCryptoServerStream::FinishProcessingHandshakeMessage( | 70 void QuicCryptoServerStream::FinishProcessingHandshakeMessage( |
71 const CryptoHandshakeMessage& message, | 71 const CryptoHandshakeMessage& message, |
72 const ValidateClientHelloResultCallback::Result& result) { | 72 const ValidateClientHelloResultCallback::Result& result) { |
73 // Clear the callback that got us here. | 73 // Clear the callback that got us here. |
74 DCHECK(validate_client_hello_cb_ != NULL); | 74 DCHECK(validate_client_hello_cb_ != NULL); |
75 validate_client_hello_cb_ = NULL; | 75 validate_client_hello_cb_ = NULL; |
76 | 76 |
77 string error_details; | 77 string error_details; |
78 CryptoHandshakeMessage reply; | 78 CryptoHandshakeMessage reply; |
79 QuicErrorCode error = ProcessClientHello( | 79 QuicErrorCode error = |
80 message, result, &reply, &error_details); | 80 ProcessClientHello(message, result, &reply, &error_details); |
81 | 81 |
82 if (error != QUIC_NO_ERROR) { | 82 if (error != QUIC_NO_ERROR) { |
83 CloseConnectionWithDetails(error, error_details); | 83 CloseConnectionWithDetails(error, error_details); |
84 return; | 84 return; |
85 } | 85 } |
86 | 86 |
87 if (reply.tag() != kSHLO) { | 87 if (reply.tag() != kSHLO) { |
88 SendHandshakeMessage(reply); | 88 SendHandshakeMessage(reply); |
89 return; | 89 return; |
90 } | 90 } |
(...skipping 10 matching lines...) Expand all Loading... |
101 config->ToHandshakeMessage(&reply); | 101 config->ToHandshakeMessage(&reply); |
102 | 102 |
103 // Receiving a full CHLO implies the client is prepared to decrypt with | 103 // Receiving a full CHLO implies the client is prepared to decrypt with |
104 // the new server write key. We can start to encrypt with the new server | 104 // the new server write key. We can start to encrypt with the new server |
105 // write key. | 105 // write key. |
106 // | 106 // |
107 // NOTE: the SHLO will be encrypted with the new server write key. | 107 // NOTE: the SHLO will be encrypted with the new server write key. |
108 session()->connection()->SetEncrypter( | 108 session()->connection()->SetEncrypter( |
109 ENCRYPTION_INITIAL, | 109 ENCRYPTION_INITIAL, |
110 crypto_negotiated_params_.initial_crypters.encrypter.release()); | 110 crypto_negotiated_params_.initial_crypters.encrypter.release()); |
111 session()->connection()->SetDefaultEncryptionLevel( | 111 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); |
112 ENCRYPTION_INITIAL); | |
113 // Set the decrypter immediately so that we no longer accept unencrypted | 112 // Set the decrypter immediately so that we no longer accept unencrypted |
114 // packets. | 113 // packets. |
115 session()->connection()->SetDecrypter( | 114 session()->connection()->SetDecrypter( |
116 crypto_negotiated_params_.initial_crypters.decrypter.release(), | 115 crypto_negotiated_params_.initial_crypters.decrypter.release(), |
117 ENCRYPTION_INITIAL); | 116 ENCRYPTION_INITIAL); |
118 SendHandshakeMessage(reply); | 117 SendHandshakeMessage(reply); |
119 | 118 |
120 session()->connection()->SetEncrypter( | 119 session()->connection()->SetEncrypter( |
121 ENCRYPTION_FORWARD_SECURE, | 120 ENCRYPTION_FORWARD_SECURE, |
122 crypto_negotiated_params_.forward_secure_crypters.encrypter.release()); | 121 crypto_negotiated_params_.forward_secure_crypters.encrypter.release()); |
123 session()->connection()->SetDefaultEncryptionLevel( | 122 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); |
124 ENCRYPTION_FORWARD_SECURE); | |
125 session()->connection()->SetAlternativeDecrypter( | 123 session()->connection()->SetAlternativeDecrypter( |
126 crypto_negotiated_params_.forward_secure_crypters.decrypter.release(), | 124 crypto_negotiated_params_.forward_secure_crypters.decrypter.release(), |
127 ENCRYPTION_FORWARD_SECURE, false /* don't latch */); | 125 ENCRYPTION_FORWARD_SECURE, |
| 126 false /* don't latch */); |
128 | 127 |
129 encryption_established_ = true; | 128 encryption_established_ = true; |
130 handshake_confirmed_ = true; | 129 handshake_confirmed_ = true; |
131 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); | 130 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); |
132 } | 131 } |
133 | 132 |
134 bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID( | 133 bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID( |
135 string* output) const { | 134 string* output) const { |
136 if (!encryption_established_ || | 135 if (!encryption_established_ || |
137 crypto_negotiated_params_.channel_id.empty()) { | 136 crypto_negotiated_params_.channel_id.empty()) { |
138 return false; | 137 return false; |
139 } | 138 } |
140 | 139 |
141 const string& channel_id(crypto_negotiated_params_.channel_id); | 140 const string& channel_id(crypto_negotiated_params_.channel_id); |
142 scoped_ptr<crypto::SecureHash> hash( | 141 scoped_ptr<crypto::SecureHash> hash( |
143 crypto::SecureHash::Create(crypto::SecureHash::SHA256)); | 142 crypto::SecureHash::Create(crypto::SecureHash::SHA256)); |
144 hash->Update(channel_id.data(), channel_id.size()); | 143 hash->Update(channel_id.data(), channel_id.size()); |
145 uint8 digest[32]; | 144 uint8 digest[32]; |
146 hash->Finish(digest, sizeof(digest)); | 145 hash->Finish(digest, sizeof(digest)); |
147 | 146 |
148 base::Base64Encode(string( | 147 base::Base64Encode( |
149 reinterpret_cast<const char*>(digest), sizeof(digest)), output); | 148 string(reinterpret_cast<const char*>(digest), sizeof(digest)), output); |
150 // Remove padding. | 149 // Remove padding. |
151 size_t len = output->size(); | 150 size_t len = output->size(); |
152 if (len >= 2) { | 151 if (len >= 2) { |
153 if ((*output)[len - 1] == '=') { | 152 if ((*output)[len - 1] == '=') { |
154 len--; | 153 len--; |
155 if ((*output)[len - 1] == '=') { | 154 if ((*output)[len - 1] == '=') { |
156 len--; | 155 len--; |
157 } | 156 } |
158 output->resize(len); | 157 output->resize(len); |
159 } | 158 } |
160 } | 159 } |
161 return true; | 160 return true; |
162 } | 161 } |
163 | 162 |
164 QuicErrorCode QuicCryptoServerStream::ProcessClientHello( | 163 QuicErrorCode QuicCryptoServerStream::ProcessClientHello( |
165 const CryptoHandshakeMessage& message, | 164 const CryptoHandshakeMessage& message, |
166 const ValidateClientHelloResultCallback::Result& result, | 165 const ValidateClientHelloResultCallback::Result& result, |
167 CryptoHandshakeMessage* reply, | 166 CryptoHandshakeMessage* reply, |
168 string* error_details) { | 167 string* error_details) { |
169 return crypto_config_.ProcessClientHello( | 168 return crypto_config_.ProcessClientHello( |
170 result, | 169 result, |
171 session()->connection()->connection_id(), | 170 session()->connection()->connection_id(), |
172 session()->connection()->peer_address(), | 171 session()->connection()->peer_address(), |
173 session()->connection()->version(), | 172 session()->connection()->version(), |
174 session()->connection()->supported_versions(), | 173 session()->connection()->supported_versions(), |
175 session()->connection()->max_flow_control_receive_window_bytes(), | 174 session()->connection()->max_flow_control_receive_window_bytes(), |
176 session()->connection()->clock(), | 175 session()->connection()->clock(), |
177 session()->connection()->random_generator(), | 176 session()->connection()->random_generator(), |
178 &crypto_negotiated_params_, reply, error_details); | 177 &crypto_negotiated_params_, |
| 178 reply, |
| 179 error_details); |
179 } | 180 } |
180 | 181 |
181 QuicCryptoServerStream::ValidateCallback::ValidateCallback( | 182 QuicCryptoServerStream::ValidateCallback::ValidateCallback( |
182 QuicCryptoServerStream* parent) : parent_(parent) { | 183 QuicCryptoServerStream* parent) |
| 184 : parent_(parent) { |
183 } | 185 } |
184 | 186 |
185 void QuicCryptoServerStream::ValidateCallback::Cancel() { | 187 void QuicCryptoServerStream::ValidateCallback::Cancel() { |
186 parent_ = NULL; | 188 parent_ = NULL; |
187 } | 189 } |
188 | 190 |
189 void QuicCryptoServerStream::ValidateCallback::RunImpl( | 191 void QuicCryptoServerStream::ValidateCallback::RunImpl( |
190 const CryptoHandshakeMessage& client_hello, | 192 const CryptoHandshakeMessage& client_hello, |
191 const Result& result) { | 193 const Result& result) { |
192 if (parent_ != NULL) { | 194 if (parent_ != NULL) { |
193 parent_->FinishProcessingHandshakeMessage(client_hello, result); | 195 parent_->FinishProcessingHandshakeMessage(client_hello, result); |
194 } | 196 } |
195 } | 197 } |
196 | 198 |
197 } // namespace net | 199 } // namespace net |
OLD | NEW |