Increase code coverage 57/320557/4
authorJakub Wlostowski <j.wlostowski@samsung.com>
Mon, 18 Nov 2024 11:11:37 +0000 (12:11 +0100)
committerJakub Wlostowski <j.wlostowski@samsung.com>
Tue, 19 Nov 2024 10:51:00 +0000 (11:51 +0100)
Change-Id: Ie97fd2a4ffe39d711ce19214e58e438ed6b1a648

15 files changed:
srcs/crypto/ec_key.cpp
srcs/crypto/ecdh.cpp
srcs/crypto/encryptor.cpp
srcs/crypto/hkdf.cpp
srcs/crypto/hmac.cpp
srcs/crypto/openssl_error.h
srcs/crypto/random.cpp
srcs/crypto/sha2.cpp
srcs/exception.h
tests/bluetooth_tests.cpp
tests/cbor_tests.cpp
tests/crypto/ec_key_unittest.cpp
tests/ctap_message_processor_tests.cpp
tests/message_tests.cpp
tests/request_handler_tests.cpp

index 057abf6913a0d411bc652be595e1cf2fe29b4381..1b5e71695a64bb850561a01d4e9543719e93935c 100644 (file)
 #include "../common.h"
 #include "crypto/common.h"
 #include "crypto/ec_key.h"
-#include "crypto/openssl_error.h"
 #include "exception.h"
 #include "log/log.h"
 
 #include <cassert>
 #include <cstring>
+#include <memory>
 #include <openssl/bn.h>
 #include <openssl/ec.h>
 #include <openssl/evp.h>
@@ -55,188 +55,131 @@ ECKey::~ECKey() { EVP_PKEY_free(m_key); }
 
 ECKey ECKey::Create(Curve curve)
 {
-    EVP_PKEY_CTX *ctx = nullptr;
-    EVP_PKEY *pkey = nullptr;
-
-    ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr);
-    if (!ctx) {
-        TRY_LOG_ERROR("EVP_PKEY_CTX_new_id() error");
-        goto opensslError;
-    }
-    if (EVP_PKEY_keygen_init(ctx) != 1) {
-        TRY_LOG_ERROR("EVP_PKEY_keygen_init() error");
-        goto opensslError;
-    }
-    if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, Curve2NID(curve)) != 1) {
-        TRY_LOG_ERROR("EVP_PKEY_CTX_set_ec_paramgen_curve_nid() error");
-        goto opensslError;
-    }
-    if (EVP_PKEY_keygen(ctx, &pkey) != 1) {
-        TRY_LOG_ERROR("EVP_PKEY_keygen() error");
-        goto opensslError;
-    }
-
-    EVP_PKEY_CTX_free(ctx);
-    return ECKey{pkey};
-
-opensslError:
-    EVP_PKEY_CTX_free(ctx);
-    throw OpensslError{};
+    EVP_PKEY *pkeyTmp = nullptr;
+    std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)> ctx(
+        EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr), EVP_PKEY_CTX_free);
+    if (!ctx)
+        THROW_OPENSSL("EVP_PKEY_CTX_new_id() error");
+    if (EVP_PKEY_keygen_init(ctx.get()) != 1)
+        THROW_OPENSSL("EVP_PKEY_keygen_init() error");
+    if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx.get(), Curve2NID(curve)) != 1)
+        THROW_OPENSSL("EVP_PKEY_CTX_set_ec_paramgen_curve_nid() error");
+    if (EVP_PKEY_keygen(ctx.get(), &pkeyTmp) != 1)
+        THROW_OPENSSL("EVP_PKEY_keygen() error");
+
+    std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)> pkey(pkeyTmp, EVP_PKEY_free);
+
+    return ECKey{pkey.release()};
 }
 
 ECKey ECKey::ImportPrivateKey(Curve curve, const CryptoBuffer &input)
 {
-    EVP_PKEY *pkey = nullptr;
-    EC_KEY *ec = nullptr;
-    EC_GROUP *group = nullptr;
-    EC_POINT *point = nullptr;
-    const BIGNUM *bn = nullptr;
-
-    pkey = EVP_PKEY_new();
-    if (!pkey) {
-        TRY_LOG_ERROR("EVP_PKEY_new() error");
-        goto opensslError;
-    }
-    ec = EC_KEY_new();
-    if (!ec) {
-        TRY_LOG_ERROR("EC_KEY_new() error");
-        goto opensslError;
-    }
-    group = EC_GROUP_new_by_curve_name(Curve2NID(curve));
-    if (!group) {
-        TRY_LOG_ERROR("EC_GROUP_new_by_curve_name() error");
-        goto opensslError;
-    }
-    EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
-    if (EC_KEY_set_group(ec, group) != 1) {
-        TRY_LOG_ERROR("EC_KEY_set_group() error");
-        goto opensslError;
-    }
-    if (EC_KEY_oct2priv(ec, input.data(), input.size()) != 1) {
-        TRY_LOG_ERROR("EC_KEY_oct2priv() error");
-        goto opensslError;
-    }
-    point = EC_POINT_new(group);
-    if (!point) {
-        TRY_LOG_ERROR("EC_POINT_new() error");
-        goto opensslError;
-    }
-    bn = EC_KEY_get0_private_key(ec);
-    if (!bn) {
-        TRY_LOG_ERROR("EC_KEY_get0_private_key() error");
-        goto opensslError;
-    }
-    if (EC_POINT_mul(group, point, bn, nullptr, nullptr, nullptr) != 1) {
-        TRY_LOG_ERROR("EC_POINT_mul() error");
-        goto opensslError;
-    }
-    if (EC_KEY_set_public_key(ec, point) != 1) {
-        TRY_LOG_ERROR("EC_KEY_set_public_key() error");
-        goto opensslError;
-    }
-    if (EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) {
-        TRY_LOG_ERROR("EVP_PKEY_assign_EC_KEY() error");
-        goto opensslError;
-    }
+    std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)> pkey(EVP_PKEY_new(), EVP_PKEY_free);
+    if (!pkey)
+        THROW_OPENSSL("EVP_PKEY_new() error");
+
+    std::unique_ptr<EC_KEY, decltype(&EC_KEY_free)> ec(EC_KEY_new(), EC_KEY_free);
+    if (!ec)
+        THROW_OPENSSL("EC_KEY_new() error");
+
+    std::unique_ptr<EC_GROUP, decltype(&EC_GROUP_clear_free)> group(
+        EC_GROUP_new_by_curve_name(Curve2NID(curve)), EC_GROUP_clear_free);
+    if (!group)
+        THROW_OPENSSL("EC_GROUP_new_by_curve_name() error");
+
+    EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE);
+    if (EC_KEY_set_group(ec.get(), group.get()) != 1)
+        THROW_OPENSSL("EC_KEY_set_group() error");
 
-    EC_GROUP_clear_free(group);
-    EC_POINT_clear_free(point);
-    return ECKey{pkey};
+    if (EC_KEY_oct2priv(ec.get(), input.data(), input.size()) != 1)
+        THROW_OPENSSL("EC_KEY_oct2priv() error");
 
