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
@@ -1,5 +1,4 @@
1
1
  #include "ncrypto.h"
2
-
3
2
  #include <openssl/asn1.h>
4
3
  #include <openssl/bn.h>
5
4
  #include <openssl/dh.h>
@@ -11,25 +10,24 @@
11
10
 
12
11
  #ifndef NCRYPTO_NO_KDF_H
13
12
  #include <openssl/kdf.h>
14
- #else
13
+ #endif
14
+ #ifdef OPENSSL_IS_BORINGSSL
15
15
  #include <openssl/hkdf.h>
16
16
  #endif
17
17
 
18
+ #if OPENSSL_VERSION_NUMBER >= 0x30200000L
19
+ #include <openssl/thread.h>
20
+ #endif
21
+
18
22
  #include <algorithm>
19
23
  #include <array>
20
- #include <cctype>
21
- #include <climits>
22
24
  #include <cstring>
23
25
  #include <string_view>
24
26
  #include <vector>
25
-
26
27
  #if OPENSSL_VERSION_MAJOR >= 3
27
28
  #include <openssl/core_names.h>
28
29
  #include <openssl/params.h>
29
30
  #include <openssl/provider.h>
30
- #if OPENSSL_VERSION_NUMBER >= 0x30200000L
31
- #include <openssl/thread.h>
32
- #endif
33
31
  #endif
34
32
  #if OPENSSL_WITH_PQC
