Make Cbor::EncodeQRContents throw exception instead of returning error 58/305858/3
authorKrzysztof Malysa <k.malysa@samsung.com>
Fri, 9 Feb 2024 13:19:52 +0000 (14:19 +0100)
committerDariusz Michaluk <d.michaluk@samsung.com>
Fri, 9 Feb 2024 17:10:00 +0000 (17:10 +0000)
Change-Id: I63f87a9d20c9d9cd5ed29b68fd2b7f8c529d3ef9

srcs/cbor_encoding.cpp
srcs/cbor_encoding.h
srcs/request.cpp
srcs/request.h
tests/cbor_tests.cpp

index 17ade44429375398ab6ed5986c1bd5aa9997ade6..9a08243ebe63aa184a7be8f58f27eaee08c61df3 100644 (file)
 #include "cbor.h"
 #include "cbor_encoding.h"
 #include "crypto/random.h"
+#include "exception.h"
 #include "log/log.h"
 #include "tunnel_server_domain.h"
 
 #include <chrono>
 #include <iomanip>
 #include <sstream>
-#include <webauthn-hal.h>
 
 using namespace std;
 
@@ -76,11 +76,11 @@ bool Cbor::getGrease() const
     return extraKey;
 }
 
-wauthn_error_e Cbor::EncodeQRContents(const CryptoBuffer &publicKey,
-                                      const CryptoBuffer &qrSecret,
-                                      const Hint &hint,
-                                      bool stateAssisted,
-                                      string &fidoUri)
+void Cbor::EncodeQRContents(const CryptoBuffer &publicKey,
+                            const CryptoBuffer &qrSecret,
+                            const Hint &hint,
+                            bool stateAssisted,
+                            string &fidoUri)
 {
     size_t buffSize = 73; // epoch is int64 which may take up to 8B (9B with key) in CBOR
     size_t mapElements = 6;
@@ -94,7 +94,7 @@ wauthn_error_e Cbor::EncodeQRContents(const CryptoBuffer &publicKey,
     // Integer value < 24 uses only one byte, larger value use more bytes
     if (ASSIGNED_TUNNEL_SERVER_DOMAINS.size() >= 24) {
         LogError("larger encoding needed!");
-        return WAUTHN_ERROR_ENCODING_FAILED;
+        throw EncodingFailed{};
     }
 
     bool extraKey = getGrease();
@@ -107,102 +107,98 @@ wauthn_error_e Cbor::EncodeQRContents(const CryptoBuffer &publicKey,
     cbor_encoder_init(&encoder, buffer.data(), buffer.size(), 0);
     if ((err = cbor_encoder_create_map(&encoder, &mapEncoder, mapElements))) {
         LogError("cbor_encoder_create_map error");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     // key 0 - public key
     if ((err = cbor_encode_int(&mapEncoder, 0))) {
         LogError("cbor_encode_int error in public key encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     if ((err = cbor_encode_byte_string(&mapEncoder, publicKey.data(), publicKey.size()))) {
         LogError("cbor_encode_byte_string error in public key encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     // key 1 - QR Secret
     if ((err = cbor_encode_int(&mapEncoder, 1))) {
         LogError("cbor_encode_int error in QR secret encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     if ((err = cbor_encode_byte_string(&mapEncoder, qrSecret.data(), qrSecret.size()))) {
         LogError("cbor_encode_byte_string error in QR secret encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     // key 2 - assigned tunnel servers domains
     if ((err = cbor_encode_int(&mapEncoder, 2))) {
         LogError("cbor_encode_int error in tunnel servers domains encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     if ((err = cbor_encode_int(&mapEncoder, ASSIGNED_TUNNEL_SERVER_DOMAINS.size()))) {
         LogError("cbor_encode_int error in tunnel servers domains encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     // key 3 - current time
     if ((err = cbor_encode_int(&mapEncoder, 3))) {
         LogError("cbor_encode_int error in time encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     if ((err = cbor_encode_int(&mapEncoder, getEpoch()))) {
         LogError("cbor_encode_int error in time encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     // key 4 - state assisted transactions
     if ((err = cbor_encode_int(&mapEncoder, 4))) {
         LogError("cbor_encode_int error in state assisted transactions encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     if ((err = cbor_encode_boolean(&mapEncoder, stateAssisted))) {
         LogError("cbor_encode_boolean error in state assisted transactions encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     // key 5 - "ga" if get assertion and "mc" if make credential
     if ((err = cbor_encode_int(&mapEncoder, 5))) {
         LogError("cbor_encode_int error in hint encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     // Here specification says byte string with which Android does not work. webauthn.io uses text
     // string which works.
     if ((err = cbor_encode_text_string(&mapEncoder, hint.data(), hint.size()))) {
         LogError("cbor_encode_text_string error in hint encoding");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     // key 6 - when GREASE is true
     if (extraKey) {
         if ((err = cbor_encode_int(&mapEncoder, 65535))) {
             LogError("cbor_encode_int error in GREASE");
-            goto cborError;
+            throw EncodingFailed{};
         }
         if ((err = cbor_encode_int(&mapEncoder, 0))) {
             LogError("cbor_encode_int error in GREASE");
-            goto cborError;
+            throw EncodingFailed{};
         }
     }
 
     if ((err = cbor_encoder_close_container(&encoder, &mapEncoder))) {
         LogError("Cbor encode error: cannot close container");
-        goto cborError;
+        throw EncodingFailed{};
     }
 
     buffSize = cbor_encoder_get_buffer_size(&encoder, buffer.data());
     buffer.resize(buffSize);
 
     fidoUri = "FIDO:/" + DigitEncode(buffer);
-    return WAUTHN_ERROR_NONE;
-
-cborError:
-    return WAUTHN_ERROR_ENCODING_FAILED;
 }
 
 } // namespace CborEncoding
index 8275788101b22d6fe267032ffb177036b62ec3ec..f346838908c583b982f43b85256318aa25b80fbc 100644 (file)
@@ -20,7 +20,6 @@
 #include "crypto/common.h"
 
 #include <string>
-#include <webauthn-types.h>
 
 namespace CborEncoding {
 
@@ -33,11 +32,12 @@ public:
     Cbor &operator=(Cbor &&) = delete;
     virtual ~Cbor() = default;
 
-    wauthn_error_e EncodeQRContents(const CryptoBuffer &publicKey,
-                                    const CryptoBuffer &qrSecret,
-                                    const Hint &hint,
-                                    bool stateAssisted,
-                                    std::string &fidoUri);
+    // Throws on error.
+    void EncodeQRContents(const CryptoBuffer &publicKey,
+                          const CryptoBuffer &qrSecret,
+                          const Hint &hint,
+                          bool stateAssisted,
+                          std::string &fidoUri);
 
 protected:
     virtual int64_t getEpoch() const;
index 597180bd9a35d9da02e43d150b2ac6e5d635805c..211b634f0399c69983af4c0dac9783035975c107 100644 (file)
@@ -28,9 +28,7 @@ wauthn_error_e Request::Process()
         auto qrSecret = Crypto::RandomBytes(16);
         auto identityKeyCompressed = Crypto::GenerateCompressedX9_62_P_256_Key();
 
-        auto qrErr = ShowQRCode(qrSecret, identityKeyCompressed);
-        if (qrErr != WAUTHN_ERROR_NONE)
-            return qrErr;
+        ShowQRCode(qrSecret, identityKeyCompressed);
 
         auto eidKey = DeriveKey(qrSecret, {}, KeyPurpose::EIDKey, 64);
 
@@ -82,19 +80,12 @@ wauthn_error_e Request::Cancel()
     return WAUTHN_ERROR_NONE;
 }
 
-wauthn_error_e Request::ShowQRCode(const CryptoBuffer &qrSecret,
-                                   const CryptoBuffer &identityKeyCompressed)
+void Request::ShowQRCode(const CryptoBuffer &qrSecret, const CryptoBuffer &identityKeyCompressed)
 {
 
     std::string fidoUri;
     CborEncoding::Cbor cbor;
-    wauthn_error_e ret =
-        cbor.EncodeQRContents(identityKeyCompressed, qrSecret, GetHint(), StateAssisted(), fidoUri);
-
-    if (ret != WAUTHN_ERROR_NONE)
-        return ret;
+    cbor.EncodeQRContents(identityKeyCompressed, qrSecret, GetHint(), StateAssisted(), fidoUri);
 
     QRCallback(fidoUri);
-
-    return WAUTHN_ERROR_NONE;
 }
index f6e0cd1ce25a612430f585ca7eaf42292c1bc0d6..9281727972aa7c08bb38a3918ea98d315467c681 100644 (file)
@@ -44,8 +44,7 @@ protected:
 
     bool StateAssisted() const { return LinkData() != nullptr; }
 
-    wauthn_error_e ShowQRCode(const CryptoBuffer &qrSecret,
-                              const CryptoBuffer &identityKeyCompressed);
+    void ShowQRCode(const CryptoBuffer &qrSecret, const CryptoBuffer &identityKeyCompressed);
     virtual Hint GetHint() const = 0;
 
 private:
index 2034515f431d6701ba0706c9e84c61eb2c5271e1..947f406071a2c68c3e78fc002f7af031b36f6f0e 100644 (file)
@@ -116,26 +116,20 @@ private:
 
 TEST(WebAuthnBleTest, testCborEncodeCurrTime)
 {
-    int ret = WAUTHN_ERROR_NONE;
     std::string str;
     CborEncoding::Cbor cb;
-    ret = cb.EncodeQRContents(PUBKEY1, SECRET1, GA, false, str);
-
-    EXPECT_EQ(ret, WAUTHN_ERROR_NONE) << "[EncodeQRContents] failed. " << std::endl;
+    EXPECT_NO_THROW(cb.EncodeQRContents(PUBKEY1, SECRET1, GA, false, str));
 }
 
 TEST(WebAuthnBleTest, testCborEncodeGivenTime)
 {
-    int ret = WAUTHN_ERROR_NONE;
     std::string str;
 
     DT = {4, 46, 30, 7, 6, 2023};
     EXTRAKEY = true;
 
     MockCbor cb;
-    ret = cb.EncodeQRContents(PUBKEY1, SECRET1, MC, false, str);
-
-    EXPECT_EQ(ret, WAUTHN_ERROR_NONE) << "[EncodeQRContents] failed. " << std::endl;
+    EXPECT_NO_THROW(cb.EncodeQRContents(PUBKEY1, SECRET1, MC, false, str));
 }
 
 TEST(WebAuthnBleTest, testCborEncodeMaxLength)
@@ -144,44 +138,34 @@ TEST(WebAuthnBleTest, testCborEncodeMaxLength)
         int64_t getEpoch() const override { return INT64_MAX; }
     } cb;
 
-    int ret = WAUTHN_ERROR_NONE;
     std::string str;
     EXTRAKEY = true;
 
-    ret = cb.EncodeQRContents(PUBKEY1, SECRET1, MC, false, str);
-
-    EXPECT_EQ(ret, WAUTHN_ERROR_NONE) << "[EncodeQRContents] failed. " << std::endl;
+    EXPECT_NO_THROW(cb.EncodeQRContents(PUBKEY1, SECRET1, MC, false, str));
 }
 
 TEST(WebAuthnBleTest, testCborEncodeExtraKey)
 {
-    int ret = WAUTHN_ERROR_NONE;
     std::string str;
 
     EXTRAKEY = true;
 
     MockRandCbor cb;
-    ret = cb.EncodeQRContents(PUBKEY1, SECRET1, MC, false, str);
-
-    EXPECT_EQ(ret, WAUTHN_ERROR_NONE) << "[EncodeQRContents] failed. " << std::endl;
+    EXPECT_NO_THROW(cb.EncodeQRContents(PUBKEY1, SECRET1, MC, false, str));
 }
 
 TEST(WebAuthnBleTest, testCborEncodeStateAssisted)
 {
-    int ret = WAUTHN_ERROR_NONE;
     std::string str;
 
     EXTRAKEY = false;
 
     MockRandCbor cb;
-    ret = cb.EncodeQRContents(PUBKEY1, SECRET1, MC, true, str);
-
-    EXPECT_EQ(ret, WAUTHN_ERROR_NONE) << "[EncodeQRContents] failed. " << std::endl;
+    EXPECT_NO_THROW(cb.EncodeQRContents(PUBKEY1, SECRET1, MC, true, str));
 }
 
 TEST(WebAuthnBleTest, testCborDocsExample1)
 {
-    int ret = WAUTHN_ERROR_NONE;
     std::string str;
 
     // this string is an CBOR map generated via cbor.me based on parameters used in this test
@@ -195,16 +179,12 @@ TEST(WebAuthnBleTest, testCborDocsExample1)
     EXTRAKEY = true;
 
     MockCbor cb;
-    ret = cb.EncodeQRContents(PUBKEY_EXAMPLE_1, SECRET_EXAMPLE_1, MC, true, str);
-
-    EXPECT_EQ(ret, WAUTHN_ERROR_NONE) << "[EncodeQRContents] failed. " << std::endl;
-
+    EXPECT_NO_THROW(cb.EncodeQRContents(PUBKEY_EXAMPLE_1, SECRET_EXAMPLE_1, MC, true, str));
     EXPECT_EQ(str, exp) << "[EncodeQRContents] failed." << std::endl;
 }
 
 TEST(WebAuthnBleTest, testCborDocsExample2)
 {
-    int ret = WAUTHN_ERROR_NONE;
     std::string str;
 
     // this string is an CBOR map generated via cbor.me based on parameters used in this test
@@ -217,9 +197,7 @@ TEST(WebAuthnBleTest, testCborDocsExample2)
     EXTRAKEY = false;
 
     MockCbor cb;
-    ret = cb.EncodeQRContents(PUBKEY_EXAMPLE_2, SECRET_EXAMPLE_2, GA, true, str);
-
-    EXPECT_EQ(ret, WAUTHN_ERROR_NONE) << "[EncodeQRContents] failed." << std::endl;
+    EXPECT_NO_THROW(cb.EncodeQRContents(PUBKEY_EXAMPLE_2, SECRET_EXAMPLE_2, GA, true, str));
 
     EXPECT_EQ(str, exp) << "[EncodeQRContents] failed." << std::endl;
 }