-opensslError:
-    EVP_PKEY_free(pkey);
-    EC_KEY_free(ec);
-    EC_GROUP_clear_free(group);
-    EC_POINT_clear_free(point);
-    throw OpensslError{};
+    std::unique_ptr<EC_POINT, decltype(&EC_POINT_clear_free)> point(EC_POINT_new(group.get()),
+                                                                    EC_POINT_clear_free);
+    if (!point)
+        THROW_OPENSSL("EC_POINT_new() error");
+
+    const BIGNUM *bn = EC_KEY_get0_private_key(ec.get());
+    if (!bn)
+        THROW_OPENSSL("EC_KEY_get0_private_key() error");
+
+    if (EC_POINT_mul(group.get(), point.get(), bn, nullptr, nullptr, nullptr) != 1)
+        THROW_OPENSSL("EC_POINT_mul() error");
+
+    if (EC_KEY_set_public_key(ec.get(), point.get()) != 1)
+        THROW_OPENSSL("EC_KEY_set_public_key() error");
+
+    if (EVP_PKEY_assign_EC_KEY(pkey.get(), ec.get()) != 1)
+        THROW_OPENSSL("EVP_PKEY_assign_EC_KEY() error");
+
+    ec.release();
+
+    return ECKey{pkey.release()};
 }
 
 ECKey ECKey::ImportPublicKey(Curve curve, const CryptoBuffer &input)
 {
-    EVP_PKEY *pkey = nullptr;
-    EC_KEY *ec = nullptr;
-    EC_GROUP *group = nullptr;
-
-    pkey = EVP_PKEY_new();
-    if (!pkey) {
-        TRY_LOG_ERROR("EVP_PKEY_new() error");
-        goto opensslError;
-    }
-    ec = EC_KEY_new();
-    if (!ec) {
-        TRY_LOG_ERROR("EC_KEY_new() error");
-        goto opensslError;
-    }
-    group = EC_GROUP_new_by_curve_name(Curve2NID(curve));
-    if (!group) {
-        TRY_LOG_ERROR("EC_GROUP_new_by_curve_name() error");
-        goto opensslError;
-    }
-    EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
-    if (EC_KEY_set_group(ec, group) != 1) {
-        TRY_LOG_ERROR("EC_KEY_set_group() error");
-        goto opensslError;
-    }
-    if (EC_KEY_oct2key(ec, input.data(), input.size(), nullptr) != 1) {
-        TRY_LOG_ERROR("EC_KEY_oct2key() error");
-        goto opensslError;
-    }
-    if (EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) {
-        TRY_LOG_ERROR("EVP_PKEY_assign_EC_KEY() error");
-        goto opensslError;
-    }
+    std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)> pkey(EVP_PKEY_new(), EVP_PKEY_free);
+    if (!pkey)
+        THROW_OPENSSL("EVP_PKEY_new() error");
+
+    std::unique_ptr<EC_KEY, decltype(&EC_KEY_free)> ec(EC_KEY_new(), EC_KEY_free);
+    if (!ec)
+        THROW_OPENSSL("EC_KEY_new() error");
+
+    std::unique_ptr<EC_GROUP, decltype(&EC_GROUP_clear_free)> group(
+        EC_GROUP_new_by_curve_name(Curve2NID(curve)), EC_GROUP_clear_free);
+    if (!group)
+        THROW_OPENSSL("EC_GROUP_new_by_curve_name() error");
+
+    EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE);
+    if (EC_KEY_set_group(ec.get(), group.get()) != 1)
+        THROW_OPENSSL("EC_KEY_set_group() error");
 
-    EC_GROUP_clear_free(group);
-    return ECKey{pkey};
+    if (EC_KEY_oct2key(ec.get(), input.data(), input.size(), nullptr) != 1)
+        THROW_OPENSSL("EC_KEY_oct2key() error");
 
-opensslError:
-    EVP_PKEY_free(pkey);
-    EC_KEY_free(ec);
-    EC_GROUP_clear_free(group);
-    throw OpensslError{};
+    if (EVP_PKEY_assign_EC_KEY(pkey.get(), ec.get()) != 1)
+        THROW_OPENSSL("EVP_PKEY_assign_EC_KEY() error");
+
+    ec.release();
+
+    return ECKey{pkey.release()};
 }
 
 ECKey ECKey::ImportPublicKey(Curve curve, const CryptoBuffer &x, const CryptoBuffer &y)
 {
-    BIGNUM *bx = BN_new();
+    std::unique_ptr<BIGNUM, decltype(&BN_free)> bx(BN_new(), BN_free);
     if (!bx)
-        THROW_MEMORY();
-    auto cleanupBx = OnScopeExit([&bx] { BN_free(bx); });
+        THROW_OPENSSL("BN_new() error");
 
-    BIGNUM *by = BN_new();
+    std::unique_ptr<BIGNUM, decltype(&BN_free)> by(BN_new(), BN_free);
     if (!by)
-        THROW_MEMORY();
-    auto cleanupBy = OnScopeExit([&by] { BN_free(by); });
+        THROW_OPENSSL("BN_new() error");
 
-    // TODO compressed format
-    if (BN_bin2bn(x.data(), static_cast<int>(x.size()), bx) == nullptr)
-        THROW_UNKNOWN("Bignum x creation failed");
-    if (BN_bin2bn(y.data(), static_cast<int>(y.size()), by) == nullptr)
-        THROW_UNKNOWN("Bignum y creation failed");
+    if (BN_bin2bn(x.data(), static_cast<int>(x.size()), bx.get()) == nullptr)
+        THROW_OPENSSL("Bignum x creation failed");
+    if (BN_bin2bn(y.data(), static_cast<int>(y.size()), by.get()) == nullptr)
+        THROW_OPENSSL("Bignum y creation failed");
 
-    auto ecKey = EC_KEY_new_by_curve_name(Curve2NID(curve));
+    std::unique_ptr<EC_KEY, decltype(&EC_KEY_free)> ecKey(
+        EC_KEY_new_by_curve_name(Curve2NID(curve)), EC_KEY_free);
     if (!ecKey)
-        THROW_UNKNOWN("EC_KEY_new_by_curve_name() failed");
+        THROW_OPENSSL("EC_KEY_new_by_curve_name() failed");
 
-    auto cleanupEcKey = OnScopeExit([&ecKey] { EC_KEY_free(ecKey); });
+    if (EC_KEY_set_public_key_affine_coordinates(ecKey.get(), bx.get(), by.get()) != 1)
+        THROW_OPENSSL("EC_KEY_set_public_key_affine_coordinates() failed");
 
-    if (EC_KEY_set_public_key_affine_coordinates(ecKey, bx, by) != 1)
-        THROW_UNKNOWN("EC_KEY_set_public_key_affine_coordinates() failed");
-
-    auto evpKey = EVP_PKEY_new();
+    std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)> evpKey(EVP_PKEY_new(), EVP_PKEY_free);
     if (!evpKey)
-        THROW_MEMORY();
-
-    auto cleanupEvpKey = OnScopeExit([&evpKey] { EVP_PKEY_free(evpKey); });
+        THROW_OPENSSL("EVP_PKEY_new() error");
 
-    if (EVP_PKEY_assign_EC_KEY(evpKey, ecKey) != 1)
-        THROW_UNKNOWN("EVP_PKEY_assign_EC_KEY() failed");
-    ecKey = nullptr;
+    if (EVP_PKEY_assign_EC_KEY(evpKey.get(), ecKey.get()) != 1)
+        THROW_OPENSSL("EVP_PKEY_assign_EC_KEY() failed");
 
-    auto ret = ECKey{evpKey};
-    evpKey = nullptr;
+    ecKey.release();
 
-    return ret;
+    return ECKey{evpKey.release()};
 }
 
 CryptoBuffer ECKey::ExportPrivateKey() const