35
33
  struct PQCMapping {
@@ -71,8 +69,6 @@ constexpr static PQCMapping pqc_mappings[] = {
71
69
  nullptr)
72
70
  #endif
73
71
 
74
- // ============================================================================
75
-
76
72
  namespace ncrypto {
77
73
  namespace {
78
74
  using BignumCtxPointer = DeleteFnPtr<BN_CTX, BN_CTX_free>;
@@ -261,7 +257,7 @@ Buffer<void> DataPointer::release() {
261
257
  DataPointer DataPointer::resize(size_t len) {
262
258
  size_t actual_len = std::min(len_, len);
263
259
  auto buf = release();
264
- if (actual_len == len_) return DataPointer(buf);
260
+ if (actual_len == len_) return DataPointer(buf.data, actual_len);
265
261
  buf.data = OPENSSL_realloc(buf.data, actual_len);
266
262
  buf.len = actual_len;
267
263
  return DataPointer(buf);
@@ -354,12 +350,12 @@ BIGNUM* BignumPointer::release() {
354
350
  }
355
351
 
356
352
  size_t BignumPointer::byteLength() const {
357
- if (!bn_) return 0;
353
+ if (bn_ == nullptr) return 0;
358
354
  return BN_num_bytes(bn_.get());
359
355
  }
360
356
 
361
357
  size_t BignumPointer::bitLength() const {
362
- if (!bn_) return 0;
358
+ if (bn_ == nullptr) return 0;
363
359
  return BN_num_bits(bn_.get());
364
360
  }
365
361
 
@@ -635,9 +631,7 @@ int64_t PortableTimeGM(struct tm* t) {
635
631
  // ============================================================================
636
632
  // SPKAC
637
633
 
638
- namespace {
639
- bool VerifySpkacImpl(const char* input, size_t length) {
640
- ClearErrorOnReturn clearErrorOnReturn;
634
+ bool VerifySpkac(const char* input, size_t length) {
641
635
  #ifdef OPENSSL_IS_BORINGSSL
642
636
  // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters,
643
637
  // while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not.
@@ -655,11 +649,9 @@ bool VerifySpkacImpl(const char* input, size_t length) {
655
649
  return pkey ? NETSCAPE_SPKI_verify(spki.get(), pkey.get()) > 0 : false;
656
650
  }
657
651
 
658
- BIOPointer ExportPublicKeyImpl(const char* input, size_t length) {
659
- ClearErrorOnReturn clearErrorOnReturn;
660
- auto bio = BIOPointer::NewMem();
661
- if (!bio) [[unlikely]]
662
- return {};
652
+ BIOPointer ExportPublicKey(const char* input, size_t length) {
653
+ BIOPointer bio(BIO_new(BIO_s_mem()));
654
+ if (!bio) return {};
663
655
 
664
656
  #ifdef OPENSSL_IS_BORINGSSL
665
657
  // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters,
@@ -668,21 +660,17 @@ BIOPointer ExportPublicKeyImpl(const char* input, size_t length) {
668
660
  length = std::string_view(input, length).find_last_not_of(" \n\r\t") + 1;
669
661
  #endif
670
662
  NetscapeSPKIPointer spki(NETSCAPE_SPKI_b64_decode(input, length));
671
- if (!spki) [[unlikely]] {
672
- return {};
673
- }
663
+ if (!spki) return {};
674
664
 
675
665
  EVPKeyPointer pkey(NETSCAPE_SPKI_get_pubkey(spki.get()));
666
+ if (!pkey) return {};
676
667
 
677
- if (!pkey || PEM_write_bio_PUBKEY(bio.get(), pkey.get()) <= 0) [[unlikely]] {
678
- return {};
679
- }
668
+ if (PEM_write_bio_PUBKEY(bio.get(), pkey.get()) <= 0) return {};
680
669
 
681
670
  return bio;
682
671
  }
683
672
 
684
- DataPointer ExportChallengeImpl(const char* input, size_t length) {
685
- ClearErrorOnReturn clearErrorOnReturn;
673
+ Buffer<char> ExportChallenge(const char* input, size_t length) {
686
674
  #ifdef OPENSSL_IS_BORINGSSL
687
675
  // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters,
688
676
  // while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not.
@@ -695,43 +683,27 @@ DataPointer ExportChallengeImpl(const char* input, size_t length) {
695
683
  unsigned char* buf = nullptr;
696
684
  int buf_size = ASN1_STRING_to_UTF8(&buf, sp->spkac->challenge);
697
685
  if (buf_size >= 0) {
698
- return DataPointer({
686
+ return {
699
687
  .data = reinterpret_cast<char*>(buf),
700
688
  .len = static_cast<size_t>(buf_size),
701
- });
689
+ };
702
690
  }
703
691
 
704
692
  return {};
705
693
  }
706
- } // namespace
707
694
 
708
695
  bool VerifySpkac(const Buffer<const char>& input) {
709
- return VerifySpkacImpl(input.data, input.len);
696
+ return VerifySpkac(input.data, input.len);
710
697
  }
711
698
 
712
699
  BIOPointer ExportPublicKey(const Buffer<const char>& input) {
713
- return ExportPublicKeyImpl(input.data, input.len);
700
+ return ExportPublicKey(input.data, input.len);
714
701
  }
715
702
 
716
703
  DataPointer ExportChallenge(const Buffer<const char>& input) {
717
- return ExportChallengeImpl(input.data, input.len);
718
- }
719
-
720
- bool VerifySpkac(const char* input, size_t length) {
721
- return VerifySpkacImpl(input, length);
722
- }
723
-
724
- BIOPointer ExportPublicKey(const char* input, size_t length) {
725
- return ExportPublicKeyImpl(input, length);
726
- }
727
-
728
- Buffer<char> ExportChallenge(const char* input, size_t length) {
729
- if (auto dp = ExportChallengeImpl(input, length)) {
730
- auto released = dp.release();
731
- return Buffer<char>{
732
- .data = static_cast<char*>(released.data),
733
- .len = released.len,
734
- };
704
+ auto buf = ExportChallenge(input.data, input.len);
705
+ if (buf.data != nullptr) {
706
+ return DataPointer(buf.data, buf.len);
735
707
  }
736
708
  return {};
737
709
  }
@@ -1406,16 +1378,10 @@ bool X509View::enumUsages(UsageCallback callback) const {
1406
1378
 
1407
1379
  bool X509View::ifRsa(KeyCallback<Rsa> callback) const {
1408
1380
  if (cert_ == nullptr) return true;
1409
- // The const_cast is a bit unfortunate. The X509_get_pubkey API accepts
1410
- // a const X509* in newer versions of openssl and boringssl but a non-const
1411
- // X509* in older versions. By removing the const if it exists we can
1412
- // support both.
1413
- EVPKeyPointer pkey(X509_get_pubkey(const_cast<X509*>(cert_)));
1414
- if (!pkey) [[unlikely]]
1415
- return true;
1416
- auto id = pkey.id();
1381
+ OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_);
1382
+ auto id = EVP_PKEY_id(pkey);
1417
1383
  if (id == EVP_PKEY_RSA || id == EVP_PKEY_RSA2 || id == EVP_PKEY_RSA_PSS) {
1418
- Rsa rsa = pkey;
1384
+ Rsa rsa(EVP_PKEY_get0_RSA(pkey));
1419
1385
  if (!rsa) [[unlikely]]
1420
1386
  return true;
1421
1387
  return callback(rsa);
@@ -1425,16 +1391,10 @@ bool X509View::ifRsa(KeyCallback<Rsa> callback) const {
1425
1391
 
1426
1392
  bool X509View::ifEc(KeyCallback<Ec> callback) const {
1427
1393
  if (cert_ == nullptr) return true;
1428
- // The const_cast is a bit unfortunate. The X509_get_pubkey API accepts
1429
- // a const X509* in newer versions of openssl and boringssl but a non-const
1430
- // X509* in older versions. By removing the const if it exists we can
1431
- // support both.
1432
- EVPKeyPointer pkey(X509_get_pubkey(const_cast<X509*>(cert_)));
1433
- if (!pkey) [[unlikely]]
1434
- return true;
1435
- auto id = pkey.id();
1394
+ OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_);
1395
+ auto id = EVP_PKEY_id(pkey);
1436
1396
  if (id == EVP_PKEY_EC) {
1437
- Ec ec = pkey;
1397
+ Ec ec(EVP_PKEY_get0_EC_KEY(pkey));
1438
1398
  if (!ec) [[unlikely]]
1439
1399
  return true;
1440
1400
  return callback(ec);
@@ -1584,15 +1544,6 @@ int BIOPointer::Write(BIOPointer* bio, std::string_view message) {
1584
1544
  // ============================================================================
1585
1545
  // DHPointer
1586
1546
 
1587
- namespace {
1588
- bool EqualNoCase(const std::string_view a, const std::string_view b) {
1589
- if (a.size() != b.size()) return false;
1590
- return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](char a, char b) {
1591
- return std::tolower(a) == std::tolower(b);
1592
- });
1593
- }
1594
- } // namespace
1595
-
1596
1547
  DHPointer::DHPointer(DH* dh) : dh_(dh) {}
1597
1548
 
1598
1549
  DHPointer::DHPointer(DHPointer&& other) noexcept : dh_(other.release()) {}
@@ -1889,7 +1840,18 @@ bool hkdfInfo(const Digest& md,
1889
1840
  actual_salt = {default_salt, static_cast<unsigned>(md.size())};
1890
1841
  }
1891
1842
 
1892
- #ifndef NCRYPTO_NO_KDF_H
1843
+ #ifdef OPENSSL_IS_BORINGSSL
1844
+ if (out == nullptr || out->len != length) return false;
1845
+ return HKDF(out->data,
1846
+ length,
1847
+ md,
1848
+ key.data,
1849
+ key.len,
1850
+ reinterpret_cast<const unsigned char*>(actual_salt.data()),
1851
+ actual_salt.size(),
1852
+ info.data,
1853
+ info.len) == 1;
1854
+ #else
1893
1855
  auto ctx = EVPKeyCtxPointer::NewFromID(EVP_PKEY_HKDF);
1894
1856
  // OpenSSL < 3.0.0 accepted only a void* as the argument of
1895
1857
  // EVP_PKEY_CTX_set_hkdf_md.
@@ -1927,16 +1889,6 @@ bool hkdfInfo(const Digest& md,
1927
1889
  if (out == nullptr || out->len != length) return false;
1928
1890
 
1929
1891
  return EVP_PKEY_derive(ctx.get(), out->data, &length) > 0;
1930
- #else
1931
- return HKDF(out->data,
1932
- length,
1933
- md,
1934
- key.data,
1935
- key.len,
1936
- salt.data,
1937
- salt.len,
1938
- info.data,
1939
- info.len);
1940
1892
  #endif
1941
1893
  }
1942
1894
 
@@ -1947,10 +1899,14 @@ DataPointer hkdf(const Digest& md,
1947
1899
  size_t length) {
1948
1900
  auto buf = DataPointer::Alloc(length);
1949
1901
  if (!buf) return {};
1950
- Buffer<unsigned char> out = buf;
1951
-
1952
- return hkdfInfo(md, key, info, salt, length, &out) ? std::move(buf)
1953
- : DataPointer();
1902
+ Buffer<unsigned char> out{
1903
+ .data = static_cast<unsigned char*>(buf.get()),
1904
+ .len = length,
1905
+ };
1906
+ if (hkdfInfo(md, key, info, salt, length, &out)) {
1907
+ return buf;
1908
+ }
1909
+ return {};
1954
1910
  }
1955
1911
 
1956
1912
  bool checkScryptParams(uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem) {
@@ -1972,20 +1928,16 @@ bool scryptInto(const Buffer<const char>& pass,
1972
1928
  return false;
1973
1929
  }
1974
1930
 
1975
- if (auto dp = DataPointer::Alloc(length)) {
1976
- return EVP_PBE_scrypt(pass.data,
1977
- pass.len,
1978
- salt.data,
1979
- salt.len,
1980
- N,
1981
- r,
1982
- p,
1983
- maxmem,
1984
- out->data,
1985
- length);
1986
- }
1987
-
1988
- return false;
1931
+ return EVP_PBE_scrypt(pass.data,
1932
+ pass.len,
1933
+ salt.data,
1934
+ salt.len,
1935
+ N,
1936
+ r,
1937
+ p,
1938
+ maxmem,
1939
+ out->data,
1940
+ length) == 1;
1989
1941
  }
1990
1942
 
1991
1943
  DataPointer scrypt(const Buffer<const char>& pass,
@@ -1995,11 +1947,24 @@ DataPointer scrypt(const Buffer<const char>& pass,
1995
1947
  uint64_t p,
1996
1948
  uint64_t maxmem,
1997
1949
  size_t length) {
1998
- if (auto dp = DataPointer::Alloc(length)) {
1999
- Buffer<unsigned char> buf = dp;
2000
- if (scryptInto(pass, salt, N, r, p, maxmem, length, &buf)) {
2001
- return dp;
2002
- }
1950
+ ClearErrorOnReturn clearErrorOnReturn;
1951
+
1952
+ if (pass.len > INT_MAX || salt.len > INT_MAX) {
1953
+ return {};
1954
+ }
1955
+
1956
+ auto dp = DataPointer::Alloc(length);
1957
+ if (dp && EVP_PBE_scrypt(pass.data,
1958
+ pass.len,
1959
+ salt.data,
1960
+ salt.len,
1961
+ N,
1962
+ r,
1963
+ p,
1964
+ maxmem,
1965
+ reinterpret_cast<unsigned char*>(dp.get()),
1966
+ length)) {
1967
+ return dp;
2003
1968
  }
2004
1969
 
2005
1970
  return {};
@@ -2019,18 +1984,14 @@ bool pbkdf2Into(const Digest& md,
2019
1984
  }
2020
1985
 
2021
1986
  const EVP_MD* md_ptr = md;
2022
- if (PKCS5_PBKDF2_HMAC(pass.data,
2023
- pass.len,
2024
- salt.data,
2025
- salt.len,
2026
- iterations,
2027
- md_ptr,
2028
- length,
2029
- out->data)) {
2030
- return true;
2031
- }
2032
-
2033
- return false;
1987
+ return PKCS5_PBKDF2_HMAC(pass.data,
1988
+ pass.len,
1989
+ salt.data,
1990
+ salt.len,
1991
+ iterations,
1992
+ md_ptr,
1993
+ length,
1994
+ out->data) == 1;
2034
1995
  }
2035
1996
 
2036
1997
  DataPointer pbkdf2(const Digest& md,
@@ -2038,11 +1999,23 @@ DataPointer pbkdf2(const Digest& md,
2038
1999
  const Buffer<const unsigned char>& salt,
2039
2000
  uint32_t iterations,
2040
2001
  size_t length) {
2041
- if (auto dp = DataPointer::Alloc(length)) {
2042
- Buffer<unsigned char> buf = dp;
2043
- if (pbkdf2Into(md, pass, salt, iterations, length, &buf)) {
2044
- return dp;
2045
- }
2002
+ ClearErrorOnReturn clearErrorOnReturn;
2003
+
2004
+ if (pass.len > INT_MAX || salt.len > INT_MAX || length > INT_MAX) {
2005
+ return {};
2006
+ }
2007
+
2008
+ auto dp = DataPointer::Alloc(length);
2009
+ const EVP_MD* md_ptr = md;
2010
+ if (dp && PKCS5_PBKDF2_HMAC(pass.data,
2011
+ pass.len,
2012
+ salt.data,
2013
+ salt.len,
2014
+ iterations,
2015
+ md_ptr,
2016
+ length,
2017
+ reinterpret_cast<unsigned char*>(dp.get()))) {
2018
+ return dp;
2046
2019
  }
2047
2020
 
2048
2021
  return {};
@@ -2245,12 +2218,6 @@ EVPKeyPointer::EVPKeyPointer(EVP_PKEY* pkey) : pkey_(pkey) {}
2245
2218
  EVPKeyPointer::EVPKeyPointer(EVPKeyPointer&& other) noexcept
2246
2219
  : pkey_(other.release()) {}
2247
2220
 
2248
- EVPKeyPointer EVPKeyPointer::clone() const {
2249
- if (!pkey_) return {};
2250
- if (!EVP_PKEY_up_ref(pkey_.get())) return {};
2251
- return EVPKeyPointer(pkey_.get());
2252
- }
2253
-
2254
2221
  EVPKeyPointer& EVPKeyPointer::operator=(EVPKeyPointer&& other) noexcept {
2255
2222
  if (this == &other) return *this;
2256
2223
  this->~EVPKeyPointer();
@@ -2599,7 +2566,6 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePrivateKey(
2599
2566
  ERR_GET_REASON(err) == PEM_R_BAD_PASSWORD_READ && !had_passphrase) {
2600
2567
  return ParseKeyResult(PKParseError::NEED_PASSPHRASE);
2601
2568
  }
2602
-
2603
2569
  return ParseKeyResult(PKParseError::FAILED, err);
2604
2570
  }
2605
2571
  if (!pkey) return ParseKeyResult(PKParseError::FAILED);
@@ -2675,8 +2641,11 @@ Result<BIOPointer, bool> EVPKeyPointer::writePrivateKey(
2675
2641
  // PKCS1 is only permitted for RSA keys.
2676
2642
  if (id() != EVP_PKEY_RSA) return Result<BIOPointer, bool>(false);
2677
2643
 
2678
- OSSL3_CONST RSA* rsa = EVP_PKEY_get0_RSA(get());
2679
-
2644
+ #if OPENSSL_VERSION_MAJOR >= 3
2645
+ const RSA* rsa = EVP_PKEY_get0_RSA(get());
2646
+ #else
2647
+ RSA* rsa = EVP_PKEY_get0_RSA(get());
2648
+ #endif
2680
2649
  switch (config.format) {
2681
2650
  case PKFormatType::PEM: {
2682
2651
  err = PEM_write_bio_RSAPrivateKey(
@@ -2735,8 +2704,11 @@ Result<BIOPointer, bool> EVPKeyPointer::writePrivateKey(
2735
2704
  // SEC1 is only permitted for EC keys
2736
2705
  if (id() != EVP_PKEY_EC) return Result<BIOPointer, bool>(false);
2737
2706
 
2738
- OSSL3_CONST EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get());
2739
-
2707
+ #if OPENSSL_VERSION_MAJOR >= 3
2708
+ const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get());
2709
+ #else
2710
+ EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get());
2711
+ #endif
2740
2712
  switch (config.format) {
2741
2713
  case PKFormatType::PEM: {
2742
2714
  err = PEM_write_bio_ECPrivateKey(
@@ -2921,9 +2893,15 @@ EVPKeyPointer::operator Ec() const {
2921
2893
  return Ec(ec);
2922
2894
  }
2923
2895
 
2896
+ EVPKeyPointer EVPKeyPointer::clone() const {
2897
+ if (!pkey_) return {};
2898
+ if (!EVP_PKEY_up_ref(pkey_.get())) return {};
2899
+ return EVPKeyPointer(pkey_.get());
2900
+ }
2901
+
2924
2902
  bool EVPKeyPointer::validateDsaParameters() const {
2925
2903
  if (!pkey_) return false;
2926
- /* Validate DSA2 parameters from FIPS 186-4 */
2904
+ /* Validate DSA2 parameters from FIPS 186-4 */
2927
2905
  #if OPENSSL_VERSION_MAJOR >= 3
2928
2906
  if (EVP_default_properties_is_fips_enabled(nullptr) && EVP_PKEY_DSA == id()) {
2929
2907
  #else
@@ -3222,36 +3200,6 @@ bool SSLCtxPointer::setCipherSuites(const char* ciphers) {
3222
3200
  return true;
3223
3201
  #endif
3224
3202
  }
3225
- // ============================================================================
3226
-
3227
- template <typename T>
3228
- std::string_view ModeMixin<T>::getModeLabel() const {
3229
- switch (self().getMode()) {
3230
- case EVP_CIPH_CCM_MODE:
3231
- return "ccm";
3232
- case EVP_CIPH_CFB_MODE:
3233
- return "cfb";
3234
- case EVP_CIPH_CBC_MODE:
3235
- return "cbc";
3236
- case EVP_CIPH_CTR_MODE:
3237
- return "ctr";
3238
- case EVP_CIPH_ECB_MODE:
3239
- return "ecb";
3240
- case EVP_CIPH_GCM_MODE:
3241
- return "gcm";
3242
- case EVP_CIPH_OCB_MODE:
3243
- return "ocb";
3244
- case EVP_CIPH_OFB_MODE:
3245
- return "ofb";
3246
- case EVP_CIPH_WRAP_MODE:
3247
- return "wrap";
3248
- case EVP_CIPH_XTS_MODE:
3249
- return "xts";
3250
- case EVP_CIPH_STREAM_CIPHER:
3251
- return "stream";
3252
- }
3253
- return "{unknown}";
3254
- }
3255
3203
 
3256
3204
  // ============================================================================
3257
3205
 
@@ -3289,13 +3237,43 @@ const Cipher Cipher::AES_256_OCB = Cipher::FromNid(NID_aes_256_ocb);
3289
3237
 
3290
3238
  const Cipher Cipher::CHACHA20_POLY1305 = Cipher::FromNid(NID_chacha20_poly1305);
3291
3239
 
3240
+ bool Cipher::isGcmMode() const {
3241
+ if (!cipher_) return false;
3242
+ return getMode() == EVP_CIPH_GCM_MODE;
3243
+ }
3244
+
3245
+ bool Cipher::isWrapMode() const {
3246
+ if (!cipher_) return false;
3247
+ return getMode() == EVP_CIPH_WRAP_MODE;
3248
+ }
3249
+
3250
+ bool Cipher::isCtrMode() const {
3251
+ if (!cipher_) return false;
3252
+ return getMode() == EVP_CIPH_CTR_MODE;
3253
+ }
3254
+
3255
+ bool Cipher::isCcmMode() const {
3256
+ if (!cipher_) return false;
3257
+ return getMode() == EVP_CIPH_CCM_MODE;
3258
+ }
3259
+
3260
+ bool Cipher::isOcbMode() const {
3261
+ if (!cipher_) return false;
3262
+ return getMode() == EVP_CIPH_OCB_MODE;
3263
+ }
3264
+
3265
+ bool Cipher::isStreamMode() const {
3266
+ if (!cipher_) return false;
3267
+ return getMode() == EVP_CIPH_STREAM_CIPHER;
3268
+ }
3269
+
3292
3270
  bool Cipher::isChaCha20Poly1305() const {
3293
3271
  if (!cipher_) return false;
3294
3272
  return getNid() == NID_chacha20_poly1305;
3295
3273
  }
3296
3274
 
3297
3275
  int Cipher::getMode() const {
3298
- if (!cipher_) return -1;
3276
+ if (!cipher_) return 0;
3299
3277
  return EVP_CIPHER_mode(cipher_);
3300
3278
  }
3301
3279
 
@@ -3319,6 +3297,35 @@ int Cipher::getNid() const {
3319
3297
  return EVP_CIPHER_nid(cipher_);
3320
3298
  }
3321
3299
 
3300
+ std::string_view Cipher::getModeLabel() const {
3301
+ if (!cipher_) return {};
3302
+ switch (getMode()) {
3303
+ case EVP_CIPH_CCM_MODE:
3304
+ return "ccm";
3305
+ case EVP_CIPH_CFB_MODE:
3306
+ return "cfb";
3307
+ case EVP_CIPH_CBC_MODE:
3308
+ return "cbc";
3309
+ case EVP_CIPH_CTR_MODE:
3310
+ return "ctr";
3311
+ case EVP_CIPH_ECB_MODE:
3312
+ return "ecb";
3313
+ case EVP_CIPH_GCM_MODE:
3314
+ return "gcm";
3315
+ case EVP_CIPH_OCB_MODE:
3316
+ return "ocb";
3317
+ case EVP_CIPH_OFB_MODE:
3318
+ return "ofb";
3319
+ case EVP_CIPH_WRAP_MODE:
3320
+ return "wrap";
3321
+ case EVP_CIPH_XTS_MODE:
3322
+ return "xts";
3323
+ case EVP_CIPH_STREAM_CIPHER:
3324
+ return "stream";
3325
+ }
3326
+ return "{unknown}";
3327
+ }
3328
+
3322
3329
  const char* Cipher::getName() const {
3323
3330
  if (!cipher_) return {};
3324
3331
  // OBJ_nid2sn(EVP_CIPHER_nid(cipher)) is used here instead of
@@ -3349,76 +3356,6 @@ int Cipher::bytesToKey(const Digest& digest,
3349
3356
  *this, Digest::MD5, nullptr, input.data, input.len, 1, key, iv);
3350
3357
  }
3351
3358
 
3352
- template class ModeMixin<Cipher>;
3353
-
3354
- namespace {
3355
- struct CipherCallbackContext {
3356
- Cipher::CipherNameCallback cb;
3357
- void operator()(const char* name) { cb(name); }
3358
- };
3359
-
3360
- #if OPENSSL_VERSION_MAJOR >= 3
3361
- template <class TypeName,
3362
- TypeName* fetch_type(OSSL_LIB_CTX*, const char*, const char*),
3363
- void free_type(TypeName*),
3364
- const TypeName* getbyname(const char*),
3365
- const char* getname(const TypeName*)>
3366
- void array_push_back(const TypeName* evp_ref,
3367
- const char* from,
3368
- const char* to,
3369
- void* arg) {
3370
- if (from == nullptr) return;
3371
-
3372
- const TypeName* real_instance = getbyname(from);
3373
- if (!real_instance) return;
3374
-
3375
- const char* real_name = getname(real_instance);
3376
- if (!real_name) return;
3377
-
3378
- // EVP_*_fetch() does not support alias names, so we need to pass it the
3379
- // real/original algorithm name.
3380
- // We use EVP_*_fetch() as a filter here because it will only return an
3381
- // instance if the algorithm is supported by the public OpenSSL APIs (some
3382
- // algorithms are used internally by OpenSSL and are also passed to this
3383
- // callback).
3384
- TypeName* fetched = fetch_type(nullptr, real_name, nullptr);
3385
- if (fetched == nullptr) return;
3386
-
3387
- free_type(fetched);
3388
- auto& cb = *(static_cast<CipherCallbackContext*>(arg));
3389
- cb(from);
3390
- }
3391
- #else
3392
- template <class TypeName>
3393
- void array_push_back(const TypeName* evp_ref,
3394
- const char* from,
3395
- const char* to,
3396
- void* arg) {
3397
- if (!from) return;
3398
- auto& cb = *(static_cast<CipherCallbackContext*>(arg));
3399
- cb(from);
3400
- }
3401
- #endif
3402
- } // namespace
3403
-
3404
- void Cipher::ForEach(Cipher::CipherNameCallback callback) {
3405
- ClearErrorOnReturn clearErrorOnReturn;
3406
- CipherCallbackContext context;
3407
- context.cb = std::move(callback);
3408
-
3409
- EVP_CIPHER_do_all_sorted(
3410
- #if OPENSSL_VERSION_MAJOR >= 3
3411
- array_push_back<EVP_CIPHER,
3412
- EVP_CIPHER_fetch,
3413
- EVP_CIPHER_free,
3414
- EVP_get_cipherbyname,
3415
- EVP_CIPHER_get0_name>,
3416
- #else
3417
- array_push_back<EVP_CIPHER>,
3418
- #endif
3419
- &context);
3420
- }
3421
-
3422
3359
  // ============================================================================
3423
3360
 
3424
3361
  CipherCtxPointer CipherCtxPointer::New() {
@@ -3495,11 +3432,6 @@ int CipherCtxPointer::getMode() const {
3495
3432
  return EVP_CIPHER_CTX_mode(ctx_.get());
3496
3433
  }
3497
3434
 
3498
- int CipherCtxPointer::getNid() const {
3499
- if (!ctx_) return 0;
3500
- return EVP_CIPHER_CTX_nid(ctx_.get());
3501
- }
3502
-
3503
3435
  bool CipherCtxPointer::isGcmMode() const {
3504
3436
  if (!ctx_) return false;
3505
3437
  return getMode() == EVP_CIPH_GCM_MODE;
@@ -3525,6 +3457,11 @@ bool CipherCtxPointer::isChaCha20Poly1305() const {
3525
3457
  return getNid() == NID_chacha20_poly1305;
3526
3458
  }
3527
3459
 
3460
+ int CipherCtxPointer::getNid() const {
3461
+ if (!ctx_) return 0;
3462
+ return EVP_CIPHER_CTX_nid(ctx_.get());
3463
+ }
3464
+
3528
3465
  bool CipherCtxPointer::init(const Cipher& cipher,
3529
3466
  bool encrypt,
3530
3467
  const unsigned char* key,
@@ -4225,14 +4162,9 @@ const std::optional<Rsa::PssParams> Rsa::getPssParams() const {
4225
4162
  }
4226
4163
 
4227
4164
  if (params->saltLength != nullptr) {
4228
- // Older versions of openssl/boringssl do not implement
4229
- // ASN1_INTEGER_get_int64, which the salt length here technically
4230
- // is. Let's walk it through uint64_t with a conversion.
4231
- uint64_t temp;
4232
- if (ASN1_INTEGER_get_uint64(&temp, params->saltLength) != 1) {
4165
+ if (ASN1_INTEGER_get_int64(&ret.salt_length, params->saltLength) != 1) {
4233
4166
  return std::nullopt;
4234
4167
  }
4235
- ret.salt_length = static_cast<int64_t>(temp);
4236
4168
  }
4237
4169
  return ret;
4238
4170
  }
@@ -4317,6 +4249,74 @@ DataPointer Cipher::recover(const EVPKeyPointer& key,
4317
4249
  key, params, in);
4318
4250
  }
4319
4251
 
4252
+ namespace {
4253
+ struct CipherCallbackContext {
4254
+ Cipher::CipherNameCallback cb;
4255
+ void operator()(const char* name) { cb(name); }
4256
+ };
4257
+
4258
+ #if OPENSSL_VERSION_MAJOR >= 3
4259
+ template <class TypeName,
4260
+ TypeName* fetch_type(OSSL_LIB_CTX*, const char*, const char*),
4261
+ void free_type(TypeName*),
4262
+ const TypeName* getbyname(const char*),
4263
+ const char* getname(const TypeName*)>
4264
+ void array_push_back(const TypeName* evp_ref,
4265
+ const char* from,
4266
+ const char* to,
4267
+ void* arg) {
4268
+ if (from == nullptr) return;
4269
+
4270
+ const TypeName* real_instance = getbyname(from);
4271
+ if (!real_instance) return;
4272
+
4273
+ const char* real_name = getname(real_instance);
4274
+ if (!real_name) return;
4275
+
4276
+ // EVP_*_fetch() does not support alias names, so we need to pass it the
4277
+ // real/original algorithm name.
4278
+ // We use EVP_*_fetch() as a filter here because it will only return an
4279
+ // instance if the algorithm is supported by the public OpenSSL APIs (some
4280
+ // algorithms are used internally by OpenSSL and are also passed to this
4281
+ // callback).
4282
+ TypeName* fetched = fetch_type(nullptr, real_name, nullptr);
4283
+ if (fetched == nullptr) return;
4284
+
4285
+ free_type(fetched);
4286
+ auto& cb = *(static_cast<CipherCallbackContext*>(arg));
4287
+ cb(from);
4288
+ }
4289
+ #else
4290
+ template <class TypeName>
4291
+ void array_push_back(const TypeName* evp_ref,
4292
+ const char* from,
4293
+ const char* to,
4294
+ void* arg) {
4295
+ if (!from) return;
4296
+ auto& cb = *(static_cast<CipherCallbackContext*>(arg));
4297
+ cb(from);
4298
+ }
4299
+ #endif
4300
+ } // namespace
4301
+
4302
+ void Cipher::ForEach(Cipher::CipherNameCallback callback) {
4303
+ ClearErrorOnReturn clearErrorOnReturn;
4304
+ CipherCallbackContext context;
4305
+ context.cb = std::move(callback);
4306
+
4307
+ EVP_CIPHER_do_all_sorted(
4308
+ #if OPENSSL_VERSION_MAJOR >= 3
4309
+ array_push_back<EVP_CIPHER,
4310
+ EVP_CIPHER_fetch,
4311
+ EVP_CIPHER_free,
4312
+ EVP_get_cipherbyname,
4313
+ EVP_CIPHER_get0_name>,
4314
+ #else
4315
+ array_push_back<EVP_CIPHER>,
4316
+ #endif
4317
+ &context);
4318
+ }
4319
+
4320
4320
  // ============================================================================
4321
4321
 
4322
4322
  Ec::Ec() : ec_(nullptr) {}
@@ -4338,6 +4338,22 @@ int Ec::getCurve() const {
4338
4338
  return EC_GROUP_get_curve_name(getGroup());
4339
4339
  }
4340
4340
 
4341
+ uint32_t Ec::getDegree() const {
4342
+ return EC_GROUP_get_degree(getGroup());
4343
+ }
4344
+
4345
+ std::string Ec::getCurveName() const {
4346
+ return std::string(OBJ_nid2sn(getCurve()));
4347
+ }
4348
+
4349
+ const EC_POINT* Ec::getPublicKey() const {
4350
+ return EC_KEY_get0_public_key(ec_);
4351
+ }
4352
+
4353
+ const BIGNUM* Ec::getPrivateKey() const {
4354
+ return EC_KEY_get0_private_key(ec_);
4355
+ }
4356
+
4341
4357
  int Ec::GetCurveIdFromName(const char* name) {
4342
4358
  int nid = EC_curve_nist2nid(name);
4343
4359
  if (nid == NID_undef) {
@@ -4358,22 +4374,6 @@ bool Ec::GetCurves(Ec::GetCurveCallback callback) {
4358
4374
  return true;
4359
4375
  }
4360
4376
 
4361
- uint32_t Ec::getDegree() const {
4362
- return EC_GROUP_get_degree(getGroup());
4363
- }
4364
-
4365
- std::string Ec::getCurveName() const {
4366
- return std::string(OBJ_nid2sn(getCurve()));
4367
- }
4368
-
4369
- const EC_POINT* Ec::getPublicKey() const {
4370
- return EC_KEY_get0_public_key(ec_);
4371
- }
4372
-
4373
- const BIGNUM* Ec::getPrivateKey() const {
4374
- return EC_KEY_get0_private_key(ec_);
4375
- }
4376
-
4377
4377
  // ============================================================================
4378
4378
 
4379
4379
  EVPMDCtxPointer::EVPMDCtxPointer() : ctx_(nullptr) {}
@@ -4836,9 +4836,10 @@ std::pair<std::string, std::string> X509Name::Iterator::operator*() const {
4836
4836
  unsigned char* value_str;
4837
4837
  int value_str_size = ASN1_STRING_to_UTF8(&value_str, value);
4838
4838
 
4839
- return {
4840
- std::move(name_str),
4841
- std::string(reinterpret_cast<const char*>(value_str), value_str_size)};
4839
+ std::string out(reinterpret_cast<const char*>(value_str), value_str_size);
4840
+ OPENSSL_free(value_str); // free after copy
4841
+
4842
+ return {std::move(name_str), std::move(out)};
4842
4843
  }
4843
4844
 
4844
4845
  // ============================================================================
@@ -5009,289 +5010,6 @@ DataPointer KEM::Decapsulate(const EVPKeyPointer& private_key,
5009
5010
 
5010
5011
  #endif // OPENSSL_VERSION_MAJOR >= 3
5011
5012
 
5012
- // ============================================================================
5013
- // AEAD (Authenticated Encryption with Associated Data)
5014
- #ifdef OPENSSL_IS_BORINGSSL
5015
-
5016
- const Aead Aead::FromName(std::string_view name) {
5017
- for (const auto& [construct, info] : aeadIndex) {
5018
- if (EqualNoCase(info.name, name)) {
5019
- return Aead(&info, construct());
5020
- }
5021
- }
5022
-
5023
- return Aead();
5024
- }
5025
-
5026
- const Aead Aead::FromCtx(std::string_view name, const AeadCtxPointer& ctx) {
5027
- for (const auto& [_, info] : aeadIndex) {
5028
- if (info.name == name) {
5029
- return Aead(&info, EVP_AEAD_CTX_aead(ctx.get()));
5030
- }
5031
- }
5032
-
5033
- return Aead();
5034
- }
5035
-
5036
- int Aead::getMode() const {
5037
- if (!aead_) return -1;
5038
-
5039
- return info_->mode;
5040
- }
5041
-
5042
- int Aead::getNonceLength() const {
5043
- if (!aead_) return 0;
5044
- return EVP_AEAD_nonce_length(aead_);
5045
- }
5046
-
5047
- int Aead::getKeyLength() const {
5048
- if (!aead_) return 0;
5049
- return EVP_AEAD_key_length(aead_);
5050
- }
5051
-
5052
- int Aead::getMaxOverhead() const {
5053
- if (!aead_) return 0;
5054
- return EVP_AEAD_max_overhead(aead_);
5055
- }
5056
-
5057
- int Aead::getMaxTagLength() const {
5058
- if (!aead_) return 0;
5059
- return EVP_AEAD_max_tag_len(aead_);
5060
- }
5061
-
5062
- int Aead::getBlockSize() const {
5063
- if (!aead_) return 0;
5064
-
5065
- // EVP_CIPHER_CTX_block_size returns the block size, in bytes, of the cipher
5066
- // underlying |ctx|, or one if the cipher is a stream cipher.
5067
- return 1;
5068
- }
5069
-
5070
- std::string_view Aead::getName() const {
5071
- if (!aead_) return "";
5072
-
5073
- return info_->name;
5074
- }
5075
-
5076
- int Aead::getNid() const {
5077
- if (!aead_) return 0;
5078
-
5079
- return info_->nid;
5080
- }
5081
-
5082
- const Aead Aead::FromConstructor(Aead::AeadConstructor construct) {
5083
- return Aead(&aeadIndex.at(construct), construct());
5084
- }
5085
-
5086
- const std::unordered_map<Aead::AeadConstructor, Aead::AeadInfo>
5087
- Aead::aeadIndex = {
5088
- {EVP_aead_aes_128_gcm,
5089
- {.name = LN_aes_128_gcm,
5090
- .mode = EVP_CIPH_GCM_MODE,
5091
- .nid = NID_aes_128_gcm}},
5092
- {EVP_aead_aes_192_gcm,
5093
- {.name = LN_aes_192_gcm,
5094
- .mode = EVP_CIPH_GCM_MODE,
5095
- .nid = NID_aes_192_gcm}},
5096
- {EVP_aead_aes_256_gcm,
5097
- {.name = LN_aes_256_gcm,
5098
- .mode = EVP_CIPH_GCM_MODE,
5099
- .nid = NID_aes_256_gcm}},
5100
- {EVP_aead_chacha20_poly1305,
5101
- {.name = LN_chacha20_poly1305,
5102
- .mode = EVP_CIPH_STREAM_CIPHER,
5103
- .nid = NID_chacha20_poly1305}},
5104
- {EVP_aead_xchacha20_poly1305,
5105
- {
5106
- .name = "xchacha20-poly1305",
5107
- .mode = EVP_CIPH_STREAM_CIPHER,
5108
- }},
5109
- {EVP_aead_aes_128_ctr_hmac_sha256,
5110
- {
5111
- .name = "aes-128-ctr-hmac-sha256",
5112
- .mode = EVP_CIPH_CTR_MODE,
5113
- }},
5114
- {EVP_aead_aes_256_ctr_hmac_sha256,
5115
- {
5116
- .name = "aes-256-ctr-hmac-sha256",
5117
- .mode = EVP_CIPH_CTR_MODE,
5118
- }},
5119
- {EVP_aead_aes_128_gcm_siv,
5120
- {
5121
- .name = "aes-128-gcm-siv",
5122
- .mode = EVP_CIPH_GCM_MODE,
5123
- }},
5124
- {EVP_aead_aes_256_gcm_siv,
5125
- {
5126
- .name = "aes-256-gcm-siv",
5127
- .mode = EVP_CIPH_GCM_MODE,
5128
- }},
5129
- {EVP_aead_aes_128_gcm_randnonce,
5130
- {
5131
- .name = "aes-128-gcm-randnonce",
5132
- .mode = EVP_CIPH_GCM_MODE,
5133
- }},
5134
- {EVP_aead_aes_256_gcm_randnonce,
5135
- {
5136
- .name = "aes-256-gcm-randnonce",
5137
- .mode = EVP_CIPH_GCM_MODE,
5138
- }},
5139
- {EVP_aead_aes_128_ccm_bluetooth,
5140
- {
5141
- .name = "aes-128-ccm-bluetooth",
5142
- .mode = EVP_CIPH_CCM_MODE,
5143
- }},
5144
- {EVP_aead_aes_128_ccm_bluetooth_8,
5145
- {
5146
- .name = "aes-128-ccm-bluetooth-8",
5147
- .mode = EVP_CIPH_CCM_MODE,
5148
- }},
5149
- {EVP_aead_aes_128_ccm_matter,
5150
- {
5151
- .name = "aes-128-ccm-matter",
5152
- .mode = EVP_CIPH_CCM_MODE,
5153
- }},
5154
- {EVP_aead_aes_128_eax,
5155
- {.name = "aes-128-eax",
5156
- // BoringSSL does not define a mode constant for EAX. Using STREAM
5157
- // arbitrarily
5158
- .mode = EVP_CIPH_STREAM_CIPHER}},
5159
- {EVP_aead_aes_256_eax,
5160
- {.name = "aes-256-eax",
5161
- // BoringSSL does not define a mode constant for EAX. Using STREAM
5162
- // arbitrarily
5163
- .mode = EVP_CIPH_STREAM_CIPHER}},
5164
- };
5165
-
5166
- void Aead::ForEach(AeadNameCallback callback) {
5167
- for (const auto& [_, info] : aeadIndex) {
5168
- callback(info.name);
5169
- }
5170
- }
5171
-
5172
- const Aead Aead::EMPTY = Aead();
5173
- const Aead Aead::AES_128_GCM = Aead::FromConstructor(EVP_aead_aes_128_gcm);
5174
- const Aead Aead::AES_192_GCM = Aead::FromConstructor(EVP_aead_aes_192_gcm);
5175
- const Aead Aead::AES_256_GCM = Aead::FromConstructor(EVP_aead_aes_256_gcm);
5176
- const Aead Aead::CHACHA20_POLY1305 =
5177
- Aead::FromConstructor(EVP_aead_chacha20_poly1305);
5178
- const Aead Aead::XCHACHA20_POLY1305 =
5179
- Aead::FromConstructor(EVP_aead_xchacha20_poly1305);
5180
- const Aead Aead::AES_128_CTR_HMAC_SHA256 =
5181
- Aead::FromConstructor(EVP_aead_aes_128_ctr_hmac_sha256);
5182
- const Aead Aead::AES_256_CTR_HMAC_SHA256 =
5183
- Aead::FromConstructor(EVP_aead_aes_256_ctr_hmac_sha256);
5184
- const Aead Aead::AES_128_GCM_SIV =
5185
- Aead::FromConstructor(EVP_aead_aes_128_gcm_siv);
5186
- const Aead Aead::AES_256_GCM_SIV =
5187
- Aead::FromConstructor(EVP_aead_aes_256_gcm_siv);
5188
- const Aead Aead::AES_128_GCM_RANDNONCE =
5189
- Aead::FromConstructor(EVP_aead_aes_128_gcm_randnonce);
5190
- const Aead Aead::AES_256_GCM_RANDNONCE =
5191
- Aead::FromConstructor(EVP_aead_aes_256_gcm_randnonce);
5192
- const Aead Aead::AES_128_CCM_BLUETOOTH =
5193
- Aead::FromConstructor(EVP_aead_aes_128_ccm_bluetooth);
5194
- const Aead Aead::AES_128_CCM_BLUETOOTH_8 =
5195
- Aead::FromConstructor(EVP_aead_aes_128_ccm_bluetooth_8);
5196
- const Aead Aead::AES_128_CCM_MATTER =
5197
- Aead::FromConstructor(EVP_aead_aes_128_ccm_matter);
5198
- const Aead Aead::AES_128_EAX = Aead::FromConstructor(EVP_aead_aes_128_eax);
5199
- const Aead Aead::AES_256_EAX = Aead::FromConstructor(EVP_aead_aes_256_eax);
5200
-
5201
- template class ModeMixin<Aead>;
5202
-
5203
- AeadCtxPointer AeadCtxPointer::New(const Aead& aead,
5204
- bool encrypt,
5205
- const unsigned char* key,
5206
- size_t keyLen,
5207
- size_t tagLen) {
5208
- // Note: In the EVP_AEAD API new always calls init
5209
- auto ret = AeadCtxPointer(EVP_AEAD_CTX_new(aead.get(), key, keyLen, tagLen));
5210
-
5211
- if (!ret) {
5212
- return {};
5213
- }
5214
-
5215
- return ret;
5216
- }
5217
-
5218
- AeadCtxPointer::AeadCtxPointer(EVP_AEAD_CTX* ctx) : ctx_(ctx) {}
5219
-
5220
- AeadCtxPointer::AeadCtxPointer(AeadCtxPointer&& other) noexcept
5221
- : ctx_(other.release()) {}
5222
-
5223
- AeadCtxPointer& AeadCtxPointer::operator=(AeadCtxPointer&& other) noexcept {
5224
- if (this == &other) return *this;
5225
- this->~AeadCtxPointer();
5226
- return *new (this) AeadCtxPointer(std::move(other));
5227
- }
5228
-
5229
- AeadCtxPointer::~AeadCtxPointer() {
5230
- reset();
5231
- }
5232
-
5233
- void AeadCtxPointer::reset(EVP_AEAD_CTX* ctx) {
5234
- ctx_.reset(ctx);
5235
- }
5236
-
5237
- EVP_AEAD_CTX* AeadCtxPointer::release() {
5238
- return ctx_.release();
5239
- }
5240
-
5241
- bool AeadCtxPointer::init(const Aead& aead,
5242
- bool encrypt,
5243
- const unsigned char* key,
5244
- size_t keyLen,
5245
- size_t tagLen) {
5246
- return EVP_AEAD_CTX_init_with_direction(
5247
- ctx_.get(),
5248
- aead,
5249
- key,
5250
- keyLen,
5251
- tagLen,
5252
- encrypt ? evp_aead_seal : evp_aead_open);
5253
- }
5254
-
5255
- bool AeadCtxPointer::encrypt(const Buffer<const unsigned char>& in,
5256
- Buffer<unsigned char>& out,
5257
- Buffer<unsigned char>& tag,
5258
- const Buffer<const unsigned char>& nonce,
5259
- const Buffer<const unsigned char>& aad) {
5260
- if (!ctx_) return false;
5261
- return EVP_AEAD_CTX_seal_scatter(ctx_.get(),
5262
- out.data,
5263
- tag.data,
5264
- &tag.len,
5265
- tag.len,
5266
- nonce.data,
5267
- nonce.len,
5268
- in.data,
5269
- in.len,
5270
- nullptr /* extra_in */,
5271
- 0 /* extra_in_len */,
5272
- aad.data,
5273
- aad.len) == 1;
5274
- }
5275
-
5276
- bool AeadCtxPointer::decrypt(const Buffer<const unsigned char>& in,
5277
- Buffer<unsigned char>& out,
5278
- const Buffer<const unsigned char>& tag,
5279
- const Buffer<const unsigned char>& nonce,
5280
- const Buffer<const unsigned char>& aad) {
5281
- if (!ctx_) return false;
5282
-
5283
- return EVP_AEAD_CTX_open_gather(ctx_.get(),
5284
- out.data,
5285
- nonce.data,
5286
- nonce.len,
5287
- in.data,
5288
- in.len,
5289
- tag.data,
5290
- tag.len,
5291
- aad.data,
5292
- aad.len) == 1;
5293
- }
5294
- #endif
5295
5013
  } // namespace ncrypto
5296
5014
 
5297
5015
  // ===========================================================================