react-native-quick-crypto 0.6.1 → 0.7.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/README.md +70 -18
  2. package/android/CMakeLists.txt +58 -61
  3. package/android/build.gradle +105 -53
  4. package/android/gradle.properties +5 -5
  5. package/android/src/main/{AndroidManifest.xml → AndroidManifestNew.xml} +1 -2
  6. package/cpp/Cipher/MGLCipherHostObject.cpp +30 -6
  7. package/cpp/Cipher/MGLGenerateKeyPairInstaller.cpp +21 -31
  8. package/cpp/Cipher/MGLGenerateKeyPairSyncInstaller.cpp +4 -17
  9. package/cpp/Cipher/MGLPublicCipher.h +1 -1
  10. package/cpp/Cipher/MGLPublicCipherInstaller.h +6 -6
  11. package/cpp/Cipher/MGLRsa.cpp +224 -11
  12. package/cpp/Cipher/MGLRsa.h +13 -3
  13. package/cpp/Hash/MGLHashHostObject.cpp +1 -1
  14. package/cpp/Hash/MGLHashInstaller.cpp +2 -4
  15. package/cpp/JSIUtils/MGLJSIMacros.h +10 -0
  16. package/cpp/JSIUtils/MGLThreadAwareHostObject.h +1 -1
  17. package/cpp/MGLKeys.cpp +415 -471
  18. package/cpp/MGLKeys.h +70 -2
  19. package/cpp/MGLQuickCryptoHostObject.cpp +9 -0
  20. package/cpp/Random/MGLRandomHostObject.cpp +9 -2
  21. package/cpp/Sig/MGLSignHostObjects.cpp +1 -1
  22. package/cpp/Utils/MGLUtils.cpp +104 -32
  23. package/cpp/Utils/MGLUtils.h +172 -143
  24. package/cpp/Utils/node.h +13 -0
  25. package/cpp/webcrypto/MGLWebCrypto.cpp +63 -0
  26. package/cpp/webcrypto/MGLWebCrypto.h +34 -0
  27. package/cpp/webcrypto/crypto_ec.cpp +334 -0
  28. package/cpp/webcrypto/crypto_ec.h +65 -0
  29. package/ios/QuickCrypto.xcodeproj/project.pbxproj +4 -4
  30. package/ios/QuickCrypto.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  31. package/ios/QuickCrypto.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  32. package/ios/QuickCrypto.xcodeproj/project.xcworkspace/xcuserdata/brad.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  33. package/ios/QuickCrypto.xcodeproj/xcuserdata/brad.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  34. package/lib/commonjs/@types/crypto-browserify.d.js.map +1 -1
  35. package/lib/commonjs/Cipher.js +54 -195
  36. package/lib/commonjs/Cipher.js.map +1 -1
  37. package/lib/commonjs/Hash.js +29 -29
  38. package/lib/commonjs/Hash.js.map +1 -1
  39. package/lib/commonjs/Hashnames.js +75 -0
  40. package/lib/commonjs/Hashnames.js.map +1 -0
  41. package/lib/commonjs/Hmac.js +6 -29
  42. package/lib/commonjs/Hmac.js.map +1 -1
  43. package/lib/commonjs/NativeQuickCrypto/Cipher.js +3 -5
  44. package/lib/commonjs/NativeQuickCrypto/Cipher.js.map +1 -1
  45. package/lib/commonjs/NativeQuickCrypto/NativeQuickCrypto.js +11 -20
  46. package/lib/commonjs/NativeQuickCrypto/NativeQuickCrypto.js.map +1 -1
  47. package/lib/commonjs/NativeQuickCrypto/hash.js.map +1 -1
  48. package/lib/commonjs/NativeQuickCrypto/hmac.js.map +1 -1
  49. package/lib/commonjs/NativeQuickCrypto/pbkdf2.js.map +1 -1
  50. package/lib/commonjs/NativeQuickCrypto/random.js.map +1 -1
  51. package/lib/commonjs/NativeQuickCrypto/sig.js.map +1 -1
  52. package/lib/commonjs/NativeQuickCrypto/webcrypto.js +6 -0
  53. package/lib/commonjs/NativeQuickCrypto/webcrypto.js.map +1 -0
  54. package/lib/commonjs/QuickCrypto.js +9 -15
  55. package/lib/commonjs/QuickCrypto.js.map +1 -1
  56. package/lib/commonjs/Utils.js +374 -48
  57. package/lib/commonjs/Utils.js.map +1 -1
  58. package/lib/commonjs/aes.js +324 -0
  59. package/lib/commonjs/aes.js.map +1 -0
  60. package/lib/commonjs/constants.js +1 -2
  61. package/lib/commonjs/constants.js.map +1 -1
  62. package/lib/commonjs/ec.js +288 -0
  63. package/lib/commonjs/ec.js.map +1 -0
  64. package/lib/commonjs/index.js +3 -15
  65. package/lib/commonjs/index.js.map +1 -1
  66. package/lib/commonjs/keys.js +280 -48
  67. package/lib/commonjs/keys.js.map +1 -1
  68. package/lib/commonjs/pbkdf2.js +44 -18
  69. package/lib/commonjs/pbkdf2.js.map +1 -1
  70. package/lib/commonjs/random.js +49 -68
  71. package/lib/commonjs/random.js.map +1 -1
  72. package/lib/commonjs/rsa.js +329 -0
  73. package/lib/commonjs/rsa.js.map +1 -0
  74. package/lib/commonjs/sig.js +13 -54
  75. package/lib/commonjs/sig.js.map +1 -1
  76. package/lib/commonjs/subtle.js +271 -0
  77. package/lib/commonjs/subtle.js.map +1 -0
  78. package/lib/module/@types/crypto-browserify.d.js.map +1 -1
  79. package/lib/module/Cipher.js +54 -189
  80. package/lib/module/Cipher.js.map +1 -1
  81. package/lib/module/Hash.js +27 -21
  82. package/lib/module/Hash.js.map +1 -1
  83. package/lib/module/Hashnames.js +71 -0
  84. package/lib/module/Hashnames.js.map +1 -0
  85. package/lib/module/Hmac.js +4 -21
  86. package/lib/module/Hmac.js.map +1 -1
  87. package/lib/module/NativeQuickCrypto/Cipher.js +3 -4
  88. package/lib/module/NativeQuickCrypto/Cipher.js.map +1 -1
  89. package/lib/module/NativeQuickCrypto/NativeQuickCrypto.js +11 -17
  90. package/lib/module/NativeQuickCrypto/NativeQuickCrypto.js.map +1 -1
  91. package/lib/module/NativeQuickCrypto/hash.js.map +1 -1
  92. package/lib/module/NativeQuickCrypto/hmac.js.map +1 -1
  93. package/lib/module/NativeQuickCrypto/pbkdf2.js.map +1 -1
  94. package/lib/module/NativeQuickCrypto/random.js.map +1 -1
  95. package/lib/module/NativeQuickCrypto/sig.js.map +1 -1
  96. package/lib/module/NativeQuickCrypto/webcrypto.js +2 -0
  97. package/lib/module/NativeQuickCrypto/webcrypto.js.map +1 -0
  98. package/lib/module/QuickCrypto.js +6 -1
  99. package/lib/module/QuickCrypto.js.map +1 -1
  100. package/lib/module/Utils.js +327 -33
  101. package/lib/module/Utils.js.map +1 -1
  102. package/lib/module/aes.js +317 -0
  103. package/lib/module/aes.js.map +1 -0
  104. package/lib/module/constants.js.map +1 -1
  105. package/lib/module/ec.js +282 -0
  106. package/lib/module/ec.js.map +1 -0
  107. package/lib/module/index.js +4 -8
  108. package/lib/module/index.js.map +1 -1
  109. package/lib/module/keys.js +279 -43
  110. package/lib/module/keys.js.map +1 -1
  111. package/lib/module/pbkdf2.js +44 -13
  112. package/lib/module/pbkdf2.js.map +1 -1
  113. package/lib/module/random.js +46 -54
  114. package/lib/module/random.js.map +1 -1
  115. package/lib/module/rsa.js +323 -0
  116. package/lib/module/rsa.js.map +1 -0
  117. package/lib/module/sig.js +13 -46
  118. package/lib/module/sig.js.map +1 -1
  119. package/lib/module/subtle.js +265 -0
  120. package/lib/module/subtle.js.map +1 -0
  121. package/lib/typescript/src/Cipher.d.ts +72 -0
  122. package/lib/typescript/src/Cipher.d.ts.map +1 -0
  123. package/lib/typescript/{Hash.d.ts → src/Hash.d.ts} +8 -7
  124. package/lib/typescript/src/Hash.d.ts.map +1 -0
  125. package/lib/typescript/src/Hashnames.d.ts +11 -0
  126. package/lib/typescript/src/Hashnames.d.ts.map +1 -0
  127. package/lib/typescript/{Hmac.d.ts → src/Hmac.d.ts} +3 -3
  128. package/lib/typescript/src/Hmac.d.ts.map +1 -0
  129. package/lib/typescript/src/NativeQuickCrypto/Cipher.d.ts +34 -0
  130. package/lib/typescript/src/NativeQuickCrypto/Cipher.d.ts.map +1 -0
  131. package/lib/typescript/{NativeQuickCrypto → src/NativeQuickCrypto}/NativeQuickCrypto.d.ts +3 -0
  132. package/lib/typescript/src/NativeQuickCrypto/NativeQuickCrypto.d.ts.map +1 -0
  133. package/lib/typescript/src/NativeQuickCrypto/hash.d.ts +7 -0
  134. package/lib/typescript/src/NativeQuickCrypto/hash.d.ts.map +1 -0
  135. package/lib/typescript/src/NativeQuickCrypto/hmac.d.ts +6 -0
  136. package/lib/typescript/src/NativeQuickCrypto/hmac.d.ts.map +1 -0
  137. package/lib/typescript/{NativeQuickCrypto → src/NativeQuickCrypto}/pbkdf2.d.ts +2 -1
  138. package/lib/typescript/src/NativeQuickCrypto/pbkdf2.d.ts.map +1 -0
  139. package/lib/typescript/{NativeQuickCrypto → src/NativeQuickCrypto}/random.d.ts +2 -1
  140. package/lib/typescript/src/NativeQuickCrypto/random.d.ts.map +1 -0
  141. package/lib/typescript/{NativeQuickCrypto → src/NativeQuickCrypto}/sig.d.ts +5 -4
  142. package/lib/typescript/src/NativeQuickCrypto/sig.d.ts.map +1 -0
  143. package/lib/typescript/src/NativeQuickCrypto/webcrypto.d.ts +27 -0
  144. package/lib/typescript/src/NativeQuickCrypto/webcrypto.d.ts.map +1 -0
  145. package/lib/typescript/{QuickCrypto.d.ts → src/QuickCrypto.d.ts} +18 -8
  146. package/lib/typescript/src/QuickCrypto.d.ts.map +1 -0
  147. package/lib/typescript/src/Utils.d.ts +46 -0
  148. package/lib/typescript/src/Utils.d.ts.map +1 -0
  149. package/lib/typescript/src/aes.d.ts +5 -0
  150. package/lib/typescript/src/aes.d.ts.map +1 -0
  151. package/lib/typescript/{constants.d.ts → src/constants.d.ts} +1 -0
  152. package/lib/typescript/src/constants.d.ts.map +1 -0
  153. package/lib/typescript/src/ec.d.ts +5 -0
  154. package/lib/typescript/src/ec.d.ts.map +1 -0
  155. package/lib/typescript/src/index.d.ts +3 -0
  156. package/lib/typescript/src/index.d.ts.map +1 -0
  157. package/lib/typescript/src/keys.d.ts +154 -0
  158. package/lib/typescript/src/keys.d.ts.map +1 -0
  159. package/lib/typescript/src/pbkdf2.d.ts +12 -0
  160. package/lib/typescript/src/pbkdf2.d.ts.map +1 -0
  161. package/lib/typescript/{random.d.ts → src/random.d.ts} +7 -6
  162. package/lib/typescript/src/random.d.ts.map +1 -0
  163. package/lib/typescript/src/rsa.d.ts +4 -0
  164. package/lib/typescript/src/rsa.d.ts.map +1 -0
  165. package/lib/typescript/{sig.d.ts → src/sig.d.ts} +3 -3
  166. package/lib/typescript/src/sig.d.ts.map +1 -0
  167. package/lib/typescript/src/subtle.d.ts +11 -0
  168. package/lib/typescript/src/subtle.d.ts.map +1 -0
  169. package/package.json +39 -34
  170. package/react-native-quick-crypto.podspec +4 -5
  171. package/src/Cipher.ts +108 -102
  172. package/src/Hash.ts +42 -6
  173. package/src/Hashnames.ts +91 -0
  174. package/src/Hmac.ts +3 -3
  175. package/src/NativeQuickCrypto/Cipher.ts +1 -0
  176. package/src/NativeQuickCrypto/NativeQuickCrypto.ts +2 -0
  177. package/src/NativeQuickCrypto/webcrypto.ts +46 -0
  178. package/src/QuickCrypto.ts +5 -0
  179. package/src/Utils.ts +491 -5
  180. package/src/aes.ts +365 -0
  181. package/src/ec.ts +351 -0
  182. package/src/index.ts +3 -8
  183. package/src/keys.ts +428 -54
  184. package/src/pbkdf2.ts +84 -11
  185. package/src/random.ts +37 -24
  186. package/src/rsa.ts +396 -0
  187. package/src/sig.ts +3 -2
  188. package/src/subtle.ts +358 -0
  189. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  190. package/android/gradle/wrapper/gradle-wrapper.properties +0 -5
  191. package/android/gradlew +0 -183
  192. package/android/gradlew.bat +0 -100
  193. package/lib/commonjs/@types/stream-browserify.d.js +0 -2
  194. package/lib/commonjs/@types/stream-browserify.d.js.map +0 -1
  195. package/lib/module/@types/stream-browserify.d.js +0 -2
  196. package/lib/module/@types/stream-browserify.d.js.map +0 -1
  197. package/lib/typescript/Cipher.d.ts +0 -87
  198. package/lib/typescript/NativeQuickCrypto/Cipher.d.ts +0 -32
  199. package/lib/typescript/NativeQuickCrypto/hash.d.ts +0 -6
  200. package/lib/typescript/NativeQuickCrypto/hmac.d.ts +0 -5
  201. package/lib/typescript/Utils.d.ts +0 -23
  202. package/lib/typescript/index.d.ts +0 -207
  203. package/lib/typescript/keys.d.ts +0 -60
  204. package/lib/typescript/pbkdf2.d.ts +0 -9
  205. package/src/@types/stream-browserify.d.ts +0 -4