@@ -247,9 +190,8 @@ CryptoBuffer ECKey::ExportPrivateKey() const
     const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(m_key);
     buffLen = EC_KEY_priv2buf(ec, &buff);
     if (buffLen == 0) {
-        TRY_LOG_ERROR("EC_KEY_priv2buf() error");
         OPENSSL_free(buff);
-        throw OpensslError{};
+        THROW_OPENSSL("EC_KEY_priv2buf() error");
     }
 
     CryptoBuffer res(buffLen);
@@ -269,7 +211,7 @@ CryptoBuffer ECKey::ExportPublicKey(Format format) const
 
         const int ret = i2d_EC_PUBKEY(ecKey, &derData); // deprecated in 3.0
         if (ret < 0)
-            THROW_UNKNOWN("i2d_EC_PUBKEY() failed");
+            THROW_OPENSSL("i2d_EC_PUBKEY() failed");
 
         der.resize(ret);
         return der;
@@ -284,10 +226,8 @@ CryptoBuffer ECKey::ExportPublicKey(Format format) const
 
         buffLen = EC_KEY_key2buf(ecKey, form, &buff, nullptr);
         auto cleanupBuff = OnScopeExit([&buff] { OPENSSL_free(buff); });
-        if (buffLen == 0) {
-            TRY_LOG_ERROR("EC_KEY_key2buf() error");
-            throw OpensslError{};
-        }
+        if (buffLen == 0)
+            THROW_OPENSSL("EC_KEY_key2buf() error");
 
         CryptoBuffer res(buffLen);
         std::memcpy(res.data(), buff, buffLen);
index c0c2ed7678038604695673c8d30473262c83ceac..e62ba73d20dd5406ddf149a0d0a0bd4184932345 100644 (file)
@@ -16,7 +16,7 @@
 
 #include "crypto/ec_key.h"
 #include "crypto/ecdh.h"
-#include "crypto/openssl_error.h"
+#include "exception.h"
 #include "log/log.h"
 
 #include <memory>
@@ -31,28 +31,21 @@ CryptoBuffer deriveECDHSharedSecret(const ECKey &myPrivateKey, const ECKey &peer
 
     auto ctx = std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)>{
         EVP_PKEY_CTX_new(myPrivateKey.get(), nullptr), &EVP_PKEY_CTX_free};
-    if (!ctx) {
-        LogError("EVP_PKEY_CTX_new() error");
-        throw OpensslError{};
-    }
-    if (1 != EVP_PKEY_derive_init(ctx.get())) {
-        LogError("EVP_PKEY_derive_init() error");
-        throw OpensslError{};
-    }
-    if (1 != EVP_PKEY_derive_set_peer(ctx.get(), peerPublicKey.get())) {
-        LogError("EVP_PKEY_derive_set_peer() error");
-        throw OpensslError{};
-    }
-    if (1 != EVP_PKEY_derive(ctx.get(), nullptr, &len)) {
-        LogError("EVP_PKEY_derive() error");
-        throw OpensslError{};
-    }
+    if (!ctx)
+        THROW_OPENSSL("EVP_PKEY_CTX_new() error");
+
+    if (1 != EVP_PKEY_derive_init(ctx.get()))
+        THROW_OPENSSL("EVP_PKEY_derive_init() error");
+
+    if (1 != EVP_PKEY_derive_set_peer(ctx.get(), peerPublicKey.get()))
+        THROW_OPENSSL("EVP_PKEY_derive_set_peer() error");
+
+    if (1 != EVP_PKEY_derive(ctx.get(), nullptr, &len))
+        THROW_OPENSSL("EVP_PKEY_derive() error");
 
     secret.resize(len);
-    if (1 != EVP_PKEY_derive(ctx.get(), secret.data(), &len)) {
-        LogError("EVP_PKEY_derive() error");
-        throw OpensslError{};
-    }
+    if (1 != EVP_PKEY_derive(ctx.get(), secret.data(), &len))
+        THROW_OPENSSL("EVP_PKEY_derive() error");
 
     return secret;
 }
index 199594bef702695d5fd665bebd8114ce6fd95949..6222eac33531dca3ee13a3377c6e128c1c46fbdd 100644 (file)
 
 #include "crypto/common.h"
 #include "crypto/encryptor.h"
-#include "crypto/openssl_error.h"
+#include "exception.h"
 #include "log/log.h"
 
 #include <cassert>
+#include <memory>
 #include <openssl/aes.h>
 #include <openssl/evp.h>
 
@@ -27,39 +28,28 @@ namespace {
 
 CryptoBuffer Crypt(bool encrypt, const CryptoBuffer &key, const CryptoBuffer &input)
 {
-    EVP_CIPHER_CTX *ctx = nullptr;
     CryptoBuffer output(input.size());
     int len;
 
-    ctx = EVP_CIPHER_CTX_new();
-    if (!ctx) {
-        TRY_LOG_ERROR("EVP_CIPHER_CTX_new() error");
-        goto opensslError;
-    }
-    if (EVP_CipherInit_ex(ctx, EVP_aes_256_ecb(), nullptr, key.data(), nullptr, encrypt) != 1) {
-        TRY_LOG_ERROR("EVP_CipherInit_ex() error");
-        goto opensslError;
-    }
-    if (EVP_CIPHER_CTX_set_padding(ctx, 0) != 1) {
-        TRY_LOG_ERROR("EVP_CIPHER_CTX_set_padding() error");
-        goto opensslError;
-    }
-    if (EVP_CipherUpdate(ctx, output.data(), &len, input.data(), static_cast<int>(input.size())) !=
-        1) {
-        TRY_LOG_ERROR("EVP_CipherUpdate() error");
-        goto opensslError;
-    }
-    if (EVP_CipherFinal_ex(ctx, output.data() + len, &len) != 1) {
-        TRY_LOG_ERROR("EVP_CipherFinal_ex() error");
-        goto opensslError;
-    }
-
-    EVP_CIPHER_CTX_free(ctx);
-    return output;
+    auto ctx = std::unique_ptr<EVP_CIPHER_CTX, decltype(&EVP_CIPHER_CTX_free)>{
+        EVP_CIPHER_CTX_new(), &EVP_CIPHER_CTX_free};
+    if (!ctx)
+        THROW_OPENSSL("EVP_CIPHER_CTX_new() error");
+
+    if (EVP_CipherInit_ex(ctx.get(), EVP_aes_256_ecb(), nullptr, key.data(), nullptr, encrypt) != 1)
+        THROW_OPENSSL("EVP_CipherInit_ex() error");
+
+    if (EVP_CIPHER_CTX_set_padding(ctx.get(), 0) != 1)
+        THROW_OPENSSL("EVP_CIPHER_CTX_set_padding() error");
 
-opensslError:
-    EVP_CIPHER_CTX_free(ctx);
-    throw Crypto::OpensslError{};
+    if (EVP_CipherUpdate(
+            ctx.get(), output.data(), &len, input.data(), static_cast<int>(input.size())) != 1)
+        THROW_OPENSSL("EVP_CipherUpdate() error");
+
+    if (EVP_CipherFinal_ex(ctx.get(), output.data() + len, &len) != 1)
+        THROW_OPENSSL("EVP_CipherFinal_ex() error");
+
+    return output;
 }
 
 } // namespace
