react-native-quick-crypto 1.0.9 → 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.
Files changed (292) hide show
  1. package/QuickCrypto.podspec +9 -2
  2. package/README.md +13 -9
  3. package/android/CMakeLists.txt +13 -0
  4. package/cpp/argon2/HybridArgon2.cpp +103 -0
  5. package/cpp/argon2/HybridArgon2.hpp +32 -0
  6. package/cpp/certificate/HybridCertificate.cpp +42 -0
  7. package/cpp/certificate/HybridCertificate.hpp +16 -0
  8. package/cpp/cipher/HybridCipher.cpp +58 -0
  9. package/cpp/cipher/HybridCipher.hpp +4 -0
  10. package/cpp/cipher/HybridCipherFactory.hpp +15 -1
  11. package/cpp/cipher/OCBCipher.cpp +4 -4
  12. package/cpp/cipher/XChaCha20Poly1305Cipher.cpp +161 -0
  13. package/cpp/cipher/XChaCha20Poly1305Cipher.hpp +43 -0
  14. package/cpp/cipher/XSalsa20Poly1305Cipher.cpp +145 -0
  15. package/cpp/cipher/XSalsa20Poly1305Cipher.hpp +42 -0
  16. package/cpp/dh/HybridDhKeyPair.cpp +179 -0
  17. package/cpp/dh/HybridDhKeyPair.hpp +37 -0
  18. package/cpp/dh/HybridDiffieHellman.cpp +10 -0
  19. package/cpp/dh/HybridDiffieHellman.hpp +1 -0
  20. package/cpp/dsa/HybridDsaKeyPair.cpp +128 -0
  21. package/cpp/dsa/HybridDsaKeyPair.hpp +32 -0
  22. package/cpp/ec/HybridEcKeyPair.cpp +21 -0
  23. package/cpp/ec/HybridEcKeyPair.hpp +1 -0
  24. package/cpp/ecdh/HybridECDH.cpp +35 -0
  25. package/cpp/ecdh/HybridECDH.hpp +1 -0
  26. package/cpp/hash/HybridHash.cpp +1 -1
  27. package/cpp/hash/HybridHash.hpp +1 -1
  28. package/cpp/hmac/HybridHmac.cpp +1 -1
  29. package/cpp/hmac/HybridHmac.hpp +1 -1
  30. package/cpp/keys/HybridKeyObjectHandle.cpp +131 -1
  31. package/cpp/keys/HybridKeyObjectHandle.hpp +5 -1
  32. package/cpp/prime/HybridPrime.cpp +81 -0
  33. package/cpp/prime/HybridPrime.hpp +20 -0
  34. package/deps/ncrypto/.bazelrc +0 -1
  35. package/deps/ncrypto/.bazelversion +1 -1
  36. package/deps/ncrypto/.github/workflows/commitlint.yml +16 -0
  37. package/deps/ncrypto/.github/workflows/linter.yml +2 -2
  38. package/deps/ncrypto/.github/workflows/release-please.yml +16 -0
  39. package/deps/ncrypto/.github/workflows/ubuntu.yml +82 -0
  40. package/deps/ncrypto/.release-please-manifest.json +3 -0
  41. package/deps/ncrypto/BUILD.bazel +9 -1
  42. package/deps/ncrypto/CHANGELOG.md +37 -0
  43. package/deps/ncrypto/CMakeLists.txt +35 -11
  44. package/deps/ncrypto/MODULE.bazel +16 -1
  45. package/deps/ncrypto/MODULE.bazel.lock +299 -118
  46. package/deps/ncrypto/cmake/ncrypto-flags.cmake +1 -0
  47. package/deps/ncrypto/include/ncrypto/aead.h +137 -0
  48. package/deps/ncrypto/include/ncrypto/version.h +14 -0
  49. package/deps/ncrypto/include/ncrypto.h +85 -230
  50. package/deps/ncrypto/ncrypto.pc.in +10 -0
  51. package/deps/ncrypto/release-please-config.json +11 -0
  52. package/deps/ncrypto/src/CMakeLists.txt +31 -6
  53. package/deps/ncrypto/src/aead.cpp +302 -0
  54. package/deps/ncrypto/src/ncrypto.cpp +274 -556
  55. package/deps/ncrypto/tests/BUILD.bazel +2 -0
  56. package/deps/ncrypto/tests/basic.cpp +772 -2
  57. package/deps/ncrypto/tools/run-clang-format.sh +5 -5
  58. package/lib/commonjs/argon2.js +39 -0
  59. package/lib/commonjs/argon2.js.map +1 -0
  60. package/lib/commonjs/certificate.js +35 -0
  61. package/lib/commonjs/certificate.js.map +1 -0
  62. package/lib/commonjs/cipher.js +8 -0
  63. package/lib/commonjs/cipher.js.map +1 -1
  64. package/lib/commonjs/dhKeyPair.js +109 -0
  65. package/lib/commonjs/dhKeyPair.js.map +1 -0
  66. package/lib/commonjs/diffie-hellman.js +4 -1
  67. package/lib/commonjs/diffie-hellman.js.map +1 -1
  68. package/lib/commonjs/dsa.js +92 -0
  69. package/lib/commonjs/dsa.js.map +1 -0
  70. package/lib/commonjs/ec.js +20 -25
  71. package/lib/commonjs/ec.js.map +1 -1
  72. package/lib/commonjs/ecdh.js +37 -0
  73. package/lib/commonjs/ecdh.js.map +1 -1
  74. package/lib/commonjs/ed.js +1 -2
  75. package/lib/commonjs/ed.js.map +1 -1
  76. package/lib/commonjs/hash.js +7 -0
  77. package/lib/commonjs/hash.js.map +1 -1
  78. package/lib/commonjs/index.js +46 -1
  79. package/lib/commonjs/index.js.map +1 -1
  80. package/lib/commonjs/keys/classes.js +18 -12
  81. package/lib/commonjs/keys/classes.js.map +1 -1
  82. package/lib/commonjs/keys/generateKeyPair.js +11 -0
  83. package/lib/commonjs/keys/generateKeyPair.js.map +1 -1
  84. package/lib/commonjs/prime.js +84 -0
  85. package/lib/commonjs/prime.js.map +1 -0
  86. package/lib/commonjs/specs/argon2.nitro.js +6 -0
  87. package/lib/commonjs/specs/argon2.nitro.js.map +1 -0
  88. package/lib/commonjs/specs/certificate.nitro.js +6 -0
  89. package/lib/commonjs/specs/certificate.nitro.js.map +1 -0
  90. package/lib/commonjs/specs/dhKeyPair.nitro.js +6 -0
  91. package/lib/commonjs/specs/dhKeyPair.nitro.js.map +1 -0
  92. package/lib/commonjs/specs/dsaKeyPair.nitro.js +6 -0
  93. package/lib/commonjs/specs/dsaKeyPair.nitro.js.map +1 -0
  94. package/lib/commonjs/specs/prime.nitro.js +6 -0
  95. package/lib/commonjs/specs/prime.nitro.js.map +1 -0
  96. package/lib/commonjs/subtle.js +181 -39
  97. package/lib/commonjs/subtle.js.map +1 -1
  98. package/lib/commonjs/utils/types.js.map +1 -1
  99. package/lib/module/argon2.js +34 -0
  100. package/lib/module/argon2.js.map +1 -0
  101. package/lib/module/certificate.js +30 -0
  102. package/lib/module/certificate.js.map +1 -0
  103. package/lib/module/cipher.js +7 -0
  104. package/lib/module/cipher.js.map +1 -1
  105. package/lib/module/dhKeyPair.js +102 -0
  106. package/lib/module/dhKeyPair.js.map +1 -0
  107. package/lib/module/diffie-hellman.js +4 -0
  108. package/lib/module/diffie-hellman.js.map +1 -1
  109. package/lib/module/dsa.js +85 -0
  110. package/lib/module/dsa.js.map +1 -0
  111. package/lib/module/ec.js +19 -25
  112. package/lib/module/ec.js.map +1 -1
  113. package/lib/module/ecdh.js +37 -0
  114. package/lib/module/ecdh.js.map +1 -1
  115. package/lib/module/ed.js +1 -2
  116. package/lib/module/ed.js.map +1 -1
  117. package/lib/module/hash.js +6 -0
  118. package/lib/module/hash.js.map +1 -1
  119. package/lib/module/index.js +12 -0
  120. package/lib/module/index.js.map +1 -1
  121. package/lib/module/keys/classes.js +18 -12
  122. package/lib/module/keys/classes.js.map +1 -1
  123. package/lib/module/keys/generateKeyPair.js +11 -0
  124. package/lib/module/keys/generateKeyPair.js.map +1 -1
  125. package/lib/module/prime.js +77 -0
  126. package/lib/module/prime.js.map +1 -0
  127. package/lib/module/specs/argon2.nitro.js +4 -0
  128. package/lib/module/specs/argon2.nitro.js.map +1 -0
  129. package/lib/module/specs/certificate.nitro.js +4 -0
  130. package/lib/module/specs/certificate.nitro.js.map +1 -0
  131. package/lib/module/specs/dhKeyPair.nitro.js +4 -0
  132. package/lib/module/specs/dhKeyPair.nitro.js.map +1 -0
  133. package/lib/module/specs/dsaKeyPair.nitro.js +4 -0
  134. package/lib/module/specs/dsaKeyPair.nitro.js.map +1 -0
  135. package/lib/module/specs/prime.nitro.js +4 -0
  136. package/lib/module/specs/prime.nitro.js.map +1 -0
  137. package/lib/module/subtle.js +183 -42
  138. package/lib/module/subtle.js.map +1 -1
  139. package/lib/module/utils/types.js.map +1 -1
  140. package/lib/tsconfig.tsbuildinfo +1 -1
  141. package/lib/typescript/argon2.d.ts +16 -0
  142. package/lib/typescript/argon2.d.ts.map +1 -0
  143. package/lib/typescript/certificate.d.ts +8 -0
  144. package/lib/typescript/certificate.d.ts.map +1 -0
  145. package/lib/typescript/cipher.d.ts +12 -0
  146. package/lib/typescript/cipher.d.ts.map +1 -1
  147. package/lib/typescript/dhKeyPair.d.ts +19 -0
  148. package/lib/typescript/dhKeyPair.d.ts.map +1 -0
  149. package/lib/typescript/diffie-hellman.d.ts +2 -0
  150. package/lib/typescript/diffie-hellman.d.ts.map +1 -1
  151. package/lib/typescript/dsa.d.ts +19 -0
  152. package/lib/typescript/dsa.d.ts.map +1 -0
  153. package/lib/typescript/ec.d.ts +1 -0
  154. package/lib/typescript/ec.d.ts.map +1 -1
  155. package/lib/typescript/ecdh.d.ts +3 -0
  156. package/lib/typescript/ecdh.d.ts.map +1 -1
  157. package/lib/typescript/ed.d.ts.map +1 -1
  158. package/lib/typescript/hash.d.ts +2 -0
  159. package/lib/typescript/hash.d.ts.map +1 -1
  160. package/lib/typescript/index.d.ts +22 -0
  161. package/lib/typescript/index.d.ts.map +1 -1
  162. package/lib/typescript/keys/classes.d.ts +4 -0
  163. package/lib/typescript/keys/classes.d.ts.map +1 -1
  164. package/lib/typescript/keys/generateKeyPair.d.ts.map +1 -1
  165. package/lib/typescript/prime.d.ts +19 -0
  166. package/lib/typescript/prime.d.ts.map +1 -0
  167. package/lib/typescript/specs/argon2.nitro.d.ts +9 -0
  168. package/lib/typescript/specs/argon2.nitro.d.ts.map +1 -0
  169. package/lib/typescript/specs/certificate.nitro.d.ts +10 -0
  170. package/lib/typescript/specs/certificate.nitro.d.ts.map +1 -0
  171. package/lib/typescript/specs/cipher.nitro.d.ts +9 -0
  172. package/lib/typescript/specs/cipher.nitro.d.ts.map +1 -1
  173. package/lib/typescript/specs/dhKeyPair.nitro.d.ts +14 -0
  174. package/lib/typescript/specs/dhKeyPair.nitro.d.ts.map +1 -0
  175. package/lib/typescript/specs/diffie-hellman.nitro.d.ts +1 -0
  176. package/lib/typescript/specs/diffie-hellman.nitro.d.ts.map +1 -1
  177. package/lib/typescript/specs/dsaKeyPair.nitro.d.ts +13 -0
  178. package/lib/typescript/specs/dsaKeyPair.nitro.d.ts.map +1 -0
  179. package/lib/typescript/specs/ecKeyPair.nitro.d.ts +1 -0
  180. package/lib/typescript/specs/ecKeyPair.nitro.d.ts.map +1 -1
  181. package/lib/typescript/specs/ecdh.nitro.d.ts +1 -0
  182. package/lib/typescript/specs/ecdh.nitro.d.ts.map +1 -1
  183. package/lib/typescript/specs/keyObjectHandle.nitro.d.ts +2 -0
  184. package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -1
  185. package/lib/typescript/specs/prime.nitro.d.ts +11 -0
  186. package/lib/typescript/specs/prime.nitro.d.ts.map +1 -0
  187. package/lib/typescript/subtle.d.ts +2 -0
  188. package/lib/typescript/subtle.d.ts.map +1 -1
  189. package/lib/typescript/utils/types.d.ts +24 -7
  190. package/lib/typescript/utils/types.d.ts.map +1 -1
  191. package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +13 -5
  192. package/nitrogen/generated/android/QuickCrypto+autolinking.gradle +1 -1
  193. package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +104 -54
  194. package/nitrogen/generated/android/QuickCryptoOnLoad.hpp +1 -1
  195. package/nitrogen/generated/android/kotlin/com/margelo/nitro/crypto/QuickCryptoOnLoad.kt +1 -1
  196. package/nitrogen/generated/ios/QuickCrypto+autolinking.rb +2 -2
  197. package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.cpp +1 -1
  198. package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.hpp +1 -1
  199. package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Umbrella.hpp +1 -1
  200. package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +104 -54
  201. package/nitrogen/generated/ios/QuickCryptoAutolinking.swift +5 -1
  202. package/nitrogen/generated/shared/c++/AsymmetricKeyType.hpp +1 -1
  203. package/nitrogen/generated/shared/c++/CipherArgs.hpp +34 -19
  204. package/nitrogen/generated/shared/c++/CipherInfo.hpp +104 -0
  205. package/nitrogen/generated/shared/c++/HybridArgon2Spec.cpp +22 -0
  206. package/nitrogen/generated/shared/c++/HybridArgon2Spec.hpp +66 -0
  207. package/nitrogen/generated/shared/c++/HybridBlake3Spec.cpp +1 -1
  208. package/nitrogen/generated/shared/c++/HybridBlake3Spec.hpp +1 -3
  209. package/nitrogen/generated/shared/c++/HybridCertificateSpec.cpp +23 -0
  210. package/nitrogen/generated/shared/c++/HybridCertificateSpec.hpp +64 -0
  211. package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.cpp +1 -1
  212. package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.hpp +1 -1
  213. package/nitrogen/generated/shared/c++/HybridCipherSpec.cpp +2 -1
  214. package/nitrogen/generated/shared/c++/HybridCipherSpec.hpp +5 -3
  215. package/nitrogen/generated/shared/c++/HybridDhKeyPairSpec.cpp +27 -0
  216. package/nitrogen/generated/shared/c++/HybridDhKeyPairSpec.hpp +69 -0
  217. package/nitrogen/generated/shared/c++/HybridDiffieHellmanSpec.cpp +2 -1
  218. package/nitrogen/generated/shared/c++/HybridDiffieHellmanSpec.hpp +3 -3
  219. package/nitrogen/generated/shared/c++/HybridDsaKeyPairSpec.cpp +26 -0
  220. package/nitrogen/generated/shared/c++/HybridDsaKeyPairSpec.hpp +68 -0
  221. package/nitrogen/generated/shared/c++/HybridECDHSpec.cpp +2 -1
  222. package/nitrogen/generated/shared/c++/HybridECDHSpec.hpp +3 -3
  223. package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.cpp +2 -1
  224. package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.hpp +2 -3
  225. package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.cpp +1 -1
  226. package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.hpp +2 -3
  227. package/nitrogen/generated/shared/c++/HybridHashSpec.cpp +1 -1
  228. package/nitrogen/generated/shared/c++/HybridHashSpec.hpp +2 -4
  229. package/nitrogen/generated/shared/c++/HybridHkdfSpec.cpp +1 -1
  230. package/nitrogen/generated/shared/c++/HybridHkdfSpec.hpp +2 -3
  231. package/nitrogen/generated/shared/c++/HybridHmacSpec.cpp +1 -1
  232. package/nitrogen/generated/shared/c++/HybridHmacSpec.hpp +3 -4
  233. package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp +3 -1
  234. package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +8 -4
  235. package/nitrogen/generated/shared/c++/HybridMlDsaKeyPairSpec.cpp +1 -1
  236. package/nitrogen/generated/shared/c++/HybridMlDsaKeyPairSpec.hpp +2 -3
  237. package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.cpp +1 -1
  238. package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.hpp +2 -3
  239. package/nitrogen/generated/shared/c++/HybridPrimeSpec.cpp +24 -0
  240. package/nitrogen/generated/shared/c++/HybridPrimeSpec.hpp +67 -0
  241. package/nitrogen/generated/shared/c++/HybridRandomSpec.cpp +1 -1
  242. package/nitrogen/generated/shared/c++/HybridRandomSpec.hpp +2 -3
  243. package/nitrogen/generated/shared/c++/HybridRsaCipherSpec.cpp +1 -1
  244. package/nitrogen/generated/shared/c++/HybridRsaCipherSpec.hpp +1 -3
  245. package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.cpp +1 -1
  246. package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.hpp +1 -3
  247. package/nitrogen/generated/shared/c++/HybridScryptSpec.cpp +1 -1
  248. package/nitrogen/generated/shared/c++/HybridScryptSpec.hpp +2 -3
  249. package/nitrogen/generated/shared/c++/HybridSignHandleSpec.cpp +1 -1
  250. package/nitrogen/generated/shared/c++/HybridSignHandleSpec.hpp +1 -3
  251. package/nitrogen/generated/shared/c++/HybridUtilsSpec.cpp +1 -1
  252. package/nitrogen/generated/shared/c++/HybridUtilsSpec.hpp +2 -3
  253. package/nitrogen/generated/shared/c++/HybridVerifyHandleSpec.cpp +1 -1
  254. package/nitrogen/generated/shared/c++/HybridVerifyHandleSpec.hpp +1 -3
  255. package/nitrogen/generated/shared/c++/JWK.hpp +84 -68
  256. package/nitrogen/generated/shared/c++/JWKkty.hpp +5 -1
  257. package/nitrogen/generated/shared/c++/JWKuse.hpp +1 -1
  258. package/nitrogen/generated/shared/c++/KFormatType.hpp +1 -1
  259. package/nitrogen/generated/shared/c++/KeyDetail.hpp +39 -23
  260. package/nitrogen/generated/shared/c++/KeyEncoding.hpp +1 -1
  261. package/nitrogen/generated/shared/c++/KeyObject.hpp +21 -5
  262. package/nitrogen/generated/shared/c++/KeyType.hpp +1 -1
  263. package/nitrogen/generated/shared/c++/KeyUsage.hpp +1 -1
  264. package/nitrogen/generated/shared/c++/NamedCurve.hpp +1 -1
  265. package/package.json +1 -1
  266. package/src/argon2.ts +83 -0
  267. package/src/certificate.ts +41 -0
  268. package/src/cipher.ts +24 -0
  269. package/src/dhKeyPair.ts +156 -0
  270. package/src/diffie-hellman.ts +6 -0
  271. package/src/dsa.ts +129 -0
  272. package/src/ec.ts +23 -19
  273. package/src/ecdh.ts +59 -0
  274. package/src/ed.ts +1 -2
  275. package/src/hash.ts +11 -0
  276. package/src/index.ts +12 -0
  277. package/src/keys/classes.ts +26 -8
  278. package/src/keys/generateKeyPair.ts +14 -0
  279. package/src/prime.ts +134 -0
  280. package/src/specs/argon2.nitro.ts +29 -0
  281. package/src/specs/certificate.nitro.ts +8 -0
  282. package/src/specs/cipher.nitro.ts +14 -0
  283. package/src/specs/dhKeyPair.nitro.ts +14 -0
  284. package/src/specs/diffie-hellman.nitro.ts +1 -0
  285. package/src/specs/dsaKeyPair.nitro.ts +13 -0
  286. package/src/specs/ecKeyPair.nitro.ts +2 -0
  287. package/src/specs/ecdh.nitro.ts +1 -0
  288. package/src/specs/keyObjectHandle.nitro.ts +2 -0
  289. package/src/specs/prime.nitro.ts +18 -0
  290. package/src/subtle.ts +400 -42
  291. package/src/utils/types.ts +39 -5
  292. package/deps/ncrypto/WORKSPACE +0 -15
