diff --git a/.clang-format b/.clang-format index 418529df..b5771160 100644 --- a/.clang-format +++ b/.clang-format @@ -7,6 +7,7 @@ Standard: c++14 # Indentation IndentWidth: 2 ColumnLimit: 140 +AccessModifierOffset: -1 # Includes SortIncludes: CaseSensitive diff --git a/.github/workflows/validate-cpp.yml b/.github/workflows/validate-cpp.yml index cb4da4f5..db55f1d7 100644 --- a/.github/workflows/validate-cpp.yml +++ b/.github/workflows/validate-cpp.yml @@ -22,11 +22,18 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Set up clang-format + run: sudo apt-get install -y clang-format + - name: Run clang-format check + run: | + find packages/react-native-quick-crypto/cpp packages/react-native-quick-crypto/android/src/main/cpp \ + -regex '.*\.\(cpp\|hpp\|cc\|cxx\|h\)' \ + -exec clang-format --style=file --dry-run --Werror {} + - uses: reviewdog/action-cpplint@master with: github_token: ${{ secrets.github_token }} reporter: github-pr-review - flags: --linelength=230 + flags: --linelength=140 targets: --recursive packages/react-native-quick-crypto/cpp packages/react-native-quick-crypto/android/src/main/cpp filter: "-legal/copyright\ ,-readability/todo\ @@ -35,4 +42,5 @@ jobs: ,-build/include_order\ ,-whitespace/indent_namespace\ ,-whitespace/parens\ + ,-build/include_what_you_use\ " diff --git a/package.json b/package.json index 0b28147b..96729698 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "version": "1.0.0-beta.12", "scripts": { - "check-all": "./scripts/clang-format.sh", + "clang-format": "./scripts/clang-format.sh", "clean": "bun --filter='*' clean", "specs": "bun --filter='react-native-quick-crypto' specs", "bundle-install": "bun --filter='react-native-quick-crypto-example' bundle-install", diff --git a/packages/react-native-quick-crypto/cpp/ed25519/HybridEdKeyPair.cpp b/packages/react-native-quick-crypto/cpp/ed25519/HybridEdKeyPair.cpp index 6d9f8a32..5caba089 100644 --- a/packages/react-native-quick-crypto/cpp/ed25519/HybridEdKeyPair.cpp +++ b/packages/react-native-quick-crypto/cpp/ed25519/HybridEdKeyPair.cpp @@ -5,45 +5,23 @@ namespace margelo::nitro::crypto { -std::shared_ptr> -HybridEdKeyPair::generateKeyPair( - double publicFormat, - double publicType, - double privateFormat, - double privateType, - const std::optional& cipher, - const std::optional>& passphrase -) { +std::shared_ptr> HybridEdKeyPair::generateKeyPair(double publicFormat, double publicType, double privateFormat, + double privateType, const std::optional& cipher, + const std::optional>& passphrase) { // get owned NativeArrayBuffers before passing to sync function std::optional> nativePassphrase = std::nullopt; if (passphrase.has_value()) { nativePassphrase = ToNativeArrayBuffer(passphrase.value()); } - return Promise::async( - [this, publicFormat, publicType, privateFormat, privateType, cipher, - nativePassphrase]() { - this->generateKeyPairSync( - publicFormat, - publicType, - privateFormat, - privateType, - cipher, - nativePassphrase - ); - } - ); + return Promise::async([this, publicFormat, publicType, privateFormat, privateType, cipher, nativePassphrase]() { + this->generateKeyPairSync(publicFormat, publicType, privateFormat, privateType, cipher, nativePassphrase); + }); } -void -HybridEdKeyPair::generateKeyPairSync( - double publicFormat, - double publicType, - double privateFormat, - double privateType, - const std::optional& cipher, - const std::optional>& passphrase -) { +void HybridEdKeyPair::generateKeyPairSync(double publicFormat, double publicType, double privateFormat, double privateType, + const std::optional& cipher, + const std::optional>& passphrase) { EVP_PKEY_CTX* pctx; // key context @@ -69,12 +47,8 @@ HybridEdKeyPair::generateKeyPairSync( EVP_PKEY_CTX_free(pctx); } - -std::shared_ptr>> -HybridEdKeyPair::sign( - const std::shared_ptr& message, - const std::optional>& key -) { +std::shared_ptr>> HybridEdKeyPair::sign(const std::shared_ptr& message, + const std::optional>& key) { // get owned NativeArrayBuffer before passing to sync function auto nativeMessage = ToNativeArrayBuffer(message); std::optional> nativeKey = std::nullopt; @@ -82,17 +56,12 @@ HybridEdKeyPair::sign( nativeKey = ToNativeArrayBuffer(key.value()); } - return Promise>::async([this, nativeMessage, nativeKey]() { - return this->signSync(nativeMessage, nativeKey); - } - ); + return Promise>::async( + [this, nativeMessage, nativeKey]() { return this->signSync(nativeMessage, nativeKey); }); } -std::shared_ptr -HybridEdKeyPair::signSync( - const std::shared_ptr& message, - const std::optional>& key -) { +std::shared_ptr HybridEdKeyPair::signSync(const std::shared_ptr& message, + const std::optional>& key) { size_t sig_len = 0; uint8_t* sig = NULL; @@ -135,11 +104,7 @@ HybridEdKeyPair::signSync( } // return value for JS - std::shared_ptr signature = std::make_shared( - sig, - sig_len, - [=]() { delete[] sig; } - ); + std::shared_ptr signature = std::make_shared(sig, sig_len, [=]() { delete[] sig; }); // Clean up EVP_MD_CTX_free(md_ctx); @@ -147,12 +112,9 @@ HybridEdKeyPair::signSync( return signature; } -std::shared_ptr> -HybridEdKeyPair::verify( - const std::shared_ptr& signature, - const std::shared_ptr& message, - const std::optional>& key -) { +std::shared_ptr> HybridEdKeyPair::verify(const std::shared_ptr& signature, + const std::shared_ptr& message, + const std::optional>& key) { // get owned NativeArrayBuffers before passing to sync function auto nativeSignature = ToNativeArrayBuffer(signature); auto nativeMessage = ToNativeArrayBuffer(message); @@ -161,18 +123,12 @@ HybridEdKeyPair::verify( nativeKey = ToNativeArrayBuffer(key.value()); } - return Promise::async([this, nativeSignature, nativeMessage, nativeKey]() { - return this->verifySync(nativeSignature, nativeMessage, nativeKey); - } - ); + return Promise::async( + [this, nativeSignature, nativeMessage, nativeKey]() { return this->verifySync(nativeSignature, nativeMessage, nativeKey); }); } -bool -HybridEdKeyPair::verifySync( - const std::shared_ptr& signature, - const std::shared_ptr& message, - const std::optional>& key -) { +bool HybridEdKeyPair::verifySync(const std::shared_ptr& signature, const std::shared_ptr& message, + const std::optional>& key) { // get key to use for verifying EVP_PKEY* pkey = this->importPrivateKey(key); @@ -199,13 +155,9 @@ HybridEdKeyPair::verifySync( } // verify - auto res = EVP_DigestVerify( - md_ctx, - signature.get()->data(), signature.get()->size(), - message.get()->data(), message.get()->size() - ); + auto res = EVP_DigestVerify(md_ctx, signature.get()->data(), signature.get()->size(), message.get()->data(), message.get()->size()); - //return value for JS + // return value for JS if (res < 0) { EVP_MD_CTX_free(md_ctx); throw std::runtime_error("Failed to verify"); @@ -213,8 +165,7 @@ HybridEdKeyPair::verifySync( return res == 1; // true if 1, false if 0 } -std::shared_ptr -HybridEdKeyPair::getPublicKey() { +std::shared_ptr HybridEdKeyPair::getPublicKey() { this->checkKeyPair(); size_t len = 32; uint8_t* publ = new uint8_t[len]; @@ -223,8 +174,7 @@ HybridEdKeyPair::getPublicKey() { return std::make_shared(publ, len, [=]() { delete[] publ; }); } -std::shared_ptr -HybridEdKeyPair::getPrivateKey() { +std::shared_ptr HybridEdKeyPair::getPrivateKey() { this->checkKeyPair(); size_t len = 32; uint8_t* priv = new uint8_t[len]; @@ -233,28 +183,21 @@ HybridEdKeyPair::getPrivateKey() { return std::make_shared(priv, len, [=]() { delete[] priv; }); } -void -HybridEdKeyPair::checkKeyPair() { +void HybridEdKeyPair::checkKeyPair() { if (this->pkey == nullptr) { throw std::runtime_error("Keypair not initialized"); } } -void -HybridEdKeyPair::setCurve(const std::string& curve) { +void HybridEdKeyPair::setCurve(const std::string& curve) { this->curve = curve; } -EVP_PKEY* -HybridEdKeyPair::importPrivateKey(const std::optional>& key) { +EVP_PKEY* HybridEdKeyPair::importPrivateKey(const std::optional>& key) { EVP_PKEY* pkey = nullptr; if (key.has_value()) { - pkey = EVP_PKEY_new_raw_private_key( - EVP_PKEY_ED25519, // TODO: use this->curve somehow - NULL, - key.value()->data(), - 32 - ); + pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, // TODO: use this->curve somehow + NULL, key.value()->data(), 32); if (pkey == nullptr) { throw std::runtime_error("Failed to read private key"); } diff --git a/packages/react-native-quick-crypto/cpp/ed25519/HybridEdKeyPair.hpp b/packages/react-native-quick-crypto/cpp/ed25519/HybridEdKeyPair.hpp index 42eb14d9..cd538684 100644 --- a/packages/react-native-quick-crypto/cpp/ed25519/HybridEdKeyPair.hpp +++ b/packages/react-native-quick-crypto/cpp/ed25519/HybridEdKeyPair.hpp @@ -1,6 +1,6 @@ -#include -#include #include +#include +#include #include #include "HybridEdKeyPairSpec.hpp" @@ -16,58 +16,30 @@ class HybridEdKeyPair : public HybridEdKeyPairSpec { public: // Methods - std::shared_ptr> - generateKeyPair( - double publicFormat, - double publicType, - double privateFormat, - double privateType, - const std::optional& cipher, - const std::optional>& passphrase - ) override; - - void - generateKeyPairSync( - double publicFormat, - double publicType, - double privateFormat, - double privateType, - const std::optional& cipher, - const std::optional>& passphrase - ) override; - - std::shared_ptr>> - sign( - const std::shared_ptr& message, - const std::optional>& key - ) override; - - std::shared_ptr - signSync( - const std::shared_ptr& message, - const std::optional>& key - ) override; - - std::shared_ptr> - verify( - const std::shared_ptr& signature, - const std::shared_ptr& message, - const std::optional>& key - ) override; - - bool - verifySync( - const std::shared_ptr& signature, - const std::shared_ptr& message, - const std::optional>& key - ) override; + std::shared_ptr> generateKeyPair(double publicFormat, double publicType, double privateFormat, double privateType, + const std::optional& cipher, + const std::optional>& passphrase) override; + + void generateKeyPairSync(double publicFormat, double publicType, double privateFormat, double privateType, + const std::optional& cipher, + const std::optional>& passphrase) override; + + std::shared_ptr>> sign(const std::shared_ptr& message, + const std::optional>& key) override; + + std::shared_ptr signSync(const std::shared_ptr& message, + const std::optional>& key) override; + + std::shared_ptr> verify(const std::shared_ptr& signature, const std::shared_ptr& message, + const std::optional>& key) override; + + bool verifySync(const std::shared_ptr& signature, const std::shared_ptr& message, + const std::optional>& key) override; protected: - std::shared_ptr - getPublicKey() override; + std::shared_ptr getPublicKey() override; - std::shared_ptr - getPrivateKey() override; + std::shared_ptr getPrivateKey() override; void checkKeyPair(); @@ -77,9 +49,7 @@ class HybridEdKeyPair : public HybridEdKeyPairSpec { std::string curve; EVP_PKEY* pkey = nullptr; - EVP_PKEY* importPrivateKey( - const std::optional>& key - ); + EVP_PKEY* importPrivateKey(const std::optional>& key); }; } // namespace margelo::nitro::crypto diff --git a/packages/react-native-quick-crypto/cpp/hash/HybridHash.cpp b/packages/react-native-quick-crypto/cpp/hash/HybridHash.cpp index 4a5b386d..6c790e4c 100644 --- a/packages/react-native-quick-crypto/cpp/hash/HybridHash.cpp +++ b/packages/react-native-quick-crypto/cpp/hash/HybridHash.cpp @@ -10,26 +10,21 @@ namespace margelo::nitro::crypto { -HybridHash::~HybridHash() -{ +HybridHash::~HybridHash() { if (ctx) { EVP_MD_CTX_free(ctx); ctx = nullptr; } } -void -HybridHash::createHash(const std::string& hashAlgorithmArg, - const std::optional outputLengthArg) -{ +void HybridHash::createHash(const std::string& hashAlgorithmArg, const std::optional outputLengthArg) { algorithm = hashAlgorithmArg; outputLength = outputLengthArg; // Create hash context ctx = EVP_MD_CTX_new(); if (!ctx) { - throw std::runtime_error("Failed to create hash context: " + - std::to_string(ERR_get_error())); + throw std::runtime_error("Failed to create hash context: " + std::to_string(ERR_get_error())); } // Get the message digest by name @@ -44,30 +39,22 @@ HybridHash::createHash(const std::string& hashAlgorithmArg, if (EVP_DigestInit_ex(ctx, md, nullptr) != 1) { EVP_MD_CTX_free(ctx); ctx = nullptr; - throw std::runtime_error("Failed to initialize hash digest: " + - std::to_string(ERR_get_error())); + throw std::runtime_error("Failed to initialize hash digest: " + std::to_string(ERR_get_error())); } } -void -HybridHash::update(const std::shared_ptr& data) -{ +void HybridHash::update(const std::shared_ptr& data) { if (!ctx) { throw std::runtime_error("Hash context not initialized"); } // Update the digest with the data - if (EVP_DigestUpdate(ctx, - reinterpret_cast(data->data()), - data->size()) != 1) { - throw std::runtime_error("Failed to update hash digest: " + - std::to_string(ERR_get_error())); + if (EVP_DigestUpdate(ctx, reinterpret_cast(data->data()), data->size()) != 1) { + throw std::runtime_error("Failed to update hash digest: " + std::to_string(ERR_get_error())); } } -std::shared_ptr -HybridHash::digest(const std::optional& encoding) -{ +std::shared_ptr HybridHash::digest(const std::optional& encoding) { if (!ctx) { throw std::runtime_error("Hash context not initialized"); } @@ -76,12 +63,10 @@ HybridHash::digest(const std::optional& encoding) // Get the default digest size const size_t defaultLen = EVP_MD_CTX_size(ctx); - const size_t digestSize = - (outputLength.has_value()) ? static_cast(*outputLength) : defaultLen; + const size_t digestSize = (outputLength.has_value()) ? static_cast(*outputLength) : defaultLen; if (digestSize < 0) { - throw std::runtime_error("Invalid digest size: " + - std::to_string(digestSize)); + throw std::runtime_error("Invalid digest size: " + std::to_string(digestSize)); } // Create a buffer for the hash output @@ -91,25 +76,20 @@ HybridHash::digest(const std::optional& encoding) // Finalize the digest int ret; if (digestSize == defaultLen) { - ret = EVP_DigestFinal_ex( - ctx, hashBuffer, reinterpret_cast(&hashLength)); + ret = EVP_DigestFinal_ex(ctx, hashBuffer, reinterpret_cast(&hashLength)); } else { ret = EVP_DigestFinalXOF(ctx, hashBuffer, hashLength); } if (ret != 1) { delete[] hashBuffer; - throw std::runtime_error("Failed to finalize hash digest: " + - std::to_string(ERR_get_error())); + throw std::runtime_error("Failed to finalize hash digest: " + std::to_string(ERR_get_error())); } - return std::make_shared( - hashBuffer, hashLength, [=]() { delete[] hashBuffer; }); + return std::make_shared(hashBuffer, hashLength, [=]() { delete[] hashBuffer; }); } -std::shared_ptr -HybridHash::copy(const std::optional outputLengthArg) -{ +std::shared_ptr HybridHash::copy(const std::optional outputLengthArg) { if (!ctx) { throw std::runtime_error("Hash context not initialized"); } @@ -117,42 +97,36 @@ HybridHash::copy(const std::optional outputLengthArg) // Create a new context EVP_MD_CTX* newCtx = EVP_MD_CTX_new(); if (!newCtx) { - throw std::runtime_error("Failed to create new hash context: " + - std::to_string(ERR_get_error())); + throw std::runtime_error("Failed to create new hash context: " + std::to_string(ERR_get_error())); } // Copy the existing context to the new one if (EVP_MD_CTX_copy(newCtx, ctx) != 1) { EVP_MD_CTX_free(newCtx); - throw std::runtime_error("Failed to copy hash context: " + - std::to_string(ERR_get_error())); + throw std::runtime_error("Failed to copy hash context: " + std::to_string(ERR_get_error())); } return std::make_shared(newCtx, md, algorithm, outputLengthArg); } -std::vector -HybridHash::getSupportedHashAlgorithms() -{ +std::vector HybridHash::getSupportedHashAlgorithms() { std::vector hashAlgorithms; EVP_MD_do_all_provided( - nullptr, - [](EVP_MD* md, void* arg) { - auto* algorithms = static_cast*>(arg); - const char* name = EVP_MD_get0_name(md); - if (name) { - algorithms->push_back(name); - } - }, - &hashAlgorithms); + nullptr, + [](EVP_MD* md, void* arg) { + auto* algorithms = static_cast*>(arg); + const char* name = EVP_MD_get0_name(md); + if (name) { + algorithms->push_back(name); + } + }, + &hashAlgorithms); return hashAlgorithms; } -void -HybridHash::setParams() -{ +void HybridHash::setParams() { // Handle algorithm parameters (like XOF length for SHAKE) if (outputLength.has_value()) { uint32_t xoflen = outputLength.value(); @@ -160,20 +134,16 @@ HybridHash::setParams() // Add a reasonable maximum output length const int MAX_OUTPUT_LENGTH = 16 * 1024 * 1024; // 16MB if (xoflen > MAX_OUTPUT_LENGTH) { - throw std::runtime_error("Output length " + std::to_string(xoflen) + - " exceeds maximum allowed size of " + + throw std::runtime_error("Output length " + std::to_string(xoflen) + " exceeds maximum allowed size of " + std::to_string(MAX_OUTPUT_LENGTH)); } - OSSL_PARAM params[] = { OSSL_PARAM_construct_uint("xoflen", &xoflen), - OSSL_PARAM_END }; + OSSL_PARAM params[] = {OSSL_PARAM_construct_uint("xoflen", &xoflen), OSSL_PARAM_END}; if (EVP_MD_CTX_set_params(ctx, params) != 1) { EVP_MD_CTX_free(ctx); ctx = nullptr; - throw std::runtime_error( - "Failed to set XOF length (outputLength) parameter: " + - std::to_string(ERR_get_error())); + throw std::runtime_error("Failed to set XOF length (outputLength) parameter: " + std::to_string(ERR_get_error())); } } } diff --git a/packages/react-native-quick-crypto/cpp/hash/HybridHash.hpp b/packages/react-native-quick-crypto/cpp/hash/HybridHash.hpp index a2faa71b..dfd519e3 100644 --- a/packages/react-native-quick-crypto/cpp/hash/HybridHash.hpp +++ b/packages/react-native-quick-crypto/cpp/hash/HybridHash.hpp @@ -11,42 +11,26 @@ namespace margelo::nitro::crypto { using namespace facebook; -class HybridHash : public HybridHashSpec -{ -public: - HybridHash() - : HybridObject(TAG) - { - } - HybridHash(EVP_MD_CTX* ctx, - const EVP_MD* md, - const std::string& algorithm, - const std::optional outputLength) - : HybridObject(TAG) - , ctx(ctx) - , md(md) - , algorithm(algorithm) - , outputLength(outputLength) - { - } +class HybridHash : public HybridHashSpec { + public: + HybridHash() : HybridObject(TAG) {} + HybridHash(EVP_MD_CTX* ctx, const EVP_MD* md, const std::string& algorithm, const std::optional outputLength) + : HybridObject(TAG), ctx(ctx), md(md), algorithm(algorithm), outputLength(outputLength) {} ~HybridHash(); -public: + public: // Methods - void createHash(const std::string& algorithm, - const std::optional outputLength) override; + void createHash(const std::string& algorithm, const std::optional outputLength) override; void update(const std::shared_ptr& data) override; - std::shared_ptr digest( - const std::optional& encoding = std::nullopt) override; - std::shared_ptr copy( - const std::optional outputLength) override; + std::shared_ptr digest(const std::optional& encoding = std::nullopt) override; + std::shared_ptr copy(const std::optional outputLength) override; std::vector getSupportedHashAlgorithms() override; -private: + private: // Methods void setParams(); -private: + private: // Properties EVP_MD_CTX* ctx = nullptr; const EVP_MD* md = nullptr; diff --git a/packages/react-native-quick-crypto/cpp/pbkdf2/HybridPbkdf2.cpp b/packages/react-native-quick-crypto/cpp/pbkdf2/HybridPbkdf2.cpp index 3389167d..4d68776c 100644 --- a/packages/react-native-quick-crypto/cpp/pbkdf2/HybridPbkdf2.cpp +++ b/packages/react-native-quick-crypto/cpp/pbkdf2/HybridPbkdf2.cpp @@ -3,70 +3,49 @@ namespace margelo::nitro::crypto { -std::shared_ptr>> -HybridPbkdf2::pbkdf2( - const std::shared_ptr& password, - const std::shared_ptr& salt, - double iterations, - double keylen, - const std::string& digest -) { +std::shared_ptr>> HybridPbkdf2::pbkdf2(const std::shared_ptr& password, + const std::shared_ptr& salt, double iterations, + double keylen, const std::string& digest) { // get owned NativeArrayBuffers before passing to sync function auto nativePassword = ToNativeArrayBuffer(password); auto nativeSalt = ToNativeArrayBuffer(salt); - return Promise>::async( - [this, nativePassword, nativeSalt, iterations, keylen, digest]() { - return this->pbkdf2Sync(nativePassword, nativeSalt, iterations, keylen, digest); - } - ); + return Promise>::async([this, nativePassword, nativeSalt, iterations, keylen, digest]() { + return this->pbkdf2Sync(nativePassword, nativeSalt, iterations, keylen, digest); + }); } -std::shared_ptr -HybridPbkdf2::pbkdf2Sync( - const std::shared_ptr& password, - const std::shared_ptr& salt, - double iterations, - double keylen, - const std::string& digest -) { - size_t bufferSize = static_cast(keylen); - uint8_t* data = new uint8_t[bufferSize]; - auto result = std::make_shared(data, bufferSize, [=]() { delete[] data; }); +std::shared_ptr HybridPbkdf2::pbkdf2Sync(const std::shared_ptr& password, + const std::shared_ptr& salt, double iterations, double keylen, + const std::string& digest) { + size_t bufferSize = static_cast(keylen); + uint8_t* data = new uint8_t[bufferSize]; + auto result = std::make_shared(data, bufferSize, [=]() { delete[] data; }); - // use fastpbkdf2 when possible - if (digest == "sha1") { - fastpbkdf2_hmac_sha1(password.get()->data(), password.get()->size(), - salt.get()->data(), salt.get()->size(), - static_cast(iterations), - result.get()->data(), result.get()->size()); - } else if (digest == "sha256") { - fastpbkdf2_hmac_sha256(password.get()->data(), password.get()->size(), - salt.get()->data(), salt.get()->size(), - static_cast(iterations), - result.get()->data(), result.get()->size()); - } else if (digest == "sha512") { - fastpbkdf2_hmac_sha512(password.get()->data(), password.get()->size(), - salt.get()->data(), salt.get()->size(), - static_cast(iterations), - result.get()->data(), result.get()->size()); - } else { - // fallback to OpenSSL - auto *digestByName = EVP_get_digestbyname(digest.c_str()); - if (digestByName == nullptr) { - throw std::runtime_error("Invalid hash-algorithm: " + digest); - } - char *passAsCharA = reinterpret_cast(password.get()->data()); - const unsigned char *saltAsCharA = - reinterpret_cast(salt.get()->data()); - unsigned char *resultAsCharA = - reinterpret_cast(result.get()->data()); - PKCS5_PBKDF2_HMAC(passAsCharA, password.get()->size(), saltAsCharA, - salt.get()->size(), static_cast(iterations), - digestByName, result.get()->size(), resultAsCharA); + // use fastpbkdf2 when possible + if (digest == "sha1") { + fastpbkdf2_hmac_sha1(password.get()->data(), password.get()->size(), salt.get()->data(), salt.get()->size(), + static_cast(iterations), result.get()->data(), result.get()->size()); + } else if (digest == "sha256") { + fastpbkdf2_hmac_sha256(password.get()->data(), password.get()->size(), salt.get()->data(), salt.get()->size(), + static_cast(iterations), result.get()->data(), result.get()->size()); + } else if (digest == "sha512") { + fastpbkdf2_hmac_sha512(password.get()->data(), password.get()->size(), salt.get()->data(), salt.get()->size(), + static_cast(iterations), result.get()->data(), result.get()->size()); + } else { + // fallback to OpenSSL + auto* digestByName = EVP_get_digestbyname(digest.c_str()); + if (digestByName == nullptr) { + throw std::runtime_error("Invalid hash-algorithm: " + digest); } + char* passAsCharA = reinterpret_cast(password.get()->data()); + const unsigned char* saltAsCharA = reinterpret_cast(salt.get()->data()); + unsigned char* resultAsCharA = reinterpret_cast(result.get()->data()); + PKCS5_PBKDF2_HMAC(passAsCharA, password.get()->size(), saltAsCharA, salt.get()->size(), static_cast(iterations), digestByName, + result.get()->size(), resultAsCharA); + } - return result; + return result; } } // namespace margelo::nitro::crypto diff --git a/packages/react-native-quick-crypto/cpp/pbkdf2/HybridPbkdf2.hpp b/packages/react-native-quick-crypto/cpp/pbkdf2/HybridPbkdf2.hpp index b435b3b2..4e9d29a8 100644 --- a/packages/react-native-quick-crypto/cpp/pbkdf2/HybridPbkdf2.hpp +++ b/packages/react-native-quick-crypto/cpp/pbkdf2/HybridPbkdf2.hpp @@ -13,23 +13,12 @@ class HybridPbkdf2 : public HybridPbkdf2Spec { public: // Methods - std::shared_ptr>> - pbkdf2( - const std::shared_ptr& password, - const std::shared_ptr& salt, - double iterations, - double keylen, - const std::string& digest - ) override; + std::shared_ptr>> pbkdf2(const std::shared_ptr& password, + const std::shared_ptr& salt, double iterations, double keylen, + const std::string& digest) override; - std::shared_ptr - pbkdf2Sync( - const std::shared_ptr& password, - const std::shared_ptr& salt, - double iterations, - double keylen, - const std::string& digest - ) override; + std::shared_ptr pbkdf2Sync(const std::shared_ptr& password, const std::shared_ptr& salt, + double iterations, double keylen, const std::string& digest) override; }; } // namespace margelo::nitro::crypto diff --git a/packages/react-native-quick-crypto/cpp/random/HybridRandom.cpp b/packages/react-native-quick-crypto/cpp/random/HybridRandom.cpp index d9da94f3..c2ccb48b 100644 --- a/packages/react-native-quick-crypto/cpp/random/HybridRandom.cpp +++ b/packages/react-native-quick-crypto/cpp/random/HybridRandom.cpp @@ -4,7 +4,6 @@ #include "HybridRandom.hpp" #include "Utils.hpp" - size_t checkSize(double size) { if (!CheckIsUint32(size)) { throw std::runtime_error("size must be uint32"); @@ -25,33 +24,23 @@ size_t checkOffset(double size, double offset) { return static_cast(offset); } - namespace margelo::nitro::crypto { -std::shared_ptr>> -HybridRandom::randomFill(const std::shared_ptr& buffer, - double dOffset, - double dSize) { +std::shared_ptr>> HybridRandom::randomFill(const std::shared_ptr& buffer, double dOffset, + double dSize) { // get owned NativeArrayBuffer before passing to sync function auto nativeBuffer = ToNativeArrayBuffer(buffer); return Promise>::async( - [this, nativeBuffer, dOffset, dSize]() { - return this->randomFillSync(nativeBuffer, dOffset, dSize); - } - ); + [this, nativeBuffer, dOffset, dSize]() { return this->randomFillSync(nativeBuffer, dOffset, dSize); }); }; -std::shared_ptr -HybridRandom::randomFillSync(const std::shared_ptr& buffer, - double dOffset, - double dSize) { +std::shared_ptr HybridRandom::randomFillSync(const std::shared_ptr& buffer, double dOffset, double dSize) { size_t size = checkSize(dSize); size_t offset = checkOffset(dSize, dOffset); uint8_t* data = buffer.get()->data(); if (RAND_bytes(data + offset, (int)size) != 1) { - throw std::runtime_error("error calling RAND_bytes" + - std::to_string(ERR_get_error())); + throw std::runtime_error("error calling RAND_bytes" + std::to_string(ERR_get_error())); } return buffer; }; diff --git a/packages/react-native-quick-crypto/cpp/random/HybridRandom.hpp b/packages/react-native-quick-crypto/cpp/random/HybridRandom.hpp index 44e68169..5a19033f 100644 --- a/packages/react-native-quick-crypto/cpp/random/HybridRandom.hpp +++ b/packages/react-native-quick-crypto/cpp/random/HybridRandom.hpp @@ -1,7 +1,7 @@ #include #include -#include #include +#include #include "HybridRandomSpec.hpp" @@ -15,17 +15,16 @@ class HybridRandom : public HybridRandomSpec { public: // Methods - std::shared_ptr>> - randomFill(const std::shared_ptr& buffer, double dOffset, double dSize) override; + std::shared_ptr>> randomFill(const std::shared_ptr& buffer, double dOffset, + double dSize) override; - std::shared_ptr - randomFillSync(const std::shared_ptr& buffer, double dOffset, double dSize) override; + std::shared_ptr randomFillSync(const std::shared_ptr& buffer, double dOffset, double dSize) override; }; inline void printData(std::string name, uint8_t* data, size_t size) { std::cout << "data - " << name << std::endl; for (size_t i = 0; i < size; i++) { - printf("%u ", data[i]); + printf("%u ", data[i]); } printf("\n"); } diff --git a/packages/react-native-quick-crypto/cpp/utils/Utils.hpp b/packages/react-native-quick-crypto/cpp/utils/Utils.hpp index e0597a8e..82718f4b 100644 --- a/packages/react-native-quick-crypto/cpp/utils/Utils.hpp +++ b/packages/react-native-quick-crypto/cpp/utils/Utils.hpp @@ -3,8 +3,7 @@ #include // copy a JSArrayBuffer that we do not own into a NativeArrayBuffer that we do own -inline std::shared_ptr -ToNativeArrayBuffer(const std::shared_ptr& buffer) { +inline std::shared_ptr ToNativeArrayBuffer(const std::shared_ptr& buffer) { size_t bufferSize = buffer.get()->size(); uint8_t* data = new uint8_t[bufferSize]; memcpy(data, buffer.get()->data(), bufferSize); diff --git a/scripts/clang-format.sh b/scripts/clang-format.sh index 49c151fe..ee6763a6 100755 --- a/scripts/clang-format.sh +++ b/scripts/clang-format.sh @@ -4,7 +4,6 @@ CPP_DIRS=( # react-native-quick-crypto "packages/react-native-quick-crypto/android/src/main/cpp" "packages/react-native-quick-crypto/cpp" - "packages/react-native-quick-crypto/ios" ) if which clang-format >/dev/null; then