package/cpp/MGLKeys.cpp CHANGED
@@ -9,22 +9,28 @@
9
9
 
10
10
  #include <jsi/jsi.h>
11
11
  #include <openssl/bio.h>
12
+ #include <openssl/ec.h>
12
13
 
13
14
  #include <algorithm>
15
+ #include <iostream>
14
16
  #include <optional>
15
17
  #include <utility>
16
18
  #include <vector>
17
19
 
18
20
  #ifdef ANDROID
21
+ #include "Cipher/MGLRsa.h"
19
22
  #include "JSIUtils/MGLJSIMacros.h"
20
23
  #include "JSIUtils/MGLJSIUtils.h"
21
24
  #include "JSIUtils/MGLTypedArray.h"
22
25
  #include "Utils/MGLUtils.h"
26
+ #include "webcrypto/crypto_ec.h"
23
27
  #else
28
+ #include "MGLRsa.h"
24
29
  #include "MGLJSIMacros.h"
25
30
  #include "MGLJSIUtils.h"
26
31
  #include "MGLTypedArray.h"
27
32
  #include "MGLUtils.h"
33
+ #include "crypto_ec.h"
28
34
  #endif
29
35
 
30
36
  namespace margelo {
@@ -245,28 +251,20 @@ ParseKeyResult ParsePrivateKey(EVPKeyPointer* pkey,
245
251
  return ParseKeyResult::kParseKeyFailed;
246
252
  }
247
253
 
248
- std::optional<StringOrBuffer> BIOToStringOrBuffer(BIO* bio,
249
- PKFormatType format) {
254
+ OptionJSVariant BIOToStringOrBuffer(jsi::Runtime& rt, BIO* bio, PKFormatType format) {
250
255
  BUF_MEM* bptr;
251
256
  BIO_get_mem_ptr(bio, &bptr);
252
257
  if (format == kKeyFormatPEM) {
253
258
  // PEM is an ASCII format, so we will return it as a string.
254
- return StringOrBuffer{
255
- .isString = true,
256
- .stringValue = std::string(bptr->data, bptr->length),
257
- };
259
+ return JSVariant(std::string(bptr->data, bptr->length));
258
260
  } else {
259
261
  // CHECK_EQ(format, kKeyFormatDER);
260
262
  // DER is binary, return it as a buffer.
261
- std::vector<unsigned char> vec(bptr->data, bptr->data + bptr->length);
262
- return StringOrBuffer{
263
- .isString = false,
264
- .vectorValue = vec,
265
- };
263
+ return JSVariant(ByteSource::Allocated(bptr->data, bptr->length));
266
264
  }
267
265
  }
268
266
 
269
- std::optional<StringOrBuffer> WritePrivateKey(
267
+ OptionJSVariant WritePrivateKey(
270
268
  jsi::Runtime& runtime, EVP_PKEY* pkey,
271
269
  const PrivateKeyEncodingConfig& config) {
272
270
  BIOPointer bio(BIO_new(BIO_s_mem()));
@@ -294,14 +292,14 @@ std::optional<StringOrBuffer> WritePrivateKey(
294
292
  }
295
293
  }
296
294
 
297
- bool err;
295
+ bool err = false;
298
296
 
299
297
  PKEncodingType encoding_type = config.type_.value();
300
298
  if (encoding_type == kKeyEncodingPKCS1) {
301
299
  // PKCS#1 is only permitted for RSA keys.
302
300
  // CHECK_EQ(EVP_PKEY_id(pkey), EVP_PKEY_RSA);
303
301
 
304
- RSAPointer rsa(EVP_PKEY_get1_RSA(pkey));
302
+ RsaPointer rsa(EVP_PKEY_get1_RSA(pkey));
305
303
  if (config.format_ == kKeyFormatPEM) {
306
304
  // Encode PKCS#1 as PEM.
307
305
  err = PEM_write_bio_RSAPrivateKey(bio.get(), rsa.get(), config.cipher_,
@@ -351,7 +349,7 @@ std::optional<StringOrBuffer> WritePrivateKey(
351
349
  throw jsi::JSError(runtime, "Failed to encode private key");
352
350
  }
353
351
 
354
- return BIOToStringOrBuffer(bio.get(), config.format_);
352
+ return BIOToStringOrBuffer(runtime, bio.get(), config.format_);
355
353
  }
356
354
 
357
355
  bool WritePublicKeyInner(EVP_PKEY* pkey, const BIOPointer& bio,
@@ -359,7 +357,7 @@ bool WritePublicKeyInner(EVP_PKEY* pkey, const BIOPointer& bio,
359
357
  if (config.type_.value() == kKeyEncodingPKCS1) {
360
358
  // PKCS#1 is only valid for RSA keys.
361
359
  // CHECK_EQ(EVP_PKEY_id(pkey), EVP_PKEY_RSA);
362
- RSAPointer rsa(EVP_PKEY_get1_RSA(pkey));
360
+ RsaPointer rsa(EVP_PKEY_get1_RSA(pkey));
363
361
  if (config.format_ == kKeyFormatPEM) {
364
362
  // Encode PKCS#1 as PEM.
365
363
  return PEM_write_bio_RSAPublicKey(bio.get(), rsa.get()) == 1;
@@ -381,7 +379,7 @@ bool WritePublicKeyInner(EVP_PKEY* pkey, const BIOPointer& bio,
381
379
  }
382
380
  }
383
381
 
384
- std::optional<StringOrBuffer> WritePublicKey(
382
+ OptionJSVariant WritePublicKey(
385
383
  jsi::Runtime& runtime, EVP_PKEY* pkey,
386
384
  const PublicKeyEncodingConfig& config) {
387
385
  BIOPointer bio(BIO_new(BIO_s_mem()));
@@ -391,138 +389,104 @@ std::optional<StringOrBuffer> WritePublicKey(
391
389
  throw jsi::JSError(runtime, "Failed to encode public key");
392
390
  }
393
391
 
394
- return BIOToStringOrBuffer(bio.get(), config.format_);
392
+ return BIOToStringOrBuffer(runtime, bio.get(), config.format_);
395
393
  }
396
394
 
397
- // Maybe<bool> ExportJWKSecretKey(
398
- // Environment* env,
399
- // std::shared_ptr<KeyObjectData> key,
400
- // Local<Object> target) {
401
- // CHECK_EQ(key->GetKeyType(), kKeyTypeSecret);
402
- //
403
- // Local<Value> error;
404
- // Local<Value> raw;
405
- // MaybeLocal<Value> key_data =
406
- // StringBytes::Encode(
407
- // env->isolate(),
408
- // key->GetSymmetricKey(),
409
- // key->GetSymmetricKeySize(),
410
- // BASE64URL,
411
- // &error);
412
- // if (key_data.IsEmpty()) {
413
- // CHECK(!error.IsEmpty());
414
- // env->isolate()->ThrowException(error);
415
- // return Nothing<bool>();
416
- // }
417
- // if (!key_data.ToLocal(&raw))
418
- // return Nothing<bool>();
419
- //
420
- // if (target->Set(
421
- // env->context(),
422
- // env->jwk_kty_string(),
423
- // env->jwk_oct_string()).IsNothing() ||
424
- // target->Set(
425
- // env->context(),
426
- // env->jwk_k_string(),
427
- // raw).IsNothing()) {
428
- // return Nothing<bool>();
429
- // }
430
- //
431
- // return Just(true);
432
- //}
433
- //
434
- // std::shared_ptr<KeyObjectData> ImportJWKSecretKey(
435
- // Environment* env,
436
- // Local<Object> jwk) {
437
- // Local<Value> key;
438
- // if (!jwk->Get(env->context(), env->jwk_k_string()).ToLocal(&key) ||
439
- // !key->IsString()) {
440
- // THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK secret key format");
441
- // return std::shared_ptr<KeyObjectData>();
442
- // }
443
- //
444
- // ByteSource key_data = ByteSource::FromEncodedString(env,
445
- // key.As<String>()); if (key_data.size() > INT_MAX) {
446
- // THROW_ERR_CRYPTO_INVALID_KEYLEN(env);
447
- // return std::shared_ptr<KeyObjectData>();
448
- // }
449
- //
450
- // return KeyObjectData::CreateSecret(std::move(key_data));
451
- //}
452
- //
453
- // Maybe<bool> ExportJWKAsymmetricKey(
454
- // Environment* env,
455
- // std::shared_ptr<KeyObjectData> key,
456
- // Local<Object> target,
457
- // bool handleRsaPss) {
458
- // switch (EVP_PKEY_id(key->GetAsymmetricKey().get())) {
459
- // case EVP_PKEY_RSA_PSS: {
460
- // if (handleRsaPss) return ExportJWKRsaKey(env, key, target);
461
- // break;
462
- // }
463
- // case EVP_PKEY_RSA: return ExportJWKRsaKey(env, key, target);
464
- // case EVP_PKEY_EC: return ExportJWKEcKey(env, key, target).IsJust() ?
465
- // Just(true) : Nothing<bool>();
466
- // case EVP_PKEY_ED25519:
467
- // // Fall through
468
- // case EVP_PKEY_ED448:
469
- // // Fall through
470
- // case EVP_PKEY_X25519:
471
- // // Fall through
472
- // case EVP_PKEY_X448: return ExportJWKEdKey(env, key, target);
473
- // }
474
- // THROW_ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE(env);
475
- // return Just(false);
476
- //}
477
- //
478
- // std::shared_ptr<KeyObjectData> ImportJWKAsymmetricKey(
479
- // Environment* env,
480
- // Local<Object> jwk,
481
- // const char* kty,
482
- // const
483
- // FunctionCallbackInfo<Value>&
484
- // args, unsigned int
485
- // offset) {
486
- // if (strcmp(kty, "RSA") == 0) {
487
- // return ImportJWKRsaKey(env, jwk, args, offset);
488
- // } else if (strcmp(kty, "EC") == 0) {
489
- // return ImportJWKEcKey(env, jwk, args, offset);
490
- // }
491
- //
492
- // THROW_ERR_CRYPTO_INVALID_JWK(env, "%s is not a supported JWK key type",
493
- // kty); return std::shared_ptr<KeyObjectData>();
494
- //}
495
- //
496
- // Maybe<bool> GetSecretKeyDetail(
497
- // Environment* env,
498
- // std::shared_ptr<KeyObjectData> key,
499
- // Local<Object> target) {
500
- // // For the secret key detail, all we care about is the length,
501
- // // converted to bits.
502
- //
503
- // size_t length = key->GetSymmetricKeySize() * CHAR_BIT;
504
- // return target->Set(env->context(),
505
- // env->length_string(),
506
- // Number::New(env->isolate(),
507
- // static_cast<double>(length)));
508
- //}
509
- //
510
- // Maybe<bool> GetAsymmetricKeyDetail(
511
- // Environment* env,
512
- // std::shared_ptr<KeyObjectData> key,
513
- // Local<Object> target) {
514
- // switch (EVP_PKEY_id(key->GetAsymmetricKey().get())) {
515
- // case EVP_PKEY_RSA:
516
- // // Fall through
517
- // case EVP_PKEY_RSA_PSS: return GetRsaKeyDetail(env, key, target);
518
- // case EVP_PKEY_DSA: return GetDsaKeyDetail(env, key, target);
519
- // case EVP_PKEY_EC: return GetEcKeyDetail(env, key, target);
520
- // case EVP_PKEY_DH: return GetDhKeyDetail(env, key, target);
521
- // }
522
- // THROW_ERR_CRYPTO_INVALID_KEYTYPE(env);
523
- // return Nothing<bool>();
524
- //}
525
- //} // namespace
395
+ jsi::Value ExportJWKSecretKey(jsi::Runtime &rt,
396
+ std::shared_ptr<KeyObjectData> key,
397
+ jsi::Object &result) {
398
+ CHECK_EQ(key->GetKeyType(), kKeyTypeSecret);
399
+
400
+ std::string key_data = EncodeBase64(key->GetSymmetricKey(), true);
401
+
402
+ result.setProperty(rt, "kty", "oct");
403
+ result.setProperty(rt, "k", key_data);
404
+ return std::move(result);
405
+ }
406
+
407
+ std::shared_ptr<KeyObjectData> ImportJWKSecretKey(jsi::Runtime &rt,
408
+ jsi::Object &jwk) {
409
+ std::string key = jwk
410
+ .getProperty(rt, "k")
411
+ .asString(rt)
412
+ .utf8(rt);
413
+
414
+ // TODO: when adding tests, trap errors like below (i.e. no `k` property, undefined)
415
+ // Local<Value> key;
416
+ // if (!jwk->Get(env->context(), env->jwk_k_string()).ToLocal(&key) ||
417
+ // !key->IsString()) {
418
+ // THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK secret key format");
419
+ // return std::shared_ptr<KeyObjectData>();
420
+ // }
421
+
422
+ ByteSource key_data = ByteSource::FromEncodedString(rt, key, encoding::BASE64URL);
423
+ if (key_data.size() > INT_MAX) {
424
+ throw jsi::JSError(rt, "Invalid crypto key length");
425
+ return std::shared_ptr<KeyObjectData>();
426
+ }
427
+
428
+ return KeyObjectData::CreateSecret(std::move(key_data));
429
+ }
430
+
431
+ jsi::Value ExportJWKAsymmetricKey(jsi::Runtime &rt,
432
+ std::shared_ptr<KeyObjectData> key,
433
+ jsi::Object &target,
434
+ bool handleRsaPss) {
435
+ switch (EVP_PKEY_id(key->GetAsymmetricKey().get())) {
436
+ case EVP_PKEY_RSA_PSS: {
437
+ if (handleRsaPss) return ExportJWKRsaKey(rt, key, target);
438
+ break;
439
+ }
440
+ case EVP_PKEY_RSA: return ExportJWKRsaKey(rt, key, target);
441
+ case EVP_PKEY_EC: return ExportJWKEcKey(rt, key, target);
442
+ // case EVP_PKEY_ED25519:
443
+ // // Fall through
444
+ // case EVP_PKEY_ED448:
445
+ // // Fall through
446
+ // case EVP_PKEY_X25519:
447
+ // // Fall through
448
+ // case EVP_PKEY_X448: return ExportJWKEdKey(rt, key, target);
449
+ }
450
+ throw jsi::JSError(rt, "Unsupported JWK asymmetric key type");
451
+ }
452
+
453
+ std::shared_ptr<KeyObjectData> ImportJWKAsymmetricKey(jsi::Runtime &rt,
454
+ jsi::Object &jwk,
455
+ std::string kty,
456
+ jsi::Value &namedCurve) {
457
+ if (kty.compare("RSA") == 0) {
458
+ return ImportJWKRsaKey(rt, jwk);
459
+ } else if (kty.compare("EC") == 0) {
460
+ return ImportJWKEcKey(rt, jwk, namedCurve);
461
+ }
462
+
463
+ throw jsi::JSError(rt, "%s is not a supported JWK key type", kty);
464
+ return std::shared_ptr<KeyObjectData>();
465
+ }
466
+
467
+ jsi::Value GetSecretKeyDetail(jsi::Runtime &rt,
468
+ std::shared_ptr<KeyObjectData> key) {
469
+ jsi::Object target = jsi::Object(rt);
470
+ // For the secret key detail, all we care about is the length,
471
+ // converted to bits.
472
+ size_t length = key->GetSymmetricKeySize() * CHAR_BIT;
473
+ target.setProperty(rt, "length", static_cast<double>(length));
474
+ return std::move(target);
475
+ }
476
+
477
+ jsi::Value GetAsymmetricKeyDetail(jsi::Runtime &rt,
478
+ std::shared_ptr<KeyObjectData> key) {
479
+ switch (EVP_PKEY_id(key->GetAsymmetricKey().get())) {
480
+ case EVP_PKEY_RSA:
481
+ // Fall through
482
+ case EVP_PKEY_RSA_PSS: return GetRsaKeyDetail(rt, key);
483
+ // case EVP_PKEY_DSA: return GetDsaKeyDetail(env, key);
484
+ case EVP_PKEY_EC: return GetEcKeyDetail(rt, key);
485
+ // case EVP_PKEY_DH: return GetDhKeyDetail(env, key);
486
+ }
487
+ throw jsi::JSError(rt, "Invalid Key Type");
488
+ return false;
489
+ }
526
490
 
527
491
  ManagedEVPPKey::ManagedEVPPKey(EVPKeyPointer&& pkey) : pkey_(std::move(pkey)) {}
528
492
 
@@ -568,27 +532,24 @@ EVP_PKEY* ManagedEVPPKey::get() const { return pkey_.get(); }
568
532
  // pkey_.get(), nullptr, &len)
569
533
  // == 1) ? len : 0;
570
534
  //}
571
- //
572
- // Maybe<bool> ExportJWKInner(Environment* env,
573
- // std::shared_ptr<KeyObjectData> key,
574
- // Local<Value> result,
575
- // bool handleRsaPss) {
576
- // switch (key->GetKeyType()) {
577
- // case kKeyTypeSecret:
578
- // return ExportJWKSecretKey(env, key, result.As<Object>());
579
- // case kKeyTypePublic:
580
- // // Fall through
581
- // case kKeyTypePrivate:
582
- // return ExportJWKAsymmetricKey(
583
- // env, key, result.As<Object>(),
584
- // handleRsaPss);
585
- // default:
586
- // UNREACHABLE();
587
- // }
588
- // }
589
- //
590
535
 
591
- std::optional<StringOrBuffer> ManagedEVPPKey::ToEncodedPublicKey(
536
+ jsi::Value ExportJWKInner(jsi::Runtime &rt,
537
+ std::shared_ptr<KeyObjectData> key,
538
+ jsi::Object &result,
539
+ bool handleRsaPss) {
540
+ switch (key->GetKeyType()) {
541
+ case kKeyTypeSecret:
542
+ return ExportJWKSecretKey(rt, key, result);
543
+ case kKeyTypePublic:
544
+ // Fall through
545
+ case kKeyTypePrivate:
546
+ return ExportJWKAsymmetricKey(rt, key, result, handleRsaPss);
547
+ default:
548
+ throw jsi::JSError(rt, "unreachable code in ExportJWKInner");
549
+ }
550
+ }
551
+
552
+ OptionJSVariant ManagedEVPPKey::ToEncodedPublicKey(
592
553
  jsi::Runtime& runtime, ManagedEVPPKey key,
593
554
  const PublicKeyEncodingConfig& config) {
594
555
  if (!key) return {};
@@ -610,7 +571,7 @@ std::optional<StringOrBuffer> ManagedEVPPKey::ToEncodedPublicKey(
610
571
  return WritePublicKey(runtime, key.get(), config);
611
572
  }
612
573
 
613
- std::optional<StringOrBuffer> ManagedEVPPKey::ToEncodedPrivateKey(
574
+ OptionJSVariant ManagedEVPPKey::ToEncodedPrivateKey(
614
575
  jsi::Runtime& runtime, ManagedEVPPKey key,
615
576
  const PrivateKeyEncodingConfig& config) {
616
577
  if (!key) return {};
@@ -672,7 +633,7 @@ ManagedEVPPKey::GetPrivateKeyEncodingFromJs(jsi::Runtime& runtime,
672
633
  if (needs_passphrase &&
673
634
  (arguments[*offset].isNull() || arguments[*offset].isUndefined())) {
674
635
  throw jsi::JSError(
675
- runtime, "passphrase is null or unfedined but it is required");
636
+ runtime, "passphrase is null or undefined but it is required");
676
637
  }
677
638
  }
678
639
  }
@@ -763,7 +724,7 @@ ManagedEVPPKey ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(
763
724
  is_public = false;
764
725
  break;
765
726
  default:
766
- throw new jsi::JSError(runtime, "Invalid key encoding type");
727
+ throw jsi::JSError(runtime, "Invalid key encoding type");
767
728
  }
768
729
 
769
730
  if (is_public) {
@@ -780,7 +741,7 @@ ManagedEVPPKey ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(
780
741
  return ManagedEVPPKey::GetParsedKey(runtime, std::move(pkey), ret,
781
742
  "Failed to read asymmetric key");
782
743
  } else {
783
- throw new jsi::JSError(
744
+ throw jsi::JSError(
784
745
  runtime, "public encrypt only supports ArrayBuffer at the moment");
785
746
  // CHECK(args[*offset]->IsObject());
786
747
  // KeyObjectHandle* key =
@@ -801,81 +762,87 @@ ManagedEVPPKey ManagedEVPPKey::GetParsedKey(jsi::Runtime& runtime,
801
762
  // CHECK(pkey);
802
763
  break;
803
764
  case ParseKeyResult::kParseKeyNeedPassphrase:
804
- throw jsi::JSError(runtime,
805
- "Passphrase required for encrypted key");
765
+ throw jsi::JSError(runtime, "Passphrase required for encrypted key");
806
766
  break;
807
767
  default:
808
- throw new jsi::JSError(runtime, default_msg);
768
+ throw jsi::JSError(runtime, default_msg);
809
769
  }
810
770
 
811
771
  return ManagedEVPPKey(std::move(pkey));
812
772
  }
813
- //
814
- // KeyObjectData::KeyObjectData(
815
- // ByteSource symmetric_key)
816
- //: key_type_(KeyType::kKeyTypeSecret),
817
- // symmetric_key_(std::move(symmetric_key)),
818
- // symmetric_key_len_(symmetric_key_.size()),
819
- // asymmetric_key_() {}
820
- //
821
- // KeyObjectData::KeyObjectData(
822
- // KeyType type,
823
- // const ManagedEVPPKey& pkey)
824
- //: key_type_(type),
825
- // symmetric_key_(),
826
- // symmetric_key_len_(0),
827
- // asymmetric_key_{pkey} {}
828
- //
829
- // void KeyObjectData::MemoryInfo(MemoryTracker* tracker) const {
830
- // switch (GetKeyType()) {
831
- // case kKeyTypeSecret:
832
- // tracker->TrackFieldWithSize("symmetric_key", symmetric_key_.size());
833
- // break;
834
- // case kKeyTypePrivate:
835
- // // Fall through
836
- // case kKeyTypePublic:
837
- // tracker->TrackFieldWithSize("key", asymmetric_key_);
838
- // break;
839
- // default:
840
- // UNREACHABLE();
841
- // }
842
- // }
843
- //
844
- // std::shared_ptr<KeyObjectData> KeyObjectData::CreateSecret(ByteSource key)
845
- // {
846
- // CHECK(key);
847
- // return std::shared_ptr<KeyObjectData>(new KeyObjectData(std::move(key)));
848
- // }
849
- //
850
- // std::shared_ptr<KeyObjectData> KeyObjectData::CreateAsymmetric(
851
- // KeyType
852
- // key_type,
853
- // const
854
- // ManagedEVPPKey&
855
- // pkey) {
856
- // CHECK(pkey);
857
- // return std::shared_ptr<KeyObjectData>(new KeyObjectData(key_type, pkey));
858
- // }
859
- //
860
- // KeyType KeyObjectData::GetKeyType() const {
861
- // return key_type_;
862
- // }
863
- //
864
- // ManagedEVPPKey KeyObjectData::GetAsymmetricKey() const {
865
- // CHECK_NE(key_type_, kKeyTypeSecret);
866
- // return asymmetric_key_;
867
- // }
868
- //
869
- // const char* KeyObjectData::GetSymmetricKey() const {
870
- // CHECK_EQ(key_type_, kKeyTypeSecret);
871
- // return symmetric_key_.data<char>();
872
- // }
873
- //
874
- // size_t KeyObjectData::GetSymmetricKeySize() const {
875
- // CHECK_EQ(key_type_, kKeyTypeSecret);
876
- // return symmetric_key_len_;
877
- // }
878
- //
773
+
774
+ KeyObjectData::KeyObjectData(ByteSource symmetric_key)
775
+ : key_type_(KeyType::kKeyTypeSecret),
776
+ symmetric_key_(std::move(symmetric_key)),
777
+ symmetric_key_len_(symmetric_key_.size()),
778
+ asymmetric_key_() {}
779
+
780
+ KeyObjectData::KeyObjectData(KeyType type,
781
+ const ManagedEVPPKey& pkey)
782
+ : key_type_(type),
783
+ symmetric_key_(),
784
+ symmetric_key_len_(0),
785
+ asymmetric_key_{pkey} {}
786
+
787
+ std::shared_ptr<KeyObjectData> KeyObjectData::CreateSecret(ByteSource key)
788
+ {
789
+ CHECK(key);
790
+ return std::shared_ptr<KeyObjectData>(new KeyObjectData(std::move(key)));
791
+ }
792
+
793
+ std::shared_ptr<KeyObjectData> KeyObjectData::CreateAsymmetric(
794
+ KeyType key_type,
795
+ const ManagedEVPPKey& pkey
796
+ ) {
797
+ CHECK(pkey);
798
+ return std::shared_ptr<KeyObjectData>(new KeyObjectData(key_type, pkey));
799
+ }
800
+
801
+ KeyType KeyObjectData::GetKeyType() const {
802
+ return key_type_;
803
+ }
804
+
805
+ ManagedEVPPKey KeyObjectData::GetAsymmetricKey() const {
806
+ CHECK_NE(key_type_, kKeyTypeSecret);
807
+ return asymmetric_key_;
808
+ }
809
+
810
+ /** Gets the symmetric key value
811
+ * binary data stored in string, tolerates \0 characters
812
+ */
813
+ std::string KeyObjectData::GetSymmetricKey() const {
814
+ CHECK_EQ(key_type_, kKeyTypeSecret);
815
+ return symmetric_key_.ToString();
816
+ }
817
+
818
+ size_t KeyObjectData::GetSymmetricKeySize() const {
819
+ CHECK_EQ(key_type_, kKeyTypeSecret);
820
+ return symmetric_key_len_;
821
+ }
822
+
823
+
824
+ jsi::Value KeyObjectHandle::get(
825
+ jsi::Runtime &rt,
826
+ const jsi::PropNameID &propNameID) {
827
+ auto name = propNameID.utf8(rt);
828
+
829
+ if (name == "export") {
830
+ return this->Export(rt);
831
+ } else if (name == "exportJwk") {
832
+ return this->ExportJWK(rt);
833
+ } else if (name == "initECRaw") {
834
+ return this-> InitECRaw(rt);
835
+ } else if (name == "init") {
836
+ return this->Init(rt);
837
+ } else if (name == "initJwk") {
838
+ return this->InitJWK(rt);
839
+ } else if (name == "keyDetail") {
840
+ return this->GetKeyDetail(rt);
841
+ }
842
+
843
+ return {};
844
+ }
845
+
879
846
  // v8::Local<v8::Function> KeyObjectHandle::Initialize(Environment* env) {
880
847
  // Local<Function> templ = env->crypto_key_object_handle_constructor();
881
848
  // if (!templ.IsEmpty()) {
@@ -936,9 +903,9 @@ ManagedEVPPKey ManagedEVPPKey::GetParsedKey(jsi::Runtime& runtime,
936
903
  // return obj;
937
904
  // }
938
905
  //
939
- // const std::shared_ptr<KeyObjectData>& KeyObjectHandle::Data() {
940
- // return data_;
941
- // }
906
+ const std::shared_ptr<KeyObjectData>& KeyObjectHandle::Data() {
907
+ return this->data_;
908
+ }
942
909
  //
943
910
  // void KeyObjectHandle::New(const FunctionCallbackInfo<Value>& args) {
944
911
  // CHECK(args.IsConstructCall());
@@ -952,126 +919,129 @@ ManagedEVPPKey ManagedEVPPKey::GetParsedKey(jsi::Runtime& runtime,
952
919
  // MakeWeak();
953
920
  //}
954
921
  //
955
- // void KeyObjectHandle::Init(const FunctionCallbackInfo<Value>& args) {
956
- // KeyObjectHandle* key;
957
- // ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
958
- // MarkPopErrorOnReturn mark_pop_error_on_return;
959
- //
960
- // CHECK(args[0]->IsInt32());
961
- // KeyType type = static_cast<KeyType>(args[0].As<Uint32>()->Value());
962
- //
963
- // unsigned int offset;
964
- // ManagedEVPPKey pkey;
965
- //
966
- // switch (type) {
967
- // case kKeyTypeSecret: {
968
- // CHECK_EQ(args.Length(), 2);
969
- // ArrayBufferOrViewContents<char> buf(args[1]);
970
- // key->data_ = KeyObjectData::CreateSecret(buf.ToCopy());
971
- // break;
972
- // }
973
- // case kKeyTypePublic: {
974
- // CHECK_EQ(args.Length(), 5);
975
- //
976
- // offset = 1;
977
- // pkey = ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset);
978
- // if (!pkey)
979
- // return;
980
- // key->data_ = KeyObjectData::CreateAsymmetric(type, pkey);
981
- // break;
982
- // }
983
- // case kKeyTypePrivate: {
984
- // CHECK_EQ(args.Length(), 5);
985
- //
986
- // offset = 1;
987
- // pkey = ManagedEVPPKey::GetPrivateKeyFromJs(args, &offset, false);
988
- // if (!pkey)
989
- // return;
990
- // key->data_ = KeyObjectData::CreateAsymmetric(type, pkey);
991
- // break;
992
- // }
993
- // default:
994
- // UNREACHABLE();
995
- // }
996
- //}
997
- //
998
- // void KeyObjectHandle::InitJWK(const FunctionCallbackInfo<Value>& args) {
999
- // Environment* env = Environment::GetCurrent(args);
1000
- // KeyObjectHandle* key;
1001
- // ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
1002
- // MarkPopErrorOnReturn mark_pop_error_on_return;
1003
- //
1004
- // // The argument must be a JavaScript object that we will inspect
1005
- // // to get the JWK properties from.
1006
- // CHECK(args[0]->IsObject());
1007
- //
1008
- // // Step one, Secret key or not?
1009
- // Local<Object> input = args[0].As<Object>();
1010
- //
1011
- // Local<Value> kty;
1012
- // if (!input->Get(env->context(), env->jwk_kty_string()).ToLocal(&kty) ||
1013
- // !kty->IsString()) {
1014
- // return THROW_ERR_CRYPTO_INVALID_JWK(env);
1015
- // }
1016
- //
1017
- // Utf8Value kty_string(env->isolate(), kty);
1018
- //
1019
- // if (strcmp(*kty_string, "oct") == 0) {
1020
- // // Secret key
1021
- // key->data_ = ImportJWKSecretKey(env, input);
1022
- // if (!key->data_) {
1023
- // // ImportJWKSecretKey is responsible for throwing an appropriate error
1024
- // return;
1025
- // }
1026
- // } else {
1027
- // key->data_ = ImportJWKAsymmetricKey(env, input, *kty_string, args, 1);
1028
- // if (!key->data_) {
1029
- // // ImportJWKAsymmetricKey is responsible for throwing an appropriate
1030
- // error return;
1031
- // }
1032
- // }
1033
- //
1034
- // args.GetReturnValue().Set(key->data_->GetKeyType());
1035
- //}
1036
- //
1037
- // void KeyObjectHandle::InitECRaw(const FunctionCallbackInfo<Value>& args) {
1038
- // Environment* env = Environment::GetCurrent(args);
1039
- // KeyObjectHandle* key;
1040
- // ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
1041
- //
1042
- // CHECK(args[0]->IsString());
1043
- // Utf8Value name(env->isolate(), args[0]);
1044
- //
1045
- // MarkPopErrorOnReturn mark_pop_error_on_return;
1046
- //
1047
- // int id = OBJ_txt2nid(*name);
1048
- // ECKeyPointer eckey(EC_KEY_new_by_curve_name(id));
1049
- // if (!eckey)
1050
- // return args.GetReturnValue().Set(false);
1051
- //
1052
- // const EC_GROUP* group = EC_KEY_get0_group(eckey.get());
1053
- // ECPointPointer pub(ECDH::BufferToPoint(env, group, args[1]));
1054
- //
1055
- // if (!pub ||
1056
- // !eckey ||
1057
- // !EC_KEY_set_public_key(eckey.get(), pub.get())) {
1058
- // return args.GetReturnValue().Set(false);
1059
- // }
1060
- //
1061
- // EVPKeyPointer pkey(EVP_PKEY_new());
1062
- // if (!EVP_PKEY_assign_EC_KEY(pkey.get(), eckey.get()))
1063
- // args.GetReturnValue().Set(false);
1064
- //
1065
- // eckey.release(); // Release ownership of the key
1066
- //
1067
- // key->data_ =
1068
- // KeyObjectData::CreateAsymmetric(
1069
- // kKeyTypePublic,
1070
- // ManagedEVPPKey(std::move(pkey)));
1071
- //
1072
- // args.GetReturnValue().Set(true);
1073
- //}
1074
- //
922
+
923
+ jsi::Value KeyObjectHandle::Init(jsi::Runtime &rt) {
924
+ return HOSTFN("init", 2) {
925
+ CHECK(args[0].isNumber());
926
+ KeyType type = static_cast<KeyType>((int32_t)args[0].asNumber());
927
+
928
+ unsigned int offset;
929
+ ManagedEVPPKey pkey;
930
+
931
+ switch (type) {
932
+ case kKeyTypeSecret: {
933
+ // CHECK_EQ(args.Length(), 2);
934
+
935
+ ByteSource key = ByteSource::FromStringOrBuffer(rt, args[1]);
936
+ this->data_ = KeyObjectData::CreateSecret(std::move(key));
937
+ break;
938
+ }
939
+ case kKeyTypePublic: {
940
+ // CHECK_EQ(args.Length(), 5);
941
+
942
+ offset = 1;
943
+ pkey = ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(rt, args, &offset);
944
+ if (!pkey)
945
+ return false;
946
+ this->data_ = KeyObjectData::CreateAsymmetric(type, pkey);
947
+ break;
948
+ }
949
+ case kKeyTypePrivate: {
950
+ // CHECK_EQ(args.Length(), 5);
951
+
952
+ offset = 1;
953
+ pkey = ManagedEVPPKey::GetPrivateKeyFromJs(rt, args, &offset, false);
954
+ if (!pkey)
955
+ return false;
956
+ this->data_ = KeyObjectData::CreateAsymmetric(type, pkey);
957
+ break;
958
+ }
959
+ default:
960
+ throw jsi::JSError(rt, "invalid keytype for init(): " + std::to_string(type));
961
+ }
962
+
963
+ return true;
964
+ });
965
+ }
966
+
967
+ jsi::Value KeyObjectHandle::InitJWK(jsi::Runtime &rt) {
968
+ return HOSTFN("initJwk", 2) {
969
+ // The argument must be a JavaScript object that we will inspect
970
+ // to get the JWK properties from.
971
+ jsi::Object jwk = jsi::Object(jsi::Value(rt, args[0]).asObject(rt));
972
+ jsi::Value namedCurve;
973
+ if (count == 2)
974
+ namedCurve = jsi::Value(rt, args[1]);
975
+
976
+ // Step one, Secret key or not?
977
+ std::string kty = jwk
978
+ .getProperty(rt, "kty")
979
+ .asString(rt)
980
+ .utf8(rt);
981
+
982
+ if (kty.compare("oct") == 0) {
983
+ // Secret key
984
+ this->data_ = ImportJWKSecretKey(rt, jwk);
985
+ if (!this->data_) {
986
+ // ImportJWKSecretKey is responsible for throwing an appropriate error
987
+ return jsi::Value::undefined();
988
+ }
989
+ } else {
990
+ this->data_ = ImportJWKAsymmetricKey(rt, jwk, kty, namedCurve);
991
+ if (!this->data_) {
992
+ // ImportJWKAsymmetricKey is responsible for throwing an appropriate
993
+ // error
994
+ return jsi::Value::undefined();
995
+ }
996
+ }
997
+
998
+ return static_cast<int>(this->data_->GetKeyType());
999
+ });
1000
+ }
1001
+
1002
+ jsi::Value KeyObjectHandle::InitECRaw(jsi::Runtime &rt) {
1003
+ return HOSTFN("initECRaw", 2) {
1004
+ CHECK(args[0].isString());
1005
+ std::string curveName = args[0].asString(rt).utf8(rt);
1006
+ int id = OBJ_txt2nid(curveName.c_str());
1007
+ ECKeyPointer eckey(EC_KEY_new_by_curve_name(id));
1008
+ if (!eckey) {
1009
+ return false;
1010
+ }
1011
+
1012
+ CHECK(args[1].isObject());
1013
+ if (!args[1].getObject(rt).isArrayBuffer(rt)) {
1014
+ throw jsi::JSError(rt,
1015
+ "KeyObjectHandle::InitECRaw: second argument "
1016
+ "has to be of type ArrayBuffer!");
1017
+ }
1018
+ auto buf = args[1].asObject(rt).getArrayBuffer(rt);
1019
+
1020
+ const EC_GROUP* group = EC_KEY_get0_group(eckey.get());
1021
+ ECPointPointer pub(ECDH::BufferToPoint(rt, group, buf));
1022
+
1023
+ if (!pub ||
1024
+ !eckey ||
1025
+ !EC_KEY_set_public_key(eckey.get(), pub.get())) {
1026
+ return false;
1027
+ }
1028
+
1029
+ EVPKeyPointer pkey(EVP_PKEY_new());
1030
+ if (!EVP_PKEY_assign_EC_KEY(pkey.get(), eckey.get())) {
1031
+ return false;
1032
+ }
1033
+
1034
+ eckey.release(); // Release ownership of the key
1035
+
1036
+ this->data_ =
1037
+ KeyObjectData::CreateAsymmetric(
1038
+ kKeyTypePublic,
1039
+ ManagedEVPPKey(std::move(pkey)));
1040
+
1041
+ return true;
1042
+ });
1043
+ }
1044
+
1075
1045
  // void KeyObjectHandle::InitEDRaw(const FunctionCallbackInfo<Value>& args) {
1076
1046
  // Environment* env = Environment::GetCurrent(args);
1077
1047
  // KeyObjectHandle* key;
@@ -1107,7 +1077,7 @@ ManagedEVPPKey ManagedEVPPKey::GetParsedKey(jsi::Runtime& runtime,
1107
1077
  // break;
1108
1078
  // }
1109
1079
  // default:
1110
- // UNREACHABLE();
1080
+ // throw jsi::JSError(rt, "unreachable code in InitEDRaw");
1111
1081
  // }
1112
1082
  //
1113
1083
  // args.GetReturnValue().Set(true);
@@ -1155,41 +1125,31 @@ ManagedEVPPKey ManagedEVPPKey::GetParsedKey(jsi::Runtime& runtime,
1155
1125
  // break;
1156
1126
  // }
1157
1127
  // default:
1158
- // UNREACHABLE("unsupported key type");
1128
+ // throw jsi::JSError(rt, "unreachable code in Equals");
1159
1129
  // }
1160
1130
  //
1161
1131
  // args.GetReturnValue().Set(ret);
1162
1132
  //}
1163
- //
1164
- // void KeyObjectHandle::GetKeyDetail(const FunctionCallbackInfo<Value>& args)
1165
- // {
1166
- // Environment* env = Environment::GetCurrent(args);
1167
- // KeyObjectHandle* key;
1168
- // ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
1169
- //
1170
- // CHECK(args[0]->IsObject());
1171
- //
1172
- // std::shared_ptr<KeyObjectData> data = key->Data();
1173
- //
1174
- // switch (data->GetKeyType()) {
1175
- // case kKeyTypeSecret:
1176
- // if (GetSecretKeyDetail(env, data, args[0].As<Object>()).IsNothing())
1177
- // return;
1178
- // break;
1179
- // case kKeyTypePublic:
1180
- // // Fall through
1181
- // case kKeyTypePrivate:
1182
- // if (GetAsymmetricKeyDetail(env, data,
1183
- // args[0].As<Object>()).IsNothing())
1184
- // return;
1185
- // break;
1186
- // default:
1187
- // UNREACHABLE();
1188
- // }
1189
- //
1190
- // args.GetReturnValue().Set(args[0]);
1191
- //}
1192
- //
1133
+
1134
+ jsi::Value KeyObjectHandle::GetKeyDetail(jsi::Runtime &rt) {
1135
+ return HOSTFN("keyDetail", 0) {
1136
+ std::shared_ptr<KeyObjectData> data = this->Data();
1137
+
1138
+ switch (data->GetKeyType()) {
1139
+ case kKeyTypeSecret:
1140
+ return GetSecretKeyDetail(rt, data);
1141
+ break;
1142
+ case kKeyTypePublic:
1143
+ // Fall through
1144
+ case kKeyTypePrivate:
1145
+ return GetAsymmetricKeyDetail(rt, data);
1146
+ break;
1147
+ default:
1148
+ throw jsi::JSError(rt, "unreachable code in GetKeyDetail");
1149
+ }
1150
+ });
1151
+ }
1152
+
1193
1153
  // Local<Value> KeyObjectHandle::GetAsymmetricKeyType() const {
1194
1154
  // const ManagedEVPPKey& key = data_->GetAsymmetricKey();
1195
1155
  // switch (EVP_PKEY_id(key.get())) {
@@ -1234,82 +1194,65 @@ ManagedEVPPKey ManagedEVPPKey::GetParsedKey(jsi::Runtime& runtime,
1234
1194
  // args.GetReturnValue().Set(
1235
1195
  // static_cast<uint32_t>(key->Data()->GetSymmetricKeySize()));
1236
1196
  //}
1237
- //
1238
- // void KeyObjectHandle::Export(const FunctionCallbackInfo<Value>& args) {
1239
- // KeyObjectHandle* key;
1240
- // ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
1241
- //
1242
- // KeyType type = key->Data()->GetKeyType();
1243
- //
1244
- // MaybeLocal<Value> result;
1245
- // if (type == kKeyTypeSecret) {
1246
- // result = key->ExportSecretKey();
1247
- // } else if (type == kKeyTypePublic) {
1248
- // unsigned int offset = 0;
1249
- // PublicKeyEncodingConfig config =
1250
- // ManagedEVPPKey::GetPublicKeyEncodingFromJs(
1251
- // args, &offset,
1252
- // kKeyContextExport);
1253
- // CHECK_EQ(offset, static_cast<unsigned int>(args.Length()));
1254
- // result = key->ExportPublicKey(config);
1255
- // } else {
1256
- // CHECK_EQ(type, kKeyTypePrivate);
1257
- // unsigned int offset = 0;
1258
- // NonCopyableMaybe<PrivateKeyEncodingConfig> config =
1259
- // ManagedEVPPKey::GetPrivateKeyEncodingFromJs(
1260
- // args, &offset,
1261
- // kKeyContextExport);
1262
- // if (config.IsEmpty())
1263
- // return;
1264
- // CHECK_EQ(offset, static_cast<unsigned int>(args.Length()));
1265
- // result = key->ExportPrivateKey(config.Release());
1266
- // }
1267
- //
1268
- // if (!result.IsEmpty())
1269
- // args.GetReturnValue().Set(result.FromMaybe(Local<Value>()));
1270
- //}
1271
- //
1272
- // MaybeLocal<Value> KeyObjectHandle::ExportSecretKey() const {
1273
- // const char* buf = data_->GetSymmetricKey();
1274
- // unsigned int len = data_->GetSymmetricKeySize();
1275
- // return Buffer::Copy(env(), buf, len).FromMaybe(Local<Value>());
1276
- //}
1277
- //
1278
- // MaybeLocal<Value> KeyObjectHandle::ExportPublicKey(
1279
- // const
1280
- // PublicKeyEncodingConfig&
1281
- // config) const {
1282
- // return
1283
- // WritePublicKey(env(),
1284
- // data_->GetAsymmetricKey().get(),
1285
- // config);
1286
- // }
1287
- //
1288
- // MaybeLocal<Value> KeyObjectHandle::ExportPrivateKey(
1289
- // const
1290
- // PrivateKeyEncodingConfig&
1291
- // config) const {
1292
- // return
1293
- // WritePrivateKey(env(),
1294
- // data_->GetAsymmetricKey().get(),
1295
- // config);
1296
- // }
1297
- //
1298
- // void KeyObjectHandle::ExportJWK(
1299
- // const v8::FunctionCallbackInfo<v8::Value>&
1300
- // args) {
1301
- // Environment* env = Environment::GetCurrent(args);
1302
- // KeyObjectHandle* key;
1303
- // ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
1304
- //
1305
- // CHECK(args[0]->IsObject());
1306
- // CHECK(args[1]->IsBoolean());
1307
- //
1308
- // ExportJWKInner(env, key->Data(), args[0], args[1]->IsTrue());
1309
- //
1310
- // args.GetReturnValue().Set(args[0]);
1311
- //}
1312
- //
1197
+
1198
+ jsi::Value KeyObjectHandle::Export(jsi::Runtime &rt) {
1199
+ return HOSTFN("export", 2) {
1200
+ KeyType type = this->data_->GetKeyType();
1201
+ OptionJSVariant result;
1202
+ if (type == kKeyTypeSecret) {
1203
+ result = this->ExportSecretKey(rt);
1204
+ }
1205
+ else if (type == kKeyTypePublic) {
1206
+ unsigned int offset = 0;
1207
+ PublicKeyEncodingConfig config =
1208
+ ManagedEVPPKey::GetPublicKeyEncodingFromJs(
1209
+ rt, args, &offset, kKeyContextExport);
1210
+ result = this->ExportPublicKey(rt, config);
1211
+ }
1212
+ else if (type == kKeyTypePrivate) {
1213
+ unsigned int offset = 0;
1214
+ NonCopyableMaybe<PrivateKeyEncodingConfig> config =
1215
+ ManagedEVPPKey::GetPrivateKeyEncodingFromJs(
1216
+ rt, args, &offset, kKeyContextExport);
1217
+ if (!config.IsEmpty()) {
1218
+ result = this->ExportPrivateKey(rt, config.Release());
1219
+ }
1220
+ }
1221
+ return toJSI(rt, result);
1222
+ });
1223
+ }
1224
+
1225
+ OptionJSVariant KeyObjectHandle::ExportSecretKey(jsi::Runtime &rt) const {
1226
+ std::string ret = data_->GetSymmetricKey();
1227
+ return JSVariant(ByteSource::FromString(ret));
1228
+ }
1229
+
1230
+ OptionJSVariant KeyObjectHandle::ExportPublicKey(
1231
+ jsi::Runtime& rt,
1232
+ const PublicKeyEncodingConfig& config) const {
1233
+ return WritePublicKey(rt,
1234
+ data_->GetAsymmetricKey().get(),
1235
+ config);
1236
+ }
1237
+
1238
+ OptionJSVariant KeyObjectHandle::ExportPrivateKey(
1239
+ jsi::Runtime &rt,
1240
+ const PrivateKeyEncodingConfig& config) const {
1241
+ return WritePrivateKey(rt,
1242
+ data_->GetAsymmetricKey().get(),
1243
+ config);
1244
+ }
1245
+
1246
+ jsi::Value KeyObjectHandle::ExportJWK(jsi::Runtime &rt) {
1247
+ return HOSTFN("exportJwk", 2) {
1248
+ CHECK(args[0].isObject());
1249
+ CHECK(args[1].isBool());
1250
+ std::shared_ptr<KeyObjectData> data = this->Data();
1251
+ jsi::Object result = args[0].asObject(rt);
1252
+ return ExportJWKInner(rt, data, result, args[1].asBool());
1253
+ });
1254
+ }
1255
+
1313
1256
  // void NativeKeyObject::Initialize(Environment* env, Local<Object> target) {
1314
1257
  // env->SetMethod(target, "createNativeKeyObjectClass",
1315
1258
  // NativeKeyObject::CreateNativeKeyObjectClass);
@@ -1456,4 +1399,5 @@ ManagedEVPPKey ManagedEVPPKey::GetParsedKey(jsi::Runtime& runtime,
1456
1399
  // void RegisterExternalReferences(ExternalReferenceRegistry * registry) {
1457
1400
  // KeyObjectHandle::RegisterExternalReferences(registry);
1458
1401
  // }
1402
+
1459
1403
  } // namespace margelo