Commit 49c5cc87 authored by Jun Choi's avatar Jun Choi Committed by Commit Bot

Add CTAPRequest objects with empty parameter

AuthenticatorGetInfo, AuthenticatorGetNextAssertion, AuthenticatorReset,
and AuthenticatorCancel commands in CTAP protocol are requests with empty
parameter and are serialized to a single byte that represents command
type. Add object construct to encapsulate/serialize requests with empty
parameter.

Bug: 799355
Change-Id: I05a876a17bfb3dc1c1ef21d830f330db503856f6
Reviewed-on: https://chromium-review.googlesource.com/851673
Commit-Queue: Jun Choi <hongjunchoi@chromium.org>
Reviewed-by: default avatarKim Paulhamus <kpaulhamus@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#531937}
parent e4b5dc98
......@@ -14,6 +14,8 @@ source_set("ctap") {
"authenticator_make_credential_response.h",
"authenticator_supported_options.cc",
"authenticator_supported_options.h",
"ctap_authenticator_request_param.cc",
"ctap_authenticator_request_param.h",
"ctap_constants.cc",
"ctap_constants.h",
"ctap_get_assertion_request_param.cc",
......
// Copyright 2018 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/ctap/ctap_authenticator_request_param.h"
#include "base/numerics/safe_conversions.h"
namespace device {
// static
CTAPAuthenticatorRequestParam
CTAPAuthenticatorRequestParam::CreateGetInfoParam() {
return CTAPAuthenticatorRequestParam(
CTAPRequestCommand::kAuthenticatorGetInfo);
}
// static
CTAPAuthenticatorRequestParam
CTAPAuthenticatorRequestParam::CreateGetNextAssertionParam() {
return CTAPAuthenticatorRequestParam(
CTAPRequestCommand::kAuthenticatorGetNextAssertion);
}
// static
CTAPAuthenticatorRequestParam
CTAPAuthenticatorRequestParam::CreateResetParam() {
return CTAPAuthenticatorRequestParam(CTAPRequestCommand::kAuthenticatorReset);
}
// static
CTAPAuthenticatorRequestParam
CTAPAuthenticatorRequestParam::CreateCancelParam() {
return CTAPAuthenticatorRequestParam(
CTAPRequestCommand::kAuthenticatorCancel);
}
CTAPAuthenticatorRequestParam::CTAPAuthenticatorRequestParam(
CTAPAuthenticatorRequestParam&& that) = default;
CTAPAuthenticatorRequestParam& CTAPAuthenticatorRequestParam::operator=(
CTAPAuthenticatorRequestParam&& that) = default;
CTAPAuthenticatorRequestParam::~CTAPAuthenticatorRequestParam() = default;
base::Optional<std::vector<uint8_t>> CTAPAuthenticatorRequestParam::Encode()
const {
return std::vector<uint8_t>{base::strict_cast<uint8_t>(cmd_)};
}
CTAPAuthenticatorRequestParam::CTAPAuthenticatorRequestParam(
CTAPRequestCommand cmd)
: cmd_(cmd) {}
} // namespace device
// Copyright 2018 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.
#ifndef DEVICE_CTAP_CTAP_AUTHENTICATOR_REQUEST_PARAM_H_
#define DEVICE_CTAP_CTAP_AUTHENTICATOR_REQUEST_PARAM_H_
#include <stdint.h>
#include <string>
#include <vector>
#include "base/optional.h"
#include "device/ctap/ctap_constants.h"
#include "device/ctap/ctap_request_param.h"
namespace device {
// Represents CTAP requests with empty parameters, including
// AuthenticatorGetInfo, AuthenticatorCancel, AuthenticatorReset and
// AuthenticatorGetNextAssertion commands.
class CTAPAuthenticatorRequestParam : public CTAPRequestParam {
public:
static CTAPAuthenticatorRequestParam CreateGetInfoParam();
static CTAPAuthenticatorRequestParam CreateGetNextAssertionParam();
static CTAPAuthenticatorRequestParam CreateResetParam();
static CTAPAuthenticatorRequestParam CreateCancelParam();
CTAPAuthenticatorRequestParam(CTAPAuthenticatorRequestParam&& that);
CTAPAuthenticatorRequestParam& operator=(
CTAPAuthenticatorRequestParam&& that);
~CTAPAuthenticatorRequestParam() override;
base::Optional<std::vector<uint8_t>> Encode() const override;
private:
explicit CTAPAuthenticatorRequestParam(CTAPRequestCommand cmd);
CTAPRequestCommand cmd_;
DISALLOW_COPY_AND_ASSIGN(CTAPAuthenticatorRequestParam);
};
} // namespace device
#endif // DEVICE_CTAP_CTAP_AUTHENTICATOR_REQUEST_PARAM_H_
......@@ -26,8 +26,8 @@ CTAPGetAssertionRequestParam& CTAPGetAssertionRequestParam::operator=(
CTAPGetAssertionRequestParam::~CTAPGetAssertionRequestParam() = default;
base::Optional<std::vector<uint8_t>>
CTAPGetAssertionRequestParam::SerializeToCBOR() const {
base::Optional<std::vector<uint8_t>> CTAPGetAssertionRequestParam::Encode()
const {
cbor::CBORValue::MapValue cbor_map;
cbor_map[cbor::CBORValue(1)] = cbor::CBORValue(rp_id_);
cbor_map[cbor::CBORValue(2)] = cbor::CBORValue(client_data_hash_);
......@@ -48,18 +48,11 @@ CTAPGetAssertionRequestParam::SerializeToCBOR() const {
cbor_map[cbor::CBORValue(7)] = cbor::CBORValue(*pin_protocol_);
}
auto user_presence = user_presence_required_
? cbor::CBORValue::SimpleValue::TRUE_VALUE
: cbor::CBORValue::SimpleValue::FALSE_VALUE;
auto user_verification = user_verification_required_
? cbor::CBORValue::SimpleValue::TRUE_VALUE
: cbor::CBORValue::SimpleValue::FALSE_VALUE;
cbor::CBORValue::MapValue option_map;
option_map[cbor::CBORValue(kUserPresenceMapKey)] =
cbor::CBORValue(user_presence);
cbor::CBORValue(user_presence_required_);
option_map[cbor::CBORValue(kUserVerificationMapKey)] =
cbor::CBORValue(user_verification);
cbor::CBORValue(user_verification_required_);
cbor_map[cbor::CBORValue(7)] = cbor::CBORValue(std::move(option_map));
auto serialized_param =
......
......@@ -26,7 +26,7 @@ class CTAPGetAssertionRequestParam : public CTAPRequestParam {
CTAPGetAssertionRequestParam& operator=(CTAPGetAssertionRequestParam&& other);
~CTAPGetAssertionRequestParam() override;
base::Optional<std::vector<uint8_t>> SerializeToCBOR() const override;
base::Optional<std::vector<uint8_t>> Encode() const override;
CTAPGetAssertionRequestParam& SetUserVerificationRequired(
bool user_verfication_required);
CTAPGetAssertionRequestParam& SetUserPresenceRequired(
......
......@@ -30,8 +30,8 @@ CTAPMakeCredentialRequestParam& CTAPMakeCredentialRequestParam::operator=(
CTAPMakeCredentialRequestParam::~CTAPMakeCredentialRequestParam() = default;
base::Optional<std::vector<uint8_t>>
CTAPMakeCredentialRequestParam::SerializeToCBOR() const {
base::Optional<std::vector<uint8_t>> CTAPMakeCredentialRequestParam::Encode()
const {
cbor::CBORValue::MapValue cbor_map;
cbor_map[cbor::CBORValue(1)] = cbor::CBORValue(client_data_hash_);
cbor_map[cbor::CBORValue(2)] = rp_.ConvertToCBOR();
......@@ -53,17 +53,11 @@ CTAPMakeCredentialRequestParam::SerializeToCBOR() const {
cbor_map[cbor::CBORValue(9)] = cbor::CBORValue(*pin_protocol_);
}
auto resident_key = resident_key_ ? cbor::CBORValue::SimpleValue::TRUE_VALUE
: cbor::CBORValue::SimpleValue::FALSE_VALUE;
auto user_verification_required =
user_verification_required_ ? cbor::CBORValue::SimpleValue::TRUE_VALUE
: cbor::CBORValue::SimpleValue::FALSE_VALUE;
cbor::CBORValue::MapValue option_map;
option_map[cbor::CBORValue(kResidentKeyMapKey)] =
cbor::CBORValue(resident_key);
cbor::CBORValue(resident_key_);
option_map[cbor::CBORValue(kUserVerificationMapKey)] =
cbor::CBORValue(user_verification_required);
cbor::CBORValue(user_verification_required_);
cbor_map[cbor::CBORValue(7)] = cbor::CBORValue(std::move(option_map));
auto serialized_param =
......
......@@ -33,7 +33,7 @@ class CTAPMakeCredentialRequestParam : public CTAPRequestParam {
CTAPMakeCredentialRequestParam&& that);
~CTAPMakeCredentialRequestParam() override;
base::Optional<std::vector<uint8_t>> SerializeToCBOR() const override;
base::Optional<std::vector<uint8_t>> Encode() const override;
CTAPMakeCredentialRequestParam& SetUserVerificationRequired(
bool user_verfication_required);
CTAPMakeCredentialRequestParam& SetResidentKey(bool resident_key);
......
......@@ -16,7 +16,7 @@ class CTAPRequestParam {
public:
CTAPRequestParam();
virtual ~CTAPRequestParam();
virtual base::Optional<std::vector<uint8_t>> SerializeToCBOR() const = 0;
virtual base::Optional<std::vector<uint8_t>> Encode() const = 0;
};
} // namespace device
......
......@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/ctap/ctap_authenticator_request_param.h"
#include "device/ctap/ctap_get_assertion_request_param.h"
#include "device/ctap/ctap_make_credential_request_param.h"
#include "device/ctap/ctap_request_param.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -13,17 +13,17 @@ namespace device {
// Leveraging example 4 of section 6.1 of the spec
// https://fidoalliance.org/specs/fido-v2.0-rd-20170927/fido-client-to-authenticator-protocol-v2.0-rd-20170927.html
TEST(CTAPRequestTest, TestConstructMakeCredentialRequestParam) {
const std::vector<uint8_t> kClientDataHash = {
static constexpr uint8_t kClientDataHash[] = {
0x68, 0x71, 0x34, 0x96, 0x82, 0x22, 0xec, 0x17, 0x20, 0x2e, 0x42,
0x50, 0x5f, 0x8e, 0xd2, 0xb1, 0x6a, 0xe2, 0x2f, 0x16, 0xbb, 0x05,
0xb8, 0x8c, 0x25, 0xdb, 0x9e, 0x60, 0x26, 0x45, 0xf1, 0x41};
const std::vector<uint8_t> kUserId = {
static constexpr uint8_t kUserId[] = {
0x30, 0x82, 0x01, 0x93, 0x30, 0x82, 0x01, 0x38, 0xa0, 0x03, 0x02,
0x01, 0x02, 0x30, 0x82, 0x01, 0x93, 0x30, 0x82, 0x01, 0x38, 0xa0,
0x03, 0x02, 0x01, 0x02, 0x30, 0x82, 0x01, 0x93, 0x30, 0x82};
const std::vector<uint8_t> kSerializedRequest = {
static constexpr uint8_t kSerializedRequest[] = {
// clang format-off
0x01, // authenticatorMakeCredential command
0xa5, // map(5)
......@@ -111,28 +111,30 @@ TEST(CTAPRequestTest, TestConstructMakeCredentialRequestParam) {
PublicKeyCredentialRPEntity rp("acme.com");
rp.SetRPName("Acme");
PublicKeyCredentialUserEntity user(kUserId);
PublicKeyCredentialUserEntity user(
std::vector<uint8_t>(kUserId, std::end(kUserId)));
user.SetUserName("johnpsmith@example.com")
.SetDisplayName("John P. Smith")
.SetIconUrl(GURL("https://pics.acme.com/00/p/aBjjjpqPb.png"));
CTAPMakeCredentialRequestParam make_credential_param(
kClientDataHash, std::move(rp), std::move(user),
std::vector<uint8_t>(kClientDataHash, std::end(kClientDataHash)),
std::move(rp), std::move(user),
PublicKeyCredentialParams({{"public-key", 7}, {"public-key", 257}}));
auto serialized_data = make_credential_param.SetResidentKey(true)
.SetUserVerificationRequired(true)
.SerializeToCBOR();
.Encode();
ASSERT_TRUE(serialized_data);
EXPECT_THAT(*serialized_data, testing::ElementsAreArray(kSerializedRequest));
}
TEST(CTAPRequestTest, TestConstructGetAssertionRequest) {
const std::vector<uint8_t> kClientDataHash = {
static constexpr uint8_t kClientDataHash[] = {
0x68, 0x71, 0x34, 0x96, 0x82, 0x22, 0xec, 0x17, 0x20, 0x2e, 0x42,
0x50, 0x5f, 0x8e, 0xd2, 0xb1, 0x6a, 0xe2, 0x2f, 0x16, 0xbb, 0x05,
0xb8, 0x8c, 0x25, 0xdb, 0x9e, 0x60, 0x26, 0x45, 0xf1, 0x41};
static const uint8_t kSerializedRequest[] = {
static constexpr uint8_t kSerializedRequest[] = {
// clang format-off
0x02, // authenticatorGetAssertion command
0xa4, // map(4)
......@@ -195,7 +197,10 @@ TEST(CTAPRequestTest, TestConstructGetAssertionRequest) {
// clang format-on
};
CTAPGetAssertionRequestParam get_assertion_req("acme.com", kClientDataHash);
CTAPGetAssertionRequestParam get_assertion_req(
"acme.com",
std::vector<uint8_t>(kClientDataHash, std::end(kClientDataHash)));
std::vector<PublicKeyCredentialDescriptor> allowed_list;
allowed_list.push_back(PublicKeyCredentialDescriptor(
"public-key",
......@@ -217,9 +222,35 @@ TEST(CTAPRequestTest, TestConstructGetAssertionRequest) {
.SetUserPresenceRequired(true)
.SetUserVerificationRequired(true);
auto serialized_data = get_assertion_req.SerializeToCBOR();
auto serialized_data = get_assertion_req.Encode();
ASSERT_TRUE(serialized_data);
EXPECT_THAT(*serialized_data, testing::ElementsAreArray(kSerializedRequest));
}
TEST(CTAPRequestTest, TestConstructCtapAuthenticatorRequestParam) {
static constexpr uint8_t kSerializedGetInfoCmd = 0x04;
static constexpr uint8_t kSerializedGetNextAssertionCmd = 0x08;
static constexpr uint8_t kSerializedCancelCmd = 0x03;
static constexpr uint8_t kSerializedResetCmd = 0x07;
auto get_info_cmd =
CTAPAuthenticatorRequestParam::CreateGetInfoParam().Encode();
ASSERT_TRUE(get_info_cmd);
EXPECT_THAT(*get_info_cmd, testing::ElementsAre(kSerializedGetInfoCmd));
auto get_next_assertion_cmd =
CTAPAuthenticatorRequestParam::CreateGetNextAssertionParam().Encode();
ASSERT_TRUE(get_next_assertion_cmd);
EXPECT_THAT(*get_next_assertion_cmd,
testing::ElementsAre(kSerializedGetNextAssertionCmd));
auto cancel_cmd = CTAPAuthenticatorRequestParam::CreateCancelParam().Encode();
ASSERT_TRUE(cancel_cmd);
EXPECT_THAT(*cancel_cmd, testing::ElementsAre(kSerializedCancelCmd));
auto reset_cmd = CTAPAuthenticatorRequestParam::CreateResetParam().Encode();
ASSERT_TRUE(reset_cmd);
EXPECT_THAT(*reset_cmd, testing::ElementsAre(kSerializedResetCmd));
}
} // namespace device
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment