Update message parsing 43/307943/13
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 14 Mar 2024 10:20:23 +0000 (11:20 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Tue, 26 Mar 2024 13:03:53 +0000 (14:03 +0100)
Change-Id: Ie65bc883ce81586816e20d28ca5585743005018e

srcs/message.cpp
srcs/message.h
tests/message_tests.cpp

index 924f089888091158ba636bc4864f6224dc284c4b..8cabf8e823e6aea738825103e0777b6e6c690d19 100644 (file)
@@ -200,6 +200,15 @@ constexpr int64_t KEY_GA_RSP_UNSIGNED_EXTENSIONS_OUTPUT = 0x08;
 constexpr int64_t KEY_GA_RSP_EP_ATT = 0x09;
 constexpr int64_t KEY_GA_RSP_ATT_STMT = 0x0A;
 
+// Update message
+constexpr int64_t KEY_UP_LINK_INFO = 0x01;
+constexpr int64_t KEY_UP_CMD_CONTACT_ID = 0x01;
+constexpr int64_t KEY_UP_CMD_LINK_ID = 0x02;
+constexpr int64_t KEY_UP_CMD_LINK_SECRET = 0x03;
+constexpr int64_t KEY_UP_CMD_AUTHENTICATOR_PUBLIC_KEY = 0x04;
+constexpr int64_t KEY_UP_CMD_AUTHENTICATOR_NAME = 0x05;
+constexpr int64_t KEY_UP_CMD_HANDSHAKE_SIGNATURE = 0x06;
+
 void SerializePubkeyCredDescriptors(CborEncoding::SortedMap &map,
                                     const CborEncoding::Key &key,
                                     const wauthn_pubkey_cred_descriptors_s &credentials)
@@ -872,3 +881,33 @@ void PostHandshakeResponse::Deserialize(BufferView &input)
     m_longTouchForReset = getInfoMap.GetBooleanAt(KEY_GI_RSP_LONG_TOUCH_FOR_RESET);
 }
 
+void UpdateMessage::Deserialize(BufferView &input)
+{
+
+    auto helper = CborParsing::Parser::Create(input.data(), input.size());
+    auto map = helper.EnterMap();
+
+    auto linkingMap = map.EnterMapAt(KEY_UP_LINK_INFO);
+    if (!linkingMap)
+        return;
+
+    m_linkData = {linkingMap->GetByteStringAt(KEY_UP_CMD_CONTACT_ID).value(),
+                  linkingMap->GetByteStringAt(KEY_UP_CMD_LINK_ID).value(),
+                  linkingMap->GetByteStringAt(KEY_UP_CMD_LINK_SECRET).value(),
+                  linkingMap->GetByteStringAt(KEY_UP_CMD_AUTHENTICATOR_PUBLIC_KEY).value(),
+                  linkingMap->GetTextStringAt(KEY_UP_CMD_AUTHENTICATOR_NAME).value(),
+                  linkingMap->GetByteStringAt(KEY_UP_CMD_HANDSHAKE_SIGNATURE).value()};
+
+    if (m_linkData->m_linkId.size() != 8)
+        THROW_UNKNOWN("Wrong link ID length " << m_linkData->m_linkId.size());
+    if (m_linkData->m_linkSecret.size() != 32)
+        THROW_UNKNOWN("Wrong link secret length " << m_linkData->m_linkSecret.size());
+    if (m_linkData->m_authenticatorPublicKey.size() != 65)
+        THROW_UNKNOWN("Wrong authenticator public key length "
+                      << m_linkData->m_authenticatorPublicKey.size());
+    if (m_linkData->m_handshakeSignature.size() != 32)
+        THROW_UNKNOWN("Wrong handshake signature length "
+                      << m_linkData->m_handshakeSignature.size());
+}
+
+void UpdateMessage::Notify(IMessageObserver &observer) { observer.HandleUpdateMessage(*this); }
index d9ce655ffce10e7e83960bfde9ea631533e69dfe..e5b1efddec6cb061065559e3b695d69436ce4c29 100644 (file)
@@ -206,10 +206,32 @@ public:
     std::string m_userDisplayName;
 };
 
+// Contains only CBOR map
+class UpdateMessage : public IIncomingNotifyingMessage {
+public:
+    void Deserialize(BufferView &input) override;
+    void Notify(IMessageObserver &observer) override;
+
+    struct LinkData {
+        Buffer m_contactId;
+        Buffer m_linkId;
+        Buffer m_linkSecret;
+        Buffer m_authenticatorPublicKey;
+        std::string m_authenticatorName;
+        Buffer m_handshakeSignature;
+    };
+
+    const std::optional<LinkData> &GetLinkData() const { return m_linkData; }
+
+private:
+    std::optional<LinkData> m_linkData;
+};
+
 class IMessageObserver {
 public:
     virtual void HandleMakeCredentialResponse(const MakeCredentialResponse &response) = 0;
     virtual void HandleGetAssertionResponse(const GetAssertionResponse &response) = 0;
+    virtual void HandleUpdateMessage(const UpdateMessage &response) = 0;
     virtual ~IMessageObserver() = default;
 };
 
index 251802569f0f21d1cb731f092ea5b1954c59effc..3a7e2f4dc4694a7f8564d8ee238dca56c475f216 100644 (file)
@@ -29,7 +29,8 @@ void AssertEq(const T &left, const T &right)
 template <typename T>
 void AssertEq(const T &left, const uint8_t *rightData, size_t rightSize)
 {
-    ASSERT_EQ(BufferView(left.data(), left.size()), BufferView(rightData, rightSize));
+    ASSERT_EQ(BufferView(reinterpret_cast<const uint8_t *>(left.data()), left.size()),
+              BufferView(rightData, rightSize));
 }
 
 // from chromium/device/fido/fido_test_data.h
@@ -652,3 +653,47 @@ TEST(Messages, ParseGetAssertionResponse)
     ASSERT_TRUE(msg.m_userName.empty());
     ASSERT_TRUE(msg.m_userDisplayName.empty());
 }
+
+TEST(Messages, ParseUpdateMessage)
+{
+    // sample value received from an Android authenticator during manual testing
+    constexpr uint8_t blob[] =
+        "\xa2\x00\x58\xaf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x01\xa7\x01\x58\x98\x64\x2d\x51\x6b\x57\x6e\x54\x6d\x77\x53\x45\x3a\x41\x50"
+        "\x41\x39\x31\x62\x48\x76\x72\x44\x72\x39\x53\x64\x44\x31\x71\x39\x4a\x69\x4d\x55\x78\x52"
+        "\x38\x57\x30\x41\x5a\x48\x57\x61\x56\x31\x4d\x46\x4b\x36\x77\x4f\x56\x78\x70\x76\x38\x30"
+        "\x47\x37\x59\x57\x79\x5a\x51\x72\x77\x68\x6b\x6c\x66\x57\x55\x31\x4a\x6e\x6b\x6e\x59\x78"
+        "\x4e\x6d\x45\x69\x64\x33\x4f\x4e\x59\x6f\x4d\x77\x6f\x6a\x34\x56\x33\x51\x69\x33\x68\x6f"
+        "\x59\x57\x39\x6d\x31\x71\x42\x6e\x4f\x76\x55\x69\x63\x55\x57\x49\x68\x4d\x63\x56\x42\x64"
+        "\x69\x73\x39\x69\x67\x4d\x5a\x34\x79\x2d\x48\x7a\x6b\x31\x35\x65\x42\x4d\x63\x58\x39\x6e"
+        "\x63\x6a\x69\x6b\x74\x2d\x02\x48\xc3\x38\xcc\xd2\x66\x09\x9c\xff\x03\x58\x20\xcc\x2f\xaa"
+        "\xf2\x37\x92\x3e\xda\xa1\x1f\xc8\x7e\x3e\x60\xe5\x52\xf6\xa0\xe9\x67\x78\xa7\x31\xda\x1e"
+        "\xa9\xd6\x6c\x29\xd9\xa6\x5b\x04\x58\x41\x04\x4d\x7a\xcd\xb4\x1c\x63\x70\x56\x43\x37\xc3"
+        "\x7d\x20\xa3\x05\x64\x8d\x16\x6c\xa2\x41\xaa\x96\x90\xea\x9a\xde\xd2\x01\xab\x3d\x93\x08"
+        "\x13\x54\xd9\x99\x16\x18\x80\xfd\x3b\x21\x26\xf4\xbb\xdb\x43\x35\x80\xed\x3e\x2b\xe2\x43"
+        "\x5a\x31\xcf\xc6\x05\x5d\x3e\xfe\xb5\x05\x65\x4d\x69\x20\x41\x32\x06\x58\x20\x35\x5a\xbb"
+        "\xcf\x8f\x6a\xca\xaa\xda\x49\xee\x3d\xf0\xf3\xd6\x4c\x88\x35\x1b\xd6\x69\x51\x2f\x98\xe6"
+        "\xad\x8e\x80\xcf\x50\xb0\x09\x19\x03\xe7\xf5";
+    BufferView view(blob, sizeof(blob) - 1);
+
+    UpdateMessage msg;
+    ASSERT_NO_THROW(msg.Deserialize(view));
+
+    auto linkDataOpt = msg.GetLinkData();
+    ASSERT_TRUE(linkDataOpt.has_value());
+    const auto &linkData = *linkDataOpt;
+
+    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);
+}