@@ -81,66 +71,51 @@ CryptoBuffer EncryptAes256GCM(const CryptoBuffer &key,
                               const CryptoBuffer &aad,
                               const CryptoBuffer &plaintext)
 {
-    if (key.size() != 32) {
-        LogError("Invalid key length");
-        throw OpensslError{};
-    }
+    if (key.size() != 32)
+        THROW_OPENSSL("Invalid key length");
 
-    EVP_CIPHER_CTX *ctx = nullptr;
     constexpr int TAG_LEN = 16;
     int len = 0;
     size_t outputLen = 0;
     CryptoBuffer output(plaintext.size() + TAG_LEN);
 
-    ctx = EVP_CIPHER_CTX_new();
-    if (!ctx) {
-        TRY_LOG_ERROR("EVP_CIPHER_CTX_new() error");
-        goto opensslError;
-    }
-    if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr)) {
-        TRY_LOG_ERROR("EVP_EncryptInit_ex() error");
-        goto opensslError;
-    }
+    auto ctx = std::unique_ptr<EVP_CIPHER_CTX, decltype(&EVP_CIPHER_CTX_free)>{
+        EVP_CIPHER_CTX_new(), &EVP_CIPHER_CTX_free};
+    if (!ctx)
+        THROW_OPENSSL("EVP_CIPHER_CTX_new() error");
+
+    if (1 != EVP_EncryptInit_ex(ctx.get(), EVP_aes_256_gcm(), nullptr, nullptr, nullptr))
+        THROW_OPENSSL("EVP_EncryptInit_ex() error");
+
     if (1 !=
-        EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, static_cast<int>(iv.size()), nullptr)) {
-        TRY_LOG_ERROR("EVP_CIPHER_CTX_ctrl() error");
-        goto opensslError;
-    }
-    if (1 != EVP_EncryptInit_ex(ctx, nullptr, nullptr, key.data(), iv.data())) {
-        TRY_LOG_ERROR("EVP_EncryptInit_ex() error");
-        goto opensslError;
-    }
-    if (1 != EVP_EncryptUpdate(ctx, nullptr, &len, aad.data(), static_cast<int>(aad.size()))) {
-        TRY_LOG_ERROR("EVP_EncryptUpdate() error");
-        goto opensslError;
-    }
+        EVP_CIPHER_CTX_ctrl(
+            ctx.get(), EVP_CTRL_GCM_SET_IVLEN, static_cast<int>(iv.size()), nullptr))
+        THROW_OPENSSL("EVP_CIPHER_CTX_ctrl() error");
+
+    if (1 != EVP_EncryptInit_ex(ctx.get(), nullptr, nullptr, key.data(), iv.data()))
+        THROW_OPENSSL("EVP_EncryptInit_ex() error");
+
+    if (1 != EVP_EncryptUpdate(ctx.get(), nullptr, &len, aad.data(), static_cast<int>(aad.size())))
+        THROW_OPENSSL("EVP_EncryptUpdate() error");
 
     if (1 !=
         EVP_EncryptUpdate(
-            ctx, output.data(), &len, plaintext.data(), static_cast<int>(plaintext.size()))) {
-        TRY_LOG_ERROR("EVP_EncryptUpdate() error");
-        goto opensslError;
-    }
+            ctx.get(), output.data(), &len, plaintext.data(), static_cast<int>(plaintext.size())))
+        THROW_OPENSSL("EVP_EncryptUpdate() error");
+
     outputLen = len;
 
-    if (1 != EVP_EncryptFinal_ex(ctx, output.data() + len, &len)) {
-        TRY_LOG_ERROR("EVP_EncryptFinal_ex() error");
-        goto opensslError;
-    }
+    if (1 != EVP_EncryptFinal_ex(ctx.get(), output.data() + len, &len))
+        THROW_OPENSSL("EVP_EncryptFinal_ex() error");
+
     outputLen += len;
 
-    if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, TAG_LEN, output.data() + outputLen)) {
-        TRY_LOG_ERROR("EVP_CIPHER_CTX_ctrl() error");
-        goto opensslError;
-    }
+    if (1 !=
+        EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, TAG_LEN, output.data() + outputLen))
+        THROW_OPENSSL("EVP_CIPHER_CTX_ctrl() error");
 
     assert(output.size() == outputLen + TAG_LEN);
-    EVP_CIPHER_CTX_free(ctx);
     return output;
-
-opensslError:
-    EVP_CIPHER_CTX_free(ctx);
-    throw OpensslError{};
 }
 
 CryptoBuffer DecryptAes256GCM(const CryptoBuffer &key,
@@ -148,78 +123,61 @@ CryptoBuffer DecryptAes256GCM(const CryptoBuffer &key,
                               const CryptoBuffer &aad,
                               const CryptoBuffer &ciphertext)
 {
-    if (key.size() != 32) {
-        LogError("Invalid key length");
-        throw OpensslError{};
-    }
+    if (key.size() != 32)
+        THROW_OPENSSL("Invalid key length");
+
     constexpr int TAG_LEN = 16;
-    if (ciphertext.size() < TAG_LEN) {
-        LogError("ciphertext length shorter than tag length");
-        throw OpensslError{};
-    }
+    if (ciphertext.size() < TAG_LEN)
+        THROW_OPENSSL("ciphertext length shorter than tag length");
 
-    EVP_CIPHER_CTX *ctx = nullptr;
     int len = 0;
     [[maybe_unused]] size_t outputLen = 0;
     CryptoBuffer output(ciphertext.size() - TAG_LEN);
 
-    ctx = EVP_CIPHER_CTX_new();
-    if (!ctx) {
-        TRY_LOG_ERROR("EVP_CIPHER_CTX_new() error");
-        goto opensslError;
-    }
-    if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr)) {
-        TRY_LOG_ERROR("EVP_DecryptInit_ex() error");
-        goto opensslError;
-    }
+    auto ctx = std::unique_ptr<EVP_CIPHER_CTX, decltype(&EVP_CIPHER_CTX_free)>{
+        EVP_CIPHER_CTX_new(), &EVP_CIPHER_CTX_free};
+    if (!ctx)
+        THROW_OPENSSL("EVP_CIPHER_CTX_new() error");
+
+    if (1 != EVP_DecryptInit_ex(ctx.get(), EVP_aes_256_gcm(), nullptr, nullptr, nullptr))
+        THROW_OPENSSL("EVP_DecryptInit_ex() error");
+
     if (1 !=
-        EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, static_cast<int>(iv.size()), nullptr)) {
-        TRY_LOG_ERROR("EVP_CIPHER_CTX_ctrl() error");
-        goto opensslError;
-    }
-    if (1 != EVP_DecryptInit_ex(ctx, nullptr, nullptr, key.data(), iv.data())) {
-        TRY_LOG_ERROR("EVP_DecryptInit_ex() error");
-        goto opensslError;
-    }
-    if (1 != EVP_DecryptUpdate(ctx, nullptr, &len, aad.data(), static_cast<int>(aad.size()))) {
-        TRY_LOG_ERROR("EVP_DecryptUpdate() error");
-        goto opensslError;
-    }
+        EVP_CIPHER_CTX_ctrl(
+            ctx.get(), EVP_CTRL_GCM_SET_IVLEN, static_cast<int>(iv.size()), nullptr))
+        THROW_OPENSSL("EVP_CIPHER_CTX_ctrl() error");
+
+    if (1 != EVP_DecryptInit_ex(ctx.get(), nullptr, nullptr, key.data(), iv.data()))
+        THROW_OPENSSL("EVP_DecryptInit_ex() error");
+
+    if (1 != EVP_DecryptUpdate(ctx.get(), nullptr, &len, aad.data(), static_cast<int>(aad.size())))
+        THROW_OPENSSL("EVP_DecryptUpdate() error");
 
     if (1 !=
-        EVP_DecryptUpdate(ctx,
+        EVP_DecryptUpdate(ctx.get(),
                           output.data(),
                           &len,
                           ciphertext.data(),
-                          static_cast<int>(ciphertext.size()) - TAG_LEN)) {
-        TRY_LOG_ERROR("EVP_DecryptUpdate() error");
-        goto opensslError;
-    }
+                          static_cast<int>(ciphertext.size()) - TAG_LEN))
+        THROW_OPENSSL("EVP_DecryptUpdate() error");
+
     outputLen = len;
 
     if (1 !=
-        EVP_CIPHER_CTX_ctrl(ctx,
+        EVP_CIPHER_CTX_ctrl(ctx.get(),
                             EVP_CTRL_GCM_SET_TAG,
                             TAG_LEN,
                             const_cast<void *>(static_cast<const void *>(
-                                ciphertext.data() + ciphertext.size() - TAG_LEN)))) {
-        TRY_LOG_ERROR("EVP_CIPHER_CTX_ctrl() error");
-        goto opensslError;
-    }
-
-    if (1 != EVP_DecryptFinal_ex(ctx, output.data() + len, &len)) {
-        TRY_LOG_ERROR("EVP_DecryptFinal_ex() error");
-        goto opensslError;
-    }
+                                ciphertext.data() + ciphertext.size() - TAG_LEN))))
+        THROW_OPENSSL("EVP_CIPHER_CTX_ctrl() error");
+
+    if (1 != EVP_DecryptFinal_ex(ctx.get(), output.data() + len, &len))
+        THROW_OPENSSL("EVP_DecryptFinal_ex() error");
+
     outputLen += len;
 
     assert(output.size() == outputLen);
