| 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 "net/quic/crypto/crypto_protocol.h" | 7 #include "net/quic/crypto/crypto_protocol.h" |
| 8 #include "net/quic/quic_data_reader.h" | 8 #include "net/quic/quic_data_reader.h" |
| 9 #include "net/quic/quic_data_writer.h" | 9 #include "net/quic/quic_data_writer.h" |
| 10 | 10 |
| 11 using base::StringPiece; | 11 using base::StringPiece; |
| 12 using std::pair; | 12 using std::pair; |
| 13 using std::vector; | 13 using std::vector; |
| 14 | 14 |
| 15 namespace net { | 15 namespace net { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 const size_t kQuicTagSize = sizeof(uint32); | 19 const size_t kQuicTagSize = sizeof(uint32_t); |
| 20 const size_t kCryptoEndOffsetSize = sizeof(uint32); | 20 const size_t kCryptoEndOffsetSize = sizeof(uint32_t); |
| 21 const size_t kNumEntriesSize = sizeof(uint16); | 21 const size_t kNumEntriesSize = sizeof(uint16_t); |
| 22 | 22 |
| 23 // OneShotVisitor is a framer visitor that records a single handshake message. | 23 // OneShotVisitor is a framer visitor that records a single handshake message. |
| 24 class OneShotVisitor : public CryptoFramerVisitorInterface { | 24 class OneShotVisitor : public CryptoFramerVisitorInterface { |
| 25 public: | 25 public: |
| 26 OneShotVisitor() : error_(false) {} | 26 OneShotVisitor() : error_(false) {} |
| 27 | 27 |
| 28 void OnError(CryptoFramer* framer) override { error_ = true; } | 28 void OnError(CryptoFramer* framer) override { error_ = true; } |
| 29 | 29 |
| 30 void OnHandshakeMessage(const CryptoHandshakeMessage& message) override { | 30 void OnHandshakeMessage(const CryptoHandshakeMessage& message) override { |
| 31 out_.reset(new CryptoHandshakeMessage(message)); | 31 out_.reset(new CryptoHandshakeMessage(message)); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 if (num_entries > kMaxEntries) { | 102 if (num_entries > kMaxEntries) { |
| 103 return nullptr; | 103 return nullptr; |
| 104 } | 104 } |
| 105 | 105 |
| 106 scoped_ptr<char[]> buffer(new char[len]); | 106 scoped_ptr<char[]> buffer(new char[len]); |
| 107 QuicDataWriter writer(len, buffer.get()); | 107 QuicDataWriter writer(len, buffer.get()); |
| 108 if (!writer.WriteUInt32(message.tag())) { | 108 if (!writer.WriteUInt32(message.tag())) { |
| 109 DCHECK(false) << "Failed to write message tag."; | 109 DCHECK(false) << "Failed to write message tag."; |
| 110 return nullptr; | 110 return nullptr; |
| 111 } | 111 } |
| 112 if (!writer.WriteUInt16(static_cast<uint16>(num_entries))) { | 112 if (!writer.WriteUInt16(static_cast<uint16_t>(num_entries))) { |
| 113 DCHECK(false) << "Failed to write size."; | 113 DCHECK(false) << "Failed to write size."; |
| 114 return nullptr; | 114 return nullptr; |
| 115 } | 115 } |
| 116 if (!writer.WriteUInt16(0)) { | 116 if (!writer.WriteUInt16(0)) { |
| 117 DCHECK(false) << "Failed to write padding."; | 117 DCHECK(false) << "Failed to write padding."; |
| 118 return nullptr; | 118 return nullptr; |
| 119 } | 119 } |
| 120 | 120 |
| 121 uint32 end_offset = 0; | 121 uint32_t end_offset = 0; |
| 122 // Tags and offsets | 122 // Tags and offsets |
| 123 for (QuicTagValueMap::const_iterator it = message.tag_value_map().begin(); | 123 for (QuicTagValueMap::const_iterator it = message.tag_value_map().begin(); |
| 124 it != message.tag_value_map().end(); ++it) { | 124 it != message.tag_value_map().end(); ++it) { |
| 125 if (it->first == kPAD && need_pad_tag) { | 125 if (it->first == kPAD && need_pad_tag) { |
| 126 // Existing PAD tags are only checked when padding needs to be added | 126 // Existing PAD tags are only checked when padding needs to be added |
| 127 // because parts of the code may need to reserialize received messages | 127 // because parts of the code may need to reserialize received messages |
| 128 // and those messages may, legitimately include padding. | 128 // and those messages may, legitimately include padding. |
| 129 DCHECK(false) << "Message needed padding but already contained a PAD tag"; | 129 DCHECK(false) << "Message needed padding but already contained a PAD tag"; |
| 130 return nullptr; | 130 return nullptr; |
| 131 } | 131 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 switch (state_) { | 196 switch (state_) { |
| 197 case STATE_READING_TAG: | 197 case STATE_READING_TAG: |
| 198 if (reader.BytesRemaining() < kQuicTagSize) { | 198 if (reader.BytesRemaining() < kQuicTagSize) { |
| 199 break; | 199 break; |
| 200 } | 200 } |
| 201 QuicTag message_tag; | 201 QuicTag message_tag; |
| 202 reader.ReadUInt32(&message_tag); | 202 reader.ReadUInt32(&message_tag); |
| 203 message_.set_tag(message_tag); | 203 message_.set_tag(message_tag); |
| 204 state_ = STATE_READING_NUM_ENTRIES; | 204 state_ = STATE_READING_NUM_ENTRIES; |
| 205 case STATE_READING_NUM_ENTRIES: | 205 case STATE_READING_NUM_ENTRIES: |
| 206 if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16)) { | 206 if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16_t)) { |
| 207 break; | 207 break; |
| 208 } | 208 } |
| 209 reader.ReadUInt16(&num_entries_); | 209 reader.ReadUInt16(&num_entries_); |
| 210 if (num_entries_ > kMaxEntries) { | 210 if (num_entries_ > kMaxEntries) { |
| 211 return QUIC_CRYPTO_TOO_MANY_ENTRIES; | 211 return QUIC_CRYPTO_TOO_MANY_ENTRIES; |
| 212 } | 212 } |
| 213 uint16 padding; | 213 uint16_t padding; |
| 214 reader.ReadUInt16(&padding); | 214 reader.ReadUInt16(&padding); |
| 215 | 215 |
| 216 tags_and_lengths_.reserve(num_entries_); | 216 tags_and_lengths_.reserve(num_entries_); |
| 217 state_ = STATE_READING_TAGS_AND_LENGTHS; | 217 state_ = STATE_READING_TAGS_AND_LENGTHS; |
| 218 values_len_ = 0; | 218 values_len_ = 0; |
| 219 case STATE_READING_TAGS_AND_LENGTHS: { | 219 case STATE_READING_TAGS_AND_LENGTHS: { |
| 220 if (reader.BytesRemaining() < | 220 if (reader.BytesRemaining() < |
| 221 num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) { | 221 num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) { |
| 222 break; | 222 break; |
| 223 } | 223 } |
| 224 | 224 |
| 225 uint32 last_end_offset = 0; | 225 uint32_t last_end_offset = 0; |
| 226 for (unsigned i = 0; i < num_entries_; ++i) { | 226 for (unsigned i = 0; i < num_entries_; ++i) { |
| 227 QuicTag tag; | 227 QuicTag tag; |
| 228 reader.ReadUInt32(&tag); | 228 reader.ReadUInt32(&tag); |
| 229 if (i > 0 && tag <= tags_and_lengths_[i - 1].first) { | 229 if (i > 0 && tag <= tags_and_lengths_[i - 1].first) { |
| 230 if (tag == tags_and_lengths_[i - 1].first) { | 230 if (tag == tags_and_lengths_[i - 1].first) { |
| 231 return QUIC_CRYPTO_DUPLICATE_TAG; | 231 return QUIC_CRYPTO_DUPLICATE_TAG; |
| 232 } | 232 } |
| 233 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; | 233 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; |
| 234 } | 234 } |
| 235 | 235 |
| 236 uint32 end_offset; | 236 uint32_t end_offset; |
| 237 reader.ReadUInt32(&end_offset); | 237 reader.ReadUInt32(&end_offset); |
| 238 | 238 |
| 239 if (end_offset < last_end_offset) { | 239 if (end_offset < last_end_offset) { |
| 240 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; | 240 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; |
| 241 } | 241 } |
| 242 tags_and_lengths_.push_back(std::make_pair( | 242 tags_and_lengths_.push_back(std::make_pair( |
| 243 tag, static_cast<size_t>(end_offset - last_end_offset))); | 243 tag, static_cast<size_t>(end_offset - last_end_offset))); |
| 244 last_end_offset = end_offset; | 244 last_end_offset = end_offset; |
| 245 } | 245 } |
| 246 values_len_ = last_end_offset; | 246 values_len_ = last_end_offset; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 261 break; | 261 break; |
| 262 } | 262 } |
| 263 // Save any remaining data. | 263 // Save any remaining data. |
| 264 buffer_ = reader.PeekRemainingPayload().as_string(); | 264 buffer_ = reader.PeekRemainingPayload().as_string(); |
| 265 return QUIC_NO_ERROR; | 265 return QUIC_NO_ERROR; |
| 266 } | 266 } |
| 267 | 267 |
| 268 // static | 268 // static |
| 269 bool CryptoFramer::WritePadTag(QuicDataWriter* writer, | 269 bool CryptoFramer::WritePadTag(QuicDataWriter* writer, |
| 270 size_t pad_length, | 270 size_t pad_length, |
| 271 uint32* end_offset) { | 271 uint32_t* end_offset) { |
| 272 if (!writer->WriteUInt32(kPAD)) { | 272 if (!writer->WriteUInt32(kPAD)) { |
| 273 DCHECK(false) << "Failed to write tag."; | 273 DCHECK(false) << "Failed to write tag."; |
| 274 return false; | 274 return false; |
| 275 } | 275 } |
| 276 *end_offset += pad_length; | 276 *end_offset += pad_length; |
| 277 if (!writer->WriteUInt32(*end_offset)) { | 277 if (!writer->WriteUInt32(*end_offset)) { |
| 278 DCHECK(false) << "Failed to write end offset."; | 278 DCHECK(false) << "Failed to write end offset."; |
| 279 return false; | 279 return false; |
| 280 } | 280 } |
| 281 return true; | 281 return true; |
| 282 } | 282 } |
| 283 | 283 |
| 284 } // namespace net | 284 } // namespace net |
| OLD | NEW |