@ohos-ports/react-native-quick-crypto 0.0.0-stage → 1.1.8-beta.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 +259 -0
- package/README.md +170 -2
- package/android/CMakeLists.txt +155 -0
- package/android/build.gradle +176 -0
- package/android/gradle.properties +6 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/cpp/cpp-adapter.cpp +8 -0
- package/android/src/main/java/com/margelo/nitro/quickcrypto/QuickCryptoPackage.java +41 -0
- package/app.plugin.js +3 -0
- package/cpp/argon2/HybridArgon2.cpp +110 -0
- package/cpp/argon2/HybridArgon2.hpp +32 -0
- package/cpp/blake3/HybridBlake3.cpp +120 -0
- package/cpp/blake3/HybridBlake3.hpp +35 -0
- package/cpp/certificate/HybridCertificate.cpp +42 -0
- package/cpp/certificate/HybridCertificate.hpp +16 -0
- package/cpp/cipher/CCMCipher.cpp +211 -0
- package/cpp/cipher/CCMCipher.hpp +24 -0
- package/cpp/cipher/ChaCha20Cipher.cpp +91 -0
- package/cpp/cipher/ChaCha20Cipher.hpp +23 -0
- package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +175 -0
- package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +27 -0
- package/cpp/cipher/GCMCipher.cpp +65 -0
- package/cpp/cipher/GCMCipher.hpp +14 -0
- package/cpp/cipher/HybridCipher.cpp +403 -0
- package/cpp/cipher/HybridCipher.hpp +90 -0
- package/cpp/cipher/HybridCipherFactory.hpp +119 -0
- package/cpp/cipher/HybridRsaCipher.cpp +477 -0
- package/cpp/cipher/HybridRsaCipher.hpp +33 -0
- package/cpp/cipher/OCBCipher.cpp +55 -0
- package/cpp/cipher/OCBCipher.hpp +19 -0
- package/cpp/cipher/XChaCha20Poly1305Cipher.cpp +158 -0
- package/cpp/cipher/XChaCha20Poly1305Cipher.hpp +42 -0
- package/cpp/cipher/XSalsa20Cipher.cpp +127 -0
- package/cpp/cipher/XSalsa20Cipher.hpp +55 -0
- package/cpp/cipher/XSalsa20Poly1305Cipher.cpp +138 -0
- package/cpp/cipher/XSalsa20Poly1305Cipher.hpp +41 -0
- package/cpp/dh/HybridDhKeyPair.cpp +179 -0
- package/cpp/dh/HybridDhKeyPair.hpp +37 -0
- package/cpp/dh/HybridDiffieHellman.cpp +482 -0
- package/cpp/dh/HybridDiffieHellman.hpp +42 -0
- package/cpp/dsa/HybridDsaKeyPair.cpp +128 -0
- package/cpp/dsa/HybridDsaKeyPair.hpp +32 -0
- package/cpp/ec/HybridEcKeyPair.cpp +481 -0
- package/cpp/ec/HybridEcKeyPair.hpp +45 -0
- package/cpp/ecdh/HybridECDH.cpp +251 -0
- package/cpp/ecdh/HybridECDH.hpp +43 -0
- package/cpp/ed25519/HybridEdKeyPair.cpp +360 -0
- package/cpp/ed25519/HybridEdKeyPair.hpp +67 -0
- package/cpp/hash/HybridHash.cpp +190 -0
- package/cpp/hash/HybridHash.hpp +43 -0
- package/cpp/hkdf/HybridHkdf.cpp +115 -0
- package/cpp/hkdf/HybridHkdf.hpp +29 -0
- package/cpp/hmac/HybridHmac.cpp +102 -0
- package/cpp/hmac/HybridHmac.hpp +32 -0
- package/cpp/keys/HybridKeyObjectHandle.cpp +1519 -0
- package/cpp/keys/HybridKeyObjectHandle.hpp +78 -0
- package/cpp/keys/KeyObjectData.cpp +298 -0
- package/cpp/keys/KeyObjectData.hpp +73 -0
- package/cpp/keys/node.h +5 -0
- package/cpp/kmac/HybridKmac.cpp +83 -0
- package/cpp/kmac/HybridKmac.hpp +31 -0
- package/cpp/mldsa/HybridMlDsaKeyPair.cpp +243 -0
- package/cpp/mldsa/HybridMlDsaKeyPair.hpp +49 -0
- package/cpp/mlkem/HybridMlKemKeyPair.cpp +315 -0
- package/cpp/mlkem/HybridMlKemKeyPair.hpp +48 -0
- package/cpp/pbkdf2/HybridPbkdf2.cpp +50 -0
- package/cpp/pbkdf2/HybridPbkdf2.hpp +24 -0
- package/cpp/prime/HybridPrime.cpp +81 -0
- package/cpp/prime/HybridPrime.hpp +20 -0
- package/cpp/random/HybridRandom.cpp +48 -0
- package/cpp/random/HybridRandom.hpp +32 -0
- package/cpp/rsa/HybridRsaKeyPair.cpp +151 -0
- package/cpp/rsa/HybridRsaKeyPair.hpp +40 -0
- package/cpp/scrypt/HybridScrypt.cpp +64 -0
- package/cpp/scrypt/HybridScrypt.hpp +28 -0
- package/cpp/sign/HybridSignHandle.cpp +241 -0
- package/cpp/sign/HybridSignHandle.hpp +36 -0
- package/cpp/sign/HybridVerifyHandle.cpp +207 -0
- package/cpp/sign/HybridVerifyHandle.hpp +36 -0
- package/cpp/sign/SignUtils.hpp +91 -0
- package/cpp/slhdsa/HybridSlhDsaKeyPair.cpp +245 -0
- package/cpp/slhdsa/HybridSlhDsaKeyPair.hpp +48 -0
- package/cpp/turboshake/HybridTurboShake.cpp +379 -0
- package/cpp/turboshake/HybridTurboShake.hpp +28 -0
- package/cpp/utils/HybridUtils.cpp +399 -0
- package/cpp/utils/HybridUtils.hpp +28 -0
- package/cpp/utils/Macros.hpp +68 -0
- package/cpp/utils/QuickCryptoUtils.cpp +44 -0
- package/cpp/utils/QuickCryptoUtils.hpp +186 -0
- package/cpp/utils/base64.h +309 -0
- package/cpp/x509/HybridX509Certificate.cpp +174 -0
- package/cpp/x509/HybridX509Certificate.hpp +51 -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 +228 -0
- package/deps/blake3/c/README.md +403 -0
- package/deps/blake3/c/blake3.c +651 -0
- package/deps/blake3/c/blake3.h +86 -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 +367 -0
- package/deps/blake3/c/blake3_portable.c +160 -0
- package/deps/fastpbkdf2/fastpbkdf2.c +356 -0
- package/deps/fastpbkdf2/fastpbkdf2.h +68 -0
- package/deps/ncrypto/LICENSE +21 -0
- package/deps/ncrypto/README.md +18 -0
- package/deps/ncrypto/include/dh-primes.h +67 -0
- package/deps/ncrypto/include/ncrypto/aead.h +137 -0
- package/deps/ncrypto/include/ncrypto/version.h +14 -0
- package/deps/ncrypto/include/ncrypto.h +1759 -0
- package/deps/ncrypto/src/aead.cpp +302 -0
- package/deps/ncrypto/src/engine.cpp +93 -0
- package/deps/ncrypto/src/ncrypto.cpp +5426 -0
- package/deps/simdutf/LICENSE-APACHE +201 -0
- package/deps/simdutf/LICENSE-MIT +18 -0
- package/deps/simdutf/README.md +2782 -0
- package/deps/simdutf/include/simdutf/avx512.h +79 -0
- package/deps/simdutf/include/simdutf/base64_implementation.h +158 -0
- package/deps/simdutf/include/simdutf/base64_tables.h +887 -0
- package/deps/simdutf/include/simdutf/common_defs.h +186 -0
- package/deps/simdutf/include/simdutf/compiler_check.h +50 -0
- package/deps/simdutf/include/simdutf/constexpr_ptr.h +138 -0
- package/deps/simdutf/include/simdutf/encoding_types.h +189 -0
- package/deps/simdutf/include/simdutf/error.h +126 -0
- package/deps/simdutf/include/simdutf/implementation.h +7081 -0
- package/deps/simdutf/include/simdutf/internal/isadetection.h +325 -0
- package/deps/simdutf/include/simdutf/portability.h +285 -0
- package/deps/simdutf/include/simdutf/scalar/ascii.h +86 -0
- package/deps/simdutf/include/simdutf/scalar/atomic_util.h +105 -0
- package/deps/simdutf/include/simdutf/scalar/base64.h +911 -0
- package/deps/simdutf/include/simdutf/scalar/latin1.h +26 -0
- package/deps/simdutf/include/simdutf/scalar/latin1_to_utf16/latin1_to_utf16.h +52 -0
- package/deps/simdutf/include/simdutf/scalar/latin1_to_utf32/latin1_to_utf32.h +27 -0
- package/deps/simdutf/include/simdutf/scalar/latin1_to_utf8/latin1_to_utf8.h +191 -0
- package/deps/simdutf/include/simdutf/scalar/swap_bytes.h +35 -0
- package/deps/simdutf/include/simdutf/scalar/utf16.h +226 -0
- package/deps/simdutf/include/simdutf/scalar/utf16_to_latin1/utf16_to_latin1.h +108 -0
- package/deps/simdutf/include/simdutf/scalar/utf16_to_latin1/valid_utf16_to_latin1.h +40 -0
- package/deps/simdutf/include/simdutf/scalar/utf16_to_utf32/utf16_to_utf32.h +86 -0
- package/deps/simdutf/include/simdutf/scalar/utf16_to_utf32/valid_utf16_to_utf32.h +44 -0
- package/deps/simdutf/include/simdutf/scalar/utf16_to_utf8/utf16_to_utf8.h +295 -0
- package/deps/simdutf/include/simdutf/scalar/utf16_to_utf8/valid_utf16_to_utf8.h +91 -0
- package/deps/simdutf/include/simdutf/scalar/utf32.h +82 -0
- package/deps/simdutf/include/simdutf/scalar/utf32_to_latin1/utf32_to_latin1.h +68 -0
- package/deps/simdutf/include/simdutf/scalar/utf32_to_latin1/valid_utf32_to_latin1.h +67 -0
- package/deps/simdutf/include/simdutf/scalar/utf32_to_utf16/utf32_to_utf16.h +84 -0
- package/deps/simdutf/include/simdutf/scalar/utf32_to_utf16/valid_utf32_to_utf16.h +44 -0
- package/deps/simdutf/include/simdutf/scalar/utf32_to_utf8/utf32_to_utf8.h +142 -0
- package/deps/simdutf/include/simdutf/scalar/utf32_to_utf8/valid_utf32_to_utf8.h +72 -0
- package/deps/simdutf/include/simdutf/scalar/utf8.h +326 -0
- package/deps/simdutf/include/simdutf/scalar/utf8_to_latin1/utf8_to_latin1.h +225 -0
- package/deps/simdutf/include/simdutf/scalar/utf8_to_latin1/valid_utf8_to_latin1.h +87 -0
- package/deps/simdutf/include/simdutf/scalar/utf8_to_utf16/utf8_to_utf16.h +342 -0
- package/deps/simdutf/include/simdutf/scalar/utf8_to_utf16/valid_utf8_to_utf16.h +106 -0
- package/deps/simdutf/include/simdutf/scalar/utf8_to_utf32/utf8_to_utf32.h +299 -0
- package/deps/simdutf/include/simdutf/scalar/utf8_to_utf32/valid_utf8_to_utf32.h +83 -0
- package/deps/simdutf/include/simdutf/simdutf_version.h +26 -0
- package/deps/simdutf/include/simdutf.h +26 -0
- package/deps/simdutf/include/simdutf_c.h +342 -0
- package/deps/simdutf/src/arm64/arm_base64.cpp +791 -0
- package/deps/simdutf/src/arm64/arm_convert_latin1_to_utf16.cpp +24 -0
- package/deps/simdutf/src/arm64/arm_convert_latin1_to_utf32.cpp +24 -0
- package/deps/simdutf/src/arm64/arm_convert_latin1_to_utf8.cpp +70 -0
- package/deps/simdutf/src/arm64/arm_convert_utf16_to_latin1.cpp +61 -0
- package/deps/simdutf/src/arm64/arm_convert_utf16_to_utf32.cpp +185 -0
- package/deps/simdutf/src/arm64/arm_convert_utf16_to_utf8.cpp +780 -0
- package/deps/simdutf/src/arm64/arm_convert_utf32_to_latin1.cpp +60 -0
- package/deps/simdutf/src/arm64/arm_convert_utf32_to_utf16.cpp +208 -0
- package/deps/simdutf/src/arm64/arm_convert_utf32_to_utf8.cpp +505 -0
- package/deps/simdutf/src/arm64/arm_convert_utf8_to_latin1.cpp +69 -0
- package/deps/simdutf/src/arm64/arm_convert_utf8_to_utf16.cpp +313 -0
- package/deps/simdutf/src/arm64/arm_convert_utf8_to_utf32.cpp +179 -0
- package/deps/simdutf/src/arm64/arm_find.cpp +199 -0
- package/deps/simdutf/src/arm64/arm_utf16fix.cpp +185 -0
- package/deps/simdutf/src/arm64/arm_validate_utf16.cpp +165 -0
- package/deps/simdutf/src/arm64/arm_validate_utf32le.cpp +65 -0
- package/deps/simdutf/src/arm64/implementation.cpp +1442 -0
- package/deps/simdutf/src/encoding_types.cpp +67 -0
- package/deps/simdutf/src/error.cpp +3 -0
- package/deps/simdutf/src/fallback/implementation.cpp +589 -0
- package/deps/simdutf/src/generic/ascii_validation.h +50 -0
- package/deps/simdutf/src/generic/base64.h +233 -0
- package/deps/simdutf/src/generic/base64lengths.h +63 -0
- package/deps/simdutf/src/generic/buf_block_reader.h +109 -0
- package/deps/simdutf/src/generic/find.h +75 -0
- package/deps/simdutf/src/generic/utf16/change_endianness.h +24 -0
- package/deps/simdutf/src/generic/utf16/count_code_points_bytemask.h +58 -0
- package/deps/simdutf/src/generic/utf16/to_well_formed.h +93 -0
- package/deps/simdutf/src/generic/utf16/utf32_length_from_utf16.h +15 -0
- package/deps/simdutf/src/generic/utf16/utf8_length_from_utf16.h +35 -0
- package/deps/simdutf/src/generic/utf16/utf8_length_from_utf16_bytemask.h +199 -0
- package/deps/simdutf/src/generic/utf16.h +73 -0
- package/deps/simdutf/src/generic/utf32.h +136 -0
- package/deps/simdutf/src/generic/utf8/utf16_length_from_utf8_bytemask.h +53 -0
- package/deps/simdutf/src/generic/utf8.h +92 -0
- package/deps/simdutf/src/generic/utf8_to_latin1/utf8_to_latin1.h +316 -0
- package/deps/simdutf/src/generic/utf8_to_latin1/valid_utf8_to_latin1.h +78 -0
- package/deps/simdutf/src/generic/utf8_to_utf16/utf8_to_utf16.h +332 -0
- package/deps/simdutf/src/generic/utf8_to_utf16/valid_utf8_to_utf16.h +74 -0
- package/deps/simdutf/src/generic/utf8_to_utf32/utf8_to_utf32.h +318 -0
- package/deps/simdutf/src/generic/utf8_to_utf32/valid_utf8_to_utf32.h +42 -0
- package/deps/simdutf/src/generic/utf8_validation/utf8_lookup4_algorithm.h +223 -0
- package/deps/simdutf/src/generic/utf8_validation/utf8_validator.h +84 -0
- package/deps/simdutf/src/generic/validate_utf16.h +164 -0
- package/deps/simdutf/src/generic/validate_utf32.h +99 -0
- package/deps/simdutf/src/haswell/avx2_base64.cpp +837 -0
- package/deps/simdutf/src/haswell/avx2_convert_latin1_to_utf16.cpp +28 -0
- package/deps/simdutf/src/haswell/avx2_convert_latin1_to_utf32.cpp +20 -0
- package/deps/simdutf/src/haswell/avx2_convert_latin1_to_utf8.cpp +83 -0
- package/deps/simdutf/src/haswell/avx2_convert_utf16_to_latin1.cpp +83 -0
- package/deps/simdutf/src/haswell/avx2_convert_utf16_to_utf32.cpp +210 -0
- package/deps/simdutf/src/haswell/avx2_convert_utf16_to_utf8.cpp +602 -0
- package/deps/simdutf/src/haswell/avx2_convert_utf32_to_latin1.cpp +116 -0
- package/deps/simdutf/src/haswell/avx2_convert_utf32_to_utf16.cpp +164 -0
- package/deps/simdutf/src/haswell/avx2_convert_utf32_to_utf8.cpp +569 -0
- package/deps/simdutf/src/haswell/avx2_convert_utf8_to_latin1.cpp +60 -0
- package/deps/simdutf/src/haswell/avx2_convert_utf8_to_utf16.cpp +195 -0
- package/deps/simdutf/src/haswell/avx2_convert_utf8_to_utf32.cpp +135 -0
- package/deps/simdutf/src/haswell/avx2_utf16fix.cpp +173 -0
- package/deps/simdutf/src/haswell/avx2_validate_utf16.cpp +17 -0
- package/deps/simdutf/src/haswell/implementation.cpp +1447 -0
- package/deps/simdutf/src/icelake/icelake_ascii_validation.inl.cpp +19 -0
- package/deps/simdutf/src/icelake/icelake_base64.inl.cpp +630 -0
- package/deps/simdutf/src/icelake/icelake_common.inl.cpp +37 -0
- package/deps/simdutf/src/icelake/icelake_convert_latin1_to_utf16.inl.cpp +36 -0
- package/deps/simdutf/src/icelake/icelake_convert_latin1_to_utf32.inl.cpp +23 -0
- package/deps/simdutf/src/icelake/icelake_convert_latin1_to_utf8.inl.cpp +107 -0
- package/deps/simdutf/src/icelake/icelake_convert_utf16_to_latin1.inl.cpp +103 -0
- package/deps/simdutf/src/icelake/icelake_convert_utf16_to_utf32.inl.cpp +136 -0
- package/deps/simdutf/src/icelake/icelake_convert_utf16_to_utf8.inl.cpp +206 -0
- package/deps/simdutf/src/icelake/icelake_convert_utf32_to_latin1.inl.cpp +74 -0
- package/deps/simdutf/src/icelake/icelake_convert_utf32_to_utf16.inl.cpp +338 -0
- package/deps/simdutf/src/icelake/icelake_convert_utf32_to_utf8.inl.cpp +574 -0
- package/deps/simdutf/src/icelake/icelake_convert_utf8_to_latin1.inl.cpp +104 -0
- package/deps/simdutf/src/icelake/icelake_convert_utf8_to_utf16.inl.cpp +75 -0
- package/deps/simdutf/src/icelake/icelake_convert_valid_utf8_to_latin1.inl.cpp +69 -0
- package/deps/simdutf/src/icelake/icelake_find.inl.cpp +146 -0
- package/deps/simdutf/src/icelake/icelake_from_utf8.inl.cpp +266 -0
- package/deps/simdutf/src/icelake/icelake_from_valid_utf8.inl.cpp +136 -0
- package/deps/simdutf/src/icelake/icelake_macros.inl.cpp +143 -0
- package/deps/simdutf/src/icelake/icelake_utf16fix.cpp +138 -0
- package/deps/simdutf/src/icelake/icelake_utf32_validation.inl.cpp +63 -0
- package/deps/simdutf/src/icelake/icelake_utf8_common.inl.cpp +753 -0
- package/deps/simdutf/src/icelake/icelake_utf8_length_from_utf16.inl.cpp +269 -0
- package/deps/simdutf/src/icelake/icelake_utf8_validation.inl.cpp +116 -0
- package/deps/simdutf/src/icelake/implementation.cpp +1903 -0
- package/deps/simdutf/src/implementation.cpp +2526 -0
- package/deps/simdutf/src/lasx/implementation.cpp +1531 -0
- package/deps/simdutf/src/lasx/lasx_base64.cpp +695 -0
- package/deps/simdutf/src/lasx/lasx_convert_latin1_to_utf16.cpp +76 -0
- package/deps/simdutf/src/lasx/lasx_convert_latin1_to_utf32.cpp +55 -0
- package/deps/simdutf/src/lasx/lasx_convert_latin1_to_utf8.cpp +65 -0
- package/deps/simdutf/src/lasx/lasx_convert_utf16_to_latin1.cpp +64 -0
- package/deps/simdutf/src/lasx/lasx_convert_utf16_to_utf32.cpp +183 -0
- package/deps/simdutf/src/lasx/lasx_convert_utf16_to_utf8.cpp +550 -0
- package/deps/simdutf/src/lasx/lasx_convert_utf32_to_latin1.cpp +73 -0
- package/deps/simdutf/src/lasx/lasx_convert_utf32_to_utf16.cpp +218 -0
- package/deps/simdutf/src/lasx/lasx_convert_utf32_to_utf8.cpp +589 -0
- package/deps/simdutf/src/lasx/lasx_convert_utf8_to_latin1.cpp +72 -0
- package/deps/simdutf/src/lasx/lasx_convert_utf8_to_utf16.cpp +296 -0
- package/deps/simdutf/src/lasx/lasx_convert_utf8_to_utf32.cpp +190 -0
- package/deps/simdutf/src/lasx/lasx_find.cpp +64 -0
- package/deps/simdutf/src/lasx/lasx_validate_utf16.cpp +13 -0
- package/deps/simdutf/src/lasx/lasx_validate_utf32le.cpp +84 -0
- package/deps/simdutf/src/lsx/implementation.cpp +1417 -0
- package/deps/simdutf/src/lsx/lsx_base64.cpp +675 -0
- package/deps/simdutf/src/lsx/lsx_convert_latin1_to_utf16.cpp +39 -0
- package/deps/simdutf/src/lsx/lsx_convert_latin1_to_utf32.cpp +27 -0
- package/deps/simdutf/src/lsx/lsx_convert_latin1_to_utf8.cpp +56 -0
- package/deps/simdutf/src/lsx/lsx_convert_utf16_to_latin1.cpp +64 -0
- package/deps/simdutf/src/lsx/lsx_convert_utf16_to_utf32.cpp +133 -0
- package/deps/simdutf/src/lsx/lsx_convert_utf16_to_utf8.cpp +518 -0
- package/deps/simdutf/src/lsx/lsx_convert_utf32_to_latin1.cpp +66 -0
- package/deps/simdutf/src/lsx/lsx_convert_utf32_to_utf16.cpp +155 -0
- package/deps/simdutf/src/lsx/lsx_convert_utf32_to_utf8.cpp +459 -0
- package/deps/simdutf/src/lsx/lsx_convert_utf8_to_latin1.cpp +75 -0
- package/deps/simdutf/src/lsx/lsx_convert_utf8_to_utf16.cpp +291 -0
- package/deps/simdutf/src/lsx/lsx_convert_utf8_to_utf32.cpp +179 -0
- package/deps/simdutf/src/lsx/lsx_find.cpp +60 -0
- package/deps/simdutf/src/lsx/lsx_validate_utf16.cpp +13 -0
- package/deps/simdutf/src/lsx/lsx_validate_utf32le.cpp +68 -0
- package/deps/simdutf/src/ppc64/implementation.cpp +992 -0
- package/deps/simdutf/src/ppc64/ppc64_base64.cpp +480 -0
- package/deps/simdutf/src/ppc64/ppc64_base64_internal_tests.cpp +401 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_latin1_to_utf16.cpp +12 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_latin1_to_utf32.cpp +12 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_latin1_to_utf8.cpp +149 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_utf16_to_latin1.cpp +67 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_utf16_to_utf32.cpp +87 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_utf16_to_utf8.cpp +296 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_utf32_to_latin1.cpp +57 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_utf32_to_utf16.cpp +117 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_utf32_to_utf8.cpp +166 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_utf8_to_latin1.cpp +69 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_utf8_to_utf16.cpp +211 -0
- package/deps/simdutf/src/ppc64/ppc64_convert_utf8_to_utf32.cpp +153 -0
- package/deps/simdutf/src/ppc64/ppc64_utf16_to_utf8_tables.h +1011 -0
- package/deps/simdutf/src/ppc64/ppc64_utf8_length_from_latin1.cpp +37 -0
- package/deps/simdutf/src/ppc64/ppc64_validate_utf16.cpp +19 -0
- package/deps/simdutf/src/ppc64/templates.cpp +91 -0
- package/deps/simdutf/src/rvv/implementation.cpp +138 -0
- package/deps/simdutf/src/rvv/rvv_find.cpp +27 -0
- package/deps/simdutf/src/rvv/rvv_helpers.inl.cpp +23 -0
- package/deps/simdutf/src/rvv/rvv_latin1_to.inl.cpp +71 -0
- package/deps/simdutf/src/rvv/rvv_length_from.inl.cpp +164 -0
- package/deps/simdutf/src/rvv/rvv_utf16_to.inl.cpp +399 -0
- package/deps/simdutf/src/rvv/rvv_utf16fix.cpp +110 -0
- package/deps/simdutf/src/rvv/rvv_utf32_to.inl.cpp +307 -0
- package/deps/simdutf/src/rvv/rvv_utf8_to.inl.cpp +435 -0
- package/deps/simdutf/src/rvv/rvv_validate.inl.cpp +275 -0
- package/deps/simdutf/src/simdutf/arm64/begin.h +2 -0
- package/deps/simdutf/src/simdutf/arm64/bitmanipulation.h +34 -0
- package/deps/simdutf/src/simdutf/arm64/end.h +2 -0
- package/deps/simdutf/src/simdutf/arm64/implementation.h +307 -0
- package/deps/simdutf/src/simdutf/arm64/intrinsics.h +10 -0
- package/deps/simdutf/src/simdutf/arm64/simd.h +547 -0
- package/deps/simdutf/src/simdutf/arm64/simd16-inl.h +403 -0
- package/deps/simdutf/src/simdutf/arm64/simd32-inl.h +129 -0
- package/deps/simdutf/src/simdutf/arm64/simd64-inl.h +28 -0
- package/deps/simdutf/src/simdutf/arm64.h +43 -0
- package/deps/simdutf/src/simdutf/fallback/begin.h +1 -0
- package/deps/simdutf/src/simdutf/fallback/bitmanipulation.h +13 -0
- package/deps/simdutf/src/simdutf/fallback/end.h +1 -0
- package/deps/simdutf/src/simdutf/fallback/implementation.h +331 -0
- package/deps/simdutf/src/simdutf/fallback.h +42 -0
- package/deps/simdutf/src/simdutf/haswell/begin.h +15 -0
- package/deps/simdutf/src/simdutf/haswell/bitmanipulation.h +35 -0
- package/deps/simdutf/src/simdutf/haswell/end.h +13 -0
- package/deps/simdutf/src/simdutf/haswell/implementation.h +338 -0
- package/deps/simdutf/src/simdutf/haswell/intrinsics.h +67 -0
- package/deps/simdutf/src/simdutf/haswell/simd.h +363 -0
- package/deps/simdutf/src/simdutf/haswell/simd16-inl.h +261 -0
- package/deps/simdutf/src/simdutf/haswell/simd32-inl.h +111 -0
- package/deps/simdutf/src/simdutf/haswell/simd64-inl.h +34 -0
- package/deps/simdutf/src/simdutf/haswell.h +63 -0
- package/deps/simdutf/src/simdutf/icelake/begin.h +14 -0
- package/deps/simdutf/src/simdutf/icelake/bitmanipulation.h +44 -0
- package/deps/simdutf/src/simdutf/icelake/end.h +12 -0
- package/deps/simdutf/src/simdutf/icelake/implementation.h +346 -0
- package/deps/simdutf/src/simdutf/icelake/intrinsics.h +138 -0
- package/deps/simdutf/src/simdutf/icelake/simd.h +17 -0
- package/deps/simdutf/src/simdutf/icelake/simd16-inl.h +90 -0
- package/deps/simdutf/src/simdutf/icelake/simd32-inl.h +47 -0
- package/deps/simdutf/src/simdutf/icelake.h +81 -0
- package/deps/simdutf/src/simdutf/lasx/begin.h +8 -0
- package/deps/simdutf/src/simdutf/lasx/bitmanipulation.h +25 -0
- package/deps/simdutf/src/simdutf/lasx/end.h +8 -0
- package/deps/simdutf/src/simdutf/lasx/implementation.h +310 -0
- package/deps/simdutf/src/simdutf/lasx/intrinsics.h +319 -0
- package/deps/simdutf/src/simdutf/lasx/simd.h +551 -0
- package/deps/simdutf/src/simdutf/lasx/simd16-inl.h +234 -0
- package/deps/simdutf/src/simdutf/lasx/simd32-inl.h +74 -0
- package/deps/simdutf/src/simdutf/lasx/simd64-inl.h +52 -0
- package/deps/simdutf/src/simdutf/lasx.h +49 -0
- package/deps/simdutf/src/simdutf/lsx/begin.h +2 -0
- package/deps/simdutf/src/simdutf/lsx/bitmanipulation.h +25 -0
- package/deps/simdutf/src/simdutf/lsx/end.h +2 -0
- package/deps/simdutf/src/simdutf/lsx/implementation.h +309 -0
- package/deps/simdutf/src/simdutf/lsx/intrinsics.h +196 -0
- package/deps/simdutf/src/simdutf/lsx/simd.h +421 -0
- package/deps/simdutf/src/simdutf/lsx/simd16-inl.h +242 -0
- package/deps/simdutf/src/simdutf/lsx/simd32-inl.h +69 -0
- package/deps/simdutf/src/simdutf/lsx/simd64-inl.h +50 -0
- package/deps/simdutf/src/simdutf/lsx.h +52 -0
- package/deps/simdutf/src/simdutf/ppc64/begin.h +1 -0
- package/deps/simdutf/src/simdutf/ppc64/bitmanipulation.h +29 -0
- package/deps/simdutf/src/simdutf/ppc64/end.h +1 -0
- package/deps/simdutf/src/simdutf/ppc64/implementation.h +348 -0
- package/deps/simdutf/src/simdutf/ppc64/intrinsics.h +19 -0
- package/deps/simdutf/src/simdutf/ppc64/simd.h +177 -0
- package/deps/simdutf/src/simdutf/ppc64/simd16-inl.h +327 -0
- package/deps/simdutf/src/simdutf/ppc64/simd32-inl.h +247 -0
- package/deps/simdutf/src/simdutf/ppc64/simd8-inl.h +618 -0
- package/deps/simdutf/src/simdutf/ppc64.h +40 -0
- package/deps/simdutf/src/simdutf/rvv/begin.h +7 -0
- package/deps/simdutf/src/simdutf/rvv/end.h +7 -0
- package/deps/simdutf/src/simdutf/rvv/implementation.h +321 -0
- package/deps/simdutf/src/simdutf/rvv/intrinsics.h +131 -0
- package/deps/simdutf/src/simdutf/rvv.h +41 -0
- package/deps/simdutf/src/simdutf/westmere/begin.h +8 -0
- package/deps/simdutf/src/simdutf/westmere/bitmanipulation.h +37 -0
- package/deps/simdutf/src/simdutf/westmere/end.h +8 -0
- package/deps/simdutf/src/simdutf/westmere/implementation.h +338 -0
- package/deps/simdutf/src/simdutf/westmere/intrinsics.h +38 -0
- package/deps/simdutf/src/simdutf/westmere/simd.h +379 -0
- package/deps/simdutf/src/simdutf/westmere/simd16-inl.h +242 -0
- package/deps/simdutf/src/simdutf/westmere/simd32-inl.h +151 -0
- package/deps/simdutf/src/simdutf/westmere/simd64-inl.h +33 -0
- package/deps/simdutf/src/simdutf/westmere.h +59 -0
- package/deps/simdutf/src/simdutf.cpp +152 -0
- package/deps/simdutf/src/simdutf_c.cpp +525 -0
- package/deps/simdutf/src/tables/utf16_to_utf8_tables.h +768 -0
- package/deps/simdutf/src/tables/utf32_to_utf16_tables.h +53 -0
- package/deps/simdutf/src/tables/utf8_to_utf16_tables.h +826 -0
- package/deps/simdutf/src/westmere/implementation.cpp +1479 -0
- package/deps/simdutf/src/westmere/internal/loader.cpp +7 -0
- package/deps/simdutf/src/westmere/internal/write_v_u16_11bits_to_utf8.cpp +66 -0
- package/deps/simdutf/src/westmere/sse_base64.cpp +672 -0
- package/deps/simdutf/src/westmere/sse_convert_latin1_to_utf16.cpp +21 -0
- package/deps/simdutf/src/westmere/sse_convert_latin1_to_utf32.cpp +31 -0
- package/deps/simdutf/src/westmere/sse_convert_latin1_to_utf8.cpp +71 -0
- package/deps/simdutf/src/westmere/sse_convert_utf16_to_latin1.cpp +70 -0
- package/deps/simdutf/src/westmere/sse_convert_utf16_to_utf32.cpp +206 -0
- package/deps/simdutf/src/westmere/sse_convert_utf16_to_utf8.cpp +504 -0
- package/deps/simdutf/src/westmere/sse_convert_utf32_to_latin1.cpp +82 -0
- package/deps/simdutf/src/westmere/sse_convert_utf32_to_utf16.cpp +209 -0
- package/deps/simdutf/src/westmere/sse_convert_utf32_to_utf8.cpp +589 -0
- package/deps/simdutf/src/westmere/sse_convert_utf8_to_latin1.cpp +58 -0
- package/deps/simdutf/src/westmere/sse_convert_utf8_to_utf16.cpp +197 -0
- package/deps/simdutf/src/westmere/sse_convert_utf8_to_utf32.cpp +141 -0
- package/deps/simdutf/src/westmere/sse_utf16fix.cpp +82 -0
- package/deps/simdutf/src/westmere/sse_validate_utf16.cpp +17 -0
- package/jest/index.js +16 -0
- package/lib/commonjs/argon2.js +88 -0
- package/lib/commonjs/argon2.js.map +1 -0
- package/lib/commonjs/blake3.js +99 -0
- package/lib/commonjs/blake3.js.map +1 -0
- package/lib/commonjs/certificate.js +35 -0
- package/lib/commonjs/certificate.js.map +1 -0
- package/lib/commonjs/cipher.js +299 -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/dh-groups.js +29 -0
- package/lib/commonjs/dh-groups.js.map +1 -0
- package/lib/commonjs/dhKeyPair.js +112 -0
- package/lib/commonjs/dhKeyPair.js.map +1 -0
- package/lib/commonjs/diffie-hellman.js +151 -0
- package/lib/commonjs/diffie-hellman.js.map +1 -0
- package/lib/commonjs/dsa.js +101 -0
- package/lib/commonjs/dsa.js.map +1 -0
- package/lib/commonjs/ec.js +370 -0
- package/lib/commonjs/ec.js.map +1 -0
- package/lib/commonjs/ecdh.js +109 -0
- package/lib/commonjs/ecdh.js.map +1 -0
- package/lib/commonjs/ed.js +443 -0
- package/lib/commonjs/ed.js.map +1 -0
- 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 +23 -0
- package/lib/commonjs/expo-plugin/withSodiumIos.js.map +1 -0
- package/lib/commonjs/expo-plugin/withXCode.js +109 -0
- package/lib/commonjs/expo-plugin/withXCode.js.map +1 -0
- package/lib/commonjs/hash.js +291 -0
- package/lib/commonjs/hash.js.map +1 -0
- package/lib/commonjs/hkdf.js +178 -0
- package/lib/commonjs/hkdf.js.map +1 -0
- package/lib/commonjs/hmac.js +125 -0
- package/lib/commonjs/hmac.js.map +1 -0
- package/lib/commonjs/index.js +356 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/keys/classes.js +280 -0
- package/lib/commonjs/keys/classes.js.map +1 -0
- package/lib/commonjs/keys/generateKeyPair.js +237 -0
- package/lib/commonjs/keys/generateKeyPair.js.map +1 -0
- package/lib/commonjs/keys/index.js +381 -0
- package/lib/commonjs/keys/index.js.map +1 -0
- package/lib/commonjs/keys/publicCipher.js +171 -0
- package/lib/commonjs/keys/publicCipher.js.map +1 -0
- package/lib/commonjs/keys/signVerify.js +227 -0
- package/lib/commonjs/keys/signVerify.js.map +1 -0
- package/lib/commonjs/keys/utils.js +181 -0
- package/lib/commonjs/keys/utils.js.map +1 -0
- package/lib/commonjs/mldsa.js +69 -0
- package/lib/commonjs/mldsa.js.map +1 -0
- package/lib/commonjs/mlkem.js +219 -0
- package/lib/commonjs/mlkem.js.map +1 -0
- package/lib/commonjs/native-nitro-bridge.js +344 -0
- package/lib/commonjs/nitro-node-shim.js +23 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/pbkdf2.js +106 -0
- package/lib/commonjs/pbkdf2.js.map +1 -0
- package/lib/commonjs/prime.js +84 -0
- package/lib/commonjs/prime.js.map +1 -0
- package/lib/commonjs/random.js +296 -0
- package/lib/commonjs/random.js.map +1 -0
- package/lib/commonjs/rsa.js +213 -0
- package/lib/commonjs/rsa.js.map +1 -0
- package/lib/commonjs/scrypt.js +139 -0
- package/lib/commonjs/scrypt.js.map +1 -0
- package/lib/commonjs/slhdsa.js +70 -0
- package/lib/commonjs/slhdsa.js.map +1 -0
- package/lib/commonjs/specs/argon2.nitro.js +6 -0
- package/lib/commonjs/specs/argon2.nitro.js.map +1 -0
- package/lib/commonjs/specs/blake3.nitro.js +6 -0
- package/lib/commonjs/specs/blake3.nitro.js.map +1 -0
- package/lib/commonjs/specs/certificate.nitro.js +6 -0
- package/lib/commonjs/specs/certificate.nitro.js.map +1 -0
- package/lib/commonjs/specs/cipher.nitro.js +6 -0
- package/lib/commonjs/specs/cipher.nitro.js.map +1 -0
- package/lib/commonjs/specs/dhKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/dhKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/diffie-hellman.nitro.js +6 -0
- package/lib/commonjs/specs/diffie-hellman.nitro.js.map +1 -0
- package/lib/commonjs/specs/dsaKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/dsaKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/ecKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/ecKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/ecdh.nitro.js +6 -0
- package/lib/commonjs/specs/ecdh.nitro.js.map +1 -0
- package/lib/commonjs/specs/edKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/edKeyPair.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/hkdf.nitro.js +6 -0
- package/lib/commonjs/specs/hkdf.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/keyObjectHandle.nitro.js +6 -0
- package/lib/commonjs/specs/keyObjectHandle.nitro.js.map +1 -0
- package/lib/commonjs/specs/kmac.nitro.js +6 -0
- package/lib/commonjs/specs/kmac.nitro.js.map +1 -0
- package/lib/commonjs/specs/mlDsaKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/mlDsaKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/mlKemKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/mlKemKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/pbkdf2.nitro.js +6 -0
- package/lib/commonjs/specs/pbkdf2.nitro.js.map +1 -0
- package/lib/commonjs/specs/prime.nitro.js +6 -0
- package/lib/commonjs/specs/prime.nitro.js.map +1 -0
- package/lib/commonjs/specs/random.nitro.js +6 -0
- package/lib/commonjs/specs/random.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/scrypt.nitro.js +6 -0
- package/lib/commonjs/specs/scrypt.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/specs/slhDsaKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/slhDsaKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/turboshake.nitro.js +6 -0
- package/lib/commonjs/specs/turboshake.nitro.js.map +1 -0
- package/lib/commonjs/specs/utils.nitro.js +6 -0
- package/lib/commonjs/specs/utils.nitro.js.map +1 -0
- package/lib/commonjs/specs/x509certificate.nitro.js +6 -0
- package/lib/commonjs/specs/x509certificate.nitro.js.map +1 -0
- package/lib/commonjs/subtle.js +3211 -0
- package/lib/commonjs/subtle.js.map +1 -0
- package/lib/commonjs/utils/cipher.js +75 -0
- package/lib/commonjs/utils/cipher.js.map +1 -0
- package/lib/commonjs/utils/conversion.js +249 -0
- package/lib/commonjs/utils/conversion.js.map +1 -0
- package/lib/commonjs/utils/errors.js +73 -0
- package/lib/commonjs/utils/errors.js.map +1 -0
- package/lib/commonjs/utils/hashnames.js +122 -0
- package/lib/commonjs/utils/hashnames.js.map +1 -0
- package/lib/commonjs/utils/index.js +83 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/commonjs/utils/noble.js +82 -0
- package/lib/commonjs/utils/noble.js.map +1 -0
- package/lib/commonjs/utils/timingSafeEqual.js +29 -0
- package/lib/commonjs/utils/timingSafeEqual.js.map +1 -0
- package/lib/commonjs/utils/types.js +55 -0
- package/lib/commonjs/utils/types.js.map +1 -0
- package/lib/commonjs/utils/validation.js +144 -0
- package/lib/commonjs/utils/validation.js.map +1 -0
- package/lib/commonjs/x509certificate.js +189 -0
- package/lib/commonjs/x509certificate.js.map +1 -0
- package/lib/module/argon2.js +83 -0
- package/lib/module/argon2.js.map +1 -0
- package/lib/module/blake3.js +91 -0
- package/lib/module/blake3.js.map +1 -0
- package/lib/module/certificate.js +30 -0
- package/lib/module/certificate.js.map +1 -0
- package/lib/module/cipher.js +291 -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/dh-groups.js +25 -0
- package/lib/module/dh-groups.js.map +1 -0
- package/lib/module/dhKeyPair.js +105 -0
- package/lib/module/dhKeyPair.js.map +1 -0
- package/lib/module/diffie-hellman.js +145 -0
- package/lib/module/diffie-hellman.js.map +1 -0
- package/lib/module/dsa.js +94 -0
- package/lib/module/dsa.js.map +1 -0
- package/lib/module/ec.js +358 -0
- package/lib/module/ec.js.map +1 -0
- package/lib/module/ecdh.js +103 -0
- package/lib/module/ecdh.js.map +1 -0
- package/lib/module/ed.js +433 -0
- package/lib/module/ed.js.map +1 -0
- 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 +17 -0
- package/lib/module/expo-plugin/withSodiumIos.js.map +1 -0
- package/lib/module/expo-plugin/withXCode.js +101 -0
- package/lib/module/expo-plugin/withXCode.js.map +1 -0
- package/lib/module/hash.js +282 -0
- package/lib/module/hash.js.map +1 -0
- package/lib/module/hkdf.js +168 -0
- package/lib/module/hkdf.js.map +1 -0
- package/lib/module/hmac.js +120 -0
- package/lib/module/hmac.js.map +1 -0
- package/lib/module/index.js +115 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/keys/classes.js +271 -0
- package/lib/module/keys/classes.js.map +1 -0
- package/lib/module/keys/generateKeyPair.js +231 -0
- package/lib/module/keys/generateKeyPair.js.map +1 -0
- package/lib/module/keys/index.js +246 -0
- package/lib/module/keys/index.js.map +1 -0
- package/lib/module/keys/publicCipher.js +164 -0
- package/lib/module/keys/publicCipher.js.map +1 -0
- package/lib/module/keys/signVerify.js +217 -0
- package/lib/module/keys/signVerify.js.map +1 -0
- package/lib/module/keys/utils.js +170 -0
- package/lib/module/keys/utils.js.map +1 -0
- package/lib/module/mldsa.js +63 -0
- package/lib/module/mldsa.js.map +1 -0
- package/lib/module/mlkem.js +211 -0
- package/lib/module/mlkem.js.map +1 -0
- package/lib/module/pbkdf2.js +100 -0
- package/lib/module/pbkdf2.js.map +1 -0
- package/lib/module/prime.js +77 -0
- package/lib/module/prime.js.map +1 -0
- package/lib/module/random.js +284 -0
- package/lib/module/random.js.map +1 -0
- package/lib/module/rsa.js +205 -0
- package/lib/module/rsa.js.map +1 -0
- package/lib/module/scrypt.js +134 -0
- package/lib/module/scrypt.js.map +1 -0
- package/lib/module/slhdsa.js +64 -0
- package/lib/module/slhdsa.js.map +1 -0
- package/lib/module/specs/argon2.nitro.js +4 -0
- package/lib/module/specs/argon2.nitro.js.map +1 -0
- package/lib/module/specs/blake3.nitro.js +4 -0
- package/lib/module/specs/blake3.nitro.js.map +1 -0
- package/lib/module/specs/certificate.nitro.js +4 -0
- package/lib/module/specs/certificate.nitro.js.map +1 -0
- package/lib/module/specs/cipher.nitro.js +4 -0
- package/lib/module/specs/cipher.nitro.js.map +1 -0
- package/lib/module/specs/dhKeyPair.nitro.js +4 -0
- package/lib/module/specs/dhKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/diffie-hellman.nitro.js +4 -0
- package/lib/module/specs/diffie-hellman.nitro.js.map +1 -0
- package/lib/module/specs/dsaKeyPair.nitro.js +4 -0
- package/lib/module/specs/dsaKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/ecKeyPair.nitro.js +4 -0
- package/lib/module/specs/ecKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/ecdh.nitro.js +4 -0
- package/lib/module/specs/ecdh.nitro.js.map +1 -0
- package/lib/module/specs/edKeyPair.nitro.js +4 -0
- package/lib/module/specs/edKeyPair.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/hkdf.nitro.js +4 -0
- package/lib/module/specs/hkdf.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/keyObjectHandle.nitro.js +4 -0
- package/lib/module/specs/keyObjectHandle.nitro.js.map +1 -0
- package/lib/module/specs/kmac.nitro.js +4 -0
- package/lib/module/specs/kmac.nitro.js.map +1 -0
- package/lib/module/specs/mlDsaKeyPair.nitro.js +4 -0
- package/lib/module/specs/mlDsaKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/mlKemKeyPair.nitro.js +4 -0
- package/lib/module/specs/mlKemKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/pbkdf2.nitro.js +4 -0
- package/lib/module/specs/pbkdf2.nitro.js.map +1 -0
- package/lib/module/specs/prime.nitro.js +4 -0
- package/lib/module/specs/prime.nitro.js.map +1 -0
- package/lib/module/specs/random.nitro.js +4 -0
- package/lib/module/specs/random.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/scrypt.nitro.js +4 -0
- package/lib/module/specs/scrypt.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/specs/slhDsaKeyPair.nitro.js +4 -0
- package/lib/module/specs/slhDsaKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/turboshake.nitro.js +4 -0
- package/lib/module/specs/turboshake.nitro.js.map +1 -0
- package/lib/module/specs/utils.nitro.js +4 -0
- package/lib/module/specs/utils.nitro.js.map +1 -0
- package/lib/module/specs/x509certificate.nitro.js +4 -0
- package/lib/module/specs/x509certificate.nitro.js.map +1 -0
- package/lib/module/subtle.js +3205 -0
- package/lib/module/subtle.js.map +1 -0
- package/lib/module/utils/cipher.js +67 -0
- package/lib/module/utils/cipher.js.map +1 -0
- package/lib/module/utils/conversion.js +205 -0
- package/lib/module/utils/conversion.js.map +1 -0
- package/lib/module/utils/errors.js +67 -0
- package/lib/module/utils/errors.js.map +1 -0
- package/lib/module/utils/hashnames.js +120 -0
- package/lib/module/utils/hashnames.js.map +1 -0
- package/lib/module/utils/index.js +10 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/module/utils/noble.js +76 -0
- package/lib/module/utils/noble.js.map +1 -0
- package/lib/module/utils/timingSafeEqual.js +25 -0
- package/lib/module/utils/timingSafeEqual.js.map +1 -0
- package/lib/module/utils/types.js +57 -0
- package/lib/module/utils/types.js.map +1 -0
- package/lib/module/utils/validation.js +131 -0
- package/lib/module/utils/validation.js.map +1 -0
- package/lib/module/x509certificate.js +184 -0
- package/lib/module/x509certificate.js.map +1 -0
- package/lib/typescript/argon2.d.ts +16 -0
- package/lib/typescript/argon2.d.ts.map +1 -0
- package/lib/typescript/blake3.d.ts +33 -0
- package/lib/typescript/blake3.d.ts.map +1 -0
- package/lib/typescript/certificate.d.ts +8 -0
- package/lib/typescript/certificate.d.ts.map +1 -0
- package/lib/typescript/cipher.d.ts +75 -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/dh-groups.d.ts +5 -0
- package/lib/typescript/dh-groups.d.ts.map +1 -0
- package/lib/typescript/dhKeyPair.d.ts +19 -0
- package/lib/typescript/dhKeyPair.d.ts.map +1 -0
- package/lib/typescript/diffie-hellman.d.ts +18 -0
- package/lib/typescript/diffie-hellman.d.ts.map +1 -0
- package/lib/typescript/dsa.d.ts +19 -0
- package/lib/typescript/dsa.d.ts.map +1 -0
- package/lib/typescript/ec.d.ts +24 -0
- package/lib/typescript/ec.d.ts.map +1 -0
- package/lib/typescript/ecdh.d.ts +19 -0
- package/lib/typescript/ecdh.d.ts.map +1 -0
- package/lib/typescript/ed.d.ts +47 -0
- package/lib/typescript/ed.d.ts.map +1 -0
- 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 +23 -0
- package/lib/typescript/expo-plugin/withXCode.d.ts.map +1 -0
- package/lib/typescript/hash.d.ts +126 -0
- package/lib/typescript/hash.d.ts.map +1 -0
- package/lib/typescript/hkdf.d.ts +26 -0
- package/lib/typescript/hkdf.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 +240 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/keys/classes.d.ts +95 -0
- package/lib/typescript/keys/classes.d.ts.map +1 -0
- package/lib/typescript/keys/generateKeyPair.d.ts +17 -0
- package/lib/typescript/keys/generateKeyPair.d.ts.map +1 -0
- package/lib/typescript/keys/index.d.ts +26 -0
- package/lib/typescript/keys/index.d.ts.map +1 -0
- package/lib/typescript/keys/publicCipher.d.ts +23 -0
- package/lib/typescript/keys/publicCipher.d.ts.map +1 -0
- package/lib/typescript/keys/signVerify.d.ts +35 -0
- package/lib/typescript/keys/signVerify.d.ts.map +1 -0
- package/lib/typescript/keys/utils.d.ts +51 -0
- package/lib/typescript/keys/utils.d.ts.map +1 -0
- package/lib/typescript/mldsa.d.ts +18 -0
- package/lib/typescript/mldsa.d.ts.map +1 -0
- package/lib/typescript/mlkem.d.ts +30 -0
- package/lib/typescript/mlkem.d.ts.map +1 -0
- package/lib/typescript/pbkdf2.d.ts +12 -0
- package/lib/typescript/pbkdf2.d.ts.map +1 -0
- package/lib/typescript/prime.d.ts +19 -0
- package/lib/typescript/prime.d.ts.map +1 -0
- package/lib/typescript/random.d.ts +31 -0
- package/lib/typescript/random.d.ts.map +1 -0
- package/lib/typescript/rsa.d.ts +20 -0
- package/lib/typescript/rsa.d.ts.map +1 -0
- package/lib/typescript/scrypt.d.ts +18 -0
- package/lib/typescript/scrypt.d.ts.map +1 -0
- package/lib/typescript/slhdsa.d.ts +19 -0
- package/lib/typescript/slhdsa.d.ts.map +1 -0
- package/lib/typescript/specs/argon2.nitro.d.ts +9 -0
- package/lib/typescript/specs/argon2.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/blake3.nitro.d.ts +15 -0
- package/lib/typescript/specs/blake3.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/certificate.nitro.d.ts +10 -0
- package/lib/typescript/specs/certificate.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/cipher.nitro.d.ts +38 -0
- package/lib/typescript/specs/cipher.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/dhKeyPair.nitro.d.ts +14 -0
- package/lib/typescript/specs/dhKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/diffie-hellman.nitro.d.ts +18 -0
- package/lib/typescript/specs/diffie-hellman.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/dsaKeyPair.nitro.d.ts +13 -0
- package/lib/typescript/specs/dsaKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/ecKeyPair.nitro.d.ts +21 -0
- package/lib/typescript/specs/ecKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/ecdh.nitro.d.ts +15 -0
- package/lib/typescript/specs/ecdh.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/edKeyPair.nitro.d.ts +17 -0
- package/lib/typescript/specs/edKeyPair.nitro.d.ts.map +1 -0
- 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/hkdf.nitro.d.ts +10 -0
- package/lib/typescript/specs/hkdf.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 +27 -0
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/kmac.nitro.d.ts +10 -0
- package/lib/typescript/specs/kmac.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/mlDsaKeyPair.nitro.d.ts +16 -0
- package/lib/typescript/specs/mlDsaKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts +18 -0
- package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/pbkdf2.nitro.d.ts +9 -0
- package/lib/typescript/specs/pbkdf2.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/prime.nitro.d.ts +11 -0
- package/lib/typescript/specs/prime.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/random.nitro.d.ts +9 -0
- package/lib/typescript/specs/random.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/rsaCipher.nitro.d.ts +54 -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/scrypt.nitro.d.ts +9 -0
- package/lib/typescript/specs/scrypt.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/specs/slhDsaKeyPair.nitro.d.ts +16 -0
- package/lib/typescript/specs/slhDsaKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/turboshake.nitro.d.ts +11 -0
- package/lib/typescript/specs/turboshake.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/utils.nitro.d.ts +8 -0
- package/lib/typescript/specs/utils.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/x509certificate.nitro.d.ts +34 -0
- package/lib/typescript/specs/x509certificate.nitro.d.ts.map +1 -0
- package/lib/typescript/subtle.d.ts +33 -0
- package/lib/typescript/subtle.d.ts.map +1 -0
- package/lib/typescript/utils/cipher.d.ts +19 -0
- package/lib/typescript/utils/cipher.d.ts.map +1 -0
- package/lib/typescript/utils/conversion.d.ts +36 -0
- package/lib/typescript/utils/conversion.d.ts.map +1 -0
- package/lib/typescript/utils/errors.d.ts +19 -0
- package/lib/typescript/utils/errors.d.ts.map +1 -0
- package/lib/typescript/utils/hashnames.d.ts +13 -0
- package/lib/typescript/utils/hashnames.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +8 -0
- package/lib/typescript/utils/index.d.ts.map +1 -0
- package/lib/typescript/utils/noble.d.ts +19 -0
- package/lib/typescript/utils/noble.d.ts.map +1 -0
- package/lib/typescript/utils/timingSafeEqual.d.ts +3 -0
- package/lib/typescript/utils/timingSafeEqual.d.ts.map +1 -0
- package/lib/typescript/utils/types.d.ts +314 -0
- package/lib/typescript/utils/types.d.ts.map +1 -0
- package/lib/typescript/utils/validation.d.ts +15 -0
- package/lib/typescript/utils/validation.d.ts.map +1 -0
- package/lib/typescript/x509certificate.d.ts +64 -0
- package/lib/typescript/x509certificate.d.ts.map +1 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +110 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.gradle +27 -0
- package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +334 -0
- package/nitrogen/generated/android/QuickCryptoOnLoad.hpp +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/crypto/QuickCryptoOnLoad.kt +35 -0
- package/nitrogen/generated/ios/QuickCrypto+autolinking.rb +60 -0
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Umbrella.hpp +38 -0
- package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +325 -0
- package/nitrogen/generated/ios/QuickCryptoAutolinking.swift +16 -0
- package/nitrogen/generated/shared/c++/AsymmetricKeyType.hpp +176 -0
- package/nitrogen/generated/shared/c++/CipherArgs.hpp +101 -0
- package/nitrogen/generated/shared/c++/CipherInfo.hpp +104 -0
- package/nitrogen/generated/shared/c++/HkdfMode.hpp +80 -0
- package/nitrogen/generated/shared/c++/HybridArgon2Spec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridArgon2Spec.hpp +66 -0
- package/nitrogen/generated/shared/c++/HybridBlake3Spec.cpp +28 -0
- package/nitrogen/generated/shared/c++/HybridBlake3Spec.hpp +74 -0
- package/nitrogen/generated/shared/c++/HybridCertificateSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridCertificateSpec.hpp +64 -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 +29 -0
- package/nitrogen/generated/shared/c++/HybridCipherSpec.hpp +78 -0
- package/nitrogen/generated/shared/c++/HybridDhKeyPairSpec.cpp +27 -0
- package/nitrogen/generated/shared/c++/HybridDhKeyPairSpec.hpp +69 -0
- package/nitrogen/generated/shared/c++/HybridDiffieHellmanSpec.cpp +31 -0
- package/nitrogen/generated/shared/c++/HybridDiffieHellmanSpec.hpp +72 -0
- package/nitrogen/generated/shared/c++/HybridDsaKeyPairSpec.cpp +26 -0
- package/nitrogen/generated/shared/c++/HybridDsaKeyPairSpec.hpp +68 -0
- package/nitrogen/generated/shared/c++/HybridECDHSpec.cpp +28 -0
- package/nitrogen/generated/shared/c++/HybridECDHSpec.hpp +70 -0
- package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.cpp +30 -0
- package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.hpp +76 -0
- package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.cpp +30 -0
- package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.hpp +74 -0
- package/nitrogen/generated/shared/c++/HybridHashSpec.cpp +26 -0
- package/nitrogen/generated/shared/c++/HybridHashSpec.hpp +74 -0
- package/nitrogen/generated/shared/c++/HybridHkdfSpec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridHkdfSpec.hpp +67 -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 +39 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +107 -0
- package/nitrogen/generated/shared/c++/HybridKmacSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridKmacSpec.hpp +66 -0
- package/nitrogen/generated/shared/c++/HybridMlDsaKeyPairSpec.cpp +29 -0
- package/nitrogen/generated/shared/c++/HybridMlDsaKeyPairSpec.hpp +72 -0
- package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.cpp +31 -0
- package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.hpp +74 -0
- package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.hpp +65 -0
- package/nitrogen/generated/shared/c++/HybridPrimeSpec.cpp +24 -0
- package/nitrogen/generated/shared/c++/HybridPrimeSpec.hpp +67 -0
- package/nitrogen/generated/shared/c++/HybridRandomSpec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridRandomSpec.hpp +64 -0
- package/nitrogen/generated/shared/c++/HybridRsaCipherSpec.cpp +25 -0
- package/nitrogen/generated/shared/c++/HybridRsaCipherSpec.hpp +71 -0
- package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.cpp +29 -0
- package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.hpp +75 -0
- package/nitrogen/generated/shared/c++/HybridScryptSpec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridScryptSpec.hpp +64 -0
- package/nitrogen/generated/shared/c++/HybridSignHandleSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridSignHandleSpec.hpp +69 -0
- package/nitrogen/generated/shared/c++/HybridSlhDsaKeyPairSpec.cpp +29 -0
- package/nitrogen/generated/shared/c++/HybridSlhDsaKeyPairSpec.hpp +72 -0
- package/nitrogen/generated/shared/c++/HybridTurboShakeSpec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridTurboShakeSpec.hpp +70 -0
- package/nitrogen/generated/shared/c++/HybridUtilsSpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridUtilsSpec.hpp +62 -0
- package/nitrogen/generated/shared/c++/HybridVerifyHandleSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridVerifyHandleSpec.hpp +69 -0
- package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.cpp +46 -0
- package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.hpp +96 -0
- package/nitrogen/generated/shared/c++/JWK.hpp +185 -0
- package/nitrogen/generated/shared/c++/JWKkty.hpp +92 -0
- package/nitrogen/generated/shared/c++/JWKuse.hpp +76 -0
- package/nitrogen/generated/shared/c++/KFormatType.hpp +63 -0
- package/nitrogen/generated/shared/c++/KangarooTwelveVariant.hpp +76 -0
- package/nitrogen/generated/shared/c++/KeyDetail.hpp +108 -0
- package/nitrogen/generated/shared/c++/KeyEncoding.hpp +64 -0
- package/nitrogen/generated/shared/c++/KeyObject.hpp +83 -0
- package/nitrogen/generated/shared/c++/KeyType.hpp +63 -0
- package/nitrogen/generated/shared/c++/KeyUsage.hpp +116 -0
- package/nitrogen/generated/shared/c++/NamedCurve.hpp +80 -0
- package/nitrogen/generated/shared/c++/TurboShakeVariant.hpp +76 -0
- package/ohos/binding.gyp +33 -0
- package/ohos/build/Release/quick_crypto.node +0 -0
- package/ohos/quick_crypto_napi.cpp +1316 -0
- package/package.json +158 -4
- package/src/argon2.ts +161 -0
- package/src/blake3.ts +124 -0
- package/src/certificate.ts +41 -0
- package/src/cipher.ts +497 -0
- package/src/constants.ts +32 -0
- package/src/dh-groups.ts +27 -0
- package/src/dhKeyPair.ts +164 -0
- package/src/diffie-hellman.ts +195 -0
- package/src/dsa.ts +146 -0
- package/src/ec.ts +580 -0
- package/src/ecdh.ts +132 -0
- package/src/ed.ts +605 -0
- 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 +25 -0
- package/src/expo-plugin/withXCode.ts +134 -0
- package/src/hash.ts +433 -0
- package/src/hkdf.ts +327 -0
- package/src/hmac.ts +150 -0
- package/src/index.ts +126 -0
- package/src/keys/classes.ts +369 -0
- package/src/keys/generateKeyPair.ts +358 -0
- package/src/keys/index.ts +383 -0
- package/src/keys/publicCipher.ts +256 -0
- package/src/keys/signVerify.ts +329 -0
- package/src/keys/utils.ts +263 -0
- package/src/mldsa.ts +125 -0
- package/src/mlkem.ts +350 -0
- package/src/pbkdf2.ts +183 -0
- package/src/prime.ts +134 -0
- package/src/random.ts +427 -0
- package/src/rsa.ts +333 -0
- package/src/scrypt.ts +201 -0
- package/src/slhdsa.ts +146 -0
- package/src/specs/argon2.nitro.ts +29 -0
- package/src/specs/blake3.nitro.ts +12 -0
- package/src/specs/certificate.nitro.ts +8 -0
- package/src/specs/cipher.nitro.ts +39 -0
- package/src/specs/dhKeyPair.nitro.ts +14 -0
- package/src/specs/diffie-hellman.nitro.ts +16 -0
- package/src/specs/dsaKeyPair.nitro.ts +13 -0
- package/src/specs/ecKeyPair.nitro.ts +40 -0
- package/src/specs/ecdh.nitro.ts +12 -0
- package/src/specs/edKeyPair.nitro.ts +43 -0
- package/src/specs/hash.nitro.ts +10 -0
- package/src/specs/hkdf.nitro.ts +25 -0
- package/src/specs/hmac.nitro.ts +7 -0
- package/src/specs/keyObjectHandle.nitro.ts +56 -0
- package/src/specs/kmac.nitro.ts +12 -0
- package/src/specs/mlDsaKeyPair.nitro.ts +29 -0
- package/src/specs/mlKemKeyPair.nitro.ts +32 -0
- package/src/specs/pbkdf2.nitro.ts +18 -0
- package/src/specs/prime.nitro.ts +18 -0
- package/src/specs/random.nitro.ts +14 -0
- package/src/specs/rsaCipher.nitro.ts +82 -0
- package/src/specs/rsaKeyPair.nitro.ts +33 -0
- package/src/specs/scrypt.nitro.ts +23 -0
- package/src/specs/sign.nitro.ts +31 -0
- package/src/specs/slhDsaKeyPair.nitro.ts +29 -0
- package/src/specs/turboshake.nitro.ts +21 -0
- package/src/specs/utils.nitro.ts +5 -0
- package/src/specs/x509certificate.nitro.ts +38 -0
- package/src/subtle.ts +4545 -0
- package/src/utils/cipher.ts +82 -0
- package/src/utils/conversion.ts +285 -0
- package/src/utils/errors.ts +83 -0
- package/src/utils/hashnames.ts +129 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/noble.ts +85 -0
- package/src/utils/timingSafeEqual.ts +28 -0
- package/src/utils/types.ts +617 -0
- package/src/utils/validation.ts +199 -0
- package/src/x509certificate.ts +276 -0
|
@@ -0,0 +1,3211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Subtle = exports.PQC_SEEDLESS_PKCS8_LENGTHS = void 0;
|
|
7
|
+
exports.isCryptoKeyPair = isCryptoKeyPair;
|
|
8
|
+
exports.subtle = void 0;
|
|
9
|
+
var _safeBuffer = require("safe-buffer");
|
|
10
|
+
var _utils = require("./utils");
|
|
11
|
+
var _reactNativeBuffer = require("@craftzdog/react-native-buffer");
|
|
12
|
+
var _keys = require("./keys");
|
|
13
|
+
var _conversion = require("./utils/conversion");
|
|
14
|
+
var _argon = require("./argon2");
|
|
15
|
+
var _errors = require("./utils/errors");
|
|
16
|
+
var _hashnames = require("./utils/hashnames");
|
|
17
|
+
var _validation = require("./utils/validation");
|
|
18
|
+
var _hash = require("./hash");
|
|
19
|
+
var _reactNativeNitroModules = require("./nitro-node-shim");
|
|
20
|
+
var _pbkdf = require("./pbkdf2");
|
|
21
|
+
var _ec = require("./ec");
|
|
22
|
+
var _rsa = require("./rsa");
|
|
23
|
+
var _random = require("./random");
|
|
24
|
+
var _hmac = require("./hmac");
|
|
25
|
+
var _timingSafeEqual = require("./utils/timingSafeEqual");
|
|
26
|
+
var _signVerify = require("./keys/signVerify");
|
|
27
|
+
var _ed = require("./ed");
|
|
28
|
+
var _mldsa = require("./mldsa");
|
|
29
|
+
var _slhdsa = require("./slhdsa");
|
|
30
|
+
var _mlkem = require("./mlkem");
|
|
31
|
+
var _hkdf = require("./hkdf");
|
|
32
|
+
// Temporary enums that need to be defined
|
|
33
|
+
var KWebCryptoKeyFormat = /*#__PURE__*/function (KWebCryptoKeyFormat) {
|
|
34
|
+
KWebCryptoKeyFormat[KWebCryptoKeyFormat["kWebCryptoKeyFormatRaw"] = 0] = "kWebCryptoKeyFormatRaw";
|
|
35
|
+
KWebCryptoKeyFormat[KWebCryptoKeyFormat["kWebCryptoKeyFormatSPKI"] = 1] = "kWebCryptoKeyFormatSPKI";
|
|
36
|
+
KWebCryptoKeyFormat[KWebCryptoKeyFormat["kWebCryptoKeyFormatPKCS8"] = 2] = "kWebCryptoKeyFormatPKCS8";
|
|
37
|
+
return KWebCryptoKeyFormat;
|
|
38
|
+
}(KWebCryptoKeyFormat || {});
|
|
39
|
+
var CipherOrWrapMode = /*#__PURE__*/function (CipherOrWrapMode) {
|
|
40
|
+
CipherOrWrapMode[CipherOrWrapMode["kWebCryptoCipherEncrypt"] = 0] = "kWebCryptoCipherEncrypt";
|
|
41
|
+
CipherOrWrapMode[CipherOrWrapMode["kWebCryptoCipherDecrypt"] = 1] = "kWebCryptoCipherDecrypt";
|
|
42
|
+
return CipherOrWrapMode;
|
|
43
|
+
}(CipherOrWrapMode || {}); // Placeholder functions that need to be implemented
|
|
44
|
+
function hasAnyNotIn(usages, allowed) {
|
|
45
|
+
return usages.some(usage => !allowed.includes(usage));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Mirrors webidl.requiredArguments. Node throws TypeError when a SubtleCrypto
|
|
49
|
+
// method is called with fewer than the spec-required number of arguments
|
|
50
|
+
// (webcrypto.js:866 etc.); we relied on TypeScript types alone, which apps
|
|
51
|
+
// catching `instanceof TypeError` could not see at runtime.
|
|
52
|
+
function requireArgs(actual, required, method) {
|
|
53
|
+
if (actual < required) {
|
|
54
|
+
throw new TypeError(`Failed to execute '${method}' on 'SubtleCrypto': ${required} arguments required, but only ${actual} present.`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// WebCrypto §18.4.4: algorithm name lookup is case-insensitive, but the
|
|
59
|
+
// canonical mixed-case form is preserved in the resulting `name` field
|
|
60
|
+
// (e.g. "aes-gcm" → "AES-GCM"). This map is built lazily on first call so
|
|
61
|
+
// the registry of canonical names below can stay declared after the
|
|
62
|
+
// function. Without this, callers who pass lowercase strings bypass the
|
|
63
|
+
// downstream `SUPPORTED_ALGORITHMS` set comparisons silently.
|
|
64
|
+
//
|
|
65
|
+
// The map's value type is `AnyAlgorithm` so callers can use the lookup
|
|
66
|
+
// result directly without re-asserting. The `as AnyAlgorithm` at insertion
|
|
67
|
+
// is the single contract boundary: every name in `SUPPORTED_ALGORITHMS` is
|
|
68
|
+
// already a member of `AnyAlgorithm` by construction.
|
|
69
|
+
let _canonicalAlgorithmNames = null;
|
|
70
|
+
function getCanonicalAlgorithmNames() {
|
|
71
|
+
if (_canonicalAlgorithmNames === null) {
|
|
72
|
+
const map = new Map();
|
|
73
|
+
for (const set of Object.values(SUPPORTED_ALGORITHMS)) {
|
|
74
|
+
if (!set) continue;
|
|
75
|
+
for (const name of set) {
|
|
76
|
+
map.set(name.toLowerCase(), name);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
_canonicalAlgorithmNames = map;
|
|
80
|
+
}
|
|
81
|
+
return _canonicalAlgorithmNames;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Per-algorithm WebIDL converter table. Mirrors Node's kAlgorithmDefinitions
|
|
85
|
+
// (lib/internal/crypto/util.js): each (algorithm, operation) pair maps to a
|
|
86
|
+
// dictionary converter name, or null when only the `name` member is required.
|
|
87
|
+
// Operation keys are missing when an algorithm cannot perform that operation,
|
|
88
|
+
// causing `normalizeAlgorithm` to reject the call.
|
|
89
|
+
const kAlgorithmDefinitions = {
|
|
90
|
+
'AES-CBC': {
|
|
91
|
+
generateKey: 'AesKeyGenParams',
|
|
92
|
+
exportKey: null,
|
|
93
|
+
importKey: null,
|
|
94
|
+
encrypt: 'AesCbcParams',
|
|
95
|
+
decrypt: 'AesCbcParams',
|
|
96
|
+
'get key length': 'AesDerivedKeyParams'
|
|
97
|
+
},
|
|
98
|
+
'AES-CTR': {
|
|
99
|
+
generateKey: 'AesKeyGenParams',
|
|
100
|
+
exportKey: null,
|
|
101
|
+
importKey: null,
|
|
102
|
+
encrypt: 'AesCtrParams',
|
|
103
|
+
decrypt: 'AesCtrParams',
|
|
104
|
+
'get key length': 'AesDerivedKeyParams'
|
|
105
|
+
},
|
|
106
|
+
'AES-GCM': {
|
|
107
|
+
generateKey: 'AesKeyGenParams',
|
|
108
|
+
exportKey: null,
|
|
109
|
+
importKey: null,
|
|
110
|
+
encrypt: 'AeadParams',
|
|
111
|
+
decrypt: 'AeadParams',
|
|
112
|
+
'get key length': 'AesDerivedKeyParams'
|
|
113
|
+
},
|
|
114
|
+
'AES-KW': {
|
|
115
|
+
generateKey: 'AesKeyGenParams',
|
|
116
|
+
exportKey: null,
|
|
117
|
+
importKey: null,
|
|
118
|
+
'get key length': 'AesDerivedKeyParams',
|
|
119
|
+
wrapKey: null,
|
|
120
|
+
unwrapKey: null
|
|
121
|
+
},
|
|
122
|
+
'AES-OCB': {
|
|
123
|
+
generateKey: 'AesKeyGenParams',
|
|
124
|
+
exportKey: null,
|
|
125
|
+
importKey: null,
|
|
126
|
+
encrypt: 'AeadParams',
|
|
127
|
+
decrypt: 'AeadParams',
|
|
128
|
+
'get key length': 'AesDerivedKeyParams'
|
|
129
|
+
},
|
|
130
|
+
Argon2d: {
|
|
131
|
+
deriveBits: 'Argon2Params',
|
|
132
|
+
'get key length': null,
|
|
133
|
+
importKey: null
|
|
134
|
+
},
|
|
135
|
+
Argon2i: {
|
|
136
|
+
deriveBits: 'Argon2Params',
|
|
137
|
+
'get key length': null,
|
|
138
|
+
importKey: null
|
|
139
|
+
},
|
|
140
|
+
Argon2id: {
|
|
141
|
+
deriveBits: 'Argon2Params',
|
|
142
|
+
'get key length': null,
|
|
143
|
+
importKey: null
|
|
144
|
+
},
|
|
145
|
+
'ChaCha20-Poly1305': {
|
|
146
|
+
generateKey: null,
|
|
147
|
+
exportKey: null,
|
|
148
|
+
importKey: null,
|
|
149
|
+
encrypt: 'AeadParams',
|
|
150
|
+
decrypt: 'AeadParams',
|
|
151
|
+
'get key length': null
|
|
152
|
+
},
|
|
153
|
+
ECDH: {
|
|
154
|
+
generateKey: 'EcKeyGenParams',
|
|
155
|
+
exportKey: null,
|
|
156
|
+
importKey: 'EcKeyImportParams',
|
|
157
|
+
deriveBits: 'EcdhKeyDeriveParams'
|
|
158
|
+
},
|
|
159
|
+
ECDSA: {
|
|
160
|
+
generateKey: 'EcKeyGenParams',
|
|
161
|
+
exportKey: null,
|
|
162
|
+
importKey: 'EcKeyImportParams',
|
|
163
|
+
sign: 'EcdsaParams',
|
|
164
|
+
verify: 'EcdsaParams'
|
|
165
|
+
},
|
|
166
|
+
Ed25519: {
|
|
167
|
+
generateKey: null,
|
|
168
|
+
exportKey: null,
|
|
169
|
+
importKey: null,
|
|
170
|
+
sign: null,
|
|
171
|
+
verify: null
|
|
172
|
+
},
|
|
173
|
+
Ed448: {
|
|
174
|
+
generateKey: null,
|
|
175
|
+
exportKey: null,
|
|
176
|
+
importKey: null,
|
|
177
|
+
sign: 'ContextParams',
|
|
178
|
+
verify: 'ContextParams'
|
|
179
|
+
},
|
|
180
|
+
HKDF: {
|
|
181
|
+
importKey: null,
|
|
182
|
+
deriveBits: 'HkdfParams',
|
|
183
|
+
'get key length': null
|
|
184
|
+
},
|
|
185
|
+
HMAC: {
|
|
186
|
+
generateKey: 'HmacKeyGenParams',
|
|
187
|
+
exportKey: null,
|
|
188
|
+
importKey: 'HmacImportParams',
|
|
189
|
+
sign: null,
|
|
190
|
+
verify: null,
|
|
191
|
+
'get key length': 'HmacImportParams'
|
|
192
|
+
},
|
|
193
|
+
KMAC128: {
|
|
194
|
+
generateKey: 'KmacKeyGenParams',
|
|
195
|
+
exportKey: null,
|
|
196
|
+
importKey: 'KmacImportParams',
|
|
197
|
+
sign: 'KmacParams',
|
|
198
|
+
verify: 'KmacParams',
|
|
199
|
+
'get key length': 'KmacImportParams'
|
|
200
|
+
},
|
|
201
|
+
KMAC256: {
|
|
202
|
+
generateKey: 'KmacKeyGenParams',
|
|
203
|
+
exportKey: null,
|
|
204
|
+
importKey: 'KmacImportParams',
|
|
205
|
+
sign: 'KmacParams',
|
|
206
|
+
verify: 'KmacParams',
|
|
207
|
+
'get key length': 'KmacImportParams'
|
|
208
|
+
},
|
|
209
|
+
'ML-DSA-44': {
|
|
210
|
+
generateKey: null,
|
|
211
|
+
exportKey: null,
|
|
212
|
+
importKey: null,
|
|
213
|
+
sign: 'ContextParams',
|
|
214
|
+
verify: 'ContextParams'
|
|
215
|
+
},
|
|
216
|
+
'ML-DSA-65': {
|
|
217
|
+
generateKey: null,
|
|
218
|
+
exportKey: null,
|
|
219
|
+
importKey: null,
|
|
220
|
+
sign: 'ContextParams',
|
|
221
|
+
verify: 'ContextParams'
|
|
222
|
+
},
|
|
223
|
+
'ML-DSA-87': {
|
|
224
|
+
generateKey: null,
|
|
225
|
+
exportKey: null,
|
|
226
|
+
importKey: null,
|
|
227
|
+
sign: 'ContextParams',
|
|
228
|
+
verify: 'ContextParams'
|
|
229
|
+
},
|
|
230
|
+
'ML-KEM-512': {
|
|
231
|
+
generateKey: null,
|
|
232
|
+
exportKey: null,
|
|
233
|
+
importKey: null,
|
|
234
|
+
encapsulateBits: null,
|
|
235
|
+
decapsulateBits: null,
|
|
236
|
+
encapsulateKey: null,
|
|
237
|
+
decapsulateKey: null
|
|
238
|
+
},
|
|
239
|
+
'ML-KEM-768': {
|
|
240
|
+
generateKey: null,
|
|
241
|
+
exportKey: null,
|
|
242
|
+
importKey: null,
|
|
243
|
+
encapsulateBits: null,
|
|
244
|
+
decapsulateBits: null,
|
|
245
|
+
encapsulateKey: null,
|
|
246
|
+
decapsulateKey: null
|
|
247
|
+
},
|
|
248
|
+
'ML-KEM-1024': {
|
|
249
|
+
generateKey: null,
|
|
250
|
+
exportKey: null,
|
|
251
|
+
importKey: null,
|
|
252
|
+
encapsulateBits: null,
|
|
253
|
+
decapsulateBits: null,
|
|
254
|
+
encapsulateKey: null,
|
|
255
|
+
decapsulateKey: null
|
|
256
|
+
},
|
|
257
|
+
PBKDF2: {
|
|
258
|
+
importKey: null,
|
|
259
|
+
deriveBits: 'Pbkdf2Params',
|
|
260
|
+
'get key length': null
|
|
261
|
+
},
|
|
262
|
+
'RSA-OAEP': {
|
|
263
|
+
generateKey: 'RsaHashedKeyGenParams',
|
|
264
|
+
exportKey: null,
|
|
265
|
+
importKey: 'RsaHashedImportParams',
|
|
266
|
+
encrypt: 'RsaOaepParams',
|
|
267
|
+
decrypt: 'RsaOaepParams'
|
|
268
|
+
},
|
|
269
|
+
'RSA-PSS': {
|
|
270
|
+
generateKey: 'RsaHashedKeyGenParams',
|
|
271
|
+
exportKey: null,
|
|
272
|
+
importKey: 'RsaHashedImportParams',
|
|
273
|
+
sign: 'RsaPssParams',
|
|
274
|
+
verify: 'RsaPssParams'
|
|
275
|
+
},
|
|
276
|
+
'RSASSA-PKCS1-v1_5': {
|
|
277
|
+
generateKey: 'RsaHashedKeyGenParams',
|
|
278
|
+
exportKey: null,
|
|
279
|
+
importKey: 'RsaHashedImportParams',
|
|
280
|
+
sign: null,
|
|
281
|
+
verify: null
|
|
282
|
+
},
|
|
283
|
+
'SHA-1': {
|
|
284
|
+
digest: null
|
|
285
|
+
},
|
|
286
|
+
'SHA-256': {
|
|
287
|
+
digest: null
|
|
288
|
+
},
|
|
289
|
+
'SHA-384': {
|
|
290
|
+
digest: null
|
|
291
|
+
},
|
|
292
|
+
'SHA-512': {
|
|
293
|
+
digest: null
|
|
294
|
+
},
|
|
295
|
+
'SHA3-256': {
|
|
296
|
+
digest: null
|
|
297
|
+
},
|
|
298
|
+
'SHA3-384': {
|
|
299
|
+
digest: null
|
|
300
|
+
},
|
|
301
|
+
'SHA3-512': {
|
|
302
|
+
digest: null
|
|
303
|
+
},
|
|
304
|
+
cSHAKE128: {
|
|
305
|
+
digest: 'CShakeParams'
|
|
306
|
+
},
|
|
307
|
+
cSHAKE256: {
|
|
308
|
+
digest: 'CShakeParams'
|
|
309
|
+
},
|
|
310
|
+
KT128: {
|
|
311
|
+
digest: 'KangarooTwelveParams'
|
|
312
|
+
},
|
|
313
|
+
KT256: {
|
|
314
|
+
digest: 'KangarooTwelveParams'
|
|
315
|
+
},
|
|
316
|
+
TurboSHAKE128: {
|
|
317
|
+
digest: 'TurboShakeParams'
|
|
318
|
+
},
|
|
319
|
+
TurboSHAKE256: {
|
|
320
|
+
digest: 'TurboShakeParams'
|
|
321
|
+
},
|
|
322
|
+
X25519: {
|
|
323
|
+
generateKey: null,
|
|
324
|
+
exportKey: null,
|
|
325
|
+
importKey: null,
|
|
326
|
+
deriveBits: 'EcdhKeyDeriveParams'
|
|
327
|
+
},
|
|
328
|
+
X448: {
|
|
329
|
+
generateKey: null,
|
|
330
|
+
exportKey: null,
|
|
331
|
+
importKey: null,
|
|
332
|
+
deriveBits: 'EcdhKeyDeriveParams'
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
for (const v of _slhdsa.SLH_DSA_VARIANTS) {
|
|
336
|
+
kAlgorithmDefinitions[v] = {
|
|
337
|
+
generateKey: null,
|
|
338
|
+
exportKey: null,
|
|
339
|
+
importKey: null,
|
|
340
|
+
sign: null,
|
|
341
|
+
verify: null
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// WebIDL dictionary member specs. Mirrors Node's per-converter
|
|
346
|
+
// `createDictionaryConverter` definitions in lib/internal/crypto/webidl.js.
|
|
347
|
+
// `required: true` causes `normalizeAlgorithm` to throw a TypeError when the
|
|
348
|
+
// member is missing — matching the spec'd WebCrypto behavior that
|
|
349
|
+
// `SubtleCrypto.supports` relies on via try/catch.
|
|
350
|
+
|
|
351
|
+
const kRequiredFields = {
|
|
352
|
+
AesKeyGenParams: [{
|
|
353
|
+
key: 'length',
|
|
354
|
+
required: true
|
|
355
|
+
}],
|
|
356
|
+
AesDerivedKeyParams: [{
|
|
357
|
+
key: 'length',
|
|
358
|
+
required: true
|
|
359
|
+
}],
|
|
360
|
+
AesCbcParams: [{
|
|
361
|
+
key: 'iv',
|
|
362
|
+
required: true
|
|
363
|
+
}],
|
|
364
|
+
AesCtrParams: [{
|
|
365
|
+
key: 'counter',
|
|
366
|
+
required: true
|
|
367
|
+
}, {
|
|
368
|
+
key: 'length',
|
|
369
|
+
required: true
|
|
370
|
+
}],
|
|
371
|
+
AeadParams: [{
|
|
372
|
+
key: 'iv',
|
|
373
|
+
required: true
|
|
374
|
+
}, {
|
|
375
|
+
key: 'tagLength'
|
|
376
|
+
}, {
|
|
377
|
+
key: 'additionalData'
|
|
378
|
+
}],
|
|
379
|
+
EcKeyGenParams: [{
|
|
380
|
+
key: 'namedCurve',
|
|
381
|
+
required: true
|
|
382
|
+
}],
|
|
383
|
+
EcKeyImportParams: [{
|
|
384
|
+
key: 'namedCurve',
|
|
385
|
+
required: true
|
|
386
|
+
}],
|
|
387
|
+
EcdsaParams: [{
|
|
388
|
+
key: 'hash',
|
|
389
|
+
required: true
|
|
390
|
+
}],
|
|
391
|
+
EcdhKeyDeriveParams: [{
|
|
392
|
+
key: 'public',
|
|
393
|
+
required: true
|
|
394
|
+
}],
|
|
395
|
+
HmacKeyGenParams: [{
|
|
396
|
+
key: 'hash',
|
|
397
|
+
required: true
|
|
398
|
+
}, {
|
|
399
|
+
key: 'length'
|
|
400
|
+
}],
|
|
401
|
+
HmacImportParams: [{
|
|
402
|
+
key: 'hash',
|
|
403
|
+
required: true
|
|
404
|
+
}, {
|
|
405
|
+
key: 'length'
|
|
406
|
+
}],
|
|
407
|
+
HkdfParams: [{
|
|
408
|
+
key: 'hash',
|
|
409
|
+
required: true
|
|
410
|
+
}, {
|
|
411
|
+
key: 'salt',
|
|
412
|
+
required: true
|
|
413
|
+
}, {
|
|
414
|
+
key: 'info',
|
|
415
|
+
required: true
|
|
416
|
+
}],
|
|
417
|
+
Pbkdf2Params: [{
|
|
418
|
+
key: 'hash',
|
|
419
|
+
required: true
|
|
420
|
+
}, {
|
|
421
|
+
key: 'iterations',
|
|
422
|
+
required: true
|
|
423
|
+
}, {
|
|
424
|
+
key: 'salt',
|
|
425
|
+
required: true
|
|
426
|
+
}],
|
|
427
|
+
RsaHashedKeyGenParams: [{
|
|
428
|
+
key: 'modulusLength',
|
|
429
|
+
required: true
|
|
430
|
+
}, {
|
|
431
|
+
key: 'publicExponent',
|
|
432
|
+
required: true
|
|
433
|
+
}, {
|
|
434
|
+
key: 'hash',
|
|
435
|
+
required: true
|
|
436
|
+
}],
|
|
437
|
+
RsaHashedImportParams: [{
|
|
438
|
+
key: 'hash',
|
|
439
|
+
required: true
|
|
440
|
+
}],
|
|
441
|
+
RsaOaepParams: [{
|
|
442
|
+
key: 'label'
|
|
443
|
+
}],
|
|
444
|
+
RsaPssParams: [{
|
|
445
|
+
key: 'saltLength',
|
|
446
|
+
required: true
|
|
447
|
+
}],
|
|
448
|
+
ContextParams: [{
|
|
449
|
+
key: 'context'
|
|
450
|
+
}],
|
|
451
|
+
Argon2Params: [{
|
|
452
|
+
key: 'nonce',
|
|
453
|
+
required: true
|
|
454
|
+
}, {
|
|
455
|
+
key: 'parallelism',
|
|
456
|
+
required: true
|
|
457
|
+
}, {
|
|
458
|
+
key: 'memory',
|
|
459
|
+
required: true
|
|
460
|
+
}, {
|
|
461
|
+
key: 'passes',
|
|
462
|
+
required: true
|
|
463
|
+
}, {
|
|
464
|
+
key: 'version'
|
|
465
|
+
}, {
|
|
466
|
+
key: 'secretValue'
|
|
467
|
+
}, {
|
|
468
|
+
key: 'associatedData'
|
|
469
|
+
}],
|
|
470
|
+
KmacKeyGenParams: [{
|
|
471
|
+
key: 'length'
|
|
472
|
+
}],
|
|
473
|
+
KmacImportParams: [{
|
|
474
|
+
key: 'length'
|
|
475
|
+
}],
|
|
476
|
+
KmacParams: [{
|
|
477
|
+
key: 'outputLength',
|
|
478
|
+
required: true
|
|
479
|
+
}, {
|
|
480
|
+
key: 'customization'
|
|
481
|
+
}],
|
|
482
|
+
CShakeParams: [{
|
|
483
|
+
key: 'outputLength',
|
|
484
|
+
required: true
|
|
485
|
+
}, {
|
|
486
|
+
key: 'functionName'
|
|
487
|
+
}, {
|
|
488
|
+
key: 'customization'
|
|
489
|
+
}],
|
|
490
|
+
KangarooTwelveParams: [{
|
|
491
|
+
key: 'outputLength',
|
|
492
|
+
required: true
|
|
493
|
+
}, {
|
|
494
|
+
key: 'customization'
|
|
495
|
+
}],
|
|
496
|
+
TurboShakeParams: [{
|
|
497
|
+
key: 'outputLength',
|
|
498
|
+
required: true
|
|
499
|
+
}, {
|
|
500
|
+
key: 'domainSeparation'
|
|
501
|
+
}]
|
|
502
|
+
};
|
|
503
|
+
function isBufferSource(value) {
|
|
504
|
+
return value instanceof ArrayBuffer || ArrayBuffer.isView(value);
|
|
505
|
+
}
|
|
506
|
+
function validateBufferSource(algorithm, key) {
|
|
507
|
+
const value = algorithm[key];
|
|
508
|
+
if (value === undefined) return undefined;
|
|
509
|
+
if (!isBufferSource(value)) {
|
|
510
|
+
throw new TypeError(`Failed to normalize algorithm: '${key}' must be a BufferSource`);
|
|
511
|
+
}
|
|
512
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(value);
|
|
513
|
+
}
|
|
514
|
+
function validateBinaryLike(algorithm, key) {
|
|
515
|
+
const value = algorithm[key];
|
|
516
|
+
if (value === undefined) return undefined;
|
|
517
|
+
try {
|
|
518
|
+
return (0, _conversion.binaryLikeToArrayBuffer)(value);
|
|
519
|
+
} catch {
|
|
520
|
+
throw new TypeError(`Failed to normalize algorithm: '${key}' must be a BufferSource`);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
function validateByteLength(buffer, key, length, message) {
|
|
524
|
+
if (buffer !== undefined && buffer.byteLength !== length) {
|
|
525
|
+
throw (0, _errors.lazyDOMException)(message ?? `${key} must be ${length} bytes`, 'OperationError');
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
function validateUnsignedInteger(algorithm, key) {
|
|
529
|
+
const value = algorithm[key];
|
|
530
|
+
if (value === undefined) return undefined;
|
|
531
|
+
const numberValue = Number(value);
|
|
532
|
+
if (!Number.isFinite(numberValue) || !Number.isInteger(numberValue) || numberValue < 0) {
|
|
533
|
+
throw new TypeError(`Failed to normalize algorithm: '${key}' must be an unsigned integer`);
|
|
534
|
+
}
|
|
535
|
+
algorithm[key] = numberValue;
|
|
536
|
+
return numberValue;
|
|
537
|
+
}
|
|
538
|
+
function validateHashAlgorithm(algorithm, converterName) {
|
|
539
|
+
const hash = algorithm.hash;
|
|
540
|
+
if (hash === undefined) return;
|
|
541
|
+
const normalizedHash = (0, _hashnames.normalizeHashName)(hash, _hashnames.HashContext.WebCrypto);
|
|
542
|
+
if (!['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512', 'SHA3-256', 'SHA3-384', 'SHA3-512'].includes(normalizedHash)) {
|
|
543
|
+
throw (0, _errors.lazyDOMException)(`Unsupported ${converterName}.hash`, 'NotSupportedError');
|
|
544
|
+
}
|
|
545
|
+
algorithm.hash = {
|
|
546
|
+
name: normalizedHash
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
function validateAesLength(length) {
|
|
550
|
+
if (length !== undefined && length !== 128 && length !== 192 && length !== 256) {
|
|
551
|
+
throw (0, _errors.lazyDOMException)('Invalid key length', 'OperationError');
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
function validateMacLength(algorithm, key, zeroError) {
|
|
555
|
+
const length = validateUnsignedInteger(algorithm, key);
|
|
556
|
+
if (length === undefined) return;
|
|
557
|
+
if (length === 0) {
|
|
558
|
+
throw (0, _errors.lazyDOMException)(`${key} cannot be 0`, zeroError);
|
|
559
|
+
}
|
|
560
|
+
if (length % 8) {
|
|
561
|
+
throw (0, _errors.lazyDOMException)(`Unsupported ${key}`, 'NotSupportedError');
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
function validateAeadParams(algorithm) {
|
|
565
|
+
const iv = validateBufferSource(algorithm, 'iv');
|
|
566
|
+
const tagLength = validateUnsignedInteger(algorithm, 'tagLength');
|
|
567
|
+
validateBufferSource(algorithm, 'additionalData');
|
|
568
|
+
switch (algorithm.name) {
|
|
569
|
+
case 'AES-GCM':
|
|
570
|
+
if (tagLength !== undefined && ![32, 64, 96, 104, 112, 120, 128].includes(tagLength)) {
|
|
571
|
+
throw (0, _errors.lazyDOMException)(`${tagLength} is not a valid AES-GCM tag length`, 'OperationError');
|
|
572
|
+
}
|
|
573
|
+
break;
|
|
574
|
+
case 'AES-OCB':
|
|
575
|
+
if (iv !== undefined && (iv.byteLength < 1 || iv.byteLength > 15)) {
|
|
576
|
+
throw (0, _errors.lazyDOMException)('AES-OCB algorithm.iv must be between 1 and 15 bytes', 'OperationError');
|
|
577
|
+
}
|
|
578
|
+
if (tagLength !== undefined && ![64, 96, 128].includes(tagLength)) {
|
|
579
|
+
throw (0, _errors.lazyDOMException)(`${tagLength} is not a valid AES-OCB tag length`, 'OperationError');
|
|
580
|
+
}
|
|
581
|
+
break;
|
|
582
|
+
case 'ChaCha20-Poly1305':
|
|
583
|
+
validateByteLength(iv, 'algorithm.iv', 12, 'ChaCha20-Poly1305 IV must be exactly 12 bytes');
|
|
584
|
+
if (tagLength !== undefined && tagLength !== 128) {
|
|
585
|
+
throw (0, _errors.lazyDOMException)(`${tagLength} is not a valid ChaCha20-Poly1305 tag length`, 'OperationError');
|
|
586
|
+
}
|
|
587
|
+
break;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
function validateNormalizedAlgorithm(converterName, algorithm) {
|
|
591
|
+
switch (converterName) {
|
|
592
|
+
case 'AesKeyGenParams':
|
|
593
|
+
case 'AesDerivedKeyParams':
|
|
594
|
+
validateAesLength(validateUnsignedInteger(algorithm, 'length'));
|
|
595
|
+
break;
|
|
596
|
+
case 'AesCbcParams':
|
|
597
|
+
validateByteLength(validateBufferSource(algorithm, 'iv'), 'algorithm.iv', 16, 'algorithm.iv must contain exactly 16 bytes');
|
|
598
|
+
break;
|
|
599
|
+
case 'AesCtrParams':
|
|
600
|
+
{
|
|
601
|
+
validateByteLength(validateBufferSource(algorithm, 'counter'), 'algorithm.counter', 16);
|
|
602
|
+
const length = validateUnsignedInteger(algorithm, 'length');
|
|
603
|
+
if (length !== undefined && (length === 0 || length > 128)) {
|
|
604
|
+
throw (0, _errors.lazyDOMException)('AES-CTR algorithm.length must be between 1 and 128', 'OperationError');
|
|
605
|
+
}
|
|
606
|
+
break;
|
|
607
|
+
}
|
|
608
|
+
case 'AeadParams':
|
|
609
|
+
validateAeadParams(algorithm);
|
|
610
|
+
break;
|
|
611
|
+
case 'EcdsaParams':
|
|
612
|
+
case 'HmacKeyGenParams':
|
|
613
|
+
case 'HmacImportParams':
|
|
614
|
+
case 'HkdfParams':
|
|
615
|
+
case 'Pbkdf2Params':
|
|
616
|
+
case 'RsaHashedKeyGenParams':
|
|
617
|
+
case 'RsaHashedImportParams':
|
|
618
|
+
validateHashAlgorithm(algorithm, converterName);
|
|
619
|
+
if (converterName === 'HmacKeyGenParams') {
|
|
620
|
+
validateMacLength(algorithm, 'length', 'OperationError');
|
|
621
|
+
}
|
|
622
|
+
if (converterName === 'HkdfParams') {
|
|
623
|
+
validateBinaryLike(algorithm, 'salt');
|
|
624
|
+
validateBinaryLike(algorithm, 'info');
|
|
625
|
+
} else if (converterName === 'Pbkdf2Params') {
|
|
626
|
+
const iterations = validateUnsignedInteger(algorithm, 'iterations');
|
|
627
|
+
if (iterations === 0) {
|
|
628
|
+
throw (0, _errors.lazyDOMException)('iterations cannot be zero', 'OperationError');
|
|
629
|
+
}
|
|
630
|
+
validateBinaryLike(algorithm, 'salt');
|
|
631
|
+
} else if (converterName === 'RsaHashedKeyGenParams') {
|
|
632
|
+
validateUnsignedInteger(algorithm, 'modulusLength');
|
|
633
|
+
validateBufferSource(algorithm, 'publicExponent');
|
|
634
|
+
}
|
|
635
|
+
break;
|
|
636
|
+
case 'RsaPssParams':
|
|
637
|
+
validateUnsignedInteger(algorithm, 'saltLength');
|
|
638
|
+
break;
|
|
639
|
+
case 'RsaOaepParams':
|
|
640
|
+
validateBufferSource(algorithm, 'label');
|
|
641
|
+
break;
|
|
642
|
+
case 'ContextParams':
|
|
643
|
+
validateBufferSource(algorithm, 'context');
|
|
644
|
+
break;
|
|
645
|
+
case 'EcdhKeyDeriveParams':
|
|
646
|
+
if (!(algorithm.public instanceof _keys.CryptoKey)) {
|
|
647
|
+
throw (0, _errors.lazyDOMException)('algorithm.public must be a public key', 'InvalidAccessError');
|
|
648
|
+
}
|
|
649
|
+
break;
|
|
650
|
+
case 'Argon2Params':
|
|
651
|
+
{
|
|
652
|
+
validateBufferSource(algorithm, 'nonce');
|
|
653
|
+
const parallelism = validateUnsignedInteger(algorithm, 'parallelism');
|
|
654
|
+
const memory = validateUnsignedInteger(algorithm, 'memory');
|
|
655
|
+
validateUnsignedInteger(algorithm, 'passes');
|
|
656
|
+
const version = validateUnsignedInteger(algorithm, 'version');
|
|
657
|
+
validateBufferSource(algorithm, 'secretValue');
|
|
658
|
+
validateBufferSource(algorithm, 'associatedData');
|
|
659
|
+
if (parallelism !== undefined && (parallelism === 0 || parallelism > 2 ** 24 - 1)) {
|
|
660
|
+
throw (0, _errors.lazyDOMException)('parallelism must be > 0 and < 16777215', 'OperationError');
|
|
661
|
+
}
|
|
662
|
+
if (memory !== undefined && parallelism !== undefined && memory < 8 * parallelism) {
|
|
663
|
+
throw (0, _errors.lazyDOMException)('memory must be at least 8 times the degree of parallelism', 'OperationError');
|
|
664
|
+
}
|
|
665
|
+
if (version !== undefined && version !== 0x13) {
|
|
666
|
+
throw (0, _errors.lazyDOMException)(`${version} is not a valid Argon2 version`, 'OperationError');
|
|
667
|
+
}
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
case 'KmacKeyGenParams':
|
|
671
|
+
validateMacLength(algorithm, 'length', 'OperationError');
|
|
672
|
+
break;
|
|
673
|
+
case 'KmacImportParams':
|
|
674
|
+
validateMacLength(algorithm, 'length', 'DataError');
|
|
675
|
+
break;
|
|
676
|
+
case 'KmacParams':
|
|
677
|
+
validateMacLength(algorithm, 'outputLength', 'OperationError');
|
|
678
|
+
validateBufferSource(algorithm, 'customization');
|
|
679
|
+
break;
|
|
680
|
+
case 'CShakeParams':
|
|
681
|
+
case 'KangarooTwelveParams':
|
|
682
|
+
{
|
|
683
|
+
const outputLength = validateUnsignedInteger(algorithm, 'outputLength');
|
|
684
|
+
if (outputLength !== undefined && (outputLength === 0 || outputLength % 8)) {
|
|
685
|
+
throw (0, _errors.lazyDOMException)(`Invalid ${converterName} outputLength`, 'OperationError');
|
|
686
|
+
}
|
|
687
|
+
validateBufferSource(algorithm, 'functionName');
|
|
688
|
+
validateBufferSource(algorithm, 'customization');
|
|
689
|
+
break;
|
|
690
|
+
}
|
|
691
|
+
case 'TurboShakeParams':
|
|
692
|
+
{
|
|
693
|
+
const outputLength = validateUnsignedInteger(algorithm, 'outputLength');
|
|
694
|
+
const domainSeparation = validateUnsignedInteger(algorithm, 'domainSeparation');
|
|
695
|
+
if (outputLength !== undefined && (outputLength === 0 || outputLength % 8)) {
|
|
696
|
+
throw (0, _errors.lazyDOMException)('Invalid TurboShakeParams outputLength', 'OperationError');
|
|
697
|
+
}
|
|
698
|
+
if (domainSeparation !== undefined && (domainSeparation < 0x01 || domainSeparation > 0x7f)) {
|
|
699
|
+
throw (0, _errors.lazyDOMException)('TurboShakeParams.domainSeparation must be in range 0x01-0x7f', 'OperationError');
|
|
700
|
+
}
|
|
701
|
+
break;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// WebCrypto §18.4.4 algorithm normalization. Mirrors Node's normalizeAlgorithm
|
|
707
|
+
// in lib/internal/crypto/util.js: canonicalizes `name`, looks up the
|
|
708
|
+
// (name, op) → converter mapping, and rejects inputs that omit required
|
|
709
|
+
// dictionary members. Callers in Subtle.supports rely on this throwing for
|
|
710
|
+
// invalid params — without it, supports() over-reports capability (#1025).
|
|
711
|
+
function normalizeAlgorithm(algorithm, operation) {
|
|
712
|
+
if (typeof algorithm === 'string') {
|
|
713
|
+
return normalizeAlgorithm({
|
|
714
|
+
name: algorithm
|
|
715
|
+
}, operation);
|
|
716
|
+
}
|
|
717
|
+
const name = algorithm.name;
|
|
718
|
+
if (typeof name !== 'string') {
|
|
719
|
+
throw new TypeError("Algorithm: 'name' is required");
|
|
720
|
+
}
|
|
721
|
+
const map = getCanonicalAlgorithmNames();
|
|
722
|
+
const canonical = map.get(name.toLowerCase());
|
|
723
|
+
if (canonical === undefined) {
|
|
724
|
+
throw (0, _errors.lazyDOMException)('Unrecognized algorithm name', 'NotSupportedError');
|
|
725
|
+
}
|
|
726
|
+
const opMap = kAlgorithmDefinitions[canonical];
|
|
727
|
+
if (!opMap || !(operation in opMap)) {
|
|
728
|
+
throw (0, _errors.lazyDOMException)('Unrecognized algorithm name', 'NotSupportedError');
|
|
729
|
+
}
|
|
730
|
+
const converterName = opMap[operation];
|
|
731
|
+
if (converterName == null) {
|
|
732
|
+
return {
|
|
733
|
+
name: canonical
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
const fields = kRequiredFields[converterName];
|
|
737
|
+
if (!fields) {
|
|
738
|
+
return {
|
|
739
|
+
...algorithm,
|
|
740
|
+
name: canonical
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
const out = {
|
|
744
|
+
name: canonical
|
|
745
|
+
};
|
|
746
|
+
const src = algorithm;
|
|
747
|
+
for (const field of fields) {
|
|
748
|
+
const value = src[field.key];
|
|
749
|
+
if (value === undefined) {
|
|
750
|
+
if (field.required) {
|
|
751
|
+
throw new TypeError(`Failed to normalize algorithm: '${field.key}' is required in '${converterName}'`);
|
|
752
|
+
}
|
|
753
|
+
continue;
|
|
754
|
+
}
|
|
755
|
+
out[field.key] = value;
|
|
756
|
+
}
|
|
757
|
+
validateNormalizedAlgorithm(converterName, out);
|
|
758
|
+
return out;
|
|
759
|
+
}
|
|
760
|
+
function getAlgorithmName(name, length) {
|
|
761
|
+
switch (name) {
|
|
762
|
+
case 'AES-CBC':
|
|
763
|
+
return `A${length}CBC`;
|
|
764
|
+
case 'AES-CTR':
|
|
765
|
+
return `A${length}CTR`;
|
|
766
|
+
case 'AES-GCM':
|
|
767
|
+
return `A${length}GCM`;
|
|
768
|
+
case 'AES-KW':
|
|
769
|
+
return `A${length}KW`;
|
|
770
|
+
case 'AES-OCB':
|
|
771
|
+
return `A${length}OCB`;
|
|
772
|
+
case 'ChaCha20-Poly1305':
|
|
773
|
+
return 'C20P';
|
|
774
|
+
default:
|
|
775
|
+
return `${name}${length}`;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
// Mirrors Node's aliasKeyFormat (lib/internal/crypto/webcrypto.js): for
|
|
780
|
+
// algorithms whose import/export accepts both 'raw' and the disambiguated
|
|
781
|
+
// 'raw-secret' / 'raw-public', collapse the latter to 'raw'. Used per-algorithm
|
|
782
|
+
// — algorithms that demand the disambiguated form (KMAC, AES-OCB,
|
|
783
|
+
// ChaCha20-Poly1305, Argon2*, ML-DSA, ML-KEM) MUST NOT alias.
|
|
784
|
+
function aliasKeyFormat(format) {
|
|
785
|
+
if (format === 'raw-secret' || format === 'raw-public') return 'raw';
|
|
786
|
+
return format;
|
|
787
|
+
}
|
|
788
|
+
const kUncompressedSpkiLength = {
|
|
789
|
+
'P-256': 91,
|
|
790
|
+
'P-384': 120,
|
|
791
|
+
'P-521': 158
|
|
792
|
+
};
|
|
793
|
+
function ecExportKey(key, format) {
|
|
794
|
+
const keyObject = key.keyObject;
|
|
795
|
+
if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatRaw) {
|
|
796
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(keyObject.handle.exportKey());
|
|
797
|
+
} else if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatSPKI) {
|
|
798
|
+
const exported = (0, _conversion.bufferLikeToArrayBuffer)(keyObject.export({
|
|
799
|
+
format: 'der',
|
|
800
|
+
type: 'spki'
|
|
801
|
+
}));
|
|
802
|
+
|
|
803
|
+
// WebCrypto requires uncompressed point format for SPKI exports.
|
|
804
|
+
// If the key was imported in compressed form, re-export as uncompressed
|
|
805
|
+
// by reconstructing the point from the JWK x,y coordinates and
|
|
806
|
+
// round-tripping through initECRaw.
|
|
807
|
+
const namedCurve = key.algorithm.namedCurve;
|
|
808
|
+
const expected = namedCurve === undefined ? undefined : kUncompressedSpkiLength[namedCurve];
|
|
809
|
+
if (expected !== undefined && exported.byteLength !== expected) {
|
|
810
|
+
const jwk = keyObject.handle.exportJwk({}, false);
|
|
811
|
+
if (!jwk.x || !jwk.y) {
|
|
812
|
+
throw (0, _errors.lazyDOMException)('Failed to re-export EC public key as uncompressed SPKI', 'OperationError');
|
|
813
|
+
}
|
|
814
|
+
const x = _reactNativeBuffer.Buffer.from(jwk.x, 'base64url');
|
|
815
|
+
const y = _reactNativeBuffer.Buffer.from(jwk.y, 'base64url');
|
|
816
|
+
const raw = new Uint8Array(1 + x.length + y.length);
|
|
817
|
+
raw[0] = 0x04;
|
|
818
|
+
raw.set(x, 1);
|
|
819
|
+
raw.set(y, 1 + x.length);
|
|
820
|
+
const tmp = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
821
|
+
const curveAlias = _utils.kNamedCurveAliases[namedCurve];
|
|
822
|
+
if (!tmp.initECRaw(curveAlias, raw.buffer)) {
|
|
823
|
+
throw (0, _errors.lazyDOMException)('Failed to re-export EC public key as uncompressed SPKI', 'OperationError');
|
|
824
|
+
}
|
|
825
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(tmp.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI));
|
|
826
|
+
}
|
|
827
|
+
return exported;
|
|
828
|
+
} else if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatPKCS8) {
|
|
829
|
+
const exported = keyObject.export({
|
|
830
|
+
format: 'der',
|
|
831
|
+
type: 'pkcs8'
|
|
832
|
+
});
|
|
833
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(exported);
|
|
834
|
+
} else {
|
|
835
|
+
throw new Error(`Unsupported EC export format: ${format}`);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
function rsaExportKey(key, format) {
|
|
839
|
+
const keyObject = key.keyObject;
|
|
840
|
+
if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatSPKI) {
|
|
841
|
+
// Export public key in SPKI format
|
|
842
|
+
const exported = keyObject.export({
|
|
843
|
+
format: 'der',
|
|
844
|
+
type: 'spki'
|
|
845
|
+
});
|
|
846
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(exported);
|
|
847
|
+
} else if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatPKCS8) {
|
|
848
|
+
// Export private key in PKCS8 format
|
|
849
|
+
const exported = keyObject.export({
|
|
850
|
+
format: 'der',
|
|
851
|
+
type: 'pkcs8'
|
|
852
|
+
});
|
|
853
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(exported);
|
|
854
|
+
} else {
|
|
855
|
+
throw new Error(`Unsupported RSA export format: ${format}`);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
async function rsaCipher(mode, key, data, algorithm) {
|
|
859
|
+
const rsaParams = algorithm;
|
|
860
|
+
|
|
861
|
+
// Validate key type matches operation
|
|
862
|
+
const expectedType = mode === CipherOrWrapMode.kWebCryptoCipherEncrypt ? 'public' : 'private';
|
|
863
|
+
if (key.type !== expectedType) {
|
|
864
|
+
throw (0, _errors.lazyDOMException)('The requested operation is not valid for the provided key', 'InvalidAccessError');
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
// Get hash algorithm from key
|
|
868
|
+
const hashAlgorithm = (0, _hashnames.normalizeHashName)(key.algorithm.hash);
|
|
869
|
+
|
|
870
|
+
// Prepare label (optional)
|
|
871
|
+
const label = rsaParams.label ? (0, _conversion.bufferLikeToArrayBuffer)(rsaParams.label) : undefined;
|
|
872
|
+
|
|
873
|
+
// Create RSA cipher instance
|
|
874
|
+
const rsaCipherModule = _reactNativeNitroModules.NitroModules.createHybridObject('RsaCipher');
|
|
875
|
+
|
|
876
|
+
// RSA-OAEP padding constant = 4
|
|
877
|
+
const RSA_PKCS1_OAEP_PADDING = 4;
|
|
878
|
+
if (mode === CipherOrWrapMode.kWebCryptoCipherEncrypt) {
|
|
879
|
+
// Encrypt with public key
|
|
880
|
+
return rsaCipherModule.encrypt(key.keyObject.handle, data, RSA_PKCS1_OAEP_PADDING, hashAlgorithm, label);
|
|
881
|
+
} else {
|
|
882
|
+
// Decrypt with private key
|
|
883
|
+
return rsaCipherModule.decrypt(key.keyObject.handle, data, RSA_PKCS1_OAEP_PADDING, hashAlgorithm, label);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
async function aesCipher(mode, key, data, algorithm) {
|
|
887
|
+
const {
|
|
888
|
+
name
|
|
889
|
+
} = algorithm;
|
|
890
|
+
switch (name) {
|
|
891
|
+
case 'AES-CTR':
|
|
892
|
+
return aesCtrCipher(mode, key, data, algorithm);
|
|
893
|
+
case 'AES-CBC':
|
|
894
|
+
return aesCbcCipher(mode, key, data, algorithm);
|
|
895
|
+
case 'AES-GCM':
|
|
896
|
+
return aesGcmCipher(mode, key, data, algorithm);
|
|
897
|
+
case 'AES-OCB':
|
|
898
|
+
return aesOcbCipher(mode, key, data, algorithm);
|
|
899
|
+
default:
|
|
900
|
+
throw (0, _errors.lazyDOMException)(`Unsupported AES algorithm: ${name}`, 'NotSupportedError');
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
async function aesCtrCipher(mode, key, data, algorithm) {
|
|
904
|
+
// Validate counter and length
|
|
905
|
+
if (!algorithm.counter || algorithm.counter.byteLength !== 16) {
|
|
906
|
+
throw (0, _errors.lazyDOMException)('AES-CTR algorithm.counter must be 16 bytes', 'OperationError');
|
|
907
|
+
}
|
|
908
|
+
if (algorithm.length < 1 || algorithm.length > 128) {
|
|
909
|
+
throw (0, _errors.lazyDOMException)('AES-CTR algorithm.length must be between 1 and 128', 'OperationError');
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
// Get cipher type based on key length
|
|
913
|
+
const keyLength = key.algorithm.length;
|
|
914
|
+
const cipherType = `aes-${keyLength}-ctr`;
|
|
915
|
+
|
|
916
|
+
// Create cipher
|
|
917
|
+
const factory = _reactNativeNitroModules.NitroModules.createHybridObject('CipherFactory');
|
|
918
|
+
const cipher = factory.createCipher({
|
|
919
|
+
isCipher: mode === CipherOrWrapMode.kWebCryptoCipherEncrypt,
|
|
920
|
+
cipherType,
|
|
921
|
+
cipherKey: (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.export()),
|
|
922
|
+
iv: (0, _conversion.bufferLikeToArrayBuffer)(algorithm.counter)
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
// Process data
|
|
926
|
+
const updated = cipher.update(data);
|
|
927
|
+
const final = cipher.final();
|
|
928
|
+
|
|
929
|
+
// Concatenate results
|
|
930
|
+
const result = new Uint8Array(updated.byteLength + final.byteLength);
|
|
931
|
+
result.set(new Uint8Array(updated), 0);
|
|
932
|
+
result.set(new Uint8Array(final), updated.byteLength);
|
|
933
|
+
return result.buffer;
|
|
934
|
+
}
|
|
935
|
+
async function aesCbcCipher(mode, key, data, algorithm) {
|
|
936
|
+
// Validate IV
|
|
937
|
+
const iv = (0, _conversion.bufferLikeToArrayBuffer)(algorithm.iv);
|
|
938
|
+
if (iv.byteLength !== 16) {
|
|
939
|
+
throw (0, _errors.lazyDOMException)('algorithm.iv must contain exactly 16 bytes', 'OperationError');
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// Get cipher type based on key length
|
|
943
|
+
const keyLength = key.algorithm.length;
|
|
944
|
+
const cipherType = `aes-${keyLength}-cbc`;
|
|
945
|
+
|
|
946
|
+
// Create cipher
|
|
947
|
+
const factory = _reactNativeNitroModules.NitroModules.createHybridObject('CipherFactory');
|
|
948
|
+
const cipher = factory.createCipher({
|
|
949
|
+
isCipher: mode === CipherOrWrapMode.kWebCryptoCipherEncrypt,
|
|
950
|
+
cipherType,
|
|
951
|
+
cipherKey: (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.export()),
|
|
952
|
+
iv
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
// Process data
|
|
956
|
+
const updated = cipher.update(data);
|
|
957
|
+
const final = cipher.final();
|
|
958
|
+
|
|
959
|
+
// Concatenate results
|
|
960
|
+
const result = new Uint8Array(updated.byteLength + final.byteLength);
|
|
961
|
+
result.set(new Uint8Array(updated), 0);
|
|
962
|
+
result.set(new Uint8Array(final), updated.byteLength);
|
|
963
|
+
return result.buffer;
|
|
964
|
+
}
|
|
965
|
+
async function aesAeadCipher(mode, key, data, config, additionalData, tagLength = 128) {
|
|
966
|
+
if (!config.validTagLengths.includes(tagLength)) {
|
|
967
|
+
throw (0, _errors.lazyDOMException)(`${tagLength} is not a valid ${config.algorithmName} tag length`, 'OperationError');
|
|
968
|
+
}
|
|
969
|
+
const tagByteLength = tagLength / 8;
|
|
970
|
+
const keyLength = key.algorithm.length;
|
|
971
|
+
const cipherType = `aes-${keyLength}-${config.cipherSuffix}`;
|
|
972
|
+
const factory = _reactNativeNitroModules.NitroModules.createHybridObject('CipherFactory');
|
|
973
|
+
const cipher = factory.createCipher({
|
|
974
|
+
isCipher: mode === CipherOrWrapMode.kWebCryptoCipherEncrypt,
|
|
975
|
+
cipherType,
|
|
976
|
+
cipherKey: (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.export()),
|
|
977
|
+
iv: config.iv,
|
|
978
|
+
authTagLen: tagByteLength
|
|
979
|
+
});
|
|
980
|
+
let processData;
|
|
981
|
+
if (mode === CipherOrWrapMode.kWebCryptoCipherDecrypt) {
|
|
982
|
+
const dataView = new Uint8Array(data);
|
|
983
|
+
if (dataView.byteLength < tagByteLength) {
|
|
984
|
+
throw (0, _errors.lazyDOMException)('The provided data is too small.', 'OperationError');
|
|
985
|
+
}
|
|
986
|
+
const ciphertextLength = dataView.byteLength - tagByteLength;
|
|
987
|
+
processData = dataView.slice(0, ciphertextLength).buffer;
|
|
988
|
+
const authTag = dataView.slice(ciphertextLength).buffer;
|
|
989
|
+
cipher.setAuthTag(authTag);
|
|
990
|
+
} else {
|
|
991
|
+
processData = data;
|
|
992
|
+
}
|
|
993
|
+
if (additionalData) {
|
|
994
|
+
cipher.setAAD((0, _conversion.bufferLikeToArrayBuffer)(additionalData));
|
|
995
|
+
}
|
|
996
|
+
const updated = cipher.update(processData);
|
|
997
|
+
const final = cipher.final();
|
|
998
|
+
if (mode === CipherOrWrapMode.kWebCryptoCipherEncrypt) {
|
|
999
|
+
const tag = cipher.getAuthTag();
|
|
1000
|
+
const result = new Uint8Array(updated.byteLength + final.byteLength + tag.byteLength);
|
|
1001
|
+
result.set(new Uint8Array(updated), 0);
|
|
1002
|
+
result.set(new Uint8Array(final), updated.byteLength);
|
|
1003
|
+
result.set(new Uint8Array(tag), updated.byteLength + final.byteLength);
|
|
1004
|
+
return result.buffer;
|
|
1005
|
+
} else {
|
|
1006
|
+
const result = new Uint8Array(updated.byteLength + final.byteLength);
|
|
1007
|
+
result.set(new Uint8Array(updated), 0);
|
|
1008
|
+
result.set(new Uint8Array(final), updated.byteLength);
|
|
1009
|
+
return result.buffer;
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
async function aesGcmCipher(mode, key, data, algorithm) {
|
|
1013
|
+
return aesAeadCipher(mode, key, data, {
|
|
1014
|
+
algorithmName: 'AES-GCM',
|
|
1015
|
+
validTagLengths: [32, 64, 96, 104, 112, 120, 128],
|
|
1016
|
+
cipherSuffix: 'gcm',
|
|
1017
|
+
iv: (0, _conversion.bufferLikeToArrayBuffer)(algorithm.iv)
|
|
1018
|
+
}, algorithm.additionalData, algorithm.tagLength);
|
|
1019
|
+
}
|
|
1020
|
+
async function aesOcbCipher(mode, key, data, algorithm) {
|
|
1021
|
+
const ivBuffer = (0, _conversion.bufferLikeToArrayBuffer)(algorithm.iv);
|
|
1022
|
+
if (ivBuffer.byteLength < 1 || ivBuffer.byteLength > 15) {
|
|
1023
|
+
throw (0, _errors.lazyDOMException)('AES-OCB algorithm.iv must be between 1 and 15 bytes', 'OperationError');
|
|
1024
|
+
}
|
|
1025
|
+
return aesAeadCipher(mode, key, data, {
|
|
1026
|
+
algorithmName: 'AES-OCB',
|
|
1027
|
+
validTagLengths: [64, 96, 128],
|
|
1028
|
+
cipherSuffix: 'ocb',
|
|
1029
|
+
iv: ivBuffer
|
|
1030
|
+
}, algorithm.additionalData, algorithm.tagLength);
|
|
1031
|
+
}
|
|
1032
|
+
async function aesKwCipher(mode, key, data) {
|
|
1033
|
+
const isWrap = mode === CipherOrWrapMode.kWebCryptoCipherEncrypt;
|
|
1034
|
+
|
|
1035
|
+
// AES-KW requires input to be a multiple of 8 bytes (64 bits)
|
|
1036
|
+
if (data.byteLength % 8 !== 0) {
|
|
1037
|
+
throw (0, _errors.lazyDOMException)(`AES-KW input length must be a multiple of 8 bytes, got ${data.byteLength}`, 'OperationError');
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
// AES-KW requires at least 16 bytes of input (128 bits)
|
|
1041
|
+
if (isWrap && data.byteLength < 16) {
|
|
1042
|
+
throw (0, _errors.lazyDOMException)(`AES-KW input must be at least 16 bytes, got ${data.byteLength}`, 'OperationError');
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
// Get cipher type based on key length
|
|
1046
|
+
const keyLength = key.algorithm.length;
|
|
1047
|
+
// Use aes*-wrap for both operations (matching Node.js)
|
|
1048
|
+
const cipherType = `aes${keyLength}-wrap`;
|
|
1049
|
+
|
|
1050
|
+
// Export key material
|
|
1051
|
+
const exportedKey = key.keyObject.export();
|
|
1052
|
+
const cipherKey = (0, _conversion.bufferLikeToArrayBuffer)(exportedKey);
|
|
1053
|
+
|
|
1054
|
+
// AES-KW uses a default IV as specified in RFC 3394
|
|
1055
|
+
const defaultWrapIV = new Uint8Array([0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6]);
|
|
1056
|
+
const factory = _reactNativeNitroModules.NitroModules.createHybridObject('CipherFactory');
|
|
1057
|
+
const cipher = factory.createCipher({
|
|
1058
|
+
isCipher: isWrap,
|
|
1059
|
+
cipherType,
|
|
1060
|
+
cipherKey,
|
|
1061
|
+
iv: defaultWrapIV.buffer // RFC 3394 default IV for AES-KW
|
|
1062
|
+
});
|
|
1063
|
+
|
|
1064
|
+
// Process data
|
|
1065
|
+
const updated = cipher.update(data);
|
|
1066
|
+
const final = cipher.final();
|
|
1067
|
+
|
|
1068
|
+
// Concatenate results
|
|
1069
|
+
const result = new Uint8Array(updated.byteLength + final.byteLength);
|
|
1070
|
+
result.set(new Uint8Array(updated), 0);
|
|
1071
|
+
result.set(new Uint8Array(final), updated.byteLength);
|
|
1072
|
+
return result.buffer;
|
|
1073
|
+
}
|
|
1074
|
+
async function chaCha20Poly1305Cipher(mode, key, data, algorithm) {
|
|
1075
|
+
const {
|
|
1076
|
+
iv,
|
|
1077
|
+
additionalData,
|
|
1078
|
+
tagLength = 128
|
|
1079
|
+
} = algorithm;
|
|
1080
|
+
|
|
1081
|
+
// Validate IV (must be 12 bytes for ChaCha20-Poly1305)
|
|
1082
|
+
const ivBuffer = (0, _conversion.bufferLikeToArrayBuffer)(iv);
|
|
1083
|
+
if (!ivBuffer || ivBuffer.byteLength !== 12) {
|
|
1084
|
+
throw (0, _errors.lazyDOMException)('ChaCha20-Poly1305 IV must be exactly 12 bytes', 'OperationError');
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
// Validate tag length (only 128-bit supported)
|
|
1088
|
+
if (tagLength !== 128) {
|
|
1089
|
+
throw (0, _errors.lazyDOMException)('ChaCha20-Poly1305 only supports 128-bit auth tags', 'NotSupportedError');
|
|
1090
|
+
}
|
|
1091
|
+
const tagByteLength = 16; // 128 bits = 16 bytes
|
|
1092
|
+
|
|
1093
|
+
// Create cipher using existing ChaCha20-Poly1305 implementation
|
|
1094
|
+
const factory = _reactNativeNitroModules.NitroModules.createHybridObject('CipherFactory');
|
|
1095
|
+
const cipher = factory.createCipher({
|
|
1096
|
+
isCipher: mode === CipherOrWrapMode.kWebCryptoCipherEncrypt,
|
|
1097
|
+
cipherType: 'chacha20-poly1305',
|
|
1098
|
+
cipherKey: (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.export()),
|
|
1099
|
+
iv: ivBuffer,
|
|
1100
|
+
authTagLen: tagByteLength
|
|
1101
|
+
});
|
|
1102
|
+
let processData;
|
|
1103
|
+
let authTag;
|
|
1104
|
+
if (mode === CipherOrWrapMode.kWebCryptoCipherDecrypt) {
|
|
1105
|
+
// For decryption, extract auth tag from end of data
|
|
1106
|
+
const dataView = new Uint8Array(data);
|
|
1107
|
+
if (dataView.byteLength < tagByteLength) {
|
|
1108
|
+
throw (0, _errors.lazyDOMException)('The provided data is too small.', 'OperationError');
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
// Split data and tag
|
|
1112
|
+
const ciphertextLength = dataView.byteLength - tagByteLength;
|
|
1113
|
+
processData = dataView.slice(0, ciphertextLength).buffer;
|
|
1114
|
+
authTag = dataView.slice(ciphertextLength).buffer;
|
|
1115
|
+
|
|
1116
|
+
// Set auth tag for verification
|
|
1117
|
+
cipher.setAuthTag(authTag);
|
|
1118
|
+
} else {
|
|
1119
|
+
processData = data;
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
// Set additional authenticated data if provided
|
|
1123
|
+
if (additionalData) {
|
|
1124
|
+
cipher.setAAD((0, _conversion.bufferLikeToArrayBuffer)(additionalData));
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
// Process data
|
|
1128
|
+
const updated = cipher.update(processData);
|
|
1129
|
+
const final = cipher.final();
|
|
1130
|
+
if (mode === CipherOrWrapMode.kWebCryptoCipherEncrypt) {
|
|
1131
|
+
// For encryption, append auth tag to result
|
|
1132
|
+
const tag = cipher.getAuthTag();
|
|
1133
|
+
const result = new Uint8Array(updated.byteLength + final.byteLength + tag.byteLength);
|
|
1134
|
+
result.set(new Uint8Array(updated), 0);
|
|
1135
|
+
result.set(new Uint8Array(final), updated.byteLength);
|
|
1136
|
+
result.set(new Uint8Array(tag), updated.byteLength + final.byteLength);
|
|
1137
|
+
return result.buffer;
|
|
1138
|
+
} else {
|
|
1139
|
+
// For decryption, just concatenate plaintext
|
|
1140
|
+
const result = new Uint8Array(updated.byteLength + final.byteLength);
|
|
1141
|
+
result.set(new Uint8Array(updated), 0);
|
|
1142
|
+
result.set(new Uint8Array(final), updated.byteLength);
|
|
1143
|
+
return result.buffer;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
async function aesGenerateKey(algorithm, extractable, keyUsages) {
|
|
1147
|
+
const {
|
|
1148
|
+
length
|
|
1149
|
+
} = algorithm;
|
|
1150
|
+
const name = algorithm.name;
|
|
1151
|
+
if (!name) {
|
|
1152
|
+
throw (0, _errors.lazyDOMException)('Algorithm name is required', 'OperationError');
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
// Validate key length
|
|
1156
|
+
if (![128, 192, 256].includes(length)) {
|
|
1157
|
+
throw (0, _errors.lazyDOMException)(`Invalid AES key length: ${length}. Must be 128, 192, or 256.`, 'OperationError');
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// Validate usages
|
|
1161
|
+
const validUsages = ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'];
|
|
1162
|
+
if (hasAnyNotIn(keyUsages, validUsages)) {
|
|
1163
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name}`, 'SyntaxError');
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
// Generate random key bytes
|
|
1167
|
+
const keyBytes = new Uint8Array(length / 8);
|
|
1168
|
+
(0, _random.getRandomValues)(keyBytes);
|
|
1169
|
+
|
|
1170
|
+
// Create secret key
|
|
1171
|
+
const keyObject = (0, _keys.createSecretKey)(keyBytes);
|
|
1172
|
+
|
|
1173
|
+
// Construct algorithm object with guaranteed name
|
|
1174
|
+
const keyAlgorithm = {
|
|
1175
|
+
name,
|
|
1176
|
+
length
|
|
1177
|
+
};
|
|
1178
|
+
return new _keys.CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
|
|
1179
|
+
}
|
|
1180
|
+
async function hmacGenerateKey(algorithm, extractable, keyUsages) {
|
|
1181
|
+
// Validate usages
|
|
1182
|
+
if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
|
|
1183
|
+
throw (0, _errors.lazyDOMException)('Unsupported key usage for HMAC key', 'SyntaxError');
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
// Get hash algorithm
|
|
1187
|
+
const hash = algorithm.hash;
|
|
1188
|
+
if (!hash) {
|
|
1189
|
+
throw (0, _errors.lazyDOMException)('HMAC algorithm requires a hash parameter', 'TypeError');
|
|
1190
|
+
}
|
|
1191
|
+
const hashName = (0, _hashnames.normalizeHashName)(hash);
|
|
1192
|
+
|
|
1193
|
+
// Determine key length
|
|
1194
|
+
let length = algorithm.length;
|
|
1195
|
+
if (length === undefined) {
|
|
1196
|
+
// Use hash output length as default key length
|
|
1197
|
+
switch (hashName) {
|
|
1198
|
+
case 'SHA-1':
|
|
1199
|
+
length = 160;
|
|
1200
|
+
break;
|
|
1201
|
+
case 'SHA-256':
|
|
1202
|
+
length = 256;
|
|
1203
|
+
break;
|
|
1204
|
+
case 'SHA-384':
|
|
1205
|
+
length = 384;
|
|
1206
|
+
break;
|
|
1207
|
+
case 'SHA-512':
|
|
1208
|
+
length = 512;
|
|
1209
|
+
break;
|
|
1210
|
+
default:
|
|
1211
|
+
length = 256;
|
|
1212
|
+
// Default to 256 bits
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
if (length === 0) {
|
|
1216
|
+
throw (0, _errors.lazyDOMException)('Zero-length key is not supported', 'OperationError');
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
// Generate random key bytes
|
|
1220
|
+
const keyBytes = new Uint8Array(Math.ceil(length / 8));
|
|
1221
|
+
(0, _random.getRandomValues)(keyBytes);
|
|
1222
|
+
|
|
1223
|
+
// Create secret key
|
|
1224
|
+
const keyObject = (0, _keys.createSecretKey)(keyBytes);
|
|
1225
|
+
|
|
1226
|
+
// Construct algorithm object with hash normalized to { name: string } format per WebCrypto spec
|
|
1227
|
+
const webCryptoHashName = (0, _hashnames.normalizeHashName)(hash, _hashnames.HashContext.WebCrypto);
|
|
1228
|
+
const keyAlgorithm = {
|
|
1229
|
+
name: 'HMAC',
|
|
1230
|
+
hash: {
|
|
1231
|
+
name: webCryptoHashName
|
|
1232
|
+
},
|
|
1233
|
+
length
|
|
1234
|
+
};
|
|
1235
|
+
return new _keys.CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
|
|
1236
|
+
}
|
|
1237
|
+
async function kmacGenerateKey(algorithm, extractable, keyUsages) {
|
|
1238
|
+
const {
|
|
1239
|
+
name
|
|
1240
|
+
} = algorithm;
|
|
1241
|
+
if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
|
|
1242
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
1243
|
+
}
|
|
1244
|
+
const defaultLength = name === 'KMAC128' ? 128 : 256;
|
|
1245
|
+
const length = algorithm.length ?? defaultLength;
|
|
1246
|
+
if (length === 0) {
|
|
1247
|
+
throw (0, _errors.lazyDOMException)('Zero-length key is not supported', 'OperationError');
|
|
1248
|
+
}
|
|
1249
|
+
const keyBytes = new Uint8Array(Math.ceil(length / 8));
|
|
1250
|
+
(0, _random.getRandomValues)(keyBytes);
|
|
1251
|
+
const keyObject = (0, _keys.createSecretKey)(keyBytes);
|
|
1252
|
+
const keyAlgorithm = {
|
|
1253
|
+
name: name,
|
|
1254
|
+
length
|
|
1255
|
+
};
|
|
1256
|
+
return new _keys.CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
|
|
1257
|
+
}
|
|
1258
|
+
function kmacSignVerify(key, data, algorithm, signature) {
|
|
1259
|
+
const {
|
|
1260
|
+
name
|
|
1261
|
+
} = algorithm;
|
|
1262
|
+
|
|
1263
|
+
// KmacParams.outputLength is required per
|
|
1264
|
+
// https://wicg.github.io/webcrypto-modern-algos/#KmacParams-dictionary
|
|
1265
|
+
// and the rename from `length` (commit ab8dc2b84c2). Mirror Node's
|
|
1266
|
+
// mac.js:213-223 by reading `outputLength` (in bits).
|
|
1267
|
+
if (typeof algorithm.outputLength !== 'number') {
|
|
1268
|
+
throw (0, _errors.lazyDOMException)(`${name}Params.outputLength is required`, 'OperationError');
|
|
1269
|
+
}
|
|
1270
|
+
const outputLengthBits = algorithm.outputLength;
|
|
1271
|
+
if (outputLengthBits % 8 !== 0) {
|
|
1272
|
+
throw (0, _errors.lazyDOMException)(`Unsupported ${name}Params outputLength`, 'NotSupportedError');
|
|
1273
|
+
}
|
|
1274
|
+
const outputLengthBytes = outputLengthBits / 8;
|
|
1275
|
+
const keyData = key.keyObject.export();
|
|
1276
|
+
const kmac = _reactNativeNitroModules.NitroModules.createHybridObject('Kmac');
|
|
1277
|
+
let customizationBuffer;
|
|
1278
|
+
if (algorithm.customization !== undefined) {
|
|
1279
|
+
customizationBuffer = (0, _conversion.bufferLikeToArrayBuffer)(algorithm.customization);
|
|
1280
|
+
}
|
|
1281
|
+
kmac.createKmac(name, (0, _conversion.bufferLikeToArrayBuffer)(keyData), outputLengthBytes, customizationBuffer);
|
|
1282
|
+
kmac.update((0, _conversion.bufferLikeToArrayBuffer)(data));
|
|
1283
|
+
const computed = kmac.digest();
|
|
1284
|
+
if (signature === undefined) {
|
|
1285
|
+
return computed;
|
|
1286
|
+
}
|
|
1287
|
+
const sigBuffer = (0, _conversion.bufferLikeToArrayBuffer)(signature);
|
|
1288
|
+
if (computed.byteLength !== sigBuffer.byteLength) {
|
|
1289
|
+
return false;
|
|
1290
|
+
}
|
|
1291
|
+
return (0, _timingSafeEqual.timingSafeEqual)(new Uint8Array(computed), new Uint8Array(sigBuffer));
|
|
1292
|
+
}
|
|
1293
|
+
async function kmacImportKey(algorithm, format, data, extractable, keyUsages) {
|
|
1294
|
+
const {
|
|
1295
|
+
name
|
|
1296
|
+
} = algorithm;
|
|
1297
|
+
let keyObject;
|
|
1298
|
+
if (format === 'jwk') {
|
|
1299
|
+
const jwk = data;
|
|
1300
|
+
if (!jwk || typeof jwk !== 'object') {
|
|
1301
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', 'DataError');
|
|
1302
|
+
}
|
|
1303
|
+
if (jwk.kty !== 'oct') {
|
|
1304
|
+
throw (0, _errors.lazyDOMException)('Invalid JWK "kty" Parameter', 'DataError');
|
|
1305
|
+
}
|
|
1306
|
+
(0, _validation.validateJwkStructure)(jwk, extractable, keyUsages, 'sig');
|
|
1307
|
+
const expectedAlg = name === 'KMAC128' ? 'K128' : 'K256';
|
|
1308
|
+
if (jwk.alg !== undefined && jwk.alg !== expectedAlg) {
|
|
1309
|
+
throw (0, _errors.lazyDOMException)('JWK "alg" Parameter and algorithm name mismatch', 'DataError');
|
|
1310
|
+
}
|
|
1311
|
+
if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
|
|
1312
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
1313
|
+
}
|
|
1314
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
1315
|
+
let keyType;
|
|
1316
|
+
try {
|
|
1317
|
+
keyType = handle.initJwk(jwk, undefined);
|
|
1318
|
+
} catch (err) {
|
|
1319
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', {
|
|
1320
|
+
name: 'DataError',
|
|
1321
|
+
cause: err
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
if (keyType === undefined || keyType !== 0) {
|
|
1325
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', 'DataError');
|
|
1326
|
+
}
|
|
1327
|
+
keyObject = new _keys.SecretKeyObject(handle);
|
|
1328
|
+
} else if (format === 'raw-secret') {
|
|
1329
|
+
// KMAC accepts only the disambiguated 'raw-secret' form (Node mac.js:141-145
|
|
1330
|
+
// returns undefined for plain 'raw' when not HMAC).
|
|
1331
|
+
if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
|
|
1332
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
1333
|
+
}
|
|
1334
|
+
keyObject = (0, _keys.createSecretKey)(data);
|
|
1335
|
+
} else {
|
|
1336
|
+
throw (0, _errors.lazyDOMException)(`Unable to import ${name} key with format ${format}`, 'NotSupportedError');
|
|
1337
|
+
}
|
|
1338
|
+
const exported = keyObject.export();
|
|
1339
|
+
const keyLength = exported.byteLength * 8;
|
|
1340
|
+
if (keyLength === 0) {
|
|
1341
|
+
throw (0, _errors.lazyDOMException)('Zero-length key is not supported', 'DataError');
|
|
1342
|
+
}
|
|
1343
|
+
if (algorithm.length !== undefined && algorithm.length !== keyLength) {
|
|
1344
|
+
throw (0, _errors.lazyDOMException)('Invalid key length', 'DataError');
|
|
1345
|
+
}
|
|
1346
|
+
const keyAlgorithm = {
|
|
1347
|
+
name: name,
|
|
1348
|
+
length: keyLength
|
|
1349
|
+
};
|
|
1350
|
+
return new _keys.CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
|
|
1351
|
+
}
|
|
1352
|
+
function rsaImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
1353
|
+
const {
|
|
1354
|
+
name
|
|
1355
|
+
} = algorithm;
|
|
1356
|
+
let checkSet;
|
|
1357
|
+
switch (name) {
|
|
1358
|
+
case 'RSASSA-PKCS1-v1_5':
|
|
1359
|
+
case 'RSA-PSS':
|
|
1360
|
+
checkSet = ['sign', 'verify'];
|
|
1361
|
+
break;
|
|
1362
|
+
case 'RSA-OAEP':
|
|
1363
|
+
checkSet = ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'];
|
|
1364
|
+
break;
|
|
1365
|
+
default:
|
|
1366
|
+
throw new Error(`Unsupported RSA algorithm: ${name}`);
|
|
1367
|
+
}
|
|
1368
|
+
const checkUsages = () => {
|
|
1369
|
+
if (hasAnyNotIn(keyUsages, checkSet)) {
|
|
1370
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
1371
|
+
}
|
|
1372
|
+
};
|
|
1373
|
+
let keyObject;
|
|
1374
|
+
if (format === 'jwk') {
|
|
1375
|
+
const jwk = data;
|
|
1376
|
+
if (!jwk || typeof jwk !== 'object') {
|
|
1377
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', 'DataError');
|
|
1378
|
+
}
|
|
1379
|
+
if (jwk.kty !== 'RSA') {
|
|
1380
|
+
throw (0, _errors.lazyDOMException)('Invalid JWK "kty" Parameter', 'DataError');
|
|
1381
|
+
}
|
|
1382
|
+
const expectedUse = name === 'RSA-OAEP' ? 'enc' : 'sig';
|
|
1383
|
+
(0, _validation.validateJwkStructure)(jwk, extractable, keyUsages, expectedUse);
|
|
1384
|
+
checkUsages();
|
|
1385
|
+
if (jwk.alg !== undefined) {
|
|
1386
|
+
let jwkContext;
|
|
1387
|
+
switch (name) {
|
|
1388
|
+
case 'RSASSA-PKCS1-v1_5':
|
|
1389
|
+
jwkContext = _hashnames.HashContext.JwkRsa;
|
|
1390
|
+
break;
|
|
1391
|
+
case 'RSA-PSS':
|
|
1392
|
+
jwkContext = _hashnames.HashContext.JwkRsaPss;
|
|
1393
|
+
break;
|
|
1394
|
+
default:
|
|
1395
|
+
jwkContext = _hashnames.HashContext.JwkRsaOaep;
|
|
1396
|
+
}
|
|
1397
|
+
const expectedAlg = (0, _hashnames.normalizeHashName)(algorithm.hash, jwkContext);
|
|
1398
|
+
if (jwk.alg !== expectedAlg) {
|
|
1399
|
+
throw (0, _errors.lazyDOMException)('JWK "alg" does not match the requested algorithm', 'DataError');
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
1403
|
+
let keyType;
|
|
1404
|
+
try {
|
|
1405
|
+
keyType = handle.initJwk(jwk, undefined);
|
|
1406
|
+
} catch (err) {
|
|
1407
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', {
|
|
1408
|
+
name: 'DataError',
|
|
1409
|
+
cause: err
|
|
1410
|
+
});
|
|
1411
|
+
}
|
|
1412
|
+
if (keyType === undefined) {
|
|
1413
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', 'DataError');
|
|
1414
|
+
}
|
|
1415
|
+
if (keyType === _utils.KeyType.PUBLIC) {
|
|
1416
|
+
keyObject = new _keys.PublicKeyObject(handle);
|
|
1417
|
+
} else if (keyType === _utils.KeyType.PRIVATE) {
|
|
1418
|
+
keyObject = new _keys.PrivateKeyObject(handle);
|
|
1419
|
+
} else {
|
|
1420
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', 'DataError');
|
|
1421
|
+
}
|
|
1422
|
+
} else if (format === 'spki') {
|
|
1423
|
+
checkUsages();
|
|
1424
|
+
const keyData = (0, _conversion.bufferLikeToArrayBuffer)(data);
|
|
1425
|
+
keyObject = _keys.KeyObject.createKeyObject('public', keyData, _utils.KFormatType.DER, _utils.KeyEncoding.SPKI);
|
|
1426
|
+
} else if (format === 'pkcs8') {
|
|
1427
|
+
checkUsages();
|
|
1428
|
+
const keyData = (0, _conversion.bufferLikeToArrayBuffer)(data);
|
|
1429
|
+
keyObject = _keys.KeyObject.createKeyObject('private', keyData, _utils.KFormatType.DER, _utils.KeyEncoding.PKCS8);
|
|
1430
|
+
} else {
|
|
1431
|
+
throw (0, _errors.lazyDOMException)(`Unsupported format for ${name} import: ${format}`, 'NotSupportedError');
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
// Get the modulus length from the key and add it to the algorithm
|
|
1435
|
+
const keyDetails = keyObject.asymmetricKeyDetails;
|
|
1436
|
+
|
|
1437
|
+
// Convert publicExponent number to big-endian byte array
|
|
1438
|
+
let publicExponentBytes;
|
|
1439
|
+
if (keyDetails?.publicExponent) {
|
|
1440
|
+
const exp = keyDetails.publicExponent;
|
|
1441
|
+
// Convert number to big-endian bytes
|
|
1442
|
+
const bytes = [];
|
|
1443
|
+
let value = exp;
|
|
1444
|
+
while (value > 0) {
|
|
1445
|
+
bytes.unshift(value & 0xff);
|
|
1446
|
+
value = Math.floor(value / 256);
|
|
1447
|
+
}
|
|
1448
|
+
publicExponentBytes = new Uint8Array(bytes.length > 0 ? bytes : [0]);
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
// Normalize hash to { name: string } format per WebCrypto spec
|
|
1452
|
+
const hashName = (0, _hashnames.normalizeHashName)(algorithm.hash, _hashnames.HashContext.WebCrypto);
|
|
1453
|
+
const normalizedHash = {
|
|
1454
|
+
name: hashName
|
|
1455
|
+
};
|
|
1456
|
+
const algorithmWithDetails = {
|
|
1457
|
+
...algorithm,
|
|
1458
|
+
modulusLength: keyDetails?.modulusLength,
|
|
1459
|
+
publicExponent: publicExponentBytes,
|
|
1460
|
+
hash: normalizedHash
|
|
1461
|
+
};
|
|
1462
|
+
return new _keys.CryptoKey(keyObject, algorithmWithDetails, keyUsages, extractable);
|
|
1463
|
+
}
|
|
1464
|
+
async function hmacImportKey(algorithm, format, data, extractable, keyUsages) {
|
|
1465
|
+
const checkUsages = () => {
|
|
1466
|
+
if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
|
|
1467
|
+
throw new Error('Unsupported key usage for an HMAC key');
|
|
1468
|
+
}
|
|
1469
|
+
};
|
|
1470
|
+
let keyObject;
|
|
1471
|
+
if (format === 'jwk') {
|
|
1472
|
+
const jwk = data;
|
|
1473
|
+
if (!jwk || typeof jwk !== 'object') {
|
|
1474
|
+
throw new Error('Invalid keyData');
|
|
1475
|
+
}
|
|
1476
|
+
if (jwk.kty !== 'oct') {
|
|
1477
|
+
throw new Error('Invalid JWK format for HMAC key');
|
|
1478
|
+
}
|
|
1479
|
+
(0, _validation.validateJwkStructure)(jwk, extractable, keyUsages, 'sig');
|
|
1480
|
+
checkUsages();
|
|
1481
|
+
if (algorithm.length !== undefined) {
|
|
1482
|
+
if (!jwk.k) {
|
|
1483
|
+
throw new Error('JWK missing key data');
|
|
1484
|
+
}
|
|
1485
|
+
const decoded = _safeBuffer.Buffer.from(jwk.k, 'base64');
|
|
1486
|
+
const keyBitLength = decoded.length * 8;
|
|
1487
|
+
if (algorithm.length === 0) {
|
|
1488
|
+
throw new Error('Zero-length key is not supported');
|
|
1489
|
+
}
|
|
1490
|
+
if (algorithm.length !== keyBitLength) {
|
|
1491
|
+
throw new Error('Invalid key length');
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
1495
|
+
let keyType;
|
|
1496
|
+
try {
|
|
1497
|
+
keyType = handle.initJwk(jwk, undefined);
|
|
1498
|
+
} catch (err) {
|
|
1499
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', {
|
|
1500
|
+
name: 'DataError',
|
|
1501
|
+
cause: err
|
|
1502
|
+
});
|
|
1503
|
+
}
|
|
1504
|
+
if (keyType === undefined || keyType !== 0) {
|
|
1505
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', 'DataError');
|
|
1506
|
+
}
|
|
1507
|
+
keyObject = new _keys.SecretKeyObject(handle);
|
|
1508
|
+
} else if (format === 'raw' || format === 'raw-secret') {
|
|
1509
|
+
// HMAC accepts both 'raw' and 'raw-secret' (Node mac.js:141-145).
|
|
1510
|
+
checkUsages();
|
|
1511
|
+
keyObject = (0, _keys.createSecretKey)(data);
|
|
1512
|
+
} else {
|
|
1513
|
+
throw (0, _errors.lazyDOMException)(`Unable to import HMAC key with format ${format}`, 'NotSupportedError');
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
// Normalize hash to { name: string } format per WebCrypto spec
|
|
1517
|
+
const hashName = (0, _hashnames.normalizeHashName)(algorithm.hash, _hashnames.HashContext.WebCrypto);
|
|
1518
|
+
const normalizedAlgorithm = {
|
|
1519
|
+
...algorithm,
|
|
1520
|
+
name: 'HMAC',
|
|
1521
|
+
hash: {
|
|
1522
|
+
name: hashName
|
|
1523
|
+
}
|
|
1524
|
+
};
|
|
1525
|
+
return new _keys.CryptoKey(keyObject, normalizedAlgorithm, keyUsages, extractable);
|
|
1526
|
+
}
|
|
1527
|
+
async function aesImportKey(algorithm, format, data, extractable, keyUsages) {
|
|
1528
|
+
const {
|
|
1529
|
+
name,
|
|
1530
|
+
length
|
|
1531
|
+
} = algorithm;
|
|
1532
|
+
const validUsages = ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'];
|
|
1533
|
+
const checkUsages = () => {
|
|
1534
|
+
if (hasAnyNotIn(keyUsages, validUsages)) {
|
|
1535
|
+
throw new Error(`Unsupported key usage for ${name}`);
|
|
1536
|
+
}
|
|
1537
|
+
};
|
|
1538
|
+
|
|
1539
|
+
// AES-OCB and ChaCha20-Poly1305 require the disambiguated 'raw-secret' form
|
|
1540
|
+
// and reject 'raw' (Node aes.js:243-249, chacha20_poly1305.js:104-134).
|
|
1541
|
+
// Other AES variants accept both 'raw' and 'raw-secret'.
|
|
1542
|
+
const requiresRawSecret = name === 'AES-OCB' || name === 'ChaCha20-Poly1305';
|
|
1543
|
+
const acceptsRaw = format === 'raw-secret' || format === 'raw' && !requiresRawSecret;
|
|
1544
|
+
let keyObject;
|
|
1545
|
+
let actualLength;
|
|
1546
|
+
if (format === 'jwk') {
|
|
1547
|
+
const jwk = data;
|
|
1548
|
+
if (jwk.kty !== 'oct') {
|
|
1549
|
+
throw new Error('Invalid JWK format for AES key');
|
|
1550
|
+
}
|
|
1551
|
+
(0, _validation.validateJwkStructure)(jwk, extractable, keyUsages, 'enc');
|
|
1552
|
+
checkUsages();
|
|
1553
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
1554
|
+
let keyType;
|
|
1555
|
+
try {
|
|
1556
|
+
keyType = handle.initJwk(jwk, undefined);
|
|
1557
|
+
} catch (err) {
|
|
1558
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', {
|
|
1559
|
+
name: 'DataError',
|
|
1560
|
+
cause: err
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
if (keyType === undefined || keyType !== 0) {
|
|
1564
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', 'DataError');
|
|
1565
|
+
}
|
|
1566
|
+
keyObject = new _keys.SecretKeyObject(handle);
|
|
1567
|
+
const exported = keyObject.export();
|
|
1568
|
+
actualLength = exported.byteLength * 8;
|
|
1569
|
+
} else if (acceptsRaw) {
|
|
1570
|
+
checkUsages();
|
|
1571
|
+
const keyData = (0, _conversion.bufferLikeToArrayBuffer)(data);
|
|
1572
|
+
actualLength = keyData.byteLength * 8;
|
|
1573
|
+
if (name === 'ChaCha20-Poly1305') {
|
|
1574
|
+
if (actualLength !== 256) {
|
|
1575
|
+
throw (0, _errors.lazyDOMException)('Invalid ChaCha20-Poly1305 key length', 'DataError');
|
|
1576
|
+
}
|
|
1577
|
+
} else if (![128, 192, 256].includes(actualLength)) {
|
|
1578
|
+
throw new Error('Invalid AES key length');
|
|
1579
|
+
}
|
|
1580
|
+
keyObject = (0, _keys.createSecretKey)(keyData);
|
|
1581
|
+
} else {
|
|
1582
|
+
throw (0, _errors.lazyDOMException)(`Unable to import ${name} key with format ${format}`, 'NotSupportedError');
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
// Validate length if specified
|
|
1586
|
+
if (length !== undefined && length !== actualLength) {
|
|
1587
|
+
throw new Error(`Key length mismatch: expected ${length}, got ${actualLength}`);
|
|
1588
|
+
}
|
|
1589
|
+
return new _keys.CryptoKey(keyObject, {
|
|
1590
|
+
name,
|
|
1591
|
+
length: actualLength
|
|
1592
|
+
}, keyUsages, extractable);
|
|
1593
|
+
}
|
|
1594
|
+
function edImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
1595
|
+
const {
|
|
1596
|
+
name
|
|
1597
|
+
} = algorithm;
|
|
1598
|
+
const isX = name === 'X25519' || name === 'X448';
|
|
1599
|
+
const allowedUsages = isX ? ['deriveKey', 'deriveBits'] : ['sign', 'verify'];
|
|
1600
|
+
const checkUsages = () => {
|
|
1601
|
+
if (hasAnyNotIn(keyUsages, allowedUsages)) {
|
|
1602
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
1603
|
+
}
|
|
1604
|
+
};
|
|
1605
|
+
let keyObject;
|
|
1606
|
+
if (format === 'spki') {
|
|
1607
|
+
checkUsages();
|
|
1608
|
+
const keyData = (0, _conversion.bufferLikeToArrayBuffer)(data);
|
|
1609
|
+
keyObject = _keys.KeyObject.createKeyObject('public', keyData, _utils.KFormatType.DER, _utils.KeyEncoding.SPKI);
|
|
1610
|
+
} else if (format === 'pkcs8') {
|
|
1611
|
+
checkUsages();
|
|
1612
|
+
const keyData = (0, _conversion.bufferLikeToArrayBuffer)(data);
|
|
1613
|
+
keyObject = _keys.KeyObject.createKeyObject('private', keyData, _utils.KFormatType.DER, _utils.KeyEncoding.PKCS8);
|
|
1614
|
+
} else if (format === 'raw') {
|
|
1615
|
+
checkUsages();
|
|
1616
|
+
const keyData = (0, _conversion.bufferLikeToArrayBuffer)(data);
|
|
1617
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
1618
|
+
handle.init(1, keyData);
|
|
1619
|
+
keyObject = new _keys.PublicKeyObject(handle);
|
|
1620
|
+
} else if (format === 'jwk') {
|
|
1621
|
+
const jwkData = data;
|
|
1622
|
+
if (!jwkData || typeof jwkData !== 'object') {
|
|
1623
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', 'DataError');
|
|
1624
|
+
}
|
|
1625
|
+
if (jwkData.kty !== 'OKP') {
|
|
1626
|
+
throw (0, _errors.lazyDOMException)('Invalid JWK "kty" Parameter', 'DataError');
|
|
1627
|
+
}
|
|
1628
|
+
const expectedUse = isX ? 'enc' : 'sig';
|
|
1629
|
+
(0, _validation.validateJwkStructure)(jwkData, extractable, keyUsages, expectedUse);
|
|
1630
|
+
if (jwkData.crv !== name) {
|
|
1631
|
+
throw (0, _errors.lazyDOMException)('JWK "crv" Parameter and algorithm name mismatch', 'DataError');
|
|
1632
|
+
}
|
|
1633
|
+
if (!isX && jwkData.alg !== undefined) {
|
|
1634
|
+
if (jwkData.alg !== name && jwkData.alg !== 'EdDSA') {
|
|
1635
|
+
throw (0, _errors.lazyDOMException)('JWK "alg" does not match the requested algorithm', 'DataError');
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
checkUsages();
|
|
1639
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
1640
|
+
let keyType;
|
|
1641
|
+
try {
|
|
1642
|
+
keyType = handle.initJwk(jwkData);
|
|
1643
|
+
} catch (err) {
|
|
1644
|
+
throw (0, _errors.lazyDOMException)('Invalid JWK data', {
|
|
1645
|
+
name: 'DataError',
|
|
1646
|
+
cause: err
|
|
1647
|
+
});
|
|
1648
|
+
}
|
|
1649
|
+
if (keyType === undefined) {
|
|
1650
|
+
throw (0, _errors.lazyDOMException)('Invalid JWK data', 'DataError');
|
|
1651
|
+
}
|
|
1652
|
+
if (keyType === _utils.KeyType.PRIVATE) {
|
|
1653
|
+
keyObject = new _keys.PrivateKeyObject(handle);
|
|
1654
|
+
} else {
|
|
1655
|
+
keyObject = new _keys.PublicKeyObject(handle);
|
|
1656
|
+
}
|
|
1657
|
+
} else {
|
|
1658
|
+
throw (0, _errors.lazyDOMException)(`Unsupported format for ${name} import: ${format}`, 'NotSupportedError');
|
|
1659
|
+
}
|
|
1660
|
+
return new _keys.CryptoKey(keyObject, {
|
|
1661
|
+
name
|
|
1662
|
+
}, keyUsages, extractable);
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
// Lengths (in bytes) of seedless ML-DSA / ML-KEM PKCS#8 encodings. A PKCS#8
|
|
1666
|
+
// blob of exactly this length contains only the expanded private key with no
|
|
1667
|
+
// seed; Node rejects these to keep cross-implementation interop intact.
|
|
1668
|
+
// Refs: node lib/internal/crypto/ml_dsa.js (mlDsaImportKey, pkcs8 case)
|
|
1669
|
+
// node lib/internal/crypto/ml_kem.js (mlKemImportKey, pkcs8 case)
|
|
1670
|
+
const PQC_SEEDLESS_PKCS8_LENGTHS = exports.PQC_SEEDLESS_PKCS8_LENGTHS = {
|
|
1671
|
+
'ML-DSA-44': 2588,
|
|
1672
|
+
'ML-DSA-65': 4060,
|
|
1673
|
+
'ML-DSA-87': 4924,
|
|
1674
|
+
'ML-KEM-512': 1660,
|
|
1675
|
+
'ML-KEM-768': 2428,
|
|
1676
|
+
'ML-KEM-1024': 3196
|
|
1677
|
+
};
|
|
1678
|
+
|
|
1679
|
+
// Map from PQC algorithm name to display family. Used to render the
|
|
1680
|
+
// import-rejection error message in the same form Node emits.
|
|
1681
|
+
const PQC_FAMILY = {
|
|
1682
|
+
'ML-DSA-44': 'ML-DSA',
|
|
1683
|
+
'ML-DSA-65': 'ML-DSA',
|
|
1684
|
+
'ML-DSA-87': 'ML-DSA',
|
|
1685
|
+
'ML-KEM-512': 'ML-KEM',
|
|
1686
|
+
'ML-KEM-768': 'ML-KEM',
|
|
1687
|
+
'ML-KEM-1024': 'ML-KEM',
|
|
1688
|
+
'SLH-DSA-SHA2-128s': 'SLH-DSA',
|
|
1689
|
+
'SLH-DSA-SHA2-128f': 'SLH-DSA',
|
|
1690
|
+
'SLH-DSA-SHA2-192s': 'SLH-DSA',
|
|
1691
|
+
'SLH-DSA-SHA2-192f': 'SLH-DSA',
|
|
1692
|
+
'SLH-DSA-SHA2-256s': 'SLH-DSA',
|
|
1693
|
+
'SLH-DSA-SHA2-256f': 'SLH-DSA',
|
|
1694
|
+
'SLH-DSA-SHAKE-128s': 'SLH-DSA',
|
|
1695
|
+
'SLH-DSA-SHAKE-128f': 'SLH-DSA',
|
|
1696
|
+
'SLH-DSA-SHAKE-192s': 'SLH-DSA',
|
|
1697
|
+
'SLH-DSA-SHAKE-192f': 'SLH-DSA',
|
|
1698
|
+
'SLH-DSA-SHAKE-256s': 'SLH-DSA',
|
|
1699
|
+
'SLH-DSA-SHAKE-256f': 'SLH-DSA'
|
|
1700
|
+
};
|
|
1701
|
+
function pqcImportKeyObject(format, data, name) {
|
|
1702
|
+
if (format === 'spki') {
|
|
1703
|
+
return {
|
|
1704
|
+
keyObject: _keys.KeyObject.createKeyObject('public', (0, _conversion.bufferLikeToArrayBuffer)(data), _utils.KFormatType.DER, _utils.KeyEncoding.SPKI),
|
|
1705
|
+
isPublic: true
|
|
1706
|
+
};
|
|
1707
|
+
} else if (format === 'pkcs8') {
|
|
1708
|
+
const ab = (0, _conversion.bufferLikeToArrayBuffer)(data);
|
|
1709
|
+
const family = PQC_FAMILY[name];
|
|
1710
|
+
if (family !== undefined && ab.byteLength === PQC_SEEDLESS_PKCS8_LENGTHS[name]) {
|
|
1711
|
+
throw (0, _errors.lazyDOMException)(`Importing an ${family} PKCS#8 key without a seed is not supported`, 'NotSupportedError');
|
|
1712
|
+
}
|
|
1713
|
+
return {
|
|
1714
|
+
keyObject: _keys.KeyObject.createKeyObject('private', ab, _utils.KFormatType.DER, _utils.KeyEncoding.PKCS8),
|
|
1715
|
+
isPublic: false
|
|
1716
|
+
};
|
|
1717
|
+
} else if (format === 'raw-public') {
|
|
1718
|
+
// ML-DSA / ML-KEM reject plain 'raw' — only 'raw-public' is accepted for
|
|
1719
|
+
// public-key import (Node webcrypto.js:493-499, 506-511).
|
|
1720
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
1721
|
+
if (!handle.initPqcRaw(name, (0, _conversion.bufferLikeToArrayBuffer)(data), true)) {
|
|
1722
|
+
throw (0, _errors.lazyDOMException)(`Failed to import ${name} raw public key`, 'DataError');
|
|
1723
|
+
}
|
|
1724
|
+
return {
|
|
1725
|
+
keyObject: new _keys.PublicKeyObject(handle),
|
|
1726
|
+
isPublic: true
|
|
1727
|
+
};
|
|
1728
|
+
} else if (format === 'raw-seed') {
|
|
1729
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
1730
|
+
if (!handle.initPqcRaw(name, (0, _conversion.bufferLikeToArrayBuffer)(data), false)) {
|
|
1731
|
+
throw (0, _errors.lazyDOMException)(`Failed to import ${name} raw seed`, 'DataError');
|
|
1732
|
+
}
|
|
1733
|
+
return {
|
|
1734
|
+
keyObject: new _keys.PrivateKeyObject(handle),
|
|
1735
|
+
isPublic: false
|
|
1736
|
+
};
|
|
1737
|
+
} else if (format === 'jwk') {
|
|
1738
|
+
const jwkData = data;
|
|
1739
|
+
const isPublic = jwkData.priv === undefined;
|
|
1740
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
1741
|
+
let keyType;
|
|
1742
|
+
try {
|
|
1743
|
+
keyType = handle.initJwk(jwkData);
|
|
1744
|
+
} catch (err) {
|
|
1745
|
+
throw (0, _errors.lazyDOMException)('Invalid JWK data', {
|
|
1746
|
+
name: 'DataError',
|
|
1747
|
+
cause: err
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1750
|
+
if (keyType === undefined) {
|
|
1751
|
+
throw (0, _errors.lazyDOMException)('Invalid JWK data', 'DataError');
|
|
1752
|
+
}
|
|
1753
|
+
return {
|
|
1754
|
+
keyObject: isPublic ? new _keys.PublicKeyObject(handle) : new _keys.PrivateKeyObject(handle),
|
|
1755
|
+
isPublic
|
|
1756
|
+
};
|
|
1757
|
+
}
|
|
1758
|
+
throw (0, _errors.lazyDOMException)(`Unsupported format for ${name} import: ${format}`, 'NotSupportedError');
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
// Per WebCrypto AKP JWK rules, public-vs-private is determined by the presence
|
|
1762
|
+
// of `priv`. For binary formats it follows from the format itself.
|
|
1763
|
+
function pqcIsPublicImport(format, data) {
|
|
1764
|
+
if (format === 'jwk') {
|
|
1765
|
+
return typeof data === 'object' && data !== null && data.priv === undefined;
|
|
1766
|
+
}
|
|
1767
|
+
return format === 'spki' || format === 'raw-public';
|
|
1768
|
+
}
|
|
1769
|
+
function validatePqcJwk(data, name, extractable, keyUsages, expectedUse) {
|
|
1770
|
+
if (typeof data !== 'object' || data === null) {
|
|
1771
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', 'DataError');
|
|
1772
|
+
}
|
|
1773
|
+
const jwk = data;
|
|
1774
|
+
if (jwk.kty !== 'AKP') {
|
|
1775
|
+
throw (0, _errors.lazyDOMException)('Invalid JWK "kty" Parameter', 'DataError');
|
|
1776
|
+
}
|
|
1777
|
+
(0, _validation.validateJwkStructure)(jwk, extractable, keyUsages, expectedUse);
|
|
1778
|
+
if (jwk.alg !== name) {
|
|
1779
|
+
throw (0, _errors.lazyDOMException)('JWK "alg" Parameter and algorithm name mismatch', 'DataError');
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
// Validates that `format` is one of the formats PQC algorithms accept; rejects
|
|
1784
|
+
// plain 'raw' early so the format error wins over usage-based errors.
|
|
1785
|
+
function validatePqcFormat(format, name) {
|
|
1786
|
+
if (format !== 'spki' && format !== 'pkcs8' && format !== 'raw-public' && format !== 'raw-seed' && format !== 'jwk') {
|
|
1787
|
+
throw (0, _errors.lazyDOMException)(`Unsupported format for ${name} import: ${format}`, 'NotSupportedError');
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
function mldsaImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
1791
|
+
const {
|
|
1792
|
+
name
|
|
1793
|
+
} = algorithm;
|
|
1794
|
+
validatePqcFormat(format, name);
|
|
1795
|
+
if (format === 'jwk') {
|
|
1796
|
+
validatePqcJwk(data, name, extractable, keyUsages, 'sig');
|
|
1797
|
+
}
|
|
1798
|
+
const isPublic = pqcIsPublicImport(format, data);
|
|
1799
|
+
if (hasAnyNotIn(keyUsages, isPublic ? ['verify'] : ['sign'])) {
|
|
1800
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
1801
|
+
}
|
|
1802
|
+
const {
|
|
1803
|
+
keyObject
|
|
1804
|
+
} = pqcImportKeyObject(format, data, name);
|
|
1805
|
+
return new _keys.CryptoKey(keyObject, {
|
|
1806
|
+
name
|
|
1807
|
+
}, keyUsages, extractable);
|
|
1808
|
+
}
|
|
1809
|
+
function slhdsaImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
1810
|
+
return mldsaImportKey(format, data, algorithm, extractable, keyUsages);
|
|
1811
|
+
}
|
|
1812
|
+
function mlkemImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
1813
|
+
const {
|
|
1814
|
+
name
|
|
1815
|
+
} = algorithm;
|
|
1816
|
+
validatePqcFormat(format, name);
|
|
1817
|
+
if (format === 'jwk') {
|
|
1818
|
+
validatePqcJwk(data, name, extractable, keyUsages, 'enc');
|
|
1819
|
+
}
|
|
1820
|
+
const isPublic = pqcIsPublicImport(format, data);
|
|
1821
|
+
const allowedUsages = isPublic ? ['encapsulateBits', 'encapsulateKey'] : ['decapsulateBits', 'decapsulateKey'];
|
|
1822
|
+
if (hasAnyNotIn(keyUsages, allowedUsages)) {
|
|
1823
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
1824
|
+
}
|
|
1825
|
+
const {
|
|
1826
|
+
keyObject
|
|
1827
|
+
} = pqcImportKeyObject(format, data, name);
|
|
1828
|
+
return new _keys.CryptoKey(keyObject, {
|
|
1829
|
+
name
|
|
1830
|
+
}, keyUsages, extractable);
|
|
1831
|
+
}
|
|
1832
|
+
const exportKeySpki = async key => {
|
|
1833
|
+
switch (key.algorithm.name) {
|
|
1834
|
+
case 'RSASSA-PKCS1-v1_5':
|
|
1835
|
+
// Fall through
|
|
1836
|
+
case 'RSA-PSS':
|
|
1837
|
+
// Fall through
|
|
1838
|
+
case 'RSA-OAEP':
|
|
1839
|
+
if (key.type === 'public') {
|
|
1840
|
+
return rsaExportKey(key, KWebCryptoKeyFormat.kWebCryptoKeyFormatSPKI);
|
|
1841
|
+
}
|
|
1842
|
+
break;
|
|
1843
|
+
case 'ECDSA':
|
|
1844
|
+
// Fall through
|
|
1845
|
+
case 'ECDH':
|
|
1846
|
+
if (key.type === 'public') {
|
|
1847
|
+
return ecExportKey(key, KWebCryptoKeyFormat.kWebCryptoKeyFormatSPKI);
|
|
1848
|
+
}
|
|
1849
|
+
break;
|
|
1850
|
+
case 'Ed25519':
|
|
1851
|
+
// Fall through
|
|
1852
|
+
case 'Ed448':
|
|
1853
|
+
// Fall through
|
|
1854
|
+
case 'X25519':
|
|
1855
|
+
// Fall through
|
|
1856
|
+
case 'X448':
|
|
1857
|
+
if (key.type === 'public') {
|
|
1858
|
+
// Export Ed/X key in SPKI DER format
|
|
1859
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI));
|
|
1860
|
+
}
|
|
1861
|
+
break;
|
|
1862
|
+
case 'ML-DSA-44':
|
|
1863
|
+
// Fall through
|
|
1864
|
+
case 'ML-DSA-65':
|
|
1865
|
+
// Fall through
|
|
1866
|
+
case 'ML-DSA-87':
|
|
1867
|
+
// Fall through
|
|
1868
|
+
case 'SLH-DSA-SHA2-128s':
|
|
1869
|
+
case 'SLH-DSA-SHA2-128f':
|
|
1870
|
+
case 'SLH-DSA-SHA2-192s':
|
|
1871
|
+
case 'SLH-DSA-SHA2-192f':
|
|
1872
|
+
case 'SLH-DSA-SHA2-256s':
|
|
1873
|
+
case 'SLH-DSA-SHA2-256f':
|
|
1874
|
+
case 'SLH-DSA-SHAKE-128s':
|
|
1875
|
+
case 'SLH-DSA-SHAKE-128f':
|
|
1876
|
+
case 'SLH-DSA-SHAKE-192s':
|
|
1877
|
+
case 'SLH-DSA-SHAKE-192f':
|
|
1878
|
+
case 'SLH-DSA-SHAKE-256s':
|
|
1879
|
+
case 'SLH-DSA-SHAKE-256f':
|
|
1880
|
+
if (key.type === 'public') {
|
|
1881
|
+
// Export ML-DSA / SLH-DSA key in SPKI DER format
|
|
1882
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI));
|
|
1883
|
+
}
|
|
1884
|
+
break;
|
|
1885
|
+
case 'ML-KEM-512':
|
|
1886
|
+
// Fall through
|
|
1887
|
+
case 'ML-KEM-768':
|
|
1888
|
+
// Fall through
|
|
1889
|
+
case 'ML-KEM-1024':
|
|
1890
|
+
if (key.type === 'public') {
|
|
1891
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI));
|
|
1892
|
+
}
|
|
1893
|
+
break;
|
|
1894
|
+
}
|
|
1895
|
+
throw new Error(`Unable to export a spki ${key.algorithm.name} ${key.type} key`);
|
|
1896
|
+
};
|
|
1897
|
+
const exportKeyPkcs8 = async key => {
|
|
1898
|
+
switch (key.algorithm.name) {
|
|
1899
|
+
case 'RSASSA-PKCS1-v1_5':
|
|
1900
|
+
// Fall through
|
|
1901
|
+
case 'RSA-PSS':
|
|
1902
|
+
// Fall through
|
|
1903
|
+
case 'RSA-OAEP':
|
|
1904
|
+
if (key.type === 'private') {
|
|
1905
|
+
return rsaExportKey(key, KWebCryptoKeyFormat.kWebCryptoKeyFormatPKCS8);
|
|
1906
|
+
}
|
|
1907
|
+
break;
|
|
1908
|
+
case 'ECDSA':
|
|
1909
|
+
// Fall through
|
|
1910
|
+
case 'ECDH':
|
|
1911
|
+
if (key.type === 'private') {
|
|
1912
|
+
return ecExportKey(key, KWebCryptoKeyFormat.kWebCryptoKeyFormatPKCS8);
|
|
1913
|
+
}
|
|
1914
|
+
break;
|
|
1915
|
+
case 'Ed25519':
|
|
1916
|
+
// Fall through
|
|
1917
|
+
case 'Ed448':
|
|
1918
|
+
// Fall through
|
|
1919
|
+
case 'X25519':
|
|
1920
|
+
// Fall through
|
|
1921
|
+
case 'X448':
|
|
1922
|
+
if (key.type === 'private') {
|
|
1923
|
+
// Export Ed/X key in PKCS8 DER format
|
|
1924
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.PKCS8));
|
|
1925
|
+
}
|
|
1926
|
+
break;
|
|
1927
|
+
case 'ML-DSA-44':
|
|
1928
|
+
// Fall through
|
|
1929
|
+
case 'ML-DSA-65':
|
|
1930
|
+
// Fall through
|
|
1931
|
+
case 'ML-DSA-87':
|
|
1932
|
+
// Fall through
|
|
1933
|
+
case 'ML-KEM-512':
|
|
1934
|
+
// Fall through
|
|
1935
|
+
case 'ML-KEM-768':
|
|
1936
|
+
// Fall through
|
|
1937
|
+
case 'ML-KEM-1024':
|
|
1938
|
+
if (key.type === 'private') {
|
|
1939
|
+
const ab = (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.PKCS8));
|
|
1940
|
+
// 22 bytes of PKCS#8 ASN.1 + seed (32 ML-DSA, 64 ML-KEM). Guards
|
|
1941
|
+
// against a seedless KeyObject that was wrapped via toCryptoKey.
|
|
1942
|
+
const expected = key.algorithm.name.startsWith('ML-DSA') ? 54 : 86;
|
|
1943
|
+
if (ab.byteLength !== expected) {
|
|
1944
|
+
throw (0, _errors.lazyDOMException)('The operation failed for an operation-specific reason', 'OperationError');
|
|
1945
|
+
}
|
|
1946
|
+
return ab;
|
|
1947
|
+
}
|
|
1948
|
+
break;
|
|
1949
|
+
case 'SLH-DSA-SHA2-128s':
|
|
1950
|
+
case 'SLH-DSA-SHA2-128f':
|
|
1951
|
+
case 'SLH-DSA-SHA2-192s':
|
|
1952
|
+
case 'SLH-DSA-SHA2-192f':
|
|
1953
|
+
case 'SLH-DSA-SHA2-256s':
|
|
1954
|
+
case 'SLH-DSA-SHA2-256f':
|
|
1955
|
+
case 'SLH-DSA-SHAKE-128s':
|
|
1956
|
+
case 'SLH-DSA-SHAKE-128f':
|
|
1957
|
+
case 'SLH-DSA-SHAKE-192s':
|
|
1958
|
+
case 'SLH-DSA-SHAKE-192f':
|
|
1959
|
+
case 'SLH-DSA-SHAKE-256s':
|
|
1960
|
+
case 'SLH-DSA-SHAKE-256f':
|
|
1961
|
+
if (key.type === 'private') {
|
|
1962
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.PKCS8));
|
|
1963
|
+
}
|
|
1964
|
+
break;
|
|
1965
|
+
}
|
|
1966
|
+
throw new Error(`Unable to export a pkcs8 ${key.algorithm.name} ${key.type} key`);
|
|
1967
|
+
};
|
|
1968
|
+
|
|
1969
|
+
// Mirrors Node's export key matrix (lib/internal/crypto/webcrypto.js
|
|
1970
|
+
// exportKeyRawSecret / exportKeyRawPublic, lines 472-563):
|
|
1971
|
+
//
|
|
1972
|
+
// raw — AES-CTR/CBC/GCM/KW + HMAC (secret); ECDSA/ECDH/Ed/X (public)
|
|
1973
|
+
// raw-secret — AES-CTR/CBC/GCM/KW + HMAC + AES-OCB + KMAC + ChaCha20-Poly1305
|
|
1974
|
+
// raw-public — ECDSA/ECDH + Ed/X + ML-DSA + ML-KEM (public)
|
|
1975
|
+
const exportKeyRaw = (key, format) => {
|
|
1976
|
+
const name = key.algorithm.name;
|
|
1977
|
+
const isPublic = key.type === 'public';
|
|
1978
|
+
const isSecret = key.type === 'secret';
|
|
1979
|
+
const exportSecret = () => {
|
|
1980
|
+
const exported = key.keyObject.export();
|
|
1981
|
+
return exported.buffer.slice(exported.byteOffset, exported.byteOffset + exported.byteLength);
|
|
1982
|
+
};
|
|
1983
|
+
const exportRawPublic = () => (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey());
|
|
1984
|
+
const fail = () => {
|
|
1985
|
+
throw (0, _errors.lazyDOMException)(`Unable to export ${name} ${key.type} key using ${format} format`, 'NotSupportedError');
|
|
1986
|
+
};
|
|
1987
|
+
|
|
1988
|
+
// Symmetric: AES-CTR/CBC/GCM/KW and HMAC accept both 'raw' and 'raw-secret';
|
|
1989
|
+
// AES-OCB / KMAC* / ChaCha20-Poly1305 only 'raw-secret'.
|
|
1990
|
+
switch (name) {
|
|
1991
|
+
case 'AES-CTR':
|
|
1992
|
+
case 'AES-CBC':
|
|
1993
|
+
case 'AES-GCM':
|
|
1994
|
+
case 'AES-KW':
|
|
1995
|
+
case 'HMAC':
|
|
1996
|
+
if (!isSecret) return fail();
|
|
1997
|
+
if (format === 'raw' || format === 'raw-secret') return exportSecret();
|
|
1998
|
+
return fail();
|
|
1999
|
+
case 'AES-OCB':
|
|
2000
|
+
case 'KMAC128':
|
|
2001
|
+
case 'KMAC256':
|
|
2002
|
+
case 'ChaCha20-Poly1305':
|
|
2003
|
+
if (!isSecret) return fail();
|
|
2004
|
+
if (format === 'raw-secret') return exportSecret();
|
|
2005
|
+
return fail();
|
|
2006
|
+
case 'ECDSA':
|
|
2007
|
+
case 'ECDH':
|
|
2008
|
+
if (!isPublic) return fail();
|
|
2009
|
+
if (format === 'raw' || format === 'raw-public') {
|
|
2010
|
+
return ecExportKey(key, KWebCryptoKeyFormat.kWebCryptoKeyFormatRaw);
|
|
2011
|
+
}
|
|
2012
|
+
return fail();
|
|
2013
|
+
case 'Ed25519':
|
|
2014
|
+
case 'Ed448':
|
|
2015
|
+
case 'X25519':
|
|
2016
|
+
case 'X448':
|
|
2017
|
+
if (!isPublic) return fail();
|
|
2018
|
+
if (format === 'raw' || format === 'raw-public') return exportRawPublic();
|
|
2019
|
+
return fail();
|
|
2020
|
+
case 'ML-DSA-44':
|
|
2021
|
+
case 'ML-DSA-65':
|
|
2022
|
+
case 'ML-DSA-87':
|
|
2023
|
+
case 'ML-KEM-512':
|
|
2024
|
+
case 'ML-KEM-768':
|
|
2025
|
+
case 'ML-KEM-1024':
|
|
2026
|
+
case 'SLH-DSA-SHA2-128s':
|
|
2027
|
+
case 'SLH-DSA-SHA2-128f':
|
|
2028
|
+
case 'SLH-DSA-SHA2-192s':
|
|
2029
|
+
case 'SLH-DSA-SHA2-192f':
|
|
2030
|
+
case 'SLH-DSA-SHA2-256s':
|
|
2031
|
+
case 'SLH-DSA-SHA2-256f':
|
|
2032
|
+
case 'SLH-DSA-SHAKE-128s':
|
|
2033
|
+
case 'SLH-DSA-SHAKE-128f':
|
|
2034
|
+
case 'SLH-DSA-SHAKE-192s':
|
|
2035
|
+
case 'SLH-DSA-SHAKE-192f':
|
|
2036
|
+
case 'SLH-DSA-SHAKE-256s':
|
|
2037
|
+
case 'SLH-DSA-SHAKE-256f':
|
|
2038
|
+
// ML-DSA / ML-KEM / SLH-DSA keys do not recognize plain 'raw' (Node
|
|
2039
|
+
// webcrypto.js lines 488-510).
|
|
2040
|
+
if (!isPublic) return fail();
|
|
2041
|
+
if (format === 'raw-public') return exportRawPublic();
|
|
2042
|
+
return fail();
|
|
2043
|
+
}
|
|
2044
|
+
return fail();
|
|
2045
|
+
};
|
|
2046
|
+
const exportKeyJWK = key => {
|
|
2047
|
+
const jwk = key.keyObject.handle.exportJwk({
|
|
2048
|
+
key_ops: [...key.usages],
|
|
2049
|
+
ext: key.extractable
|
|
2050
|
+
}, true);
|
|
2051
|
+
switch (key.algorithm.name) {
|
|
2052
|
+
case 'RSASSA-PKCS1-v1_5':
|
|
2053
|
+
jwk.alg = (0, _hashnames.normalizeHashName)(key.algorithm.hash, _hashnames.HashContext.JwkRsa);
|
|
2054
|
+
return jwk;
|
|
2055
|
+
case 'RSA-PSS':
|
|
2056
|
+
jwk.alg = (0, _hashnames.normalizeHashName)(key.algorithm.hash, _hashnames.HashContext.JwkRsaPss);
|
|
2057
|
+
return jwk;
|
|
2058
|
+
case 'RSA-OAEP':
|
|
2059
|
+
jwk.alg = (0, _hashnames.normalizeHashName)(key.algorithm.hash, _hashnames.HashContext.JwkRsaOaep);
|
|
2060
|
+
return jwk;
|
|
2061
|
+
case 'HMAC':
|
|
2062
|
+
jwk.alg = (0, _hashnames.normalizeHashName)(key.algorithm.hash, _hashnames.HashContext.JwkHmac);
|
|
2063
|
+
return jwk;
|
|
2064
|
+
case 'KMAC128':
|
|
2065
|
+
jwk.alg = 'K128';
|
|
2066
|
+
return jwk;
|
|
2067
|
+
case 'KMAC256':
|
|
2068
|
+
jwk.alg = 'K256';
|
|
2069
|
+
return jwk;
|
|
2070
|
+
case 'ECDSA':
|
|
2071
|
+
// Fall through
|
|
2072
|
+
case 'ECDH':
|
|
2073
|
+
jwk.crv ||= key.algorithm.namedCurve;
|
|
2074
|
+
return jwk;
|
|
2075
|
+
case 'Ed25519':
|
|
2076
|
+
// Fall through
|
|
2077
|
+
case 'Ed448':
|
|
2078
|
+
// Fall through
|
|
2079
|
+
case 'X25519':
|
|
2080
|
+
// Fall through
|
|
2081
|
+
case 'X448':
|
|
2082
|
+
return jwk;
|
|
2083
|
+
case 'ML-DSA-44':
|
|
2084
|
+
// Fall through
|
|
2085
|
+
case 'ML-DSA-65':
|
|
2086
|
+
// Fall through
|
|
2087
|
+
case 'ML-DSA-87':
|
|
2088
|
+
// Fall through
|
|
2089
|
+
case 'ML-KEM-512':
|
|
2090
|
+
// Fall through
|
|
2091
|
+
case 'ML-KEM-768':
|
|
2092
|
+
// Fall through
|
|
2093
|
+
case 'ML-KEM-1024':
|
|
2094
|
+
// Fall through
|
|
2095
|
+
case 'SLH-DSA-SHA2-128s':
|
|
2096
|
+
case 'SLH-DSA-SHA2-128f':
|
|
2097
|
+
case 'SLH-DSA-SHA2-192s':
|
|
2098
|
+
case 'SLH-DSA-SHA2-192f':
|
|
2099
|
+
case 'SLH-DSA-SHA2-256s':
|
|
2100
|
+
case 'SLH-DSA-SHA2-256f':
|
|
2101
|
+
case 'SLH-DSA-SHAKE-128s':
|
|
2102
|
+
case 'SLH-DSA-SHAKE-128f':
|
|
2103
|
+
case 'SLH-DSA-SHAKE-192s':
|
|
2104
|
+
case 'SLH-DSA-SHAKE-192f':
|
|
2105
|
+
case 'SLH-DSA-SHAKE-256s':
|
|
2106
|
+
case 'SLH-DSA-SHAKE-256f':
|
|
2107
|
+
return jwk;
|
|
2108
|
+
case 'AES-CTR':
|
|
2109
|
+
// Fall through
|
|
2110
|
+
case 'AES-CBC':
|
|
2111
|
+
// Fall through
|
|
2112
|
+
case 'AES-GCM':
|
|
2113
|
+
// Fall through
|
|
2114
|
+
case 'AES-KW':
|
|
2115
|
+
// Fall through
|
|
2116
|
+
case 'AES-OCB':
|
|
2117
|
+
// Fall through
|
|
2118
|
+
case 'ChaCha20-Poly1305':
|
|
2119
|
+
if (key.algorithm.length === undefined) {
|
|
2120
|
+
throw (0, _errors.lazyDOMException)(`Algorithm ${key.algorithm.name} missing required length property`, 'InvalidAccessError');
|
|
2121
|
+
}
|
|
2122
|
+
jwk.alg = getAlgorithmName(key.algorithm.name, key.algorithm.length);
|
|
2123
|
+
return jwk;
|
|
2124
|
+
default:
|
|
2125
|
+
// Fall through
|
|
2126
|
+
}
|
|
2127
|
+
throw (0, _errors.lazyDOMException)(`JWK export not yet supported: ${key.algorithm.name}`, 'NotSupportedError');
|
|
2128
|
+
};
|
|
2129
|
+
|
|
2130
|
+
// PBKDF2 import. Mirrors Node's importGenericSecretKey ordering
|
|
2131
|
+
// (keys.js:945-971): extractable → usage → format → length. Callers pre-alias
|
|
2132
|
+
// 'raw-secret' / 'raw-public' to 'raw' via aliasKeyFormat
|
|
2133
|
+
// (webcrypto.js:798-808).
|
|
2134
|
+
const pbkdf2ImportKey = async ({
|
|
2135
|
+
name,
|
|
2136
|
+
length
|
|
2137
|
+
}, format, keyData, extractable, keyUsages) => {
|
|
2138
|
+
if (extractable) {
|
|
2139
|
+
throw (0, _errors.lazyDOMException)(`${name} keys are not extractable`, 'SyntaxError');
|
|
2140
|
+
}
|
|
2141
|
+
if (hasAnyNotIn(keyUsages, ['deriveKey', 'deriveBits'])) {
|
|
2142
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for a ${name} key`, 'SyntaxError');
|
|
2143
|
+
}
|
|
2144
|
+
if (format !== 'raw') {
|
|
2145
|
+
throw (0, _errors.lazyDOMException)(`Unable to import ${name} key with format ${format}`, 'NotSupportedError');
|
|
2146
|
+
}
|
|
2147
|
+
const checkLength = typeof keyData === 'string' || _safeBuffer.Buffer.isBuffer(keyData) ? keyData.length * 8 : keyData.byteLength * 8;
|
|
2148
|
+
if (length !== undefined && length !== checkLength) {
|
|
2149
|
+
throw (0, _errors.lazyDOMException)('Invalid key length', 'DataError');
|
|
2150
|
+
}
|
|
2151
|
+
const keyObject = (0, _keys.createSecretKey)(keyData);
|
|
2152
|
+
return new _keys.CryptoKey(keyObject, {
|
|
2153
|
+
name
|
|
2154
|
+
}, keyUsages, false);
|
|
2155
|
+
};
|
|
2156
|
+
|
|
2157
|
+
// Argon2 import. Node gates the format at the dispatcher level — only
|
|
2158
|
+
// 'raw-secret' enters importGenericSecretKey (webcrypto.js:813-822). To match
|
|
2159
|
+
// that, format is the first check here; remaining ordering matches Node's
|
|
2160
|
+
// importGenericSecretKey.
|
|
2161
|
+
const argon2ImportKey = async ({
|
|
2162
|
+
name,
|
|
2163
|
+
length
|
|
2164
|
+
}, format, keyData, extractable, keyUsages) => {
|
|
2165
|
+
if (format !== 'raw-secret') {
|
|
2166
|
+
throw (0, _errors.lazyDOMException)(`Unable to import ${name} key with format ${format}`, 'NotSupportedError');
|
|
2167
|
+
}
|
|
2168
|
+
if (extractable) {
|
|
2169
|
+
throw (0, _errors.lazyDOMException)(`${name} keys are not extractable`, 'SyntaxError');
|
|
2170
|
+
}
|
|
2171
|
+
if (hasAnyNotIn(keyUsages, ['deriveKey', 'deriveBits'])) {
|
|
2172
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for a ${name} key`, 'SyntaxError');
|
|
2173
|
+
}
|
|
2174
|
+
const checkLength = typeof keyData === 'string' || _safeBuffer.Buffer.isBuffer(keyData) ? keyData.length * 8 : keyData.byteLength * 8;
|
|
2175
|
+
if (length !== undefined && length !== checkLength) {
|
|
2176
|
+
throw (0, _errors.lazyDOMException)('Invalid key length', 'DataError');
|
|
2177
|
+
}
|
|
2178
|
+
const keyObject = (0, _keys.createSecretKey)(keyData);
|
|
2179
|
+
return new _keys.CryptoKey(keyObject, {
|
|
2180
|
+
name
|
|
2181
|
+
}, keyUsages, false);
|
|
2182
|
+
};
|
|
2183
|
+
const hkdfImportKey = async (format, keyData, algorithm, extractable, keyUsages) => {
|
|
2184
|
+
const {
|
|
2185
|
+
name
|
|
2186
|
+
} = algorithm;
|
|
2187
|
+
// WebCrypto §28.7.6: HKDF keys are never extractable. The previous
|
|
2188
|
+
// implementation passed `extractable` through verbatim, allowing callers
|
|
2189
|
+
// to round-trip the input keying material via `exportKey` — defeating
|
|
2190
|
+
// the whole point of the deriveBits-only usage.
|
|
2191
|
+
if (extractable) {
|
|
2192
|
+
throw (0, _errors.lazyDOMException)(`${name} keys are not extractable`, 'SyntaxError');
|
|
2193
|
+
}
|
|
2194
|
+
if (hasAnyNotIn(keyUsages, ['deriveKey', 'deriveBits'])) {
|
|
2195
|
+
throw new Error(`Unsupported key usage for a ${name} key`);
|
|
2196
|
+
}
|
|
2197
|
+
switch (format) {
|
|
2198
|
+
case 'raw':
|
|
2199
|
+
{
|
|
2200
|
+
const keyObject = (0, _keys.createSecretKey)(keyData);
|
|
2201
|
+
return new _keys.CryptoKey(keyObject, {
|
|
2202
|
+
name
|
|
2203
|
+
}, keyUsages, false);
|
|
2204
|
+
}
|
|
2205
|
+
default:
|
|
2206
|
+
throw new Error(`Unable to import ${name} key with format ${format}`);
|
|
2207
|
+
}
|
|
2208
|
+
};
|
|
2209
|
+
const checkCryptoKeyPairUsages = pair => {
|
|
2210
|
+
if (pair.privateKey && pair.privateKey instanceof _keys.CryptoKey && pair.privateKey.keyUsages && pair.privateKey.keyUsages.length > 0) {
|
|
2211
|
+
return;
|
|
2212
|
+
}
|
|
2213
|
+
throw (0, _errors.lazyDOMException)('Usages cannot be empty when creating a key.', 'SyntaxError');
|
|
2214
|
+
};
|
|
2215
|
+
function argon2DeriveBits(algorithm, baseKey, length) {
|
|
2216
|
+
if (length === 0 || length % 8 !== 0) {
|
|
2217
|
+
throw (0, _errors.lazyDOMException)('Invalid Argon2 derived key length', 'OperationError');
|
|
2218
|
+
}
|
|
2219
|
+
if (length < 32) {
|
|
2220
|
+
throw (0, _errors.lazyDOMException)('Argon2 derived key length must be at least 32 bits', 'OperationError');
|
|
2221
|
+
}
|
|
2222
|
+
const {
|
|
2223
|
+
nonce,
|
|
2224
|
+
parallelism,
|
|
2225
|
+
memory,
|
|
2226
|
+
passes,
|
|
2227
|
+
secretValue,
|
|
2228
|
+
associatedData
|
|
2229
|
+
} = algorithm;
|
|
2230
|
+
const tagLength = length / 8;
|
|
2231
|
+
const message = baseKey.keyObject.export();
|
|
2232
|
+
const algName = algorithm.name.toLowerCase();
|
|
2233
|
+
const result = (0, _argon.argon2Sync)(algName, {
|
|
2234
|
+
message,
|
|
2235
|
+
nonce: nonce ?? new Uint8Array(0),
|
|
2236
|
+
parallelism: parallelism ?? 1,
|
|
2237
|
+
tagLength,
|
|
2238
|
+
memory: memory ?? 65536,
|
|
2239
|
+
passes: passes ?? 3,
|
|
2240
|
+
secret: secretValue,
|
|
2241
|
+
associatedData,
|
|
2242
|
+
version: algorithm.version
|
|
2243
|
+
});
|
|
2244
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(result);
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2247
|
+
// Type guard to check if result is CryptoKeyPair
|
|
2248
|
+
function isCryptoKeyPair(result) {
|
|
2249
|
+
return 'publicKey' in result && 'privateKey' in result;
|
|
2250
|
+
}
|
|
2251
|
+
function hmacSignVerify(key, data, signature) {
|
|
2252
|
+
// Get hash algorithm from key
|
|
2253
|
+
const hashName = (0, _hashnames.normalizeHashName)(key.algorithm.hash);
|
|
2254
|
+
|
|
2255
|
+
// Export the secret key material
|
|
2256
|
+
const keyData = key.keyObject.export();
|
|
2257
|
+
|
|
2258
|
+
// Create HMAC and compute digest
|
|
2259
|
+
const hmac = (0, _hmac.createHmac)(hashName, keyData);
|
|
2260
|
+
hmac.update((0, _conversion.bufferLikeToArrayBuffer)(data));
|
|
2261
|
+
const computed = hmac.digest();
|
|
2262
|
+
if (signature === undefined) {
|
|
2263
|
+
// Sign operation - return the HMAC as ArrayBuffer
|
|
2264
|
+
return computed.buffer.slice(computed.byteOffset, computed.byteOffset + computed.byteLength);
|
|
2265
|
+
}
|
|
2266
|
+
const sigBuffer = (0, _conversion.bufferLikeToArrayBuffer)(signature);
|
|
2267
|
+
const computedBuffer = computed.buffer.slice(computed.byteOffset, computed.byteOffset + computed.byteLength);
|
|
2268
|
+
if (computedBuffer.byteLength !== sigBuffer.byteLength) {
|
|
2269
|
+
return false;
|
|
2270
|
+
}
|
|
2271
|
+
return (0, _timingSafeEqual.timingSafeEqual)(new Uint8Array(computedBuffer), new Uint8Array(sigBuffer));
|
|
2272
|
+
}
|
|
2273
|
+
function rsaSignVerify(key, data, padding, signature, saltLength) {
|
|
2274
|
+
// Get hash algorithm from key
|
|
2275
|
+
const hashName = (0, _hashnames.normalizeHashName)(key.algorithm.hash);
|
|
2276
|
+
|
|
2277
|
+
// Determine RSA padding constant
|
|
2278
|
+
const RSA_PKCS1_PADDING = 1;
|
|
2279
|
+
const RSA_PKCS1_PSS_PADDING = 6;
|
|
2280
|
+
const paddingValue = padding === 'pss' ? RSA_PKCS1_PSS_PADDING : RSA_PKCS1_PADDING;
|
|
2281
|
+
if (signature === undefined) {
|
|
2282
|
+
// Sign operation
|
|
2283
|
+
const signer = (0, _signVerify.createSign)(hashName);
|
|
2284
|
+
signer.update(data);
|
|
2285
|
+
const sig = signer.sign({
|
|
2286
|
+
key: key,
|
|
2287
|
+
padding: paddingValue,
|
|
2288
|
+
saltLength
|
|
2289
|
+
});
|
|
2290
|
+
return sig.buffer.slice(sig.byteOffset, sig.byteOffset + sig.byteLength);
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
// Verify operation
|
|
2294
|
+
const verifier = (0, _signVerify.createVerify)(hashName);
|
|
2295
|
+
verifier.update(data);
|
|
2296
|
+
return verifier.verify({
|
|
2297
|
+
key: key,
|
|
2298
|
+
padding: paddingValue,
|
|
2299
|
+
saltLength
|
|
2300
|
+
}, signature);
|
|
2301
|
+
}
|
|
2302
|
+
function edSignVerify(key, data, signature) {
|
|
2303
|
+
const isSign = signature === undefined;
|
|
2304
|
+
const expectedKeyType = isSign ? 'private' : 'public';
|
|
2305
|
+
if (key.type !== expectedKeyType) {
|
|
2306
|
+
throw (0, _errors.lazyDOMException)(`Key must be a ${expectedKeyType} key`, 'InvalidAccessError');
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2309
|
+
// Get curve type from algorithm name (Ed25519 or Ed448)
|
|
2310
|
+
const algorithmName = key.algorithm.name;
|
|
2311
|
+
const curveType = algorithmName.toLowerCase();
|
|
2312
|
+
|
|
2313
|
+
// Create Ed instance with the curve
|
|
2314
|
+
const ed = new _ed.Ed(curveType, {});
|
|
2315
|
+
|
|
2316
|
+
// Export raw key bytes (exportKey with no format returns raw for Ed keys)
|
|
2317
|
+
const rawKey = key.keyObject.handle.exportKey();
|
|
2318
|
+
const dataBuffer = (0, _conversion.bufferLikeToArrayBuffer)(data);
|
|
2319
|
+
if (isSign) {
|
|
2320
|
+
// Sign operation - use raw private key
|
|
2321
|
+
const sig = ed.signSync(dataBuffer, rawKey);
|
|
2322
|
+
return sig;
|
|
2323
|
+
} else {
|
|
2324
|
+
// Verify operation - use raw public key
|
|
2325
|
+
const signatureBuffer = (0, _conversion.bufferLikeToArrayBuffer)(signature);
|
|
2326
|
+
return ed.verifySync(signatureBuffer, dataBuffer, rawKey);
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
function mldsaSignVerify(key, data, signature) {
|
|
2330
|
+
const isSign = signature === undefined;
|
|
2331
|
+
const expectedKeyType = isSign ? 'private' : 'public';
|
|
2332
|
+
if (key.type !== expectedKeyType) {
|
|
2333
|
+
throw (0, _errors.lazyDOMException)(`Key must be a ${expectedKeyType} key`, 'InvalidAccessError');
|
|
2334
|
+
}
|
|
2335
|
+
const dataBuffer = (0, _conversion.bufferLikeToArrayBuffer)(data);
|
|
2336
|
+
if (isSign) {
|
|
2337
|
+
const signer = (0, _signVerify.createSign)('');
|
|
2338
|
+
signer.update(dataBuffer);
|
|
2339
|
+
const sig = signer.sign({
|
|
2340
|
+
key: key
|
|
2341
|
+
});
|
|
2342
|
+
return sig.buffer.slice(sig.byteOffset, sig.byteOffset + sig.byteLength);
|
|
2343
|
+
} else {
|
|
2344
|
+
const signatureBuffer = (0, _conversion.bufferLikeToArrayBuffer)(signature);
|
|
2345
|
+
const verifier = (0, _signVerify.createVerify)('');
|
|
2346
|
+
verifier.update(dataBuffer);
|
|
2347
|
+
return verifier.verify({
|
|
2348
|
+
key: key
|
|
2349
|
+
}, signatureBuffer);
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
const signVerify = (algorithm, key, data, signature) => {
|
|
2353
|
+
const usage = signature === undefined ? 'sign' : 'verify';
|
|
2354
|
+
algorithm = normalizeAlgorithm(algorithm, usage);
|
|
2355
|
+
if (algorithm.name !== key.algorithm.name) {
|
|
2356
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
2357
|
+
}
|
|
2358
|
+
if (!key.usages.includes(usage)) {
|
|
2359
|
+
throw (0, _errors.lazyDOMException)(`Unable to use this key to ${usage}`, 'InvalidAccessError');
|
|
2360
|
+
}
|
|
2361
|
+
switch (algorithm.name) {
|
|
2362
|
+
case 'ECDSA':
|
|
2363
|
+
return (0, _ec.ecdsaSignVerify)(key, data, algorithm, signature);
|
|
2364
|
+
case 'HMAC':
|
|
2365
|
+
return hmacSignVerify(key, data, signature);
|
|
2366
|
+
case 'RSASSA-PKCS1-v1_5':
|
|
2367
|
+
return rsaSignVerify(key, data, 'pkcs1', signature);
|
|
2368
|
+
case 'RSA-PSS':
|
|
2369
|
+
return rsaSignVerify(key, data, 'pss', signature, algorithm.saltLength);
|
|
2370
|
+
case 'Ed25519':
|
|
2371
|
+
case 'Ed448':
|
|
2372
|
+
return edSignVerify(key, data, signature);
|
|
2373
|
+
case 'ML-DSA-44':
|
|
2374
|
+
case 'ML-DSA-65':
|
|
2375
|
+
case 'ML-DSA-87':
|
|
2376
|
+
case 'SLH-DSA-SHA2-128s':
|
|
2377
|
+
case 'SLH-DSA-SHA2-128f':
|
|
2378
|
+
case 'SLH-DSA-SHA2-192s':
|
|
2379
|
+
case 'SLH-DSA-SHA2-192f':
|
|
2380
|
+
case 'SLH-DSA-SHA2-256s':
|
|
2381
|
+
case 'SLH-DSA-SHA2-256f':
|
|
2382
|
+
case 'SLH-DSA-SHAKE-128s':
|
|
2383
|
+
case 'SLH-DSA-SHAKE-128f':
|
|
2384
|
+
case 'SLH-DSA-SHAKE-192s':
|
|
2385
|
+
case 'SLH-DSA-SHAKE-192f':
|
|
2386
|
+
case 'SLH-DSA-SHAKE-256s':
|
|
2387
|
+
case 'SLH-DSA-SHAKE-256f':
|
|
2388
|
+
return mldsaSignVerify(key, data, signature);
|
|
2389
|
+
case 'KMAC128':
|
|
2390
|
+
case 'KMAC256':
|
|
2391
|
+
return kmacSignVerify(key, data, algorithm, signature);
|
|
2392
|
+
}
|
|
2393
|
+
throw (0, _errors.lazyDOMException)(`Unrecognized algorithm name '${algorithm.name}' for '${usage}'`, 'NotSupportedError');
|
|
2394
|
+
};
|
|
2395
|
+
|
|
2396
|
+
// Algorithm-mismatch and usage checks live at the public-method call sites
|
|
2397
|
+
// (encrypt / decrypt / wrapKey / unwrapKey) so spec-mandated message and
|
|
2398
|
+
// ordering — algorithm-mismatch first, then usage — is preserved
|
|
2399
|
+
// (Node webcrypto.js, commit 4cb1f284136).
|
|
2400
|
+
const cipherOrWrap = async (mode, algorithm, key, data) => {
|
|
2401
|
+
(0, _validation.validateMaxBufferLength)(data, 'data');
|
|
2402
|
+
switch (algorithm.name) {
|
|
2403
|
+
case 'RSA-OAEP':
|
|
2404
|
+
return rsaCipher(mode, key, data, algorithm);
|
|
2405
|
+
case 'AES-CTR':
|
|
2406
|
+
// Fall through
|
|
2407
|
+
case 'AES-CBC':
|
|
2408
|
+
// Fall through
|
|
2409
|
+
case 'AES-GCM':
|
|
2410
|
+
// Fall through
|
|
2411
|
+
case 'AES-OCB':
|
|
2412
|
+
return aesCipher(mode, key, data, algorithm);
|
|
2413
|
+
case 'AES-KW':
|
|
2414
|
+
return aesKwCipher(mode, key, data);
|
|
2415
|
+
case 'ChaCha20-Poly1305':
|
|
2416
|
+
return chaCha20Poly1305Cipher(mode, key, data, algorithm);
|
|
2417
|
+
}
|
|
2418
|
+
};
|
|
2419
|
+
const SUPPORTED_ALGORITHMS = {
|
|
2420
|
+
encrypt: new Set(['RSA-OAEP', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-OCB', 'ChaCha20-Poly1305']),
|
|
2421
|
+
decrypt: new Set(['RSA-OAEP', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-OCB', 'ChaCha20-Poly1305']),
|
|
2422
|
+
sign: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'ECDSA', 'HMAC', 'KMAC128', 'KMAC256', 'Ed25519', 'Ed448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', ..._slhdsa.SLH_DSA_VARIANTS]),
|
|
2423
|
+
verify: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'ECDSA', 'HMAC', 'KMAC128', 'KMAC256', 'Ed25519', 'Ed448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', ..._slhdsa.SLH_DSA_VARIANTS]),
|
|
2424
|
+
digest: new Set(['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512', 'SHA3-256', 'SHA3-384', 'SHA3-512', 'cSHAKE128', 'cSHAKE256', 'TurboSHAKE128', 'TurboSHAKE256', 'KT128', 'KT256']),
|
|
2425
|
+
generateKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'KMAC128', 'KMAC256', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024', ..._slhdsa.SLH_DSA_VARIANTS]),
|
|
2426
|
+
importKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'KMAC128', 'KMAC256', 'HKDF', 'PBKDF2', 'Argon2d', 'Argon2i', 'Argon2id', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024', ..._slhdsa.SLH_DSA_VARIANTS]),
|
|
2427
|
+
exportKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'KMAC128', 'KMAC256', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024', ..._slhdsa.SLH_DSA_VARIANTS]),
|
|
2428
|
+
deriveBits: new Set(['PBKDF2', 'HKDF', 'ECDH', 'X25519', 'X448', 'Argon2d', 'Argon2i', 'Argon2id']),
|
|
2429
|
+
wrapKey: new Set(['AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'RSA-OAEP']),
|
|
2430
|
+
unwrapKey: new Set(['AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'RSA-OAEP']),
|
|
2431
|
+
encapsulateBits: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
2432
|
+
decapsulateBits: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
2433
|
+
encapsulateKey: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
2434
|
+
decapsulateKey: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024'])
|
|
2435
|
+
};
|
|
2436
|
+
const ASYMMETRIC_ALGORITHMS = new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024', ..._slhdsa.SLH_DSA_VARIANTS]);
|
|
2437
|
+
|
|
2438
|
+
// Per-algorithm validators for deriveBits (mirrors Node's hkdf.js:141-149,
|
|
2439
|
+
// pbkdf2.js:96-105, argon2.js:194-209). Used by Subtle.supports to reject
|
|
2440
|
+
// length values that the actual deriveBits implementation would reject.
|
|
2441
|
+
function validateKdfDeriveBitsLength(length, algName) {
|
|
2442
|
+
if (length === null || length === undefined) {
|
|
2443
|
+
throw (0, _errors.lazyDOMException)('length cannot be null', 'OperationError');
|
|
2444
|
+
}
|
|
2445
|
+
if (length % 8) {
|
|
2446
|
+
throw (0, _errors.lazyDOMException)('length must be a multiple of 8', 'OperationError');
|
|
2447
|
+
}
|
|
2448
|
+
if (algName.startsWith('Argon2') && length < 32) {
|
|
2449
|
+
throw (0, _errors.lazyDOMException)('length must be >= 32', 'OperationError');
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
|
|
2453
|
+
// Mirrors Node's webcrypto.js:1652-1731 `check`. Normalizes the algorithm,
|
|
2454
|
+
// looks it up in SUPPORTED_ALGORITHMS, and runs per-algorithm validation
|
|
2455
|
+
// (deriveBits length validators, HMAC+SHA3 generateKey rejection).
|
|
2456
|
+
// `op` is the operation key in SUPPORTED_ALGORITHMS — wrapKey/unwrapKey fall
|
|
2457
|
+
// back to encrypt/decrypt to mirror Node's normalize fallback.
|
|
2458
|
+
function supportsCheck(op, alg, length) {
|
|
2459
|
+
let normalizedAlgorithm;
|
|
2460
|
+
try {
|
|
2461
|
+
normalizedAlgorithm = normalizeAlgorithm(alg, op);
|
|
2462
|
+
} catch {
|
|
2463
|
+
if (op === 'wrapKey') return supportsCheck('encrypt', alg);
|
|
2464
|
+
if (op === 'unwrapKey') return supportsCheck('decrypt', alg);
|
|
2465
|
+
return false;
|
|
2466
|
+
}
|
|
2467
|
+
const supported = SUPPORTED_ALGORITHMS[op];
|
|
2468
|
+
if (!supported || !supported.has(normalizedAlgorithm.name)) {
|
|
2469
|
+
if (op === 'wrapKey') return supportsCheck('encrypt', alg);
|
|
2470
|
+
if (op === 'unwrapKey') return supportsCheck('decrypt', alg);
|
|
2471
|
+
return false;
|
|
2472
|
+
}
|
|
2473
|
+
if (op === 'deriveBits') {
|
|
2474
|
+
const name = normalizedAlgorithm.name;
|
|
2475
|
+
if (name === 'HKDF' || name === 'PBKDF2' || name.startsWith('Argon2')) {
|
|
2476
|
+
try {
|
|
2477
|
+
validateKdfDeriveBitsLength(length, name);
|
|
2478
|
+
} catch {
|
|
2479
|
+
return false;
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
if (op === 'generateKey' && normalizedAlgorithm.name === 'HMAC') {
|
|
2484
|
+
const hashName = typeof normalizedAlgorithm.hash === 'string' ? normalizedAlgorithm.hash : normalizedAlgorithm.hash?.name;
|
|
2485
|
+
if (normalizedAlgorithm.length === undefined && typeof hashName === 'string' && hashName.startsWith('SHA3-')) {
|
|
2486
|
+
return false;
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
return true;
|
|
2490
|
+
}
|
|
2491
|
+
function supportsImpl(operation, algorithm, lengthOrAdditionalAlgorithm) {
|
|
2492
|
+
switch (operation) {
|
|
2493
|
+
case 'decapsulateBits':
|
|
2494
|
+
case 'decapsulateKey':
|
|
2495
|
+
case 'decrypt':
|
|
2496
|
+
case 'deriveBits':
|
|
2497
|
+
case 'deriveKey':
|
|
2498
|
+
case 'digest':
|
|
2499
|
+
case 'encapsulateBits':
|
|
2500
|
+
case 'encapsulateKey':
|
|
2501
|
+
case 'encrypt':
|
|
2502
|
+
case 'exportKey':
|
|
2503
|
+
case 'generateKey':
|
|
2504
|
+
case 'getPublicKey':
|
|
2505
|
+
case 'importKey':
|
|
2506
|
+
case 'sign':
|
|
2507
|
+
case 'unwrapKey':
|
|
2508
|
+
case 'verify':
|
|
2509
|
+
case 'wrapKey':
|
|
2510
|
+
break;
|
|
2511
|
+
default:
|
|
2512
|
+
return false;
|
|
2513
|
+
}
|
|
2514
|
+
let length;
|
|
2515
|
+
if (operation === 'deriveKey') {
|
|
2516
|
+
// deriveKey decomposes to importKey of derived alg + deriveBits with that
|
|
2517
|
+
// alg's key length. Node webcrypto.js:1547-1563.
|
|
2518
|
+
if (lengthOrAdditionalAlgorithm != null) {
|
|
2519
|
+
const additional = lengthOrAdditionalAlgorithm;
|
|
2520
|
+
if (!supportsCheck('importKey', additional)) return false;
|
|
2521
|
+
try {
|
|
2522
|
+
length = getKeyLength(normalizeAlgorithm(additional, 'get key length'));
|
|
2523
|
+
} catch {
|
|
2524
|
+
return false;
|
|
2525
|
+
}
|
|
2526
|
+
return supportsCheck('deriveBits', algorithm, length);
|
|
2527
|
+
}
|
|
2528
|
+
// No additional algorithm given — only check the deriveBits side.
|
|
2529
|
+
return supportsCheck('deriveBits', algorithm);
|
|
2530
|
+
}
|
|
2531
|
+
if (operation === 'wrapKey') {
|
|
2532
|
+
// wrapKey decomposes to encrypt of wrapping alg + exportKey of wrapped alg.
|
|
2533
|
+
// Node webcrypto.js:1564-1572.
|
|
2534
|
+
if (lengthOrAdditionalAlgorithm != null) {
|
|
2535
|
+
const additional = lengthOrAdditionalAlgorithm;
|
|
2536
|
+
if (!supportsCheck('exportKey', additional)) return false;
|
|
2537
|
+
}
|
|
2538
|
+
return supportsCheck('wrapKey', algorithm);
|
|
2539
|
+
}
|
|
2540
|
+
if (operation === 'unwrapKey') {
|
|
2541
|
+
// unwrapKey decomposes to decrypt of wrapping alg + importKey of wrapped
|
|
2542
|
+
// alg. Node webcrypto.js:1573-1581.
|
|
2543
|
+
if (lengthOrAdditionalAlgorithm != null) {
|
|
2544
|
+
const additional = lengthOrAdditionalAlgorithm;
|
|
2545
|
+
if (!supportsCheck('importKey', additional)) return false;
|
|
2546
|
+
}
|
|
2547
|
+
return supportsCheck('unwrapKey', algorithm);
|
|
2548
|
+
}
|
|
2549
|
+
if (operation === 'deriveBits') {
|
|
2550
|
+
if (lengthOrAdditionalAlgorithm == null) {
|
|
2551
|
+
length = null;
|
|
2552
|
+
} else if (typeof lengthOrAdditionalAlgorithm === 'number') {
|
|
2553
|
+
length = lengthOrAdditionalAlgorithm;
|
|
2554
|
+
} else {
|
|
2555
|
+
return false;
|
|
2556
|
+
}
|
|
2557
|
+
return supportsCheck('deriveBits', algorithm, length);
|
|
2558
|
+
}
|
|
2559
|
+
if (operation === 'getPublicKey') {
|
|
2560
|
+
let normalized;
|
|
2561
|
+
try {
|
|
2562
|
+
normalized = normalizeAlgorithm(algorithm, 'exportKey');
|
|
2563
|
+
} catch {
|
|
2564
|
+
return false;
|
|
2565
|
+
}
|
|
2566
|
+
return ASYMMETRIC_ALGORITHMS.has(normalized.name);
|
|
2567
|
+
}
|
|
2568
|
+
if (operation === 'encapsulateKey' || operation === 'decapsulateKey') {
|
|
2569
|
+
// sharedKeyAlgorithm must support importKey, with HMAC/KMAC limited to
|
|
2570
|
+
// length === undefined or 256 (Node webcrypto.js:1610-1645).
|
|
2571
|
+
const additional = lengthOrAdditionalAlgorithm;
|
|
2572
|
+
let normalizedAdd;
|
|
2573
|
+
try {
|
|
2574
|
+
normalizedAdd = normalizeAlgorithm(additional, 'importKey');
|
|
2575
|
+
} catch {
|
|
2576
|
+
return false;
|
|
2577
|
+
}
|
|
2578
|
+
switch (normalizedAdd.name) {
|
|
2579
|
+
case 'AES-OCB':
|
|
2580
|
+
case 'AES-KW':
|
|
2581
|
+
case 'AES-GCM':
|
|
2582
|
+
case 'AES-CTR':
|
|
2583
|
+
case 'AES-CBC':
|
|
2584
|
+
case 'ChaCha20-Poly1305':
|
|
2585
|
+
case 'HKDF':
|
|
2586
|
+
case 'PBKDF2':
|
|
2587
|
+
case 'Argon2i':
|
|
2588
|
+
case 'Argon2d':
|
|
2589
|
+
case 'Argon2id':
|
|
2590
|
+
break;
|
|
2591
|
+
case 'HMAC':
|
|
2592
|
+
case 'KMAC128':
|
|
2593
|
+
case 'KMAC256':
|
|
2594
|
+
{
|
|
2595
|
+
const addLen = normalizedAdd.length;
|
|
2596
|
+
if (addLen !== undefined && addLen !== 256) return false;
|
|
2597
|
+
break;
|
|
2598
|
+
}
|
|
2599
|
+
default:
|
|
2600
|
+
return false;
|
|
2601
|
+
}
|
|
2602
|
+
return supportsCheck(operation, algorithm);
|
|
2603
|
+
}
|
|
2604
|
+
return supportsCheck(operation, algorithm);
|
|
2605
|
+
}
|
|
2606
|
+
class Subtle {
|
|
2607
|
+
// Spec-compliant capability detector. Mirrors Node's webcrypto.js:1506-1649
|
|
2608
|
+
// `SubtleCrypto.supports`, including:
|
|
2609
|
+
// • composed-operation decomposition (deriveKey, wrapKey, unwrapKey,
|
|
2610
|
+
// encapsulateKey, decapsulateKey, getPublicKey)
|
|
2611
|
+
// • per-algorithm length validators for deriveBits (HKDF/PBKDF2/Argon2)
|
|
2612
|
+
// • HMAC + SHA3 generateKey with no length → false
|
|
2613
|
+
// Static-only per the WICG spec.
|
|
2614
|
+
static supports(operation, algorithm, lengthOrAdditionalAlgorithm = null) {
|
|
2615
|
+
return supportsImpl(operation, algorithm, lengthOrAdditionalAlgorithm);
|
|
2616
|
+
}
|
|
2617
|
+
async decrypt(algorithm, key, data) {
|
|
2618
|
+
requireArgs(arguments.length, 3, 'decrypt');
|
|
2619
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'decrypt');
|
|
2620
|
+
if (normalizedAlgorithm.name !== key.algorithm.name) {
|
|
2621
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
2622
|
+
}
|
|
2623
|
+
if (!key.usages.includes('decrypt')) {
|
|
2624
|
+
throw (0, _errors.lazyDOMException)('Unable to use this key to decrypt', 'InvalidAccessError');
|
|
2625
|
+
}
|
|
2626
|
+
return cipherOrWrap(CipherOrWrapMode.kWebCryptoCipherDecrypt, normalizedAlgorithm, key, (0, _conversion.bufferLikeToArrayBuffer)(data));
|
|
2627
|
+
}
|
|
2628
|
+
async digest(algorithm, data) {
|
|
2629
|
+
requireArgs(arguments.length, 2, 'digest');
|
|
2630
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'digest');
|
|
2631
|
+
return (0, _hash.asyncDigest)(normalizedAlgorithm, data);
|
|
2632
|
+
}
|
|
2633
|
+
async deriveBits(algorithm, baseKey, length = null) {
|
|
2634
|
+
requireArgs(arguments.length, 2, 'deriveBits');
|
|
2635
|
+
// WebCrypto §SubtleCrypto.deriveBits step 11: throw InvalidAccessError
|
|
2636
|
+
// unless `baseKey.[[usages]]` contains "deriveBits" specifically. The
|
|
2637
|
+
// previous `deriveBits || deriveKey` accept-either branch silently
|
|
2638
|
+
// promoted deriveKey-only keys into deriveBits use, contradicting the
|
|
2639
|
+
// spec usage gate.
|
|
2640
|
+
if (!baseKey.usages.includes('deriveBits')) {
|
|
2641
|
+
throw (0, _errors.lazyDOMException)('baseKey does not have deriveBits usage', 'InvalidAccessError');
|
|
2642
|
+
}
|
|
2643
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'deriveBits');
|
|
2644
|
+
if (baseKey.algorithm.name !== normalizedAlgorithm.name) {
|
|
2645
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
2646
|
+
}
|
|
2647
|
+
switch (normalizedAlgorithm.name) {
|
|
2648
|
+
case 'PBKDF2':
|
|
2649
|
+
if (length === null) {
|
|
2650
|
+
throw (0, _errors.lazyDOMException)('length cannot be null', 'OperationError');
|
|
2651
|
+
}
|
|
2652
|
+
return (0, _pbkdf.pbkdf2DeriveBits)(normalizedAlgorithm, baseKey, length);
|
|
2653
|
+
case 'X25519':
|
|
2654
|
+
// Fall through
|
|
2655
|
+
case 'X448':
|
|
2656
|
+
return (0, _ed.xDeriveBits)(normalizedAlgorithm, baseKey, length);
|
|
2657
|
+
case 'ECDH':
|
|
2658
|
+
return (0, _ec.ecDeriveBits)(normalizedAlgorithm, baseKey, length);
|
|
2659
|
+
case 'HKDF':
|
|
2660
|
+
if (length === null) {
|
|
2661
|
+
throw (0, _errors.lazyDOMException)('length cannot be null', 'OperationError');
|
|
2662
|
+
}
|
|
2663
|
+
return (0, _hkdf.hkdfDeriveBits)(normalizedAlgorithm, baseKey, length);
|
|
2664
|
+
case 'Argon2d':
|
|
2665
|
+
case 'Argon2i':
|
|
2666
|
+
case 'Argon2id':
|
|
2667
|
+
if (length === null) {
|
|
2668
|
+
throw (0, _errors.lazyDOMException)('length cannot be null', 'OperationError');
|
|
2669
|
+
}
|
|
2670
|
+
return argon2DeriveBits(normalizedAlgorithm, baseKey, length);
|
|
2671
|
+
}
|
|
2672
|
+
throw (0, _errors.lazyDOMException)(`'subtle.deriveBits()' for ${normalizedAlgorithm.name} is not implemented.`, 'NotSupportedError');
|
|
2673
|
+
}
|
|
2674
|
+
async deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages) {
|
|
2675
|
+
requireArgs(arguments.length, 5, 'deriveKey');
|
|
2676
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'deriveBits');
|
|
2677
|
+
// Validate the derived-key algorithm up front (mirrors Node webcrypto.js:341).
|
|
2678
|
+
// The normalized form is unused — `this.importKey` re-normalizes below.
|
|
2679
|
+
normalizeAlgorithm(derivedKeyAlgorithm, 'importKey');
|
|
2680
|
+
|
|
2681
|
+
// Validate baseKey usage
|
|
2682
|
+
if (!baseKey.usages.includes('deriveKey')) {
|
|
2683
|
+
throw (0, _errors.lazyDOMException)('baseKey does not have deriveKey usage', 'InvalidAccessError');
|
|
2684
|
+
}
|
|
2685
|
+
if (baseKey.algorithm.name !== normalizedAlgorithm.name) {
|
|
2686
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
2687
|
+
}
|
|
2688
|
+
|
|
2689
|
+
// Calculate required key length (may be null for KDF-derived material).
|
|
2690
|
+
// Mirrors Node webcrypto.js:350 — uses the raw derivedKeyAlgorithm with
|
|
2691
|
+
// op='get key length' so AES `length` survives normalization (the
|
|
2692
|
+
// 'importKey' converter for AES is null and strips dictionary members).
|
|
2693
|
+
const length = getKeyLength(normalizeAlgorithm(derivedKeyAlgorithm, 'get key length'));
|
|
2694
|
+
|
|
2695
|
+
// Step 1: Derive bits
|
|
2696
|
+
let derivedBits;
|
|
2697
|
+
switch (normalizedAlgorithm.name) {
|
|
2698
|
+
case 'PBKDF2':
|
|
2699
|
+
if (length === null) {
|
|
2700
|
+
throw (0, _errors.lazyDOMException)('length cannot be null', 'OperationError');
|
|
2701
|
+
}
|
|
2702
|
+
derivedBits = await (0, _pbkdf.pbkdf2DeriveBits)(normalizedAlgorithm, baseKey, length);
|
|
2703
|
+
break;
|
|
2704
|
+
case 'X25519':
|
|
2705
|
+
// Fall through
|
|
2706
|
+
case 'X448':
|
|
2707
|
+
derivedBits = await (0, _ed.xDeriveBits)(normalizedAlgorithm, baseKey, length);
|
|
2708
|
+
break;
|
|
2709
|
+
case 'ECDH':
|
|
2710
|
+
derivedBits = await (0, _ec.ecDeriveBits)(normalizedAlgorithm, baseKey, length);
|
|
2711
|
+
break;
|
|
2712
|
+
case 'HKDF':
|
|
2713
|
+
if (length === null) {
|
|
2714
|
+
throw (0, _errors.lazyDOMException)('length cannot be null', 'OperationError');
|
|
2715
|
+
}
|
|
2716
|
+
derivedBits = (0, _hkdf.hkdfDeriveBits)(normalizedAlgorithm, baseKey, length);
|
|
2717
|
+
break;
|
|
2718
|
+
case 'Argon2d':
|
|
2719
|
+
case 'Argon2i':
|
|
2720
|
+
case 'Argon2id':
|
|
2721
|
+
if (length === null) {
|
|
2722
|
+
throw (0, _errors.lazyDOMException)('length cannot be null', 'OperationError');
|
|
2723
|
+
}
|
|
2724
|
+
derivedBits = argon2DeriveBits(normalizedAlgorithm, baseKey, length);
|
|
2725
|
+
break;
|
|
2726
|
+
default:
|
|
2727
|
+
throw (0, _errors.lazyDOMException)(`'subtle.deriveKey()' for ${normalizedAlgorithm.name} is not implemented.`, 'NotSupportedError');
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2730
|
+
// Step 2: Import as key. Use 'raw-secret' so derived material flows into
|
|
2731
|
+
// AEADs / KMAC correctly — they reject plain 'raw' (Node webcrypto.js:381-385).
|
|
2732
|
+
return this.importKey('raw-secret', derivedBits, derivedKeyAlgorithm, extractable, keyUsages);
|
|
2733
|
+
}
|
|
2734
|
+
async encrypt(algorithm, key, data) {
|
|
2735
|
+
requireArgs(arguments.length, 3, 'encrypt');
|
|
2736
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'encrypt');
|
|
2737
|
+
if (normalizedAlgorithm.name !== key.algorithm.name) {
|
|
2738
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
2739
|
+
}
|
|
2740
|
+
if (!key.usages.includes('encrypt')) {
|
|
2741
|
+
throw (0, _errors.lazyDOMException)('Unable to use this key to encrypt', 'InvalidAccessError');
|
|
2742
|
+
}
|
|
2743
|
+
return cipherOrWrap(CipherOrWrapMode.kWebCryptoCipherEncrypt, normalizedAlgorithm, key, (0, _conversion.bufferLikeToArrayBuffer)(data));
|
|
2744
|
+
}
|
|
2745
|
+
async exportKey(format, key) {
|
|
2746
|
+
requireArgs(arguments.length, 2, 'exportKey');
|
|
2747
|
+
if (!key.extractable) throw (0, _errors.lazyDOMException)('key is not extractable', 'InvalidAccessError');
|
|
2748
|
+
if (format === 'raw-seed') {
|
|
2749
|
+
const pqcAlgos = ['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', ..._slhdsa.SLH_DSA_VARIANTS];
|
|
2750
|
+
if (!pqcAlgos.includes(key.algorithm.name)) {
|
|
2751
|
+
throw (0, _errors.lazyDOMException)('raw-seed export only supported for PQC keys', 'NotSupportedError');
|
|
2752
|
+
}
|
|
2753
|
+
if (key.type !== 'private') {
|
|
2754
|
+
throw (0, _errors.lazyDOMException)('raw-seed export requires a private key', 'InvalidAccessError');
|
|
2755
|
+
}
|
|
2756
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey());
|
|
2757
|
+
}
|
|
2758
|
+
switch (format) {
|
|
2759
|
+
case 'spki':
|
|
2760
|
+
return await exportKeySpki(key);
|
|
2761
|
+
case 'pkcs8':
|
|
2762
|
+
return await exportKeyPkcs8(key);
|
|
2763
|
+
case 'jwk':
|
|
2764
|
+
return exportKeyJWK(key);
|
|
2765
|
+
case 'raw':
|
|
2766
|
+
case 'raw-secret':
|
|
2767
|
+
case 'raw-public':
|
|
2768
|
+
return exportKeyRaw(key, format);
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
async wrapKey(format, key, wrappingKey, wrapAlgorithm) {
|
|
2772
|
+
requireArgs(arguments.length, 4, 'wrapKey');
|
|
2773
|
+
// Mirrors Node webcrypto.js:923-927: prefer the 'wrapKey' op (only
|
|
2774
|
+
// AES-KW defines it) and fall back to 'encrypt' for cipher-based wrap
|
|
2775
|
+
// algorithms like AES-GCM and RSA-OAEP.
|
|
2776
|
+
let normalizedWrapAlgorithm;
|
|
2777
|
+
try {
|
|
2778
|
+
normalizedWrapAlgorithm = normalizeAlgorithm(wrapAlgorithm, 'wrapKey');
|
|
2779
|
+
} catch {
|
|
2780
|
+
normalizedWrapAlgorithm = normalizeAlgorithm(wrapAlgorithm, 'encrypt');
|
|
2781
|
+
}
|
|
2782
|
+
if (normalizedWrapAlgorithm.name !== wrappingKey.algorithm.name) {
|
|
2783
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
2784
|
+
}
|
|
2785
|
+
if (!wrappingKey.usages.includes('wrapKey')) {
|
|
2786
|
+
throw (0, _errors.lazyDOMException)('Unable to use this key to wrapKey', 'InvalidAccessError');
|
|
2787
|
+
}
|
|
2788
|
+
|
|
2789
|
+
// Step 1: Export the key
|
|
2790
|
+
const exported = await this.exportKey(format, key);
|
|
2791
|
+
|
|
2792
|
+
// Step 2: Convert to ArrayBuffer if JWK
|
|
2793
|
+
let keyData;
|
|
2794
|
+
if (format === 'jwk') {
|
|
2795
|
+
const jwkString = JSON.stringify(exported);
|
|
2796
|
+
const buffer = _safeBuffer.Buffer.from(jwkString, 'utf8');
|
|
2797
|
+
|
|
2798
|
+
// For AES-KW, pad to multiple of 8 bytes (accounting for null terminator)
|
|
2799
|
+
if (normalizedWrapAlgorithm.name === 'AES-KW') {
|
|
2800
|
+
const length = buffer.length;
|
|
2801
|
+
// Add 1 for null terminator, then pad to multiple of 8
|
|
2802
|
+
const paddedLength = Math.ceil((length + 1) / 8) * 8;
|
|
2803
|
+
const paddedBuffer = _safeBuffer.Buffer.alloc(paddedLength);
|
|
2804
|
+
buffer.copy(paddedBuffer);
|
|
2805
|
+
// Null terminator for JSON string (remaining bytes are already zeros from alloc)
|
|
2806
|
+
paddedBuffer.writeUInt8(0, length);
|
|
2807
|
+
keyData = (0, _conversion.bufferLikeToArrayBuffer)(paddedBuffer);
|
|
2808
|
+
} else {
|
|
2809
|
+
keyData = (0, _conversion.bufferLikeToArrayBuffer)(buffer);
|
|
2810
|
+
}
|
|
2811
|
+
} else {
|
|
2812
|
+
keyData = exported;
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
// Step 3: Encrypt the exported key
|
|
2816
|
+
return cipherOrWrap(CipherOrWrapMode.kWebCryptoCipherEncrypt, normalizedWrapAlgorithm, wrappingKey, keyData);
|
|
2817
|
+
}
|
|
2818
|
+
async unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages) {
|
|
2819
|
+
requireArgs(arguments.length, 7, 'unwrapKey');
|
|
2820
|
+
// Mirrors Node webcrypto.js:1006-1010: prefer 'unwrapKey', fall back to
|
|
2821
|
+
// 'decrypt' for cipher-based unwrap algorithms.
|
|
2822
|
+
let normalizedUnwrapAlgorithm;
|
|
2823
|
+
try {
|
|
2824
|
+
normalizedUnwrapAlgorithm = normalizeAlgorithm(unwrapAlgorithm, 'unwrapKey');
|
|
2825
|
+
} catch {
|
|
2826
|
+
normalizedUnwrapAlgorithm = normalizeAlgorithm(unwrapAlgorithm, 'decrypt');
|
|
2827
|
+
}
|
|
2828
|
+
if (normalizedUnwrapAlgorithm.name !== unwrappingKey.algorithm.name) {
|
|
2829
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
2830
|
+
}
|
|
2831
|
+
if (!unwrappingKey.usages.includes('unwrapKey')) {
|
|
2832
|
+
throw (0, _errors.lazyDOMException)('Unable to use this key to unwrapKey', 'InvalidAccessError');
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2835
|
+
// Step 1: Decrypt the wrapped key
|
|
2836
|
+
const decrypted = await cipherOrWrap(CipherOrWrapMode.kWebCryptoCipherDecrypt, normalizedUnwrapAlgorithm, unwrappingKey, (0, _conversion.bufferLikeToArrayBuffer)(wrappedKey));
|
|
2837
|
+
|
|
2838
|
+
// Step 2: Convert to appropriate format
|
|
2839
|
+
let keyData;
|
|
2840
|
+
if (format === 'jwk') {
|
|
2841
|
+
const buffer = _safeBuffer.Buffer.from(decrypted);
|
|
2842
|
+
// For AES-KW, the data may be padded - find the null terminator
|
|
2843
|
+
let jwkString;
|
|
2844
|
+
if (normalizedUnwrapAlgorithm.name === 'AES-KW') {
|
|
2845
|
+
// Find the null terminator (if present) to get the original string
|
|
2846
|
+
const nullIndex = buffer.indexOf(0);
|
|
2847
|
+
if (nullIndex !== -1) {
|
|
2848
|
+
jwkString = buffer.toString('utf8', 0, nullIndex);
|
|
2849
|
+
} else {
|
|
2850
|
+
// No null terminator, try to parse the whole buffer
|
|
2851
|
+
jwkString = buffer.toString('utf8').trim();
|
|
2852
|
+
}
|
|
2853
|
+
} else {
|
|
2854
|
+
jwkString = buffer.toString('utf8');
|
|
2855
|
+
}
|
|
2856
|
+
keyData = JSON.parse(jwkString);
|
|
2857
|
+
} else {
|
|
2858
|
+
keyData = decrypted;
|
|
2859
|
+
}
|
|
2860
|
+
|
|
2861
|
+
// Step 3: Import the key
|
|
2862
|
+
return this.importKey(format, keyData, unwrappedKeyAlgorithm, extractable, keyUsages);
|
|
2863
|
+
}
|
|
2864
|
+
async generateKey(algorithm, extractable, keyUsages) {
|
|
2865
|
+
requireArgs(arguments.length, 3, 'generateKey');
|
|
2866
|
+
algorithm = normalizeAlgorithm(algorithm, 'generateKey');
|
|
2867
|
+
let result;
|
|
2868
|
+
switch (algorithm.name) {
|
|
2869
|
+
case 'RSASSA-PKCS1-v1_5':
|
|
2870
|
+
// Fall through
|
|
2871
|
+
case 'RSA-PSS':
|
|
2872
|
+
// Fall through
|
|
2873
|
+
case 'RSA-OAEP':
|
|
2874
|
+
result = await (0, _rsa.rsa_generateKeyPair)(algorithm, extractable, keyUsages);
|
|
2875
|
+
break;
|
|
2876
|
+
case 'ECDSA':
|
|
2877
|
+
// Fall through
|
|
2878
|
+
case 'ECDH':
|
|
2879
|
+
result = await (0, _ec.ec_generateKeyPair)(algorithm.name, algorithm.namedCurve, extractable, keyUsages);
|
|
2880
|
+
checkCryptoKeyPairUsages(result);
|
|
2881
|
+
break;
|
|
2882
|
+
case 'AES-CTR':
|
|
2883
|
+
// Fall through
|
|
2884
|
+
case 'AES-CBC':
|
|
2885
|
+
// Fall through
|
|
2886
|
+
case 'AES-GCM':
|
|
2887
|
+
// Fall through
|
|
2888
|
+
case 'AES-KW':
|
|
2889
|
+
// Fall through
|
|
2890
|
+
case 'AES-OCB':
|
|
2891
|
+
result = await aesGenerateKey(algorithm, extractable, keyUsages);
|
|
2892
|
+
break;
|
|
2893
|
+
case 'ChaCha20-Poly1305':
|
|
2894
|
+
{
|
|
2895
|
+
const length = algorithm.length ?? 256;
|
|
2896
|
+
if (length !== 256) {
|
|
2897
|
+
throw (0, _errors.lazyDOMException)('ChaCha20-Poly1305 only supports 256-bit keys', 'NotSupportedError');
|
|
2898
|
+
}
|
|
2899
|
+
result = await aesGenerateKey({
|
|
2900
|
+
name: 'ChaCha20-Poly1305',
|
|
2901
|
+
length: 256
|
|
2902
|
+
}, extractable, keyUsages);
|
|
2903
|
+
break;
|
|
2904
|
+
}
|
|
2905
|
+
case 'HMAC':
|
|
2906
|
+
result = await hmacGenerateKey(algorithm, extractable, keyUsages);
|
|
2907
|
+
break;
|
|
2908
|
+
case 'KMAC128':
|
|
2909
|
+
// Fall through
|
|
2910
|
+
case 'KMAC256':
|
|
2911
|
+
result = await kmacGenerateKey(algorithm, extractable, keyUsages);
|
|
2912
|
+
break;
|
|
2913
|
+
case 'Ed25519':
|
|
2914
|
+
// Fall through
|
|
2915
|
+
case 'Ed448':
|
|
2916
|
+
result = await (0, _ed.ed_generateKeyPairWebCrypto)(algorithm.name.toLowerCase(), extractable, keyUsages);
|
|
2917
|
+
checkCryptoKeyPairUsages(result);
|
|
2918
|
+
break;
|
|
2919
|
+
case 'ML-DSA-44':
|
|
2920
|
+
// Fall through
|
|
2921
|
+
case 'ML-DSA-65':
|
|
2922
|
+
// Fall through
|
|
2923
|
+
case 'ML-DSA-87':
|
|
2924
|
+
result = await (0, _mldsa.mldsa_generateKeyPairWebCrypto)(algorithm.name, extractable, keyUsages);
|
|
2925
|
+
checkCryptoKeyPairUsages(result);
|
|
2926
|
+
break;
|
|
2927
|
+
case 'SLH-DSA-SHA2-128s':
|
|
2928
|
+
case 'SLH-DSA-SHA2-128f':
|
|
2929
|
+
case 'SLH-DSA-SHA2-192s':
|
|
2930
|
+
case 'SLH-DSA-SHA2-192f':
|
|
2931
|
+
case 'SLH-DSA-SHA2-256s':
|
|
2932
|
+
case 'SLH-DSA-SHA2-256f':
|
|
2933
|
+
case 'SLH-DSA-SHAKE-128s':
|
|
2934
|
+
case 'SLH-DSA-SHAKE-128f':
|
|
2935
|
+
case 'SLH-DSA-SHAKE-192s':
|
|
2936
|
+
case 'SLH-DSA-SHAKE-192f':
|
|
2937
|
+
case 'SLH-DSA-SHAKE-256s':
|
|
2938
|
+
case 'SLH-DSA-SHAKE-256f':
|
|
2939
|
+
result = await (0, _slhdsa.slhdsa_generateKeyPairWebCrypto)(algorithm.name, extractable, keyUsages);
|
|
2940
|
+
checkCryptoKeyPairUsages(result);
|
|
2941
|
+
break;
|
|
2942
|
+
case 'X25519':
|
|
2943
|
+
// Fall through
|
|
2944
|
+
case 'X448':
|
|
2945
|
+
result = await (0, _ed.x_generateKeyPairWebCrypto)(algorithm.name.toLowerCase(), extractable, keyUsages);
|
|
2946
|
+
checkCryptoKeyPairUsages(result);
|
|
2947
|
+
break;
|
|
2948
|
+
case 'ML-KEM-512':
|
|
2949
|
+
// Fall through
|
|
2950
|
+
case 'ML-KEM-768':
|
|
2951
|
+
// Fall through
|
|
2952
|
+
case 'ML-KEM-1024':
|
|
2953
|
+
result = await (0, _mlkem.mlkem_generateKeyPairWebCrypto)(algorithm.name, extractable, keyUsages);
|
|
2954
|
+
checkCryptoKeyPairUsages(result);
|
|
2955
|
+
break;
|
|
2956
|
+
default:
|
|
2957
|
+
throw new Error(`'subtle.generateKey()' is not implemented for ${algorithm.name}.
|
|
2958
|
+
Unrecognized algorithm name`);
|
|
2959
|
+
}
|
|
2960
|
+
return result;
|
|
2961
|
+
}
|
|
2962
|
+
async getPublicKey(key, keyUsages) {
|
|
2963
|
+
requireArgs(arguments.length, 2, 'getPublicKey');
|
|
2964
|
+
if (key.type === 'secret') {
|
|
2965
|
+
throw (0, _errors.lazyDOMException)('key must be a private key', 'NotSupportedError');
|
|
2966
|
+
}
|
|
2967
|
+
if (key.type !== 'private') {
|
|
2968
|
+
throw (0, _errors.lazyDOMException)('key must be a private key', 'InvalidAccessError');
|
|
2969
|
+
}
|
|
2970
|
+
const publicKeyObject = (0, _keys.createPublicKey)(key.keyObject);
|
|
2971
|
+
return publicKeyObject.toCryptoKey(key.algorithm, true, keyUsages);
|
|
2972
|
+
}
|
|
2973
|
+
async importKey(format, data, algorithm, extractable, keyUsages) {
|
|
2974
|
+
requireArgs(arguments.length, 5, 'importKey');
|
|
2975
|
+
// Per-algorithm format handling. Some algorithms alias raw-secret/raw-public
|
|
2976
|
+
// to 'raw' (RSA, EC, Ed/X, HMAC, HKDF, PBKDF2); others demand the
|
|
2977
|
+
// disambiguated form (KMAC, AES-OCB, ChaCha20-Poly1305, Argon2, ML-DSA,
|
|
2978
|
+
// ML-KEM). 'raw-seed' is never normalized — PQC import handles it directly.
|
|
2979
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'importKey');
|
|
2980
|
+
let result;
|
|
2981
|
+
switch (normalizedAlgorithm.name) {
|
|
2982
|
+
case 'RSASSA-PKCS1-v1_5':
|
|
2983
|
+
// Fall through
|
|
2984
|
+
case 'RSA-PSS':
|
|
2985
|
+
// Fall through
|
|
2986
|
+
case 'RSA-OAEP':
|
|
2987
|
+
result = rsaImportKey(aliasKeyFormat(format), data, normalizedAlgorithm, extractable, keyUsages);
|
|
2988
|
+
break;
|
|
2989
|
+
case 'ECDSA':
|
|
2990
|
+
// Fall through
|
|
2991
|
+
case 'ECDH':
|
|
2992
|
+
result = (0, _ec.ecImportKey)(aliasKeyFormat(format), data, normalizedAlgorithm, extractable, keyUsages);
|
|
2993
|
+
break;
|
|
2994
|
+
case 'HMAC':
|
|
2995
|
+
// No aliasing — Node routes HMAC straight into mac.js, which accepts
|
|
2996
|
+
// 'raw' / 'raw-secret' / 'jwk' and rejects everything else
|
|
2997
|
+
// (webcrypto.js:774-781, mac.js:136-174).
|
|
2998
|
+
result = await hmacImportKey(normalizedAlgorithm, format, data, extractable, keyUsages);
|
|
2999
|
+
break;
|
|
3000
|
+
case 'KMAC128':
|
|
3001
|
+
// Fall through
|
|
3002
|
+
case 'KMAC256':
|
|
3003
|
+
result = await kmacImportKey(normalizedAlgorithm, format, data, extractable, keyUsages);
|
|
3004
|
+
break;
|
|
3005
|
+
case 'AES-CTR':
|
|
3006
|
+
// Fall through
|
|
3007
|
+
case 'AES-CBC':
|
|
3008
|
+
// Fall through
|
|
3009
|
+
case 'AES-GCM':
|
|
3010
|
+
// Fall through
|
|
3011
|
+
case 'AES-KW':
|
|
3012
|
+
// Fall through
|
|
3013
|
+
case 'AES-OCB':
|
|
3014
|
+
// Fall through
|
|
3015
|
+
case 'ChaCha20-Poly1305':
|
|
3016
|
+
result = await aesImportKey(normalizedAlgorithm, format, data, extractable, keyUsages);
|
|
3017
|
+
break;
|
|
3018
|
+
case 'PBKDF2':
|
|
3019
|
+
result = await pbkdf2ImportKey(normalizedAlgorithm, aliasKeyFormat(format), data, extractable, keyUsages);
|
|
3020
|
+
break;
|
|
3021
|
+
case 'Argon2d':
|
|
3022
|
+
case 'Argon2i':
|
|
3023
|
+
case 'Argon2id':
|
|
3024
|
+
result = await argon2ImportKey(normalizedAlgorithm, format, data, extractable, keyUsages);
|
|
3025
|
+
break;
|
|
3026
|
+
case 'HKDF':
|
|
3027
|
+
result = await hkdfImportKey(aliasKeyFormat(format), data, normalizedAlgorithm, extractable, keyUsages);
|
|
3028
|
+
break;
|
|
3029
|
+
case 'X25519':
|
|
3030
|
+
// Fall through
|
|
3031
|
+
case 'X448':
|
|
3032
|
+
// Fall through
|
|
3033
|
+
case 'Ed25519':
|
|
3034
|
+
// Fall through
|
|
3035
|
+
case 'Ed448':
|
|
3036
|
+
result = edImportKey(aliasKeyFormat(format), data, normalizedAlgorithm, extractable, keyUsages);
|
|
3037
|
+
break;
|
|
3038
|
+
case 'SLH-DSA-SHA2-128s':
|
|
3039
|
+
case 'SLH-DSA-SHA2-128f':
|
|
3040
|
+
case 'SLH-DSA-SHA2-192s':
|
|
3041
|
+
case 'SLH-DSA-SHA2-192f':
|
|
3042
|
+
case 'SLH-DSA-SHA2-256s':
|
|
3043
|
+
case 'SLH-DSA-SHA2-256f':
|
|
3044
|
+
case 'SLH-DSA-SHAKE-128s':
|
|
3045
|
+
case 'SLH-DSA-SHAKE-128f':
|
|
3046
|
+
case 'SLH-DSA-SHAKE-192s':
|
|
3047
|
+
case 'SLH-DSA-SHAKE-192f':
|
|
3048
|
+
case 'SLH-DSA-SHAKE-256s':
|
|
3049
|
+
case 'SLH-DSA-SHAKE-256f':
|
|
3050
|
+
result = slhdsaImportKey(format, data, normalizedAlgorithm, extractable, keyUsages);
|
|
3051
|
+
break;
|
|
3052
|
+
case 'ML-DSA-44':
|
|
3053
|
+
// Fall through
|
|
3054
|
+
case 'ML-DSA-65':
|
|
3055
|
+
// Fall through
|
|
3056
|
+
case 'ML-DSA-87':
|
|
3057
|
+
result = mldsaImportKey(format, data, normalizedAlgorithm, extractable, keyUsages);
|
|
3058
|
+
break;
|
|
3059
|
+
case 'ML-KEM-512':
|
|
3060
|
+
// Fall through
|
|
3061
|
+
case 'ML-KEM-768':
|
|
3062
|
+
// Fall through
|
|
3063
|
+
case 'ML-KEM-1024':
|
|
3064
|
+
result = mlkemImportKey(format, data, normalizedAlgorithm, extractable, keyUsages);
|
|
3065
|
+
break;
|
|
3066
|
+
default:
|
|
3067
|
+
throw new Error(`"subtle.importKey()" is not implemented for ${normalizedAlgorithm.name}`);
|
|
3068
|
+
}
|
|
3069
|
+
if ((result.type === 'secret' || result.type === 'private') && result.usages.length === 0) {
|
|
3070
|
+
throw new Error(`Usages cannot be empty when importing a ${result.type} key.`);
|
|
3071
|
+
}
|
|
3072
|
+
return result;
|
|
3073
|
+
}
|
|
3074
|
+
async sign(algorithm, key, data) {
|
|
3075
|
+
requireArgs(arguments.length, 3, 'sign');
|
|
3076
|
+
return signVerify(normalizeAlgorithm(algorithm, 'sign'), key, data);
|
|
3077
|
+
}
|
|
3078
|
+
async verify(algorithm, key, signature, data) {
|
|
3079
|
+
requireArgs(arguments.length, 4, 'verify');
|
|
3080
|
+
return signVerify(normalizeAlgorithm(algorithm, 'verify'), key, data, signature);
|
|
3081
|
+
}
|
|
3082
|
+
_encapsulateCore(algorithm, key) {
|
|
3083
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'encapsulateBits');
|
|
3084
|
+
if (key.algorithm.name !== normalizedAlgorithm.name) {
|
|
3085
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
3086
|
+
}
|
|
3087
|
+
const variant = normalizedAlgorithm.name;
|
|
3088
|
+
const mlkem = new _mlkem.MlKem(variant);
|
|
3089
|
+
const keyData = key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI);
|
|
3090
|
+
mlkem.setPublicKey((0, _conversion.bufferLikeToArrayBuffer)(keyData), _utils.KFormatType.DER, _utils.KeyEncoding.SPKI);
|
|
3091
|
+
return mlkem.encapsulateSync();
|
|
3092
|
+
}
|
|
3093
|
+
_decapsulateCore(algorithm, key, ciphertext) {
|
|
3094
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'decapsulateBits');
|
|
3095
|
+
if (key.algorithm.name !== normalizedAlgorithm.name) {
|
|
3096
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
3097
|
+
}
|
|
3098
|
+
const variant = normalizedAlgorithm.name;
|
|
3099
|
+
const mlkem = new _mlkem.MlKem(variant);
|
|
3100
|
+
const keyData = key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.PKCS8);
|
|
3101
|
+
mlkem.setPrivateKey((0, _conversion.bufferLikeToArrayBuffer)(keyData), _utils.KFormatType.DER, _utils.KeyEncoding.PKCS8);
|
|
3102
|
+
return mlkem.decapsulateSync((0, _conversion.bufferLikeToArrayBuffer)(ciphertext));
|
|
3103
|
+
}
|
|
3104
|
+
async encapsulateBits(algorithm, key) {
|
|
3105
|
+
requireArgs(arguments.length, 2, 'encapsulateBits');
|
|
3106
|
+
if (!key.usages.includes('encapsulateBits')) {
|
|
3107
|
+
throw (0, _errors.lazyDOMException)('Key does not have encapsulateBits usage', 'InvalidAccessError');
|
|
3108
|
+
}
|
|
3109
|
+
return this._encapsulateCore(algorithm, key);
|
|
3110
|
+
}
|
|
3111
|
+
async encapsulateKey(algorithm, key, sharedKeyAlgorithm, extractable, usages) {
|
|
3112
|
+
requireArgs(arguments.length, 5, 'encapsulateKey');
|
|
3113
|
+
if (!key.usages.includes('encapsulateKey')) {
|
|
3114
|
+
throw (0, _errors.lazyDOMException)('Key does not have encapsulateKey usage', 'InvalidAccessError');
|
|
3115
|
+
}
|
|
3116
|
+
const {
|
|
3117
|
+
sharedKey,
|
|
3118
|
+
ciphertext
|
|
3119
|
+
} = this._encapsulateCore(algorithm, key);
|
|
3120
|
+
// Node imports the encapsulated shared bits as 'raw-secret'
|
|
3121
|
+
// (webcrypto.js:1370-1374) so AEADs / KMAC accept the result.
|
|
3122
|
+
const importedKey = await this.importKey('raw-secret', sharedKey, sharedKeyAlgorithm, extractable, usages);
|
|
3123
|
+
return {
|
|
3124
|
+
key: importedKey,
|
|
3125
|
+
ciphertext
|
|
3126
|
+
};
|
|
3127
|
+
}
|
|
3128
|
+
async decapsulateBits(algorithm, key, ciphertext) {
|
|
3129
|
+
requireArgs(arguments.length, 3, 'decapsulateBits');
|
|
3130
|
+
if (!key.usages.includes('decapsulateBits')) {
|
|
3131
|
+
throw (0, _errors.lazyDOMException)('Key does not have decapsulateBits usage', 'InvalidAccessError');
|
|
3132
|
+
}
|
|
3133
|
+
return this._decapsulateCore(algorithm, key, ciphertext);
|
|
3134
|
+
}
|
|
3135
|
+
async decapsulateKey(algorithm, key, ciphertext, sharedKeyAlgorithm, extractable, usages) {
|
|
3136
|
+
requireArgs(arguments.length, 6, 'decapsulateKey');
|
|
3137
|
+
if (!key.usages.includes('decapsulateKey')) {
|
|
3138
|
+
throw (0, _errors.lazyDOMException)('Key does not have decapsulateKey usage', 'InvalidAccessError');
|
|
3139
|
+
}
|
|
3140
|
+
const sharedKey = this._decapsulateCore(algorithm, key, ciphertext);
|
|
3141
|
+
// Node imports the decapsulated shared bits as 'raw-secret'
|
|
3142
|
+
// (webcrypto.js:1490-1494).
|
|
3143
|
+
return this.importKey('raw-secret', sharedKey, sharedKeyAlgorithm, extractable, usages);
|
|
3144
|
+
}
|
|
3145
|
+
}
|
|
3146
|
+
exports.Subtle = Subtle;
|
|
3147
|
+
const subtle = exports.subtle = new Subtle();
|
|
3148
|
+
|
|
3149
|
+
// Returns the number of bits to derive for an `importKey` algorithm, mirroring
|
|
3150
|
+
// Node's webcrypto.js:269-306 `getKeyLength`. Returns null for KDF algorithms
|
|
3151
|
+
// (HKDF / PBKDF2 / Argon2) — those carry their full derived secret without a
|
|
3152
|
+
// fixed key length. Throws OperationError on invalid AES / HMAC inputs rather
|
|
3153
|
+
// than silently coercing to a default (Node commit 4cb1f284136 behavior).
|
|
3154
|
+
function getKeyLength(algorithm) {
|
|
3155
|
+
const name = algorithm.name;
|
|
3156
|
+
const length = algorithm.length;
|
|
3157
|
+
switch (name) {
|
|
3158
|
+
case 'AES-CTR':
|
|
3159
|
+
case 'AES-CBC':
|
|
3160
|
+
case 'AES-GCM':
|
|
3161
|
+
case 'AES-KW':
|
|
3162
|
+
case 'AES-OCB':
|
|
3163
|
+
if (length !== 128 && length !== 192 && length !== 256) {
|
|
3164
|
+
throw (0, _errors.lazyDOMException)('Invalid key length', 'OperationError');
|
|
3165
|
+
}
|
|
3166
|
+
return length;
|
|
3167
|
+
case 'HMAC':
|
|
3168
|
+
{
|
|
3169
|
+
if (length === undefined) {
|
|
3170
|
+
return getHmacBlockSize(algorithm.hash?.name ?? algorithm.hash);
|
|
3171
|
+
}
|
|
3172
|
+
if (typeof length === 'number' && length !== 0) {
|
|
3173
|
+
return length;
|
|
3174
|
+
}
|
|
3175
|
+
throw (0, _errors.lazyDOMException)('Invalid key length', 'OperationError');
|
|
3176
|
+
}
|
|
3177
|
+
case 'KMAC128':
|
|
3178
|
+
return typeof length === 'number' ? length : 128;
|
|
3179
|
+
case 'KMAC256':
|
|
3180
|
+
return typeof length === 'number' ? length : 256;
|
|
3181
|
+
case 'ChaCha20-Poly1305':
|
|
3182
|
+
return 256;
|
|
3183
|
+
case 'HKDF':
|
|
3184
|
+
case 'PBKDF2':
|
|
3185
|
+
case 'Argon2d':
|
|
3186
|
+
case 'Argon2i':
|
|
3187
|
+
case 'Argon2id':
|
|
3188
|
+
return null;
|
|
3189
|
+
default:
|
|
3190
|
+
throw (0, _errors.lazyDOMException)(`Cannot determine key length for ${name}`, 'NotSupportedError');
|
|
3191
|
+
}
|
|
3192
|
+
}
|
|
3193
|
+
function getHmacBlockSize(name) {
|
|
3194
|
+
switch (name) {
|
|
3195
|
+
case 'SHA-1':
|
|
3196
|
+
case 'SHA-256':
|
|
3197
|
+
return 512;
|
|
3198
|
+
case 'SHA-384':
|
|
3199
|
+
case 'SHA-512':
|
|
3200
|
+
return 1024;
|
|
3201
|
+
case 'SHA3-256':
|
|
3202
|
+
case 'SHA3-384':
|
|
3203
|
+
case 'SHA3-512':
|
|
3204
|
+
// SHA-3 / HMAC interaction undefined — Node throws here too
|
|
3205
|
+
// (webcrypto-modern-algos issue #23).
|
|
3206
|
+
throw (0, _errors.lazyDOMException)('Explicit algorithm length member is required', 'NotSupportedError');
|
|
3207
|
+
default:
|
|
3208
|
+
throw (0, _errors.lazyDOMException)('Invalid key length', 'OperationError');
|
|
3209
|
+
}
|
|
3210
|
+
}
|
|
3211
|
+
//# sourceMappingURL=subtle.js.map
|