blob: a5cb3dc630bfb0d7be88ae3eb66257a79e3f21d6 [file] [log] [blame]
// 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 <list>
#include <vector>
#include "base/gtest_prod_util.h"
#include "device/u2f/u2f_packet.h"
namespace net {
class IOBufferWithSize;
} // namespace net
namespace device {
// U2fMessages are defined by the specification at
// A U2fMessage object represents a list of U2fPackets. Basic information
// about the message are available through class methods.
class U2fMessage {
enum class Type : uint8_t {
CMD_PING = 0x81,
CMD_MSG = 0x83,
CMD_INIT = 0x86,
CMD_WINK = 0x88,
CMD_ERROR = 0xbf,
U2fMessage(uint32_t channel_id, Type type, const std::vector<uint8_t>& data);
U2fMessage(std::unique_ptr<U2fInitPacket> init_packet, size_t remaining_size);
static std::unique_ptr<U2fMessage> Create(uint32_t channel_id,
Type type,
const std::vector<uint8_t>& data);
// Reconstruct a message from serialized message data
static std::unique_ptr<U2fMessage> CreateFromSerializedData(
const std::vector<uint8_t>& buf);
// Pop front of queue with next packet
scoped_refptr<net::IOBufferWithSize> PopNextPacket();
// Adds a continuation packet to the packet list, from the serialized
// response value
bool AddContinuationPacket(const std::vector<uint8_t>& packet_buf);
size_t NumPackets();
// Returns entire message payload
std::vector<uint8_t> GetMessagePayload() const;
uint32_t channel_id() { return channel_id_; }
// Message construction complete
bool MessageComplete();
std::list<std::unique_ptr<U2fPacket>>::const_iterator begin();
std::list<std::unique_ptr<U2fPacket>>::const_iterator end();
FRIEND_TEST_ALL_PREFIXES(U2fMessageTest, TestMaxLengthPacketConstructors);
FRIEND_TEST_ALL_PREFIXES(U2fMessageTest, TestMessagePartitoning);
FRIEND_TEST_ALL_PREFIXES(U2fMessageTest, TestDeconstruct);
FRIEND_TEST_ALL_PREFIXES(U2fMessageTest, TestMaxSize);
FRIEND_TEST_ALL_PREFIXES(U2fMessageTest, TestDeserialize);
static constexpr size_t kInitPacketHeader = 7;
static constexpr size_t kContinuationPacketHeader = 5;
static constexpr size_t kMaxHidPacketSize = 64;
static constexpr size_t kInitPacketDataSize =
kMaxHidPacketSize - kInitPacketHeader;
static constexpr size_t kContinuationPacketDataSize =
kMaxHidPacketSize - kContinuationPacketHeader;
// Messages are limited to an init packet and 128 continuation packets
// Maximum payload length therefore is 64-7 + 128 * (64-5) = 7609 bytes
static constexpr size_t kMaxMessageSize = 7609;
std::list<std::unique_ptr<U2fPacket>> packets_;
size_t remaining_size_;
uint32_t channel_id_;
} // namespace device