#include <gtest/gtest.h>
namespace {
-template <typename T>
-void AssertEq(const T &left, const T &right)
-{
- ASSERT_EQ(left, right);
-}
-
-template <typename T>
-void AssertEq(const T &left, const uint8_t *rightData, size_t rightSize)
-{
- ASSERT_EQ(BufferView(reinterpret_cast<const uint8_t *>(left.data()), left.size()),
- BufferView(rightData, rightSize));
-}
// from chromium/device/fido/fido_test_data.h
constexpr inline uint8_t SAMPLE_MAKE_CREDENTIAL_REQUEST[] = {
auto view = BUFFER_VIEW(IPHONE_EXAMPLE_POST_HANDSHAKE_RAW_RESPONSE);
ASSERT_NO_THROW(msg.Deserialize(view));
- AssertEq(msg.m_versions, {"FIDO_2_0", "FIDO_2_1"});
- AssertEq(msg.m_extensions, {"largeBlob"});
- AssertEq(msg.m_aaguid,
- {0xf2,
- 0x4a,
- 0x8e,
- 0x70,
- 0xd0,
- 0xd3,
- 0xf8,
- 0x2c,
- 0x29,
- 0x37,
- 0x32,
- 0x52,
- 0x3c,
- 0xc4,
- 0xde,
- 0x5a});
- ASSERT_TRUE(msg.m_options.uv);
- ASSERT_TRUE(msg.m_options.rk);
- ASSERT_FALSE(msg.m_maxMsgSize.has_value());
- ASSERT_TRUE(msg.m_pinUvAuthProtocols.empty());
- ASSERT_FALSE(msg.m_maxCredentialCountInList.has_value());
- ASSERT_FALSE(msg.m_maxCredentialIdLength.has_value());
- AssertEq(msg.m_transports, {"internal", "hybrid"});
- ASSERT_TRUE(msg.m_algorithms.empty());
- ASSERT_FALSE(msg.m_maxSerializedLargeBlobArray.has_value());
- ASSERT_FALSE(msg.m_forcePINChange.has_value());
- ASSERT_FALSE(msg.m_minPINLength.has_value());
- ASSERT_FALSE(msg.m_firmwareVersion.has_value());
- ASSERT_FALSE(msg.m_maxCredBlobLength.has_value());
- ASSERT_FALSE(msg.m_maxRPIDsForSetMinPINLength.has_value());
- ASSERT_FALSE(msg.m_preferredPlatformUvAttempts.has_value());
- ASSERT_FALSE(msg.m_uvModality.has_value());
- ASSERT_TRUE(msg.m_certifications.empty());
- ASSERT_FALSE(msg.m_remainingDiscoverableCredentials.has_value());
- ASSERT_TRUE(msg.m_vendorPrototypeConfigCommands.empty());
- ASSERT_TRUE(msg.m_attestationFormats.empty());
- ASSERT_FALSE(msg.m_uvCountSinceLastPinEntry.has_value());
- ASSERT_FALSE(msg.m_longTouchForReset.has_value());
+ EXPECT_EQ(msg.m_versions, (std::vector<std::string>{"FIDO_2_0", "FIDO_2_1"}));
+ EXPECT_EQ(msg.m_extensions, std::vector<std::string>{"largeBlob"});
+ EXPECT_EQ(ToBufferView(msg.m_aaguid),
+ BUFFER_VIEW("\xf2\x4a\x8e\x70\xd0\xd3\xf8\x2c\x29\x37\x32\x52\x3c\xc4\xde\x5a"));
+ EXPECT_TRUE(msg.m_options.uv);
+ EXPECT_TRUE(msg.m_options.rk);
+ EXPECT_EQ(msg.m_maxMsgSize, std::nullopt);
+ EXPECT_EQ(msg.m_pinUvAuthProtocols, std::vector<uint64_t>{});
+ EXPECT_EQ(msg.m_maxCredentialCountInList, std::nullopt);
+ EXPECT_EQ(msg.m_maxCredentialIdLength, std::nullopt);
+ EXPECT_EQ(msg.m_transports, (std::vector<std::string>{"internal", "hybrid"}));
+ EXPECT_EQ(msg.m_algorithms.size(), 0);
+ EXPECT_EQ(msg.m_maxSerializedLargeBlobArray, std::nullopt);
+ EXPECT_EQ(msg.m_forcePINChange, std::nullopt);
+ EXPECT_EQ(msg.m_minPINLength, std::nullopt);
+ EXPECT_EQ(msg.m_firmwareVersion, std::nullopt);
+ EXPECT_EQ(msg.m_maxCredBlobLength, std::nullopt);
+ EXPECT_EQ(msg.m_maxRPIDsForSetMinPINLength, std::nullopt);
+ EXPECT_EQ(msg.m_preferredPlatformUvAttempts, std::nullopt);
+ EXPECT_EQ(msg.m_uvModality, std::nullopt);
+ EXPECT_EQ(msg.m_certifications, (std::unordered_map<std::string, uint64_t>{}));
+ EXPECT_EQ(msg.m_remainingDiscoverableCredentials, std::nullopt);
+ EXPECT_EQ(msg.m_vendorPrototypeConfigCommands, std::vector<uint64_t>{});
+ EXPECT_EQ(msg.m_attestationFormats, std::vector<std::string>{});
+ EXPECT_EQ(msg.m_uvCountSinceLastPinEntry, std::nullopt);
+ EXPECT_EQ(msg.m_longTouchForReset, std::nullopt);
}
TEST(Messages, ParsePostHandshakeMessage2)
auto view = BUFFER_VIEW(ANDROID_EXAMPLE_POST_HANDSHAKE_RAW_RESPONSE);
ASSERT_NO_THROW(msg.Deserialize(view));
- AssertEq(msg.m_versions, {"FIDO_2_0", "FIDO_2_1"});
- AssertEq(msg.m_extensions, {"prf"});
- AssertEq(msg.m_aaguid, Buffer(16, 0x00));
- ASSERT_TRUE(msg.m_options.uv);
- ASSERT_TRUE(msg.m_options.rk);
- ASSERT_FALSE(msg.m_maxMsgSize.has_value());
- ASSERT_TRUE(msg.m_pinUvAuthProtocols.empty());
- ASSERT_FALSE(msg.m_maxCredentialCountInList.has_value());
- ASSERT_FALSE(msg.m_maxCredentialIdLength.has_value());
- AssertEq(msg.m_transports, {"internal", "hybrid"});
- ASSERT_TRUE(msg.m_algorithms.empty());
- ASSERT_FALSE(msg.m_maxSerializedLargeBlobArray.has_value());
- ASSERT_FALSE(msg.m_forcePINChange.has_value());
- ASSERT_FALSE(msg.m_minPINLength.has_value());
- ASSERT_FALSE(msg.m_firmwareVersion.has_value());
- ASSERT_FALSE(msg.m_maxCredBlobLength.has_value());
- ASSERT_FALSE(msg.m_maxRPIDsForSetMinPINLength.has_value());
- ASSERT_FALSE(msg.m_preferredPlatformUvAttempts.has_value());
- ASSERT_FALSE(msg.m_uvModality.has_value());
- ASSERT_TRUE(msg.m_certifications.empty());
- ASSERT_FALSE(msg.m_remainingDiscoverableCredentials.has_value());
- ASSERT_TRUE(msg.m_vendorPrototypeConfigCommands.empty());
- ASSERT_TRUE(msg.m_attestationFormats.empty());
- ASSERT_FALSE(msg.m_uvCountSinceLastPinEntry.has_value());
- ASSERT_FALSE(msg.m_longTouchForReset.has_value());
+ EXPECT_EQ(msg.m_versions, (std::vector<std::string>{"FIDO_2_0", "FIDO_2_1"}));
+ EXPECT_EQ(msg.m_extensions, std::vector<std::string>{"prf"});
+ EXPECT_EQ(msg.m_aaguid, Buffer(16, 0x00));
+ EXPECT_TRUE(msg.m_options.uv);
+ EXPECT_TRUE(msg.m_options.rk);
+ EXPECT_EQ(msg.m_maxMsgSize, std::nullopt);
+ EXPECT_EQ(msg.m_pinUvAuthProtocols, std::vector<uint64_t>{});
+ EXPECT_EQ(msg.m_maxCredentialCountInList, std::nullopt);
+ EXPECT_EQ(msg.m_maxCredentialIdLength, std::nullopt);
+ EXPECT_EQ(msg.m_transports, (std::vector<std::string>{"internal", "hybrid"}));
+ EXPECT_EQ(msg.m_algorithms.size(), 0);
+ EXPECT_EQ(msg.m_maxSerializedLargeBlobArray, std::nullopt);
+ EXPECT_EQ(msg.m_forcePINChange, std::nullopt);
+ EXPECT_EQ(msg.m_minPINLength, std::nullopt);
+ EXPECT_EQ(msg.m_firmwareVersion, std::nullopt);
+ EXPECT_EQ(msg.m_maxCredBlobLength, std::nullopt);
+ EXPECT_EQ(msg.m_maxRPIDsForSetMinPINLength, std::nullopt);
+ EXPECT_EQ(msg.m_preferredPlatformUvAttempts, std::nullopt);
+ EXPECT_EQ(msg.m_uvModality, std::nullopt);
+ EXPECT_EQ(msg.m_certifications, (std::unordered_map<std::string, uint64_t>{}));
+ EXPECT_EQ(msg.m_remainingDiscoverableCredentials, std::nullopt);
+ EXPECT_EQ(msg.m_vendorPrototypeConfigCommands, std::vector<uint64_t>{});
+ EXPECT_EQ(msg.m_attestationFormats, std::vector<std::string>{});
+ EXPECT_EQ(msg.m_uvCountSinceLastPinEntry, std::nullopt);
+ EXPECT_EQ(msg.m_longTouchForReset, std::nullopt);
}
TEST(Messages, DomainName)
tooLongDomain.resize(254);
assert(tooLongDomain.back() != '.');
- ASSERT_NO_THROW(ValidateDomain("acme"));
- ASSERT_NO_THROW(ValidateDomain("acme.com"));
- ASSERT_NO_THROW(ValidateDomain("acme.acme.com"));
- ASSERT_NO_THROW(ValidateDomain("a-cme.acme.com"));
- ASSERT_NO_THROW(ValidateDomain("a-cme.ac-me.com"));
- ASSERT_NO_THROW(ValidateDomain("a-cme.ac-me.c-om"));
- ASSERT_NO_THROW(ValidateDomain("a-c5me.ac-me.c-om"));
- ASSERT_NO_THROW(ValidateDomain("a-c5me.ac-5me.c-om"));
- ASSERT_NO_THROW(ValidateDomain("a-c5me.ac-m5e.c-5om"));
- ASSERT_NO_THROW(ValidateDomain("a-c5me.ac-m5e.c--5om"));
- ASSERT_NO_THROW(ValidateDomain(notTooLongLabel.c_str()));
- ASSERT_NO_THROW(ValidateDomain(tooLongDomain.c_str() + 1));
- ASSERT_THROW(ValidateDomain(nullptr), Exception::InvalidParam);
- ASSERT_THROW(ValidateDomain("acme."), Exception::InvalidParam);
- ASSERT_THROW(ValidateDomain(".acme"), Exception::InvalidParam);
- ASSERT_THROW(ValidateDomain("-acme.com"), Exception::InvalidParam);
- ASSERT_THROW(ValidateDomain("acme..com"), Exception::InvalidParam);
- ASSERT_THROW(ValidateDomain("acme-.com"), Exception::InvalidParam);
- ASSERT_THROW(ValidateDomain("acme.-com"), Exception::InvalidParam);
- ASSERT_THROW(ValidateDomain("acme.com-"), Exception::InvalidParam);
- ASSERT_THROW(ValidateDomain("a_cme.com"), Exception::InvalidParam);
- ASSERT_THROW(ValidateDomain("a?cme.com"), Exception::InvalidParam);
- ASSERT_THROW(ValidateDomain(tooLongLabel.c_str()), Exception::InvalidParam);
- ASSERT_THROW(ValidateDomain(tooLongDomain.c_str()), Exception::InvalidParam);
+ EXPECT_NO_THROW(ValidateDomain("acme"));
+ EXPECT_NO_THROW(ValidateDomain("acme.com"));
+ EXPECT_NO_THROW(ValidateDomain("acme.acme.com"));
+ EXPECT_NO_THROW(ValidateDomain("a-cme.acme.com"));
+ EXPECT_NO_THROW(ValidateDomain("a-cme.ac-me.com"));
+ EXPECT_NO_THROW(ValidateDomain("a-cme.ac-me.c-om"));
+ EXPECT_NO_THROW(ValidateDomain("a-c5me.ac-me.c-om"));
+ EXPECT_NO_THROW(ValidateDomain("a-c5me.ac-5me.c-om"));
+ EXPECT_NO_THROW(ValidateDomain("a-c5me.ac-m5e.c-5om"));
+ EXPECT_NO_THROW(ValidateDomain("a-c5me.ac-m5e.c--5om"));
+ EXPECT_NO_THROW(ValidateDomain(notTooLongLabel.c_str()));
+ EXPECT_NO_THROW(ValidateDomain(tooLongDomain.c_str() + 1));
+ EXPECT_THROW(ValidateDomain(nullptr), Exception::InvalidParam);
+ EXPECT_THROW(ValidateDomain("acme."), Exception::InvalidParam);
+ EXPECT_THROW(ValidateDomain(".acme"), Exception::InvalidParam);
+ EXPECT_THROW(ValidateDomain("-acme.com"), Exception::InvalidParam);
+ EXPECT_THROW(ValidateDomain("acme..com"), Exception::InvalidParam);
+ EXPECT_THROW(ValidateDomain("acme-.com"), Exception::InvalidParam);
+ EXPECT_THROW(ValidateDomain("acme.-com"), Exception::InvalidParam);
+ EXPECT_THROW(ValidateDomain("acme.com-"), Exception::InvalidParam);
+ EXPECT_THROW(ValidateDomain("a_cme.com"), Exception::InvalidParam);
+ EXPECT_THROW(ValidateDomain("a?cme.com"), Exception::InvalidParam);
+ EXPECT_THROW(ValidateDomain(tooLongLabel.c_str()), Exception::InvalidParam);
+ EXPECT_THROW(ValidateDomain(tooLongDomain.c_str()), Exception::InvalidParam);
}
TEST(Messages, SerializeMakeCredential1)
ASSERT_NO_THROW(msg.Serialize(buffer));
- constexpr uint8_t blob[] =
- "\x01\x01\xa4\x01\x58\x20\x05\x4e\xde\xc1\xd0\x21\x1f\x62\x4f\xed\x0c\xbc\xa9\xd4\xf9\x40"
- "\x0b\x0e\x49\x1c\x43\x74\x2a\xf2\xc5\xb0\xab\xeb\xf0\xc9\x90\xd8\x02\xa2\x62\x69\x64\x65"
- "\x52\x70\x2e\x69\x64\x64\x6e\x61\x6d\x65\x67\x52\x70\x20\x6e\x61\x6d\x65\x03\xa3\x62\x69"
- "\x64\x48\x00\x01\x02\x03\x04\x05\x06\x07\x64\x6e\x61\x6d\x65\x69\x55\x73\x65\x72\x20\x6e"
- "\x61\x6d\x65\x6b\x64\x69\x73\x70\x6c\x61\x79\x4e\x61\x6d\x65\x71\x55\x73\x65\x72\x20\x64"
- "\x69\x73\x70\x6c\x61\x79\x20\x6e\x61\x6d\x65\x04\x8a\xa2\x63\x61\x6c\x67\x26\x64\x74\x79"
- "\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c\x67\x38\x22\x64\x74"
- "\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c\x67\x38\x23\x64"
- "\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c\x67\x27\x64"
- "\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c\x67\x38\x24"
- "\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c\x67\x38"
- "\x25\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c\x67"
- "\x38\x26\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c"
- "\x67\x39\x01\x00\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63"
- "\x61\x6c\x67\x39\x01\x01\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79"
- "\xa2\x63\x61\x6c\x67\x39\x01\x02\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b"
- "\x65\x79";
- AssertEq(buffer, blob, sizeof(blob) - 1);
+ EXPECT_EQ(
+ ToBufferView(buffer),
+ BUFFER_VIEW(
+ "\x01\x01\xa4\x01\x58\x20\x05\x4e\xde\xc1\xd0\x21\x1f\x62\x4f\xed\x0c\xbc\xa9\xd4\xf9"
+ "\x40\x0b\x0e\x49\x1c\x43\x74\x2a\xf2\xc5\xb0\xab\xeb\xf0\xc9\x90\xd8\x02\xa2\x62\x69"
+ "\x64\x65\x52\x70\x2e\x69\x64\x64\x6e\x61\x6d\x65\x67\x52\x70\x20\x6e\x61\x6d\x65\x03"
+ "\xa3\x62\x69\x64\x48\x00\x01\x02\x03\x04\x05\x06\x07\x64\x6e\x61\x6d\x65\x69\x55\x73"
+ "\x65\x72\x20\x6e\x61\x6d\x65\x6b\x64\x69\x73\x70\x6c\x61\x79\x4e\x61\x6d\x65\x71\x55"
+ "\x73\x65\x72\x20\x64\x69\x73\x70\x6c\x61\x79\x20\x6e\x61\x6d\x65\x04\x8a\xa2\x63\x61"
+ "\x6c\x67\x26\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63"
+ "\x61\x6c\x67\x38\x22\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79"
+ "\xa2\x63\x61\x6c\x67\x38\x23\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b"
+ "\x65\x79\xa2\x63\x61\x6c\x67\x27\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d"
+ "\x6b\x65\x79\xa2\x63\x61\x6c\x67\x38\x24\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69"
+ "\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c\x67\x38\x25\x64\x74\x79\x70\x65\x6a\x70\x75\x62"
+ "\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c\x67\x38\x26\x64\x74\x79\x70\x65\x6a\x70"
+ "\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c\x67\x39\x01\x00\x64\x74\x79\x70"
+ "\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c\x67\x39\x01\x01\x64"
+ "\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\xa2\x63\x61\x6c\x67\x39"
+ "\x01\x02\x64\x74\x79\x70\x65\x6a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79"));
}
TEST(Messages, SerializeMakeCredential2)
MakeCredentialCommand msg(client_data, options, {false, false});
ASSERT_NO_THROW(msg.Serialize(buffer));
- AssertEq(buffer, SAMPLE_MAKE_CREDENTIAL_REQUEST, sizeof(SAMPLE_MAKE_CREDENTIAL_REQUEST));
+ EXPECT_EQ(ToBufferView(buffer),
+ (BufferView{SAMPLE_MAKE_CREDENTIAL_REQUEST, sizeof(SAMPLE_MAKE_CREDENTIAL_REQUEST)}));
}
TEST(Messages, SerializeGetAssertion)
GetAssertionCommand msg(client_data, options, {false, false});
ASSERT_NO_THROW(msg.Serialize(buffer));
- AssertEq(buffer, SAMPLE_GET_ASSERTION_REQUEST, sizeof(SAMPLE_GET_ASSERTION_REQUEST));
+ EXPECT_EQ(ToBufferView(buffer),
+ (BufferView{SAMPLE_GET_ASSERTION_REQUEST, sizeof(SAMPLE_GET_ASSERTION_REQUEST)}));
}
TEST(Messages, ShutdownMessage)
{
- Buffer buffer;
-
ShutdownMessage shutdown;
+ Buffer buffer;
ASSERT_NO_THROW(shutdown.Serialize(buffer));
- AssertEq(buffer, {0x00});
+ EXPECT_EQ(ToBufferView(buffer), BUFFER_VIEW("\x00"));
}
-TEST(Messages, ParseMakeCredentialResponse1)
+TEST(Messages, ParseMakeCredentialResponseFromIphone)
{
MakeCredentialResponse msg;
auto view = BUFFER_VIEW(IPHONE_EXAMPLE_MAKE_CREDENTIAL_RAW_RESPONSE);
const auto *blob =
reinterpret_cast<const uint8_t *>(IPHONE_EXAMPLE_MAKE_CREDENTIAL_RAW_RESPONSE) + 1;
- ASSERT_EQ(msg.m_authDataRaw.size(), 152);
- AssertEq(msg.m_authDataRaw, blob + 11, msg.m_authDataRaw.size());
- AssertEq(msg.m_authData.m_rpIdHash, blob + 11, 32);
- ASSERT_NO_THROW(VerifyRpIdHash("acme.com", msg.m_authData.m_rpIdHash));
- ASSERT_EQ(msg.m_authData.m_flags, blob[43]);
- ASSERT_TRUE(msg.m_authData.m_attestationData.has_value());
- AssertEq(msg.m_authData.m_attestationData->m_credentialId, blob + 66, 20);
- ASSERT_EQ(msg.m_authData.m_attestationData->m_publicKeyDer,
+ EXPECT_EQ(ToBufferView(msg.m_authDataRaw), (BufferView{blob + 11, 152}));
+ EXPECT_EQ(msg.m_authData.m_rpIdHash, (BufferView{blob + 11, 32}));
+ EXPECT_NO_THROW(VerifyRpIdHash("acme.com", msg.m_authData.m_rpIdHash));
+ EXPECT_EQ(msg.m_authData.m_flags, blob[43]);
+ ASSERT_NE(msg.m_authData.m_attestationData, std::nullopt);
+ EXPECT_EQ(msg.m_authData.m_attestationData->m_credentialId, (BufferView{blob + 66, 20}));
+ EXPECT_EQ(msg.m_authData.m_attestationData->m_publicKeyDer,
BUFFER(IPHONE_EXAMPLE_MAKE_CREDENTIAL_RAW_RESPONSE_PUBLIC_KEY_DER));
- ASSERT_EQ(msg.m_authData.m_attestationData->m_alg,
+ EXPECT_EQ(msg.m_authData.m_attestationData->m_alg,
WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256);
- AssertEq(msg.m_attestationObject, view.data(), view.size());
- ASSERT_EQ(msg.m_format, "none");
- ASSERT_FALSE(msg.m_epAtt.has_value());
- ASSERT_TRUE(msg.m_largeBlobKey.empty());
+ EXPECT_EQ(ToBufferView(msg.m_attestationObject), view);
+ EXPECT_EQ(msg.m_format, "none");
+ EXPECT_EQ(msg.m_epAtt, std::nullopt);
+ EXPECT_EQ(msg.m_largeBlobKey, Buffer{});
}
-TEST(Messages, ParseMakeCredentialResponse2)
+TEST(Messages, ParseMakeCredentialResponseFromAndroid)
{
MakeCredentialResponse msg;
auto view = BUFFER_VIEW(ANDROID_EXAMPLE_MAKE_CREDENTIAL_RAW_RESPONSE);
const auto *blob =
reinterpret_cast<const uint8_t *>(ANDROID_EXAMPLE_MAKE_CREDENTIAL_RAW_RESPONSE) + 1;
- ASSERT_EQ(msg.m_authDataRaw.size(), 164);
- AssertEq(msg.m_authDataRaw, blob + 11, msg.m_authDataRaw.size());
- AssertEq(msg.m_authData.m_rpIdHash, blob + 11, 32);
- ASSERT_NO_THROW(VerifyRpIdHash("acme.com", msg.m_authData.m_rpIdHash));
- ASSERT_EQ(msg.m_authData.m_flags, blob[43]);
- ASSERT_TRUE(msg.m_authData.m_attestationData.has_value());
- AssertEq(msg.m_authData.m_attestationData->m_credentialId, blob + 66, 32);
- ASSERT_EQ(msg.m_authData.m_attestationData->m_publicKeyDer,
+ EXPECT_EQ(ToBufferView(msg.m_authDataRaw), (BufferView{blob + 11, 164}));
+ EXPECT_EQ(msg.m_authData.m_rpIdHash, (BufferView{blob + 11, 32}));
+ EXPECT_NO_THROW(VerifyRpIdHash("acme.com", msg.m_authData.m_rpIdHash));
+ EXPECT_EQ(msg.m_authData.m_flags, blob[43]);
+ ASSERT_NE(msg.m_authData.m_attestationData, std::nullopt);
+ EXPECT_EQ(msg.m_authData.m_attestationData->m_credentialId, (BufferView{blob + 66, 32}));
+ EXPECT_EQ(msg.m_authData.m_attestationData->m_publicKeyDer,
BUFFER(ANDROID_EXAMPLE_MAKE_CREDENTIAL_RAW_RESPONSE_PUBLIC_KEY_DER));
- ASSERT_EQ(msg.m_authData.m_attestationData->m_alg,
+ EXPECT_EQ(msg.m_authData.m_attestationData->m_alg,
WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256);
- AssertEq(msg.m_attestationObject, view.data(), view.size());
- ASSERT_EQ(msg.m_format, "none");
- ASSERT_FALSE(msg.m_epAtt.has_value());
- ASSERT_TRUE(msg.m_largeBlobKey.empty());
+ EXPECT_EQ(ToBufferView(msg.m_attestationObject), view);
+ EXPECT_EQ(msg.m_format, "none");
+ EXPECT_EQ(msg.m_epAtt, std::nullopt);
+ EXPECT_EQ(msg.m_largeBlobKey, Buffer{});
}
-TEST(Messages, ParseGetAssertionResponse)
+TEST(Messages, ParseGetAssertionResponseFromIphone)
{
GetAssertionResponse msg;
auto view = BUFFER_VIEW(IPHONE_EXAMPLE_GET_ASSERTION_RAW_RESPONSE);
const auto *blob =
reinterpret_cast<const uint8_t *>(IPHONE_EXAMPLE_GET_ASSERTION_RAW_RESPONSE) + 1;
- ASSERT_GE(msg.m_authDataRaw.size(), 37);
- AssertEq(msg.m_authDataRaw, blob + 47, msg.m_authDataRaw.size());
- AssertEq(msg.m_authData.m_rpIdHash, blob + 47, 32);
- ASSERT_NO_THROW(VerifyRpIdHash("acme.com", msg.m_authData.m_rpIdHash));
- ASSERT_EQ(msg.m_authData.m_flags, blob[79]);
- ASSERT_FALSE(msg.m_authData.m_attestationData.has_value());
- AssertEq(msg.m_credentialId, blob + 8, 20);
- AssertEq(msg.m_signature, blob + 87, 72);
- AssertEq(msg.m_userId, blob + 165, 8);
- ASSERT_TRUE(msg.m_userName.empty());
- ASSERT_TRUE(msg.m_userDisplayName.empty());
+ EXPECT_EQ(ToBufferView(msg.m_authDataRaw), (BufferView{blob + 47, 37}));
+ EXPECT_EQ(msg.m_authData.m_rpIdHash, (BufferView{blob + 47, 32}));
+ EXPECT_NO_THROW(VerifyRpIdHash("acme.com", msg.m_authData.m_rpIdHash));
+ EXPECT_EQ(msg.m_authData.m_flags, blob[79]);
+ EXPECT_EQ(msg.m_authData.m_attestationData, std::nullopt);
+ EXPECT_EQ(ToBufferView(msg.m_credentialId), (BufferView{blob + 8, 20}));
+ EXPECT_EQ(ToBufferView(msg.m_userId), (BufferView{blob + 165, 8}));
+ EXPECT_EQ(msg.m_userName, "");
+ EXPECT_EQ(msg.m_userDisplayName, "");
+}
+
+TEST(Messages, ParseGetAssertionResponseFromAndroid)
+{
+ GetAssertionResponse msg;
+ auto view = BUFFER_VIEW(ANDROID_EXAMPLE_GET_ASSERTION_RAW_RESPONSE);
+ view.remove_prefix(1); // remove CTAP message type prefix
+ ASSERT_NO_THROW(msg.Deserialize(view));
+
+ const auto *blob =
+ reinterpret_cast<const uint8_t *>(ANDROID_EXAMPLE_GET_ASSERTION_RAW_RESPONSE) + 1;
+ EXPECT_EQ(ToBufferView(msg.m_authDataRaw), (BufferView{blob + 60, 37}));
+ EXPECT_EQ(msg.m_authData.m_rpIdHash, (BufferView{blob + 60, 32}));
+ EXPECT_NO_THROW(VerifyRpIdHash("acme.com", msg.m_authData.m_rpIdHash));
+ EXPECT_EQ(msg.m_authData.m_flags, blob[92]);
+ EXPECT_EQ(msg.m_authData.m_attestationData, std::nullopt);
+ EXPECT_EQ(ToBufferView(msg.m_credentialId), (BufferView{blob + 9, 32}));
+ EXPECT_EQ(msg.m_userId, Buffer{});
+ EXPECT_EQ(msg.m_userName, "");
+ EXPECT_EQ(msg.m_userDisplayName, "");
}
TEST(Messages, ParseUpdateMessage)
ASSERT_NO_THROW(msg.Deserialize(view));
auto linkDataOpt = msg.GetLinkData();
- ASSERT_TRUE(linkDataOpt.has_value());
+ ASSERT_NE(linkDataOpt, std::nullopt);
const auto &linkData = *linkDataOpt;
const auto *blob = reinterpret_cast<const uint8_t *>(ANDROID_EXAMPLE_RAW_UPDATE_MSG) + 1;
- AssertEq(linkData.m_contactId, blob + 184, 152);
- AssertEq(linkData.m_linkId, blob + 338, 8);
- AssertEq(linkData.m_linkSecret, blob + 349, 32);
- AssertEq(linkData.m_authenticatorPublicKey, blob + 384, 65);
- AssertEq(linkData.m_authenticatorName, blob + 451, 5);
- AssertEq(linkData.m_handshakeSignature, blob + 459, 32);
+ EXPECT_EQ(ToBufferView(linkData.m_contactId), (BufferView{blob + 184, 152}));
+ EXPECT_EQ(ToBufferView(linkData.m_linkId), (BufferView{blob + 338, 8}));
+ EXPECT_EQ(ToBufferView(linkData.m_linkSecret), (BufferView{blob + 349, 32}));
+ EXPECT_EQ(ToBufferView(linkData.m_authenticatorPublicKey), (BufferView{blob + 384, 65}));
+ EXPECT_EQ(ToBufferView(linkData.m_authenticatorName), (BufferView{blob + 451, 5}));
+ EXPECT_EQ(ToBufferView(linkData.m_handshakeSignature), (BufferView{blob + 459, 32}));
}