-    EVP_CIPHER_CTX_free(ctx);
     return output;
-
-opensslError:
-    EVP_CIPHER_CTX_free(ctx);
-    throw OpensslError{};
 }
 
 } // namespace Crypto
index 5ac68c0b625885d6369445f50cd4b8abd0cee340..3305ed2fd571c0ea3e6370dc188db023d78a4451 100644 (file)
 
 #include "crypto/common.h"
 #include "crypto/hkdf.h"
-#include "crypto/openssl_error.h"
+#include "exception.h"
 #include "log/log.h"
 
 #include <cassert>
+#include <memory>
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 #include <openssl/kdf.h>
@@ -38,65 +39,47 @@ CryptoBuffer HkdfSha256(const CryptoBuffer &secret,
     if (derivedKeySize == 0)
         return derivedKey;
 
-    EVP_PKEY_CTX *ctx = nullptr;
     size_t outLen = derivedKeySize;
 
-    ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr);
-    if (!ctx) {
-        TRY_LOG_ERROR("EVP_PKEY_CTX_new_id() error");
-        goto opensslError;
-    }
-    if (EVP_PKEY_derive_init(ctx) <= 0) {
-        TRY_LOG_ERROR("EVP_PKEY_derive_init() error");
-        goto opensslError;
-    }
-    if (EVP_PKEY_CTX_set_hkdf_md(ctx, EVP_sha256()) <= 0) {
-        TRY_LOG_ERROR("EVP_PKEY_CTX_set_hkdf_md() error");
-        goto opensslError;
-    }
+    auto ctx = std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)>{
+        EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr), &EVP_PKEY_CTX_free};
+    if (!ctx)
+        THROW_OPENSSL("EVP_PKEY_CTX_new_id() error");
+
+    if (EVP_PKEY_derive_init(ctx.get()) <= 0)
+        THROW_OPENSSL("EVP_PKEY_derive_init() error");
+
+    if (EVP_PKEY_CTX_set_hkdf_md(ctx.get(), EVP_sha256()) <= 0)
+        THROW_OPENSSL("EVP_PKEY_CTX_set_hkdf_md() error");
+
     if (secret.empty()) {
         uint8_t key[EVP_MAX_MD_SIZE];
         unsigned int len;
         // TODO: before openssl 3.0 EVP_PKEY_CTX_set1_hkdf_key() does not allow zero-length argument
         // See issue: https://github.com/openssl/openssl/issues/8531
-        if (EVP_PKEY_CTX_hkdf_mode(ctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) != 1) {
-            TRY_LOG_ERROR("EVP_PKEY_CTX_hkdf_mode() error");
-            goto opensslError;
-        }
-        if (!HMAC(
-                EVP_sha256(), salt.data(), static_cast<int>(salt.size()), nullptr, 0, key, &len)) {
-            TRY_LOG_ERROR("HMAC() error");
-            goto opensslError;
-        }
-        if (EVP_PKEY_CTX_set1_hkdf_key(ctx, key, static_cast<int>(len)) != 1) {
-            TRY_LOG_ERROR("EVP_PKEY_CTX_set1_hkdf_key() error");
-            goto opensslError;
-        }
+        if (EVP_PKEY_CTX_hkdf_mode(ctx.get(), EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) != 1)
+            THROW_OPENSSL("EVP_PKEY_CTX_hkdf_mode() error");
+
+        if (!HMAC(EVP_sha256(), salt.data(), static_cast<int>(salt.size()), nullptr, 0, key, &len))
+            THROW_OPENSSL("HMAC() error");
+
+        if (EVP_PKEY_CTX_set1_hkdf_key(ctx.get(), key, static_cast<int>(len)) != 1)
+            THROW_OPENSSL("EVP_PKEY_CTX_set1_hkdf_key() error");
     } else {
-        if (EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt.data(), static_cast<int>(salt.size())) <= 0) {
-            TRY_LOG_ERROR("EVP_PKEY_CTX_set1_hkdf_salt() error");
-            goto opensslError;
-        }
-        if (EVP_PKEY_CTX_set1_hkdf_key(ctx, secret.data(), static_cast<int>(secret.size())) <= 0) {
-            TRY_LOG_ERROR("EVP_PKEY_CTX_set1_hkdf_key() error");
-            goto opensslError;
-        }
-    }
-    if (EVP_PKEY_CTX_add1_hkdf_info(ctx, info.data(), static_cast<int>(info.size())) <= 0) {
-        TRY_LOG_ERROR("EVP_PKEY_CTX_add1_hkdf_info() error");
-        goto opensslError;
-    }
-    if (EVP_PKEY_derive(ctx, derivedKey.data(), &outLen) <= 0) {
-        TRY_LOG_ERROR("EVP_PKEY_derive() error");
-        goto opensslError;
+        if (EVP_PKEY_CTX_set1_hkdf_salt(ctx.get(), salt.data(), static_cast<int>(salt.size())) <= 0)
+            THROW_OPENSSL("EVP_PKEY_CTX_set1_hkdf_salt() error");
+
+        if (EVP_PKEY_CTX_set1_hkdf_key(ctx.get(), secret.data(), static_cast<int>(secret.size())) <=
+            0)
+            THROW_OPENSSL("EVP_PKEY_CTX_set1_hkdf_key() error");
     }
+    if (EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), info.data(), static_cast<int>(info.size())) <= 0)
+        THROW_OPENSSL("EVP_PKEY_CTX_add1_hkdf_info() error");
 
