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