@@ -0,0 +1,43 @@
1
+ #pragma once
2
+
3
+ #ifdef BLSALLOC_SODIUM
4
+ #include "sodium.h"
5
+ #else
6
+ #define crypto_aead_xchacha20poly1305_ietf_KEYBYTES 32U
7
+ #define crypto_aead_xchacha20poly1305_ietf_NPUBBYTES 24U
8
+ #define crypto_aead_xchacha20poly1305_ietf_ABYTES 16U
9
+ #endif
10
+
11
+ #include <vector>
12
+
13
+ #include "HybridCipher.hpp"
14
+
15
+ namespace margelo::nitro::crypto {
16
+
17
+ class XChaCha20Poly1305Cipher : public HybridCipher {
18
+ public:
19
+ XChaCha20Poly1305Cipher() : HybridObject(TAG), final_called_(false) {}
20
+ ~XChaCha20Poly1305Cipher();
21
+
22
+ void init(const std::shared_ptr<ArrayBuffer> cipher_key, const std::shared_ptr<ArrayBuffer> iv) override;
23
+ std::shared_ptr<ArrayBuffer> update(const std::shared_ptr<ArrayBuffer>& data) override;
24
+ std::shared_ptr<ArrayBuffer> final() override;
25
+ bool setAAD(const std::shared_ptr<ArrayBuffer>& data, std::optional<double> plaintextLength) override;
26
+ std::shared_ptr<ArrayBuffer> getAuthTag() override;
27
+ bool setAuthTag(const std::shared_ptr<ArrayBuffer>& tag) override;
28
+ bool setAutoPadding(bool autoPad) override;
29
+
30
+ private:
31
+ static constexpr size_t kKeySize = crypto_aead_xchacha20poly1305_ietf_KEYBYTES;
32
+ static constexpr size_t kNonceSize = crypto_aead_xchacha20poly1305_ietf_NPUBBYTES;
33
+ static constexpr size_t kTagSize = crypto_aead_xchacha20poly1305_ietf_ABYTES;
34
+
35
+ uint8_t key_[kKeySize];
36
+ uint8_t nonce_[kNonceSize];
37
+ std::vector<uint8_t> aad_;
38
+ std::vector<uint8_t> data_buffer_;
39
+ uint8_t auth_tag_[kTagSize];
40
+ bool final_called_;
41
+ };
42
+
43
+ } // namespace margelo::nitro::crypto
@@ -0,0 +1,145 @@
1
+ #include "XSalsa20Poly1305Cipher.hpp"
2
+
3
+ #include <cstring>
4
+ #include <stdexcept>
5
+
6
+ #include "NitroModules/ArrayBuffer.hpp"
7
+ #include "QuickCryptoUtils.hpp"
8
+
9
+ namespace margelo::nitro::crypto {
10
+
11
+ XSalsa20Poly1305Cipher::~XSalsa20Poly1305Cipher() {
12
+ #ifdef BLSALLOC_SODIUM
13
+ sodium_memzero(key_, kKeySize);
14
+ sodium_memzero(nonce_, kNonceSize);
15
+ sodium_memzero(auth_tag_, kTagSize);
16
+ if (!data_buffer_.empty()) {
17
+ sodium_memzero(data_buffer_.data(), data_buffer_.size());
18
+ }
19
+ #else
20
+ std::memset(key_, 0, kKeySize);
21
+ std::memset(nonce_, 0, kNonceSize);
22
+ std::memset(auth_tag_, 0, kTagSize);
23
+ #endif
24
+ data_buffer_.clear();
25
+ }
26
+
27
+ void XSalsa20Poly1305Cipher::init(const std::shared_ptr<ArrayBuffer> cipher_key, const std::shared_ptr<ArrayBuffer> iv) {
28
+ auto native_key = ToNativeArrayBuffer(cipher_key);
29
+ auto native_iv = ToNativeArrayBuffer(iv);
30
+
31
+ if (native_key->size() != kKeySize) {
32
+ throw std::runtime_error("XSalsa20-Poly1305 key must be 32 bytes, got " + std::to_string(native_key->size()) + " bytes");
33
+ }
34
+
35
+ if (native_iv->size() != kNonceSize) {
36
+ throw std::runtime_error("XSalsa20-Poly1305 nonce must be 24 bytes, got " + std::to_string(native_iv->size()) + " bytes");
37
+ }
38
+
39
+ std::memcpy(key_, native_key->data(), kKeySize);
40
+ std::memcpy(nonce_, native_iv->data(), kNonceSize);
41
+
42
+ data_buffer_.clear();
43
+ final_called_ = false;
44
+ }
45
+
46
+ std::shared_ptr<ArrayBuffer> XSalsa20Poly1305Cipher::update(const std::shared_ptr<ArrayBuffer>& data) {
47
+ #ifndef BLSALLOC_SODIUM
48
+ throw std::runtime_error("XSalsa20Poly1305Cipher: libsodium must be enabled (BLSALLOC_SODIUM)");
49
+ #else
50
+ auto native_data = ToNativeArrayBuffer(data);
51
+ size_t data_len = native_data->size();
52
+
53
+ size_t old_size = data_buffer_.size();
54
+ data_buffer_.resize(old_size + data_len);
55
+ std::memcpy(data_buffer_.data() + old_size, native_data->data(), data_len);
56
+
57
+ return std::make_shared<NativeArrayBuffer>(nullptr, 0, nullptr);
58
+ #endif
59
+ }
60
+
61
+ std::shared_ptr<ArrayBuffer> XSalsa20Poly1305Cipher::final() {
62
+ #ifndef BLSALLOC_SODIUM
63
+ throw std::runtime_error("XSalsa20Poly1305Cipher: libsodium must be enabled (BLSALLOC_SODIUM)");
64
+ #else
65
+ if (is_cipher) {
66
+ uint8_t* ciphertext = new uint8_t[data_buffer_.size()];
67
+
68
+ int result = crypto_secretbox_detached(ciphertext, auth_tag_, data_buffer_.data(), data_buffer_.size(), nonce_, key_);
69
+
70
+ if (result != 0) {
71
+ sodium_memzero(ciphertext, data_buffer_.size());
72
+ delete[] ciphertext;
73
+ throw std::runtime_error("XSalsa20Poly1305Cipher: encryption failed");
74
+ }
75
+
76
+ final_called_ = true;
77
+ size_t ct_len = data_buffer_.size();
78
+ return std::make_shared<NativeArrayBuffer>(ciphertext, ct_len, [=]() { delete[] ciphertext; });
79
+ } else {
80
+ if (data_buffer_.empty()) {
81
+ final_called_ = true;
82
+ return std::make_shared<NativeArrayBuffer>(nullptr, 0, nullptr);
83
+ }
84
+
85
+ uint8_t* plaintext = new uint8_t[data_buffer_.size()];
86
+
87
+ int result = crypto_secretbox_open_detached(plaintext, data_buffer_.data(), auth_tag_, data_buffer_.size(), nonce_, key_);
88
+
89
+ if (result != 0) {
90
+ sodium_memzero(plaintext, data_buffer_.size());
91
+ delete[] plaintext;
92
+ throw std::runtime_error("XSalsa20Poly1305Cipher: decryption failed - authentication tag mismatch");
93
+ }
94
+
95
+ final_called_ = true;
96
+ size_t pt_len = data_buffer_.size();
97
+ return std::make_shared<NativeArrayBuffer>(plaintext, pt_len, [=]() { delete[] plaintext; });
98
+ }
99
+ #endif
100
+ }
101
+
102
+ bool XSalsa20Poly1305Cipher::setAAD(const std::shared_ptr<ArrayBuffer>& data, std::optional<double> plaintextLength) {
103
+ throw std::runtime_error("AAD is not supported for xsalsa20-poly1305 (use xchacha20-poly1305 instead)");
104
+ }
105
+
106
+ std::shared_ptr<ArrayBuffer> XSalsa20Poly1305Cipher::getAuthTag() {
107
+ #ifndef BLSALLOC_SODIUM
108
+ throw std::runtime_error("XSalsa20Poly1305Cipher: libsodium must be enabled (BLSALLOC_SODIUM)");
109
+ #else
110
+ if (!is_cipher) {
111
+ throw std::runtime_error("getAuthTag can only be called during encryption");
112
+ }
113
+ if (!final_called_) {
114
+ throw std::runtime_error("getAuthTag must be called after final()");
115
+ }
116
+
117
+ uint8_t* tag_copy = new uint8_t[kTagSize];
118
+ std::memcpy(tag_copy, auth_tag_, kTagSize);
119
+ return std::make_shared<NativeArrayBuffer>(tag_copy, kTagSize, [=]() { delete[] tag_copy; });
120
+ #endif
121
+ }
122
+
123
+ bool XSalsa20Poly1305Cipher::setAuthTag(const std::shared_ptr<ArrayBuffer>& tag) {
124
+ #ifndef BLSALLOC_SODIUM
125
+ throw std::runtime_error("XSalsa20Poly1305Cipher: libsodium must be enabled (BLSALLOC_SODIUM)");
126
+ #else
127
+ if (is_cipher) {
128
+ throw std::runtime_error("setAuthTag can only be called during decryption");
129
+ }
130
+
131
+ auto native_tag = ToNativeArrayBuffer(tag);
132
+ if (native_tag->size() != kTagSize) {
133
+ throw std::runtime_error("XSalsa20-Poly1305 tag must be 16 bytes, got " + std::to_string(native_tag->size()) + " bytes");
134
+ }
135
+
136
+ std::memcpy(auth_tag_, native_tag->data(), kTagSize);
137
+ return true;
138
+ #endif
139
+ }
140
+
141
+ bool XSalsa20Poly1305Cipher::setAutoPadding(bool autoPad) {
142
+ throw std::runtime_error("setAutoPadding is not supported for xsalsa20-poly1305");
143
+ }
144
+
145
+ } // namespace margelo::nitro::crypto
@@ -0,0 +1,42 @@
1
+ #pragma once
2
+
3
+ #ifdef BLSALLOC_SODIUM
4
+ #include "sodium.h"
5
+ #else
6
+ #define crypto_secretbox_xsalsa20poly1305_KEYBYTES 32U
7
+ #define crypto_secretbox_xsalsa20poly1305_NONCEBYTES 24U
8
+ #define crypto_secretbox_xsalsa20poly1305_MACBYTES 16U
9
+ #endif
10
+
11
+ #include <vector>
12
+
13
+ #include "HybridCipher.hpp"
14
+
15
+ namespace margelo::nitro::crypto {
16
+
17
+ class XSalsa20Poly1305Cipher : public HybridCipher {
18
+ public:
19
+ XSalsa20Poly1305Cipher() : HybridObject(TAG), final_called_(false) {}
20
+ ~XSalsa20Poly1305Cipher();
21
+
22
+ void init(const std::shared_ptr<ArrayBuffer> cipher_key, const std::shared_ptr<ArrayBuffer> iv) override;
23
+ std::shared_ptr<ArrayBuffer> update(const std::shared_ptr<ArrayBuffer>& data) override;
24
+ std::shared_ptr<ArrayBuffer> final() override;
25
+ bool setAAD(const std::shared_ptr<ArrayBuffer>& data, std::optional<double> plaintextLength) override;
26
+ std::shared_ptr<ArrayBuffer> getAuthTag() override;
27
+ bool setAuthTag(const std::shared_ptr<ArrayBuffer>& tag) override;
28
+ bool setAutoPadding(bool autoPad) override;
29
+
30
+ private:
31
+ static constexpr size_t kKeySize = crypto_secretbox_xsalsa20poly1305_KEYBYTES;
32
+ static constexpr size_t kNonceSize = crypto_secretbox_xsalsa20poly1305_NONCEBYTES;
33
+ static constexpr size_t kTagSize = crypto_secretbox_xsalsa20poly1305_MACBYTES;
34
+
35
+ uint8_t key_[kKeySize];
36
+ uint8_t nonce_[kNonceSize];
37
+ std::vector<uint8_t> data_buffer_;
38
+ uint8_t auth_tag_[kTagSize];
39
+ bool final_called_;
40
+ };
41
+
42
+ } // namespace margelo::nitro::crypto
@@ -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(), &params) <= 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
@@ -433,6 +433,16 @@ const DH* HybridDiffieHellman::getDH() const {
433
433
  return dh;
434
434
  }