-    EVP_PKEY_CTX_free(ctx);
-    return derivedKey;
+    if (EVP_PKEY_derive(ctx.get(), derivedKey.data(), &outLen) <= 0)
+        THROW_OPENSSL("EVP_PKEY_derive() error");
 
-opensslError:
-    EVP_PKEY_CTX_free(ctx);
-    throw OpensslError{};
+    return derivedKey;
 }
 
 } // namespace Crypto
index 6d922d53246c9c62b812302530798b18bc0b4f91..56d1ea7864cbc3f4378ad3d2c66dca1c9a1f4f88 100644 (file)
@@ -15,7 +15,7 @@
  */
 #include "crypto/common.h"
 #include "crypto/hmac.h"
-#include "crypto/openssl_error.h"
+#include "exception.h"
 #include "log/log.h"
 
 #include <cassert>
@@ -36,8 +36,7 @@ CryptoBuffer HmacSha256(const CryptoBuffer &key, const CryptoBuffer &data)
               data.size(),
               digest.data(),
               &digestLen)) {
-        LogError("HMAC() error");
-        throw OpensslError{};
+        THROW_OPENSSL("HMAC() error");
     }
 
     digest.resize(digestLen);
index 8ee44842d82db44006f9b9fd185a55e7b56c8b04..3556dcacfb4147de5466bc98d3efd2ade0cdbaa7 100644 (file)
 #pragma once
 
 #include <exception>
+#include <string>
 
 namespace Crypto {
 
 class OpensslError : public std::exception {
 public:
-    [[nodiscard]] const char *what() const noexcept override { return "openssl error"; }
+    explicit OpensslError(const std::string &messageIn) : message(messageIn) {}
+
+    [[nodiscard]] const char *what() const noexcept override { return message.c_str(); }
+
+protected:
+    std::string message;
 };
 
 } // namespace Crypto
index 24e2c156979d15b302b94c1f91bf61dda74e9708..d4adaa8457b3a94e315112f7a1b311ba28784c96 100644 (file)
@@ -15,8 +15,8 @@
  */
 
 #include "crypto/common.h"
-#include "crypto/openssl_error.h"
 #include "crypto/random.h"
+#include "exception.h"
 #include "log/log.h"
 
 #include <openssl/rand.h>
@@ -28,8 +28,7 @@ CryptoBuffer RandomBytes(size_t bytes)
     CryptoBuffer random(bytes);
 
     if (RAND_bytes(random.data(), static_cast<int>(random.size())) <= 0) {
-        LogError("RAND_bytes() error");
-        throw OpensslError{};
+        THROW_OPENSSL("RAND_bytes() error");
     }
 
     return random;
index f1f4bdda28ffddb8eaeaf63c6b95e3243262c628..30f966bc80b8eebd8bb643d462b0e793d03ba9bf 100644 (file)
@@ -15,8 +15,8 @@
  */
 
 #include "crypto/common.h"
-#include "crypto/openssl_error.h"
 #include "crypto/sha2.h"
+#include "exception.h"
 #include "log/log.h"
 
 #include <openssl/sha.h>
@@ -28,8 +28,7 @@ CryptoBuffer Sha256Hash(const CryptoBuffer &data)
     CryptoBuffer digest(SHA256_DIGEST_LENGTH);
 
     if (!SHA256(data.data(), data.size(), digest.data())) {
-        LogError("SHA256() error");
-        throw OpensslError{};
+        THROW_OPENSSL("SHA256() error");
     }
 
     return digest;
index 071a376af39f4398dc0a3a41db78dadd139b9270..a8b4447c08bace60e3a750e0fe842e9cf2603be1 100644 (file)
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include "crypto/openssl_error.h"
 #include "log/log.h"
 
 #include <stdexcept>
@@ -71,5 +72,6 @@ using Uncontactable = Exception<WAUTHN_ERROR_CONNECTION_REFUSED>;
 #define THROW_TIMEOUT(...) ERROR_LOGGED_THROW(::Exception::Timeout, __VA_ARGS__)
 #define THROW_UNCONTACTABLE() \
     ERROR_LOGGED_THROW(::Exception::Uncontactable, "Authenticator is uncontactable")
+#define THROW_OPENSSL(...) ERROR_LOGGED_THROW(Crypto::OpensslError, __VA_ARGS__)
 
 #define THROW_CANCELLED() DEBUG_LOGGED_THROW(::Exception::Cancelled, "Operation cancelled")
index 2c20ae111b5e620a73ca8e4732a9e0701a69eb52..07fb911077bd2dfa30497a649752cf28e0a0451a 100644 (file)
@@ -271,7 +271,10 @@ TEST(BtAdvertScanner, successful_await_advert_android_or_new_iphone_Positive)
     SuccessfulAwaitAdvertTest("FFF9");
 }
 
-TEST(BtAdvertScanner, successful_await_advert_old_iphone_Positive) { SuccessfulAwaitAdvertTest("FDE2"); }
+TEST(BtAdvertScanner, successful_await_advert_old_iphone_Positive)
+{
+    SuccessfulAwaitAdvertTest("FDE2");
+}
 
 TEST(BtAdvertScanner, await_advert_fails_because_bluetooth_is_turned_off_Negative)
 {
@@ -490,3 +493,48 @@ TEST(UnpackDecryptedAdvert, first_byte_is_non_0_Negative)
                 testing::ThrowsMessage<std::runtime_error>(
                     "First byte of decrypted advert should have value 0"));
 }
+
+TEST(UnpackDecryptedAdvert, validate_bluetooth_errors_Positive)
+{
+    std::map<int, std::string> errors = {
+        {BT_ERROR_NONE,                        "BT_ERROR_NONE"                       },
+        {BT_ERROR_CANCELLED,                   "BT_ERROR_CANCELLED"                  },
+        {BT_ERROR_INVALID_PARAMETER,           "BT_ERROR_INVALID_PARAMETER"          },
+        {BT_ERROR_OUT_OF_MEMORY,               "BT_ERROR_OUT_OF_MEMORY"              },
+        {BT_ERROR_RESOURCE_BUSY,               "BT_ERROR_RESOURCE_BUSY"              },
+        {BT_ERROR_TIMED_OUT,                   "BT_ERROR_TIMED_OUT"                  },
+        {BT_ERROR_NOW_IN_PROGRESS,             "BT_ERROR_NOW_IN_PROGRESS"            },
+        {BT_ERROR_NOT_SUPPORTED,               "BT_ERROR_NOT_SUPPORTED"              },
+        {BT_ERROR_PERMISSION_DENIED,           "BT_ERROR_PERMISSION_DENIED"          },
+        {BT_ERROR_QUOTA_EXCEEDED,              "BT_ERROR_QUOTA_EXCEEDED"             },
+        {BT_ERROR_NO_DATA,                     "BT_ERROR_NO_DATA"                    },
+        {BT_ERROR_DEVICE_POLICY_RESTRICTION,   "DEVICE_POLICY_RESTRICTION"           },
+        {BT_ERROR_NOT_INITIALIZED,             "BT_ERROR_NOT_INITIALIZED"            },
+        {BT_ERROR_NOT_ENABLED,                 "BT_ERROR_NOT_ENABLED"                },
+        {BT_ERROR_ALREADY_DONE,                "BT_ERROR_ALREADY_DONE"               },
+        {BT_ERROR_OPERATION_FAILED,            "BT_ERROR_OPERATION_FAILED"           },
+        {BT_ERROR_NOT_IN_PROGRESS,             "BT_ERROR_NOT_IN_PROGRESS"            },
+        {BT_ERROR_REMOTE_DEVICE_NOT_BONDED,    "BT_ERROR_REMOTE_DEVICE_NOT_BONDED"   },
+        {BT_ERROR_AUTH_REJECTED,               "BT_ERROR_AUTH_REJECTED"              },
+        {BT_ERROR_AUTH_FAILED,                 "BT_ERROR_AUTH_FAILED"                },
+        {BT_ERROR_REMOTE_DEVICE_NOT_FOUND,     "BT_ERROR_REMOTE_DEVICE_NOT_FOUND"    },
+        {BT_ERROR_SERVICE_SEARCH_FAILED,       "BT_ERROR_SERVICE_SEARCH_FAILED"      },
+        {BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED, "BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED"},
+        {BT_ERROR_AGAIN,                       "BT_ERROR_AGAIN"                      },
+        {BT_ERROR_SERVICE_NOT_FOUND,           "BT_ERROR_SERVICE_NOT_FOUND"          },
+        {BT_ERROR_AUTHORIZATION_REJECTED,      "BT_ERROR_AUTHORIZATION_REJECTED"     },
+    };
+
+    for (const auto &[index, error] : errors) {
+        EXPECT_EQ(BtErrorToString(index), error);
+    }
+}
+
+#ifdef EMULATOR_BUILD
+TEST(BtAdvertScanner, BluetoothInitialize_Negative)
+{
+    Bluetooth bt;
+    int err;
+    ASSERT_EQ(err = bt.Initialize(), BT_ERROR_NOT_SUPPORTED) << BtErrorToString(err);
+}
+#endif
index ffd3198cd05f8b68ef5269519d2d5714c8c786f4..efc83a9f93e6cb4648872e3118b6f844ab03dcf3 100644 (file)
@@ -1240,11 +1240,11 @@ TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInContainerAppendBoolean_Negat
                                     2 - 1,
                                     auto array = encoder.OpenArray(1),
                                     EXPECT_THROW(array.AppendBoolean(true), EncodingFailed))
-TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInContainerAppendByteStringOfWauthnBuffer_Negative,
-                                    2 - 1,
-                                    auto array = encoder.OpenArray(1),
-                                    EXPECT_THROW(array.AppendByteString(wauthn_const_buffer_s{}),
-                                                 EncodingFailed))
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(
+    TooShortBufferInContainerAppendByteStringOfWauthnBuffer_Negative,
+    2 - 1,
+    auto array = encoder.OpenArray(1),
+    EXPECT_THROW(array.AppendByteString(wauthn_const_buffer_s{}), EncodingFailed))
 
 // Too short buffer map encoding tests
 TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInSortedMapAppendByteStringAtOfBuffer_Negative,
@@ -1546,7 +1546,9 @@ TEST_CBOR_PARSING(SortedMapArrayInEnterMapAt_Negative,
                   "\xa1\x07\x81\x07",
                   EXPECT_THROW(parser.EnterMap().EnterMapAt(7), Unknown),
                   {})
-TEST_CBOR_PARSING(SortedMapEmptyMapInEnterMapAt_Positive, "\xa1\x07\xa0", auto outerMap = parser.EnterMap();
+TEST_CBOR_PARSING(SortedMapEmptyMapInEnterMapAt_Positive,
+                  "\xa1\x07\xa0",
+                  auto outerMap = parser.EnterMap();
                   // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
                   auto map = outerMap.EnterMapAt(7).value(),
                   EXPECT_EQ(map.GetInt64At(CborParsing::CURRENT_KEY), std::nullopt))
@@ -1621,14 +1623,20 @@ TEST_CBOR_PARSING(SortedMapDifferentValueInGetInt64At_Negative,
                   "\xa1\x60\x40",
                   auto map = parser.EnterMap(),
                   { EXPECT_THROW(map.GetInt64At(CborParsing::CURRENT_KEY), Unknown); })
-TEST_CBOR_PARSING(SortedMapNullKeyInGetInt64At_Negative, "\xa1\xF6\x07", auto map = parser.EnterMap(), {
-    EXPECT_EQ(map.GetInt64At(""), std::nullopt);
-    EXPECT_THROW(map.GetInt64At(CborParsing::CURRENT_KEY), Unknown);
-})
-TEST_CBOR_PARSING(SortedMapUndefinedKeyInGetInt64At_Negative, "\xa1\xF7\x07", auto map = parser.EnterMap(), {
-    EXPECT_EQ(map.GetInt64At(""), std::nullopt);
-    EXPECT_THROW(map.GetInt64At(CborParsing::CURRENT_KEY), Unknown);
-})
+TEST_CBOR_PARSING(SortedMapNullKeyInGetInt64At_Negative,
+                  "\xa1\xF6\x07",
+                  auto map = parser.EnterMap(),
+                  {
+                      EXPECT_EQ(map.GetInt64At(""), std::nullopt);
+                      EXPECT_THROW(map.GetInt64At(CborParsing::CURRENT_KEY), Unknown);
+                  })
+TEST_CBOR_PARSING(SortedMapUndefinedKeyInGetInt64At_Negative,
+                  "\xa1\xF7\x07",
+                  auto map = parser.EnterMap(),
+                  {
+                      EXPECT_EQ(map.GetInt64At(""), std::nullopt);
+                      EXPECT_THROW(map.GetInt64At(CborParsing::CURRENT_KEY), Unknown);
+                  })
 
 // GetTextStringAt tests
 TEST_CBOR_PARSING(SortedMapCurrentIntKeyInGetTextStringAt_Positive,
@@ -1840,10 +1848,13 @@ TEST_CBOR_PARSING(SortedMapUndefinedKeyInGetBooleanAt_Negative,
                       EXPECT_EQ(map.GetBooleanAt(""), std::nullopt);
                       EXPECT_THROW(map.GetBooleanAt(CborParsing::CURRENT_KEY), Unknown);
                   })
-TEST_CBOR_PARSING(SortedMapNullKeyInGetBooleanAt_Negative, "\xa1\xF6\xF5", auto map = parser.EnterMap(), {
-    EXPECT_EQ(map.GetBooleanAt(""), std::nullopt);
-    EXPECT_THROW(map.GetBooleanAt(CborParsing::CURRENT_KEY), Unknown);
-})
+TEST_CBOR_PARSING(SortedMapNullKeyInGetBooleanAt_Negative,
+                  "\xa1\xF6\xF5",
+                  auto map = parser.EnterMap(),
+                  {
+                      EXPECT_EQ(map.GetBooleanAt(""), std::nullopt);
+                      EXPECT_THROW(map.GetBooleanAt(CborParsing::CURRENT_KEY), Unknown);
+                  })
 
 // GetUInt64At tests
 TEST_CBOR_PARSING(SortedMapIntKeyInGetUint64At_Positive,
@@ -1908,10 +1919,13 @@ TEST_CBOR_PARSING(SortedMapUndefinedKeyInGetUint64At_Negative,
                       EXPECT_EQ(map.GetUint64At(""), std::nullopt);
                       EXPECT_THROW(map.GetUint64At(CborParsing::CURRENT_KEY), Unknown);
                   })
-TEST_CBOR_PARSING(SortedMapNullKeyInGetUint64At_Negative, "\xa1\xF6\x07", auto map = parser.EnterMap(), {
-    EXPECT_EQ(map.GetUint64At(""), std::nullopt);
-    EXPECT_THROW(map.GetUint64At(CborParsing::CURRENT_KEY), Unknown);
-})
+TEST_CBOR_PARSING(SortedMapNullKeyInGetUint64At_Negative,
+                  "\xa1\xF6\x07",
+                  auto map = parser.EnterMap(),
+                  {
+                      EXPECT_EQ(map.GetUint64At(""), std::nullopt);
+                      EXPECT_THROW(map.GetUint64At(CborParsing::CURRENT_KEY), Unknown);
+                  })
 
 // PeekKey tests
 TEST_CBOR_PARSING(SortedMapIntKeyInPeekKey_Positive,
index 4fb4cbea0932a76badd012cafdc31eabeb14ccf2..19e113f7ad352f992f10fd11fe504f9a117bd15a 100644 (file)
@@ -15,6 +15,8 @@
  */
 
 #include "crypto/ec_key.h"
+#include "crypto/openssl_error.h"
+#include "exception.h"
 
 #include <gtest/gtest.h>
 #include <unordered_map>
@@ -271,3 +273,9 @@ TEST(ECKeyTest, ImportExportTestVectorSecp521r1_Positive)
     ImportExportTestVector<ECKey::Curve::SECP521R1>(
         PRIV_KEY, PUB_KEY, PUB_KEY_COMPRESSED, X, Y, PUB_KEY_DER);
 }
+
+TEST(ECKeyTest, CreateNonExistentCurve_Negative)
+{
+    const auto invalid_curve = static_cast<ECKey::Curve>(5);
+    EXPECT_THROW(ECKey::Create(invalid_curve), Exception::Unknown);
+}
index 3d72f25a1f991b8f126a748e65f6011d5a23d27c..dcf0600e40e6432e646ff64f3ee2ec0aee84b632 100644 (file)
@@ -724,7 +724,8 @@ private:
 
 } // namespace
 
