react-native-quick-crypto 0.6.1 → 0.7.0-rc.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 (196) 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/wrapper/gradle-wrapper.properties +1 -1
  5. package/android/gradle.properties +5 -5
  6. package/android/src/main/{AndroidManifest.xml → AndroidManifestNew.xml} +1 -2
  7. package/cpp/Cipher/MGLCipherHostObject.cpp +31 -5
  8. package/cpp/Cipher/MGLGenerateKeyPairInstaller.cpp +21 -31
  9. package/cpp/Cipher/MGLGenerateKeyPairSyncInstaller.cpp +4 -17
  10. package/cpp/Cipher/MGLPublicCipher.h +1 -1
  11. package/cpp/Cipher/MGLPublicCipherInstaller.h +6 -6
  12. package/cpp/Cipher/MGLRsa.cpp +224 -11
  13. package/cpp/Cipher/MGLRsa.h +13 -3
  14. package/cpp/Hash/MGLHashHostObject.cpp +1 -1
  15. package/cpp/Hash/MGLHashInstaller.cpp +2 -4
  16. package/cpp/JSIUtils/MGLJSIMacros.h +10 -0
  17. package/cpp/JSIUtils/MGLThreadAwareHostObject.h +1 -1
  18. package/cpp/MGLKeys.cpp +415 -471
  19. package/cpp/MGLKeys.h +70 -2
  20. package/cpp/MGLQuickCryptoHostObject.cpp +9 -0
  21. package/cpp/Random/MGLRandomHostObject.cpp +9 -2
  22. package/cpp/Sig/MGLSignHostObjects.cpp +1 -1
  23. package/cpp/Utils/MGLUtils.cpp +104 -32
  24. package/cpp/Utils/MGLUtils.h +172 -143
  25. package/cpp/Utils/node.h +13 -0
  26. package/cpp/webcrypto/MGLWebCrypto.cpp +63 -0
  27. package/cpp/webcrypto/MGLWebCrypto.h +34 -0
  28. package/cpp/webcrypto/crypto_ec.cpp +334 -0
  29. package/cpp/webcrypto/crypto_ec.h +65 -0
  30. package/ios/QuickCrypto.xcodeproj/project.pbxproj +4 -4
  31. package/lib/commonjs/@types/crypto-browserify.d.js.map +1 -1
  32. package/lib/commonjs/Cipher.js +53 -194
  33. package/lib/commonjs/Cipher.js.map +1 -1
  34. package/lib/commonjs/Hash.js +29 -29
  35. package/lib/commonjs/Hash.js.map +1 -1
  36. package/lib/commonjs/Hashnames.js +75 -0
  37. package/lib/commonjs/Hashnames.js.map +1 -0
  38. package/lib/commonjs/Hmac.js +6 -29
  39. package/lib/commonjs/Hmac.js.map +1 -1
  40. package/lib/commonjs/NativeQuickCrypto/Cipher.js +3 -5
  41. package/lib/commonjs/NativeQuickCrypto/Cipher.js.map +1 -1
  42. package/lib/commonjs/NativeQuickCrypto/NativeQuickCrypto.js +11 -20
  43. package/lib/commonjs/NativeQuickCrypto/NativeQuickCrypto.js.map +1 -1
  44. package/lib/commonjs/NativeQuickCrypto/hash.js.map +1 -1
  45. package/lib/commonjs/NativeQuickCrypto/hmac.js.map +1 -1
  46. package/lib/commonjs/NativeQuickCrypto/pbkdf2.js.map +1 -1
  47. package/lib/commonjs/NativeQuickCrypto/random.js.map +1 -1
  48. package/lib/commonjs/NativeQuickCrypto/sig.js.map +1 -1
  49. package/lib/commonjs/NativeQuickCrypto/webcrypto.js +6 -0
  50. package/lib/commonjs/NativeQuickCrypto/webcrypto.js.map +1 -0
  51. package/lib/commonjs/QuickCrypto.js +5 -14
  52. package/lib/commonjs/QuickCrypto.js.map +1 -1
  53. package/lib/commonjs/Utils.js +360 -48
  54. package/lib/commonjs/Utils.js.map +1 -1
  55. package/lib/commonjs/aes.js +324 -0
  56. package/lib/commonjs/aes.js.map +1 -0
  57. package/lib/commonjs/constants.js +1 -2
  58. package/lib/commonjs/constants.js.map +1 -1
  59. package/lib/commonjs/ec.js +288 -0
  60. package/lib/commonjs/ec.js.map +1 -0
  61. package/lib/commonjs/index.js +6 -10
  62. package/lib/commonjs/index.js.map +1 -1
  63. package/lib/commonjs/keys.js +280 -48
  64. package/lib/commonjs/keys.js.map +1 -1
  65. package/lib/commonjs/pbkdf2.js +44 -18
  66. package/lib/commonjs/pbkdf2.js.map +1 -1
  67. package/lib/commonjs/random.js +49 -68
  68. package/lib/commonjs/random.js.map +1 -1
  69. package/lib/commonjs/rsa.js +329 -0
  70. package/lib/commonjs/rsa.js.map +1 -0
  71. package/lib/commonjs/sig.js +13 -54
  72. package/lib/commonjs/sig.js.map +1 -1
  73. package/lib/commonjs/subtle.js +271 -0
  74. package/lib/commonjs/subtle.js.map +1 -0
  75. package/lib/module/@types/crypto-browserify.d.js.map +1 -1
  76. package/lib/module/Cipher.js +53 -188
  77. package/lib/module/Cipher.js.map +1 -1
  78. package/lib/module/Hash.js +27 -21
  79. package/lib/module/Hash.js.map +1 -1
  80. package/lib/module/Hashnames.js +71 -0
  81. package/lib/module/Hashnames.js.map +1 -0
  82. package/lib/module/Hmac.js +4 -21
  83. package/lib/module/Hmac.js.map +1 -1
  84. package/lib/module/NativeQuickCrypto/Cipher.js +3 -4
  85. package/lib/module/NativeQuickCrypto/Cipher.js.map +1 -1
  86. package/lib/module/NativeQuickCrypto/NativeQuickCrypto.js +11 -17
  87. package/lib/module/NativeQuickCrypto/NativeQuickCrypto.js.map +1 -1
  88. package/lib/module/NativeQuickCrypto/hash.js.map +1 -1
  89. package/lib/module/NativeQuickCrypto/hmac.js.map +1 -1
  90. package/lib/module/NativeQuickCrypto/pbkdf2.js.map +1 -1
  91. package/lib/module/NativeQuickCrypto/random.js.map +1 -1
  92. package/lib/module/NativeQuickCrypto/sig.js.map +1 -1
  93. package/lib/module/NativeQuickCrypto/webcrypto.js +2 -0
  94. package/lib/module/NativeQuickCrypto/webcrypto.js.map +1 -0
  95. package/lib/module/QuickCrypto.js +2 -0
  96. package/lib/module/QuickCrypto.js.map +1 -1
  97. package/lib/module/Utils.js +319 -33
  98. package/lib/module/Utils.js.map +1 -1
  99. package/lib/module/aes.js +317 -0
  100. package/lib/module/aes.js.map +1 -0
  101. package/lib/module/constants.js.map +1 -1
  102. package/lib/module/ec.js +282 -0
  103. package/lib/module/ec.js.map +1 -0
  104. package/lib/module/index.js +7 -4
  105. package/lib/module/index.js.map +1 -1
  106. package/lib/module/keys.js +279 -43
  107. package/lib/module/keys.js.map +1 -1
  108. package/lib/module/pbkdf2.js +44 -13
  109. package/lib/module/pbkdf2.js.map +1 -1
  110. package/lib/module/random.js +46 -54
  111. package/lib/module/random.js.map +1 -1
  112. package/lib/module/rsa.js +323 -0
  113. package/lib/module/rsa.js.map +1 -0
  114. package/lib/module/sig.js +13 -46
  115. package/lib/module/sig.js.map +1 -1
  116. package/lib/module/subtle.js +265 -0
  117. package/lib/module/subtle.js.map +1 -0
  118. package/lib/typescript/src/Cipher.d.ts +72 -0
  119. package/lib/typescript/src/Cipher.d.ts.map +1 -0
  120. package/lib/typescript/{Hash.d.ts → src/Hash.d.ts} +8 -7
  121. package/lib/typescript/src/Hash.d.ts.map +1 -0
  122. package/lib/typescript/src/Hashnames.d.ts +11 -0
  123. package/lib/typescript/src/Hashnames.d.ts.map +1 -0
  124. package/lib/typescript/{Hmac.d.ts → src/Hmac.d.ts} +3 -3
  125. package/lib/typescript/src/Hmac.d.ts.map +1 -0
  126. package/lib/typescript/src/NativeQuickCrypto/Cipher.d.ts +34 -0
  127. package/lib/typescript/src/NativeQuickCrypto/Cipher.d.ts.map +1 -0
  128. package/lib/typescript/{NativeQuickCrypto → src/NativeQuickCrypto}/NativeQuickCrypto.d.ts +3 -0
  129. package/lib/typescript/src/NativeQuickCrypto/NativeQuickCrypto.d.ts.map +1 -0
  130. package/lib/typescript/src/NativeQuickCrypto/hash.d.ts +7 -0
  131. package/lib/typescript/src/NativeQuickCrypto/hash.d.ts.map +1 -0
  132. package/lib/typescript/src/NativeQuickCrypto/hmac.d.ts +6 -0
  133. package/lib/typescript/src/NativeQuickCrypto/hmac.d.ts.map +1 -0
  134. package/lib/typescript/{NativeQuickCrypto → src/NativeQuickCrypto}/pbkdf2.d.ts +2 -1
  135. package/lib/typescript/src/NativeQuickCrypto/pbkdf2.d.ts.map +1 -0
  136. package/lib/typescript/{NativeQuickCrypto → src/NativeQuickCrypto}/random.d.ts +2 -1
  137. package/lib/typescript/src/NativeQuickCrypto/random.d.ts.map +1 -0
  138. package/lib/typescript/{NativeQuickCrypto → src/NativeQuickCrypto}/sig.d.ts +5 -4
  139. package/lib/typescript/src/NativeQuickCrypto/sig.d.ts.map +1 -0
  140. package/lib/typescript/src/NativeQuickCrypto/webcrypto.d.ts +27 -0
  141. package/lib/typescript/src/NativeQuickCrypto/webcrypto.d.ts.map +1 -0
  142. package/lib/typescript/{QuickCrypto.d.ts → src/QuickCrypto.d.ts} +16 -8
  143. package/lib/typescript/src/QuickCrypto.d.ts.map +1 -0
  144. package/lib/typescript/src/Utils.d.ts +44 -0
  145. package/lib/typescript/src/Utils.d.ts.map +1 -0
  146. package/lib/typescript/src/aes.d.ts +5 -0
  147. package/lib/typescript/src/aes.d.ts.map +1 -0
  148. package/lib/typescript/{constants.d.ts → src/constants.d.ts} +1 -0
  149. package/lib/typescript/src/constants.d.ts.map +1 -0
  150. package/lib/typescript/src/ec.d.ts +5 -0
  151. package/lib/typescript/src/ec.d.ts.map +1 -0
  152. package/lib/typescript/{index.d.ts → src/index.d.ts} +33 -27
  153. package/lib/typescript/src/index.d.ts.map +1 -0
  154. package/lib/typescript/src/keys.d.ts +154 -0
  155. package/lib/typescript/src/keys.d.ts.map +1 -0
  156. package/lib/typescript/src/pbkdf2.d.ts +12 -0
  157. package/lib/typescript/src/pbkdf2.d.ts.map +1 -0
  158. package/lib/typescript/{random.d.ts → src/random.d.ts} +7 -6
  159. package/lib/typescript/src/random.d.ts.map +1 -0
  160. package/lib/typescript/src/rsa.d.ts +4 -0
  161. package/lib/typescript/src/rsa.d.ts.map +1 -0
  162. package/lib/typescript/{sig.d.ts → src/sig.d.ts} +3 -3
  163. package/lib/typescript/src/sig.d.ts.map +1 -0
  164. package/lib/typescript/src/subtle.d.ts +11 -0
  165. package/lib/typescript/src/subtle.d.ts.map +1 -0
  166. package/package.json +35 -30
  167. package/react-native-quick-crypto.podspec +4 -3
  168. package/src/Cipher.ts +103 -100
  169. package/src/Hash.ts +42 -6
  170. package/src/Hashnames.ts +91 -0
  171. package/src/Hmac.ts +3 -3
  172. package/src/NativeQuickCrypto/Cipher.ts +1 -0
  173. package/src/NativeQuickCrypto/NativeQuickCrypto.ts +2 -0
  174. package/src/NativeQuickCrypto/webcrypto.ts +46 -0
  175. package/src/QuickCrypto.ts +2 -0
  176. package/src/Utils.ts +409 -5
  177. package/src/aes.ts +365 -0
  178. package/src/ec.ts +351 -0
  179. package/src/keys.ts +428 -54
  180. package/src/pbkdf2.ts +84 -11
  181. package/src/random.ts +37 -24
  182. package/src/rsa.ts +396 -0
  183. package/src/sig.ts +3 -2
  184. package/src/subtle.ts +358 -0
  185. package/lib/commonjs/@types/stream-browserify.d.js +0 -2
  186. package/lib/commonjs/@types/stream-browserify.d.js.map +0 -1
  187. package/lib/module/@types/stream-browserify.d.js +0 -2
  188. package/lib/module/@types/stream-browserify.d.js.map +0 -1
  189. package/lib/typescript/Cipher.d.ts +0 -87
  190. package/lib/typescript/NativeQuickCrypto/Cipher.d.ts +0 -32
  191. package/lib/typescript/NativeQuickCrypto/hash.d.ts +0 -6
  192. package/lib/typescript/NativeQuickCrypto/hmac.d.ts +0 -5
  193. package/lib/typescript/Utils.d.ts +0 -23
  194. package/lib/typescript/keys.d.ts +0 -60
  195. package/lib/typescript/pbkdf2.d.ts +0 -9
  196. package/src/@types/stream-browserify.d.ts +0 -4
