react-native-quick-crypto 0.7.0-rc.9 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/cpp/Cipher/MGLGenerateKeyPairInstaller.cpp +51 -14
  2. package/cpp/Cipher/MGLGenerateKeyPairSyncInstaller.cpp +25 -9
  3. package/cpp/Cipher/MGLRsa.cpp +13 -12
  4. package/cpp/Cipher/MGLRsa.h +2 -8
  5. package/cpp/JSIUtils/MGLJSIUtils.h +9 -0
  6. package/cpp/MGLKeys.cpp +174 -149
  7. package/cpp/MGLKeys.h +18 -13
  8. package/cpp/Sig/MGLSignHostObjects.cpp +284 -421
  9. package/cpp/Sig/MGLSignHostObjects.h +40 -0
  10. package/cpp/Utils/MGLUtils.cpp +0 -41
  11. package/cpp/Utils/MGLUtils.h +27 -6
  12. package/cpp/webcrypto/MGLWebCrypto.cpp +14 -4
  13. package/cpp/webcrypto/crypto_ec.cpp +106 -0
  14. package/cpp/webcrypto/crypto_ec.h +18 -0
  15. package/lib/commonjs/Cipher.js +138 -95
  16. package/lib/commonjs/Cipher.js.map +1 -1
  17. package/lib/commonjs/NativeQuickCrypto/Cipher.js +11 -8
  18. package/lib/commonjs/NativeQuickCrypto/Cipher.js.map +1 -1
  19. package/lib/commonjs/NativeQuickCrypto/sig.js +17 -0
  20. package/lib/commonjs/NativeQuickCrypto/sig.js.map +1 -1
  21. package/lib/commonjs/Utils.js +15 -1
  22. package/lib/commonjs/Utils.js.map +1 -1
  23. package/lib/commonjs/ec.js +79 -91
  24. package/lib/commonjs/ec.js.map +1 -1
  25. package/lib/commonjs/keys.js +10 -24
  26. package/lib/commonjs/keys.js.map +1 -1
  27. package/lib/commonjs/random.js +6 -0
  28. package/lib/commonjs/random.js.map +1 -1
  29. package/lib/commonjs/subtle.js +114 -0
  30. package/lib/commonjs/subtle.js.map +1 -1
  31. package/lib/module/Cipher.js +136 -93
  32. package/lib/module/Cipher.js.map +1 -1
  33. package/lib/module/NativeQuickCrypto/Cipher.js +10 -7
  34. package/lib/module/NativeQuickCrypto/Cipher.js.map +1 -1
  35. package/lib/module/NativeQuickCrypto/sig.js +13 -0
  36. package/lib/module/NativeQuickCrypto/sig.js.map +1 -1
  37. package/lib/module/Utils.js +12 -0
  38. package/lib/module/Utils.js.map +1 -1
  39. package/lib/module/ec.js +76 -93
  40. package/lib/module/ec.js.map +1 -1
  41. package/lib/module/keys.js +8 -24
  42. package/lib/module/keys.js.map +1 -1
  43. package/lib/module/random.js +6 -0
  44. package/lib/module/random.js.map +1 -1
  45. package/lib/module/subtle.js +115 -1
  46. package/lib/module/subtle.js.map +1 -1
  47. package/lib/typescript/Cipher.d.ts +23 -13
  48. package/lib/typescript/Cipher.d.ts.map +1 -1
  49. package/lib/typescript/NativeQuickCrypto/Cipher.d.ts +11 -6
  50. package/lib/typescript/NativeQuickCrypto/Cipher.d.ts.map +1 -1
  51. package/lib/typescript/NativeQuickCrypto/sig.d.ts +10 -0
  52. package/lib/typescript/NativeQuickCrypto/sig.d.ts.map +1 -1
  53. package/lib/typescript/NativeQuickCrypto/webcrypto.d.ts +2 -0
  54. package/lib/typescript/NativeQuickCrypto/webcrypto.d.ts.map +1 -1
  55. package/lib/typescript/Utils.d.ts +1 -0
  56. package/lib/typescript/Utils.d.ts.map +1 -1
  57. package/lib/typescript/ec.d.ts +3 -1
  58. package/lib/typescript/ec.d.ts.map +1 -1
  59. package/lib/typescript/index.d.ts +11 -8
  60. package/lib/typescript/index.d.ts.map +1 -1
  61. package/lib/typescript/keys.d.ts +12 -1
  62. package/lib/typescript/keys.d.ts.map +1 -1
  63. package/lib/typescript/random.d.ts +2 -1
  64. package/lib/typescript/random.d.ts.map +1 -1
  65. package/lib/typescript/subtle.d.ts +4 -1
  66. package/lib/typescript/subtle.d.ts.map +1 -1
  67. package/package.json +1 -1
  68. package/src/Cipher.ts +139 -75
  69. package/src/NativeQuickCrypto/Cipher.ts +14 -14
  70. package/src/NativeQuickCrypto/sig.ts +27 -0
  71. package/src/NativeQuickCrypto/webcrypto.ts +2 -0
  72. package/src/Utils.ts +12 -0
  73. package/src/ec.ts +114 -90
  74. package/src/keys.ts +26 -31
  75. package/src/random.ts +12 -1
  76. package/src/subtle.ts +157 -1
