react-native-quick-crypto 0.7.3 → 1.0.0-beta.2
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 +34 -0
- package/README.md +13 -46
- package/android/CMakeLists.txt +32 -64
- package/android/build.gradle +52 -125
- package/android/gradle.properties +4 -4
- package/android/src/main/cpp/cpp-adapter.cpp +9 -54
- package/android/src/main/java/com/margelo/nitro/quickcrypto/QuickCryptoPackage.java +38 -0
- package/cpp/random/HybridRandom.cpp +34 -0
- package/cpp/random/HybridRandom.hpp +44 -0
- package/cpp/utils/Utils.hpp +9 -0
- package/ios/QuickCryptoOnLoad.mm +19 -0
- package/lib/commonjs/index.js +39 -39
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/random.js +26 -12
- package/lib/commonjs/random.js.map +1 -1
- package/lib/commonjs/{NativeQuickCrypto/rsa.js → specs/random.nitro.js} +1 -1
- package/lib/commonjs/{NativeQuickCrypto/aes.js.map → specs/random.nitro.js.map} +1 -1
- package/lib/commonjs/utils/conversion.js +22 -0
- package/lib/commonjs/utils/conversion.js.map +1 -0
- package/lib/commonjs/utils/index.js +12 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/commonjs/utils/types.js +2 -0
- package/lib/{module/NativeQuickCrypto/aes.js.map → commonjs/utils/types.js.map} +1 -1
- package/lib/module/index.js +38 -38
- package/lib/module/index.js.map +1 -1
- package/lib/module/random.js +26 -12
- package/lib/module/random.js.map +1 -1
- package/lib/module/specs/random.nitro.js +4 -0
- package/lib/module/{NativeQuickCrypto/rsa.js.map → specs/random.nitro.js.map} +1 -1
- package/lib/module/utils/conversion.js +16 -0
- package/lib/module/utils/conversion.js.map +1 -0
- package/lib/module/utils/index.js +8 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/module/utils/types.js +2 -0
- package/lib/{commonjs/NativeQuickCrypto/rsa.js.map → module/utils/types.js.map} +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/typescript/index.d.ts +10 -141
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/random.d.ts +4 -5
- package/lib/typescript/random.d.ts.map +1 -1
- package/lib/typescript/specs/random.nitro.d.ts +9 -0
- package/lib/typescript/specs/random.nitro.d.ts.map +1 -0
- package/lib/typescript/utils/conversion.d.ts +4 -0
- package/lib/typescript/utils/conversion.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +6 -0
- package/lib/typescript/utils/index.d.ts.map +1 -0
- package/lib/typescript/utils/types.d.ts +5 -0
- package/lib/typescript/utils/types.d.ts.map +1 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +45 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.gradle +26 -0
- package/nitrogen/generated/ios/QuickCrypto+autolinking.rb +57 -0
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.cpp +9 -0
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.hpp +25 -0
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Umbrella.hpp +29 -0
- package/nitrogen/generated/shared/c++/HybridRandomSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridRandomSpec.hpp +62 -0
- package/package.json +50 -106
- package/src/index.ts +38 -48
- package/src/random.ts +51 -48
- package/src/specs/random.nitro.ts +14 -0
- package/src/utils/conversion.ts +16 -0
- package/src/utils/index.ts +6 -0
- package/src/utils/types.ts +15 -0
- package/LICENSE +0 -27
- package/android/src/main/java/com/margelo/quickcrypto/QuickCryptoModule.java +0 -70
- package/android/src/main/java/com/margelo/quickcrypto/QuickCryptoPackage.java +0 -25
- package/cpp/Cipher/MGLCipherHostObject.cpp +0 -663
- package/cpp/Cipher/MGLCipherHostObject.h +0 -90
- package/cpp/Cipher/MGLCreateCipherInstaller.cpp +0 -75
- package/cpp/Cipher/MGLCreateCipherInstaller.h +0 -22
- package/cpp/Cipher/MGLCreateDecipherInstaller.cpp +0 -77
- package/cpp/Cipher/MGLCreateDecipherInstaller.h +0 -17
- package/cpp/Cipher/MGLGenerateKeyPairInstaller.cpp +0 -134
- package/cpp/Cipher/MGLGenerateKeyPairInstaller.h +0 -35
- package/cpp/Cipher/MGLGenerateKeyPairSyncInstaller.cpp +0 -63
- package/cpp/Cipher/MGLGenerateKeyPairSyncInstaller.h +0 -37
- package/cpp/Cipher/MGLPublicCipher.h +0 -124
- package/cpp/Cipher/MGLPublicCipherInstaller.h +0 -107
- package/cpp/Cipher/MGLRsa.cpp +0 -573
- package/cpp/Cipher/MGLRsa.h +0 -109
- package/cpp/HMAC/MGLHmacHostObject.cpp +0 -95
- package/cpp/HMAC/MGLHmacHostObject.h +0 -39
- package/cpp/HMAC/MGLHmacInstaller.cpp +0 -43
- package/cpp/HMAC/MGLHmacInstaller.h +0 -20
- package/cpp/Hash/MGLHashHostObject.cpp +0 -147
- package/cpp/Hash/MGLHashHostObject.h +0 -53
- package/cpp/Hash/MGLHashInstaller.cpp +0 -44
- package/cpp/Hash/MGLHashInstaller.h +0 -20
- package/cpp/JSIUtils/MGLJSIMacros.h +0 -110
- package/cpp/JSIUtils/MGLJSIUtils.h +0 -41
- package/cpp/JSIUtils/MGLSmartHostObject.cpp +0 -43
- package/cpp/JSIUtils/MGLSmartHostObject.h +0 -46
- package/cpp/JSIUtils/MGLThreadAwareHostObject.cpp +0 -24
- package/cpp/JSIUtils/MGLThreadAwareHostObject.h +0 -43
- package/cpp/JSIUtils/MGLTypedArray.cpp +0 -325
- package/cpp/JSIUtils/MGLTypedArray.h +0 -160
- package/cpp/MGLKeys.cpp +0 -1426
- package/cpp/MGLKeys.h +0 -203
- package/cpp/MGLQuickCryptoHostObject.cpp +0 -127
- package/cpp/MGLQuickCryptoHostObject.h +0 -30
- package/cpp/Random/MGLRandomHostObject.cpp +0 -96
- package/cpp/Random/MGLRandomHostObject.h +0 -27
- package/cpp/Sig/MGLSignHostObjects.cpp +0 -757
- package/cpp/Sig/MGLSignHostObjects.h +0 -128
- package/cpp/Sig/MGLSignInstaller.cpp +0 -24
- package/cpp/Sig/MGLSignInstaller.h +0 -29
- package/cpp/Sig/MGLVerifyInstaller.cpp +0 -24
- package/cpp/Sig/MGLVerifyInstaller.h +0 -22
- package/cpp/Utils/MGLDispatchQueue.cpp +0 -75
- package/cpp/Utils/MGLDispatchQueue.h +0 -55
- package/cpp/Utils/MGLUtils.cpp +0 -295
- package/cpp/Utils/MGLUtils.h +0 -358
- package/cpp/Utils/base64.h +0 -320
- package/cpp/Utils/logs.h +0 -38
- package/cpp/Utils/node.h +0 -13
- package/cpp/fastpbkdf2/MGLPbkdf2HostObject.cpp +0 -164
- package/cpp/fastpbkdf2/MGLPbkdf2HostObject.h +0 -29
- package/cpp/fastpbkdf2/fastpbkdf2.c +0 -352
- package/cpp/fastpbkdf2/fastpbkdf2.h +0 -68
- package/cpp/webcrypto/MGLWebCrypto.cpp +0 -125
- package/cpp/webcrypto/MGLWebCrypto.h +0 -32
- package/cpp/webcrypto/crypto_aes.cpp +0 -516
- package/cpp/webcrypto/crypto_aes.h +0 -79
- package/cpp/webcrypto/crypto_ec.cpp +0 -424
- package/cpp/webcrypto/crypto_ec.h +0 -78
- package/cpp/webcrypto/crypto_keygen.cpp +0 -86
- package/cpp/webcrypto/crypto_keygen.h +0 -38
- package/ios/QuickCrypto.xcodeproj/project.pbxproj +0 -274
- package/ios/QuickCryptoModule.h +0 -5
- package/ios/QuickCryptoModule.mm +0 -42
- package/lib/commonjs/Cipher.js +0 -502
- package/lib/commonjs/Cipher.js.map +0 -1
- package/lib/commonjs/Hash.js +0 -99
- package/lib/commonjs/Hash.js.map +0 -1
- package/lib/commonjs/Hashnames.js +0 -87
- package/lib/commonjs/Hashnames.js.map +0 -1
- package/lib/commonjs/Hmac.js +0 -79
- package/lib/commonjs/Hmac.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/Cipher.js +0 -30
- package/lib/commonjs/NativeQuickCrypto/Cipher.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/NativeQuickCrypto.js +0 -52
- package/lib/commonjs/NativeQuickCrypto/NativeQuickCrypto.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/aes.js +0 -6
- package/lib/commonjs/NativeQuickCrypto/hash.js +0 -2
- package/lib/commonjs/NativeQuickCrypto/hash.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/hmac.js +0 -2
- package/lib/commonjs/NativeQuickCrypto/hmac.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/keygen.js +0 -6
- package/lib/commonjs/NativeQuickCrypto/keygen.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/pbkdf2.js +0 -2
- package/lib/commonjs/NativeQuickCrypto/pbkdf2.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/random.js +0 -2
- package/lib/commonjs/NativeQuickCrypto/random.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/sig.js +0 -19
- package/lib/commonjs/NativeQuickCrypto/sig.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/webcrypto.js +0 -6
- package/lib/commonjs/NativeQuickCrypto/webcrypto.js.map +0 -1
- package/lib/commonjs/Utils.js +0 -608
- package/lib/commonjs/Utils.js.map +0 -1
- package/lib/commonjs/aes.js +0 -281
- package/lib/commonjs/aes.js.map +0 -1
- package/lib/commonjs/constants.js +0 -85
- package/lib/commonjs/constants.js.map +0 -1
- package/lib/commonjs/ec.js +0 -276
- package/lib/commonjs/ec.js.map +0 -1
- package/lib/commonjs/keygen.js +0 -56
- package/lib/commonjs/keygen.js.map +0 -1
- package/lib/commonjs/keys.js +0 -492
- package/lib/commonjs/keys.js.map +0 -1
- package/lib/commonjs/pbkdf2.js +0 -90
- package/lib/commonjs/pbkdf2.js.map +0 -1
- package/lib/commonjs/rsa.js +0 -248
- package/lib/commonjs/rsa.js.map +0 -1
- package/lib/commonjs/sig.js +0 -129
- package/lib/commonjs/sig.js.map +0 -1
- package/lib/commonjs/subtle.js +0 -448
- package/lib/commonjs/subtle.js.map +0 -1
- package/lib/commonjs/webcrypto.js +0 -14
- package/lib/commonjs/webcrypto.js.map +0 -1
- package/lib/module/Cipher.js +0 -491
- package/lib/module/Cipher.js.map +0 -1
- package/lib/module/Hash.js +0 -93
- package/lib/module/Hash.js.map +0 -1
- package/lib/module/Hashnames.js +0 -85
- package/lib/module/Hashnames.js.map +0 -1
- package/lib/module/Hmac.js +0 -74
- package/lib/module/Hmac.js.map +0 -1
- package/lib/module/NativeQuickCrypto/Cipher.js +0 -26
- package/lib/module/NativeQuickCrypto/Cipher.js.map +0 -1
- package/lib/module/NativeQuickCrypto/NativeQuickCrypto.js +0 -49
- package/lib/module/NativeQuickCrypto/NativeQuickCrypto.js.map +0 -1
- package/lib/module/NativeQuickCrypto/aes.js +0 -4
- package/lib/module/NativeQuickCrypto/hash.js +0 -2
- package/lib/module/NativeQuickCrypto/hash.js.map +0 -1
- package/lib/module/NativeQuickCrypto/hmac.js +0 -2
- package/lib/module/NativeQuickCrypto/hmac.js.map +0 -1
- package/lib/module/NativeQuickCrypto/keygen.js +0 -4
- package/lib/module/NativeQuickCrypto/keygen.js.map +0 -1
- package/lib/module/NativeQuickCrypto/pbkdf2.js +0 -2
- package/lib/module/NativeQuickCrypto/pbkdf2.js.map +0 -1
- package/lib/module/NativeQuickCrypto/random.js +0 -2
- package/lib/module/NativeQuickCrypto/random.js.map +0 -1
- package/lib/module/NativeQuickCrypto/rsa.js +0 -4
- package/lib/module/NativeQuickCrypto/sig.js +0 -17
- package/lib/module/NativeQuickCrypto/sig.js.map +0 -1
- package/lib/module/NativeQuickCrypto/webcrypto.js +0 -4
- package/lib/module/NativeQuickCrypto/webcrypto.js.map +0 -1
- package/lib/module/Utils.js +0 -539
- package/lib/module/Utils.js.map +0 -1
- package/lib/module/aes.js +0 -274
- package/lib/module/aes.js.map +0 -1
- package/lib/module/constants.js +0 -81
- package/lib/module/constants.js.map +0 -1
- package/lib/module/ec.js +0 -267
- package/lib/module/ec.js.map +0 -1
- package/lib/module/keygen.js +0 -49
- package/lib/module/keygen.js.map +0 -1
- package/lib/module/keys.js +0 -477
- package/lib/module/keys.js.map +0 -1
- package/lib/module/pbkdf2.js +0 -84
- package/lib/module/pbkdf2.js.map +0 -1
- package/lib/module/rsa.js +0 -242
- package/lib/module/rsa.js.map +0 -1
- package/lib/module/sig.js +0 -124
- package/lib/module/sig.js.map +0 -1
- package/lib/module/subtle.js +0 -443
- package/lib/module/subtle.js.map +0 -1
- package/lib/module/webcrypto.js +0 -10
- package/lib/module/webcrypto.js.map +0 -1
- package/lib/typescript/Cipher.d.ts +0 -81
- package/lib/typescript/Cipher.d.ts.map +0 -1
- package/lib/typescript/Hash.d.ts +0 -44
- package/lib/typescript/Hash.d.ts.map +0 -1
- package/lib/typescript/Hashnames.d.ts +0 -11
- package/lib/typescript/Hashnames.d.ts.map +0 -1
- package/lib/typescript/Hmac.d.ts +0 -37
- package/lib/typescript/Hmac.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/Cipher.d.ts +0 -44
- package/lib/typescript/NativeQuickCrypto/Cipher.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/NativeQuickCrypto.d.ts +0 -33
- package/lib/typescript/NativeQuickCrypto/NativeQuickCrypto.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/aes.d.ts +0 -5
- package/lib/typescript/NativeQuickCrypto/aes.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/hash.d.ts +0 -7
- package/lib/typescript/NativeQuickCrypto/hash.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/hmac.d.ts +0 -6
- package/lib/typescript/NativeQuickCrypto/hmac.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/keygen.d.ts +0 -4
- package/lib/typescript/NativeQuickCrypto/keygen.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/pbkdf2.d.ts +0 -5
- package/lib/typescript/NativeQuickCrypto/pbkdf2.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/random.d.ts +0 -5
- package/lib/typescript/NativeQuickCrypto/random.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/rsa.d.ts +0 -5
- package/lib/typescript/NativeQuickCrypto/rsa.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/sig.d.ts +0 -23
- package/lib/typescript/NativeQuickCrypto/sig.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/webcrypto.d.ts +0 -39
- package/lib/typescript/NativeQuickCrypto/webcrypto.d.ts.map +0 -1
- package/lib/typescript/Utils.d.ts +0 -48
- package/lib/typescript/Utils.d.ts.map +0 -1
- package/lib/typescript/aes.d.ts +0 -22
- package/lib/typescript/aes.d.ts.map +0 -1
- package/lib/typescript/constants.d.ts +0 -76
- package/lib/typescript/constants.d.ts.map +0 -1
- package/lib/typescript/ec.d.ts +0 -7
- package/lib/typescript/ec.d.ts.map +0 -1
- package/lib/typescript/keygen.d.ts +0 -6
- package/lib/typescript/keygen.d.ts.map +0 -1
- package/lib/typescript/keys.d.ts +0 -206
- package/lib/typescript/keys.d.ts.map +0 -1
- package/lib/typescript/pbkdf2.d.ts +0 -12
- package/lib/typescript/pbkdf2.d.ts.map +0 -1
- package/lib/typescript/rsa.d.ts +0 -12
- package/lib/typescript/rsa.d.ts.map +0 -1
- package/lib/typescript/sig.d.ts +0 -21
- package/lib/typescript/sig.d.ts.map +0 -1
- package/lib/typescript/subtle.d.ts +0 -15
- package/lib/typescript/subtle.d.ts.map +0 -1
- package/lib/typescript/webcrypto.d.ts +0 -9
- package/lib/typescript/webcrypto.d.ts.map +0 -1
- package/react-native-quick-crypto.podspec +0 -40
- package/src/Cipher.ts +0 -832
- package/src/Hash.ts +0 -132
- package/src/Hashnames.ts +0 -93
- package/src/Hmac.ts +0 -106
- package/src/NativeQuickCrypto/Cipher.ts +0 -102
- package/src/NativeQuickCrypto/NativeQuickCrypto.ts +0 -102
- package/src/NativeQuickCrypto/aes.ts +0 -14
- package/src/NativeQuickCrypto/hash.ts +0 -10
- package/src/NativeQuickCrypto/hmac.ts +0 -9
- package/src/NativeQuickCrypto/keygen.ts +0 -7
- package/src/NativeQuickCrypto/pbkdf2.ts +0 -16
- package/src/NativeQuickCrypto/random.ts +0 -12
- package/src/NativeQuickCrypto/rsa.ts +0 -12
- package/src/NativeQuickCrypto/sig.ts +0 -44
- package/src/NativeQuickCrypto/webcrypto.ts +0 -72
- package/src/Utils.ts +0 -777
- package/src/aes.ts +0 -402
- package/src/constants.ts +0 -79
- package/src/ec.ts +0 -375
- package/src/keygen.ts +0 -80
- package/src/keys.ts +0 -787
- package/src/pbkdf2.ts +0 -169
- package/src/rsa.ts +0 -370
- package/src/sig.ts +0 -164
- package/src/subtle.ts +0 -639
- package/src/webcrypto.ts +0 -8
- /package/android/src/main/{AndroidManifestNew.xml → AndroidManifest.xml} +0 -0
package/cpp/MGLKeys.cpp
DELETED
|
@@ -1,1426 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// MGLCipherKeys.cpp
|
|
3
|
-
// react-native-quick-crypto
|
|
4
|
-
//
|
|
5
|
-
// Created by Oscar on 20.06.22.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
#include "MGLKeys.h"
|
|
9
|
-
|
|
10
|
-
#include <jsi/jsi.h>
|
|
11
|
-
#include <openssl/bio.h>
|
|
12
|
-
#include <openssl/ec.h>
|
|
13
|
-
|
|
14
|
-
#include <algorithm>
|
|
15
|
-
#include <iostream>
|
|
16
|
-
#include <optional>
|
|
17
|
-
#include <utility>
|
|
18
|
-
#include <vector>
|
|
19
|
-
|
|
20
|
-
#ifdef ANDROID
|
|
21
|
-
#include "Cipher/MGLRsa.h"
|
|
22
|
-
#include "JSIUtils/MGLJSIMacros.h"
|
|
23
|
-
#include "JSIUtils/MGLJSIUtils.h"
|
|
24
|
-
#include "JSIUtils/MGLTypedArray.h"
|
|
25
|
-
#include "Utils/MGLUtils.h"
|
|
26
|
-
#include "webcrypto/crypto_ec.h"
|
|
27
|
-
#else
|
|
28
|
-
#include "MGLRsa.h"
|
|
29
|
-
#include "MGLJSIMacros.h"
|
|
30
|
-
#include "MGLJSIUtils.h"
|
|
31
|
-
#include "MGLTypedArray.h"
|
|
32
|
-
#include "MGLUtils.h"
|
|
33
|
-
#include "crypto_ec.h"
|
|
34
|
-
#endif
|
|
35
|
-
|
|
36
|
-
namespace margelo {
|
|
37
|
-
namespace jsi = facebook::jsi;
|
|
38
|
-
|
|
39
|
-
void GetKeyFormatAndTypeFromJs(AsymmetricKeyEncodingConfig* config,
|
|
40
|
-
jsi::Runtime& runtime, const jsi::Value* args,
|
|
41
|
-
unsigned int* offset,
|
|
42
|
-
KeyEncodingContext context) {
|
|
43
|
-
// During key pair generation, it is possible not to specify a key encoding,
|
|
44
|
-
// which will lead to a key object being returned.
|
|
45
|
-
if (args[*offset].isUndefined()) {
|
|
46
|
-
CHECK_EQ(context, kKeyContextGenerate);
|
|
47
|
-
CHECK(args[*offset + 1].isUndefined());
|
|
48
|
-
config->output_key_object_ = true;
|
|
49
|
-
} else {
|
|
50
|
-
config->output_key_object_ = false;
|
|
51
|
-
|
|
52
|
-
// TODO(osp) implement check
|
|
53
|
-
// CHECK(args[*offset]->IsInt32());
|
|
54
|
-
config->format_ = static_cast<PKFormatType>((int)args[*offset].getNumber());
|
|
55
|
-
|
|
56
|
-
if (args[*offset + 1].isNumber()) {
|
|
57
|
-
config->type_ =
|
|
58
|
-
static_cast<PKEncodingType>((int)args[*offset + 1].getNumber());
|
|
59
|
-
} else {
|
|
60
|
-
CHECK(
|
|
61
|
-
(context == kKeyContextInput && config->format_ == kKeyFormatPEM) ||
|
|
62
|
-
(context == kKeyContextGenerate && config->format_ == kKeyFormatJWK));
|
|
63
|
-
CHECK(args[*offset + 1].isUndefined());
|
|
64
|
-
config->type_ = std::nullopt;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
*offset += 2;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
ParseKeyResult TryParsePublicKey(
|
|
72
|
-
EVPKeyPointer* pkey, const BIOPointer& bp, const char* name,
|
|
73
|
-
const std::function<EVP_PKEY*(const unsigned char** p, long l)>& parse) {
|
|
74
|
-
unsigned char* der_data;
|
|
75
|
-
long der_len;
|
|
76
|
-
|
|
77
|
-
// This skips surrounding data and decodes PEM to DER.
|
|
78
|
-
if (PEM_bytes_read_bio(&der_data, &der_len, nullptr, name, bp.get(), nullptr,
|
|
79
|
-
nullptr) != 1) {
|
|
80
|
-
return ParseKeyResult::kParseKeyNotRecognized;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// OpenSSL might modify the pointer, so we need to make a copy before parsing.
|
|
84
|
-
const unsigned char* p = der_data;
|
|
85
|
-
pkey->reset(parse(&p, der_len));
|
|
86
|
-
OPENSSL_clear_free(der_data, der_len);
|
|
87
|
-
|
|
88
|
-
return *pkey ? ParseKeyResult::kParseKeyOk : ParseKeyResult::kParseKeyFailed;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
ParseKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey, const char* key_pem,
|
|
92
|
-
int key_pem_len) {
|
|
93
|
-
BIOPointer bp(BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len));
|
|
94
|
-
if (!bp) return ParseKeyResult::kParseKeyFailed;
|
|
95
|
-
|
|
96
|
-
ParseKeyResult ret;
|
|
97
|
-
|
|
98
|
-
// Try parsing as a SubjectPublicKeyInfo first.
|
|
99
|
-
ret = TryParsePublicKey(pkey, bp, "PUBLIC KEY",
|
|
100
|
-
[](const unsigned char** p, long l) {
|
|
101
|
-
return d2i_PUBKEY(nullptr, p, l);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
if (ret != ParseKeyResult::kParseKeyNotRecognized) return ret;
|
|
105
|
-
|
|
106
|
-
// Maybe it is PKCS#1.
|
|
107
|
-
BIO_reset(bp.get());
|
|
108
|
-
ret = TryParsePublicKey(pkey, bp, "RSA PUBLIC KEY",
|
|
109
|
-
[](const unsigned char** p, long l) {
|
|
110
|
-
return d2i_PublicKey(EVP_PKEY_RSA, nullptr, p, l);
|
|
111
|
-
});
|
|
112
|
-
if (ret != ParseKeyResult::kParseKeyNotRecognized) return ret;
|
|
113
|
-
|
|
114
|
-
// X.509 fallback.
|
|
115
|
-
BIO_reset(bp.get());
|
|
116
|
-
return TryParsePublicKey(
|
|
117
|
-
pkey, bp, "CERTIFICATE", [](const unsigned char** p, long l) {
|
|
118
|
-
X509Pointer x509(d2i_X509(nullptr, p, l));
|
|
119
|
-
return x509 ? X509_get_pubkey(x509.get()) : nullptr;
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
ParseKeyResult ParsePublicKey(EVPKeyPointer* pkey,
|
|
124
|
-
const PublicKeyEncodingConfig& config,
|
|
125
|
-
const char* key, size_t key_len) {
|
|
126
|
-
if (config.format_ == kKeyFormatPEM) {
|
|
127
|
-
return ParsePublicKeyPEM(pkey, key, key_len);
|
|
128
|
-
} else {
|
|
129
|
-
// CHECK_EQ(config.format_, kKeyFormatDER);
|
|
130
|
-
|
|
131
|
-
const unsigned char* p = reinterpret_cast<const unsigned char*>(key);
|
|
132
|
-
if (config.type_.value() == kKeyEncodingPKCS1) {
|
|
133
|
-
pkey->reset(d2i_PublicKey(EVP_PKEY_RSA, nullptr, &p, key_len));
|
|
134
|
-
} else {
|
|
135
|
-
// CHECK_EQ(config.type_.ToChecked(), kKeyEncodingSPKI);
|
|
136
|
-
pkey->reset(d2i_PUBKEY(nullptr, &p, key_len));
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return *pkey ? ParseKeyResult::kParseKeyOk
|
|
140
|
-
: ParseKeyResult::kParseKeyFailed;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
bool IsASN1Sequence(const unsigned char* data, size_t size, size_t* data_offset,
|
|
145
|
-
size_t* data_size) {
|
|
146
|
-
if (size < 2 || data[0] != 0x30) return false;
|
|
147
|
-
|
|
148
|
-
if (data[1] & 0x80) {
|
|
149
|
-
// Long form.
|
|
150
|
-
size_t n_bytes = data[1] & ~0x80;
|
|
151
|
-
if (n_bytes + 2 > size || n_bytes > sizeof(size_t)) return false;
|
|
152
|
-
size_t length = 0;
|
|
153
|
-
for (size_t i = 0; i < n_bytes; i++) length = (length << 8) | data[i + 2];
|
|
154
|
-
*data_offset = 2 + n_bytes;
|
|
155
|
-
*data_size = std::min(size - 2 - n_bytes, length);
|
|
156
|
-
} else {
|
|
157
|
-
// Short form.
|
|
158
|
-
*data_offset = 2;
|
|
159
|
-
*data_size = std::min<size_t>(size - 2, data[1]);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
bool IsRSAPrivateKey(const unsigned char* data, size_t size) {
|
|
166
|
-
// Both RSAPrivateKey and RSAPublicKey structures start with a SEQUENCE.
|
|
167
|
-
size_t offset, len;
|
|
168
|
-
if (!IsASN1Sequence(data, size, &offset, &len)) return false;
|
|
169
|
-
|
|
170
|
-
// An RSAPrivateKey sequence always starts with a single-byte integer whose
|
|
171
|
-
// value is either 0 or 1, whereas an RSAPublicKey starts with the modulus
|
|
172
|
-
// (which is the product of two primes and therefore at least 4), so we can
|
|
173
|
-
// decide the type of the structure based on the first three bytes of the
|
|
174
|
-
// sequence.
|
|
175
|
-
return len >= 3 && data[offset] == 2 && data[offset + 1] == 1 &&
|
|
176
|
-
!(data[offset + 2] & 0xfe);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
bool IsEncryptedPrivateKeyInfo(const unsigned char* data, size_t size) {
|
|
180
|
-
// Both PrivateKeyInfo and EncryptedPrivateKeyInfo start with a SEQUENCE.
|
|
181
|
-
size_t offset, len;
|
|
182
|
-
if (!IsASN1Sequence(data, size, &offset, &len)) return false;
|
|
183
|
-
|
|
184
|
-
// A PrivateKeyInfo sequence always starts with an integer whereas an
|
|
185
|
-
// EncryptedPrivateKeyInfo starts with an AlgorithmIdentifier.
|
|
186
|
-
return len >= 1 && data[offset] != 2;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
ParseKeyResult ParsePrivateKey(EVPKeyPointer* pkey,
|
|
190
|
-
const PrivateKeyEncodingConfig& config,
|
|
191
|
-
const char* key, size_t key_len) {
|
|
192
|
-
const ByteSource* passphrase = config.passphrase_.get();
|
|
193
|
-
|
|
194
|
-
if (config.format_ == kKeyFormatPEM) {
|
|
195
|
-
BIOPointer bio(BIO_new_mem_buf(key, (int)key_len));
|
|
196
|
-
if (!bio) {
|
|
197
|
-
return ParseKeyResult::kParseKeyFailed;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
pkey->reset(PEM_read_bio_PrivateKey(bio.get(), nullptr, PasswordCallback,
|
|
201
|
-
&passphrase));
|
|
202
|
-
} else {
|
|
203
|
-
CHECK_EQ(config.format_, kKeyFormatDER);
|
|
204
|
-
|
|
205
|
-
if (!config.type_.has_value()) {
|
|
206
|
-
throw new std::runtime_error("ParsePrivateKey key config has no type!");
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (config.type_.value() == kKeyEncodingPKCS1) {
|
|
210
|
-
const unsigned char* p = reinterpret_cast<const unsigned char*>(key);
|
|
211
|
-
pkey->reset(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &p, key_len));
|
|
212
|
-
} else if (config.type_.value() == kKeyEncodingPKCS8) {
|
|
213
|
-
BIOPointer bio(BIO_new_mem_buf(key, (int)key_len));
|
|
214
|
-
if (!bio) return ParseKeyResult::kParseKeyFailed;
|
|
215
|
-
|
|
216
|
-
if (IsEncryptedPrivateKeyInfo(reinterpret_cast<const unsigned char*>(key),
|
|
217
|
-
key_len)) {
|
|
218
|
-
pkey->reset(d2i_PKCS8PrivateKey_bio(bio.get(), nullptr,
|
|
219
|
-
PasswordCallback, &passphrase));
|
|
220
|
-
} else {
|
|
221
|
-
PKCS8Pointer p8inf(d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), nullptr));
|
|
222
|
-
if (p8inf) pkey->reset(EVP_PKCS82PKEY(p8inf.get()));
|
|
223
|
-
}
|
|
224
|
-
} else {
|
|
225
|
-
CHECK_EQ(config.type_.value(), kKeyEncodingSEC1);
|
|
226
|
-
const unsigned char* p = reinterpret_cast<const unsigned char*>(key);
|
|
227
|
-
pkey->reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, key_len));
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// OpenSSL can fail to parse the key but still return a non-null pointer.
|
|
232
|
-
unsigned long err = ERR_peek_error(); // NOLINT(runtime/int)
|
|
233
|
-
auto reason = ERR_GET_REASON(err);
|
|
234
|
-
// Per OpenSSL documentation PEM_R_NO_START_LINE signals all PEM certs have
|
|
235
|
-
// been consumed and is a harmless error
|
|
236
|
-
if (reason == PEM_R_NO_START_LINE && *pkey) {
|
|
237
|
-
return ParseKeyResult::kParseKeyOk;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (err != 0) pkey->reset();
|
|
241
|
-
|
|
242
|
-
if (*pkey) {
|
|
243
|
-
return ParseKeyResult::kParseKeyOk;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (ERR_GET_LIB(err) == ERR_LIB_PEM) {
|
|
247
|
-
if (reason == PEM_R_BAD_PASSWORD_READ && config.passphrase_.IsEmpty()) {
|
|
248
|
-
return ParseKeyResult::kParseKeyNeedPassphrase;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
return ParseKeyResult::kParseKeyFailed;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
jsi::Value BIOToStringOrBuffer(jsi::Runtime& rt, BIO* bio, PKFormatType format) {
|
|
255
|
-
BUF_MEM* bptr;
|
|
256
|
-
BIO_get_mem_ptr(bio, &bptr);
|
|
257
|
-
if (format == kKeyFormatPEM) {
|
|
258
|
-
// PEM is an ASCII format, so we will return it as a string.
|
|
259
|
-
return toJSI(rt, std::string(bptr->data, bptr->length));
|
|
260
|
-
} else {
|
|
261
|
-
CHECK_EQ(format, kKeyFormatDER);
|
|
262
|
-
// DER is binary, return it as a buffer.
|
|
263
|
-
ByteSource::Builder out(bptr->length);
|
|
264
|
-
memcpy(out.data<void>(), bptr->data, bptr->length);
|
|
265
|
-
return toJSI(rt, std::move(out).release());
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
jsi::Value WritePrivateKey(
|
|
270
|
-
jsi::Runtime& runtime, EVP_PKEY* pkey,
|
|
271
|
-
const PrivateKeyEncodingConfig& config) {
|
|
272
|
-
BIOPointer bio(BIO_new(BIO_s_mem()));
|
|
273
|
-
CHECK(bio);
|
|
274
|
-
|
|
275
|
-
// If an empty string was passed as the passphrase, the ByteSource might
|
|
276
|
-
// contain a null pointer, which OpenSSL will ignore, causing it to invoke its
|
|
277
|
-
// default passphrase callback, which would block the thread until the user
|
|
278
|
-
// manually enters a passphrase. We could supply our own passphrase callback
|
|
279
|
-
// to handle this special case, but it is easier to avoid passing a null
|
|
280
|
-
// pointer to OpenSSL.
|
|
281
|
-
char* pass = nullptr;
|
|
282
|
-
size_t pass_len = 0;
|
|
283
|
-
if (!config.passphrase_.IsEmpty()) {
|
|
284
|
-
pass = const_cast<char*>(config.passphrase_->data<char>());
|
|
285
|
-
pass_len = config.passphrase_->size();
|
|
286
|
-
if (pass == nullptr) {
|
|
287
|
-
// OpenSSL will not actually dereference this pointer, so it can be any
|
|
288
|
-
// non-null pointer. We cannot assert that directly, which is why we
|
|
289
|
-
// intentionally use a pointer that will likely cause a segmentation fault
|
|
290
|
-
// when dereferenced.
|
|
291
|
-
// CHECK_EQ(pass_len, 0);
|
|
292
|
-
pass = reinterpret_cast<char*>(-1);
|
|
293
|
-
// CHECK_NE(pass, nullptr);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
bool err = false;
|
|
298
|
-
PKEncodingType encoding_type;
|
|
299
|
-
|
|
300
|
-
if (config.type_.has_value()) {
|
|
301
|
-
encoding_type = config.type_.value();
|
|
302
|
-
} else {
|
|
303
|
-
// default for no value in std::option `config.type_`
|
|
304
|
-
encoding_type = kKeyEncodingSEC1;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (encoding_type == kKeyEncodingPKCS1) {
|
|
308
|
-
// PKCS#1 is only permitted for RSA keys.
|
|
309
|
-
// CHECK_EQ(EVP_PKEY_id(pkey), EVP_PKEY_RSA);
|
|
310
|
-
|
|
311
|
-
RsaPointer rsa(EVP_PKEY_get1_RSA(pkey));
|
|
312
|
-
if (config.format_ == kKeyFormatPEM) {
|
|
313
|
-
// Encode PKCS#1 as PEM.
|
|
314
|
-
err = PEM_write_bio_RSAPrivateKey(bio.get(), rsa.get(), config.cipher_,
|
|
315
|
-
reinterpret_cast<unsigned char*>(pass),
|
|
316
|
-
pass_len, nullptr, nullptr) != 1;
|
|
317
|
-
} else {
|
|
318
|
-
// Encode PKCS#1 as DER. This does not permit encryption.
|
|
319
|
-
CHECK_EQ(config.format_, kKeyFormatDER);
|
|
320
|
-
CHECK_NULL(config.cipher_);
|
|
321
|
-
err = i2d_RSAPrivateKey_bio(bio.get(), rsa.get()) != 1;
|
|
322
|
-
}
|
|
323
|
-
} else if (encoding_type == kKeyEncodingPKCS8) {
|
|
324
|
-
if (config.format_ == kKeyFormatPEM) {
|
|
325
|
-
// Encode PKCS#8 as PEM.
|
|
326
|
-
err = PEM_write_bio_PKCS8PrivateKey(bio.get(), pkey, config.cipher_, pass,
|
|
327
|
-
pass_len, nullptr, nullptr) != 1;
|
|
328
|
-
} else {
|
|
329
|
-
// Encode PKCS#8 as DER.
|
|
330
|
-
CHECK_EQ(config.format_, kKeyFormatDER);
|
|
331
|
-
err = i2d_PKCS8PrivateKey_bio(bio.get(), pkey, config.cipher_, pass,
|
|
332
|
-
pass_len, nullptr, nullptr) != 1;
|
|
333
|
-
}
|
|
334
|
-
} else {
|
|
335
|
-
CHECK_EQ(encoding_type, kKeyEncodingSEC1);
|
|
336
|
-
|
|
337
|
-
// SEC1 is only permitted for EC keys.
|
|
338
|
-
CHECK_EQ(EVP_PKEY_id(pkey), EVP_PKEY_EC);
|
|
339
|
-
|
|
340
|
-
ECKeyPointer ec_key(EVP_PKEY_get1_EC_KEY(pkey));
|
|
341
|
-
if (config.format_ == kKeyFormatPEM) {
|
|
342
|
-
// Encode SEC1 as PEM.
|
|
343
|
-
err = PEM_write_bio_ECPrivateKey(bio.get(),ec_key.get(), config.cipher_,
|
|
344
|
-
reinterpret_cast<unsigned char*>(pass),
|
|
345
|
-
pass_len, nullptr, nullptr) != 1;
|
|
346
|
-
} else {
|
|
347
|
-
// Encode SEC1 as DER. This does not permit encryption.
|
|
348
|
-
CHECK_EQ(config.format_, kKeyFormatDER);
|
|
349
|
-
// CHECK_NULL(config.cipher_);
|
|
350
|
-
err = i2d_ECPrivateKey_bio(bio.get(), ec_key.get()) != 1;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
if (err) {
|
|
355
|
-
throw jsi::JSError(runtime, "Failed to encode private key");
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
return BIOToStringOrBuffer(runtime, bio.get(), config.format_);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
bool WritePublicKeyInner(EVP_PKEY* pkey, const BIOPointer& bio,
|
|
362
|
-
const PublicKeyEncodingConfig& config) {
|
|
363
|
-
if (!config.type_.has_value()) return false;
|
|
364
|
-
if (config.type_.value() == kKeyEncodingPKCS1) {
|
|
365
|
-
// PKCS#1 is only valid for RSA keys.
|
|
366
|
-
CHECK_EQ(EVP_PKEY_id(pkey), EVP_PKEY_RSA);
|
|
367
|
-
RsaPointer rsa(EVP_PKEY_get1_RSA(pkey));
|
|
368
|
-
if (config.format_ == kKeyFormatPEM) {
|
|
369
|
-
// Encode PKCS#1 as PEM.
|
|
370
|
-
return PEM_write_bio_RSAPublicKey(bio.get(), rsa.get()) == 1;
|
|
371
|
-
} else {
|
|
372
|
-
// Encode PKCS#1 as DER.
|
|
373
|
-
CHECK_EQ(config.format_, kKeyFormatDER);
|
|
374
|
-
return i2d_RSAPublicKey_bio(bio.get(), rsa.get()) == 1;
|
|
375
|
-
}
|
|
376
|
-
} else {
|
|
377
|
-
CHECK_EQ(config.type_.value(), kKeyEncodingSPKI);
|
|
378
|
-
if (config.format_ == kKeyFormatPEM) {
|
|
379
|
-
// Encode SPKI as PEM.
|
|
380
|
-
return PEM_write_bio_PUBKEY(bio.get(), pkey) == 1;
|
|
381
|
-
} else {
|
|
382
|
-
// Encode SPKI as DER.
|
|
383
|
-
CHECK_EQ(config.format_, kKeyFormatDER);
|
|
384
|
-
return i2d_PUBKEY_bio(bio.get(), pkey) == 1;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
jsi::Value WritePublicKey(
|
|
390
|
-
jsi::Runtime& runtime, EVP_PKEY* pkey,
|
|
391
|
-
const PublicKeyEncodingConfig& config) {
|
|
392
|
-
BIOPointer bio(BIO_new(BIO_s_mem()));
|
|
393
|
-
CHECK(bio);
|
|
394
|
-
|
|
395
|
-
if (!WritePublicKeyInner(pkey, bio, config)) {
|
|
396
|
-
throw jsi::JSError(runtime, "Failed to encode public key");
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
return BIOToStringOrBuffer(runtime, bio.get(), config.format_);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
jsi::Value ExportJWKSecretKey(jsi::Runtime &rt,
|
|
403
|
-
std::shared_ptr<KeyObjectData> key,
|
|
404
|
-
jsi::Object &result) {
|
|
405
|
-
CHECK_EQ(key->GetKeyType(), kKeyTypeSecret);
|
|
406
|
-
|
|
407
|
-
std::string key_data = EncodeBase64(key->GetSymmetricKey(), true);
|
|
408
|
-
|
|
409
|
-
result.setProperty(rt, "kty", "oct");
|
|
410
|
-
result.setProperty(rt, "k", key_data);
|
|
411
|
-
return std::move(result);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
std::shared_ptr<KeyObjectData> ImportJWKSecretKey(jsi::Runtime &rt,
|
|
415
|
-
jsi::Object &jwk) {
|
|
416
|
-
std::string key = jwk
|
|
417
|
-
.getProperty(rt, "k")
|
|
418
|
-
.asString(rt)
|
|
419
|
-
.utf8(rt);
|
|
420
|
-
|
|
421
|
-
// TODO: when adding tests, trap errors like below (i.e. no `k` property, undefined)
|
|
422
|
-
// Local<Value> key;
|
|
423
|
-
// if (!jwk->Get(env->context(), env->jwk_k_string()).ToLocal(&key) ||
|
|
424
|
-
// !key->IsString()) {
|
|
425
|
-
// THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK secret key format");
|
|
426
|
-
// return std::shared_ptr<KeyObjectData>();
|
|
427
|
-
// }
|
|
428
|
-
|
|
429
|
-
ByteSource key_data = ByteSource::FromEncodedString(rt, key, encoding::BASE64URL);
|
|
430
|
-
if (key_data.size() > INT_MAX) {
|
|
431
|
-
throw jsi::JSError(rt, "Invalid crypto key length");
|
|
432
|
-
return std::shared_ptr<KeyObjectData>();
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
return KeyObjectData::CreateSecret(std::move(key_data));
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
jsi::Value ExportJWKAsymmetricKey(jsi::Runtime &rt,
|
|
439
|
-
std::shared_ptr<KeyObjectData> key,
|
|
440
|
-
jsi::Object &target,
|
|
441
|
-
bool handleRsaPss) {
|
|
442
|
-
switch (EVP_PKEY_id(key->GetAsymmetricKey().get())) {
|
|
443
|
-
case EVP_PKEY_RSA_PSS: {
|
|
444
|
-
if (handleRsaPss) return ExportJWKRsaKey(rt, key, target);
|
|
445
|
-
break;
|
|
446
|
-
}
|
|
447
|
-
case EVP_PKEY_RSA: return ExportJWKRsaKey(rt, key, target);
|
|
448
|
-
case EVP_PKEY_EC: return ExportJWKEcKey(rt, key, target);
|
|
449
|
-
// case EVP_PKEY_ED25519:
|
|
450
|
-
// // Fall through
|
|
451
|
-
// case EVP_PKEY_ED448:
|
|
452
|
-
// // Fall through
|
|
453
|
-
// case EVP_PKEY_X25519:
|
|
454
|
-
// // Fall through
|
|
455
|
-
// case EVP_PKEY_X448: return ExportJWKEdKey(rt, key, target);
|
|
456
|
-
}
|
|
457
|
-
throw jsi::JSError(rt, "Unsupported JWK asymmetric key type");
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
std::shared_ptr<KeyObjectData> ImportJWKAsymmetricKey(jsi::Runtime &rt,
|
|
461
|
-
jsi::Object &jwk,
|
|
462
|
-
std::string kty,
|
|
463
|
-
jsi::Value &namedCurve) {
|
|
464
|
-
if (kty.compare("RSA") == 0) {
|
|
465
|
-
return ImportJWKRsaKey(rt, jwk);
|
|
466
|
-
} else if (kty.compare("EC") == 0) {
|
|
467
|
-
return ImportJWKEcKey(rt, jwk, namedCurve);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
throw jsi::JSError(rt, "%s is not a supported JWK key type", kty);
|
|
471
|
-
return std::shared_ptr<KeyObjectData>();
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
jsi::Value GetSecretKeyDetail(jsi::Runtime &rt,
|
|
475
|
-
std::shared_ptr<KeyObjectData> key) {
|
|
476
|
-
jsi::Object target = jsi::Object(rt);
|
|
477
|
-
// For the secret key detail, all we care about is the length,
|
|
478
|
-
// converted to bits.
|
|
479
|
-
size_t length = key->GetSymmetricKeySize() * CHAR_BIT;
|
|
480
|
-
target.setProperty(rt, "length", static_cast<double>(length));
|
|
481
|
-
return std::move(target);
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
jsi::Value GetAsymmetricKeyDetail(jsi::Runtime &rt,
|
|
485
|
-
std::shared_ptr<KeyObjectData> key) {
|
|
486
|
-
switch (EVP_PKEY_id(key->GetAsymmetricKey().get())) {
|
|
487
|
-
case EVP_PKEY_RSA:
|
|
488
|
-
// Fall through
|
|
489
|
-
case EVP_PKEY_RSA_PSS: return GetRsaKeyDetail(rt, key);
|
|
490
|
-
// case EVP_PKEY_DSA: return GetDsaKeyDetail(env, key);
|
|
491
|
-
case EVP_PKEY_EC: return GetEcKeyDetail(rt, key);
|
|
492
|
-
// case EVP_PKEY_DH: return GetDhKeyDetail(env, key);
|
|
493
|
-
}
|
|
494
|
-
throw jsi::JSError(rt, "Invalid Key Type");
|
|
495
|
-
return false;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
ManagedEVPPKey::ManagedEVPPKey(EVPKeyPointer&& pkey) : pkey_(std::move(pkey)) {}
|
|
499
|
-
|
|
500
|
-
ManagedEVPPKey::ManagedEVPPKey(const ManagedEVPPKey& that) { *this = that; }
|
|
501
|
-
|
|
502
|
-
ManagedEVPPKey& ManagedEVPPKey::operator=(const ManagedEVPPKey& that) {
|
|
503
|
-
// Mutex::ScopedLock lock(*that.mutex_);
|
|
504
|
-
|
|
505
|
-
pkey_.reset(that.get());
|
|
506
|
-
|
|
507
|
-
if (pkey_) EVP_PKEY_up_ref(pkey_.get());
|
|
508
|
-
|
|
509
|
-
// mutex_ = that.mutex_;
|
|
510
|
-
|
|
511
|
-
return *this;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
ManagedEVPPKey::operator bool() const { return !!pkey_; }
|
|
515
|
-
|
|
516
|
-
EVP_PKEY* ManagedEVPPKey::get() const { return pkey_.get(); }
|
|
517
|
-
|
|
518
|
-
// Mutex* ManagedEVPPKey::mutex() const {
|
|
519
|
-
// return mutex_.get();
|
|
520
|
-
//}
|
|
521
|
-
//
|
|
522
|
-
// void ManagedEVPPKey::MemoryInfo(MemoryTracker* tracker) const {
|
|
523
|
-
// tracker->TrackFieldWithSize("pkey",
|
|
524
|
-
// !pkey_ ? 0 : kSizeOf_EVP_PKEY +
|
|
525
|
-
// size_of_private_key() +
|
|
526
|
-
// size_of_public_key());
|
|
527
|
-
//}
|
|
528
|
-
|
|
529
|
-
size_t ManagedEVPPKey::size_of_private_key() const {
|
|
530
|
-
size_t len = 0;
|
|
531
|
-
return (pkey_ && EVP_PKEY_get_raw_private_key(pkey_.get(), nullptr, &len) == 1)
|
|
532
|
-
? len : 0;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
size_t ManagedEVPPKey::size_of_public_key() const {
|
|
536
|
-
size_t len = 0;
|
|
537
|
-
return (pkey_ && EVP_PKEY_get_raw_public_key(pkey_.get(), nullptr, &len) == 1)
|
|
538
|
-
? len : 0;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
jsi::Value ExportJWKInner(jsi::Runtime &rt,
|
|
542
|
-
std::shared_ptr<KeyObjectData> key,
|
|
543
|
-
jsi::Object &result,
|
|
544
|
-
bool handleRsaPss) {
|
|
545
|
-
switch (key->GetKeyType()) {
|
|
546
|
-
case kKeyTypeSecret:
|
|
547
|
-
return ExportJWKSecretKey(rt, key, result);
|
|
548
|
-
case kKeyTypePublic:
|
|
549
|
-
// Fall through
|
|
550
|
-
case kKeyTypePrivate:
|
|
551
|
-
return ExportJWKAsymmetricKey(rt, key, result, handleRsaPss);
|
|
552
|
-
default:
|
|
553
|
-
throw jsi::JSError(rt, "unreachable code in ExportJWKInner");
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
jsi::Value ManagedEVPPKey::ToEncodedPublicKey(jsi::Runtime& rt,
|
|
558
|
-
ManagedEVPPKey key,
|
|
559
|
-
const PublicKeyEncodingConfig& config) {
|
|
560
|
-
if (!key) return {};
|
|
561
|
-
if (config.output_key_object_) {
|
|
562
|
-
// Note that this has the downside of containing sensitive data of the
|
|
563
|
-
// private key.
|
|
564
|
-
auto data = KeyObjectData::CreateAsymmetric(kKeyTypePublic, std::move(key));
|
|
565
|
-
auto handle = KeyObjectHandle::Create(data);
|
|
566
|
-
auto out = jsi::Object::createFromHostObject(rt, handle);
|
|
567
|
-
return jsi::Value(std::move(out));
|
|
568
|
-
} else
|
|
569
|
-
if (config.format_ == kKeyFormatJWK) {
|
|
570
|
-
throw std::runtime_error("ToEncodedPublicKey 2 (JWK) not implemented from node");
|
|
571
|
-
// std::shared_ptr<KeyObjectData> data =
|
|
572
|
-
// KeyObjectData::CreateAsymmetric(kKeyTypePublic, std::move(key));
|
|
573
|
-
// *out = Object::New(env->isolate());
|
|
574
|
-
// return ExportJWKInner(env, data, *out, false);
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
return WritePublicKey(rt, key.get(), config);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
jsi::Value ManagedEVPPKey::ToEncodedPrivateKey(jsi::Runtime& rt,
|
|
581
|
-
ManagedEVPPKey key,
|
|
582
|
-
const PrivateKeyEncodingConfig& config) {
|
|
583
|
-
if (!key) return {};
|
|
584
|
-
if (config.output_key_object_) {
|
|
585
|
-
auto data = KeyObjectData::CreateAsymmetric(kKeyTypePrivate, std::move(key));
|
|
586
|
-
auto handle = KeyObjectHandle::Create(data);
|
|
587
|
-
auto out = jsi::Object::createFromHostObject(rt, handle);
|
|
588
|
-
return jsi::Value(std::move(out));
|
|
589
|
-
} else
|
|
590
|
-
if (config.format_ == kKeyFormatJWK) {
|
|
591
|
-
throw std::runtime_error("ToEncodedPrivateKey 2 (JWK) not implemented from node");
|
|
592
|
-
// std::shared_ptr<KeyObjectData> data =
|
|
593
|
-
// KeyObjectData::CreateAsymmetric(kKeyTypePrivate, std::move(key));
|
|
594
|
-
// *out = Object::New(env->isolate());
|
|
595
|
-
// return ExportJWKInner(env, data, *out, false);
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
return WritePrivateKey(rt, key.get(), config);
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
NonCopyableMaybe<PrivateKeyEncodingConfig>
|
|
602
|
-
ManagedEVPPKey::GetPrivateKeyEncodingFromJs(jsi::Runtime& runtime,
|
|
603
|
-
const jsi::Value* arguments,
|
|
604
|
-
unsigned int* offset,
|
|
605
|
-
KeyEncodingContext context) {
|
|
606
|
-
PrivateKeyEncodingConfig result;
|
|
607
|
-
GetKeyFormatAndTypeFromJs(&result, runtime, arguments, offset, context);
|
|
608
|
-
|
|
609
|
-
if (result.output_key_object_) {
|
|
610
|
-
if (context != kKeyContextInput) (*offset)++;
|
|
611
|
-
} else {
|
|
612
|
-
bool needs_passphrase = false;
|
|
613
|
-
if (context != kKeyContextInput) {
|
|
614
|
-
if (arguments[*offset].isString()) {
|
|
615
|
-
auto cipher_name = arguments[*offset].getString(runtime).utf8(runtime);
|
|
616
|
-
result.cipher_ = EVP_get_cipherbyname(cipher_name.c_str());
|
|
617
|
-
if (result.cipher_ == nullptr) {
|
|
618
|
-
throw jsi::JSError(runtime, "Unknown cipher");
|
|
619
|
-
}
|
|
620
|
-
needs_passphrase = true;
|
|
621
|
-
} else {
|
|
622
|
-
// CHECK(args[*offset]->IsNullOrUndefined());
|
|
623
|
-
result.cipher_ = nullptr;
|
|
624
|
-
}
|
|
625
|
-
(*offset)++;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
if (CheckIsArrayBuffer(runtime, arguments[*offset])) {
|
|
629
|
-
// CHECK_IMPLIES(context != kKeyContextInput, result.cipher_ !=
|
|
630
|
-
// nullptr); ArrayBufferOrViewContents<char>
|
|
631
|
-
// passphrase(arguments[*offset]);
|
|
632
|
-
jsi::ArrayBuffer passphrase =
|
|
633
|
-
arguments[*offset].asObject(runtime).getArrayBuffer(runtime);
|
|
634
|
-
if (!CheckSizeInt32(runtime, passphrase)) {
|
|
635
|
-
throw jsi::JSError(runtime, "passphrase is too long");
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
result.passphrase_ = NonCopyableMaybe<ByteSource>(
|
|
639
|
-
ToNullTerminatedByteSource(runtime, passphrase));
|
|
640
|
-
} else {
|
|
641
|
-
if (needs_passphrase &&
|
|
642
|
-
(arguments[*offset].isNull() || arguments[*offset].isUndefined())) {
|
|
643
|
-
throw jsi::JSError(
|
|
644
|
-
runtime, "passphrase is null or undefined but it is required");
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
(*offset)++;
|
|
650
|
-
return NonCopyableMaybe<PrivateKeyEncodingConfig>(std::move(result));
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
PublicKeyEncodingConfig ManagedEVPPKey::GetPublicKeyEncodingFromJs(
|
|
654
|
-
jsi::Runtime& runtime, const jsi::Value* arguments, unsigned int* offset,
|
|
655
|
-
KeyEncodingContext context) {
|
|
656
|
-
PublicKeyEncodingConfig result;
|
|
657
|
-
GetKeyFormatAndTypeFromJs(&result, runtime, arguments, offset, context);
|
|
658
|
-
return result;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
ManagedEVPPKey ManagedEVPPKey::GetPrivateKeyFromJs(jsi::Runtime& runtime,
|
|
662
|
-
const jsi::Value* args,
|
|
663
|
-
unsigned int* offset,
|
|
664
|
-
bool allow_key_object) {
|
|
665
|
-
if (args[*offset].isString() ||
|
|
666
|
-
args[*offset].asObject(runtime).isArrayBuffer(runtime)) {
|
|
667
|
-
ByteSource key = ByteSource::FromStringOrBuffer(runtime, args[*offset]);
|
|
668
|
-
(*offset)++;
|
|
669
|
-
NonCopyableMaybe<PrivateKeyEncodingConfig> config =
|
|
670
|
-
GetPrivateKeyEncodingFromJs(runtime, args, offset, kKeyContextInput);
|
|
671
|
-
if (config.IsEmpty()) return ManagedEVPPKey();
|
|
672
|
-
|
|
673
|
-
EVPKeyPointer pkey;
|
|
674
|
-
ParseKeyResult ret =
|
|
675
|
-
ParsePrivateKey(&pkey, config.Release(), key.data<char>(), key.size());
|
|
676
|
-
return GetParsedKey(runtime, std::move(pkey), ret,
|
|
677
|
-
"Failed to read private key");
|
|
678
|
-
} else {
|
|
679
|
-
if( !(args[*offset].isObject() && allow_key_object)) {
|
|
680
|
-
throw jsi::JSError(runtime,
|
|
681
|
-
"ManagedEVPPKey::GetPrivateKeyFromJs: First argument "
|
|
682
|
-
"must be object (CryptoKey) and caller must pass "
|
|
683
|
-
"allow_key_object as true");
|
|
684
|
-
}
|
|
685
|
-
std::shared_ptr<KeyObjectHandle> handle =
|
|
686
|
-
std::static_pointer_cast<KeyObjectHandle>(
|
|
687
|
-
args[*offset].asObject(runtime).getHostObject(runtime));
|
|
688
|
-
CHECK_EQ(handle->Data()->GetKeyType(), kKeyTypePrivate);
|
|
689
|
-
(*offset) += 4;
|
|
690
|
-
return handle->Data()->GetAsymmetricKey();
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
ManagedEVPPKey ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(
|
|
695
|
-
jsi::Runtime& runtime,
|
|
696
|
-
const jsi::Value* args,
|
|
697
|
-
unsigned int* offset) {
|
|
698
|
-
if (args[*offset].asObject(runtime).isArrayBuffer(runtime)) {
|
|
699
|
-
// data (key) as ArrayBuffer
|
|
700
|
-
auto dataArrayBuffer =
|
|
701
|
-
args[(*offset)++].asObject(runtime).getArrayBuffer(runtime);
|
|
702
|
-
|
|
703
|
-
if (!CheckSizeInt32(runtime, dataArrayBuffer)) {
|
|
704
|
-
throw jsi::JSError(runtime, "data is too big");
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
// rest of args for encoding
|
|
708
|
-
NonCopyableMaybe<PrivateKeyEncodingConfig> config_ =
|
|
709
|
-
GetPrivateKeyEncodingFromJs(runtime, args, offset, kKeyContextInput);
|
|
710
|
-
if (config_.IsEmpty()) return ManagedEVPPKey();
|
|
711
|
-
|
|
712
|
-
ParseKeyResult ret;
|
|
713
|
-
PrivateKeyEncodingConfig config = config_.Release();
|
|
714
|
-
EVPKeyPointer pkey;
|
|
715
|
-
if (config.format_ == kKeyFormatPEM) {
|
|
716
|
-
// For PEM, we can easily determine whether it is a public or private
|
|
717
|
-
// key by looking for the respective PEM tags.
|
|
718
|
-
ret = ParsePublicKeyPEM(&pkey, (const char*)dataArrayBuffer.data(runtime),
|
|
719
|
-
(int)dataArrayBuffer.size(runtime));
|
|
720
|
-
if (ret == ParseKeyResult::kParseKeyNotRecognized) {
|
|
721
|
-
ret = ParsePrivateKey(&pkey, config,
|
|
722
|
-
(const char*)dataArrayBuffer.data(runtime),
|
|
723
|
-
(int)dataArrayBuffer.size(runtime));
|
|
724
|
-
}
|
|
725
|
-
} else {
|
|
726
|
-
// For DER, the type determines how to parse it. SPKI, PKCS#8 and SEC1
|
|
727
|
-
// are easy, but PKCS#1 can be a public key or a private key.
|
|
728
|
-
bool is_public;
|
|
729
|
-
switch (config.type_.value()) {
|
|
730
|
-
case kKeyEncodingPKCS1:
|
|
731
|
-
is_public = !IsRSAPrivateKey(reinterpret_cast<const unsigned char*>(
|
|
732
|
-
dataArrayBuffer.data(runtime)),
|
|
733
|
-
dataArrayBuffer.size(runtime));
|
|
734
|
-
break;
|
|
735
|
-
case kKeyEncodingSPKI:
|
|
736
|
-
is_public = true;
|
|
737
|
-
break;
|
|
738
|
-
case kKeyEncodingPKCS8:
|
|
739
|
-
case kKeyEncodingSEC1:
|
|
740
|
-
is_public = false;
|
|
741
|
-
break;
|
|
742
|
-
default:
|
|
743
|
-
throw jsi::JSError(runtime, "Invalid key encoding type");
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
if (is_public) {
|
|
747
|
-
ret = ParsePublicKey(&pkey, config,
|
|
748
|
-
(const char*)dataArrayBuffer.data(runtime),
|
|
749
|
-
dataArrayBuffer.size(runtime));
|
|
750
|
-
} else {
|
|
751
|
-
ret = ParsePrivateKey(&pkey, config,
|
|
752
|
-
(const char*)dataArrayBuffer.data(runtime),
|
|
753
|
-
dataArrayBuffer.size(runtime));
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
return ManagedEVPPKey::GetParsedKey(runtime, std::move(pkey), ret,
|
|
758
|
-
"Failed to read asymmetric key");
|
|
759
|
-
} else {
|
|
760
|
-
if( !(args[*offset].isObject()) ) {
|
|
761
|
-
throw jsi::JSError(runtime,
|
|
762
|
-
"ManagedEVPPKey::GetPublicOrPrivateKeyFromJs: First "
|
|
763
|
-
"argument not ArrayBuffer or object (CryptoKey)");
|
|
764
|
-
}
|
|
765
|
-
std::shared_ptr<KeyObjectHandle> handle =
|
|
766
|
-
std::static_pointer_cast<KeyObjectHandle>(
|
|
767
|
-
args[*offset].asObject(runtime).getHostObject(runtime));
|
|
768
|
-
// note: below check is kKeyTypeSecret in Node.js
|
|
769
|
-
// but kKeyTypePublic in RNQC when testing verify() on ECDSA
|
|
770
|
-
CHECK_EQ(handle->Data()->GetKeyType(), kKeyTypePublic);
|
|
771
|
-
(*offset) += 4;
|
|
772
|
-
return handle->Data()->GetAsymmetricKey();
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
ManagedEVPPKey ManagedEVPPKey::GetParsedKey(jsi::Runtime& runtime,
|
|
777
|
-
EVPKeyPointer&& pkey,
|
|
778
|
-
ParseKeyResult ret,
|
|
779
|
-
const char* default_msg) {
|
|
780
|
-
switch (ret) {
|
|
781
|
-
case ParseKeyResult::kParseKeyOk:
|
|
782
|
-
// CHECK(pkey);
|
|
783
|
-
break;
|
|
784
|
-
case ParseKeyResult::kParseKeyNeedPassphrase:
|
|
785
|
-
throw jsi::JSError(runtime, "Passphrase required for encrypted key");
|
|
786
|
-
break;
|
|
787
|
-
default:
|
|
788
|
-
throw jsi::JSError(runtime, default_msg);
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
return ManagedEVPPKey(std::move(pkey));
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
KeyObjectData::KeyObjectData(ByteSource symmetric_key)
|
|
795
|
-
: key_type_(KeyType::kKeyTypeSecret),
|
|
796
|
-
symmetric_key_(std::move(symmetric_key)),
|
|
797
|
-
symmetric_key_len_(symmetric_key_.size()),
|
|
798
|
-
asymmetric_key_() {}
|
|
799
|
-
|
|
800
|
-
KeyObjectData::KeyObjectData(KeyType type,
|
|
801
|
-
const ManagedEVPPKey& pkey)
|
|
802
|
-
: key_type_(type),
|
|
803
|
-
symmetric_key_(),
|
|
804
|
-
symmetric_key_len_(0),
|
|
805
|
-
asymmetric_key_{pkey} {}
|
|
806
|
-
|
|
807
|
-
std::shared_ptr<KeyObjectData> KeyObjectData::CreateSecret(ByteSource key)
|
|
808
|
-
{
|
|
809
|
-
CHECK(key);
|
|
810
|
-
return std::shared_ptr<KeyObjectData>(new KeyObjectData(std::move(key)));
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
std::shared_ptr<KeyObjectData> KeyObjectData::CreateAsymmetric(
|
|
814
|
-
KeyType key_type,
|
|
815
|
-
const ManagedEVPPKey& pkey
|
|
816
|
-
) {
|
|
817
|
-
CHECK(pkey);
|
|
818
|
-
return std::shared_ptr<KeyObjectData>(new KeyObjectData(key_type, pkey));
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
KeyType KeyObjectData::GetKeyType() const {
|
|
822
|
-
return key_type_;
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
ManagedEVPPKey KeyObjectData::GetAsymmetricKey() const {
|
|
826
|
-
CHECK_NE(key_type_, kKeyTypeSecret);
|
|
827
|
-
return asymmetric_key_;
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
/** Gets the symmetric key value
|
|
831
|
-
* binary data stored in string, tolerates \0 characters
|
|
832
|
-
*/
|
|
833
|
-
std::string KeyObjectData::GetSymmetricKey() const {
|
|
834
|
-
CHECK_EQ(key_type_, kKeyTypeSecret);
|
|
835
|
-
return symmetric_key_.ToString();
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
size_t KeyObjectData::GetSymmetricKeySize() const {
|
|
839
|
-
CHECK_EQ(key_type_, kKeyTypeSecret);
|
|
840
|
-
return symmetric_key_len_;
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
jsi::Value KeyObjectHandle::get(
|
|
845
|
-
jsi::Runtime &rt,
|
|
846
|
-
const jsi::PropNameID &propNameID) {
|
|
847
|
-
auto name = propNameID.utf8(rt);
|
|
848
|
-
|
|
849
|
-
if (name == "export") {
|
|
850
|
-
return this->Export(rt);
|
|
851
|
-
} else if (name == "exportJwk") {
|
|
852
|
-
return this->ExportJWK(rt);
|
|
853
|
-
} else if (name == "initECRaw") {
|
|
854
|
-
return this-> InitECRaw(rt);
|
|
855
|
-
} else if (name == "init") {
|
|
856
|
-
return this->Init(rt);
|
|
857
|
-
} else if (name == "initJwk") {
|
|
858
|
-
return this->InitJWK(rt);
|
|
859
|
-
} else if (name == "keyDetail") {
|
|
860
|
-
return this->GetKeyDetail(rt);
|
|
861
|
-
} else if (name == "getAsymmetricKeyType") {
|
|
862
|
-
return this->GetAsymmetricKeyType(rt);
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
return {};
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
// v8::Local<v8::Function> KeyObjectHandle::Initialize(Environment* env) {
|
|
869
|
-
// Local<Function> templ = env->crypto_key_object_handle_constructor();
|
|
870
|
-
// if (!templ.IsEmpty()) {
|
|
871
|
-
// return templ;
|
|
872
|
-
// }
|
|
873
|
-
// Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
|
|
874
|
-
// t->InstanceTemplate()->SetInternalFieldCount(
|
|
875
|
-
// KeyObjectHandle::kInternalFieldCount);
|
|
876
|
-
// t->Inherit(BaseObject::GetConstructorTemplate(env));
|
|
877
|
-
//
|
|
878
|
-
// env->SetProtoMethod(t, "init", Init);
|
|
879
|
-
// env->SetProtoMethodNoSideEffect(t, "getSymmetricKeySize",
|
|
880
|
-
// GetSymmetricKeySize);
|
|
881
|
-
// env->SetProtoMethodNoSideEffect(t, "getAsymmetricKeyType",
|
|
882
|
-
// GetAsymmetricKeyType);
|
|
883
|
-
// env->SetProtoMethod(t, "export", Export);
|
|
884
|
-
// env->SetProtoMethod(t, "exportJwk", ExportJWK);
|
|
885
|
-
// env->SetProtoMethod(t, "initECRaw", InitECRaw);
|
|
886
|
-
// env->SetProtoMethod(t, "initEDRaw", InitEDRaw);
|
|
887
|
-
// env->SetProtoMethod(t, "initJwk", InitJWK);
|
|
888
|
-
// env->SetProtoMethod(t, "keyDetail", GetKeyDetail);
|
|
889
|
-
// env->SetProtoMethod(t, "equals", Equals);
|
|
890
|
-
//
|
|
891
|
-
// auto function = t->GetFunction(env->context()).ToLocalChecked();
|
|
892
|
-
// env->set_crypto_key_object_handle_constructor(function);
|
|
893
|
-
// return function;
|
|
894
|
-
// }
|
|
895
|
-
//
|
|
896
|
-
// void KeyObjectHandle::RegisterExternalReferences(
|
|
897
|
-
// ExternalReferenceRegistry*
|
|
898
|
-
// registry) {
|
|
899
|
-
// registry->Register(New);
|
|
900
|
-
// registry->Register(Init);
|
|
901
|
-
// registry->Register(GetSymmetricKeySize);
|
|
902
|
-
// registry->Register(GetAsymmetricKeyType);
|
|
903
|
-
// registry->Register(Export);
|
|
904
|
-
// registry->Register(ExportJWK);
|
|
905
|
-
// registry->Register(InitECRaw);
|
|
906
|
-
// registry->Register(InitEDRaw);
|
|
907
|
-
// registry->Register(InitJWK);
|
|
908
|
-
// registry->Register(GetKeyDetail);
|
|
909
|
-
// registry->Register(Equals);
|
|
910
|
-
// }
|
|
911
|
-
|
|
912
|
-
std::shared_ptr<KeyObjectHandle> KeyObjectHandle::Create(std::shared_ptr<KeyObjectData> data) {
|
|
913
|
-
auto handle = std::make_shared<KeyObjectHandle>();
|
|
914
|
-
handle->data_ = data;
|
|
915
|
-
return handle;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
const std::shared_ptr<KeyObjectData>& KeyObjectHandle::Data() {
|
|
919
|
-
return this->data_;
|
|
920
|
-
}
|
|
921
|
-
//
|
|
922
|
-
// void KeyObjectHandle::New(const FunctionCallbackInfo<Value>& args) {
|
|
923
|
-
// CHECK(args.IsConstructCall());
|
|
924
|
-
// Environment* env = Environment::GetCurrent(args);
|
|
925
|
-
// new KeyObjectHandle(env, args.This());
|
|
926
|
-
// }
|
|
927
|
-
//
|
|
928
|
-
// KeyObjectHandle::KeyObjectHandle(Environment* env,
|
|
929
|
-
// Local<Object> wrap)
|
|
930
|
-
//: BaseObject(env, wrap) {
|
|
931
|
-
// MakeWeak();
|
|
932
|
-
//}
|
|
933
|
-
//
|
|
934
|
-
|
|
935
|
-
jsi::Value KeyObjectHandle::Init(jsi::Runtime &rt) {
|
|
936
|
-
return HOSTFN("init", 5) {
|
|
937
|
-
CHECK(args[0].isNumber());
|
|
938
|
-
KeyType type = static_cast<KeyType>((int32_t)args[0].asNumber());
|
|
939
|
-
|
|
940
|
-
unsigned int offset;
|
|
941
|
-
ManagedEVPPKey pkey;
|
|
942
|
-
|
|
943
|
-
switch (type) {
|
|
944
|
-
case kKeyTypeSecret: {
|
|
945
|
-
CHECK_EQ(count, 2);
|
|
946
|
-
ByteSource key = ByteSource::FromStringOrBuffer(rt, args[1]);
|
|
947
|
-
this->data_ = KeyObjectData::CreateSecret(std::move(key));
|
|
948
|
-
break;
|
|
949
|
-
}
|
|
950
|
-
case kKeyTypePublic: {
|
|
951
|
-
CHECK_EQ(count, 5);
|
|
952
|
-
offset = 1;
|
|
953
|
-
pkey = ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(rt, args, &offset);
|
|
954
|
-
if (!pkey)
|
|
955
|
-
return false;
|
|
956
|
-
this->data_ = KeyObjectData::CreateAsymmetric(type, pkey);
|
|
957
|
-
break;
|
|
958
|
-
}
|
|
959
|
-
case kKeyTypePrivate: {
|
|
960
|
-
CHECK_EQ(count, 5);
|
|
961
|
-
offset = 1;
|
|
962
|
-
pkey = ManagedEVPPKey::GetPrivateKeyFromJs(rt, args, &offset, false);
|
|
963
|
-
if (!pkey)
|
|
964
|
-
return false;
|
|
965
|
-
this->data_ = KeyObjectData::CreateAsymmetric(type, pkey);
|
|
966
|
-
break;
|
|
967
|
-
}
|
|
968
|
-
default:
|
|
969
|
-
throw jsi::JSError(rt, "invalid keytype for init(): " + std::to_string(type));
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
return true;
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
jsi::Value KeyObjectHandle::InitJWK(jsi::Runtime &rt) {
|
|
977
|
-
return HOSTFN("initJwk", 2) {
|
|
978
|
-
// The argument must be a JavaScript object that we will inspect
|
|
979
|
-
// to get the JWK properties from.
|
|
980
|
-
jsi::Object jwk = jsi::Object(jsi::Value(rt, args[0]).asObject(rt));
|
|
981
|
-
jsi::Value namedCurve;
|
|
982
|
-
if (count == 2)
|
|
983
|
-
namedCurve = jsi::Value(rt, args[1]);
|
|
984
|
-
|
|
985
|
-
// Step one, Secret key or not?
|
|
986
|
-
std::string kty = jwk
|
|
987
|
-
.getProperty(rt, "kty")
|
|
988
|
-
.asString(rt)
|
|
989
|
-
.utf8(rt);
|
|
990
|
-
|
|
991
|
-
if (kty.compare("oct") == 0) {
|
|
992
|
-
// Secret key
|
|
993
|
-
this->data_ = ImportJWKSecretKey(rt, jwk);
|
|
994
|
-
if (!this->data_) {
|
|
995
|
-
// ImportJWKSecretKey is responsible for throwing an appropriate error
|
|
996
|
-
return jsi::Value::undefined();
|
|
997
|
-
}
|
|
998
|
-
} else {
|
|
999
|
-
this->data_ = ImportJWKAsymmetricKey(rt, jwk, kty, namedCurve);
|
|
1000
|
-
if (!this->data_) {
|
|
1001
|
-
// ImportJWKAsymmetricKey is responsible for throwing an appropriate
|
|
1002
|
-
// error
|
|
1003
|
-
return jsi::Value::undefined();
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
return static_cast<int>(this->data_->GetKeyType());
|
|
1008
|
-
});
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
jsi::Value KeyObjectHandle::InitECRaw(jsi::Runtime &rt) {
|
|
1012
|
-
return HOSTFN("initECRaw", 2) {
|
|
1013
|
-
CHECK(args[0].isString());
|
|
1014
|
-
std::string curveName = args[0].asString(rt).utf8(rt);
|
|
1015
|
-
int id = OBJ_txt2nid(curveName.c_str());
|
|
1016
|
-
ECKeyPointer eckey(EC_KEY_new_by_curve_name(id));
|
|
1017
|
-
if (!eckey) {
|
|
1018
|
-
return false;
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
|
-
CHECK(args[1].isObject());
|
|
1022
|
-
if (!args[1].getObject(rt).isArrayBuffer(rt)) {
|
|
1023
|
-
throw jsi::JSError(rt,
|
|
1024
|
-
"KeyObjectHandle::InitECRaw: second argument "
|
|
1025
|
-
"has to be of type ArrayBuffer!");
|
|
1026
|
-
}
|
|
1027
|
-
auto buf = args[1].asObject(rt).getArrayBuffer(rt);
|
|
1028
|
-
|
|
1029
|
-
const EC_GROUP* group = EC_KEY_get0_group(eckey.get());
|
|
1030
|
-
ECPointPointer pub(ECDH::BufferToPoint(rt, group, buf));
|
|
1031
|
-
|
|
1032
|
-
if (!pub ||
|
|
1033
|
-
!eckey ||
|
|
1034
|
-
!EC_KEY_set_public_key(eckey.get(), pub.get())) {
|
|
1035
|
-
return false;
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
EVPKeyPointer pkey(EVP_PKEY_new());
|
|
1039
|
-
if (!EVP_PKEY_assign_EC_KEY(pkey.get(), eckey.get())) {
|
|
1040
|
-
return false;
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
eckey.release(); // Release ownership of the key
|
|
1044
|
-
|
|
1045
|
-
this->data_ =
|
|
1046
|
-
KeyObjectData::CreateAsymmetric(
|
|
1047
|
-
kKeyTypePublic,
|
|
1048
|
-
ManagedEVPPKey(std::move(pkey)));
|
|
1049
|
-
|
|
1050
|
-
return true;
|
|
1051
|
-
});
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
// void KeyObjectHandle::InitEDRaw(const FunctionCallbackInfo<Value>& args) {
|
|
1055
|
-
// Environment* env = Environment::GetCurrent(args);
|
|
1056
|
-
// KeyObjectHandle* key;
|
|
1057
|
-
// ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
|
|
1058
|
-
//
|
|
1059
|
-
// CHECK(args[0]->IsString());
|
|
1060
|
-
// Utf8Value name(env->isolate(), args[0]);
|
|
1061
|
-
//
|
|
1062
|
-
// ArrayBufferOrViewContents<unsigned char> key_data(args[1]);
|
|
1063
|
-
// KeyType type = static_cast<KeyType>(args[2].As<Int32>()->Value());
|
|
1064
|
-
//
|
|
1065
|
-
// MarkPopErrorOnReturn mark_pop_error_on_return;
|
|
1066
|
-
//
|
|
1067
|
-
// typedef EVP_PKEY* (*new_key_fn)(int, ENGINE*, const unsigned char*,
|
|
1068
|
-
// size_t); new_key_fn fn = type == kKeyTypePrivate ?
|
|
1069
|
-
// EVP_PKEY_new_raw_private_key : EVP_PKEY_new_raw_public_key;
|
|
1070
|
-
//
|
|
1071
|
-
// int id = GetOKPCurveFromName(*name);
|
|
1072
|
-
//
|
|
1073
|
-
// switch (id) {
|
|
1074
|
-
// case EVP_PKEY_X25519:
|
|
1075
|
-
// case EVP_PKEY_X448:
|
|
1076
|
-
// case EVP_PKEY_ED25519:
|
|
1077
|
-
// case EVP_PKEY_ED448: {
|
|
1078
|
-
// EVPKeyPointer pkey(fn(id, nullptr, key_data.data(), key_data.size()));
|
|
1079
|
-
// if (!pkey)
|
|
1080
|
-
// return args.GetReturnValue().Set(false);
|
|
1081
|
-
// key->data_ =
|
|
1082
|
-
// KeyObjectData::CreateAsymmetric(
|
|
1083
|
-
// type,
|
|
1084
|
-
// ManagedEVPPKey(std::move(pkey)));
|
|
1085
|
-
// CHECK(key->data_);
|
|
1086
|
-
// break;
|
|
1087
|
-
// }
|
|
1088
|
-
// default:
|
|
1089
|
-
// throw jsi::JSError(rt, "unreachable code in InitEDRaw");
|
|
1090
|
-
// }
|
|
1091
|
-
//
|
|
1092
|
-
// args.GetReturnValue().Set(true);
|
|
1093
|
-
//}
|
|
1094
|
-
//
|
|
1095
|
-
// void KeyObjectHandle::Equals(const FunctionCallbackInfo<Value>& args) {
|
|
1096
|
-
// KeyObjectHandle* self_handle;
|
|
1097
|
-
// KeyObjectHandle* arg_handle;
|
|
1098
|
-
// ASSIGN_OR_RETURN_UNWRAP(&self_handle, args.Holder());
|
|
1099
|
-
// ASSIGN_OR_RETURN_UNWRAP(&arg_handle, args[0].As<Object>());
|
|
1100
|
-
// std::shared_ptr<KeyObjectData> key = self_handle->Data();
|
|
1101
|
-
// std::shared_ptr<KeyObjectData> key2 = arg_handle->Data();
|
|
1102
|
-
//
|
|
1103
|
-
// KeyType key_type = key->GetKeyType();
|
|
1104
|
-
// CHECK_EQ(key_type, key2->GetKeyType());
|
|
1105
|
-
//
|
|
1106
|
-
// bool ret;
|
|
1107
|
-
// switch (key_type) {
|
|
1108
|
-
// case kKeyTypeSecret: {
|
|
1109
|
-
// size_t size = key->GetSymmetricKeySize();
|
|
1110
|
-
// if (size == key2->GetSymmetricKeySize()) {
|
|
1111
|
-
// ret = CRYPTO_memcmp(
|
|
1112
|
-
// key->GetSymmetricKey(),
|
|
1113
|
-
// key2->GetSymmetricKey(),
|
|
1114
|
-
// size) == 0;
|
|
1115
|
-
// } else {
|
|
1116
|
-
// ret = false;
|
|
1117
|
-
// }
|
|
1118
|
-
// break;
|
|
1119
|
-
// }
|
|
1120
|
-
// case kKeyTypePublic:
|
|
1121
|
-
// case kKeyTypePrivate: {
|
|
1122
|
-
// EVP_PKEY* pkey = key->GetAsymmetricKey().get();
|
|
1123
|
-
// EVP_PKEY* pkey2 = key2->GetAsymmetricKey().get();
|
|
1124
|
-
//#if OPENSSL_VERSION_MAJOR >= 3
|
|
1125
|
-
// int ok = EVP_PKEY_eq(pkey, pkey2);
|
|
1126
|
-
//#else
|
|
1127
|
-
// int ok = EVP_PKEY_cmp(pkey, pkey2);
|
|
1128
|
-
//#endif
|
|
1129
|
-
// if (ok == -2) {
|
|
1130
|
-
// Environment* env = Environment::GetCurrent(args);
|
|
1131
|
-
// return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env);
|
|
1132
|
-
// }
|
|
1133
|
-
// ret = ok == 1;
|
|
1134
|
-
// break;
|
|
1135
|
-
// }
|
|
1136
|
-
// default:
|
|
1137
|
-
// throw jsi::JSError(rt, "unreachable code in Equals");
|
|
1138
|
-
// }
|
|
1139
|
-
//
|
|
1140
|
-
// args.GetReturnValue().Set(ret);
|
|
1141
|
-
//}
|
|
1142
|
-
|
|
1143
|
-
jsi::Value KeyObjectHandle::GetKeyDetail(jsi::Runtime &rt) {
|
|
1144
|
-
return HOSTFN("keyDetail", 0) {
|
|
1145
|
-
std::shared_ptr<KeyObjectData> data = this->Data();
|
|
1146
|
-
|
|
1147
|
-
switch (data->GetKeyType()) {
|
|
1148
|
-
case kKeyTypeSecret:
|
|
1149
|
-
return GetSecretKeyDetail(rt, data);
|
|
1150
|
-
break;
|
|
1151
|
-
case kKeyTypePublic:
|
|
1152
|
-
// Fall through
|
|
1153
|
-
case kKeyTypePrivate:
|
|
1154
|
-
return GetAsymmetricKeyDetail(rt, data);
|
|
1155
|
-
break;
|
|
1156
|
-
default:
|
|
1157
|
-
throw jsi::JSError(rt, "unreachable code in GetKeyDetail");
|
|
1158
|
-
}
|
|
1159
|
-
});
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
jsi::Value KeyObjectHandle::GetAsymmetricKeyType(jsi::Runtime &rt) const {
|
|
1163
|
-
return HOSTFN("getAsymmetricKeyType", 0) {
|
|
1164
|
-
const ManagedEVPPKey& key = this->data_->GetAsymmetricKey();
|
|
1165
|
-
std::string ret;
|
|
1166
|
-
switch (EVP_PKEY_id(key.get())) {
|
|
1167
|
-
case EVP_PKEY_RSA:
|
|
1168
|
-
ret = "rsa";
|
|
1169
|
-
break;
|
|
1170
|
-
case EVP_PKEY_RSA_PSS:
|
|
1171
|
-
ret = "rsa_pss";
|
|
1172
|
-
break;
|
|
1173
|
-
case EVP_PKEY_DSA:
|
|
1174
|
-
ret = "dsa";
|
|
1175
|
-
break;
|
|
1176
|
-
case EVP_PKEY_DH:
|
|
1177
|
-
ret = "dh";
|
|
1178
|
-
break;
|
|
1179
|
-
case EVP_PKEY_EC:
|
|
1180
|
-
ret = "ec";
|
|
1181
|
-
break;
|
|
1182
|
-
case EVP_PKEY_ED25519:
|
|
1183
|
-
ret = "ed25519";
|
|
1184
|
-
break;
|
|
1185
|
-
case EVP_PKEY_ED448:
|
|
1186
|
-
ret = "ed448";
|
|
1187
|
-
break;
|
|
1188
|
-
case EVP_PKEY_X25519:
|
|
1189
|
-
ret = "x25519";
|
|
1190
|
-
break;
|
|
1191
|
-
case EVP_PKEY_X448:
|
|
1192
|
-
ret = "x448";
|
|
1193
|
-
break;
|
|
1194
|
-
default:
|
|
1195
|
-
throw jsi::JSError(rt, "unknown KeyType in GetAsymmetricKeyType");
|
|
1196
|
-
}
|
|
1197
|
-
return jsi::String::createFromUtf8(rt, ret);
|
|
1198
|
-
});
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
//
|
|
1202
|
-
// void KeyObjectHandle::GetAsymmetricKeyType(
|
|
1203
|
-
// const
|
|
1204
|
-
// FunctionCallbackInfo<Value>&
|
|
1205
|
-
// args) {
|
|
1206
|
-
// KeyObjectHandle* key;
|
|
1207
|
-
// ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
|
|
1208
|
-
//
|
|
1209
|
-
// args.GetReturnValue().Set(key->GetAsymmetricKeyType());
|
|
1210
|
-
//}
|
|
1211
|
-
//
|
|
1212
|
-
// void KeyObjectHandle::GetSymmetricKeySize(
|
|
1213
|
-
// const FunctionCallbackInfo<Value>&
|
|
1214
|
-
// args) {
|
|
1215
|
-
// KeyObjectHandle* key;
|
|
1216
|
-
// ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
|
|
1217
|
-
// args.GetReturnValue().Set(
|
|
1218
|
-
// static_cast<uint32_t>(key->Data()->GetSymmetricKeySize()));
|
|
1219
|
-
//}
|
|
1220
|
-
|
|
1221
|
-
jsi::Value KeyObjectHandle::Export(jsi::Runtime &rt) {
|
|
1222
|
-
return HOSTFN("export", 2) {
|
|
1223
|
-
KeyType type = this->data_->GetKeyType();
|
|
1224
|
-
jsi::Value result;
|
|
1225
|
-
if (type == kKeyTypeSecret) {
|
|
1226
|
-
result = this->ExportSecretKey(rt);
|
|
1227
|
-
}
|
|
1228
|
-
else if (type == kKeyTypePublic) {
|
|
1229
|
-
unsigned int offset = 0;
|
|
1230
|
-
PublicKeyEncodingConfig config =
|
|
1231
|
-
ManagedEVPPKey::GetPublicKeyEncodingFromJs(
|
|
1232
|
-
rt, args, &offset, kKeyContextExport);
|
|
1233
|
-
result = this->ExportPublicKey(rt, config);
|
|
1234
|
-
}
|
|
1235
|
-
else if (type == kKeyTypePrivate) {
|
|
1236
|
-
unsigned int offset = 0;
|
|
1237
|
-
NonCopyableMaybe<PrivateKeyEncodingConfig> config =
|
|
1238
|
-
ManagedEVPPKey::GetPrivateKeyEncodingFromJs(
|
|
1239
|
-
rt, args, &offset, kKeyContextExport);
|
|
1240
|
-
if (!config.IsEmpty()) {
|
|
1241
|
-
result = this->ExportPrivateKey(rt, config.Release());
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
return result;
|
|
1245
|
-
});
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
jsi::Value KeyObjectHandle::ExportSecretKey(jsi::Runtime &rt) const {
|
|
1249
|
-
std::string ret = data_->GetSymmetricKey();
|
|
1250
|
-
return toJSI(rt, ByteSource::FromString(ret));
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
jsi::Value KeyObjectHandle::ExportPublicKey(
|
|
1254
|
-
jsi::Runtime& rt,
|
|
1255
|
-
const PublicKeyEncodingConfig& config) const {
|
|
1256
|
-
return WritePublicKey(rt,
|
|
1257
|
-
data_->GetAsymmetricKey().get(),
|
|
1258
|
-
config);
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
|
-
jsi::Value KeyObjectHandle::ExportPrivateKey(
|
|
1262
|
-
jsi::Runtime &rt,
|
|
1263
|
-
const PrivateKeyEncodingConfig& config) const {
|
|
1264
|
-
return WritePrivateKey(rt,
|
|
1265
|
-
data_->GetAsymmetricKey().get(),
|
|
1266
|
-
config);
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
jsi::Value KeyObjectHandle::ExportJWK(jsi::Runtime &rt) {
|
|
1270
|
-
return HOSTFN("exportJwk", 2) {
|
|
1271
|
-
CHECK(args[0].isObject());
|
|
1272
|
-
CHECK(args[1].isBool());
|
|
1273
|
-
std::shared_ptr<KeyObjectData> data = this->Data();
|
|
1274
|
-
jsi::Object result = args[0].asObject(rt);
|
|
1275
|
-
return ExportJWKInner(rt, data, result, args[1].asBool());
|
|
1276
|
-
});
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
|
-
// void NativeKeyObject::Initialize(Environment* env, Local<Object> target) {
|
|
1280
|
-
// env->SetMethod(target, "createNativeKeyObjectClass",
|
|
1281
|
-
// NativeKeyObject::CreateNativeKeyObjectClass);
|
|
1282
|
-
//}
|
|
1283
|
-
//
|
|
1284
|
-
// void NativeKeyObject::RegisterExternalReferences(
|
|
1285
|
-
// ExternalReferenceRegistry*
|
|
1286
|
-
// registry) {
|
|
1287
|
-
// registry->Register(NativeKeyObject::CreateNativeKeyObjectClass);
|
|
1288
|
-
// registry->Register(NativeKeyObject::New);
|
|
1289
|
-
//}
|
|
1290
|
-
//
|
|
1291
|
-
// void NativeKeyObject::New(const FunctionCallbackInfo<Value>& args) {
|
|
1292
|
-
// Environment* env = Environment::GetCurrent(args);
|
|
1293
|
-
// CHECK_EQ(args.Length(), 1);
|
|
1294
|
-
// CHECK(args[0]->IsObject());
|
|
1295
|
-
// KeyObjectHandle* handle = Unwrap<KeyObjectHandle>(args[0].As<Object>());
|
|
1296
|
-
// new NativeKeyObject(env, args.This(), handle->Data());
|
|
1297
|
-
//}
|
|
1298
|
-
//
|
|
1299
|
-
// void NativeKeyObject::CreateNativeKeyObjectClass(
|
|
1300
|
-
// const
|
|
1301
|
-
// FunctionCallbackInfo<Value>&
|
|
1302
|
-
// args) {
|
|
1303
|
-
// Environment* env = Environment::GetCurrent(args);
|
|
1304
|
-
//
|
|
1305
|
-
// CHECK_EQ(args.Length(), 1);
|
|
1306
|
-
// Local<Value> callback = args[0];
|
|
1307
|
-
// CHECK(callback->IsFunction());
|
|
1308
|
-
//
|
|
1309
|
-
// Local<FunctionTemplate> t =
|
|
1310
|
-
// env->NewFunctionTemplate(NativeKeyObject::New);
|
|
1311
|
-
// t->InstanceTemplate()->SetInternalFieldCount(
|
|
1312
|
-
// KeyObjectHandle::kInternalFieldCount);
|
|
1313
|
-
// t->Inherit(BaseObject::GetConstructorTemplate(env));
|
|
1314
|
-
//
|
|
1315
|
-
// Local<Value> ctor;
|
|
1316
|
-
// if (!t->GetFunction(env->context()).ToLocal(&ctor))
|
|
1317
|
-
// return;
|
|
1318
|
-
//
|
|
1319
|
-
// Local<Value> recv = Undefined(env->isolate());
|
|
1320
|
-
// Local<Value> ret_v;
|
|
1321
|
-
// if (!callback.As<Function>()->Call(
|
|
1322
|
-
// env->context(), recv, 1,
|
|
1323
|
-
// &ctor).ToLocal(&ret_v)) {
|
|
1324
|
-
// return;
|
|
1325
|
-
// }
|
|
1326
|
-
// Local<Array> ret = ret_v.As<Array>();
|
|
1327
|
-
// if (!ret->Get(env->context(), 1).ToLocal(&ctor)) return;
|
|
1328
|
-
// env->set_crypto_key_object_secret_constructor(ctor.As<Function>());
|
|
1329
|
-
// if (!ret->Get(env->context(), 2).ToLocal(&ctor)) return;
|
|
1330
|
-
// env->set_crypto_key_object_public_constructor(ctor.As<Function>());
|
|
1331
|
-
// if (!ret->Get(env->context(), 3).ToLocal(&ctor)) return;
|
|
1332
|
-
// env->set_crypto_key_object_private_constructor(ctor.As<Function>());
|
|
1333
|
-
// args.GetReturnValue().Set(ret);
|
|
1334
|
-
//}
|
|
1335
|
-
//
|
|
1336
|
-
// BaseObjectPtr<BaseObject>
|
|
1337
|
-
// NativeKeyObject::KeyObjectTransferData::Deserialize(
|
|
1338
|
-
// Environment* env,
|
|
1339
|
-
// Local<Context>
|
|
1340
|
-
// context,
|
|
1341
|
-
// std::unique_ptr<worker::TransferData>
|
|
1342
|
-
// self) {
|
|
1343
|
-
// if (context != env->context()) {
|
|
1344
|
-
// THROW_ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE(env);
|
|
1345
|
-
// return {};
|
|
1346
|
-
// }
|
|
1347
|
-
//
|
|
1348
|
-
// Local<Value> handle;
|
|
1349
|
-
// if (!KeyObjectHandle::Create(env, data_).ToLocal(&handle))
|
|
1350
|
-
// return {};
|
|
1351
|
-
//
|
|
1352
|
-
// Local<Function> key_ctor;
|
|
1353
|
-
// Local<Value> arg = FIXED_ONE_BYTE_STRING(env->isolate(),
|
|
1354
|
-
// "internal/crypto/keys");
|
|
1355
|
-
// if (env->native_module_require()->
|
|
1356
|
-
// Call(context, Null(env->isolate()), 1, &arg).IsEmpty()) {
|
|
1357
|
-
// return {};
|
|
1358
|
-
// }
|
|
1359
|
-
// switch (data_->GetKeyType()) {
|
|
1360
|
-
// case kKeyTypeSecret:
|
|
1361
|
-
// key_ctor = env->crypto_key_object_secret_constructor();
|
|
1362
|
-
// break;
|
|
1363
|
-
// case kKeyTypePublic:
|
|
1364
|
-
// key_ctor = env->crypto_key_object_public_constructor();
|
|
1365
|
-
// break;
|
|
1366
|
-
// case kKeyTypePrivate:
|
|
1367
|
-
// key_ctor = env->crypto_key_object_private_constructor();
|
|
1368
|
-
// break;
|
|
1369
|
-
// default:
|
|
1370
|
-
// CHECK(false);
|
|
1371
|
-
// }
|
|
1372
|
-
//
|
|
1373
|
-
// Local<Value> key;
|
|
1374
|
-
// if (!key_ctor->NewInstance(context, 1, &handle).ToLocal(&key))
|
|
1375
|
-
// return {};
|
|
1376
|
-
//
|
|
1377
|
-
// return
|
|
1378
|
-
// BaseObjectPtr<BaseObject>(Unwrap<KeyObjectHandle>(key.As<Object>()));
|
|
1379
|
-
//}
|
|
1380
|
-
//
|
|
1381
|
-
// BaseObject::TransferMode NativeKeyObject::GetTransferMode() const {
|
|
1382
|
-
// return BaseObject::TransferMode::kCloneable;
|
|
1383
|
-
//}
|
|
1384
|
-
//
|
|
1385
|
-
// std::unique_ptr<worker::TransferData> NativeKeyObject::CloneForMessaging()
|
|
1386
|
-
// const {
|
|
1387
|
-
// return std::make_unique<KeyObjectTransferData>(handle_data_);
|
|
1388
|
-
//}
|
|
1389
|
-
//
|
|
1390
|
-
WebCryptoKeyExportStatus PKEY_SPKI_Export(KeyObjectData* key_data,
|
|
1391
|
-
ByteSource* out) {
|
|
1392
|
-
CHECK_EQ(key_data->GetKeyType(), kKeyTypePublic);
|
|
1393
|
-
ManagedEVPPKey m_pkey = key_data->GetAsymmetricKey();
|
|
1394
|
-
// Mutex::ScopedLock lock(*m_pkey.mutex());
|
|
1395
|
-
BIOPointer bio(BIO_new(BIO_s_mem()));
|
|
1396
|
-
CHECK(bio);
|
|
1397
|
-
if (!i2d_PUBKEY_bio(bio.get(), m_pkey.get())) {
|
|
1398
|
-
throw std::runtime_error("Failed to export key");
|
|
1399
|
-
return WebCryptoKeyExportStatus::FAILED;
|
|
1400
|
-
}
|
|
1401
|
-
|
|
1402
|
-
*out = ByteSource::FromBIO(bio);
|
|
1403
|
-
return WebCryptoKeyExportStatus::OK;
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
|
-
WebCryptoKeyExportStatus PKEY_PKCS8_Export(
|
|
1407
|
-
KeyObjectData* key_data,
|
|
1408
|
-
ByteSource* out) {
|
|
1409
|
-
CHECK_EQ(key_data->GetKeyType(), kKeyTypePrivate);
|
|
1410
|
-
ManagedEVPPKey m_pkey = key_data->GetAsymmetricKey();
|
|
1411
|
-
// Mutex::ScopedLock lock(*m_pkey.mutex());
|
|
1412
|
-
BIOPointer bio(BIO_new(BIO_s_mem()));
|
|
1413
|
-
CHECK(bio);
|
|
1414
|
-
PKCS8Pointer p8inf(EVP_PKEY2PKCS8(m_pkey.get()));
|
|
1415
|
-
if (!i2d_PKCS8_PRIV_KEY_INFO_bio(bio.get(), p8inf.get()))
|
|
1416
|
-
return WebCryptoKeyExportStatus::FAILED;
|
|
1417
|
-
|
|
1418
|
-
*out = ByteSource::FromBIO(bio);
|
|
1419
|
-
return WebCryptoKeyExportStatus::OK;
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
// void RegisterExternalReferences(ExternalReferenceRegistry * registry) {
|
|
1423
|
-
// KeyObjectHandle::RegisterExternalReferences(registry);
|
|
1424
|
-
// }
|
|
1425
|
-
|
|
1426
|
-
} // namespace margelo
|