react-native-quick-crypto 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/CMakeLists.txt +9 -0
- package/cpp/argon2/HybridArgon2.cpp +103 -0
- package/cpp/argon2/HybridArgon2.hpp +32 -0
- package/cpp/certificate/HybridCertificate.cpp +42 -0
- package/cpp/certificate/HybridCertificate.hpp +16 -0
- package/cpp/cipher/HybridCipher.cpp +58 -0
- package/cpp/cipher/HybridCipher.hpp +4 -0
- package/cpp/dh/HybridDhKeyPair.cpp +179 -0
- package/cpp/dh/HybridDhKeyPair.hpp +37 -0
- package/cpp/dsa/HybridDsaKeyPair.cpp +128 -0
- package/cpp/dsa/HybridDsaKeyPair.hpp +32 -0
- package/cpp/ecdh/HybridECDH.cpp +35 -0
- package/cpp/ecdh/HybridECDH.hpp +1 -0
- package/cpp/keys/HybridKeyObjectHandle.cpp +19 -0
- package/cpp/prime/HybridPrime.cpp +81 -0
- package/cpp/prime/HybridPrime.hpp +20 -0
- package/lib/commonjs/argon2.js +39 -0
- package/lib/commonjs/argon2.js.map +1 -0
- package/lib/commonjs/certificate.js +35 -0
- package/lib/commonjs/certificate.js.map +1 -0
- package/lib/commonjs/cipher.js +8 -0
- package/lib/commonjs/cipher.js.map +1 -1
- package/lib/commonjs/dhKeyPair.js +109 -0
- package/lib/commonjs/dhKeyPair.js.map +1 -0
- package/lib/commonjs/dsa.js +92 -0
- package/lib/commonjs/dsa.js.map +1 -0
- package/lib/commonjs/ecdh.js +37 -0
- package/lib/commonjs/ecdh.js.map +1 -1
- package/lib/commonjs/index.js +35 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/keys/classes.js +9 -7
- package/lib/commonjs/keys/classes.js.map +1 -1
- package/lib/commonjs/keys/generateKeyPair.js +11 -0
- package/lib/commonjs/keys/generateKeyPair.js.map +1 -1
- package/lib/commonjs/prime.js +84 -0
- package/lib/commonjs/prime.js.map +1 -0
- package/lib/commonjs/specs/argon2.nitro.js +6 -0
- package/lib/commonjs/specs/argon2.nitro.js.map +1 -0
- package/lib/commonjs/specs/certificate.nitro.js +6 -0
- package/lib/commonjs/specs/certificate.nitro.js.map +1 -0
- package/lib/commonjs/specs/dhKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/dhKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/dsaKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/dsaKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/prime.nitro.js +6 -0
- package/lib/commonjs/specs/prime.nitro.js.map +1 -0
- package/lib/commonjs/subtle.js +101 -10
- package/lib/commonjs/subtle.js.map +1 -1
- package/lib/commonjs/utils/types.js.map +1 -1
- package/lib/module/argon2.js +34 -0
- package/lib/module/argon2.js.map +1 -0
- package/lib/module/certificate.js +30 -0
- package/lib/module/certificate.js.map +1 -0
- package/lib/module/cipher.js +7 -0
- package/lib/module/cipher.js.map +1 -1
- package/lib/module/dhKeyPair.js +102 -0
- package/lib/module/dhKeyPair.js.map +1 -0
- package/lib/module/dsa.js +85 -0
- package/lib/module/dsa.js.map +1 -0
- package/lib/module/ecdh.js +37 -0
- package/lib/module/ecdh.js.map +1 -1
- package/lib/module/index.js +9 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/keys/classes.js +9 -7
- package/lib/module/keys/classes.js.map +1 -1
- package/lib/module/keys/generateKeyPair.js +11 -0
- package/lib/module/keys/generateKeyPair.js.map +1 -1
- package/lib/module/prime.js +77 -0
- package/lib/module/prime.js.map +1 -0
- package/lib/module/specs/argon2.nitro.js +4 -0
- package/lib/module/specs/argon2.nitro.js.map +1 -0
- package/lib/module/specs/certificate.nitro.js +4 -0
- package/lib/module/specs/certificate.nitro.js.map +1 -0
- package/lib/module/specs/dhKeyPair.nitro.js +4 -0
- package/lib/module/specs/dhKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/dsaKeyPair.nitro.js +4 -0
- package/lib/module/specs/dsaKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/prime.nitro.js +4 -0
- package/lib/module/specs/prime.nitro.js.map +1 -0
- package/lib/module/subtle.js +102 -12
- package/lib/module/subtle.js.map +1 -1
- package/lib/module/utils/types.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/typescript/argon2.d.ts +16 -0
- package/lib/typescript/argon2.d.ts.map +1 -0
- package/lib/typescript/certificate.d.ts +8 -0
- package/lib/typescript/certificate.d.ts.map +1 -0
- package/lib/typescript/cipher.d.ts +12 -0
- package/lib/typescript/cipher.d.ts.map +1 -1
- package/lib/typescript/dhKeyPair.d.ts +19 -0
- package/lib/typescript/dhKeyPair.d.ts.map +1 -0
- package/lib/typescript/dsa.d.ts +19 -0
- package/lib/typescript/dsa.d.ts.map +1 -0
- package/lib/typescript/ecdh.d.ts +3 -0
- package/lib/typescript/ecdh.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +17 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/keys/classes.d.ts +2 -0
- package/lib/typescript/keys/classes.d.ts.map +1 -1
- package/lib/typescript/keys/generateKeyPair.d.ts.map +1 -1
- package/lib/typescript/prime.d.ts +19 -0
- package/lib/typescript/prime.d.ts.map +1 -0
- package/lib/typescript/specs/argon2.nitro.d.ts +9 -0
- package/lib/typescript/specs/argon2.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/certificate.nitro.d.ts +10 -0
- package/lib/typescript/specs/certificate.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/cipher.nitro.d.ts +9 -0
- package/lib/typescript/specs/cipher.nitro.d.ts.map +1 -1
- package/lib/typescript/specs/dhKeyPair.nitro.d.ts +14 -0
- package/lib/typescript/specs/dhKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/dsaKeyPair.nitro.d.ts +13 -0
- package/lib/typescript/specs/dsaKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/ecdh.nitro.d.ts +1 -0
- package/lib/typescript/specs/ecdh.nitro.d.ts.map +1 -1
- package/lib/typescript/specs/prime.nitro.d.ts +11 -0
- package/lib/typescript/specs/prime.nitro.d.ts.map +1 -0
- package/lib/typescript/subtle.d.ts +2 -0
- package/lib/typescript/subtle.d.ts.map +1 -1
- package/lib/typescript/utils/types.d.ts +13 -3
- package/lib/typescript/utils/types.d.ts.map +1 -1
- package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +5 -0
- package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +50 -0
- package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +50 -0
- package/nitrogen/generated/shared/c++/CipherInfo.hpp +104 -0
- package/nitrogen/generated/shared/c++/HybridArgon2Spec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridArgon2Spec.hpp +66 -0
- package/nitrogen/generated/shared/c++/HybridCertificateSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridCertificateSpec.hpp +64 -0
- package/nitrogen/generated/shared/c++/HybridCipherSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridCipherSpec.hpp +4 -0
- package/nitrogen/generated/shared/c++/HybridDhKeyPairSpec.cpp +27 -0
- package/nitrogen/generated/shared/c++/HybridDhKeyPairSpec.hpp +69 -0
- package/nitrogen/generated/shared/c++/HybridDsaKeyPairSpec.cpp +26 -0
- package/nitrogen/generated/shared/c++/HybridDsaKeyPairSpec.hpp +68 -0
- package/nitrogen/generated/shared/c++/HybridECDHSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridECDHSpec.hpp +1 -0
- package/nitrogen/generated/shared/c++/HybridPrimeSpec.cpp +24 -0
- package/nitrogen/generated/shared/c++/HybridPrimeSpec.hpp +67 -0
- package/package.json +1 -1
- package/src/argon2.ts +83 -0
- package/src/certificate.ts +41 -0
- package/src/cipher.ts +24 -0
- package/src/dhKeyPair.ts +156 -0
- package/src/dsa.ts +129 -0
- package/src/ecdh.ts +59 -0
- package/src/index.ts +9 -0
- package/src/keys/classes.ts +16 -5
- package/src/keys/generateKeyPair.ts +14 -0
- package/src/prime.ts +134 -0
- package/src/specs/argon2.nitro.ts +29 -0
- package/src/specs/certificate.nitro.ts +8 -0
- package/src/specs/cipher.nitro.ts +14 -0
- package/src/specs/dhKeyPair.nitro.ts +14 -0
- package/src/specs/dsaKeyPair.nitro.ts +13 -0
- package/src/specs/ecdh.nitro.ts +1 -0
- package/src/specs/prime.nitro.ts +18 -0
- package/src/subtle.ts +271 -12
- package/src/utils/types.ts +22 -3
package/android/CMakeLists.txt
CHANGED
|
@@ -25,7 +25,9 @@ endif()
|
|
|
25
25
|
add_library(
|
|
26
26
|
${PACKAGE_NAME} SHARED
|
|
27
27
|
src/main/cpp/cpp-adapter.cpp
|
|
28
|
+
../cpp/argon2/HybridArgon2.cpp
|
|
28
29
|
../cpp/blake3/HybridBlake3.cpp
|
|
30
|
+
../cpp/certificate/HybridCertificate.cpp
|
|
29
31
|
../cpp/cipher/CCMCipher.cpp
|
|
30
32
|
../cpp/cipher/GCMCipher.cpp
|
|
31
33
|
../cpp/cipher/HybridCipher.cpp
|
|
@@ -37,6 +39,8 @@ add_library(
|
|
|
37
39
|
../cpp/cipher/ChaCha20Cipher.cpp
|
|
38
40
|
../cpp/cipher/ChaCha20Poly1305Cipher.cpp
|
|
39
41
|
../cpp/dh/HybridDiffieHellman.cpp
|
|
42
|
+
../cpp/dh/HybridDhKeyPair.cpp
|
|
43
|
+
../cpp/dsa/HybridDsaKeyPair.cpp
|
|
40
44
|
../cpp/ec/HybridEcKeyPair.cpp
|
|
41
45
|
../cpp/ecdh/HybridECDH.cpp
|
|
42
46
|
../cpp/ed25519/HybridEdKeyPair.cpp
|
|
@@ -47,6 +51,7 @@ add_library(
|
|
|
47
51
|
../cpp/keys/KeyObjectData.cpp
|
|
48
52
|
../cpp/mldsa/HybridMlDsaKeyPair.cpp
|
|
49
53
|
../cpp/pbkdf2/HybridPbkdf2.cpp
|
|
54
|
+
../cpp/prime/HybridPrime.cpp
|
|
50
55
|
../cpp/random/HybridRandom.cpp
|
|
51
56
|
../cpp/rsa/HybridRsaKeyPair.cpp
|
|
52
57
|
../cpp/scrypt/HybridScrypt.cpp
|
|
@@ -66,9 +71,12 @@ include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/QuickCrypto+autolinkin
|
|
|
66
71
|
# local includes
|
|
67
72
|
include_directories(
|
|
68
73
|
"src/main/cpp"
|
|
74
|
+
"../cpp/argon2"
|
|
69
75
|
"../cpp/blake3"
|
|
76
|
+
"../cpp/certificate"
|
|
70
77
|
"../cpp/cipher"
|
|
71
78
|
"../cpp/dh"
|
|
79
|
+
"../cpp/dsa"
|
|
72
80
|
"../cpp/ec"
|
|
73
81
|
"../cpp/ecdh"
|
|
74
82
|
"../cpp/ed25519"
|
|
@@ -78,6 +86,7 @@ include_directories(
|
|
|
78
86
|
"../cpp/keys"
|
|
79
87
|
"../cpp/mldsa"
|
|
80
88
|
"../cpp/pbkdf2"
|
|
89
|
+
"../cpp/prime"
|
|
81
90
|
"../cpp/random"
|
|
82
91
|
"../cpp/rsa"
|
|
83
92
|
"../cpp/sign"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#include <NitroModules/ArrayBuffer.hpp>
|
|
2
|
+
#include <memory>
|
|
3
|
+
#include <ncrypto.h>
|
|
4
|
+
#include <openssl/err.h>
|
|
5
|
+
#include <openssl/opensslv.h>
|
|
6
|
+
#include <string>
|
|
7
|
+
|
|
8
|
+
#include "HybridArgon2.hpp"
|
|
9
|
+
#include "QuickCryptoUtils.hpp"
|
|
10
|
+
|
|
11
|
+
namespace margelo::nitro::crypto {
|
|
12
|
+
|
|
13
|
+
#if OPENSSL_VERSION_NUMBER >= 0x30200000L
|
|
14
|
+
#ifndef OPENSSL_NO_ARGON2
|
|
15
|
+
|
|
16
|
+
static ncrypto::Argon2Type parseAlgorithm(const std::string& algo) {
|
|
17
|
+
if (algo == "argon2d")
|
|
18
|
+
return ncrypto::Argon2Type::ARGON2D;
|
|
19
|
+
if (algo == "argon2i")
|
|
20
|
+
return ncrypto::Argon2Type::ARGON2I;
|
|
21
|
+
if (algo == "argon2id")
|
|
22
|
+
return ncrypto::Argon2Type::ARGON2ID;
|
|
23
|
+
throw std::runtime_error("Unknown argon2 algorithm: " + algo);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static std::shared_ptr<ArrayBuffer> hashImpl(const std::string& algorithm, const std::shared_ptr<ArrayBuffer>& message,
|
|
27
|
+
const std::shared_ptr<ArrayBuffer>& nonce, double parallelism, double tagLength, double memory,
|
|
28
|
+
double passes, double version, const std::optional<std::shared_ptr<ArrayBuffer>>& secret,
|
|
29
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& associatedData) {
|
|
30
|
+
|
|
31
|
+
auto type = parseAlgorithm(algorithm);
|
|
32
|
+
|
|
33
|
+
ncrypto::Buffer<const char> passBuf{message->size() > 0 ? reinterpret_cast<const char*>(message->data()) : "", message->size()};
|
|
34
|
+
|
|
35
|
+
ncrypto::Buffer<const unsigned char> saltBuf{nonce->size() > 0 ? reinterpret_cast<const unsigned char*>(nonce->data())
|
|
36
|
+
: reinterpret_cast<const unsigned char*>(""),
|
|
37
|
+
nonce->size()};
|
|
38
|
+
|
|
39
|
+
ncrypto::Buffer<const unsigned char> secretBuf{nullptr, 0};
|
|
40
|
+
if (secret.has_value() && secret.value()->size() > 0) {
|
|
41
|
+
secretBuf = {reinterpret_cast<const unsigned char*>(secret.value()->data()), secret.value()->size()};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
ncrypto::Buffer<const unsigned char> adBuf{nullptr, 0};
|
|
45
|
+
if (associatedData.has_value() && associatedData.value()->size() > 0) {
|
|
46
|
+
adBuf = {reinterpret_cast<const unsigned char*>(associatedData.value()->data()), associatedData.value()->size()};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
auto result =
|
|
50
|
+
ncrypto::argon2(passBuf, saltBuf, static_cast<uint32_t>(parallelism), static_cast<size_t>(tagLength), static_cast<uint32_t>(memory),
|
|
51
|
+
static_cast<uint32_t>(passes), static_cast<uint32_t>(version), secretBuf, adBuf, type);
|
|
52
|
+
|
|
53
|
+
if (!result) {
|
|
54
|
+
unsigned long err = ERR_peek_last_error();
|
|
55
|
+
const char* reason = err ? ERR_reason_error_string(err) : nullptr;
|
|
56
|
+
throw std::runtime_error(reason ? std::string("Argon2 operation failed: ") + reason : "Argon2 operation failed");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return ToNativeArrayBuffer(reinterpret_cast<const uint8_t*>(result.get()), result.size());
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#endif // OPENSSL_NO_ARGON2
|
|
63
|
+
#endif // OPENSSL_VERSION_NUMBER
|
|
64
|
+
|
|
65
|
+
std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>>
|
|
66
|
+
HybridArgon2::hash(const std::string& algorithm, const std::shared_ptr<ArrayBuffer>& message, const std::shared_ptr<ArrayBuffer>& nonce,
|
|
67
|
+
double parallelism, double tagLength, double memory, double passes, double version,
|
|
68
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& secret,
|
|
69
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& associatedData) {
|
|
70
|
+
#if OPENSSL_VERSION_NUMBER >= 0x30200000L && !defined(OPENSSL_NO_ARGON2)
|
|
71
|
+
auto nativeMessage = ToNativeArrayBuffer(message);
|
|
72
|
+
auto nativeNonce = ToNativeArrayBuffer(nonce);
|
|
73
|
+
std::optional<std::shared_ptr<ArrayBuffer>> nativeSecret;
|
|
74
|
+
if (secret.has_value()) {
|
|
75
|
+
nativeSecret = ToNativeArrayBuffer(secret.value());
|
|
76
|
+
}
|
|
77
|
+
std::optional<std::shared_ptr<ArrayBuffer>> nativeAd;
|
|
78
|
+
if (associatedData.has_value()) {
|
|
79
|
+
nativeAd = ToNativeArrayBuffer(associatedData.value());
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return Promise<std::shared_ptr<ArrayBuffer>>::async([algorithm, nativeMessage, nativeNonce, parallelism, tagLength, memory, passes,
|
|
83
|
+
version, nativeSecret = std::move(nativeSecret), nativeAd = std::move(nativeAd)]() {
|
|
84
|
+
return hashImpl(algorithm, nativeMessage, nativeNonce, parallelism, tagLength, memory, passes, version, nativeSecret, nativeAd);
|
|
85
|
+
});
|
|
86
|
+
#else
|
|
87
|
+
throw std::runtime_error("Argon2 is not supported (requires OpenSSL 3.2+)");
|
|
88
|
+
#endif
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
std::shared_ptr<ArrayBuffer> HybridArgon2::hashSync(const std::string& algorithm, const std::shared_ptr<ArrayBuffer>& message,
|
|
92
|
+
const std::shared_ptr<ArrayBuffer>& nonce, double parallelism, double tagLength,
|
|
93
|
+
double memory, double passes, double version,
|
|
94
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& secret,
|
|
95
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& associatedData) {
|
|
96
|
+
#if OPENSSL_VERSION_NUMBER >= 0x30200000L && !defined(OPENSSL_NO_ARGON2)
|
|
97
|
+
return hashImpl(algorithm, message, nonce, parallelism, tagLength, memory, passes, version, secret, associatedData);
|
|
98
|
+
#else
|
|
99
|
+
throw std::runtime_error("Argon2 is not supported (requires OpenSSL 3.2+)");
|
|
100
|
+
#endif
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
} // namespace margelo::nitro::crypto
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <NitroModules/ArrayBuffer.hpp>
|
|
4
|
+
#include <NitroModules/Promise.hpp>
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <optional>
|
|
7
|
+
#include <string>
|
|
8
|
+
|
|
9
|
+
#include "HybridArgon2Spec.hpp"
|
|
10
|
+
|
|
11
|
+
namespace margelo::nitro::crypto {
|
|
12
|
+
|
|
13
|
+
using namespace facebook;
|
|
14
|
+
|
|
15
|
+
class HybridArgon2 : public HybridArgon2Spec {
|
|
16
|
+
public:
|
|
17
|
+
HybridArgon2() : HybridObject(TAG) {}
|
|
18
|
+
|
|
19
|
+
public:
|
|
20
|
+
std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>> hash(const std::string& algorithm, const std::shared_ptr<ArrayBuffer>& message,
|
|
21
|
+
const std::shared_ptr<ArrayBuffer>& nonce, double parallelism,
|
|
22
|
+
double tagLength, double memory, double passes, double version,
|
|
23
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& secret,
|
|
24
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& associatedData) override;
|
|
25
|
+
|
|
26
|
+
std::shared_ptr<ArrayBuffer> hashSync(const std::string& algorithm, const std::shared_ptr<ArrayBuffer>& message,
|
|
27
|
+
const std::shared_ptr<ArrayBuffer>& nonce, double parallelism, double tagLength, double memory,
|
|
28
|
+
double passes, double version, const std::optional<std::shared_ptr<ArrayBuffer>>& secret,
|
|
29
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& associatedData) override;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
} // namespace margelo::nitro::crypto
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#include "HybridCertificate.hpp"
|
|
2
|
+
#include "QuickCryptoUtils.hpp"
|
|
3
|
+
#include <ncrypto.h>
|
|
4
|
+
#include <openssl/crypto.h>
|
|
5
|
+
|
|
6
|
+
namespace margelo::nitro::crypto {
|
|
7
|
+
|
|
8
|
+
bool HybridCertificate::verifySpkac(const std::shared_ptr<ArrayBuffer>& spkac) {
|
|
9
|
+
return ncrypto::VerifySpkac(reinterpret_cast<const char*>(spkac->data()), spkac->size());
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
std::shared_ptr<ArrayBuffer> HybridCertificate::exportPublicKey(const std::shared_ptr<ArrayBuffer>& spkac) {
|
|
13
|
+
auto bio = ncrypto::ExportPublicKey(reinterpret_cast<const char*>(spkac->data()), spkac->size());
|
|
14
|
+
|
|
15
|
+
if (!bio) {
|
|
16
|
+
auto empty = new uint8_t[0];
|
|
17
|
+
return std::make_shared<NativeArrayBuffer>(empty, 0, [empty]() { delete[] empty; });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
BUF_MEM* mem = bio;
|
|
21
|
+
if (!mem || mem->length == 0) {
|
|
22
|
+
auto empty = new uint8_t[0];
|
|
23
|
+
return std::make_shared<NativeArrayBuffer>(empty, 0, [empty]() { delete[] empty; });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return ToNativeArrayBuffer(reinterpret_cast<const uint8_t*>(mem->data), mem->length);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
std::shared_ptr<ArrayBuffer> HybridCertificate::exportChallenge(const std::shared_ptr<ArrayBuffer>& spkac) {
|
|
30
|
+
auto buf = ncrypto::ExportChallenge(reinterpret_cast<const char*>(spkac->data()), spkac->size());
|
|
31
|
+
|
|
32
|
+
if (buf.data == nullptr) {
|
|
33
|
+
auto empty = new uint8_t[0];
|
|
34
|
+
return std::make_shared<NativeArrayBuffer>(empty, 0, [empty]() { delete[] empty; });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
auto result = ToNativeArrayBuffer(reinterpret_cast<const uint8_t*>(buf.data), buf.len);
|
|
38
|
+
OPENSSL_free(buf.data);
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
} // namespace margelo::nitro::crypto
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "HybridCertificateSpec.hpp"
|
|
4
|
+
|
|
5
|
+
namespace margelo::nitro::crypto {
|
|
6
|
+
|
|
7
|
+
class HybridCertificate : public HybridCertificateSpec {
|
|
8
|
+
public:
|
|
9
|
+
HybridCertificate() : HybridObject(TAG) {}
|
|
10
|
+
|
|
11
|
+
bool verifySpkac(const std::shared_ptr<ArrayBuffer>& spkac) override;
|
|
12
|
+
std::shared_ptr<ArrayBuffer> exportPublicKey(const std::shared_ptr<ArrayBuffer>& spkac) override;
|
|
13
|
+
std::shared_ptr<ArrayBuffer> exportChallenge(const std::shared_ptr<ArrayBuffer>& spkac) override;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
} // namespace margelo::nitro::crypto
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#include "HybridCipher.hpp"
|
|
9
9
|
#include "QuickCryptoUtils.hpp"
|
|
10
10
|
|
|
11
|
+
#include <ncrypto.h>
|
|
11
12
|
#include <openssl/err.h>
|
|
12
13
|
#include <openssl/evp.h>
|
|
13
14
|
|
|
@@ -336,4 +337,61 @@ std::vector<std::string> HybridCipher::getSupportedCiphers() {
|
|
|
336
337
|
return cipher_names;
|
|
337
338
|
}
|
|
338
339
|
|
|
340
|
+
std::optional<CipherInfo> HybridCipher::getCipherInfo(const std::string& name, std::optional<double> keyLength,
|
|
341
|
+
std::optional<double> ivLength) {
|
|
342
|
+
auto cipher = ncrypto::Cipher::FromName(name.c_str());
|
|
343
|
+
if (!cipher)
|
|
344
|
+
return std::nullopt;
|
|
345
|
+
|
|
346
|
+
size_t iv_length = cipher.getIvLength();
|
|
347
|
+
size_t key_length = cipher.getKeyLength();
|
|
348
|
+
|
|
349
|
+
if (keyLength.has_value() || ivLength.has_value()) {
|
|
350
|
+
auto ctx = ncrypto::CipherCtxPointer::New();
|
|
351
|
+
if (!ctx.init(cipher, true))
|
|
352
|
+
return std::nullopt;
|
|
353
|
+
|
|
354
|
+
if (keyLength.has_value()) {
|
|
355
|
+
size_t check_len = static_cast<size_t>(keyLength.value());
|
|
356
|
+
if (!ctx.setKeyLength(check_len))
|
|
357
|
+
return std::nullopt;
|
|
358
|
+
key_length = check_len;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (ivLength.has_value()) {
|
|
362
|
+
size_t check_len = static_cast<size_t>(ivLength.value());
|
|
363
|
+
if (cipher.isCcmMode()) {
|
|
364
|
+
if (check_len < 7 || check_len > 13)
|
|
365
|
+
return std::nullopt;
|
|
366
|
+
} else if (cipher.isGcmMode()) {
|
|
367
|
+
// GCM accepts flexible IV lengths
|
|
368
|
+
} else if (cipher.isOcbMode()) {
|
|
369
|
+
if (!ctx.setIvLength(check_len))
|
|
370
|
+
return std::nullopt;
|
|
371
|
+
} else {
|
|
372
|
+
if (check_len != iv_length)
|
|
373
|
+
return std::nullopt;
|
|
374
|
+
}
|
|
375
|
+
iv_length = check_len;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
std::string name_str(cipher.getName());
|
|
380
|
+
std::transform(name_str.begin(), name_str.end(), name_str.begin(), ::tolower);
|
|
381
|
+
|
|
382
|
+
std::string mode_str(cipher.getModeLabel());
|
|
383
|
+
|
|
384
|
+
std::optional<double> block_size = std::nullopt;
|
|
385
|
+
if (!cipher.isStreamMode()) {
|
|
386
|
+
block_size = static_cast<double>(cipher.getBlockSize());
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
std::optional<double> iv_len = std::nullopt;
|
|
390
|
+
if (iv_length != 0) {
|
|
391
|
+
iv_len = static_cast<double>(iv_length);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return CipherInfo{name_str, static_cast<double>(cipher.getNid()), mode_str, static_cast<double>(key_length), block_size, iv_len};
|
|
395
|
+
}
|
|
396
|
+
|
|
339
397
|
} // namespace margelo::nitro::crypto
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#include <string>
|
|
9
9
|
#include <vector>
|
|
10
10
|
|
|
11
|
+
#include "CipherInfo.hpp"
|
|
11
12
|
#include "HybridCipherSpec.hpp"
|
|
12
13
|
|
|
13
14
|
namespace margelo::nitro::crypto {
|
|
@@ -40,6 +41,9 @@ class HybridCipher : public HybridCipherSpec {
|
|
|
40
41
|
|
|
41
42
|
std::vector<std::string> getSupportedCiphers() override;
|
|
42
43
|
|
|
44
|
+
std::optional<CipherInfo> getCipherInfo(const std::string& name, std::optional<double> keyLength,
|
|
45
|
+
std::optional<double> ivLength) override;
|
|
46
|
+
|
|
43
47
|
protected:
|
|
44
48
|
// Protected enums for state management
|
|
45
49
|
enum CipherKind { kCipher, kDecipher };
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
#include "HybridDhKeyPair.hpp"
|
|
2
|
+
|
|
3
|
+
#include <NitroModules/ArrayBuffer.hpp>
|
|
4
|
+
#include <NitroModules/Promise.hpp>
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <openssl/bio.h>
|
|
7
|
+
#include <openssl/bn.h>
|
|
8
|
+
#include <openssl/buffer.h>
|
|
9
|
+
#include <openssl/dh.h>
|
|
10
|
+
#include <openssl/err.h>
|
|
11
|
+
#include <openssl/evp.h>
|
|
12
|
+
#include <openssl/pem.h>
|
|
13
|
+
#include <stdexcept>
|
|
14
|
+
#include <string>
|
|
15
|
+
|
|
16
|
+
// Suppress deprecation warnings for DH_* functions
|
|
17
|
+
// Node.js ncrypto uses the same pattern — these APIs work but are deprecated in OpenSSL 3.x
|
|
18
|
+
#pragma clang diagnostic push
|
|
19
|
+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
20
|
+
|
|
21
|
+
namespace margelo::nitro::crypto {
|
|
22
|
+
|
|
23
|
+
using BN_ptr = std::unique_ptr<BIGNUM, decltype(&BN_free)>;
|
|
24
|
+
using DH_ptr = std::unique_ptr<DH, decltype(&DH_free)>;
|
|
25
|
+
using EVP_PKEY_CTX_ptr = std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)>;
|
|
26
|
+
|
|
27
|
+
void HybridDhKeyPair::setPrimeLength(double primeLength) {
|
|
28
|
+
primeLength_ = static_cast<int>(primeLength);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
void HybridDhKeyPair::setPrime(const std::shared_ptr<ArrayBuffer>& prime) {
|
|
32
|
+
prime_.assign(prime->data(), prime->data() + prime->size());
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
void HybridDhKeyPair::setGenerator(double generator) {
|
|
36
|
+
generator_ = static_cast<int>(generator);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
std::shared_ptr<Promise<void>> HybridDhKeyPair::generateKeyPair() {
|
|
40
|
+
return Promise<void>::async([this]() { this->generateKeyPairSync(); });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
void HybridDhKeyPair::generateKeyPairSync() {
|
|
44
|
+
pkey_.reset();
|
|
45
|
+
|
|
46
|
+
EVP_PKEY* params = nullptr;
|
|
47
|
+
|
|
48
|
+
if (!prime_.empty()) {
|
|
49
|
+
// Mode B: Custom prime provided as binary
|
|
50
|
+
DH_ptr dh(DH_new(), DH_free);
|
|
51
|
+
if (!dh) {
|
|
52
|
+
throw std::runtime_error("DH: failed to create DH structure");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
BIGNUM* p = BN_bin2bn(prime_.data(), static_cast<int>(prime_.size()), nullptr);
|
|
56
|
+
BIGNUM* g = BN_new();
|
|
57
|
+
if (!p || !g) {
|
|
58
|
+
if (p)
|
|
59
|
+
BN_free(p);
|
|
60
|
+
if (g)
|
|
61
|
+
BN_free(g);
|
|
62
|
+
throw std::runtime_error("DH: failed to create BIGNUM parameters");
|
|
63
|
+
}
|
|
64
|
+
BN_set_word(g, static_cast<unsigned long>(generator_));
|
|
65
|
+
|
|
66
|
+
if (DH_set0_pqg(dh.get(), p, nullptr, g) != 1) {
|
|
67
|
+
BN_free(p);
|
|
68
|
+
BN_free(g);
|
|
69
|
+
throw std::runtime_error("DH: failed to set DH parameters");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
EVP_PKEY* pkey_params = EVP_PKEY_new();
|
|
73
|
+
if (!pkey_params) {
|
|
74
|
+
throw std::runtime_error("DH: failed to create EVP_PKEY for parameters");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (EVP_PKEY_assign_DH(pkey_params, dh.get()) != 1) {
|
|
78
|
+
EVP_PKEY_free(pkey_params);
|
|
79
|
+
throw std::runtime_error("DH: failed to assign DH to EVP_PKEY");
|
|
80
|
+
}
|
|
81
|
+
dh.release(); // EVP_PKEY now owns it
|
|
82
|
+
|
|
83
|
+
params = pkey_params;
|
|
84
|
+
|
|
85
|
+
} else if (primeLength_ > 0) {
|
|
86
|
+
// Mode C: Generate random prime of given size
|
|
87
|
+
EVP_PKEY_CTX_ptr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DH, nullptr), EVP_PKEY_CTX_free);
|
|
88
|
+
if (!pctx) {
|
|
89
|
+
throw std::runtime_error("DH: failed to create parameter context");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (EVP_PKEY_paramgen_init(pctx.get()) <= 0) {
|
|
93
|
+
throw std::runtime_error("DH: failed to initialize parameter generation");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx.get(), primeLength_) <= 0) {
|
|
97
|
+
throw std::runtime_error("DH: failed to set prime length");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (EVP_PKEY_CTX_set_dh_paramgen_generator(pctx.get(), generator_) <= 0) {
|
|
101
|
+
throw std::runtime_error("DH: failed to set generator");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (EVP_PKEY_paramgen(pctx.get(), ¶ms) <= 0) {
|
|
105
|
+
throw std::runtime_error("DH: failed to generate parameters");
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
throw std::runtime_error("DH: either prime or primeLength must be set");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)> params_guard(params, EVP_PKEY_free);
|
|
112
|
+
|
|
113
|
+
// Generate key pair from parameters
|
|
114
|
+
EVP_PKEY_CTX_ptr kctx(EVP_PKEY_CTX_new(params, nullptr), EVP_PKEY_CTX_free);
|
|
115
|
+
if (!kctx) {
|
|
116
|
+
throw std::runtime_error("DH: failed to create keygen context");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (EVP_PKEY_keygen_init(kctx.get()) <= 0) {
|
|
120
|
+
throw std::runtime_error("DH: failed to initialize key generation");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
EVP_PKEY* raw_pkey = nullptr;
|
|
124
|
+
if (EVP_PKEY_keygen(kctx.get(), &raw_pkey) <= 0) {
|
|
125
|
+
throw std::runtime_error("DH: failed to generate key pair");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
pkey_.reset(raw_pkey);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
std::shared_ptr<ArrayBuffer> HybridDhKeyPair::getPublicKey() {
|
|
132
|
+
if (!pkey_) {
|
|
133
|
+
throw std::runtime_error("DH: no key pair generated");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
BIO* bio = BIO_new(BIO_s_mem());
|
|
137
|
+
if (!bio) {
|
|
138
|
+
throw std::runtime_error("DH: failed to create BIO for public key export");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (i2d_PUBKEY_bio(bio, pkey_.get()) != 1) {
|
|
142
|
+
BIO_free(bio);
|
|
143
|
+
throw std::runtime_error("DH: failed to export public key");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
BUF_MEM* mem;
|
|
147
|
+
BIO_get_mem_ptr(bio, &mem);
|
|
148
|
+
std::string derData(mem->data, mem->length);
|
|
149
|
+
BIO_free(bio);
|
|
150
|
+
|
|
151
|
+
return ToNativeArrayBuffer(derData);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
std::shared_ptr<ArrayBuffer> HybridDhKeyPair::getPrivateKey() {
|
|
155
|
+
if (!pkey_) {
|
|
156
|
+
throw std::runtime_error("DH: no key pair generated");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
BIO* bio = BIO_new(BIO_s_mem());
|
|
160
|
+
if (!bio) {
|
|
161
|
+
throw std::runtime_error("DH: failed to create BIO for private key export");
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (i2d_PKCS8PrivateKey_bio(bio, pkey_.get(), nullptr, nullptr, 0, nullptr, nullptr) != 1) {
|
|
165
|
+
BIO_free(bio);
|
|
166
|
+
throw std::runtime_error("DH: failed to export private key");
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
BUF_MEM* mem;
|
|
170
|
+
BIO_get_mem_ptr(bio, &mem);
|
|
171
|
+
std::string derData(mem->data, mem->length);
|
|
172
|
+
BIO_free(bio);
|
|
173
|
+
|
|
174
|
+
return ToNativeArrayBuffer(derData);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
#pragma clang diagnostic pop
|
|
178
|
+
|
|
179
|
+
} // namespace margelo::nitro::crypto
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <memory>
|
|
4
|
+
#include <openssl/dh.h>
|
|
5
|
+
#include <openssl/evp.h>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <vector>
|
|
8
|
+
|
|
9
|
+
#include "HybridDhKeyPairSpec.hpp"
|
|
10
|
+
#include "QuickCryptoUtils.hpp"
|
|
11
|
+
|
|
12
|
+
namespace margelo::nitro::crypto {
|
|
13
|
+
|
|
14
|
+
class HybridDhKeyPair : public HybridDhKeyPairSpec {
|
|
15
|
+
public:
|
|
16
|
+
HybridDhKeyPair() : HybridObject(TAG) {}
|
|
17
|
+
~HybridDhKeyPair() override = default;
|
|
18
|
+
|
|
19
|
+
public:
|
|
20
|
+
std::shared_ptr<Promise<void>> generateKeyPair() override;
|
|
21
|
+
void generateKeyPairSync() override;
|
|
22
|
+
void setPrimeLength(double primeLength) override;
|
|
23
|
+
void setPrime(const std::shared_ptr<ArrayBuffer>& prime) override;
|
|
24
|
+
void setGenerator(double generator) override;
|
|
25
|
+
std::shared_ptr<ArrayBuffer> getPublicKey() override;
|
|
26
|
+
std::shared_ptr<ArrayBuffer> getPrivateKey() override;
|
|
27
|
+
|
|
28
|
+
private:
|
|
29
|
+
int primeLength_ = 0;
|
|
30
|
+
std::vector<uint8_t> prime_;
|
|
31
|
+
int generator_ = 2;
|
|
32
|
+
|
|
33
|
+
using EVP_PKEY_ptr = std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)>;
|
|
34
|
+
EVP_PKEY_ptr pkey_{nullptr, EVP_PKEY_free};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
} // namespace margelo::nitro::crypto
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#include "HybridDsaKeyPair.hpp"
|
|
2
|
+
|
|
3
|
+
#include <NitroModules/ArrayBuffer.hpp>
|
|
4
|
+
#include <NitroModules/Promise.hpp>
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <openssl/bio.h>
|
|
7
|
+
#include <openssl/buffer.h>
|
|
8
|
+
#include <openssl/err.h>
|
|
9
|
+
#include <openssl/evp.h>
|
|
10
|
+
#include <openssl/pem.h>
|
|
11
|
+
#include <stdexcept>
|
|
12
|
+
#include <string>
|
|
13
|
+
|
|
14
|
+
namespace margelo::nitro::crypto {
|
|
15
|
+
|
|
16
|
+
void HybridDsaKeyPair::setModulusLength(double modulusLength) {
|
|
17
|
+
modulusLength_ = static_cast<int>(modulusLength);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
void HybridDsaKeyPair::setDivisorLength(double divisorLength) {
|
|
21
|
+
divisorLength_ = static_cast<int>(divisorLength);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
std::shared_ptr<Promise<void>> HybridDsaKeyPair::generateKeyPair() {
|
|
25
|
+
return Promise<void>::async([this]() { this->generateKeyPairSync(); });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
void HybridDsaKeyPair::generateKeyPairSync() {
|
|
29
|
+
if (modulusLength_ <= 0) {
|
|
30
|
+
throw std::runtime_error("DSA modulusLength must be set before generating key pair");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
pkey_.reset();
|
|
34
|
+
|
|
35
|
+
// Step 1: Generate DSA parameters
|
|
36
|
+
std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)> param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, nullptr), EVP_PKEY_CTX_free);
|
|
37
|
+
|
|
38
|
+
if (!param_ctx) {
|
|
39
|
+
throw std::runtime_error("DSA: failed to create parameter context");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (EVP_PKEY_paramgen_init(param_ctx.get()) <= 0) {
|
|
43
|
+
throw std::runtime_error("DSA: failed to initialize parameter generation");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (EVP_PKEY_CTX_set_dsa_paramgen_bits(param_ctx.get(), modulusLength_) <= 0) {
|
|
47
|
+
throw std::runtime_error("DSA: failed to set modulus length");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (divisorLength_ >= 0) {
|
|
51
|
+
if (EVP_PKEY_CTX_set_dsa_paramgen_q_bits(param_ctx.get(), divisorLength_) <= 0) {
|
|
52
|
+
throw std::runtime_error("DSA: failed to set divisor length");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
EVP_PKEY* raw_params = nullptr;
|
|
57
|
+
if (EVP_PKEY_paramgen(param_ctx.get(), &raw_params) <= 0) {
|
|
58
|
+
throw std::runtime_error("DSA: failed to generate parameters");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)> params(raw_params, EVP_PKEY_free);
|
|
62
|
+
|
|
63
|
+
// Step 2: Generate key pair from parameters
|
|
64
|
+
std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)> key_ctx(EVP_PKEY_CTX_new(params.get(), nullptr), EVP_PKEY_CTX_free);
|
|
65
|
+
|
|
66
|
+
if (!key_ctx) {
|
|
67
|
+
throw std::runtime_error("DSA: failed to create key generation context");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (EVP_PKEY_keygen_init(key_ctx.get()) <= 0) {
|
|
71
|
+
throw std::runtime_error("DSA: failed to initialize key generation");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
EVP_PKEY* raw_pkey = nullptr;
|
|
75
|
+
if (EVP_PKEY_keygen(key_ctx.get(), &raw_pkey) <= 0) {
|
|
76
|
+
throw std::runtime_error("DSA: failed to generate key pair");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
pkey_.reset(raw_pkey);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
std::shared_ptr<ArrayBuffer> HybridDsaKeyPair::getPublicKey() {
|
|
83
|
+
if (!pkey_) {
|
|
84
|
+
throw std::runtime_error("DSA: no key pair generated");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
BIO* bio = BIO_new(BIO_s_mem());
|
|
88
|
+
if (!bio) {
|
|
89
|
+
throw std::runtime_error("DSA: failed to create BIO for public key export");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (i2d_PUBKEY_bio(bio, pkey_.get()) != 1) {
|
|
93
|
+
BIO_free(bio);
|
|
94
|
+
throw std::runtime_error("DSA: failed to export public key");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
BUF_MEM* mem;
|
|
98
|
+
BIO_get_mem_ptr(bio, &mem);
|
|
99
|
+
std::string derData(mem->data, mem->length);
|
|
100
|
+
BIO_free(bio);
|
|
101
|
+
|
|
102
|
+
return ToNativeArrayBuffer(derData);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
std::shared_ptr<ArrayBuffer> HybridDsaKeyPair::getPrivateKey() {
|
|
106
|
+
if (!pkey_) {
|
|
107
|
+
throw std::runtime_error("DSA: no key pair generated");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
BIO* bio = BIO_new(BIO_s_mem());
|
|
111
|
+
if (!bio) {
|
|
112
|
+
throw std::runtime_error("DSA: failed to create BIO for private key export");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (i2d_PKCS8PrivateKey_bio(bio, pkey_.get(), nullptr, nullptr, 0, nullptr, nullptr) != 1) {
|
|
116
|
+
BIO_free(bio);
|
|
117
|
+
throw std::runtime_error("DSA: failed to export private key");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
BUF_MEM* mem;
|
|
121
|
+
BIO_get_mem_ptr(bio, &mem);
|
|
122
|
+
std::string derData(mem->data, mem->length);
|
|
123
|
+
BIO_free(bio);
|
|
124
|
+
|
|
125
|
+
return ToNativeArrayBuffer(derData);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
} // namespace margelo::nitro::crypto
|