@@ -69,6 +69,46 @@ class SignBase : public MGLSmartHostObject {
69
69
  EVPMDPointer mdctx_;
70
70
  };
71
71
 
72
+ struct SignConfiguration final { // : public MemoryRetainer
73
+ enum Mode {
74
+ kSign,
75
+ kVerify
76
+ };
77
+ enum Flags {
78
+ kHasNone = 0,
79
+ kHasSaltLength = 1,
80
+ kHasPadding = 2
81
+ };
82
+
83
+ // CryptoJobMode job_mode; // all async for now
84
+ Mode mode;
85
+ ManagedEVPPKey key;
86
+ ByteSource data;
87
+ ByteSource signature;
88
+ const EVP_MD* digest = nullptr;
89
+ int flags = SignConfiguration::kHasNone;
90
+ int padding = 0;
91
+ int salt_length = 0;
92
+ DSASigEnc dsa_encoding = kSigEncDER;
93
+
94
+ SignConfiguration() = default;
95
+
96
+ // explicit SignConfiguration(SignConfiguration&& other) noexcept;
97
+
98
+ // SignConfiguration& operator=(SignConfiguration&& other) noexcept;
99
+
100
+ // void MemoryInfo(MemoryTracker* tracker) const override;
101
+ // SET_MEMORY_INFO_NAME(SignConfiguration)
102
+ // SET_SELF_SIZE(SignConfiguration)
103
+ };
104
+
105
+ class SubtleSignVerify {
106
+ public:
107
+ SignConfiguration GetParamsFromJS(jsi::Runtime &rt, const jsi::Value *args);
108
+ void DoSignVerify(jsi::Runtime &rt, const SignConfiguration &params, ByteSource &out);
109
+ jsi::Value EncodeOutput(jsi::Runtime &rt,const SignConfiguration &params, ByteSource &out);
110
+ };
111
+
72
112
  class MGLSignHostObject : public SignBase {
73
113
  public:
74
114
  explicit MGLSignHostObject(
@@ -18,47 +18,6 @@ namespace margelo {
18
18
 
19
19
  namespace jsi = facebook::jsi;
20
20
 
21
- jsi::Value toJSI(jsi::Runtime& rt, OptionJSVariant& value) {
22
- if (!value.has_value()) {
23
- return jsi::Value::null();
24
- }
25
- try {
26
- return toJSI(rt, value.value());
27
- } catch (const std::bad_optional_access& e) {
28
- std::cout << e.what() << '\n';
29
- }
30
- return jsi::Value::null();
31
- }
32
-
33
- jsi::Value toJSI(jsi::Runtime& rt, JSVariant& value) {
34
- if (std::holds_alternative<bool>(value)) {
35
- return jsi::Value(std::get<bool>(value));
36
- } else if (std::holds_alternative<int>(value)) {
37
- return jsi::Value(std::get<int>(value));
38
- } else if (std::holds_alternative<long long>(value)) {
39
- return jsi::Value(static_cast<double>(std::get<long long>(value)));
40
- } else if (std::holds_alternative<double>(value)) {
41
- return jsi::Value(std::get<double>(value));
42
- } else if (std::holds_alternative<std::string>(value)) {
43
- return jsi::String::createFromUtf8(rt, std::get<std::string>(value));
44
- } else if (std::holds_alternative<ByteSource>(value)) {
45
- ByteSource& source = std::get<ByteSource>(value);
46
- jsi::Function array_buffer_ctor =
47
- rt.global().getPropertyAsFunction(rt, "ArrayBuffer");
48
- jsi::Object o = array_buffer_ctor.callAsConstructor(rt, (int)source.size())
49
- .getObject(rt);
50
- jsi::ArrayBuffer buf = o.getArrayBuffer(rt);
51
- // You cannot share raw memory between native and JS
52
- // always copy the data
53
- // see https://github.com/facebook/hermes/pull/419 and
54
- // https://github.com/facebook/hermes/issues/564.
55
- memcpy(buf.data(rt), source.data(), source.size());
56
- return o;
57
- }
58
-
59
- return jsi::Value::null();
60
- }
61
-
62
21
  ByteSource ArrayBufferToByteSource(jsi::Runtime& runtime,
63
22
  const jsi::ArrayBuffer& buffer) {
64
23
  if (buffer.size(runtime) == 0) return ByteSource();
@@ -263,13 +263,23 @@ std::string StringBytesWrite(jsi::Runtime &rt,
263
263
  enum encoding encoding);
264
264
 
265
265
 
266
- using JSVariant = std::variant<nullptr_t, bool, int, double, long, long long,
267
- std::string, ByteSource>;
268
-
269
- using OptionJSVariant = std::optional<JSVariant>;
266
+ inline jsi::Value toJSI(jsi::Runtime& rt, std::string value) {
267
+ return jsi::String::createFromUtf8(rt, value);
268
+ }
270
269
 
271
- jsi::Value toJSI(jsi::Runtime& rt, OptionJSVariant& value);
272
- jsi::Value toJSI(jsi::Runtime& rt, JSVariant& value);
270
+ inline jsi::Value toJSI(jsi::Runtime& rt, ByteSource value) {
271
+ jsi::Function array_buffer_ctor =
272
+ rt.global().getPropertyAsFunction(rt, "ArrayBuffer");
273
+ jsi::Object o = array_buffer_ctor.callAsConstructor(rt, (int)value.size())
274
+ .getObject(rt);
275
+ jsi::ArrayBuffer buf = o.getArrayBuffer(rt);
276
+ // You cannot share raw memory between native and JS
277
+ // always copy the data
278
+ // see https://github.com/facebook/hermes/pull/419 and
279
+ // https://github.com/facebook/hermes/issues/564.
280
+ memcpy(buf.data(rt), value.data(), value.size());
281
+ return o;
282
+ }
273
283
 
274
284
  std::string EncodeBignum(const BIGNUM* bn,
275
285
  int size,
@@ -278,6 +288,17 @@ std::string EncodeBignum(const BIGNUM* bn,
278
288
  std::string EncodeBase64(const std::string data, bool url = false);
279
289
  std::string DecodeBase64(const std::string &in, bool remove_linebreaks = false);
280
290
 
291
+ // TODO: until shared, keep in sync with JS side (src/NativeQuickCrypto/Cipher.ts)
292
+ enum KeyVariant {
293
+ kvRSA_SSA_PKCS1_v1_5,
294
+ kvRSA_PSS,
295
+ kvRSA_OAEP,
296
+ kvDSA,
297
+ kvEC,
298
+ kvNID,
299
+ kvDH,
300
+ };
301
+
281
302
  } // namespace margelo
282
303
 
283
304
  #endif /* MGLUtils_h */
@@ -13,11 +13,13 @@
13
13
 
14
14
  #ifdef ANDROID
15
15
  #include "JSIUtils/MGLJSIMacros.h"
16
- #include "webcrypto/crypto_ec.h"
16
+ #include "Sig/MGLSignHostObjects.h"
17
17
  #include "Utils/MGLUtils.h"
18
+ #include "webcrypto/crypto_ec.h"
18
19
  #else
19
- #include "MGLUtils.h"
20
20
  #include "MGLJSIMacros.h"
21
+ #include "MGLSignHostObjects.h"
22
+ #include "MGLUtils.h"
21
23
  #include "crypto_ec.h"
22
24
  #endif
23
25
 
@@ -48,14 +50,22 @@ jsi::Value createWebCryptoObject(jsi::Runtime &rt) {
48
50
  if (status != WebCryptoKeyExportStatus::OK) {
49
51
  throw jsi::JSError(rt, "error exporting key, status: " + std::to_string(static_cast<int>(status)));
50
52
  }
51
- JSVariant jsv = JSVariant(std::move(out));
52
- return toJSI(rt, jsv);
53
+ return toJSI(rt, std::move(out));
54
+ });
55
+
56
+ auto signVerify = HOSTFN("signVerify", 4) {
57
+ auto ssv = SubtleSignVerify();
58
+ auto params = ssv.GetParamsFromJS(rt, args);
59
+ ByteSource out;
60
+ ssv.DoSignVerify(rt, params, out);
61
+ return ssv.EncodeOutput(rt, params, out);
53
62
  });
54
63
 
55
64
  obj.setProperty(rt,
56
65
  "createKeyObjectHandle",
57
66
  std::move(createKeyObjectHandle));
58
67
  obj.setProperty(rt, "ecExportKey", std::move(ecExportKey));
68
+ obj.setProperty(rt, "signVerify", std::move(signVerify));
59
69
  return obj;
60
70
  };
61
71
 
@@ -331,4 +331,110 @@ jsi::Value GetEcKeyDetail(jsi::Runtime &rt,
331
331
  return target;
332
332
  }
333
333
 
334
+ EcKeyPairGenConfig prepareEcKeyGenConfig(jsi::Runtime &rt,
335
+ const jsi::Value *args)
336
+ {
337
+ EcKeyPairGenConfig config = EcKeyPairGenConfig();
338
+
339
+ // curve name
340
+ std::string curveName = args[1].asString(rt).utf8(rt);
341
+ config.curve_nid = GetCurveFromName(curveName.c_str());
342
+
343
+ // encoding
344
+ if (CheckIsInt32(args[2].asNumber())) {
345
+ int encoding = static_cast<int>(args[2].asNumber());
346
+ if (encoding != OPENSSL_EC_NAMED_CURVE &&
347
+ encoding != OPENSSL_EC_EXPLICIT_CURVE) {
348
+ throw jsi::JSError(rt, "Invalid param_encoding specified");
349
+ } else {
350
+ config.param_encoding = encoding;
351
+ }
352
+ } else {
353
+ throw jsi::JSError(rt, "Invalid param_encoding specified (not int)");
354
+ }
355
+
356
+ // rest of args for encoding
357
+ unsigned int offset = 3;
358
+
359
+ config.public_key_encoding = ManagedEVPPKey::GetPublicKeyEncodingFromJs(
360
+ rt, args, &offset, kKeyContextGenerate);
361
+
362
+ auto private_key_encoding = ManagedEVPPKey::GetPrivateKeyEncodingFromJs(
363
+ rt, args, &offset, kKeyContextGenerate);
364
+
365
+ if (!private_key_encoding.IsEmpty()) {
366
+ config.private_key_encoding = private_key_encoding.Release();
367
+ }
368
+
369
+ return config;
370
+ }
371
+
372
+ EVPKeyCtxPointer setup(std::shared_ptr<EcKeyPairGenConfig> config) {
373
+ EVPKeyCtxPointer key_ctx;
374
+ switch (config->curve_nid) {
375
+ case EVP_PKEY_ED25519:
376
+ // Fall through
377
+ case EVP_PKEY_ED448:
378
+ // Fall through
379
+ case EVP_PKEY_X25519:
380
+ // Fall through
381
+ case EVP_PKEY_X448:
382
+ key_ctx.reset(EVP_PKEY_CTX_new_id(config->curve_nid, nullptr));
383
+ break;
384
+ default: {
385
+ EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
386
+ EVP_PKEY* raw_params = nullptr;
387
+ if (!param_ctx ||
388
+ EVP_PKEY_paramgen_init(param_ctx.get()) <= 0 ||
389
+ EVP_PKEY_CTX_set_ec_paramgen_curve_nid(
390
+ param_ctx.get(), config->curve_nid) <= 0 ||
391
+ EVP_PKEY_CTX_set_ec_param_enc(
392
+ param_ctx.get(), config->param_encoding) <= 0 ||
393
+ EVP_PKEY_paramgen(param_ctx.get(), &raw_params) <= 0) {
394
+ return EVPKeyCtxPointer();
395
+ }
396
+ EVPKeyPointer key_params(raw_params);
397
+ key_ctx.reset(EVP_PKEY_CTX_new(key_params.get(), nullptr));
398
+ }
399
+ }
400
+
401
+ if (key_ctx && EVP_PKEY_keygen_init(key_ctx.get()) <= 0)
402
+ key_ctx.reset();
403
+
404
+ return key_ctx;
405
+ }
406
+
407
+ std::pair<jsi::Value, jsi::Value> generateEcKeyPair(jsi::Runtime& runtime,
408
+ std::shared_ptr<EcKeyPairGenConfig> config)
409
+ {
410
+ // TODO: this is all copied from MGLRsa.cpp - template it up like Node?
411
+
412
+ EVPKeyCtxPointer ctx = setup(config);
413
+
414
+ if (!ctx) {
415
+ throw jsi::JSError(runtime, "Error on key generation job");
416
+ }
417
+
418
+ // Generate the key
419
+ EVP_PKEY* pkey = nullptr;
420
+ if (!EVP_PKEY_keygen(ctx.get(), &pkey)) {
421
+ throw jsi::JSError(runtime, "Error generating key");
422
+ }
423
+
424
+ config->key = ManagedEVPPKey(EVPKeyPointer(pkey));
425
+
426
+ jsi::Value publicBuffer =
427
+ ManagedEVPPKey::ToEncodedPublicKey(runtime, std::move(config->key),
428
+ config->public_key_encoding);
429
+ jsi::Value privateBuffer =
430
+ ManagedEVPPKey::ToEncodedPrivateKey(runtime, std::move(config->key),
431
+ config->private_key_encoding);
432
+
433
+ if (publicBuffer.isUndefined() || privateBuffer.isUndefined()) {
434
+ throw jsi::JSError(runtime, "Failed to encode public and/or private key (EC)");
435
+ }
436
+
437
+ return {std::move(publicBuffer), std::move(privateBuffer)};
438
+ }
439
+
334
440
  } // namespace margelo
@@ -15,9 +15,11 @@
15
15
  #ifdef ANDROID
16
16
  #include "Utils/MGLUtils.h"
17
17
  #include "webcrypto/MGLWebCrypto.h"
18
+ #include "JSIUtils/MGLJSIUtils.h"
18
19
  #else
19
20
  #include "MGLUtils.h"
20
21
  #include "MGLWebCrypto.h"
22
+ #include "MGLJSIUtils.h"
21
23
  #endif
22
24
 
23
25
 
@@ -60,6 +62,22 @@ std::shared_ptr<KeyObjectData> ImportJWKEcKey(jsi::Runtime &rt,
60
62
  jsi::Value GetEcKeyDetail(jsi::Runtime &rt,
61
63
  std::shared_ptr<KeyObjectData> key);
62
64
 
65
+ struct EcKeyPairGenConfig {
66
+ PublicKeyEncodingConfig public_key_encoding;
67
+ PrivateKeyEncodingConfig private_key_encoding;
68
+ ManagedEVPPKey key;
69
+
70
+ int curve_nid;
71
+ int param_encoding;
72
+ };
73
+
74
+ EcKeyPairGenConfig prepareEcKeyGenConfig(jsi::Runtime& runtime,
75
+ const jsi::Value* arguments);
76
+
77
+ std::pair<jsi::Value, jsi::Value> generateEcKeyPair(jsi::Runtime& runtime,
78
+ std::shared_ptr<EcKeyPairGenConfig> config);
79
+
80
+
63
81
  } // namespace margelo
64
82
 
65
83
  #endif /* crypto_ec_hpp */
@@ -3,11 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.ECCurve = void 0;
6
7
  exports.createCipher = createCipher;
7
8
  exports.createCipheriv = createCipheriv;
8
9
  exports.createDecipher = createDecipher;
9
10
  exports.createDecipheriv = createDecipheriv;
10
- exports.generateKeyPair = generateKeyPair;
11
+ exports.generateKeyPairPromise = exports.generateKeyPair = void 0;
11
12
  exports.generateKeyPairSync = generateKeyPairSync;
12
13
  exports.publicEncrypt = exports.publicDecrypt = exports.privateDecrypt = void 0;
13
14
  var _NativeQuickCrypto = require("./NativeQuickCrypto/NativeQuickCrypto");
@@ -21,8 +22,11 @@ var _constants = require("./constants");
21
22
  var _keys = require("./keys");
22
23
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
24
  // @types/node
24
-
25
- // make sure that nextTick is there
25
+ let ECCurve = exports.ECCurve = /*#__PURE__*/function (ECCurve) {
26
+ ECCurve[ECCurve["OPENSSL_EC_EXPLICIT_CURVE"] = 0] = "OPENSSL_EC_EXPLICIT_CURVE";
27
+ ECCurve[ECCurve["OPENSSL_EC_NAMED_CURVE"] = 1] = "OPENSSL_EC_NAMED_CURVE";
28
+ return ECCurve;
29
+ }({}); // make sure that nextTick is there
26
30
  global.process.nextTick = setImmediate;
27
31
  const createInternalCipher = _NativeQuickCrypto.NativeQuickCrypto.createCipher;
28
32
  const createInternalDecipher = _NativeQuickCrypto.NativeQuickCrypto.createDecipher;
@@ -252,9 +256,11 @@ function parseKeyEncoding(keyType, options = _Utils.kEmptyObject) {
252
256
  }
253
257
  return [publicFormat, publicType, privateFormat, privateType, cipher, passphrase];
254
258
  }