435
435
 
436
+ double HybridDiffieHellman::getVerifyError() {
437
+ ensureInitialized();
438
+ const DH* dh = getDH();
439
+ int codes = 0;
440
+ if (DH_check(const_cast<DH*>(dh), &codes) != 1) {
441
+ return 0;
442
+ }
443
+ return static_cast<double>(codes);
444
+ }
445
+
436
446
  #pragma clang diagnostic pop
437
447
 
438
448
  } // namespace margelo::nitro::crypto
@@ -30,6 +30,7 @@ class HybridDiffieHellman : public HybridDiffieHellmanSpec {
30
30
  std::shared_ptr<ArrayBuffer> getPrivateKey() override;
31
31
  void setPublicKey(const std::shared_ptr<ArrayBuffer>& publicKey) override;
32
32
  void setPrivateKey(const std::shared_ptr<ArrayBuffer>& privateKey) override;
33
+ double getVerifyError() override;
33
34
 
34
35
  private:
35
36
  EVP_PKEY_ptr _pkey;
@@ -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
@@ -0,0 +1,32 @@
1
+ #pragma once
2
+
3
+ #include <memory>
4
+ #include <openssl/evp.h>
5
+
6
+ #include "HybridDsaKeyPairSpec.hpp"
7
+ #include "QuickCryptoUtils.hpp"
8
+
9
+ namespace margelo::nitro::crypto {
10
+
11
+ class HybridDsaKeyPair : public HybridDsaKeyPairSpec {
12
+ public:
13
+ HybridDsaKeyPair() : HybridObject(TAG) {}
14
+ ~HybridDsaKeyPair() override = default;
15
+
16
+ public:
17
+ std::shared_ptr<Promise<void>> generateKeyPair() override;
18
+ void generateKeyPairSync() override;
19
+ void setModulusLength(double modulusLength) override;
20
+ void setDivisorLength(double divisorLength) override;
21
+ std::shared_ptr<ArrayBuffer> getPublicKey() override;
22
+ std::shared_ptr<ArrayBuffer> getPrivateKey() override;
23
+
24
+ private:
25
+ int modulusLength_ = 0;
26
+ int divisorLength_ = -1;
27
+
28
+ using EVP_PKEY_ptr = std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)>;
29
+ EVP_PKEY_ptr pkey_{nullptr, EVP_PKEY_free};
30
+ };
31
+
32
+ } // namespace margelo::nitro::crypto
@@ -1,5 +1,6 @@
1
1
  #include <NitroModules/ArrayBuffer.hpp>
