react-native-quick-crypto 1.0.0-beta.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/QuickCrypto.podspec +145 -6
- package/README.md +14 -27
- package/android/CMakeLists.txt +62 -7
- package/android/build.gradle +12 -2
- package/android/src/main/java/com/margelo/nitro/quickcrypto/QuickCryptoPackage.java +0 -2
- package/app.plugin.js +3 -0
- package/cpp/blake3/HybridBlake3.cpp +118 -0
- package/cpp/blake3/HybridBlake3.hpp +35 -0
- package/cpp/cipher/CCMCipher.cpp +199 -0
- package/cpp/cipher/CCMCipher.hpp +26 -0
- package/cpp/cipher/ChaCha20Cipher.cpp +97 -0
- package/cpp/cipher/ChaCha20Cipher.hpp +25 -0
- package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +170 -0
- package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +30 -0
- package/cpp/cipher/GCMCipher.cpp +68 -0
- package/cpp/cipher/GCMCipher.hpp +14 -0
- package/cpp/cipher/HybridCipher.cpp +322 -0
- package/cpp/cipher/HybridCipher.hpp +68 -0
- package/cpp/cipher/HybridCipherFactory.hpp +105 -0
- package/cpp/cipher/HybridRsaCipher.cpp +348 -0
- package/cpp/cipher/HybridRsaCipher.hpp +29 -0
- package/cpp/cipher/OCBCipher.cpp +55 -0
- package/cpp/cipher/OCBCipher.hpp +19 -0
- package/cpp/cipher/XSalsa20Cipher.cpp +61 -0
- package/cpp/cipher/XSalsa20Cipher.hpp +33 -0
- package/cpp/ec/HybridEcKeyPair.cpp +428 -0
- package/cpp/ec/HybridEcKeyPair.hpp +48 -0
- package/cpp/ed25519/HybridEdKeyPair.cpp +228 -98
- package/cpp/ed25519/HybridEdKeyPair.hpp +42 -56
- package/cpp/hash/HybridHash.cpp +185 -0
- package/cpp/hash/HybridHash.hpp +43 -0
- package/cpp/hmac/HybridHmac.cpp +95 -0
- package/cpp/hmac/HybridHmac.hpp +31 -0
- package/cpp/keys/HybridKeyObjectHandle.cpp +749 -0
- package/cpp/keys/HybridKeyObjectHandle.hpp +51 -0
- package/cpp/keys/KeyObjectData.cpp +268 -0
- package/cpp/keys/KeyObjectData.hpp +71 -0
- package/cpp/keys/node.h +5 -0
- package/cpp/pbkdf2/HybridPbkdf2.cpp +34 -55
- package/cpp/pbkdf2/HybridPbkdf2.hpp +5 -16
- package/cpp/random/HybridRandom.cpp +6 -17
- package/cpp/random/HybridRandom.hpp +5 -6
- package/cpp/rsa/HybridRsaKeyPair.cpp +154 -0
- package/cpp/rsa/HybridRsaKeyPair.hpp +43 -0
- package/cpp/sign/HybridSignHandle.cpp +191 -0
- package/cpp/sign/HybridSignHandle.hpp +36 -0
- package/cpp/sign/HybridVerifyHandle.cpp +158 -0
- package/cpp/sign/HybridVerifyHandle.hpp +36 -0
- package/cpp/sign/SignUtils.hpp +108 -0
- package/cpp/utils/Macros.hpp +68 -0
- package/cpp/utils/Utils.hpp +43 -2
- package/cpp/utils/base64.h +309 -0
- package/deps/blake3/.cargo/config.toml +2 -0
- package/deps/blake3/.git-blame-ignore-revs +2 -0
- package/deps/blake3/.github/workflows/build_b3sum.py +38 -0
- package/deps/blake3/.github/workflows/ci.yml +491 -0
- package/deps/blake3/.github/workflows/tag.yml +43 -0
- package/deps/blake3/.github/workflows/upload_github_release_asset.py +73 -0
- package/deps/blake3/CONTRIBUTING.md +31 -0
- package/deps/blake3/Cargo.toml +135 -0
- package/deps/blake3/LICENSE_A2 +202 -0
- package/deps/blake3/LICENSE_A2LLVM +219 -0
- package/deps/blake3/LICENSE_CC0 +121 -0
- package/deps/blake3/README.md +229 -0
- package/deps/blake3/b3sum/Cargo.lock +513 -0
- package/deps/blake3/b3sum/Cargo.toml +26 -0
- package/deps/blake3/b3sum/README.md +72 -0
- package/deps/blake3/b3sum/src/main.rs +564 -0
- package/deps/blake3/b3sum/src/unit_tests.rs +235 -0
- package/deps/blake3/b3sum/tests/cli_tests.rs +680 -0
- package/deps/blake3/b3sum/what_does_check_do.md +176 -0
- package/deps/blake3/benches/bench.rs +623 -0
- package/deps/blake3/build.rs +389 -0
- package/deps/blake3/c/CMakeLists.txt +383 -0
- package/deps/blake3/c/CMakePresets.json +73 -0
- package/deps/blake3/c/Makefile.testing +82 -0
- package/deps/blake3/c/README.md +403 -0
- package/deps/blake3/c/blake3-config.cmake.in +14 -0
- package/deps/blake3/c/blake3.c +650 -0
- package/deps/blake3/c/blake3.h +86 -0
- package/deps/blake3/c/blake3_avx2.c +326 -0
- package/deps/blake3/c/blake3_avx2_x86-64_unix.S +1815 -0
- package/deps/blake3/c/blake3_avx2_x86-64_windows_gnu.S +1817 -0
- package/deps/blake3/c/blake3_avx2_x86-64_windows_msvc.asm +1828 -0
- package/deps/blake3/c/blake3_avx512.c +1388 -0
- package/deps/blake3/c/blake3_avx512_x86-64_unix.S +4824 -0
- package/deps/blake3/c/blake3_avx512_x86-64_windows_gnu.S +2615 -0
- package/deps/blake3/c/blake3_avx512_x86-64_windows_msvc.asm +2634 -0
- package/deps/blake3/c/blake3_c_rust_bindings/Cargo.toml +32 -0
- package/deps/blake3/c/blake3_c_rust_bindings/README.md +4 -0
- package/deps/blake3/c/blake3_c_rust_bindings/benches/bench.rs +477 -0
- package/deps/blake3/c/blake3_c_rust_bindings/build.rs +253 -0
- package/deps/blake3/c/blake3_c_rust_bindings/cross_test.sh +31 -0
- package/deps/blake3/c/blake3_c_rust_bindings/src/lib.rs +333 -0
- package/deps/blake3/c/blake3_c_rust_bindings/src/test.rs +696 -0
- package/deps/blake3/c/blake3_dispatch.c +332 -0
- package/deps/blake3/c/blake3_impl.h +333 -0
- package/deps/blake3/c/blake3_neon.c +366 -0
- package/deps/blake3/c/blake3_portable.c +160 -0
- package/deps/blake3/c/blake3_sse2.c +566 -0
- package/deps/blake3/c/blake3_sse2_x86-64_unix.S +2291 -0
- package/deps/blake3/c/blake3_sse2_x86-64_windows_gnu.S +2332 -0
- package/deps/blake3/c/blake3_sse2_x86-64_windows_msvc.asm +2350 -0
- package/deps/blake3/c/blake3_sse41.c +560 -0
- package/deps/blake3/c/blake3_sse41_x86-64_unix.S +2028 -0
- package/deps/blake3/c/blake3_sse41_x86-64_windows_gnu.S +2069 -0
- package/deps/blake3/c/blake3_sse41_x86-64_windows_msvc.asm +2089 -0
- package/deps/blake3/c/blake3_tbb.cpp +37 -0
- package/deps/blake3/c/dependencies/CMakeLists.txt +3 -0
- package/deps/blake3/c/dependencies/tbb/CMakeLists.txt +28 -0
- package/deps/blake3/c/example.c +36 -0
- package/deps/blake3/c/example_tbb.c +57 -0
- package/deps/blake3/c/libblake3.pc.in +12 -0
- package/deps/blake3/c/main.c +166 -0
- package/deps/blake3/c/test.py +97 -0
- package/deps/blake3/media/B3.svg +70 -0
- package/deps/blake3/media/BLAKE3.svg +85 -0
- package/deps/blake3/media/speed.svg +1474 -0
- package/deps/blake3/reference_impl/Cargo.toml +8 -0
- package/deps/blake3/reference_impl/README.md +14 -0
- package/deps/blake3/reference_impl/reference_impl.rs +374 -0
- package/deps/blake3/src/ffi_avx2.rs +65 -0
- package/deps/blake3/src/ffi_avx512.rs +169 -0
- package/deps/blake3/src/ffi_neon.rs +82 -0
- package/deps/blake3/src/ffi_sse2.rs +126 -0
- package/deps/blake3/src/ffi_sse41.rs +126 -0
- package/deps/blake3/src/guts.rs +60 -0
- package/deps/blake3/src/hazmat.rs +704 -0
- package/deps/blake3/src/io.rs +64 -0
- package/deps/blake3/src/join.rs +92 -0
- package/deps/blake3/src/lib.rs +1835 -0
- package/deps/blake3/src/platform.rs +587 -0
- package/deps/blake3/src/portable.rs +198 -0
- package/deps/blake3/src/rust_avx2.rs +474 -0
- package/deps/blake3/src/rust_sse2.rs +775 -0
- package/deps/blake3/src/rust_sse41.rs +766 -0
- package/deps/blake3/src/test.rs +1049 -0
- package/deps/blake3/src/traits.rs +227 -0
- package/deps/blake3/src/wasm32_simd.rs +794 -0
- package/deps/blake3/test_vectors/Cargo.toml +19 -0
- package/deps/blake3/test_vectors/cross_test.sh +25 -0
- package/deps/blake3/test_vectors/src/bin/generate.rs +4 -0
- package/deps/blake3/test_vectors/src/lib.rs +350 -0
- package/deps/blake3/test_vectors/test_vectors.json +217 -0
- package/deps/blake3/tools/compiler_version/Cargo.toml +7 -0
- package/deps/blake3/tools/compiler_version/build.rs +6 -0
- package/deps/blake3/tools/compiler_version/src/main.rs +27 -0
- package/deps/blake3/tools/instruction_set_support/Cargo.toml +6 -0
- package/deps/blake3/tools/instruction_set_support/src/main.rs +10 -0
- package/deps/blake3/tools/release.md +16 -0
- package/deps/fastpbkdf2/fastpbkdf2.c +5 -1
- package/deps/ncrypto/ncrypto.cc +4679 -0
- package/deps/ncrypto/ncrypto.h +1625 -0
- package/lib/commonjs/blake3.js +98 -0
- package/lib/commonjs/blake3.js.map +1 -0
- package/lib/commonjs/cipher.js +180 -0
- package/lib/commonjs/cipher.js.map +1 -0
- package/lib/commonjs/constants.js +32 -0
- package/lib/commonjs/constants.js.map +1 -0
- package/lib/commonjs/ec.js +480 -0
- package/lib/commonjs/ec.js.map +1 -0
- package/lib/commonjs/ed.js +214 -2
- package/lib/commonjs/ed.js.map +1 -1
- package/lib/commonjs/expo-plugin/@types.js +2 -0
- package/lib/commonjs/expo-plugin/@types.js.map +1 -0
- package/lib/commonjs/expo-plugin/withRNQC.js +25 -0
- package/lib/commonjs/expo-plugin/withRNQC.js.map +1 -0
- package/lib/commonjs/expo-plugin/withSodiumAndroid.js +25 -0
- package/lib/commonjs/expo-plugin/withSodiumAndroid.js.map +1 -0
- package/lib/commonjs/expo-plugin/withSodiumIos.js +26 -0
- package/lib/commonjs/expo-plugin/withSodiumIos.js.map +1 -0
- package/lib/commonjs/expo-plugin/withXCode.js +51 -0
- package/lib/commonjs/expo-plugin/withXCode.js.map +1 -0
- package/lib/commonjs/hash.js +215 -0
- package/lib/commonjs/hash.js.map +1 -0
- package/lib/commonjs/hmac.js +109 -0
- package/lib/commonjs/hmac.js.map +1 -0
- package/lib/commonjs/index.js +102 -24
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/keys/classes.js +109 -52
- package/lib/commonjs/keys/classes.js.map +1 -1
- package/lib/commonjs/keys/generateKeyPair.js +141 -144
- package/lib/commonjs/keys/generateKeyPair.js.map +1 -1
- package/lib/commonjs/keys/index.js +229 -0
- package/lib/commonjs/keys/index.js.map +1 -1
- package/lib/commonjs/keys/publicCipher.js +152 -0
- package/lib/commonjs/keys/publicCipher.js.map +1 -0
- package/lib/commonjs/keys/signVerify.js +178 -39
- package/lib/commonjs/keys/signVerify.js.map +1 -1
- package/lib/commonjs/keys/utils.js +18 -13
- package/lib/commonjs/keys/utils.js.map +1 -1
- package/lib/commonjs/pbkdf2.js.map +1 -1
- package/lib/commonjs/random.js +6 -0
- package/lib/commonjs/random.js.map +1 -1
- package/lib/commonjs/rsa.js +202 -0
- package/lib/commonjs/rsa.js.map +1 -0
- package/lib/commonjs/specs/blake3.nitro.js +6 -0
- package/lib/commonjs/specs/blake3.nitro.js.map +1 -0
- package/lib/commonjs/specs/cipher.nitro.js +6 -0
- package/lib/commonjs/specs/cipher.nitro.js.map +1 -0
- package/lib/commonjs/specs/ecKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/ecKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/hash.nitro.js +6 -0
- package/lib/commonjs/specs/hash.nitro.js.map +1 -0
- package/lib/commonjs/specs/hmac.nitro.js +6 -0
- package/lib/commonjs/specs/hmac.nitro.js.map +1 -0
- package/lib/commonjs/specs/rsaCipher.nitro.js +6 -0
- package/lib/commonjs/specs/rsaCipher.nitro.js.map +1 -0
- package/lib/commonjs/specs/rsaKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/rsaKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/sign.nitro.js +6 -0
- package/lib/commonjs/specs/sign.nitro.js.map +1 -0
- package/lib/commonjs/subtle.js +987 -0
- package/lib/commonjs/subtle.js.map +1 -0
- package/lib/commonjs/utils/cipher.js +64 -0
- package/lib/commonjs/utils/cipher.js.map +1 -0
- package/lib/commonjs/utils/conversion.js +44 -5
- package/lib/commonjs/utils/conversion.js.map +1 -1
- package/lib/commonjs/utils/hashnames.js +2 -1
- package/lib/commonjs/utils/hashnames.js.map +1 -1
- package/lib/commonjs/utils/index.js +11 -0
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/commonjs/utils/noble.js +82 -0
- package/lib/commonjs/utils/noble.js.map +1 -0
- package/lib/commonjs/utils/types.js +32 -17
- package/lib/commonjs/utils/types.js.map +1 -1
- package/lib/commonjs/utils/validation.js +74 -1
- package/lib/commonjs/utils/validation.js.map +1 -1
- package/lib/module/blake3.js +90 -0
- package/lib/module/blake3.js.map +1 -0
- package/lib/module/cipher.js +173 -0
- package/lib/module/cipher.js.map +1 -0
- package/lib/module/constants.js +28 -0
- package/lib/module/constants.js.map +1 -0
- package/lib/module/ec.js +470 -0
- package/lib/module/ec.js.map +1 -0
- package/lib/module/ed.js +212 -3
- package/lib/module/ed.js.map +1 -1
- package/lib/module/expo-plugin/@types.js +2 -0
- package/lib/module/expo-plugin/@types.js.map +1 -0
- package/lib/module/expo-plugin/withRNQC.js +21 -0
- package/lib/module/expo-plugin/withRNQC.js.map +1 -0
- package/lib/module/expo-plugin/withSodiumAndroid.js +20 -0
- package/lib/module/expo-plugin/withSodiumAndroid.js.map +1 -0
- package/lib/module/expo-plugin/withSodiumIos.js +20 -0
- package/lib/module/expo-plugin/withSodiumIos.js.map +1 -0
- package/lib/module/expo-plugin/withXCode.js +46 -0
- package/lib/module/expo-plugin/withXCode.js.map +1 -0
- package/lib/module/hash.js +207 -0
- package/lib/module/hash.js.map +1 -0
- package/lib/module/hmac.js +104 -0
- package/lib/module/hmac.js.map +1 -0
- package/lib/module/index.js +21 -21
- package/lib/module/index.js.map +1 -1
- package/lib/module/keys/classes.js +106 -49
- package/lib/module/keys/classes.js.map +1 -1
- package/lib/module/keys/generateKeyPair.js +134 -143
- package/lib/module/keys/generateKeyPair.js.map +1 -1
- package/lib/module/keys/index.js +161 -22
- package/lib/module/keys/index.js.map +1 -1
- package/lib/module/keys/publicCipher.js +145 -0
- package/lib/module/keys/publicCipher.js.map +1 -0
- package/lib/module/keys/signVerify.js +170 -39
- package/lib/module/keys/signVerify.js.map +1 -1
- package/lib/module/keys/utils.js +16 -12
- package/lib/module/keys/utils.js.map +1 -1
- package/lib/module/pbkdf2.js.map +1 -1
- package/lib/module/random.js +6 -0
- package/lib/module/random.js.map +1 -1
- package/lib/module/rsa.js +194 -0
- package/lib/module/rsa.js.map +1 -0
- package/lib/module/specs/blake3.nitro.js +4 -0
- package/lib/module/specs/blake3.nitro.js.map +1 -0
- package/lib/module/specs/cipher.nitro.js +4 -0
- package/lib/module/specs/cipher.nitro.js.map +1 -0
- package/lib/module/specs/ecKeyPair.nitro.js +4 -0
- package/lib/module/specs/ecKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/hash.nitro.js +4 -0
- package/lib/module/specs/hash.nitro.js.map +1 -0
- package/lib/module/specs/hmac.nitro.js +4 -0
- package/lib/module/specs/hmac.nitro.js.map +1 -0
- package/lib/module/specs/rsaCipher.nitro.js +4 -0
- package/lib/module/specs/rsaCipher.nitro.js.map +1 -0
- package/lib/module/specs/rsaKeyPair.nitro.js +4 -0
- package/lib/module/specs/rsaKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/sign.nitro.js +4 -0
- package/lib/module/specs/sign.nitro.js.map +1 -0
- package/lib/module/subtle.js +982 -0
- package/lib/module/subtle.js.map +1 -0
- package/lib/module/utils/cipher.js +56 -0
- package/lib/module/utils/cipher.js.map +1 -0
- package/lib/module/utils/conversion.js +26 -5
- package/lib/module/utils/conversion.js.map +1 -1
- package/lib/module/utils/hashnames.js +2 -1
- package/lib/module/utils/hashnames.js.map +1 -1
- package/lib/module/utils/index.js +1 -0
- package/lib/module/utils/index.js.map +1 -1
- package/lib/module/utils/noble.js +76 -0
- package/lib/module/utils/noble.js.map +1 -0
- package/lib/module/utils/types.js +32 -17
- package/lib/module/utils/types.js.map +1 -1
- package/lib/module/utils/validation.js +69 -1
- package/lib/module/utils/validation.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/typescript/blake3.d.ts +33 -0
- package/lib/typescript/blake3.d.ts.map +1 -0
- package/lib/typescript/cipher.d.ts +60 -0
- package/lib/typescript/cipher.d.ts.map +1 -0
- package/lib/typescript/constants.d.ts +21 -0
- package/lib/typescript/constants.d.ts.map +1 -0
- package/lib/typescript/ec.d.ts +22 -0
- package/lib/typescript/ec.d.ts.map +1 -0
- package/lib/typescript/ed.d.ts +28 -1
- package/lib/typescript/ed.d.ts.map +1 -1
- package/lib/typescript/expo-plugin/@types.d.ts +8 -0
- package/lib/typescript/expo-plugin/@types.d.ts.map +1 -0
- package/lib/typescript/expo-plugin/withRNQC.d.ts +4 -0
- package/lib/typescript/expo-plugin/withRNQC.d.ts.map +1 -0
- package/lib/typescript/expo-plugin/withSodiumAndroid.d.ts +4 -0
- package/lib/typescript/expo-plugin/withSodiumAndroid.d.ts.map +1 -0
- package/lib/typescript/expo-plugin/withSodiumIos.d.ts +4 -0
- package/lib/typescript/expo-plugin/withSodiumIos.d.ts.map +1 -0
- package/lib/typescript/expo-plugin/withXCode.d.ts +9 -0
- package/lib/typescript/expo-plugin/withXCode.d.ts.map +1 -0
- package/lib/typescript/hash.d.ts +122 -0
- package/lib/typescript/hash.d.ts.map +1 -0
- package/lib/typescript/hmac.d.ts +66 -0
- package/lib/typescript/hmac.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +102 -10
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/keys/classes.d.ts +50 -8
- package/lib/typescript/keys/classes.d.ts.map +1 -1
- package/lib/typescript/keys/generateKeyPair.d.ts +5 -0
- package/lib/typescript/keys/generateKeyPair.d.ts.map +1 -1
- package/lib/typescript/keys/index.d.ts +22 -2
- package/lib/typescript/keys/index.d.ts.map +1 -1
- package/lib/typescript/keys/publicCipher.d.ts +20 -0
- package/lib/typescript/keys/publicCipher.d.ts.map +1 -0
- package/lib/typescript/keys/signVerify.d.ts +28 -0
- package/lib/typescript/keys/signVerify.d.ts.map +1 -1
- package/lib/typescript/keys/utils.d.ts +3 -1
- package/lib/typescript/keys/utils.d.ts.map +1 -1
- package/lib/typescript/pbkdf2.d.ts +1 -1
- package/lib/typescript/pbkdf2.d.ts.map +1 -1
- package/lib/typescript/random.d.ts +6 -0
- package/lib/typescript/random.d.ts.map +1 -1
- package/lib/typescript/rsa.d.ts +19 -0
- package/lib/typescript/rsa.d.ts.map +1 -0
- package/lib/typescript/specs/blake3.nitro.d.ts +15 -0
- package/lib/typescript/specs/blake3.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/cipher.nitro.d.ts +29 -0
- package/lib/typescript/specs/cipher.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/ecKeyPair.nitro.d.ts +20 -0
- package/lib/typescript/specs/ecKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/edKeyPair.nitro.d.ts +1 -0
- package/lib/typescript/specs/edKeyPair.nitro.d.ts.map +1 -1
- package/lib/typescript/specs/hash.nitro.d.ts +13 -0
- package/lib/typescript/specs/hash.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/hmac.nitro.d.ts +10 -0
- package/lib/typescript/specs/hmac.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts +1 -1
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -1
- package/lib/typescript/specs/rsaCipher.nitro.d.ts +44 -0
- package/lib/typescript/specs/rsaCipher.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/rsaKeyPair.nitro.d.ts +20 -0
- package/lib/typescript/specs/rsaKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/sign.nitro.d.ts +19 -0
- package/lib/typescript/specs/sign.nitro.d.ts.map +1 -0
- package/lib/typescript/subtle.d.ts +17 -0
- package/lib/typescript/subtle.d.ts.map +1 -0
- package/lib/typescript/utils/cipher.d.ts +7 -0
- package/lib/typescript/utils/cipher.d.ts.map +1 -0
- package/lib/typescript/utils/conversion.d.ts +1 -0
- package/lib/typescript/utils/conversion.d.ts.map +1 -1
- package/lib/typescript/utils/hashnames.d.ts +3 -1
- package/lib/typescript/utils/hashnames.d.ts.map +1 -1
- package/lib/typescript/utils/index.d.ts +1 -0
- package/lib/typescript/utils/index.d.ts.map +1 -1
- package/lib/typescript/utils/noble.d.ts +19 -0
- package/lib/typescript/utils/noble.d.ts.map +1 -0
- package/lib/typescript/utils/types.d.ts +125 -23
- package/lib/typescript/utils/types.d.ts.map +1 -1
- package/lib/typescript/utils/validation.d.ts +5 -0
- package/lib/typescript/utils/validation.d.ts.map +1 -1
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +30 -1
- package/nitrogen/generated/android/QuickCrypto+autolinking.gradle +1 -1
- package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +115 -1
- package/nitrogen/generated/android/QuickCryptoOnLoad.hpp +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/crypto/QuickCryptoOnLoad.kt +35 -0
- package/nitrogen/generated/ios/QuickCrypto+autolinking.rb +3 -1
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.cpp +1 -1
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.hpp +1 -1
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Umbrella.hpp +3 -3
- package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +111 -1
- package/nitrogen/generated/ios/QuickCryptoAutolinking.swift +1 -1
- package/nitrogen/generated/shared/c++/AsymmetricKeyType.hpp +104 -0
- package/nitrogen/generated/shared/c++/CipherArgs.hpp +86 -0
- package/nitrogen/generated/shared/c++/HybridBlake3Spec.cpp +28 -0
- package/nitrogen/generated/shared/c++/HybridBlake3Spec.hpp +76 -0
- package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.hpp +67 -0
- package/nitrogen/generated/shared/c++/HybridCipherSpec.cpp +28 -0
- package/nitrogen/generated/shared/c++/HybridCipherSpec.hpp +76 -0
- package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.cpp +29 -0
- package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.hpp +77 -0
- package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.cpp +2 -1
- package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.hpp +5 -4
- package/nitrogen/generated/shared/c++/HybridHashSpec.cpp +26 -0
- package/nitrogen/generated/shared/c++/HybridHashSpec.hpp +75 -0
- package/nitrogen/generated/shared/c++/HybridHmacSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridHmacSpec.hpp +66 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp +1 -1
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +8 -8
- package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.cpp +1 -1
- package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.hpp +3 -3
- package/nitrogen/generated/shared/c++/HybridRandomSpec.cpp +1 -1
- package/nitrogen/generated/shared/c++/HybridRandomSpec.hpp +3 -3
- package/nitrogen/generated/shared/c++/HybridRsaCipherSpec.cpp +24 -0
- package/nitrogen/generated/shared/c++/HybridRsaCipherSpec.hpp +72 -0
- package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.cpp +29 -0
- package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.hpp +77 -0
- package/nitrogen/generated/shared/c++/HybridSignHandleSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridSignHandleSpec.hpp +71 -0
- package/nitrogen/generated/shared/c++/HybridVerifyHandleSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridVerifyHandleSpec.hpp +71 -0
- package/nitrogen/generated/shared/c++/JWK.hpp +17 -18
- package/nitrogen/generated/shared/c++/JWKkty.hpp +12 -14
- package/nitrogen/generated/shared/c++/JWKuse.hpp +8 -10
- package/nitrogen/generated/shared/c++/KFormatType.hpp +14 -16
- package/nitrogen/generated/shared/c++/KeyDetail.hpp +6 -7
- package/nitrogen/generated/shared/c++/KeyEncoding.hpp +15 -17
- package/nitrogen/generated/shared/c++/KeyObject.hpp +67 -0
- package/nitrogen/generated/shared/c++/KeyType.hpp +11 -13
- package/nitrogen/generated/shared/c++/KeyUsage.hpp +38 -24
- package/nitrogen/generated/shared/c++/NamedCurve.hpp +10 -12
- package/package.json +28 -23
- package/src/blake3.ts +123 -0
- package/src/cipher.ts +335 -0
- package/src/constants.ts +32 -0
- package/src/ec.ts +657 -0
- package/src/ed.ts +297 -13
- package/src/expo-plugin/@types.ts +7 -0
- package/src/expo-plugin/withRNQC.ts +23 -0
- package/src/expo-plugin/withSodiumAndroid.ts +24 -0
- package/src/expo-plugin/withSodiumIos.ts +30 -0
- package/src/expo-plugin/withXCode.ts +55 -0
- package/src/hash.ts +274 -0
- package/src/hmac.ts +135 -0
- package/src/index.ts +20 -20
- package/src/keys/classes.ts +148 -55
- package/src/keys/generateKeyPair.ts +177 -134
- package/src/keys/index.ts +226 -14
- package/src/keys/publicCipher.ts +229 -0
- package/src/keys/signVerify.ts +239 -39
- package/src/keys/utils.ts +24 -18
- package/src/pbkdf2.ts +1 -1
- package/src/random.ts +7 -0
- package/src/rsa.ts +310 -0
- package/src/specs/blake3.nitro.ts +12 -0
- package/src/specs/cipher.nitro.ts +25 -0
- package/src/specs/ecKeyPair.nitro.ts +38 -0
- package/src/specs/edKeyPair.nitro.ts +2 -0
- package/src/specs/hash.nitro.ts +10 -0
- package/src/specs/hmac.nitro.ts +7 -0
- package/src/specs/keyObjectHandle.nitro.ts +1 -1
- package/src/specs/rsaCipher.nitro.ts +65 -0
- package/src/specs/rsaKeyPair.nitro.ts +33 -0
- package/src/specs/sign.nitro.ts +31 -0
- package/src/subtle.ts +1436 -0
- package/src/utils/cipher.ts +60 -0
- package/src/utils/conversion.ts +33 -4
- package/src/utils/hashnames.ts +4 -2
- package/src/utils/index.ts +1 -0
- package/src/utils/noble.ts +85 -0
- package/src/utils/types.ts +209 -29
- package/src/utils/validation.ts +96 -1
- package/lib/module/package.json +0 -1
- package/nitrogen/generated/android/QuickCryptoOnLoad.kt +0 -1
- package/nitrogen/generated/shared/c++/CFRGKeyPairType.hpp +0 -86
|
@@ -0,0 +1,749 @@
|
|
|
1
|
+
#include <cstdio>
|
|
2
|
+
#include <stdexcept>
|
|
3
|
+
|
|
4
|
+
#include "../utils/base64.h"
|
|
5
|
+
#include "HybridKeyObjectHandle.hpp"
|
|
6
|
+
#include "Utils.hpp"
|
|
7
|
+
#include <openssl/bn.h>
|
|
8
|
+
#include <openssl/ec.h>
|
|
9
|
+
#include <openssl/evp.h>
|
|
10
|
+
#include <openssl/obj_mac.h>
|
|
11
|
+
#include <openssl/rsa.h>
|
|
12
|
+
|
|
13
|
+
namespace margelo::nitro::crypto {
|
|
14
|
+
|
|
15
|
+
// Helper functions for base64url encoding/decoding with BIGNUMs
|
|
16
|
+
static std::string bn_to_base64url(const BIGNUM* bn, size_t expected_size = 0) {
|
|
17
|
+
if (!bn)
|
|
18
|
+
return "";
|
|
19
|
+
|
|
20
|
+
int num_bytes = BN_num_bytes(bn);
|
|
21
|
+
if (num_bytes == 0)
|
|
22
|
+
return "";
|
|
23
|
+
|
|
24
|
+
// If expected_size is provided and larger than num_bytes, pad with leading zeros
|
|
25
|
+
size_t buffer_size =
|
|
26
|
+
(expected_size > 0 && expected_size > static_cast<size_t>(num_bytes)) ? expected_size : static_cast<size_t>(num_bytes);
|
|
27
|
+
|
|
28
|
+
std::vector<unsigned char> buffer(buffer_size, 0);
|
|
29
|
+
|
|
30
|
+
// BN_bn2bin writes to the end of the buffer if it's larger than needed
|
|
31
|
+
size_t offset = buffer_size - num_bytes;
|
|
32
|
+
BN_bn2bin(bn, buffer.data() + offset);
|
|
33
|
+
|
|
34
|
+
// Return clean base64url - RFC 7517 compliant (no padding characters)
|
|
35
|
+
return base64_encode<std::string>(buffer.data(), buffer.size(), true);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Helper to add padding to base64url strings
|
|
39
|
+
static std::string add_base64_padding(const std::string& b64) {
|
|
40
|
+
std::string padded = b64;
|
|
41
|
+
// Base64 strings should be a multiple of 4 characters
|
|
42
|
+
// Add '=' padding to make it so
|
|
43
|
+
while (padded.length() % 4 != 0) {
|
|
44
|
+
padded += '=';
|
|
45
|
+
}
|
|
46
|
+
return padded;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static BIGNUM* base64url_to_bn(const std::string& b64) {
|
|
50
|
+
if (b64.empty())
|
|
51
|
+
return nullptr;
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
// Strip trailing periods (some JWK implementations use '.' as padding)
|
|
55
|
+
std::string cleaned = b64;
|
|
56
|
+
while (!cleaned.empty() && cleaned.back() == '.') {
|
|
57
|
+
cleaned.pop_back();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Add padding if needed for base64url
|
|
61
|
+
std::string padded = add_base64_padding(cleaned);
|
|
62
|
+
std::string decoded = base64_decode<std::string>(padded, false);
|
|
63
|
+
if (decoded.empty())
|
|
64
|
+
return nullptr;
|
|
65
|
+
|
|
66
|
+
return BN_bin2bn(reinterpret_cast<const unsigned char*>(decoded.data()), static_cast<int>(decoded.size()), nullptr);
|
|
67
|
+
} catch (const std::exception& e) {
|
|
68
|
+
throw std::runtime_error(std::string("Input is not valid base64-encoded data."));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static std::string base64url_encode(const unsigned char* data, size_t len) {
|
|
73
|
+
return base64_encode<std::string>(data, len, true);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static std::string base64url_decode(const std::string& input) {
|
|
77
|
+
// Strip trailing periods (some JWK implementations use '.' as padding)
|
|
78
|
+
std::string cleaned = input;
|
|
79
|
+
while (!cleaned.empty() && cleaned.back() == '.') {
|
|
80
|
+
cleaned.pop_back();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Add padding if needed for base64url
|
|
84
|
+
std::string padded = add_base64_padding(cleaned);
|
|
85
|
+
return base64_decode<std::string>(padded, false);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
std::shared_ptr<ArrayBuffer> HybridKeyObjectHandle::exportKey(std::optional<KFormatType> format, std::optional<KeyEncoding> type,
|
|
89
|
+
const std::optional<std::string>& cipher,
|
|
90
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& passphrase) {
|
|
91
|
+
auto keyType = data_.GetKeyType();
|
|
92
|
+
|
|
93
|
+
// Handle secret keys
|
|
94
|
+
if (keyType == KeyType::SECRET) {
|
|
95
|
+
return data_.GetSymmetricKey();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Handle asymmetric keys (public/private)
|
|
99
|
+
if (keyType == KeyType::PUBLIC || keyType == KeyType::PRIVATE) {
|
|
100
|
+
const auto& pkey = data_.GetAsymmetricKey();
|
|
101
|
+
if (!pkey) {
|
|
102
|
+
throw std::runtime_error("Invalid asymmetric key");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
int keyId = EVP_PKEY_id(pkey.get());
|
|
106
|
+
|
|
107
|
+
// For curve keys (X25519, X448, Ed25519, Ed448), use raw format if no format specified
|
|
108
|
+
bool isCurveKey = (keyId == EVP_PKEY_X25519 || keyId == EVP_PKEY_X448 || keyId == EVP_PKEY_ED25519 || keyId == EVP_PKEY_ED448);
|
|
109
|
+
|
|
110
|
+
// If no format specified and it's a curve key, export as raw
|
|
111
|
+
if (!format.has_value() && !type.has_value() && isCurveKey) {
|
|
112
|
+
if (keyType == KeyType::PUBLIC) {
|
|
113
|
+
auto rawData = pkey.rawPublicKey();
|
|
114
|
+
if (!rawData) {
|
|
115
|
+
throw std::runtime_error("Failed to get raw public key");
|
|
116
|
+
}
|
|
117
|
+
return ToNativeArrayBuffer(std::string(reinterpret_cast<const char*>(rawData.get()), rawData.size()));
|
|
118
|
+
} else {
|
|
119
|
+
auto rawData = pkey.rawPrivateKey();
|
|
120
|
+
if (!rawData) {
|
|
121
|
+
throw std::runtime_error("Failed to get raw private key");
|
|
122
|
+
}
|
|
123
|
+
return ToNativeArrayBuffer(std::string(reinterpret_cast<const char*>(rawData.get()), rawData.size()));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Set default format and type if not provided
|
|
128
|
+
auto exportFormat = format.value_or(KFormatType::DER);
|
|
129
|
+
auto exportType = type.value_or(keyType == KeyType::PUBLIC ? KeyEncoding::SPKI : KeyEncoding::PKCS8);
|
|
130
|
+
|
|
131
|
+
// If SPKI is requested, export as public key (works for both public and private keys)
|
|
132
|
+
// This allows extracting the public key from a private key
|
|
133
|
+
bool exportAsPublic = (exportType == KeyEncoding::SPKI) || (keyType == KeyType::PUBLIC);
|
|
134
|
+
|
|
135
|
+
// Create encoding config
|
|
136
|
+
if (exportAsPublic) {
|
|
137
|
+
ncrypto::EVPKeyPointer::PublicKeyEncodingConfig config(false, static_cast<ncrypto::EVPKeyPointer::PKFormatType>(exportFormat),
|
|
138
|
+
static_cast<ncrypto::EVPKeyPointer::PKEncodingType>(exportType));
|
|
139
|
+
|
|
140
|
+
auto result = pkey.writePublicKey(config);
|
|
141
|
+
if (!result) {
|
|
142
|
+
throw std::runtime_error("Failed to export public key");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
auto bio = std::move(result.value);
|
|
146
|
+
BUF_MEM* bptr = bio;
|
|
147
|
+
return ToNativeArrayBuffer(std::string(bptr->data, bptr->length));
|
|
148
|
+
} else {
|
|
149
|
+
ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig config(false, static_cast<ncrypto::EVPKeyPointer::PKFormatType>(exportFormat),
|
|
150
|
+
static_cast<ncrypto::EVPKeyPointer::PKEncodingType>(exportType));
|
|
151
|
+
|
|
152
|
+
// Handle cipher and passphrase for encrypted private keys
|
|
153
|
+
if (cipher.has_value()) {
|
|
154
|
+
const EVP_CIPHER* evp_cipher = EVP_get_cipherbyname(cipher.value().c_str());
|
|
155
|
+
if (!evp_cipher) {
|
|
156
|
+
throw std::runtime_error("Unknown cipher: " + cipher.value());
|
|
157
|
+
}
|
|
158
|
+
config.cipher = evp_cipher;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (passphrase.has_value()) {
|
|
162
|
+
auto& passphrase_ptr = passphrase.value();
|
|
163
|
+
config.passphrase = std::make_optional(ncrypto::DataPointer(passphrase_ptr->data(), passphrase_ptr->size()));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
auto result = pkey.writePrivateKey(config);
|
|
167
|
+
if (!result) {
|
|
168
|
+
throw std::runtime_error("Failed to export private key");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
auto bio = std::move(result.value);
|
|
172
|
+
BUF_MEM* bptr = bio;
|
|
173
|
+
return ToNativeArrayBuffer(std::string(bptr->data, bptr->length));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
throw std::runtime_error("Unsupported key type for export");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
JWK HybridKeyObjectHandle::exportJwk(const JWK& key, bool handleRsaPss) {
|
|
181
|
+
JWK result = key;
|
|
182
|
+
auto keyType = data_.GetKeyType();
|
|
183
|
+
|
|
184
|
+
// Handle secret keys (AES, HMAC)
|
|
185
|
+
if (keyType == KeyType::SECRET) {
|
|
186
|
+
auto symKey = data_.GetSymmetricKey();
|
|
187
|
+
result.kty = JWKkty::OCT;
|
|
188
|
+
// RFC 7517 compliant base64url encoding (no padding characters)
|
|
189
|
+
result.k = base64url_encode(reinterpret_cast<const unsigned char*>(symKey->data()), symKey->size());
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Handle asymmetric keys (RSA, EC)
|
|
194
|
+
const auto& pkey = data_.GetAsymmetricKey();
|
|
195
|
+
if (!pkey) {
|
|
196
|
+
throw std::runtime_error("Invalid key for JWK export");
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
int keyId = EVP_PKEY_id(pkey.get());
|
|
200
|
+
|
|
201
|
+
// Export RSA keys
|
|
202
|
+
if (keyId == EVP_PKEY_RSA || keyId == EVP_PKEY_RSA_PSS) {
|
|
203
|
+
const RSA* rsa = EVP_PKEY_get0_RSA(pkey.get());
|
|
204
|
+
if (!rsa)
|
|
205
|
+
throw std::runtime_error("Failed to get RSA key");
|
|
206
|
+
|
|
207
|
+
result.kty = JWKkty::RSA;
|
|
208
|
+
|
|
209
|
+
const BIGNUM *n_bn, *e_bn, *d_bn, *p_bn, *q_bn, *dmp1_bn, *dmq1_bn, *iqmp_bn;
|
|
210
|
+
RSA_get0_key(rsa, &n_bn, &e_bn, &d_bn);
|
|
211
|
+
RSA_get0_factors(rsa, &p_bn, &q_bn);
|
|
212
|
+
RSA_get0_crt_params(rsa, &dmp1_bn, &dmq1_bn, &iqmp_bn);
|
|
213
|
+
|
|
214
|
+
// Public components (always present)
|
|
215
|
+
if (n_bn)
|
|
216
|
+
result.n = bn_to_base64url(n_bn);
|
|
217
|
+
if (e_bn)
|
|
218
|
+
result.e = bn_to_base64url(e_bn);
|
|
219
|
+
|
|
220
|
+
// Private components (only for private keys)
|
|
221
|
+
if (keyType == KeyType::PRIVATE) {
|
|
222
|
+
if (d_bn)
|
|
223
|
+
result.d = bn_to_base64url(d_bn);
|
|
224
|
+
if (p_bn)
|
|
225
|
+
result.p = bn_to_base64url(p_bn);
|
|
226
|
+
if (q_bn)
|
|
227
|
+
result.q = bn_to_base64url(q_bn);
|
|
228
|
+
if (dmp1_bn)
|
|
229
|
+
result.dp = bn_to_base64url(dmp1_bn);
|
|
230
|
+
if (dmq1_bn)
|
|
231
|
+
result.dq = bn_to_base64url(dmq1_bn);
|
|
232
|
+
if (iqmp_bn)
|
|
233
|
+
result.qi = bn_to_base64url(iqmp_bn);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return result;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Export EC keys
|
|
240
|
+
if (keyId == EVP_PKEY_EC) {
|
|
241
|
+
const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey.get());
|
|
242
|
+
if (!ec)
|
|
243
|
+
throw std::runtime_error("Failed to get EC key");
|
|
244
|
+
|
|
245
|
+
const EC_GROUP* group = EC_KEY_get0_group(ec);
|
|
246
|
+
if (!group)
|
|
247
|
+
throw std::runtime_error("Failed to get EC group");
|
|
248
|
+
|
|
249
|
+
int nid = EC_GROUP_get_curve_name(group);
|
|
250
|
+
const char* curve_name = OBJ_nid2sn(nid);
|
|
251
|
+
if (!curve_name)
|
|
252
|
+
throw std::runtime_error("Unknown curve");
|
|
253
|
+
|
|
254
|
+
// Get the field size in bytes for proper padding
|
|
255
|
+
size_t field_size = (EC_GROUP_get_degree(group) + 7) / 8;
|
|
256
|
+
|
|
257
|
+
result.kty = JWKkty::EC;
|
|
258
|
+
|
|
259
|
+
// Map OpenSSL curve names to JWK curve names
|
|
260
|
+
if (strcmp(curve_name, "prime256v1") == 0) {
|
|
261
|
+
result.crv = "P-256";
|
|
262
|
+
} else if (strcmp(curve_name, "secp384r1") == 0) {
|
|
263
|
+
result.crv = "P-384";
|
|
264
|
+
} else if (strcmp(curve_name, "secp521r1") == 0) {
|
|
265
|
+
result.crv = "P-521";
|
|
266
|
+
} else {
|
|
267
|
+
result.crv = curve_name;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const EC_POINT* pub_key = EC_KEY_get0_public_key(ec);
|
|
271
|
+
if (pub_key) {
|
|
272
|
+
BIGNUM* x_bn = BN_new();
|
|
273
|
+
BIGNUM* y_bn = BN_new();
|
|
274
|
+
|
|
275
|
+
if (EC_POINT_get_affine_coordinates(group, pub_key, x_bn, y_bn, nullptr) == 1) {
|
|
276
|
+
result.x = bn_to_base64url(x_bn, field_size);
|
|
277
|
+
result.y = bn_to_base64url(y_bn, field_size);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
BN_free(x_bn);
|
|
281
|
+
BN_free(y_bn);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Export private key if this is a private key
|
|
285
|
+
if (keyType == KeyType::PRIVATE) {
|
|
286
|
+
const BIGNUM* priv_key = EC_KEY_get0_private_key(ec);
|
|
287
|
+
if (priv_key) {
|
|
288
|
+
result.d = bn_to_base64url(priv_key, field_size);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
throw std::runtime_error("Unsupported key type for JWK export");
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
AsymmetricKeyType HybridKeyObjectHandle::getAsymmetricKeyType() {
|
|
299
|
+
const auto& pkey = data_.GetAsymmetricKey();
|
|
300
|
+
if (!pkey) {
|
|
301
|
+
throw std::runtime_error("Key is not an asymmetric key");
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
int keyType = EVP_PKEY_id(pkey.get());
|
|
305
|
+
|
|
306
|
+
switch (keyType) {
|
|
307
|
+
case EVP_PKEY_RSA:
|
|
308
|
+
return AsymmetricKeyType::RSA;
|
|
309
|
+
case EVP_PKEY_RSA_PSS:
|
|
310
|
+
return AsymmetricKeyType::RSA_PSS;
|
|
311
|
+
case EVP_PKEY_DSA:
|
|
312
|
+
return AsymmetricKeyType::DSA;
|
|
313
|
+
case EVP_PKEY_EC:
|
|
314
|
+
return AsymmetricKeyType::EC;
|
|
315
|
+
case EVP_PKEY_DH:
|
|
316
|
+
return AsymmetricKeyType::DH;
|
|
317
|
+
case EVP_PKEY_X25519:
|
|
318
|
+
return AsymmetricKeyType::X25519;
|
|
319
|
+
case EVP_PKEY_X448:
|
|
320
|
+
return AsymmetricKeyType::X448;
|
|
321
|
+
case EVP_PKEY_ED25519:
|
|
322
|
+
return AsymmetricKeyType::ED25519;
|
|
323
|
+
case EVP_PKEY_ED448:
|
|
324
|
+
return AsymmetricKeyType::ED448;
|
|
325
|
+
default:
|
|
326
|
+
throw std::runtime_error("Unsupported asymmetric key type");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
bool HybridKeyObjectHandle::init(KeyType keyType, const std::variant<std::string, std::shared_ptr<ArrayBuffer>>& key,
|
|
331
|
+
std::optional<KFormatType> format, std::optional<KeyEncoding> type,
|
|
332
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& passphrase) {
|
|
333
|
+
// Reset any existing data to prevent state leakage
|
|
334
|
+
data_ = KeyObjectData();
|
|
335
|
+
|
|
336
|
+
// get ArrayBuffer from key - always copy to ensure we own the data
|
|
337
|
+
std::shared_ptr<ArrayBuffer> ab;
|
|
338
|
+
if (std::holds_alternative<std::string>(key)) {
|
|
339
|
+
ab = ToNativeArrayBuffer(std::get<std::string>(key));
|
|
340
|
+
} else {
|
|
341
|
+
const auto& abPtr = std::get<std::shared_ptr<ArrayBuffer>>(key);
|
|
342
|
+
ab = ToNativeArrayBuffer(abPtr);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Handle raw asymmetric key material - only for special curves with known raw sizes
|
|
346
|
+
std::optional<KFormatType> actualFormat = format;
|
|
347
|
+
if (!actualFormat.has_value() && !type.has_value() && (keyType == KeyType::PUBLIC || keyType == KeyType::PRIVATE)) {
|
|
348
|
+
size_t keySize = ab->size();
|
|
349
|
+
// Only route to initRawKey for exact special curve sizes:
|
|
350
|
+
// X25519/Ed25519: 32 bytes, X448: 56 bytes, Ed448: 57 bytes
|
|
351
|
+
// DER-encoded keys will be much larger and should use standard parsing
|
|
352
|
+
if ((keySize == 32) || (keySize == 56) || (keySize == 57)) {
|
|
353
|
+
return initRawKey(keyType, ab);
|
|
354
|
+
}
|
|
355
|
+
// For larger sizes (DER-encoded keys), fall through to standard parsing
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
switch (keyType) {
|
|
359
|
+
case KeyType::SECRET: {
|
|
360
|
+
this->data_ = KeyObjectData::CreateSecret(ab);
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
case KeyType::PUBLIC: {
|
|
364
|
+
auto data = KeyObjectData::GetPublicOrPrivateKey(ab, actualFormat, type, passphrase);
|
|
365
|
+
if (!data)
|
|
366
|
+
return false;
|
|
367
|
+
this->data_ = data.addRefWithType(KeyType::PUBLIC);
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
case KeyType::PRIVATE: {
|
|
371
|
+
if (auto data = KeyObjectData::GetPrivateKey(ab, actualFormat, type, passphrase, false)) {
|
|
372
|
+
this->data_ = std::move(data);
|
|
373
|
+
}
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
std::optional<KeyType> HybridKeyObjectHandle::initJwk(const JWK& keyData, std::optional<NamedCurve> namedCurve) {
|
|
381
|
+
// Reset any existing data
|
|
382
|
+
data_ = KeyObjectData();
|
|
383
|
+
|
|
384
|
+
if (!keyData.kty.has_value()) {
|
|
385
|
+
throw std::runtime_error("JWK missing required 'kty' field");
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
JWKkty kty = keyData.kty.value();
|
|
389
|
+
|
|
390
|
+
// Handle symmetric keys (AES, HMAC)
|
|
391
|
+
if (kty == JWKkty::OCT) {
|
|
392
|
+
if (!keyData.k.has_value()) {
|
|
393
|
+
throw std::runtime_error("JWK oct key missing 'k' field");
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
std::string decoded = base64url_decode(keyData.k.value());
|
|
397
|
+
auto keyBuffer = ToNativeArrayBuffer(decoded);
|
|
398
|
+
data_ = KeyObjectData::CreateSecret(keyBuffer);
|
|
399
|
+
return KeyType::SECRET;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Handle RSA keys
|
|
403
|
+
if (kty == JWKkty::RSA) {
|
|
404
|
+
bool isPrivate = keyData.d.has_value();
|
|
405
|
+
|
|
406
|
+
if (!keyData.n.has_value() || !keyData.e.has_value()) {
|
|
407
|
+
throw std::runtime_error("JWK RSA key missing required 'n' or 'e' fields");
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
RSA* rsa = RSA_new();
|
|
411
|
+
if (!rsa)
|
|
412
|
+
throw std::runtime_error("Failed to create RSA key");
|
|
413
|
+
|
|
414
|
+
// Set public components
|
|
415
|
+
BIGNUM* n = base64url_to_bn(keyData.n.value());
|
|
416
|
+
BIGNUM* e = base64url_to_bn(keyData.e.value());
|
|
417
|
+
|
|
418
|
+
if (!n || !e) {
|
|
419
|
+
RSA_free(rsa);
|
|
420
|
+
throw std::runtime_error("Failed to decode RSA public components");
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (isPrivate) {
|
|
424
|
+
// Private key
|
|
425
|
+
if (!keyData.d.has_value()) {
|
|
426
|
+
BN_free(n);
|
|
427
|
+
BN_free(e);
|
|
428
|
+
RSA_free(rsa);
|
|
429
|
+
throw std::runtime_error("JWK RSA private key missing 'd' field");
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
BIGNUM* d = base64url_to_bn(keyData.d.value());
|
|
433
|
+
if (!d) {
|
|
434
|
+
BN_free(n);
|
|
435
|
+
BN_free(e);
|
|
436
|
+
RSA_free(rsa);
|
|
437
|
+
throw std::runtime_error("Failed to decode RSA 'd' component");
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Set key components (RSA_set0_key takes ownership)
|
|
441
|
+
if (RSA_set0_key(rsa, n, e, d) != 1) {
|
|
442
|
+
BN_free(n);
|
|
443
|
+
BN_free(e);
|
|
444
|
+
BN_free(d);
|
|
445
|
+
RSA_free(rsa);
|
|
446
|
+
throw std::runtime_error("Failed to set RSA key components");
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Set optional CRT parameters if present
|
|
450
|
+
if (keyData.p.has_value() && keyData.q.has_value()) {
|
|
451
|
+
BIGNUM* p = base64url_to_bn(keyData.p.value());
|
|
452
|
+
BIGNUM* q = base64url_to_bn(keyData.q.value());
|
|
453
|
+
if (p && q) {
|
|
454
|
+
RSA_set0_factors(rsa, p, q);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if (keyData.dp.has_value() && keyData.dq.has_value() && keyData.qi.has_value()) {
|
|
459
|
+
BIGNUM* dmp1 = base64url_to_bn(keyData.dp.value());
|
|
460
|
+
BIGNUM* dmq1 = base64url_to_bn(keyData.dq.value());
|
|
461
|
+
BIGNUM* iqmp = base64url_to_bn(keyData.qi.value());
|
|
462
|
+
if (dmp1 && dmq1 && iqmp) {
|
|
463
|
+
RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// Create EVP_PKEY from RSA
|
|
468
|
+
EVP_PKEY* pkey = EVP_PKEY_new();
|
|
469
|
+
if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
|
|
470
|
+
RSA_free(rsa);
|
|
471
|
+
if (pkey)
|
|
472
|
+
EVP_PKEY_free(pkey);
|
|
473
|
+
throw std::runtime_error("Failed to create EVP_PKEY from RSA");
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
data_ = KeyObjectData::CreateAsymmetric(KeyType::PRIVATE, ncrypto::EVPKeyPointer(pkey));
|
|
477
|
+
return KeyType::PRIVATE;
|
|
478
|
+
|
|
479
|
+
} else {
|
|
480
|
+
// Public key
|
|
481
|
+
if (RSA_set0_key(rsa, n, e, nullptr) != 1) {
|
|
482
|
+
BN_free(n);
|
|
483
|
+
BN_free(e);
|
|
484
|
+
RSA_free(rsa);
|
|
485
|
+
throw std::runtime_error("Failed to set RSA public key components");
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
EVP_PKEY* pkey = EVP_PKEY_new();
|
|
489
|
+
if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
|
|
490
|
+
RSA_free(rsa);
|
|
491
|
+
if (pkey)
|
|
492
|
+
EVP_PKEY_free(pkey);
|
|
493
|
+
throw std::runtime_error("Failed to create EVP_PKEY from RSA");
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
data_ = KeyObjectData::CreateAsymmetric(KeyType::PUBLIC, ncrypto::EVPKeyPointer(pkey));
|
|
497
|
+
return KeyType::PUBLIC;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Handle EC keys
|
|
502
|
+
if (kty == JWKkty::EC) {
|
|
503
|
+
bool isPrivate = keyData.d.has_value();
|
|
504
|
+
|
|
505
|
+
if (!keyData.crv.has_value() || !keyData.x.has_value() || !keyData.y.has_value()) {
|
|
506
|
+
throw std::runtime_error("JWK EC key missing required fields (crv, x, y)");
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
std::string crv = keyData.crv.value();
|
|
510
|
+
|
|
511
|
+
// Map JWK curve names to OpenSSL NIDs
|
|
512
|
+
int nid;
|
|
513
|
+
if (crv == "P-256") {
|
|
514
|
+
nid = NID_X9_62_prime256v1;
|
|
515
|
+
} else if (crv == "P-384") {
|
|
516
|
+
nid = NID_secp384r1;
|
|
517
|
+
} else if (crv == "P-521") {
|
|
518
|
+
nid = NID_secp521r1;
|
|
519
|
+
} else {
|
|
520
|
+
throw std::runtime_error("Unsupported EC curve: " + crv);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Create EC_KEY
|
|
524
|
+
EC_KEY* ec = EC_KEY_new_by_curve_name(nid);
|
|
525
|
+
if (!ec)
|
|
526
|
+
throw std::runtime_error("Failed to create EC key");
|
|
527
|
+
|
|
528
|
+
const EC_GROUP* group = EC_KEY_get0_group(ec);
|
|
529
|
+
|
|
530
|
+
// Decode public key coordinates
|
|
531
|
+
BIGNUM* x_bn = base64url_to_bn(keyData.x.value());
|
|
532
|
+
BIGNUM* y_bn = base64url_to_bn(keyData.y.value());
|
|
533
|
+
|
|
534
|
+
if (!x_bn || !y_bn) {
|
|
535
|
+
EC_KEY_free(ec);
|
|
536
|
+
throw std::runtime_error("Failed to decode EC public key coordinates");
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Set public key
|
|
540
|
+
EC_POINT* pub_key = EC_POINT_new(group);
|
|
541
|
+
if (!pub_key || EC_POINT_set_affine_coordinates(group, pub_key, x_bn, y_bn, nullptr) != 1) {
|
|
542
|
+
BN_free(x_bn);
|
|
543
|
+
BN_free(y_bn);
|
|
544
|
+
if (pub_key)
|
|
545
|
+
EC_POINT_free(pub_key);
|
|
546
|
+
EC_KEY_free(ec);
|
|
547
|
+
throw std::runtime_error("Failed to set EC public key");
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
BN_free(x_bn);
|
|
551
|
+
BN_free(y_bn);
|
|
552
|
+
|
|
553
|
+
if (EC_KEY_set_public_key(ec, pub_key) != 1) {
|
|
554
|
+
EC_POINT_free(pub_key);
|
|
555
|
+
EC_KEY_free(ec);
|
|
556
|
+
throw std::runtime_error("Failed to set EC public key on EC_KEY");
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
EC_POINT_free(pub_key);
|
|
560
|
+
|
|
561
|
+
// Set private key if present
|
|
562
|
+
if (isPrivate) {
|
|
563
|
+
BIGNUM* d_bn = base64url_to_bn(keyData.d.value());
|
|
564
|
+
if (!d_bn) {
|
|
565
|
+
EC_KEY_free(ec);
|
|
566
|
+
throw std::runtime_error("Failed to decode EC private key");
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
if (EC_KEY_set_private_key(ec, d_bn) != 1) {
|
|
570
|
+
BN_free(d_bn);
|
|
571
|
+
EC_KEY_free(ec);
|
|
572
|
+
throw std::runtime_error("Failed to set EC private key");
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
BN_free(d_bn);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Create EVP_PKEY from EC_KEY
|
|
579
|
+
EVP_PKEY* pkey = EVP_PKEY_new();
|
|
580
|
+
if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) {
|
|
581
|
+
EC_KEY_free(ec);
|
|
582
|
+
if (pkey)
|
|
583
|
+
EVP_PKEY_free(pkey);
|
|
584
|
+
throw std::runtime_error("Failed to create EVP_PKEY from EC_KEY");
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
KeyType type = isPrivate ? KeyType::PRIVATE : KeyType::PUBLIC;
|
|
588
|
+
data_ = KeyObjectData::CreateAsymmetric(type, ncrypto::EVPKeyPointer(pkey));
|
|
589
|
+
return type;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
throw std::runtime_error("Unsupported JWK key type");
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
KeyDetail HybridKeyObjectHandle::keyDetail() {
|
|
596
|
+
const auto& pkey_ptr = data_.GetAsymmetricKey();
|
|
597
|
+
if (!pkey_ptr) {
|
|
598
|
+
return KeyDetail{};
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
EVP_PKEY* pkey = pkey_ptr.get();
|
|
602
|
+
int keyType = EVP_PKEY_base_id(pkey);
|
|
603
|
+
|
|
604
|
+
if (keyType == EVP_PKEY_RSA) {
|
|
605
|
+
// Extract RSA key details
|
|
606
|
+
int modulusLength = EVP_PKEY_bits(pkey);
|
|
607
|
+
|
|
608
|
+
// Extract public exponent (typically 65537 = 0x10001)
|
|
609
|
+
const RSA* rsa = EVP_PKEY_get0_RSA(pkey);
|
|
610
|
+
if (rsa) {
|
|
611
|
+
const BIGNUM* e_bn = nullptr;
|
|
612
|
+
RSA_get0_key(rsa, nullptr, &e_bn, nullptr);
|
|
613
|
+
if (e_bn) {
|
|
614
|
+
unsigned long exponent_val = BN_get_word(e_bn);
|
|
615
|
+
return KeyDetail(std::nullopt, static_cast<double>(exponent_val), static_cast<double>(modulusLength), std::nullopt, std::nullopt,
|
|
616
|
+
std::nullopt, std::nullopt);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// Fallback if we couldn't extract the exponent
|
|
621
|
+
return KeyDetail(std::nullopt, std::nullopt, static_cast<double>(modulusLength), std::nullopt, std::nullopt, std::nullopt,
|
|
622
|
+
std::nullopt);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
if (keyType == EVP_PKEY_EC) {
|
|
626
|
+
// Extract EC curve name
|
|
627
|
+
EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(pkey);
|
|
628
|
+
if (ec_key) {
|
|
629
|
+
const EC_GROUP* group = EC_KEY_get0_group(ec_key);
|
|
630
|
+
if (group) {
|
|
631
|
+
int nid = EC_GROUP_get_curve_name(group);
|
|
632
|
+
const char* curve_name = OBJ_nid2sn(nid);
|
|
633
|
+
if (curve_name) {
|
|
634
|
+
std::string namedCurve(curve_name);
|
|
635
|
+
EC_KEY_free(ec_key);
|
|
636
|
+
return KeyDetail(std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, namedCurve);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
EC_KEY_free(ec_key);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
return KeyDetail{};
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
bool HybridKeyObjectHandle::initRawKey(KeyType keyType, std::shared_ptr<ArrayBuffer> keyData) {
|
|
647
|
+
// For asymmetric keys (x25519/x448/ed25519/ed448), we need to determine the curve type
|
|
648
|
+
// Based on key size: x25519=32 bytes, x448=56 bytes, ed25519=32 bytes, ed448=57 bytes
|
|
649
|
+
int curveId = -1;
|
|
650
|
+
size_t keySize = keyData->size();
|
|
651
|
+
|
|
652
|
+
if (keySize == 32) {
|
|
653
|
+
// Could be x25519 or ed25519 - for now assume x25519 based on test context
|
|
654
|
+
curveId = EVP_PKEY_X25519;
|
|
655
|
+
} else if (keySize == 56) {
|
|
656
|
+
curveId = EVP_PKEY_X448;
|
|
657
|
+
} else if (keySize == 57) {
|
|
658
|
+
curveId = EVP_PKEY_ED448;
|
|
659
|
+
} else {
|
|
660
|
+
throw std::runtime_error("Invalid key size: expected 32, 56, or 57 bytes for curve keys");
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
ncrypto::Buffer<const unsigned char> buffer{.data = reinterpret_cast<const unsigned char*>(keyData->data()), .len = keyData->size()};
|
|
664
|
+
|
|
665
|
+
ncrypto::EVPKeyPointer pkey;
|
|
666
|
+
if (keyType == KeyType::PRIVATE) {
|
|
667
|
+
pkey = ncrypto::EVPKeyPointer::NewRawPrivate(curveId, buffer);
|
|
668
|
+
} else if (keyType == KeyType::PUBLIC) {
|
|
669
|
+
pkey = ncrypto::EVPKeyPointer::NewRawPublic(curveId, buffer);
|
|
670
|
+
} else {
|
|
671
|
+
throw std::runtime_error("Raw keys are only supported for asymmetric key types");
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
if (!pkey) {
|
|
675
|
+
throw std::runtime_error("Failed to create key from raw data");
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
this->data_ = KeyObjectData::CreateAsymmetric(keyType, std::move(pkey));
|
|
679
|
+
return true;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
bool HybridKeyObjectHandle::initECRaw(const std::string& namedCurve, const std::shared_ptr<ArrayBuffer>& keyData) {
|
|
683
|
+
// Reset any existing data
|
|
684
|
+
data_ = KeyObjectData();
|
|
685
|
+
|
|
686
|
+
// Map curve name to NID (same logic as HybridEcKeyPair::GetCurveFromName)
|
|
687
|
+
int nid = 0;
|
|
688
|
+
if (namedCurve == "prime256v1" || namedCurve == "P-256") {
|
|
689
|
+
nid = NID_X9_62_prime256v1;
|
|
690
|
+
} else if (namedCurve == "secp384r1" || namedCurve == "P-384") {
|
|
691
|
+
nid = NID_secp384r1;
|
|
692
|
+
} else if (namedCurve == "secp521r1" || namedCurve == "P-521") {
|
|
693
|
+
nid = NID_secp521r1;
|
|
694
|
+
} else if (namedCurve == "secp256k1") {
|
|
695
|
+
nid = NID_secp256k1;
|
|
696
|
+
} else {
|
|
697
|
+
// Try standard OpenSSL name resolution
|
|
698
|
+
nid = OBJ_txt2nid(namedCurve.c_str());
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
if (nid == 0) {
|
|
702
|
+
throw std::runtime_error("Unknown curve: " + namedCurve);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// Create EC_GROUP for the curve
|
|
706
|
+
ncrypto::ECGroupPointer group = ncrypto::ECGroupPointer::NewByCurveName(nid);
|
|
707
|
+
if (!group) {
|
|
708
|
+
throw std::runtime_error("Failed to create EC_GROUP for curve");
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// Create EC_POINT from raw bytes
|
|
712
|
+
ncrypto::ECPointPointer point = ncrypto::ECPointPointer::New(group.get());
|
|
713
|
+
if (!point) {
|
|
714
|
+
throw std::runtime_error("Failed to create EC_POINT");
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// Convert raw bytes to EC_POINT
|
|
718
|
+
ncrypto::Buffer<const unsigned char> buffer{.data = reinterpret_cast<const unsigned char*>(keyData->data()), .len = keyData->size()};
|
|
719
|
+
|
|
720
|
+
if (!point.setFromBuffer(buffer, group.get())) {
|
|
721
|
+
throw std::runtime_error("Failed to read DER asymmetric key");
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// Create EC_KEY and set the public key
|
|
725
|
+
ncrypto::ECKeyPointer ec = ncrypto::ECKeyPointer::New(group.get());
|
|
726
|
+
if (!ec) {
|
|
727
|
+
throw std::runtime_error("Failed to create EC_KEY");
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
if (!ec.setPublicKey(point)) {
|
|
731
|
+
throw std::runtime_error("Failed to set public key on EC_KEY");
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// Create EVP_PKEY from EC_KEY
|
|
735
|
+
ncrypto::EVPKeyPointer pkey = ncrypto::EVPKeyPointer::New();
|
|
736
|
+
if (!pkey) {
|
|
737
|
+
throw std::runtime_error("Failed to create EVP_PKEY");
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
if (!pkey.set(ec)) {
|
|
741
|
+
throw std::runtime_error("Failed to assign EC_KEY to EVP_PKEY");
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// Store as public key
|
|
745
|
+
this->data_ = KeyObjectData::CreateAsymmetric(KeyType::PUBLIC, std::move(pkey));
|
|
746
|
+
return true;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
} // namespace margelo::nitro::crypto
|