259
+
260
+ /** On node a very complex "job" chain is created, we are going for a far simpler approach and calling
261
+ * an internal function that basically executes the same byte shuffling on the native side
262
+ */
255
263
  function internalGenerateKeyPair(isAsync, type, options, callback) {
256
- // On node a very complex "job" chain is created, we are going for a far simpler approach and calling
257
- // an internal function that basically executes the same byte shuffling on the native side
258
264
  const encoding = parseKeyEncoding(type, options);
259
265
 
260
266
  // if (options !== undefined)
@@ -262,84 +268,83 @@ function internalGenerateKeyPair(isAsync, type, options, callback) {
262
268
 
263
269
  switch (type) {
264
270
  case 'rsa-pss':
271
+ // fallthrough
265
272
  case 'rsa':
266
- {
267
- (0, _Utils.validateObject)(options, 'options');
268
- const {
269
- modulusLength
270
- } = options;
271
- (0, _Utils.validateUint32)(modulusLength, 'options.modulusLength');
272
- let {
273
- publicExponent
274
- } = options;
275
- if (publicExponent == null) {
276
- publicExponent = 0x10001;
277
- } else {
278
- (0, _Utils.validateUint32)(publicExponent, 'options.publicExponent');
279
- }
280
- if (type === 'rsa') {
281
- if (isAsync) {
282
- _NativeQuickCrypto.NativeQuickCrypto.generateKeyPair(_Cipher.RSAKeyVariant.kKeyVariantRSA_SSA_PKCS1_v1_5, modulusLength, publicExponent, ...encoding).then(([err, publicKey, privateKey]) => {
283
- if (typeof publicKey === 'object') {
284
- publicKey = _reactNativeBuffer.Buffer.from(publicKey);
285
- }
286
- if (typeof privateKey === 'object') {
287
- privateKey = _reactNativeBuffer.Buffer.from(privateKey);
288
- }
289
- callback?.(err, publicKey, privateKey);
290
- }).catch(err => {
291
- callback?.(err, undefined, undefined);
292
- });
293
- return;
294
- } else {
295
- let [err, publicKey, privateKey] = _NativeQuickCrypto.NativeQuickCrypto.generateKeyPairSync(_Cipher.RSAKeyVariant.kKeyVariantRSA_SSA_PKCS1_v1_5, modulusLength, publicExponent, ...encoding);
296
- if (typeof publicKey === 'object') {
273
+ (0, _Utils.validateObject)(options, 'options');
274
+ const {
275
+ modulusLength
276
+ } = options;
277
+ (0, _Utils.validateUint32)(modulusLength, 'options.modulusLength');
278
+ let {
279
+ publicExponent
280
+ } = options;
281
+ if (publicExponent == null) {
282
+ publicExponent = 0x10001;
283
+ } else {
284
+ (0, _Utils.validateUint32)(publicExponent, 'options.publicExponent');
285
+ }
286
+ if (type === 'rsa') {
287
+ if (isAsync) {
288
+ _NativeQuickCrypto.NativeQuickCrypto.generateKeyPair(_Cipher.KeyVariant.RSA_SSA_PKCS1_v1_5, modulusLength, publicExponent, ...encoding).then(([err, publicKey, privateKey]) => {
289
+ if (publicKey instanceof _reactNativeBuffer.Buffer) {
297
290
  publicKey = _reactNativeBuffer.Buffer.from(publicKey);
298
291
  }
299
- if (typeof privateKey === 'object') {
292
+ if (privateKey instanceof _reactNativeBuffer.Buffer) {
300
293
  privateKey = _reactNativeBuffer.Buffer.from(privateKey);
301
294
  }
302
- return [err, publicKey, privateKey];
295
+ callback(err, publicKey, privateKey);
296
+ }).catch(err => {
297
+ callback(err, undefined, undefined);
298
+ });
299
+ } else {
300
+ let [err, publicKey, privateKey] = _NativeQuickCrypto.NativeQuickCrypto.generateKeyPairSync(_Cipher.KeyVariant.RSA_SSA_PKCS1_v1_5, modulusLength, publicExponent, ...encoding);
301
+ if (publicKey instanceof _reactNativeBuffer.Buffer) {
302
+ publicKey = _reactNativeBuffer.Buffer.from(publicKey);
303
+ }
304
+ if (privateKey instanceof _reactNativeBuffer.Buffer) {
305
+ privateKey = _reactNativeBuffer.Buffer.from(privateKey);
303
306
  }
307
+ return [err, publicKey, privateKey];
304
308
  }
305
- const {
306
- hash,
307
- mgf1Hash,
308
- hashAlgorithm,
309
- mgf1HashAlgorithm,
310
- saltLength
311
- } = options;
309
+ }
310
+ const {
311
+ hash,
312
+ mgf1Hash,
313
+ hashAlgorithm,
314
+ mgf1HashAlgorithm,
315
+ saltLength
316
+ } = options;
312
317
 
313
- // // We don't have a process object on RN
314
- // // const pendingDeprecation = getOptionValue('--pending-deprecation');
318
+ // // We don't have a process object on RN
319
+ // // const pendingDeprecation = getOptionValue('--pending-deprecation');
315
320
 
316
- if (saltLength !== undefined) (0, _Utils.validateInt32)(saltLength, 'options.saltLength', 0);
317
- if (hashAlgorithm !== undefined) (0, _Utils.validateString)(hashAlgorithm, 'options.hashAlgorithm');
318
- if (mgf1HashAlgorithm !== undefined) (0, _Utils.validateString)(mgf1HashAlgorithm, 'options.mgf1HashAlgorithm');
319
- if (hash !== undefined) {
320
- // pendingDeprecation && process.emitWarning(
321
- // '"options.hash" is deprecated, ' +
322
- // 'use "options.hashAlgorithm" instead.',
323
- // 'DeprecationWarning',
324
- // 'DEP0154');
325
- (0, _Utils.validateString)(hash, 'options.hash');
326
- if (hashAlgorithm && hash !== hashAlgorithm) {
327
- throw new Error(`Invalid Argument options.hash ${hash}`);
328
- }
321
+ if (saltLength !== undefined) (0, _Utils.validateInt32)(saltLength, 'options.saltLength', 0);
322
+ if (hashAlgorithm !== undefined) (0, _Utils.validateString)(hashAlgorithm, 'options.hashAlgorithm');
323
+ if (mgf1HashAlgorithm !== undefined) (0, _Utils.validateString)(mgf1HashAlgorithm, 'options.mgf1HashAlgorithm');
324
+ if (hash !== undefined) {
325
+ // pendingDeprecation && process.emitWarning(
326
+ // '"options.hash" is deprecated, ' +
327
+ // 'use "options.hashAlgorithm" instead.',
328
+ // 'DeprecationWarning',
329
+ // 'DEP0154');
330
+ (0, _Utils.validateString)(hash, 'options.hash');
331
+ if (hashAlgorithm && hash !== hashAlgorithm) {
332
+ throw new Error(`Invalid Argument options.hash ${hash}`);
329
333
  }
330
- if (mgf1Hash !== undefined) {
331
- // pendingDeprecation && process.emitWarning(
332
- // '"options.mgf1Hash" is deprecated, ' +
333
- // 'use "options.mgf1HashAlgorithm" instead.',
334
- // 'DeprecationWarning',
335
- // 'DEP0154');
336
- (0, _Utils.validateString)(mgf1Hash, 'options.mgf1Hash');
337
- if (mgf1HashAlgorithm && mgf1Hash !== mgf1HashAlgorithm) {
338
- throw new Error(`Invalid Argument options.mgf1Hash ${mgf1Hash}`);
339
- }
334
+ }
335
+ if (mgf1Hash !== undefined) {
336
+ // pendingDeprecation && process.emitWarning(
337
+ // '"options.mgf1Hash" is deprecated, ' +
338
+ // 'use "options.mgf1HashAlgorithm" instead.',
339
+ // 'DeprecationWarning',
340
+ // 'DEP0154');
341
+ (0, _Utils.validateString)(mgf1Hash, 'options.mgf1Hash');
342
+ if (mgf1HashAlgorithm && mgf1Hash !== mgf1HashAlgorithm) {
343
+ throw new Error(`Invalid Argument options.mgf1Hash ${mgf1Hash}`);
340
344
  }
341
- return _NativeQuickCrypto.NativeQuickCrypto.generateKeyPairSync(_Cipher.RSAKeyVariant.kKeyVariantRSA_PSS, modulusLength, publicExponent, hashAlgorithm || hash, mgf1HashAlgorithm || mgf1Hash, saltLength, ...encoding);
342
345
  }
346
+ return _NativeQuickCrypto.NativeQuickCrypto.generateKeyPairSync(_Cipher.KeyVariant.RSA_PSS, modulusLength, publicExponent, hashAlgorithm || hash, mgf1HashAlgorithm || mgf1Hash, saltLength, ...encoding);
347
+
343
348
  // case 'dsa': {
344
349
  // validateObject(options, 'options');
345
350
  // const { modulusLength } = options!;
@@ -356,21 +361,40 @@ function internalGenerateKeyPair(isAsync, type, options, callback) {
356
361
  // // divisorLength,
357
362
  // // ...encoding);
358
363
  // }
359
- // case 'ec': {
360
- // validateObject(options, 'options');
361
- // const { namedCurve } = options!;
362
- // validateString(namedCurve, 'options.namedCurve');
363
- // let { paramEncoding } = options!;
364
- // if (paramEncoding == null || paramEncoding === 'named')
365
- // paramEncoding = OPENSSL_EC_NAMED_CURVE;
366
- // else if (paramEncoding === 'explicit')
367
- // paramEncoding = OPENSSL_EC_EXPLICIT_CURVE;
368
- // else
369
- // throw new Error(`Invalid Argument options.paramEncoding ${paramEncoding}`);
370
- // // throw new ERR_INVALID_ARG_VALUE('options.paramEncoding', paramEncoding);
371
364
 
372
- // // return new EcKeyPairGenJob(mode, namedCurve, paramEncoding, ...encoding);
373
- // }
365
+ case 'ec':
366
+ (0, _Utils.validateObject)(options, 'options');
367
+ const {
368
+ namedCurve
369
+ } = options;
370
+ (0, _Utils.validateString)(namedCurve, 'options.namedCurve');
371
+ let paramEncodingFlag = ECCurve.OPENSSL_EC_NAMED_CURVE;
372
+ const {
373
+ paramEncoding
374
+ } = options;
375
+ if (paramEncoding == null || paramEncoding === 'named') paramEncodingFlag = ECCurve.OPENSSL_EC_NAMED_CURVE;else if (paramEncoding === 'explicit') paramEncodingFlag = ECCurve.OPENSSL_EC_EXPLICIT_CURVE;else throw new Error(`Invalid Argument options.paramEncoding ${paramEncoding}`);
376
+ if (isAsync) {
377
+ _NativeQuickCrypto.NativeQuickCrypto.generateKeyPair(_Cipher.KeyVariant.EC, namedCurve, paramEncodingFlag, ...encoding).then(([err, publicKey, privateKey]) => {
378
+ if (publicKey instanceof _reactNativeBuffer.Buffer) {
379
+ publicKey = _reactNativeBuffer.Buffer.from(publicKey);
380
+ }
381
+ if (privateKey instanceof _reactNativeBuffer.Buffer) {
382
+ privateKey = _reactNativeBuffer.Buffer.from(privateKey);
383
+ }
384
+ callback?.(err, publicKey, privateKey);
385
+ }).catch(err => {
386
+ callback?.(err, undefined, undefined);
387
+ });
388
+ }
389
+ let [err, publicKey, privateKey] = _NativeQuickCrypto.NativeQuickCrypto.generateKeyPairSync(_Cipher.KeyVariant.EC, namedCurve, paramEncodingFlag, ...encoding);
390
+ if (publicKey instanceof _reactNativeBuffer.Buffer) {
391
+ publicKey = _reactNativeBuffer.Buffer.from(publicKey);
392
+ }
393
+ if (privateKey instanceof _reactNativeBuffer.Buffer) {
394
+ privateKey = _reactNativeBuffer.Buffer.from(privateKey);
395
+ }
396
+ return [err, publicKey, privateKey];
397
+
374
398
  // case 'ed25519':
375
399
  // case 'ed448':
376
400
  // case 'x25519':
@@ -434,19 +458,38 @@ function internalGenerateKeyPair(isAsync, type, options, callback) {
434
458
  default:
435
459
  // Fall through
436
460
  }
437
- throw new Error(`Invalid Argument options: ${type} scheme not supported. Currently not all encryption methods are supported in quick-crypto!`);
461
+ const err = new Error(`
462
+ Invalid Argument options: '${type}' scheme not supported for generateKey().
463
+ Currently not all encryption methods are supported in quick-crypto. Check
464
+ implementation_coverage.md for status.
465
+ `);
466
+ return [err, undefined, undefined];
438
467
  }
439
-
440
- // TODO(osp) put correct types (e.g. type -> 'rsa', etc..)
441
-
442
- function generateKeyPair(type, options, callback) {
443
- if (typeof options === 'function') {
444
- callback = options;
445
- options = undefined;
446
- }
468
+ const generateKeyPair = (type, options, callback) => {
447
469
  (0, _Utils.validateFunction)(callback);
448
470
  internalGenerateKeyPair(true, type, options, callback);
449
- }
471
+ };
472
+
473
+ // Promisify generateKeyPair
474
+ // (attempted to use util.promisify, to no avail)
475
+ exports.generateKeyPair = generateKeyPair;
476
+ const generateKeyPairPromise = (type, options) => {
477
+ return new Promise((resolve, reject) => {
478
+ generateKeyPair(type, options, (err, publicKey, privateKey) => {
479
+ if (err) {
480
+ reject([err, undefined]);
481
+ } else {
482
+ resolve([undefined, {
483
+ publicKey,
484
+ privateKey
485
+ }]);
486
+ }
487
+ });
488
+ });
489
+ };
490
+
491
+ // generateKeyPairSync
492
+ exports.generateKeyPairPromise = generateKeyPairPromise;
450
493
  function generateKeyPairSync(type, options) {
451
494
  const [_, publicKey, privateKey] = internalGenerateKeyPair(false, type, options, undefined);
452
495
  return {