2
2
  #include <NitroModules/Promise.hpp>
3
+ #include <algorithm>
3
4
  #include <memory>
4
5
  #include <openssl/bio.h>
5
6
  #include <openssl/buffer.h>
@@ -425,4 +426,24 @@ void HybridEcKeyPair::checkKeyPair() {
425
426
  }
426
427
  }
427
428
 
429
+ std::vector<std::string> HybridEcKeyPair::getSupportedCurves() {
430
+ const size_t count = EC_get_builtin_curves(nullptr, 0);
431
+ std::vector<EC_builtin_curve> curves(count);
432
+ if (EC_get_builtin_curves(curves.data(), count) != count) {
433
+ throw std::runtime_error("Failed to enumerate EC curves");
434
+ }
435
+
436
+ std::vector<std::string> names;
437
+ names.reserve(count);
438
+ for (const auto& curve : curves) {
439
+ const char* sn = OBJ_nid2sn(curve.nid);
440
+ if (sn != nullptr) {
441
+ names.emplace_back(sn);
442
+ }
443
+ }
444
+
445
+ std::sort(names.begin(), names.end());
446
+ return names;
447
+ }
448
+
428
449
  } // namespace margelo::nitro::crypto
@@ -34,6 +34,7 @@ class HybridEcKeyPair : public HybridEcKeyPairSpec {
34
34
  std::shared_ptr<ArrayBuffer> sign(const std::shared_ptr<ArrayBuffer>& data, const std::string& hashAlgorithm) override;
35
35
  bool verify(const std::shared_ptr<ArrayBuffer>& data, const std::shared_ptr<ArrayBuffer>& signature,
36
36
  const std::string& hashAlgorithm) override;
37
+ std::vector<std::string> getSupportedCurves() override;
37
38
 
38
39
  protected:
39
40
  void checkKeyPair();