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/quic_crypto_stream.h" 6 7 #include <string> 8 9 #include "base/strings/string_piece.h" 10 #include "net/quic/crypto/crypto_handshake.h" 11 #include "net/quic/crypto/crypto_utils.h" 12 #include "net/quic/quic_connection.h" 13 #include "net/quic/quic_session.h" 14 #include "net/quic/quic_utils.h" 15 16 using std::string; 17 using base::StringPiece; 18 19 namespace net { 20 21 #define ENDPOINT (session()->is_server() ? "Server: " : " Client: ") 22 23 QuicCryptoStream::QuicCryptoStream(QuicSession* session) 24 : ReliableQuicStream(kCryptoStreamId, session), 25 encryption_established_(false), 26 handshake_confirmed_(false) { 27 crypto_framer_.set_visitor(this); 28 if (version() < QUIC_VERSION_21) { 29 // Prior to QUIC_VERSION_21 the crypto stream is not subject to any flow 30 // control. 31 DisableFlowControl(); 32 } 33 // The crypto stream is exempt from connection level flow control. 34 DisableConnectionFlowControlForThisStream(); 35 } 36 37 void QuicCryptoStream::OnError(CryptoFramer* framer) { 38 DLOG(WARNING) << "Error processing crypto data: " 39 << QuicUtils::ErrorToString(framer->error()); 40 } 41 42 void QuicCryptoStream::OnHandshakeMessage( 43 const CryptoHandshakeMessage& message) { 44 DVLOG(1) << ENDPOINT << "Received " << message.DebugString(); 45 session()->OnCryptoHandshakeMessageReceived(message); 46 } 47 48 uint32 QuicCryptoStream::ProcessRawData(const char* data, 49 uint32 data_len) { 50 if (!crypto_framer_.ProcessInput(StringPiece(data, data_len))) { 51 CloseConnection(crypto_framer_.error()); 52 return 0; 53 } 54 return data_len; 55 } 56 57 QuicPriority QuicCryptoStream::EffectivePriority() const { 58 return QuicUtils::HighestPriority(); 59 } 60 61 void QuicCryptoStream::SendHandshakeMessage( 62 const CryptoHandshakeMessage& message) { 63 SendHandshakeMessage(message, NULL); 64 } 65 66 void QuicCryptoStream::SendHandshakeMessage( 67 const CryptoHandshakeMessage& message, 68 QuicAckNotifier::DelegateInterface* delegate) { 69 DVLOG(1) << ENDPOINT << "Sending " << message.DebugString(); 70 session()->OnCryptoHandshakeMessageSent(message); 71 const QuicData& data = message.GetSerialized(); 72 // TODO(wtc): check the return value. 73 WriteOrBufferData(string(data.data(), data.length()), false, delegate); 74 } 75 76 bool QuicCryptoStream::ExportKeyingMaterial( 77 StringPiece label, 78 StringPiece context, 79 size_t result_len, 80 string* result) const { 81 if (!handshake_confirmed()) { 82 DLOG(ERROR) << "ExportKeyingMaterial was called before forward-secure" 83 << "encryption was established."; 84 return false; 85 } 86 return CryptoUtils::ExportKeyingMaterial( 87 crypto_negotiated_params_.subkey_secret, 88 label, 89 context, 90 result_len, 91 result); 92 } 93 94 const QuicCryptoNegotiatedParameters& 95 QuicCryptoStream::crypto_negotiated_params() const { 96 return crypto_negotiated_params_; 97 } 98 99 } // namespace net 100