| 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/crypto/crypto_framer.h" | 5 #include "net/quic/crypto/crypto_framer.h" |
| 6 | 6 |
| 7 #include "base/strings/stringprintf.h" |
| 7 #include "net/quic/crypto/crypto_protocol.h" | 8 #include "net/quic/crypto/crypto_protocol.h" |
| 8 #include "net/quic/quic_data_reader.h" | 9 #include "net/quic/quic_data_reader.h" |
| 9 #include "net/quic/quic_data_writer.h" | 10 #include "net/quic/quic_data_writer.h" |
| 10 | 11 |
| 11 using base::StringPiece; | 12 using base::StringPiece; |
| 12 using std::pair; | 13 using std::pair; |
| 13 using std::vector; | 14 using std::vector; |
| 14 | 15 |
| 15 namespace net { | 16 namespace net { |
| 16 | 17 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 36 CryptoHandshakeMessage* release() { return out_.release(); } | 37 CryptoHandshakeMessage* release() { return out_.release(); } |
| 37 | 38 |
| 38 private: | 39 private: |
| 39 scoped_ptr<CryptoHandshakeMessage> out_; | 40 scoped_ptr<CryptoHandshakeMessage> out_; |
| 40 bool error_; | 41 bool error_; |
| 41 }; | 42 }; |
| 42 | 43 |
| 43 } // namespace | 44 } // namespace |
| 44 | 45 |
| 45 CryptoFramer::CryptoFramer() | 46 CryptoFramer::CryptoFramer() |
| 46 : visitor_(nullptr), | 47 : visitor_(nullptr), error_detail_(""), num_entries_(0), values_len_(0) { |
| 47 num_entries_(0), | |
| 48 values_len_(0) { | |
| 49 Clear(); | 48 Clear(); |
| 50 } | 49 } |
| 51 | 50 |
| 52 CryptoFramer::~CryptoFramer() {} | 51 CryptoFramer::~CryptoFramer() {} |
| 53 | 52 |
| 54 // static | 53 // static |
| 55 CryptoHandshakeMessage* CryptoFramer::ParseMessage(StringPiece in) { | 54 CryptoHandshakeMessage* CryptoFramer::ParseMessage(StringPiece in) { |
| 56 OneShotVisitor visitor; | 55 OneShotVisitor visitor; |
| 57 CryptoFramer framer; | 56 CryptoFramer framer; |
| 58 | 57 |
| 59 framer.set_visitor(&visitor); | 58 framer.set_visitor(&visitor); |
| 60 if (!framer.ProcessInput(in) || visitor.error() || | 59 if (!framer.ProcessInput(in) || visitor.error() || |
| 61 framer.InputBytesRemaining()) { | 60 framer.InputBytesRemaining()) { |
| 62 return nullptr; | 61 return nullptr; |
| 63 } | 62 } |
| 64 | 63 |
| 65 return visitor.release(); | 64 return visitor.release(); |
| 66 } | 65 } |
| 67 | 66 |
| 68 bool CryptoFramer::ProcessInput(StringPiece input) { | 67 bool CryptoFramer::ProcessInput(StringPiece input) { |
| 69 DCHECK_EQ(QUIC_NO_ERROR, error_); | 68 DCHECK_EQ(QUIC_NO_ERROR, error_); |
| 70 if (error_ != QUIC_NO_ERROR) { | 69 if (error_ != QUIC_NO_ERROR) { |
| 71 return false; | 70 return false; |
| 72 } | 71 } |
| 73 error_ = Process(input); | 72 error_ = Process(input); |
| 74 if (error_ != QUIC_NO_ERROR) { | 73 if (error_ != QUIC_NO_ERROR) { |
| 74 DCHECK(!error_detail_.empty()); |
| 75 visitor_->OnError(this); | 75 visitor_->OnError(this); |
| 76 return false; | 76 return false; |
| 77 } | 77 } |
| 78 | 78 |
| 79 return true; | 79 return true; |
| 80 } | 80 } |
| 81 | 81 |
| 82 // static | 82 // static |
| 83 QuicData* CryptoFramer::ConstructHandshakeMessage( | 83 QuicData* CryptoFramer::ConstructHandshakeMessage( |
| 84 const CryptoHandshakeMessage& message) { | 84 const CryptoHandshakeMessage& message) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 | 182 |
| 183 return new QuicData(buffer.release(), len, true); | 183 return new QuicData(buffer.release(), len, true); |
| 184 } | 184 } |
| 185 | 185 |
| 186 void CryptoFramer::Clear() { | 186 void CryptoFramer::Clear() { |
| 187 message_.Clear(); | 187 message_.Clear(); |
| 188 tags_and_lengths_.clear(); | 188 tags_and_lengths_.clear(); |
| 189 error_ = QUIC_NO_ERROR; | 189 error_ = QUIC_NO_ERROR; |
| 190 error_detail_ = ""; |
| 190 state_ = STATE_READING_TAG; | 191 state_ = STATE_READING_TAG; |
| 191 } | 192 } |
| 192 | 193 |
| 193 QuicErrorCode CryptoFramer::Process(StringPiece input) { | 194 QuicErrorCode CryptoFramer::Process(StringPiece input) { |
| 194 // Add this data to the buffer. | 195 // Add this data to the buffer. |
| 195 buffer_.append(input.data(), input.length()); | 196 buffer_.append(input.data(), input.length()); |
| 196 QuicDataReader reader(buffer_.data(), buffer_.length()); | 197 QuicDataReader reader(buffer_.data(), buffer_.length()); |
| 197 | 198 |
| 198 switch (state_) { | 199 switch (state_) { |
| 199 case STATE_READING_TAG: | 200 case STATE_READING_TAG: |
| 200 if (reader.BytesRemaining() < kQuicTagSize) { | 201 if (reader.BytesRemaining() < kQuicTagSize) { |
| 201 break; | 202 break; |
| 202 } | 203 } |
| 203 QuicTag message_tag; | 204 QuicTag message_tag; |
| 204 reader.ReadUInt32(&message_tag); | 205 reader.ReadUInt32(&message_tag); |
| 205 message_.set_tag(message_tag); | 206 message_.set_tag(message_tag); |
| 206 state_ = STATE_READING_NUM_ENTRIES; | 207 state_ = STATE_READING_NUM_ENTRIES; |
| 207 case STATE_READING_NUM_ENTRIES: | 208 case STATE_READING_NUM_ENTRIES: |
| 208 if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16)) { | 209 if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16)) { |
| 209 break; | 210 break; |
| 210 } | 211 } |
| 211 reader.ReadUInt16(&num_entries_); | 212 reader.ReadUInt16(&num_entries_); |
| 212 if (num_entries_ > kMaxEntries) { | 213 if (num_entries_ > kMaxEntries) { |
| 214 error_detail_ = base::StringPrintf("%u entries", num_entries_); |
| 213 return QUIC_CRYPTO_TOO_MANY_ENTRIES; | 215 return QUIC_CRYPTO_TOO_MANY_ENTRIES; |
| 214 } | 216 } |
| 215 uint16 padding; | 217 uint16 padding; |
| 216 reader.ReadUInt16(&padding); | 218 reader.ReadUInt16(&padding); |
| 217 | 219 |
| 218 tags_and_lengths_.reserve(num_entries_); | 220 tags_and_lengths_.reserve(num_entries_); |
| 219 state_ = STATE_READING_TAGS_AND_LENGTHS; | 221 state_ = STATE_READING_TAGS_AND_LENGTHS; |
| 220 values_len_ = 0; | 222 values_len_ = 0; |
| 221 case STATE_READING_TAGS_AND_LENGTHS: { | 223 case STATE_READING_TAGS_AND_LENGTHS: { |
| 222 if (reader.BytesRemaining() < | 224 if (reader.BytesRemaining() < |
| 223 num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) { | 225 num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) { |
| 224 break; | 226 break; |
| 225 } | 227 } |
| 226 | 228 |
| 227 uint32 last_end_offset = 0; | 229 uint32 last_end_offset = 0; |
| 228 for (unsigned i = 0; i < num_entries_; ++i) { | 230 for (unsigned i = 0; i < num_entries_; ++i) { |
| 229 QuicTag tag; | 231 QuicTag tag; |
| 230 reader.ReadUInt32(&tag); | 232 reader.ReadUInt32(&tag); |
| 231 if (i > 0 && tag <= tags_and_lengths_[i-1].first) { | 233 if (i > 0 && tag <= tags_and_lengths_[i-1].first) { |
| 232 if (tag == tags_and_lengths_[i-1].first) { | 234 if (tag == tags_and_lengths_[i-1].first) { |
| 235 error_detail_ = base::StringPrintf("Duplicate tag:%u", tag); |
| 233 return QUIC_CRYPTO_DUPLICATE_TAG; | 236 return QUIC_CRYPTO_DUPLICATE_TAG; |
| 234 } | 237 } |
| 238 error_detail_ = base::StringPrintf("Tag %u out of order", tag); |
| 235 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; | 239 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; |
| 236 } | 240 } |
| 237 | 241 |
| 238 uint32 end_offset; | 242 uint32 end_offset; |
| 239 reader.ReadUInt32(&end_offset); | 243 reader.ReadUInt32(&end_offset); |
| 240 | 244 |
| 241 if (end_offset < last_end_offset) { | 245 if (end_offset < last_end_offset) { |
| 246 error_detail_ = base::StringPrintf("End offset: %u vs %u", end_offset, |
| 247 last_end_offset); |
| 242 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; | 248 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; |
| 243 } | 249 } |
| 244 tags_and_lengths_.push_back(std::make_pair( | 250 tags_and_lengths_.push_back(std::make_pair( |
| 245 tag, static_cast<size_t>(end_offset - last_end_offset))); | 251 tag, static_cast<size_t>(end_offset - last_end_offset))); |
| 246 last_end_offset = end_offset; | 252 last_end_offset = end_offset; |
| 247 } | 253 } |
| 248 values_len_ = last_end_offset; | 254 values_len_ = last_end_offset; |
| 249 state_ = STATE_READING_VALUES; | 255 state_ = STATE_READING_VALUES; |
| 250 } | 256 } |
| 251 case STATE_READING_VALUES: | 257 case STATE_READING_VALUES: |
| (...skipping 25 matching lines...) Expand all Loading... |
| 277 } | 283 } |
| 278 *end_offset += pad_length; | 284 *end_offset += pad_length; |
| 279 if (!writer->WriteUInt32(*end_offset)) { | 285 if (!writer->WriteUInt32(*end_offset)) { |
| 280 DCHECK(false) << "Failed to write end offset."; | 286 DCHECK(false) << "Failed to write end offset."; |
| 281 return false; | 287 return false; |
| 282 } | 288 } |
| 283 return true; | 289 return true; |
| 284 } | 290 } |
| 285 | 291 |
| 286 } // namespace net | 292 } // namespace net |
| OLD | NEW |