@@ -46,7 +46,7 @@ FieldDefinition getGenerateKeyPairFieldDefinition(
46
46
  runtime,
47
47
  jsi::Function::createFromHostFunction(
48
48
  runtime, jsi::PropNameID::forAscii(runtime, "executor"), 2,
49
- [arguments, &jsCallInvoker, config](
49
+ [&jsCallInvoker, config](
50
50
  jsi::Runtime &runtime, const jsi::Value &,
51
51
  const jsi::Value *promiseArgs, size_t) -> jsi::Value {
52
52
  auto resolve =
@@ -54,43 +54,33 @@ FieldDefinition getGenerateKeyPairFieldDefinition(
54
54
  auto reject =
55
55
  std::make_shared<jsi::Value>(runtime, promiseArgs[1]);
56
56
 
57
- std::thread t([&runtime, arguments, resolve, reject,
57
+ std::thread t([&runtime, resolve, reject,
58
58
  jsCallInvoker, config]() {
59
59
  m.lock();
60
60
  try {
61
- const auto keys = generateRSAKeyPair(runtime, config);
62
- jsCallInvoker->invokeAsync([&runtime, keys, jsCallInvoker,
63
- resolve]() {
64
- if (keys.first.isString && keys.second.isString) {
65
- auto publicKey = jsi::String::createFromUtf8(
66
- runtime, keys.first.stringValue);
67
- auto privateKey = jsi::String::createFromUtf8(
68
- runtime, keys.second.stringValue);
69
- auto res = jsi::Array::createWithElements(
70
- runtime, jsi::Value::undefined(), publicKey,
71
- privateKey);
72
- resolve->asObject(runtime).asFunction(runtime).call(
73
- runtime, std::move(res));
74
- } else {
75
- MGLTypedArray<MGLTypedArrayKind::Uint8Array>
76
- publicKeyBuffer(runtime, keys.first.vectorValue);
77
- MGLTypedArray<MGLTypedArrayKind::Uint8Array>
78
- privateKeyBuffer(runtime,
79
- keys.second.vectorValue);
80
-
81
- auto res = jsi::Array::createWithElements(
82
- runtime, jsi::Value::undefined(), publicKeyBuffer,
83
- privateKeyBuffer);
84
- resolve->asObject(runtime).asFunction(runtime).call(
85
- runtime, std::move(res));
86
- }
61
+ jsCallInvoker->invokeAsync([&runtime, config, resolve]() {
62
+ auto keys = generateRSAKeyPair(runtime, config);
63
+ auto publicKey = toJSI(runtime, keys.first);
64
+ auto privateKey = toJSI(runtime, keys.second);
65
+ auto res = jsi::Array::createWithElements(
66
+ runtime,
67
+ jsi::Value::undefined(),
68
+ publicKey,
69
+ privateKey);
70
+ resolve->asObject(runtime).asFunction(runtime).call(
71
+ runtime, std::move(res));
87
72
  });
88
73
  } catch (std::exception e) {
89
74
  jsCallInvoker->invokeAsync(
90
- [&runtime, &jsCallInvoker, reject]() {
75
+ [&runtime, reject]() {
76
+ auto res = jsi::Array::createWithElements(
77
+ runtime,
78
+ jsi::String::createFromUtf8(
79
+ runtime, "Error generating key"),
80
+ jsi::Value::undefined(),
81
+ jsi::Value::undefined());
91
82
  reject->asObject(runtime).asFunction(runtime).call(
92
- runtime, jsi::String::createFromUtf8(
93
- runtime, "Error generating key"));
83
+ runtime, std::move(res));
94
84
  });
95
85
  }
96
86
  m.unlock();
@@ -38,23 +38,10 @@ FieldDefinition getGenerateKeyPairSyncFieldDefinition(
38
38
  auto config = std::make_shared<RsaKeyPairGenConfig>(
39
39
  prepareRsaKeyGenConfig(runtime, arguments));
40
40
  auto keys = generateRSAKeyPair(runtime, std::move(config));
41
- if (keys.first.isString && keys.second.isString) {
42
- auto publicKey =
43
- jsi::String::createFromUtf8(runtime, keys.first.stringValue);
44
- auto privateKey =
45
- jsi::String::createFromUtf8(runtime, keys.second.stringValue);
46
- return jsi::Array::createWithElements(
47
- runtime, jsi::Value::undefined(), publicKey, privateKey);
48
- } else {
49
- MGLTypedArray<MGLTypedArrayKind::Uint8Array> publicKeyBuffer(
50
- runtime, keys.first.vectorValue);
51
- MGLTypedArray<MGLTypedArrayKind::Uint8Array> privateKeyBuffer(
52
- runtime, keys.second.vectorValue);
53
-
54
- return jsi::Array::createWithElements(
55
- runtime, jsi::Value::undefined(), publicKeyBuffer,
56
- privateKeyBuffer);
57
- }
41
+ auto publicKey = toJSI(runtime, keys.first);
42
+ auto privateKey = toJSI(runtime, keys.second);
43
+ return jsi::Array::createWithElements(
44
+ runtime, jsi::Value::undefined(), publicKey, privateKey);
58
45
  });
59
46
  }
60
47
  } // namespace margelo
@@ -82,7 +82,7 @@ std::optional<jsi::Value> MGLPublicCipher::Cipher(jsi::Runtime& runtime,
82
82
  void* label = OPENSSL_memdup(oaep_label_buffer.data(runtime),
83
83
  oaep_label_buffer.size(runtime));
84
84
  if (label == nullptr) {
85
- throw new jsi::JSError(runtime, "Error openSSL memdump oaep label");
85
+ throw jsi::JSError(runtime, "Error openSSL memdump oaep label");
86
86
  }
87
87
 
88
88
  if (0 >= EVP_PKEY_CTX_set0_rsa_oaep_label(
@@ -57,18 +57,18 @@ FieldDefinition getPublicCipherFieldDefinition(
57
57
  runtime, arguments, &offset);
58
58
 
59
59
  if (!pkey) {
60
- throw new jsi::JSError(runtime, "Could not generate key");
60
+ throw jsi::JSError(runtime, "Could not generate key");
61
61
  }
62
62
 
63
63
  auto buf = arguments[offset].asObject(runtime).getArrayBuffer(runtime);
64
64
  if (!CheckSizeInt32(runtime, buf)) {
65
- throw new jsi::JSError(runtime, "Data buffer is too long");
65
+ throw jsi::JSError(runtime, "Data buffer is too long");
66
66
  }
67
67
 
68
68
  uint32_t padding =
69
69
  static_cast<uint32_t>(arguments[offset + 1].getNumber());
70
70
  if (!padding) {
71
- throw new jsi::JSError(runtime, "Invalid padding");
71
+ throw jsi::JSError(runtime, "Invalid padding");
72
72
  }
73
73
 
74
74
  const EVP_MD* digest = nullptr;
@@ -78,7 +78,7 @@ FieldDefinition getPublicCipherFieldDefinition(
78
78
 
79
79
  digest = EVP_get_digestbyname(oaep_str.c_str());
80
80
  if (digest == nullptr) {
81
- throw new jsi::JSError(runtime, "Invalid digest (oaep_str)");
81
+ throw jsi::JSError(runtime, "Invalid digest (oaep_str)");
82
82
  }
83
83
  }
84
84
 
@@ -86,7 +86,7 @@ FieldDefinition getPublicCipherFieldDefinition(
86
86
  auto oaep_label_buffer =
87
87
  arguments[offset + 3].getObject(runtime).getArrayBuffer(runtime);
88
88
  if (!CheckSizeInt32(runtime, oaep_label_buffer)) {
89
- throw new jsi::JSError(runtime, "oaep_label buffer is too long");
89
+ throw jsi::JSError(runtime, "oaep_label buffer is too long");
90
90
  }
91
91
  }
92
92
 
@@ -96,7 +96,7 @@ FieldDefinition getPublicCipherFieldDefinition(
96
96
  runtime, pkey, padding, digest, arguments[offset + 3], buf);
97
97
 
98
98
  if (!out.has_value()) {
99
- throw new jsi::JSError(runtime, "Failed to decrypt");
99
+ throw jsi::JSError(runtime, "Failed to decrypt");
100
100
  }
101
101
 
102
102
  return out.value().getObject(runtime);
@@ -6,7 +6,13 @@
6
6
  //
7
7
 
8
8
  #include "MGLRsa.h"
9
+ #ifdef ANDROID
10
+ #include "JSIUtils/MGLJSIMacros.h"
11
+ #else
12
+ #include "MGLJSIMacros.h"
13
+ #endif
9
14
 
15
+ #include <string>
10
16
  #include <utility>
11
17
 
12
18
  namespace margelo {
@@ -108,7 +114,7 @@ RsaKeyPairGenConfig prepareRsaKeyGenConfig(jsi::Runtime& runtime,
108
114
  arguments[offset].asString(runtime).utf8(runtime).c_str());
109
115
 
110
116
  if (config.md == nullptr) {
111
- throw new jsi::JSError(runtime, "invalid digest");
117
+ throw jsi::JSError(runtime, "invalid digest");
112
118
  }
113
119
  }
114
120
 
@@ -118,7 +124,7 @@ RsaKeyPairGenConfig prepareRsaKeyGenConfig(jsi::Runtime& runtime,
118
124
  arguments[offset + 1].asString(runtime).utf8(runtime).c_str());
119
125
 
120
126
  if (config.mgf1_md == nullptr) {
121
- throw new jsi::JSError(runtime, "invalid digest");
127
+ throw jsi::JSError(runtime, "invalid digest");
122
128
  }
123
129
  }
124
130
 
@@ -127,7 +133,7 @@ RsaKeyPairGenConfig prepareRsaKeyGenConfig(jsi::Runtime& runtime,
127
133
  config.saltlen = static_cast<int>(arguments[offset + 2].asNumber());
128
134
 
129
135
  if (config.saltlen < 0) {
130
- throw new jsi::JSError(runtime, "salt length is out of range");
136
+ throw jsi::JSError(runtime, "salt length is out of range");
131
137
  }
132
138
  }
133
139
 
@@ -147,37 +153,244 @@ RsaKeyPairGenConfig prepareRsaKeyGenConfig(jsi::Runtime& runtime,
147
153
  return config;
148
154
  }
149
155
 
150
- std::pair<StringOrBuffer, StringOrBuffer> generateRSAKeyPair(
156
+ std::pair<JSVariant, JSVariant> generateRSAKeyPair(
151
157
  jsi::Runtime& runtime, std::shared_ptr<RsaKeyPairGenConfig> config) {
152
158
  CheckEntropy();
153
159
 
154
160
  EVPKeyCtxPointer ctx = setup(config);
155
161
 
156
162
  if (!ctx) {
157
- throw new jsi::JSError(runtime, "Error on key generation job");
163
+ throw jsi::JSError(runtime, "Error on key generation job");
158
164
  }
159
165
 
160
166
  // Generate the key
161
167
  EVP_PKEY* pkey = nullptr;
162
168
  if (!EVP_PKEY_keygen(ctx.get(), &pkey)) {
163
- throw new jsi::JSError(runtime, "Error generating key");
169
+ throw jsi::JSError(runtime, "Error generating key");
164
170
  }
165
171
 
166
172
  config->key = ManagedEVPPKey(EVPKeyPointer(pkey));
167
173
 
168
- std::optional<StringOrBuffer> publicBuffer =
174
+ OptionJSVariant publicBuffer =
169
175
  ManagedEVPPKey::ToEncodedPublicKey(runtime, std::move(config->key),
170
176
  config->public_key_encoding);
171
- std::optional<StringOrBuffer> privateBuffer =
177
+ OptionJSVariant privateBuffer =
172
178
  ManagedEVPPKey::ToEncodedPrivateKey(runtime, std::move(config->key),
173
179
  config->private_key_encoding);
174
180
 
175
181
  if (!publicBuffer.has_value() || !privateBuffer.has_value()) {
176
- throw jsi::JSError(runtime,
177
- "Failed to encode public and/or private key");
182
+ throw jsi::JSError(runtime, "Failed to encode public and/or private key");
178
183
  }
179
184
 
180
- return std::make_pair(publicBuffer.value(), privateBuffer.value());
185
+ return {std::move(publicBuffer.value()), std::move(privateBuffer.value())};
186
+ }
187
+
188
+ jsi::Value ExportJWKRsaKey(jsi::Runtime &rt,
189
+ std::shared_ptr<KeyObjectData> key,
190
+ jsi::Object &target) {
191
+ ManagedEVPPKey m_pkey = key->GetAsymmetricKey();
192
+ // std::scoped_lock lock(*m_pkey.mutex()); // TODO: mutex/lock required?
193
+ int type = EVP_PKEY_id(m_pkey.get());
194
+ CHECK(type == EVP_PKEY_RSA || type == EVP_PKEY_RSA_PSS);
195
+
196
+ // TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL
197
+ // versions older than 1.1.1e via FIPS / dynamic linking.
198
+ const RSA* rsa;
199
+ if (OpenSSL_version_num() >= 0x1010105fL) {
200
+ rsa = EVP_PKEY_get0_RSA(m_pkey.get());
201
+ } else {
202
+ rsa = static_cast<const RSA*>(EVP_PKEY_get0(m_pkey.get()));
203
+ }
204
+ CHECK_NOT_NULL(rsa);
205
+
206
+ const BIGNUM* n;
207
+ const BIGNUM* e;
208
+ const BIGNUM* d;
209
+ const BIGNUM* p;
210
+ const BIGNUM* q;
211
+ const BIGNUM* dp;
212
+ const BIGNUM* dq;
213
+ const BIGNUM* qi;
214
+ RSA_get0_key(rsa, &n, &e, &d);
215
+
216
+ target.setProperty(rt, "kty", "RSA");
217
+ target.setProperty(rt, "n", EncodeBignum(n, 0, true));
218
+ target.setProperty(rt, "e", EncodeBignum(e, 0, true));
219
+
220
+ if (key->GetKeyType() == kKeyTypePrivate) {
221
+ RSA_get0_factors(rsa, &p, &q);
222
+ RSA_get0_crt_params(rsa, &dp, &dq, &qi);
223
+ target.setProperty(rt, "d", EncodeBignum(d, 0, true));
224
+ target.setProperty(rt, "p", EncodeBignum(p, 0, true));
225
+ target.setProperty(rt, "q", EncodeBignum(q, 0, true));
226
+ target.setProperty(rt, "dp", EncodeBignum(dp, 0, true));
227
+ target.setProperty(rt, "dq", EncodeBignum(dq, 0, true));
228
+ target.setProperty(rt, "qi", EncodeBignum(qi, 0, true));
229
+ }
230
+
231
+ return std::move(target);
232
+ }
233
+
234
+ std::shared_ptr<KeyObjectData> ImportJWKRsaKey(jsi::Runtime &rt,
235
+ jsi::Object &jwk) {
236
+ jsi::Value n_value = jwk.getProperty(rt, "n");
237
+ jsi::Value e_value = jwk.getProperty(rt, "e");
238
+ jsi::Value d_value = jwk.getProperty(rt, "d");
239
+
240
+ if (!n_value.isString() ||
241
+ !e_value.isString()) {
242
+ throw jsi::JSError(rt, "Invalid JWK RSA key");
243
+ return std::shared_ptr<KeyObjectData>();
244
+ }
245
+
246
+ if (!d_value.isUndefined() && !d_value.isString()) {
247
+ throw jsi::JSError(rt, "Invalid JWK RSA key");
248
+ return std::shared_ptr<KeyObjectData>();
249
+ }
250
+
251
+ KeyType type = d_value.isString() ? kKeyTypePrivate : kKeyTypePublic;
252
+
253
+ RsaPointer rsa(RSA_new());
254
+
255
+ ByteSource n = ByteSource::FromEncodedString(rt, n_value.asString(rt).utf8(rt));
256
+ ByteSource e = ByteSource::FromEncodedString(rt, e_value.asString(rt).utf8(rt));
257
+
258
+ if (!RSA_set0_key(
259
+ rsa.get(),
260
+ n.ToBN().release(),
261
+ e.ToBN().release(),
262
+ nullptr)) {
263
+ throw jsi::JSError(rt, "Invalid JWK RSA key");
264
+ return std::shared_ptr<KeyObjectData>();
265
+ }
266
+
267
+ if (type == kKeyTypePrivate) {
268
+ jsi::Value p_value = jwk.getProperty(rt, "p");
269
+ jsi::Value q_value = jwk.getProperty(rt, "q");
270
+ jsi::Value dp_value = jwk.getProperty(rt, "dp");
271
+ jsi::Value dq_value = jwk.getProperty(rt, "dq");
272
+ jsi::Value qi_value = jwk.getProperty(rt, "qi");
273
+
274
+ if (!p_value.isString() ||
275
+ !q_value.isString() ||
276
+ !dp_value.isString() ||
277
+ !dq_value.isString() ||
278
+ !qi_value.isString()) {
279
+ throw jsi::JSError(rt, "Invalid JWK RSA key");
280
+ return std::shared_ptr<KeyObjectData>();
281
+ }
282
+
283
+ ByteSource d = ByteSource::FromEncodedString(rt, d_value.asString(rt).utf8(rt));
284
+ ByteSource q = ByteSource::FromEncodedString(rt, q_value.asString(rt).utf8(rt));
285
+ ByteSource p = ByteSource::FromEncodedString(rt, p_value.asString(rt).utf8(rt));
286
+ ByteSource dp = ByteSource::FromEncodedString(rt, dp_value.asString(rt).utf8(rt));
287
+ ByteSource dq = ByteSource::FromEncodedString(rt, dq_value.asString(rt).utf8(rt));
288
+ ByteSource qi = ByteSource::FromEncodedString(rt, qi_value.asString(rt).utf8(rt));
289
+
290
+ if (!RSA_set0_key(rsa.get(), nullptr, nullptr, d.ToBN().release()) ||
291
+ !RSA_set0_factors(rsa.get(), p.ToBN().release(), q.ToBN().release()) ||
292
+ !RSA_set0_crt_params(
293
+ rsa.get(),
294
+ dp.ToBN().release(),
295
+ dq.ToBN().release(),
296
+ qi.ToBN().release())) {
297
+ throw jsi::JSError(rt, "Invalid JWK RSA key");
298
+ return std::shared_ptr<KeyObjectData>();
299
+ }
300
+ }
301
+
302
+ EVPKeyPointer pkey(EVP_PKEY_new());
303
+ CHECK_EQ(EVP_PKEY_set1_RSA(pkey.get(), rsa.get()), 1);
304
+
305
+ return KeyObjectData::CreateAsymmetric(type, ManagedEVPPKey(std::move(pkey)));
306
+ }
307
+
308
+ jsi::Value GetRsaKeyDetail(jsi::Runtime &rt,
309
+ std::shared_ptr<KeyObjectData> key) {
310
+ jsi::Object target = jsi::Object(rt);
311
+ const BIGNUM* e; // Public Exponent
312
+ const BIGNUM* n; // Modulus
313
+
314
+ ManagedEVPPKey m_pkey = key->GetAsymmetricKey();
315
+ // std::scoped_lock lock(*m_pkey.mutex()); // TODO: mutex/lock required?
316
+ int type = EVP_PKEY_id(m_pkey.get());
317
+ CHECK(type == EVP_PKEY_RSA || type == EVP_PKEY_RSA_PSS);
318
+
319
+ // TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL
320
+ // versions older than 1.1.1e via FIPS / dynamic linking.
321
+ const RSA* rsa;
322
+ if (OpenSSL_version_num() >= 0x1010105fL) {
323
+ rsa = EVP_PKEY_get0_RSA(m_pkey.get());
324
+ } else {
325
+ rsa = static_cast<const RSA*>(EVP_PKEY_get0(m_pkey.get()));
326
+ }
327
+ CHECK_NOT_NULL(rsa);
328
+
329
+ RSA_get0_key(rsa, &n, &e, nullptr);
330
+
331
+ size_t modulus_length = BN_num_bits(n);
332
+ // TODO: should this be modulusLength or n?
333
+ target.setProperty(rt, "modulusLength", static_cast<double>(modulus_length));
334
+
335
+ size_t exp_size = BN_num_bytes(e);
336
+ // TODO: should this be publicExponent or e?
337
+ target.setProperty(rt, "publicExponent", EncodeBignum(e, exp_size, true));
338
+
339
+ if (type == EVP_PKEY_RSA_PSS) {
340
+ // Due to the way ASN.1 encoding works, default values are omitted when
341
+ // encoding the data structure. However, there are also RSA-PSS keys for
342
+ // which no parameters are set. In that case, the ASN.1 RSASSA-PSS-params
343
+ // sequence will be missing entirely and RSA_get0_pss_params will return
344
+ // nullptr. If parameters are present but all parameters are set to their
345
+ // default values, an empty sequence will be stored in the ASN.1 structure.
346
+ // In that case, RSA_get0_pss_params does not return nullptr but all fields
347
+ // of the returned RSA_PSS_PARAMS will be set to nullptr.
348
+
349
+ const RSA_PSS_PARAMS* params = RSA_get0_pss_params(rsa);
350
+ if (params != nullptr) {
351
+ int hash_nid = NID_sha1;
352
+ int mgf_nid = NID_mgf1;
353
+ int mgf1_hash_nid = NID_sha1;
354
+ int64_t salt_length = 20;
355
+
356
+ if (params->hashAlgorithm != nullptr) {
357
+ const ASN1_OBJECT* hash_obj;
358
+ X509_ALGOR_get0(&hash_obj, nullptr, nullptr, params->hashAlgorithm);
359
+ hash_nid = OBJ_obj2nid(hash_obj);
360
+ }
361
+
362
+ target.setProperty(rt, "hashAlgorithm", std::string(OBJ_nid2ln(hash_nid)));
363
+
364
+ if (params->maskGenAlgorithm != nullptr) {
365
+ const ASN1_OBJECT* mgf_obj;
366
+ X509_ALGOR_get0(&mgf_obj, nullptr, nullptr, params->maskGenAlgorithm);
367
+ mgf_nid = OBJ_obj2nid(mgf_obj);
368
+ if (mgf_nid == NID_mgf1) {
369
+ const ASN1_OBJECT* mgf1_hash_obj;
370
+ X509_ALGOR_get0(&mgf1_hash_obj, nullptr, nullptr, params->maskHash);
371
+ mgf1_hash_nid = OBJ_obj2nid(mgf1_hash_obj);
372
+ }
373
+ }
374
+
375
+ // If, for some reason, the MGF is not MGF1, then the MGF1 hash function
376
+ // is intentionally not added to the object.
377
+ if (mgf_nid == NID_mgf1) {
378
+ target.setProperty(rt, "mgf1HashAlgorithm", std::string(OBJ_nid2ln(mgf1_hash_nid)));
379
+ }
380
+
381
+ if (params->saltLength != nullptr) {
382
+ if (ASN1_INTEGER_get_int64(&salt_length, params->saltLength) != 1) {
383
+ throw jsi::JSError(rt, "ASN1_INTEGER_get_in64 error: " +
384
+ std::to_string(ERR_get_error()));
385
+ return target;
386
+ }
387
+ }
388
+
389
+ target.setProperty(rt, "saltLength", static_cast<double>(salt_length));
390
+ }
391
+ }
392
+
393
+ return target;
181
394
  }
182
395
 
183
396
  } // namespace margelo
@@ -35,7 +35,7 @@ enum RSAKeyVariant {
35
35
  // initialize the data in a generic manner this is to be later be used to
36
36
  // generate the keys in a thread-safe manner (I think) I'm however too dumb and
37
37
  // after ~4hrs I have given up on trying to replicate/extract the important
38
- // parts For now I'm storing a single config param, a generic abstractino is
38
+ // parts For now I'm storing a single config param, a generic abstraction is
39
39
  // necessary for more schemes. this struct is just a very simplified version
40
40
  // meant to carry information around
41
41
  struct RsaKeyPairGenConfig {
@@ -55,11 +55,21 @@ struct RsaKeyPairGenConfig {
55
55
  };
56
56
 
57
57
  RsaKeyPairGenConfig prepareRsaKeyGenConfig(jsi::Runtime& runtime,
58
- const jsi::Value* arguments);
58
+ const jsi::Value* arguments);
59
59
 
60
- std::pair<StringOrBuffer, StringOrBuffer> generateRSAKeyPair(
60
+ std::pair<JSVariant, JSVariant> generateRSAKeyPair(
61
61
  jsi::Runtime& runtime, std::shared_ptr<RsaKeyPairGenConfig> config);
62
62
 
63
+ jsi::Value ExportJWKRsaKey(jsi::Runtime &rt,
64
+ std::shared_ptr<KeyObjectData> key,
65
+ jsi::Object &target);
66
+
67
+ std::shared_ptr<KeyObjectData> ImportJWKRsaKey(jsi::Runtime &rt,
68
+ jsi::Object &jwk);
69
+
70
+ jsi::Value GetRsaKeyDetail(jsi::Runtime &rt,
71
+ std::shared_ptr<KeyObjectData> key);
72
+
63
73
  } // namespace margelo
64
74
 
65
75
  #endif /* MGLRsa_hpp */
@@ -67,7 +67,7 @@ void MGLHashHostObject::installMethods() {
67
67
  if (!arguments[0].isObject() ||
68
68
  !arguments[0].getObject(runtime).isArrayBuffer(runtime)) {
69
69
  throw jsi::JSError(runtime,
70
- "HmacHostObject::update: First argument ('message') "
70
+ "HashHostObject::update: First argument ('message') "
71
71
  "has to be of type ArrayBuffer!");
72
72
  }
73
73
  auto messageBuffer =
@@ -1,5 +1,5 @@
1
1
  //
2
- // HMAC-JSI-Installer.m
2
+ // Hash-JSI-Installer.m
3
3
  // PinkPanda
4
4
  //
5
5
  // Created by Marc Rousavy on 31.10.21.
@@ -7,8 +7,6 @@
7
7
 
8
8
  #include "MGLHashInstaller.h"
9
9
 
10
- #include <openssl/hmac.h>
11
-
12
10
  #include <memory>
13
11
 
14
12
  #ifdef ANDROID
@@ -29,7 +27,7 @@ FieldDefinition getHashFieldDefinition(
29
27
  // createHash(hashAlgorithm: 'sha1' | 'sha256' | 'sha512')
30
28
  return HOST_LAMBDA("createHash", {
31
29
  if (count != 1 && count != 2) {
32
- throw jsi::JSError(runtime, "createHmac(..) expects 1-2 arguments!");
30
+ throw jsi::JSError(runtime, "createHash(..) expects 1-2 arguments!");
33
31
  }
34
32
 
35
33
  auto hashAlgorithm = arguments[0].asString(runtime).utf8(runtime);
@@ -32,6 +32,16 @@ inline void Assert(const AssertionInfo &info) {
32
32
  Abort();
33
33
  }
34
34
 
35
+ #define HOSTFN(name, basecount) \
36
+ jsi::Function::createFromHostFunction( \
37
+ rt, \
38
+ jsi::PropNameID::forAscii(rt, name), \
39
+ basecount, \
40
+ [=](jsi::Runtime &rt, \
41
+ const jsi::Value &thisValue, \
42
+ const jsi::Value *args, \
43
+ size_t count) -> jsi::Value
44
+
35
45
  #define HOST_LAMBDA(name, body) HOST_LAMBDA_CAP(name, [=], body)
36
46
 
37
47
  #define HOST_LAMBDA_CAP(name, capture, body) \
@@ -10,7 +10,7 @@
10
10
 
11
11
  #include <memory>
12
12
 
13
- #ifdef ONANDROID
13
+ #ifdef ANDROID
14
14
  #include "Utils/MGLDispatchQueue.h"
15
15
  #else
16
16
  #include "MGLDispatchQueue.h"