| // Copyright 2017 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_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" |
| |
| 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 = { |
| 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 = { |
| 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 = { |
| // clang format-off |
| 0x01, // authenticatorMakeCredential command |
| 0xa4, // map(4) |
| 0x01, // clientDataHash |
| 0x58, 0x20, // bytes(32) |
| 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, |
| |
| 0x02, // unsigned(2) - rp |
| 0xa2, // map(2) |
| 0x62, // text(2) |
| 0x69, 0x64, // "id" |
| 0x68, // text(8) |
| // "acme.com" |
| 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x63, 0x6f, 0x6d, |
| 0x64, // text(4) |
| 0x6e, 0x61, 0x6d, 0x65, // "name" |
| 0x64, // text(4) |
| 0x41, 0x63, 0x6d, 0x65, // "Acme" |
| |
| 0x03, // unsigned(3) - user |
| 0xa4, // map(4) |
| 0x62, // text(2) |
| 0x69, 0x64, // "id" |
| 0x58, 0x20, // bytes(32) - user id |
| 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, |
| 0x64, // text(4) |
| 0x69, 0x63, 0x6f, 0x6e, // "icon" |
| 0x78, 0x28, // text(40) |
| // "https://pics.acme.com/00/p/aBjjjpqPb.png" |
| 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x70, 0x69, 0x63, 0x73, |
| 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x30, |
| 0x2f, 0x70, 0x2f, 0x61, 0x42, 0x6a, 0x6a, 0x6a, 0x70, 0x71, 0x50, 0x62, |
| 0x2e, 0x70, 0x6e, 0x67, |
| 0x64, // text(4) |
| 0x6e, 0x61, 0x6d, 0x65, // "name" |
| 0x76, // text(22) |
| // "johnpsmith@example.com" |
| 0x6a, 0x6f, 0x68, 0x6e, 0x70, 0x73, 0x6d, 0x69, 0x74, 0x68, 0x40, 0x65, |
| 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, |
| 0x6b, // text(11) |
| // "displayName" |
| 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, |
| 0x6d, // text(13) |
| // "John P. Smith" |
| 0x4a, 0x6f, 0x68, 0x6e, 0x20, 0x50, 0x2e, 0x20, 0x53, 0x6d, 0x69, 0x74, |
| 0x68, |
| |
| 0x04, // unsigned(4) - pubKeyCredParams |
| 0x82, // array(2) |
| 0xa2, // map(2) |
| 0x63, // text(3) |
| 0x61, 0x6c, 0x67, // "alg" |
| 0x07, // 7 |
| 0x64, // text(4) |
| 0x74, 0x79, 0x70, 0x65, // "type" |
| 0x6a, // text(10) |
| // "public-key" |
| 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x2D, 0x6B, 0x65, 0x79, |
| 0xa2, // map(2) |
| 0x63, // text(3) |
| 0x61, 0x6c, 0x67, // "alg" |
| 0x19, 0x01, 0x01, // 257 |
| 0x64, // text(4) |
| 0x74, 0x79, 0x70, 0x65, // "type" |
| 0x6a, // text(10) |
| // "public-key" |
| 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x2D, 0x6B, 0x65, 0x79 |
| // clang format-on |
| }; |
| |
| PublicKeyCredentialRPEntity rp("acme.com"); |
| rp.SetRPName("Acme"); |
| |
| PublicKeyCredentialUserEntity user(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), |
| PublicKeyCredentialParams({{"public-key", 7}, {"public-key", 257}})); |
| auto serialized_data = make_credential_param.SerializeToCBOR(); |
| ASSERT_TRUE(serialized_data); |
| EXPECT_THAT(*serialized_data, testing::ElementsAreArray(kSerializedRequest)); |
| } |
| |
| TEST(CTAPRequestTest, TestConstructGetAssertionRequest) { |
| const std::vector<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[] = { |
| // clang format-off |
| 0x02, // authenticatorGetAssertion command |
| 0xa3, // map(3) |
| |
| 0x01, // rpId |
| 0x68, // text(8) |
| // "acme.com" |
| 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x63, 0x6f, 0x6d, |
| |
| 0x02, // unsigned(2) - client data hash |
| 0x58, 0x20, // bytes(32) |
| 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, |
| |
| 0x03, // unsigned(3) - allow list |
| 0x82, // array(2) |
| 0xa2, // map(2) |
| 0x62, // text(2) |
| 0x69, 0x64, // "id" |
| 0x58, 0x40, |
| // credential ID |
| 0xf2, 0x20, 0x06, 0xde, 0x4f, 0x90, 0x5a, 0xf6, 0x8a, 0x43, 0x94, 0x2f, |
| 0x02, 0x4f, 0x2a, 0x5e, 0xce, 0x60, 0x3d, 0x9c, 0x6d, 0x4b, 0x3d, 0xf8, |
| 0xbe, 0x08, 0xed, 0x01, 0xfc, 0x44, 0x26, 0x46, 0xd0, 0x34, 0x85, 0x8a, |
| 0xc7, 0x5b, 0xed, 0x3f, 0xd5, 0x80, 0xbf, 0x98, 0x08, 0xd9, 0x4f, 0xcb, |
| 0xee, 0x82, 0xb9, 0xb2, 0xef, 0x66, 0x77, 0xaf, 0x0a, 0xdc, 0xc3, 0x58, |
| 0x52, 0xea, 0x6b, 0x9e, |
| |
| 0x64, // text(4) |
| 0x74, 0x79, 0x70, 0x65, // "type" |
| 0x6a, // text(10) |
| // "public-key" |
| 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x2D, 0x6B, 0x65, 0x79, |
| 0xa2, // map(2) |
| 0x62, // text(2) |
| 0x69, 0x64, // "id" |
| 0x58, 0x32, // text(22) |
| // credential ID |
| 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, |
| 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, |
| 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, |
| 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, |
| 0x03, 0x03, |
| 0x64, // text(4) |
| 0x74, 0x79, 0x70, 0x65, // "type" |
| 0x6a, // text(10) |
| // "public-key" |
| 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x2D, 0x6B, 0x65, 0x79, |
| // clang format-on |
| }; |
| |
| CTAPGetAssertionRequestParam get_assertion_req("acme.com", kClientDataHash); |
| std::vector<PublicKeyCredentialDescriptor> allowed_list; |
| allowed_list.push_back(PublicKeyCredentialDescriptor( |
| "public-key", |
| {0xf2, 0x20, 0x06, 0xde, 0x4f, 0x90, 0x5a, 0xf6, 0x8a, 0x43, 0x94, |
| 0x2f, 0x02, 0x4f, 0x2a, 0x5e, 0xce, 0x60, 0x3d, 0x9c, 0x6d, 0x4b, |
| 0x3d, 0xf8, 0xbe, 0x08, 0xed, 0x01, 0xfc, 0x44, 0x26, 0x46, 0xd0, |
| 0x34, 0x85, 0x8a, 0xc7, 0x5b, 0xed, 0x3f, 0xd5, 0x80, 0xbf, 0x98, |
| 0x08, 0xd9, 0x4f, 0xcb, 0xee, 0x82, 0xb9, 0xb2, 0xef, 0x66, 0x77, |
| 0xaf, 0x0a, 0xdc, 0xc3, 0x58, 0x52, 0xea, 0x6b, 0x9e})); |
| allowed_list.push_back(PublicKeyCredentialDescriptor( |
| "public-key", |
| {0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, |
| 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, |
| 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, |
| 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, |
| 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03})); |
| |
| get_assertion_req.SetAllowList(std::move(allowed_list)); |
| |
| auto serialized_data = get_assertion_req.SerializeToCBOR(); |
| ASSERT_TRUE(serialized_data); |
| EXPECT_THAT(*serialized_data, testing::ElementsAreArray(kSerializedRequest)); |
| } |
| |
| } // namespace device |