Chromium Code Reviews| Index: device/u2f/u2f_message.cc |
| diff --git a/device/u2f/u2f_message.cc b/device/u2f/u2f_message.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..98c51c3f5fd07d7ccc6efe2201e51774ea2c9445 |
| --- /dev/null |
| +++ b/device/u2f/u2f_message.cc |
| @@ -0,0 +1,138 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "device/u2f/u2f_message.h" |
| +#include "device/u2f/u2f_packet.h" |
| + |
| +namespace device { |
| + |
| +// static |
| +scoped_refptr<U2fMessage> U2fMessage::Create(const uint32_t channel_id, |
| + const Type type, |
| + const std::vector<uint8_t>& data) { |
| + if (data.size() > kMaxMessageSize) |
| + return nullptr; |
| + |
| + return make_scoped_refptr(new U2fMessage(channel_id, type, data)); |
| +} |
| + |
| +// static |
| +scoped_refptr<U2fMessage> U2fMessage::CreateFromSerializedData( |
| + scoped_refptr<net::IOBufferWithSize> buf) { |
| + if (buf == nullptr || |
| + static_cast<size_t>(buf->size()) > U2fPacket::kPacketSize || |
| + static_cast<size_t>(buf->size()) < kInitPacketHeader) |
| + return nullptr; |
| + |
| + return make_scoped_refptr(new U2fMessage(buf)); |
| +} |
| + |
| +U2fMessage::U2fMessage(scoped_refptr<net::IOBufferWithSize> buf) |
| + : packets_(), remaining_size_(0), channel_id_() { |
| + scoped_refptr<U2fInitPacket> init_packet = |
| + U2fInitPacket::CreateFromSerializedData(buf, &remaining_size_); |
| + channel_id_ = init_packet->GetChannelId(); |
| + |
| + packets_.push_back(init_packet); |
| +} |
| + |
| +U2fMessage::U2fMessage(const uint32_t channel_id, |
| + const Type type, |
| + const std::vector<uint8_t>& data) |
| + : packets_(), remaining_size_(), channel_id_(channel_id) { |
| + remaining_size_ = data.size(); |
| + uint8_t sequence = 0; |
| + |
| + std::vector<uint8_t>::const_iterator first = data.begin(); |
| + std::vector<uint8_t>::const_iterator last; |
| + |
| + if (remaining_size_ > kInitPacketDataSize) { |
| + last = data.begin() + kInitPacketDataSize; |
| + remaining_size_ -= kInitPacketDataSize; |
| + } else { |
| + last = data.begin() + remaining_size_; |
| + remaining_size_ = 0; |
| + } |
| + |
| + packets_.push_back(make_scoped_refptr( |
| + new U2fInitPacket(channel_id, static_cast<uint8_t>(type), |
| + std::vector<uint8_t>(first, last), data.size()))); |
| + |
| + while (remaining_size_ > 0) { |
| + first = last; |
| + if (remaining_size_ > kContinuationPacketDataSize) { |
| + last = first + kContinuationPacketDataSize; |
| + remaining_size_ -= kContinuationPacketDataSize; |
| + } else { |
| + last = first + remaining_size_; |
| + remaining_size_ = 0; |
| + } |
| + |
| + packets_.push_back(make_scoped_refptr(new U2fContinuationPacket( |
| + channel_id, sequence, std::vector<uint8_t>(first, last)))); |
| + sequence++; |
| + } |
| +} |
| + |
| +U2fMessage::~U2fMessage() {} |
| + |
| +std::list<scoped_refptr<U2fPacket>>::const_iterator U2fMessage::begin() { |
| + return packets_.cbegin(); |
| +} |
| + |
| +std::list<scoped_refptr<U2fPacket>>::const_iterator U2fMessage::end() { |
| + return packets_.cend(); |
| +} |
| + |
| +uint32_t U2fMessage::GetChannelId() { |
| + return channel_id_; |
| +} |
| + |
| +scoped_refptr<net::IOBufferWithSize> U2fMessage::PopNextPacket() { |
| + if (NumPackets() > 0) { |
| + scoped_refptr<net::IOBufferWithSize> buf = |
| + packets_.front()->GetSerializedBuffer(); |
| + packets_.pop_front(); |
| + return buf; |
| + } |
| + return nullptr; |
| +} |
| + |
| +bool U2fMessage::AddContinuationPacket( |
| + scoped_refptr<net::IOBufferWithSize> buf) { |
| + size_t remaining_size = remaining_size_; |
| + scoped_refptr<U2fContinuationPacket> cont_packet = |
| + U2fContinuationPacket::CreateFromSerializedData(buf, &remaining_size_); |
| + |
| + // Reject packets with a different channel id |
| + if (channel_id_ != cont_packet->GetChannelId()) { |
| + remaining_size_ = remaining_size; |
| + return false; |
| + } |
| + |
| + packets_.push_back(cont_packet); |
| + return true; |
| +} |
| + |
| +bool U2fMessage::MessageComplete() { |
| + return remaining_size_ == 0; |
|
Reilly Grant (use Gerrit)
2016/12/09 01:19:43
This method is never called and it seems dubious t
Casey Piper
2016/12/09 18:56:50
This method is intended to use when constructing a
|
| +} |
| + |
| +const std::vector<uint8_t> U2fMessage::GetMessagePayload() { |
| + std::vector<uint8_t> data; |
| + |
| + for (const auto& packet : packets_) { |
| + std::vector<uint8_t> packet_data = packet->GetPacketPayload(); |
| + |
|
Reilly Grant (use Gerrit)
2016/12/09 01:19:43
nit: this blank line isn't really necessary.
Casey Piper
2016/12/09 18:56:50
Acknowledged.
|
| + data.insert(std::end(data), packet_data.cbegin(), packet_data.cend()); |
| + } |
| + |
| + return data; |
| +} |
| + |
| +size_t U2fMessage::NumPackets() { |
| + return packets_.size(); |
| +} |
| + |
| +} // namespace device |