-TEST(CtapMessageProcessor, MakeCredential_without_update_message_cancel_from_the_other_thread_Positive)
+TEST(CtapMessageProcessor,
+     MakeCredential_without_update_message_cancel_from_the_other_thread_Positive)
 {
     auto makeCMP = [&] {
         auto cmp = std::make_unique<CtapMessageProcessor>();
@@ -763,7 +764,8 @@ TEST(CtapMessageProcessor, MakeCredential_with_update_message_cancel_from_the_ot
         });
 }
 
-TEST(CtapMessageProcessor, GetAssertion_without_update_message_cancel_from_the_other_thread_Positive)
+TEST(CtapMessageProcessor,
+     GetAssertion_without_update_message_cancel_from_the_other_thread_Positive)
 {
     auto makeCMP = [&] {
         auto cmp = std::make_unique<CtapMessageProcessor>();
@@ -864,7 +866,8 @@ TEST(CtapMessageProcessor, ProcessFollowingUpdateMsgs_invalid_message_type_Negat
     EXPECT_EQ(encryptedTunnel->m_called, "CloseConnectionAfter;ReadBinary;");
 }
 
-TEST(CtapMessageProcessor, ProcessFollowingUpdateMsgs_parse_error_of_the_truncated_update_message_Negative)
+TEST(CtapMessageProcessor,
+     ProcessFollowingUpdateMsgs_parse_error_of_the_truncated_update_message_Negative)
 {
     const auto EXAMPLE_UPDATE_MSG = BUFFER_VIEW(ANDROID_EXAMPLE_RAW_UPDATE_MSG);
     for (size_t len = 0; len + 1 < EXAMPLE_UPDATE_MSG.size(); ++len) {
index ee52b113e20a5524342988e4f6cd301a46bcc5a7..906a479af4268d3a64447dd8953e85418182d563 100644 (file)
@@ -763,3 +763,26 @@ TEST(Messages, ParseUpdateMessage_Positive)
     EXPECT_EQ(ToBufferView(linkData.m_authenticatorName), (BufferView{blob + 451, 5}));
     EXPECT_EQ(ToBufferView(linkData.m_handshakeSignature), (BufferView{blob + 459, 32}));
 }
+
+TEST(Messages, MakeCredentialResponse_Negative)
+{
+    MakeCredentialResponse msg;
+    auto cborUnexpectedType = BUFFER_VIEW("\x11");
+    auto errorProcessing = BUFFER_VIEW("\x21");
+    auto unsupportedAlgorithm = BUFFER_VIEW("\x26");
+    auto missingParameter = BUFFER_VIEW("\x14");
+    auto operationDenied = BUFFER_VIEW("\x27");
+    auto keyStoreFull = BUFFER_VIEW("\x28");
+    auto userActionTimeout = BUFFER_VIEW("\x2F");
+    auto pinBlocked = BUFFER_VIEW("\x32");
+    auto credentialExcluded = BUFFER_VIEW("\x19");
+    EXPECT_THROW(msg.Deserialize(cborUnexpectedType), Exception::EncodingFailed);
+    EXPECT_THROW(msg.Deserialize(errorProcessing), Exception::InvalidState);
+    EXPECT_THROW(msg.Deserialize(unsupportedAlgorithm), Exception::NotSupported);
+    EXPECT_THROW(msg.Deserialize(missingParameter), Exception::InvalidParam);
+    EXPECT_THROW(msg.Deserialize(operationDenied), Exception::PermissionDenied);
+    EXPECT_THROW(msg.Deserialize(keyStoreFull), Exception::InvalidState);
+    EXPECT_THROW(msg.Deserialize(userActionTimeout), Exception::Timeout);
+    EXPECT_THROW(msg.Deserialize(pinBlocked), Exception::InvalidState);
+    EXPECT_THROW(msg.Deserialize(credentialExcluded), Exception::NotAllowed);
+}
index 6cbf6a05c0ed42abd712a8aa83d4db3ac339028d..035fb49cfb8e3d82a01ee499c86f2093687fd250 100644 (file)
@@ -452,7 +452,8 @@ TEST(RequestHandler, transaction_is_not_performed_with_nullptr_callbacks_Negativ
         [](auto &test) { EXPECT_EQ(test.called, ""); });
 }
 
-TEST(RequestHandler, qr_initiated_transaction_is_not_performed_with_nullptr_qrcode_callback_Negative)
+TEST(RequestHandler,
+     qr_initiated_transaction_is_not_performed_with_nullptr_qrcode_callback_Negative)
 {
     TestBothQrTransactions<InvalidParamsTest>(
         [](auto &test, auto &options) {
@@ -796,7 +797,10 @@ TEST(RequestHandler, response_callback_throws_runtime_error_Negative)
     TestResponseCallbackThrows<ThrowRuntimeError>();
 }
 
-TEST(RequestHandler, response_callback_throws_int_Negative) { TestResponseCallbackThrows<ThrowInt>(); }
+TEST(RequestHandler, response_callback_throws_int_Negative)
+{
+    TestResponseCallbackThrows<ThrowInt>();
+}
 
 namespace {
 
@@ -1476,7 +1480,8 @@ TEST(RequestHandler, two_simultaneous_requests_Positive)
         });
 }
 
-TEST(RequestHandler, two_requests_second_one_executes_while_the_first_awaits_update_messages_Positive)
+TEST(RequestHandler,
+     two_requests_second_one_executes_while_the_first_awaits_update_messages_Positive)
 {
     RunWithAll4x4Combinations<SuccessfulRequestTest, SuccessfulRequestTest>(
         [&](const auto &firstRequestTest, const auto &secondRequestTest) {