react-native-quick-crypto 1.0.11 → 1.0.12
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 +7 -0
- package/cpp/cipher/CCMCipher.cpp +4 -1
- package/cpp/cipher/ChaCha20Cipher.cpp +3 -1
- package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +5 -5
- package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +1 -2
- package/cpp/cipher/HybridCipher.cpp +10 -1
- package/cpp/cipher/HybridCipher.hpp +2 -0
- package/cpp/cipher/HybridRsaCipher.cpp +0 -13
- package/cpp/cipher/XChaCha20Poly1305Cipher.cpp +7 -5
- package/cpp/cipher/XChaCha20Poly1305Cipher.hpp +1 -2
- package/cpp/cipher/XSalsa20Cipher.cpp +4 -0
- package/cpp/cipher/XSalsa20Poly1305Cipher.cpp +7 -5
- package/cpp/cipher/XSalsa20Poly1305Cipher.hpp +1 -2
- package/cpp/ecdh/HybridECDH.cpp +20 -133
- package/cpp/keys/HybridKeyObjectHandle.cpp +144 -141
- package/cpp/keys/HybridKeyObjectHandle.hpp +6 -3
- package/cpp/keys/KeyObjectData.hpp +2 -0
- package/cpp/kmac/HybridKmac.cpp +83 -0
- package/cpp/kmac/HybridKmac.hpp +31 -0
- package/cpp/mldsa/HybridMlDsaKeyPair.cpp +11 -20
- package/cpp/mldsa/HybridMlDsaKeyPair.hpp +4 -2
- package/cpp/mlkem/HybridMlKemKeyPair.cpp +319 -0
- package/cpp/mlkem/HybridMlKemKeyPair.hpp +48 -0
- package/cpp/sign/SignUtils.hpp +9 -26
- package/cpp/utils/QuickCryptoUtils.cpp +44 -0
- package/cpp/utils/QuickCryptoUtils.hpp +39 -0
- package/cpp/x509/HybridX509Certificate.cpp +174 -0
- package/cpp/x509/HybridX509Certificate.hpp +51 -0
- package/lib/commonjs/cipher.js +15 -2
- package/lib/commonjs/cipher.js.map +1 -1
- package/lib/commonjs/dhKeyPair.js +3 -3
- package/lib/commonjs/dhKeyPair.js.map +1 -1
- package/lib/commonjs/dsa.js +3 -3
- package/lib/commonjs/dsa.js.map +1 -1
- package/lib/commonjs/ec.js +18 -18
- package/lib/commonjs/ec.js.map +1 -1
- package/lib/commonjs/ed.js +9 -9
- package/lib/commonjs/ed.js.map +1 -1
- package/lib/commonjs/hash.js +17 -12
- package/lib/commonjs/hash.js.map +1 -1
- package/lib/commonjs/hkdf.js.map +1 -1
- package/lib/commonjs/index.js +22 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/keys/classes.js +2 -2
- package/lib/commonjs/keys/classes.js.map +1 -1
- package/lib/commonjs/keys/index.js +24 -0
- package/lib/commonjs/keys/index.js.map +1 -1
- package/lib/commonjs/keys/signVerify.js +0 -2
- package/lib/commonjs/keys/signVerify.js.map +1 -1
- package/lib/commonjs/mlkem.js +219 -0
- package/lib/commonjs/mlkem.js.map +1 -0
- package/lib/commonjs/pbkdf2.js +18 -1
- package/lib/commonjs/pbkdf2.js.map +1 -1
- package/lib/commonjs/rsa.js +7 -7
- package/lib/commonjs/rsa.js.map +1 -1
- package/lib/commonjs/specs/kmac.nitro.js +6 -0
- package/lib/commonjs/specs/kmac.nitro.js.map +1 -0
- package/lib/commonjs/specs/mlKemKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/mlKemKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/x509certificate.nitro.js +6 -0
- package/lib/commonjs/specs/x509certificate.nitro.js.map +1 -0
- package/lib/commonjs/subtle.js +292 -112
- package/lib/commonjs/subtle.js.map +1 -1
- package/lib/commonjs/utils/conversion.js +3 -3
- package/lib/commonjs/utils/conversion.js.map +1 -1
- package/lib/commonjs/utils/hashnames.js +31 -0
- package/lib/commonjs/utils/hashnames.js.map +1 -1
- package/lib/commonjs/utils/types.js.map +1 -1
- package/lib/commonjs/x509certificate.js +189 -0
- package/lib/commonjs/x509certificate.js.map +1 -0
- package/lib/module/cipher.js +16 -3
- package/lib/module/cipher.js.map +1 -1
- package/lib/module/dhKeyPair.js +1 -1
- package/lib/module/dhKeyPair.js.map +1 -1
- package/lib/module/dsa.js +1 -1
- package/lib/module/dsa.js.map +1 -1
- package/lib/module/ec.js +6 -6
- package/lib/module/ec.js.map +1 -1
- package/lib/module/ed.js +1 -1
- package/lib/module/ed.js.map +1 -1
- package/lib/module/hash.js +17 -12
- package/lib/module/hash.js.map +1 -1
- package/lib/module/hkdf.js.map +1 -1
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/keys/classes.js +2 -2
- package/lib/module/keys/classes.js.map +1 -1
- package/lib/module/keys/index.js +25 -1
- package/lib/module/keys/index.js.map +1 -1
- package/lib/module/keys/signVerify.js +0 -2
- package/lib/module/keys/signVerify.js.map +1 -1
- package/lib/module/mlkem.js +211 -0
- package/lib/module/mlkem.js.map +1 -0
- package/lib/module/pbkdf2.js +18 -1
- package/lib/module/pbkdf2.js.map +1 -1
- package/lib/module/rsa.js +1 -1
- package/lib/module/rsa.js.map +1 -1
- package/lib/module/specs/kmac.nitro.js +4 -0
- package/lib/module/specs/kmac.nitro.js.map +1 -0
- package/lib/module/specs/mlKemKeyPair.nitro.js +4 -0
- package/lib/module/specs/mlKemKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/x509certificate.nitro.js +4 -0
- package/lib/module/specs/x509certificate.nitro.js.map +1 -0
- package/lib/module/subtle.js +292 -112
- package/lib/module/subtle.js.map +1 -1
- package/lib/module/utils/conversion.js +3 -4
- package/lib/module/utils/conversion.js.map +1 -1
- package/lib/module/utils/hashnames.js +31 -0
- package/lib/module/utils/hashnames.js.map +1 -1
- package/lib/module/utils/types.js.map +1 -1
- package/lib/module/x509certificate.js +184 -0
- package/lib/module/x509certificate.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/typescript/cipher.d.ts +3 -0
- package/lib/typescript/cipher.d.ts.map +1 -1
- package/lib/typescript/dhKeyPair.d.ts +1 -1
- package/lib/typescript/dhKeyPair.d.ts.map +1 -1
- package/lib/typescript/dsa.d.ts +1 -1
- package/lib/typescript/dsa.d.ts.map +1 -1
- package/lib/typescript/ec.d.ts +1 -1
- package/lib/typescript/ec.d.ts.map +1 -1
- package/lib/typescript/ed.d.ts +1 -1
- package/lib/typescript/ed.d.ts.map +1 -1
- package/lib/typescript/hash.d.ts.map +1 -1
- package/lib/typescript/hkdf.d.ts +2 -6
- package/lib/typescript/hkdf.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +15 -4
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/keys/classes.d.ts +5 -5
- package/lib/typescript/keys/classes.d.ts.map +1 -1
- package/lib/typescript/keys/index.d.ts +2 -2
- package/lib/typescript/keys/index.d.ts.map +1 -1
- package/lib/typescript/keys/signVerify.d.ts.map +1 -1
- package/lib/typescript/mlkem.d.ts +30 -0
- package/lib/typescript/mlkem.d.ts.map +1 -0
- package/lib/typescript/pbkdf2.d.ts +2 -2
- package/lib/typescript/pbkdf2.d.ts.map +1 -1
- package/lib/typescript/rsa.d.ts +1 -1
- package/lib/typescript/rsa.d.ts.map +1 -1
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts +1 -0
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -1
- package/lib/typescript/specs/kmac.nitro.d.ts +10 -0
- package/lib/typescript/specs/kmac.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts +18 -0
- package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/x509certificate.nitro.d.ts +34 -0
- package/lib/typescript/specs/x509certificate.nitro.d.ts.map +1 -0
- package/lib/typescript/subtle.d.ts +10 -0
- package/lib/typescript/subtle.d.ts.map +1 -1
- package/lib/typescript/utils/conversion.d.ts.map +1 -1
- package/lib/typescript/utils/hashnames.d.ts +1 -1
- package/lib/typescript/utils/hashnames.d.ts.map +1 -1
- package/lib/typescript/utils/types.d.ts +13 -7
- package/lib/typescript/utils/types.d.ts.map +1 -1
- package/lib/typescript/x509certificate.d.ts +64 -0
- package/lib/typescript/x509certificate.d.ts.map +1 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +3 -0
- package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +30 -0
- package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +30 -0
- package/nitrogen/generated/shared/c++/AsymmetricKeyType.hpp +12 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +1 -0
- package/nitrogen/generated/shared/c++/HybridKmacSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridKmacSpec.hpp +66 -0
- package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.cpp +31 -0
- package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.hpp +74 -0
- package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.cpp +46 -0
- package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.hpp +96 -0
- package/package.json +4 -1
- package/src/cipher.ts +17 -3
- package/src/dhKeyPair.ts +1 -1
- package/src/dsa.ts +1 -1
- package/src/ec.ts +9 -9
- package/src/ed.ts +2 -2
- package/src/hash.ts +34 -11
- package/src/hkdf.ts +2 -7
- package/src/index.ts +7 -0
- package/src/keys/classes.ts +10 -9
- package/src/keys/index.ts +37 -2
- package/src/keys/signVerify.ts +0 -5
- package/src/mlkem.ts +350 -0
- package/src/pbkdf2.ts +34 -5
- package/src/rsa.ts +1 -1
- package/src/specs/keyObjectHandle.nitro.ts +5 -0
- package/src/specs/kmac.nitro.ts +12 -0
- package/src/specs/mlKemKeyPair.nitro.ts +32 -0
- package/src/specs/x509certificate.nitro.ts +38 -0
- package/src/subtle.ts +551 -125
- package/src/utils/conversion.ts +10 -4
- package/src/utils/hashnames.ts +33 -2
- package/src/utils/types.ts +42 -5
- package/src/x509certificate.ts +277 -0
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include "HybridKeyObjectHandle.hpp"
|
|
6
6
|
#include "QuickCryptoUtils.hpp"
|
|
7
7
|
#include <openssl/bn.h>
|
|
8
|
+
#include <openssl/core_names.h>
|
|
8
9
|
#include <openssl/crypto.h>
|
|
9
10
|
#include <openssl/ec.h>
|
|
10
11
|
#include <openssl/evp.h>
|
|
@@ -91,9 +92,9 @@ std::shared_ptr<ArrayBuffer> HybridKeyObjectHandle::exportKey(std::optional<KFor
|
|
|
91
92
|
const std::optional<std::shared_ptr<ArrayBuffer>>& passphrase) {
|
|
92
93
|
auto keyType = data_.GetKeyType();
|
|
93
94
|
|
|
94
|
-
//
|
|
95
|
+
// Copy to avoid JSI ArrayBuffer GC issues. See #645.
|
|
95
96
|
if (keyType == KeyType::SECRET) {
|
|
96
|
-
return data_.GetSymmetricKey();
|
|
97
|
+
return ToNativeArrayBuffer(data_.GetSymmetricKey());
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
// Handle asymmetric keys (public/private)
|
|
@@ -127,22 +128,39 @@ std::shared_ptr<ArrayBuffer> HybridKeyObjectHandle::exportKey(std::optional<KFor
|
|
|
127
128
|
|
|
128
129
|
// For EC keys, handle raw format (uncompressed point)
|
|
129
130
|
if (!format.has_value() && !type.has_value() && keyId == EVP_PKEY_EC && keyType == KeyType::PUBLIC) {
|
|
130
|
-
|
|
131
|
-
if (
|
|
132
|
-
throw std::runtime_error("Failed to get EC key");
|
|
133
|
-
const EC_GROUP* group = EC_KEY_get0_group(ec_key);
|
|
134
|
-
const EC_POINT* point = EC_KEY_get0_public_key(ec_key);
|
|
135
|
-
if (!group || !point)
|
|
136
|
-
throw std::runtime_error("Failed to get EC public key");
|
|
137
|
-
size_t len = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, nullptr);
|
|
138
|
-
if (len == 0)
|
|
139
|
-
throw std::runtime_error("Failed to get EC point size");
|
|
131
|
+
size_t len = 0;
|
|
132
|
+
if (EVP_PKEY_get_octet_string_param(pkey.get(), OSSL_PKEY_PARAM_PUB_KEY, nullptr, 0, &len) != 1 || len == 0)
|
|
133
|
+
throw std::runtime_error("Failed to get EC public key size");
|
|
140
134
|
std::vector<uint8_t> buf(len);
|
|
141
|
-
if (
|
|
142
|
-
throw std::runtime_error("Failed to
|
|
135
|
+
if (EVP_PKEY_get_octet_string_param(pkey.get(), OSSL_PKEY_PARAM_PUB_KEY, buf.data(), buf.size(), &len) != 1)
|
|
136
|
+
throw std::runtime_error("Failed to get EC public key");
|
|
137
|
+
return ToNativeArrayBuffer(std::string(reinterpret_cast<const char*>(buf.data()), len));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
#if OPENSSL_VERSION_NUMBER >= 0x30500000L
|
|
141
|
+
if (!format.has_value() && !type.has_value()) {
|
|
142
|
+
const char* typeName = EVP_PKEY_get0_type_name(pkey.get());
|
|
143
|
+
if (typeName != nullptr) {
|
|
144
|
+
std::string name(typeName);
|
|
145
|
+
bool isPqcKey = (name.starts_with("ML-KEM-") || name.starts_with("ML-DSA-"));
|
|
146
|
+
if (isPqcKey) {
|
|
147
|
+
if (keyType == KeyType::PUBLIC) {
|
|
148
|
+
auto rawData = pkey.rawPublicKey();
|
|
149
|
+
if (!rawData) {
|
|
150
|
+
throw std::runtime_error("Failed to get raw PQC public key");
|
|
151
|
+
}
|
|
152
|
+
return ToNativeArrayBuffer(std::string(reinterpret_cast<const char*>(rawData.get()), rawData.size()));
|
|
153
|
+
} else {
|
|
154
|
+
auto rawData = pkey.rawSeed();
|
|
155
|
+
if (!rawData) {
|
|
156
|
+
throw std::runtime_error("Failed to get raw PQC seed");
|
|
157
|
+
}
|
|
158
|
+
return ToNativeArrayBuffer(std::string(reinterpret_cast<const char*>(rawData.get()), rawData.size()));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
143
161
|
}
|
|
144
|
-
return ToNativeArrayBuffer(std::string(reinterpret_cast<const char*>(buf.data()), buf.size()));
|
|
145
162
|
}
|
|
163
|
+
#endif
|
|
146
164
|
|
|
147
165
|
// Set default format and type if not provided
|
|
148
166
|
auto exportFormat = format.value_or(KFormatType::DER);
|
|
@@ -258,54 +276,50 @@ JWK HybridKeyObjectHandle::exportJwk(const JWK& key, bool handleRsaPss) {
|
|
|
258
276
|
|
|
259
277
|
// Export EC keys
|
|
260
278
|
if (keyId == EVP_PKEY_EC) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
279
|
+
char curve_name_buf[64];
|
|
280
|
+
size_t name_len = 0;
|
|
281
|
+
if (EVP_PKEY_get_utf8_string_param(pkey.get(), OSSL_PKEY_PARAM_GROUP_NAME, curve_name_buf, sizeof(curve_name_buf), &name_len) != 1)
|
|
282
|
+
throw std::runtime_error("Failed to get EC group name");
|
|
264
283
|
|
|
265
|
-
|
|
266
|
-
if (!group)
|
|
267
|
-
throw std::runtime_error("Failed to get EC group");
|
|
284
|
+
std::string curve_name(curve_name_buf, name_len);
|
|
268
285
|
|
|
269
|
-
int
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
// Get the field size in bytes for proper padding
|
|
275
|
-
size_t field_size = (EC_GROUP_get_degree(group) + 7) / 8;
|
|
286
|
+
int bits = EVP_PKEY_bits(pkey.get());
|
|
287
|
+
if (bits <= 0)
|
|
288
|
+
throw std::runtime_error("Failed to get EC key size");
|
|
289
|
+
size_t field_size = (static_cast<size_t>(bits) + 7) / 8;
|
|
276
290
|
|
|
277
291
|
result.kty = JWKkty::EC;
|
|
278
292
|
|
|
279
293
|
// Map OpenSSL curve names to JWK curve names
|
|
280
|
-
if (
|
|
294
|
+
if (curve_name == "prime256v1") {
|
|
281
295
|
result.crv = "P-256";
|
|
282
|
-
} else if (
|
|
296
|
+
} else if (curve_name == "secp384r1") {
|
|
283
297
|
result.crv = "P-384";
|
|
284
|
-
} else if (
|
|
298
|
+
} else if (curve_name == "secp521r1") {
|
|
285
299
|
result.crv = "P-521";
|
|
286
300
|
} else {
|
|
287
301
|
result.crv = curve_name;
|
|
288
302
|
}
|
|
289
303
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if (EC_POINT_get_affine_coordinates(group, pub_key, x_bn, y_bn, nullptr) == 1) {
|
|
296
|
-
result.x = bn_to_base64url(x_bn, field_size);
|
|
297
|
-
result.y = bn_to_base64url(y_bn, field_size);
|
|
298
|
-
}
|
|
299
|
-
|
|
304
|
+
BIGNUM* x_bn = nullptr;
|
|
305
|
+
BIGNUM* y_bn = nullptr;
|
|
306
|
+
if (EVP_PKEY_get_bn_param(pkey.get(), OSSL_PKEY_PARAM_EC_PUB_X, &x_bn) != 1 ||
|
|
307
|
+
EVP_PKEY_get_bn_param(pkey.get(), OSSL_PKEY_PARAM_EC_PUB_Y, &y_bn) != 1) {
|
|
300
308
|
BN_free(x_bn);
|
|
301
309
|
BN_free(y_bn);
|
|
310
|
+
throw std::runtime_error("Failed to get EC public key coordinates");
|
|
302
311
|
}
|
|
312
|
+
result.x = bn_to_base64url(x_bn, field_size);
|
|
313
|
+
result.y = bn_to_base64url(y_bn, field_size);
|
|
314
|
+
BN_free(x_bn);
|
|
315
|
+
BN_free(y_bn);
|
|
303
316
|
|
|
304
317
|
// Export private key if this is a private key
|
|
305
318
|
if (keyType == KeyType::PRIVATE) {
|
|
306
|
-
|
|
307
|
-
if (
|
|
308
|
-
result.d = bn_to_base64url(
|
|
319
|
+
BIGNUM* priv_bn = nullptr;
|
|
320
|
+
if (EVP_PKEY_get_bn_param(pkey.get(), OSSL_PKEY_PARAM_PRIV_KEY, &priv_bn) == 1 && priv_bn) {
|
|
321
|
+
result.d = bn_to_base64url(priv_bn, field_size);
|
|
322
|
+
BN_free(priv_bn);
|
|
309
323
|
}
|
|
310
324
|
}
|
|
311
325
|
|
|
@@ -389,8 +403,25 @@ AsymmetricKeyType HybridKeyObjectHandle::getAsymmetricKeyType() {
|
|
|
389
403
|
return AsymmetricKeyType::ML_DSA_87;
|
|
390
404
|
#endif
|
|
391
405
|
default:
|
|
392
|
-
|
|
406
|
+
break;
|
|
393
407
|
}
|
|
408
|
+
|
|
409
|
+
#if OPENSSL_VERSION_NUMBER >= 0x30500000L
|
|
410
|
+
// EVP_PKEY_id returns -1 for provider-only key types (e.g. ML-KEM)
|
|
411
|
+
// Fall back to string-based type name comparison
|
|
412
|
+
const char* typeName = EVP_PKEY_get0_type_name(pkey.get());
|
|
413
|
+
if (typeName != nullptr) {
|
|
414
|
+
std::string name(typeName);
|
|
415
|
+
if (name == "ML-KEM-512")
|
|
416
|
+
return AsymmetricKeyType::ML_KEM_512;
|
|
417
|
+
if (name == "ML-KEM-768")
|
|
418
|
+
return AsymmetricKeyType::ML_KEM_768;
|
|
419
|
+
if (name == "ML-KEM-1024")
|
|
420
|
+
return AsymmetricKeyType::ML_KEM_1024;
|
|
421
|
+
}
|
|
422
|
+
#endif
|
|
423
|
+
|
|
424
|
+
throw std::runtime_error("Unsupported asymmetric key type");
|
|
394
425
|
}
|
|
395
426
|
|
|
396
427
|
bool HybridKeyObjectHandle::init(KeyType keyType, const std::variant<std::shared_ptr<ArrayBuffer>, std::string>& key,
|
|
@@ -574,81 +605,54 @@ std::optional<KeyType> HybridKeyObjectHandle::initJwk(const JWK& keyData, std::o
|
|
|
574
605
|
|
|
575
606
|
std::string crv = keyData.crv.value();
|
|
576
607
|
|
|
577
|
-
// Map JWK curve names to OpenSSL
|
|
578
|
-
|
|
608
|
+
// Map JWK curve names to OpenSSL group names and field sizes
|
|
609
|
+
const char* group_name;
|
|
610
|
+
size_t field_size;
|
|
579
611
|
if (crv == "P-256") {
|
|
580
|
-
|
|
612
|
+
group_name = "prime256v1";
|
|
613
|
+
field_size = 32;
|
|
581
614
|
} else if (crv == "P-384") {
|
|
582
|
-
|
|
615
|
+
group_name = "secp384r1";
|
|
616
|
+
field_size = 48;
|
|
583
617
|
} else if (crv == "P-521") {
|
|
584
|
-
|
|
618
|
+
group_name = "secp521r1";
|
|
619
|
+
field_size = 66;
|
|
585
620
|
} else {
|
|
586
621
|
throw std::runtime_error("Unsupported EC curve: " + crv);
|
|
587
622
|
}
|
|
588
623
|
|
|
589
|
-
// Create EC_KEY
|
|
590
|
-
EC_KEY* ec = EC_KEY_new_by_curve_name(nid);
|
|
591
|
-
if (!ec)
|
|
592
|
-
throw std::runtime_error("Failed to create EC key");
|
|
593
|
-
|
|
594
|
-
const EC_GROUP* group = EC_KEY_get0_group(ec);
|
|
595
|
-
|
|
596
624
|
// Decode public key coordinates
|
|
597
625
|
BIGNUM* x_bn = base64url_to_bn(keyData.x.value());
|
|
598
626
|
BIGNUM* y_bn = base64url_to_bn(keyData.y.value());
|
|
599
|
-
|
|
600
627
|
if (!x_bn || !y_bn) {
|
|
601
|
-
EC_KEY_free(ec);
|
|
602
|
-
throw std::runtime_error("Failed to decode EC public key coordinates");
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
// Set public key
|
|
606
|
-
EC_POINT* pub_key = EC_POINT_new(group);
|
|
607
|
-
if (!pub_key || EC_POINT_set_affine_coordinates(group, pub_key, x_bn, y_bn, nullptr) != 1) {
|
|
608
628
|
BN_free(x_bn);
|
|
609
629
|
BN_free(y_bn);
|
|
610
|
-
|
|
611
|
-
EC_POINT_free(pub_key);
|
|
612
|
-
EC_KEY_free(ec);
|
|
613
|
-
throw std::runtime_error("Failed to set EC public key");
|
|
630
|
+
throw std::runtime_error("Failed to decode EC public key coordinates");
|
|
614
631
|
}
|
|
615
632
|
|
|
633
|
+
// Build uncompressed point: 0x04 || x_padded || y_padded
|
|
634
|
+
std::vector<uint8_t> pub_oct(1 + 2 * field_size, 0);
|
|
635
|
+
pub_oct[0] = 0x04;
|
|
636
|
+
BN_bn2binpad(x_bn, pub_oct.data() + 1, static_cast<int>(field_size));
|
|
637
|
+
BN_bn2binpad(y_bn, pub_oct.data() + 1 + field_size, static_cast<int>(field_size));
|
|
616
638
|
BN_free(x_bn);
|
|
617
639
|
BN_free(y_bn);
|
|
618
640
|
|
|
619
|
-
|
|
620
|
-
EC_POINT_free(pub_key);
|
|
621
|
-
EC_KEY_free(ec);
|
|
622
|
-
throw std::runtime_error("Failed to set EC public key on EC_KEY");
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
EC_POINT_free(pub_key);
|
|
626
|
-
|
|
627
|
-
// Set private key if present
|
|
641
|
+
BIGNUM* d_bn = nullptr;
|
|
628
642
|
if (isPrivate) {
|
|
629
|
-
|
|
630
|
-
if (!d_bn)
|
|
631
|
-
EC_KEY_free(ec);
|
|
643
|
+
d_bn = base64url_to_bn(keyData.d.value());
|
|
644
|
+
if (!d_bn)
|
|
632
645
|
throw std::runtime_error("Failed to decode EC private key");
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
if (EC_KEY_set_private_key(ec, d_bn) != 1) {
|
|
636
|
-
BN_free(d_bn);
|
|
637
|
-
EC_KEY_free(ec);
|
|
638
|
-
throw std::runtime_error("Failed to set EC private key");
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
BN_free(d_bn);
|
|
642
646
|
}
|
|
643
647
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
throw std::runtime_error("Failed to create EVP_PKEY from EC_KEY");
|
|
648
|
+
EVP_PKEY* pkey = nullptr;
|
|
649
|
+
try {
|
|
650
|
+
pkey = createEcEvpPkey(group_name, pub_oct.data(), pub_oct.size(), d_bn);
|
|
651
|
+
} catch (...) {
|
|
652
|
+
BN_free(d_bn);
|
|
653
|
+
throw;
|
|
651
654
|
}
|
|
655
|
+
BN_free(d_bn);
|
|
652
656
|
|
|
653
657
|
KeyType type = isPrivate ? KeyType::PRIVATE : KeyType::PUBLIC;
|
|
654
658
|
data_ = KeyObjectData::CreateAsymmetric(type, ncrypto::EVPKeyPointer(pkey));
|
|
@@ -733,20 +737,11 @@ KeyDetail HybridKeyObjectHandle::keyDetail() {
|
|
|
733
737
|
}
|
|
734
738
|
|
|
735
739
|
if (keyType == EVP_PKEY_EC) {
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
if (
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
int nid = EC_GROUP_get_curve_name(group);
|
|
742
|
-
const char* curve_name = OBJ_nid2sn(nid);
|
|
743
|
-
if (curve_name) {
|
|
744
|
-
std::string namedCurve(curve_name);
|
|
745
|
-
EC_KEY_free(ec_key);
|
|
746
|
-
return KeyDetail(std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, namedCurve);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
EC_KEY_free(ec_key);
|
|
740
|
+
char curve_name[64];
|
|
741
|
+
size_t name_len = 0;
|
|
742
|
+
if (EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, curve_name, sizeof(curve_name), &name_len) == 1) {
|
|
743
|
+
return KeyDetail(std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt,
|
|
744
|
+
std::string(curve_name, name_len));
|
|
750
745
|
}
|
|
751
746
|
}
|
|
752
747
|
|
|
@@ -812,48 +807,56 @@ bool HybridKeyObjectHandle::initECRaw(const std::string& namedCurve, const std::
|
|
|
812
807
|
throw std::runtime_error("Unknown curve: " + namedCurve);
|
|
813
808
|
}
|
|
814
809
|
|
|
815
|
-
//
|
|
816
|
-
|
|
817
|
-
if (!
|
|
818
|
-
throw std::runtime_error("Failed to
|
|
810
|
+
// Get the OpenSSL group name for this curve
|
|
811
|
+
const char* group_name = OBJ_nid2sn(nid);
|
|
812
|
+
if (!group_name) {
|
|
813
|
+
throw std::runtime_error("Failed to get curve name for NID");
|
|
819
814
|
}
|
|
820
815
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
}
|
|
816
|
+
EVP_PKEY* pkey = createEcEvpPkey(group_name, keyData->data(), keyData->size());
|
|
817
|
+
this->data_ = KeyObjectData::CreateAsymmetric(KeyType::PUBLIC, ncrypto::EVPKeyPointer(pkey));
|
|
818
|
+
return true;
|
|
819
|
+
}
|
|
826
820
|
|
|
827
|
-
|
|
828
|
-
|
|
821
|
+
bool HybridKeyObjectHandle::initPqcRaw(const std::string& algorithmName, const std::shared_ptr<ArrayBuffer>& keyData, bool isPublic) {
|
|
822
|
+
#if OPENSSL_VERSION_NUMBER >= 0x30500000L
|
|
823
|
+
data_ = KeyObjectData();
|
|
829
824
|
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
825
|
+
int nid = 0;
|
|
826
|
+
if (algorithmName == "ML-KEM-512")
|
|
827
|
+
nid = EVP_PKEY_ML_KEM_512;
|
|
828
|
+
else if (algorithmName == "ML-KEM-768")
|
|
829
|
+
nid = EVP_PKEY_ML_KEM_768;
|
|
830
|
+
else if (algorithmName == "ML-KEM-1024")
|
|
831
|
+
nid = EVP_PKEY_ML_KEM_1024;
|
|
832
|
+
else if (algorithmName == "ML-DSA-44")
|
|
833
|
+
nid = EVP_PKEY_ML_DSA_44;
|
|
834
|
+
else if (algorithmName == "ML-DSA-65")
|
|
835
|
+
nid = EVP_PKEY_ML_DSA_65;
|
|
836
|
+
else if (algorithmName == "ML-DSA-87")
|
|
837
|
+
nid = EVP_PKEY_ML_DSA_87;
|
|
838
|
+
else
|
|
839
|
+
throw std::runtime_error("Unknown PQC algorithm: " + algorithmName);
|
|
833
840
|
|
|
834
|
-
|
|
835
|
-
ncrypto::ECKeyPointer ec = ncrypto::ECKeyPointer::New(group.get());
|
|
836
|
-
if (!ec) {
|
|
837
|
-
throw std::runtime_error("Failed to create EC_KEY");
|
|
838
|
-
}
|
|
841
|
+
ncrypto::Buffer<const unsigned char> buffer{.data = reinterpret_cast<const unsigned char*>(keyData->data()), .len = keyData->size()};
|
|
839
842
|
|
|
840
|
-
|
|
841
|
-
|
|
843
|
+
ncrypto::EVPKeyPointer pkey;
|
|
844
|
+
if (isPublic) {
|
|
845
|
+
pkey = ncrypto::EVPKeyPointer::NewRawPublic(nid, buffer);
|
|
846
|
+
} else {
|
|
847
|
+
pkey = ncrypto::EVPKeyPointer::NewRawSeed(nid, buffer);
|
|
842
848
|
}
|
|
843
849
|
|
|
844
|
-
// Create EVP_PKEY from EC_KEY
|
|
845
|
-
ncrypto::EVPKeyPointer pkey = ncrypto::EVPKeyPointer::New();
|
|
846
850
|
if (!pkey) {
|
|
847
|
-
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
if (!pkey.set(ec)) {
|
|
851
|
-
throw std::runtime_error("Failed to assign EC_KEY to EVP_PKEY");
|
|
851
|
+
return false;
|
|
852
852
|
}
|
|
853
853
|
|
|
854
|
-
|
|
855
|
-
this->data_ = KeyObjectData::CreateAsymmetric(
|
|
854
|
+
auto keyType = isPublic ? KeyType::PUBLIC : KeyType::PRIVATE;
|
|
855
|
+
this->data_ = KeyObjectData::CreateAsymmetric(keyType, std::move(pkey));
|
|
856
856
|
return true;
|
|
857
|
+
#else
|
|
858
|
+
throw std::runtime_error("PQC raw key import requires OpenSSL 3.5+");
|
|
859
|
+
#endif
|
|
857
860
|
}
|
|
858
861
|
|
|
859
862
|
bool HybridKeyObjectHandle::keyEquals(const std::shared_ptr<HybridKeyObjectHandleSpec>& other) {
|
|
@@ -31,6 +31,8 @@ class HybridKeyObjectHandle : public HybridKeyObjectHandleSpec {
|
|
|
31
31
|
|
|
32
32
|
bool initECRaw(const std::string& namedCurve, const std::shared_ptr<ArrayBuffer>& keyData) override;
|
|
33
33
|
|
|
34
|
+
bool initPqcRaw(const std::string& algorithmName, const std::shared_ptr<ArrayBuffer>& keyData, bool isPublic) override;
|
|
35
|
+
|
|
34
36
|
std::optional<KeyType> initJwk(const JWK& keyData, std::optional<NamedCurve> namedCurve) override;
|
|
35
37
|
|
|
36
38
|
KeyDetail keyDetail() override;
|
|
@@ -39,13 +41,14 @@ class HybridKeyObjectHandle : public HybridKeyObjectHandleSpec {
|
|
|
39
41
|
|
|
40
42
|
double getSymmetricKeySize() override;
|
|
41
43
|
|
|
42
|
-
KeyObjectData& getKeyObjectData() {
|
|
43
|
-
return data_;
|
|
44
|
-
}
|
|
45
44
|
const KeyObjectData& getKeyObjectData() const {
|
|
46
45
|
return data_;
|
|
47
46
|
}
|
|
48
47
|
|
|
48
|
+
void setKeyObjectData(KeyObjectData data) {
|
|
49
|
+
data_ = std::move(data);
|
|
50
|
+
}
|
|
51
|
+
|
|
49
52
|
private:
|
|
50
53
|
KeyObjectData data_;
|
|
51
54
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#include <NitroModules/ArrayBuffer.hpp>
|
|
2
|
+
#include <memory>
|
|
3
|
+
#include <openssl/core_names.h>
|
|
4
|
+
#include <openssl/err.h>
|
|
5
|
+
#include <openssl/evp.h>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <vector>
|
|
8
|
+
|
|
9
|
+
#include "HybridKmac.hpp"
|
|
10
|
+
|
|
11
|
+
namespace margelo::nitro::crypto {
|
|
12
|
+
|
|
13
|
+
void HybridKmac::createKmac(const std::string& algorithm, const std::shared_ptr<ArrayBuffer>& key, double outputLength,
|
|
14
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& customization) {
|
|
15
|
+
outputLen = static_cast<size_t>(outputLength);
|
|
16
|
+
if (outputLen == 0) {
|
|
17
|
+
throw std::runtime_error("KMAC output length must be greater than 0");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
std::unique_ptr<EVP_MAC, decltype(&EVP_MAC_free)> mac(EVP_MAC_fetch(nullptr, algorithm.c_str(), nullptr), EVP_MAC_free);
|
|
21
|
+
if (!mac) {
|
|
22
|
+
throw std::runtime_error("Failed to fetch " + algorithm + " implementation: " + std::to_string(ERR_get_error()));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
ctx.reset(EVP_MAC_CTX_new(mac.get()));
|
|
26
|
+
if (!ctx) {
|
|
27
|
+
throw std::runtime_error("Failed to create KMAC context: " + std::to_string(ERR_get_error()));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
OSSL_PARAM params[3];
|
|
31
|
+
size_t paramCount = 0;
|
|
32
|
+
|
|
33
|
+
params[paramCount++] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &outputLen);
|
|
34
|
+
|
|
35
|
+
std::vector<uint8_t> custData;
|
|
36
|
+
if (customization.has_value() && customization.value()->size() > 0) {
|
|
37
|
+
const auto& custBuf = customization.value();
|
|
38
|
+
custData.assign(reinterpret_cast<const uint8_t*>(custBuf->data()), reinterpret_cast<const uint8_t*>(custBuf->data()) + custBuf->size());
|
|
39
|
+
params[paramCount++] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_CUSTOM, custData.data(), custData.size());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
params[paramCount] = OSSL_PARAM_construct_end();
|
|
43
|
+
|
|
44
|
+
const uint8_t* keyData = reinterpret_cast<const uint8_t*>(key->data());
|
|
45
|
+
size_t keySize = key->size();
|
|
46
|
+
|
|
47
|
+
if (keySize == 0) {
|
|
48
|
+
throw std::runtime_error("KMAC key must not be empty");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (EVP_MAC_init(ctx.get(), keyData, keySize, params) != 1) {
|
|
52
|
+
throw std::runtime_error("Failed to initialize KMAC: " + std::to_string(ERR_get_error()));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void HybridKmac::update(const std::shared_ptr<ArrayBuffer>& data) {
|
|
57
|
+
if (!ctx) {
|
|
58
|
+
throw std::runtime_error("KMAC context not initialized");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (EVP_MAC_update(ctx.get(), reinterpret_cast<const uint8_t*>(data->data()), data->size()) != 1) {
|
|
62
|
+
throw std::runtime_error("Failed to update KMAC: " + std::to_string(ERR_get_error()));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
std::shared_ptr<ArrayBuffer> HybridKmac::digest() {
|
|
67
|
+
if (!ctx) {
|
|
68
|
+
throw std::runtime_error("KMAC context not initialized");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
uint8_t* buffer = new uint8_t[outputLen];
|
|
72
|
+
|
|
73
|
+
if (EVP_MAC_final(ctx.get(), buffer, nullptr, outputLen) != 1) {
|
|
74
|
+
delete[] buffer;
|
|
75
|
+
throw std::runtime_error("Failed to finalize KMAC digest: " + std::to_string(ERR_get_error()));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
ctx.reset();
|
|
79
|
+
|
|
80
|
+
return std::make_shared<NativeArrayBuffer>(buffer, outputLen, [=]() { delete[] buffer; });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
} // namespace margelo::nitro::crypto
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <NitroModules/ArrayBuffer.hpp>
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <openssl/evp.h>
|
|
6
|
+
#include <string>
|
|
7
|
+
|
|
8
|
+
#include "HybridKmacSpec.hpp"
|
|
9
|
+
|
|
10
|
+
namespace margelo::nitro::crypto {
|
|
11
|
+
|
|
12
|
+
using namespace facebook;
|
|
13
|
+
|
|
14
|
+
using EVP_MAC_CTX_ptr = std::unique_ptr<EVP_MAC_CTX, decltype(&EVP_MAC_CTX_free)>;
|
|
15
|
+
|
|
16
|
+
class HybridKmac : public HybridKmacSpec {
|
|
17
|
+
public:
|
|
18
|
+
HybridKmac() : HybridObject(TAG) {}
|
|
19
|
+
|
|
20
|
+
public:
|
|
21
|
+
void createKmac(const std::string& algorithm, const std::shared_ptr<ArrayBuffer>& key, double outputLength,
|
|
22
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& customization) override;
|
|
23
|
+
void update(const std::shared_ptr<ArrayBuffer>& data) override;
|
|
24
|
+
std::shared_ptr<ArrayBuffer> digest() override;
|
|
25
|
+
|
|
26
|
+
private:
|
|
27
|
+
EVP_MAC_CTX_ptr ctx{nullptr, EVP_MAC_CTX_free};
|
|
28
|
+
size_t outputLen = 0;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
} // namespace margelo::nitro::crypto
|
|
@@ -15,13 +15,6 @@
|
|
|
15
15
|
|
|
16
16
|
namespace margelo::nitro::crypto {
|
|
17
17
|
|
|
18
|
-
HybridMlDsaKeyPair::~HybridMlDsaKeyPair() {
|
|
19
|
-
if (pkey_ != nullptr) {
|
|
20
|
-
EVP_PKEY_free(pkey_);
|
|
21
|
-
pkey_ = nullptr;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
18
|
int HybridMlDsaKeyPair::getEvpPkeyType() const {
|
|
26
19
|
#if RNQC_HAS_ML_DSA
|
|
27
20
|
if (variant_ == "ML-DSA-44")
|
|
@@ -66,10 +59,7 @@ void HybridMlDsaKeyPair::generateKeyPairSync(double publicFormat, double publicT
|
|
|
66
59
|
privateFormat_ = static_cast<int>(privateFormat);
|
|
67
60
|
privateType_ = static_cast<int>(privateType);
|
|
68
61
|
|
|
69
|
-
|
|
70
|
-
EVP_PKEY_free(pkey_);
|
|
71
|
-
pkey_ = nullptr;
|
|
72
|
-
}
|
|
62
|
+
pkey_.reset();
|
|
73
63
|
|
|
74
64
|
EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_from_name(nullptr, variant_.c_str(), nullptr);
|
|
75
65
|
if (pctx == nullptr) {
|
|
@@ -81,10 +71,12 @@ void HybridMlDsaKeyPair::generateKeyPairSync(double publicFormat, double publicT
|
|
|
81
71
|
throw std::runtime_error("Failed to initialize keygen: " + getOpenSSLError());
|
|
82
72
|
}
|
|
83
73
|
|
|
84
|
-
|
|
74
|
+
EVP_PKEY* raw = nullptr;
|
|
75
|
+
if (EVP_PKEY_keygen(pctx, &raw) <= 0) {
|
|
85
76
|
EVP_PKEY_CTX_free(pctx);
|
|
86
77
|
throw std::runtime_error("Failed to generate ML-DSA key pair: " + getOpenSSLError());
|
|
87
78
|
}
|
|
79
|
+
pkey_.reset(raw);
|
|
88
80
|
|
|
89
81
|
EVP_PKEY_CTX_free(pctx);
|
|
90
82
|
#endif
|
|
@@ -103,9 +95,9 @@ std::shared_ptr<ArrayBuffer> HybridMlDsaKeyPair::getPublicKey() {
|
|
|
103
95
|
|
|
104
96
|
int result;
|
|
105
97
|
if (publicFormat_ == 1) {
|
|
106
|
-
result = PEM_write_bio_PUBKEY(bio, pkey_);
|
|
98
|
+
result = PEM_write_bio_PUBKEY(bio, pkey_.get());
|
|
107
99
|
} else {
|
|
108
|
-
result = i2d_PUBKEY_bio(bio, pkey_);
|
|
100
|
+
result = i2d_PUBKEY_bio(bio, pkey_.get());
|
|
109
101
|
}
|
|
110
102
|
|
|
111
103
|
if (result != 1) {
|
|
@@ -139,10 +131,9 @@ std::shared_ptr<ArrayBuffer> HybridMlDsaKeyPair::getPrivateKey() {
|
|
|
139
131
|
|
|
140
132
|
int result;
|
|
141
133
|
if (privateFormat_ == 1) {
|
|
142
|
-
result = PEM_write_bio_PrivateKey(bio, pkey_, nullptr, nullptr, 0, nullptr, nullptr);
|
|
134
|
+
result = PEM_write_bio_PrivateKey(bio, pkey_.get(), nullptr, nullptr, 0, nullptr, nullptr);
|
|
143
135
|
} else {
|
|
144
|
-
|
|
145
|
-
result = i2d_PKCS8PrivateKey_bio(bio, pkey_, nullptr, nullptr, 0, nullptr, nullptr);
|
|
136
|
+
result = i2d_PKCS8PrivateKey_bio(bio, pkey_.get(), nullptr, nullptr, 0, nullptr, nullptr);
|
|
146
137
|
}
|
|
147
138
|
|
|
148
139
|
if (result != 1) {
|
|
@@ -186,7 +177,7 @@ std::shared_ptr<ArrayBuffer> HybridMlDsaKeyPair::signSync(const std::shared_ptr<
|
|
|
186
177
|
throw std::runtime_error("Failed to create signing context for " + variant_);
|
|
187
178
|
}
|
|
188
179
|
|
|
189
|
-
if (EVP_DigestSignInit(md_ctx, &pkey_ctx, nullptr, nullptr, pkey_) <= 0) {
|
|
180
|
+
if (EVP_DigestSignInit(md_ctx, &pkey_ctx, nullptr, nullptr, pkey_.get()) <= 0) {
|
|
190
181
|
EVP_MD_CTX_free(md_ctx);
|
|
191
182
|
EVP_PKEY_CTX_free(pkey_ctx);
|
|
192
183
|
throw std::runtime_error("Failed to initialize signing: " + getOpenSSLError());
|
|
@@ -237,7 +228,7 @@ bool HybridMlDsaKeyPair::verifySync(const std::shared_ptr<ArrayBuffer>& signatur
|
|
|
237
228
|
throw std::runtime_error("Failed to create verify context for " + variant_);
|
|
238
229
|
}
|
|
239
230
|
|
|
240
|
-
if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, nullptr, nullptr, pkey_) <= 0) {
|
|
231
|
+
if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, nullptr, nullptr, pkey_.get()) <= 0) {
|
|
241
232
|
EVP_MD_CTX_free(md_ctx);
|
|
242
233
|
EVP_PKEY_CTX_free(pkey_ctx);
|
|
243
234
|
throw std::runtime_error("Failed to initialize verification: " + getOpenSSLError());
|
|
@@ -256,7 +247,7 @@ bool HybridMlDsaKeyPair::verifySync(const std::shared_ptr<ArrayBuffer>& signatur
|
|
|
256
247
|
}
|
|
257
248
|
|
|
258
249
|
void HybridMlDsaKeyPair::checkKeyPair() {
|
|
259
|
-
if (pkey_
|
|
250
|
+
if (!pkey_) {
|
|
260
251
|
throw std::runtime_error("Key pair not initialized");
|
|
261
252
|
}
|
|
262
253
|
}
|
|
@@ -11,7 +11,7 @@ namespace margelo::nitro::crypto {
|
|
|
11
11
|
class HybridMlDsaKeyPair : public HybridMlDsaKeyPairSpec {
|
|
12
12
|
public:
|
|
13
13
|
HybridMlDsaKeyPair() : HybridObject(TAG) {}
|
|
14
|
-
~HybridMlDsaKeyPair();
|
|
14
|
+
~HybridMlDsaKeyPair() override = default;
|
|
15
15
|
|
|
16
16
|
std::shared_ptr<Promise<void>> generateKeyPair(double publicFormat, double publicType, double privateFormat, double privateType) override;
|
|
17
17
|
|
|
@@ -32,8 +32,10 @@ class HybridMlDsaKeyPair : public HybridMlDsaKeyPairSpec {
|
|
|
32
32
|
void setVariant(const std::string& variant) override;
|
|
33
33
|
|
|
34
34
|
private:
|
|
35
|
+
using EVP_PKEY_ptr = std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)>;
|
|
36
|
+
|
|
35
37
|
std::string variant_;
|
|
36
|
-
|
|
38
|
+
EVP_PKEY_ptr pkey_{nullptr, EVP_PKEY_free};
|
|
37
39
|
|
|
38
40
|
int publicFormat_ = -1;
|
|
39
41
|
int publicType_ = -1;
|