react-native-quick-crypto 0.7.0-rc.8 → 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.
- package/cpp/Cipher/MGLGenerateKeyPairInstaller.cpp +51 -14
- package/cpp/Cipher/MGLGenerateKeyPairSyncInstaller.cpp +25 -9
- package/cpp/Cipher/MGLRsa.cpp +13 -12
- package/cpp/Cipher/MGLRsa.h +2 -8
- package/cpp/JSIUtils/MGLJSIUtils.h +9 -0
- package/cpp/MGLKeys.cpp +174 -149
- package/cpp/MGLKeys.h +18 -13
- package/cpp/Sig/MGLSignHostObjects.cpp +284 -421
- package/cpp/Sig/MGLSignHostObjects.h +40 -0
- package/cpp/Utils/MGLUtils.cpp +0 -41
- package/cpp/Utils/MGLUtils.h +27 -6
- package/cpp/webcrypto/MGLWebCrypto.cpp +14 -4
- package/cpp/webcrypto/crypto_ec.cpp +106 -0
- package/cpp/webcrypto/crypto_ec.h +18 -0
- package/lib/commonjs/Cipher.js +138 -95
- package/lib/commonjs/Cipher.js.map +1 -1
- package/lib/commonjs/NativeQuickCrypto/Cipher.js +11 -8
- package/lib/commonjs/NativeQuickCrypto/Cipher.js.map +1 -1
- package/lib/commonjs/NativeQuickCrypto/sig.js +17 -0
- package/lib/commonjs/NativeQuickCrypto/sig.js.map +1 -1
- package/lib/commonjs/Utils.js +15 -1
- package/lib/commonjs/Utils.js.map +1 -1
- package/lib/commonjs/ec.js +79 -91
- package/lib/commonjs/ec.js.map +1 -1
- package/lib/commonjs/keys.js +28 -39
- package/lib/commonjs/keys.js.map +1 -1
- package/lib/commonjs/random.js +0 -1
- package/lib/commonjs/random.js.map +1 -1
- package/lib/commonjs/subtle.js +114 -0
- package/lib/commonjs/subtle.js.map +1 -1
- package/lib/module/Cipher.js +136 -93
- package/lib/module/Cipher.js.map +1 -1
- package/lib/module/NativeQuickCrypto/Cipher.js +10 -7
- package/lib/module/NativeQuickCrypto/Cipher.js.map +1 -1
- package/lib/module/NativeQuickCrypto/sig.js +13 -0
- package/lib/module/NativeQuickCrypto/sig.js.map +1 -1
- package/lib/module/Utils.js +12 -0
- package/lib/module/Utils.js.map +1 -1
- package/lib/module/ec.js +76 -93
- package/lib/module/ec.js.map +1 -1
- package/lib/module/keys.js +26 -39
- package/lib/module/keys.js.map +1 -1
- package/lib/module/random.js +0 -1
- package/lib/module/random.js.map +1 -1
- package/lib/module/subtle.js +115 -1
- package/lib/module/subtle.js.map +1 -1
- package/lib/typescript/Cipher.d.ts +23 -13
- package/lib/typescript/Cipher.d.ts.map +1 -1
- package/lib/typescript/NativeQuickCrypto/Cipher.d.ts +11 -6
- package/lib/typescript/NativeQuickCrypto/Cipher.d.ts.map +1 -1
- package/lib/typescript/NativeQuickCrypto/sig.d.ts +10 -0
- package/lib/typescript/NativeQuickCrypto/sig.d.ts.map +1 -1
- package/lib/typescript/NativeQuickCrypto/webcrypto.d.ts +2 -0
- package/lib/typescript/NativeQuickCrypto/webcrypto.d.ts.map +1 -1
- package/lib/typescript/Utils.d.ts +3 -1
- package/lib/typescript/Utils.d.ts.map +1 -1
- package/lib/typescript/ec.d.ts +3 -1
- package/lib/typescript/ec.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +10 -7
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/keys.d.ts +12 -1
- package/lib/typescript/keys.d.ts.map +1 -1
- package/lib/typescript/random.d.ts +1 -1
- package/lib/typescript/random.d.ts.map +1 -1
- package/lib/typescript/subtle.d.ts +4 -1
- package/lib/typescript/subtle.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Cipher.ts +139 -75
- package/src/NativeQuickCrypto/Cipher.ts +14 -14
- package/src/NativeQuickCrypto/sig.ts +27 -0
- package/src/NativeQuickCrypto/webcrypto.ts +2 -0
- package/src/Utils.ts +24 -1
- package/src/ec.ts +114 -90
- package/src/keys.ts +53 -57
- package/src/random.ts +1 -11
- package/src/subtle.ts +157 -1
package/src/ec.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { generateKeyPairPromise, type GenerateKeyPairOptions } from './Cipher';
|
|
1
2
|
import { NativeQuickCrypto } from './NativeQuickCrypto/NativeQuickCrypto';
|
|
3
|
+
import { DSASigEnc, SignMode } from './NativeQuickCrypto/sig';
|
|
2
4
|
import {
|
|
3
5
|
bufferLikeToArrayBuffer,
|
|
4
6
|
type BufferLike,
|
|
@@ -8,6 +10,8 @@ import {
|
|
|
8
10
|
validateKeyOps,
|
|
9
11
|
hasAnyNotIn,
|
|
10
12
|
ab2str,
|
|
13
|
+
getUsagesUnion,
|
|
14
|
+
normalizeHashName,
|
|
11
15
|
} from './Utils';
|
|
12
16
|
import {
|
|
13
17
|
type ImportFormat,
|
|
@@ -22,7 +26,9 @@ import {
|
|
|
22
26
|
type AnyAlgorithm,
|
|
23
27
|
PrivateKeyObject,
|
|
24
28
|
KeyType,
|
|
29
|
+
type CryptoKeyPair,
|
|
25
30
|
} from './keys';
|
|
31
|
+
import type { KeyObjectHandle } from './NativeQuickCrypto/webcrypto';
|
|
26
32
|
|
|
27
33
|
// const {
|
|
28
34
|
// ArrayPrototypeIncludes,
|
|
@@ -114,71 +120,6 @@ function createECPublicKeyRaw(
|
|
|
114
120
|
return new PublicKeyObject(handle);
|
|
115
121
|
}
|
|
116
122
|
|
|
117
|
-
// async function ecGenerateKey(algorithm, extractable, keyUsages) {
|
|
118
|
-
// const { name, namedCurve } = algorithm;
|
|
119
|
-
|
|
120
|
-
// if (!ArrayPrototypeIncludes(ObjectKeys(kNamedCurveAliases), namedCurve)) {
|
|
121
|
-
// throw lazyDOMException(
|
|
122
|
-
// 'Unrecognized namedCurve',
|
|
123
|
-
// 'NotSupportedError');
|
|
124
|
-
// }
|
|
125
|
-
|
|
126
|
-
// const usageSet = new SafeSet(keyUsages);
|
|
127
|
-
// switch (name) {
|
|
128
|
-
// case 'ECDSA':
|
|
129
|
-
// if (hasAnyNotIn(usageSet, ['sign', 'verify'])) {
|
|
130
|
-
// throw lazyDOMException(
|
|
131
|
-
// 'Unsupported key usage for an ECDSA key',
|
|
132
|
-
// 'SyntaxError');
|
|
133
|
-
// }
|
|
134
|
-
// break;
|
|
135
|
-
// case 'ECDH':
|
|
136
|
-
// if (hasAnyNotIn(usageSet, ['deriveKey', 'deriveBits'])) {
|
|
137
|
-
// throw lazyDOMException(
|
|
138
|
-
// 'Unsupported key usage for an ECDH key',
|
|
139
|
-
// 'SyntaxError');
|
|
140
|
-
// }
|
|
141
|
-
// // Fall through
|
|
142
|
-
// }
|
|
143
|
-
|
|
144
|
-
// const keypair = await generateKeyPair('ec', { namedCurve }).catch((err) => {
|
|
145
|
-
// throw lazyDOMException(
|
|
146
|
-
// 'The operation failed for an operation-specific reason',
|
|
147
|
-
// { name: 'OperationError', cause: err });
|
|
148
|
-
// });
|
|
149
|
-
|
|
150
|
-
// let publicUsages;
|
|
151
|
-
// let privateUsages;
|
|
152
|
-
// switch (name) {
|
|
153
|
-
// case 'ECDSA':
|
|
154
|
-
// publicUsages = getUsagesUnion(usageSet, 'verify');
|
|
155
|
-
// privateUsages = getUsagesUnion(usageSet, 'sign');
|
|
156
|
-
// break;
|
|
157
|
-
// case 'ECDH':
|
|
158
|
-
// publicUsages = [];
|
|
159
|
-
// privateUsages = getUsagesUnion(usageSet, 'deriveKey', 'deriveBits');
|
|
160
|
-
// break;
|
|
161
|
-
// }
|
|
162
|
-
|
|
163
|
-
// const keyAlgorithm = { name, namedCurve };
|
|
164
|
-
|
|
165
|
-
// const publicKey =
|
|
166
|
-
// new InternalCryptoKey(
|
|
167
|
-
// keypair.publicKey,
|
|
168
|
-
// keyAlgorithm,
|
|
169
|
-
// publicUsages,
|
|
170
|
-
// true);
|
|
171
|
-
|
|
172
|
-
// const privateKey =
|
|
173
|
-
// new InternalCryptoKey(
|
|
174
|
-
// keypair.privateKey,
|
|
175
|
-
// keyAlgorithm,
|
|
176
|
-
// privateUsages,
|
|
177
|
-
// extractable);
|
|
178
|
-
|
|
179
|
-
// return { __proto__: null, publicKey, privateKey };
|
|
180
|
-
// }
|
|
181
|
-
|
|
182
123
|
export function ecExportKey(
|
|
183
124
|
key: CryptoKey,
|
|
184
125
|
format: KWebCryptoKeyFormat
|
|
@@ -310,8 +251,8 @@ export function ecImportKey(
|
|
|
310
251
|
case 'ECDSA':
|
|
311
252
|
// Fall through
|
|
312
253
|
case 'ECDH':
|
|
313
|
-
|
|
314
|
-
|
|
254
|
+
if (keyObject.asymmetricKeyType !== 'ec')
|
|
255
|
+
throw new Error('Invalid key type');
|
|
315
256
|
break;
|
|
316
257
|
}
|
|
317
258
|
|
|
@@ -326,26 +267,109 @@ export function ecImportKey(
|
|
|
326
267
|
return new CryptoKey(keyObject, { name, namedCurve }, keyUsages, extractable);
|
|
327
268
|
}
|
|
328
269
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
//
|
|
350
|
-
|
|
351
|
-
|
|
270
|
+
export const ecdsaSignVerify = (
|
|
271
|
+
key: CryptoKey,
|
|
272
|
+
data: BufferLike,
|
|
273
|
+
{ hash }: SubtleAlgorithm,
|
|
274
|
+
signature?: BufferLike
|
|
275
|
+
) => {
|
|
276
|
+
const mode: SignMode =
|
|
277
|
+
signature === undefined
|
|
278
|
+
? SignMode.kSignJobModeSign
|
|
279
|
+
: SignMode.kSignJobModeVerify;
|
|
280
|
+
const type = mode === SignMode.kSignJobModeSign ? 'private' : 'public';
|
|
281
|
+
|
|
282
|
+
if (key.type !== type)
|
|
283
|
+
throw lazyDOMException(`Key must be a ${type} key`, 'InvalidAccessError');
|
|
284
|
+
|
|
285
|
+
const hashname = normalizeHashName(hash);
|
|
286
|
+
|
|
287
|
+
return NativeQuickCrypto.webcrypto.signVerify(
|
|
288
|
+
mode,
|
|
289
|
+
key.keyObject.handle,
|
|
290
|
+
// three undefined args because C++ uses `GetPublicOrPrivateKeyFromJs` & friends
|
|
291
|
+
undefined,
|
|
292
|
+
undefined,
|
|
293
|
+
undefined,
|
|
294
|
+
bufferLikeToArrayBuffer(data),
|
|
295
|
+
hashname,
|
|
296
|
+
undefined, // salt length, not used with ECDSA
|
|
297
|
+
undefined, // pss padding, not used with ECDSA
|
|
298
|
+
DSASigEnc.kSigEncP1363,
|
|
299
|
+
bufferLikeToArrayBuffer(signature || new ArrayBuffer(0))
|
|
300
|
+
);
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
export const ecGenerateKey = async (
|
|
304
|
+
algorithm: SubtleAlgorithm,
|
|
305
|
+
extractable: boolean,
|
|
306
|
+
keyUsages: KeyUsage[]
|
|
307
|
+
): Promise<CryptoKeyPair> => {
|
|
308
|
+
const { name, namedCurve } = algorithm;
|
|
309
|
+
|
|
310
|
+
if (!Object.keys(kNamedCurveAliases).includes(namedCurve || '')) {
|
|
311
|
+
throw lazyDOMException(
|
|
312
|
+
`Unrecognized namedCurve '${namedCurve}'`,
|
|
313
|
+
'NotSupportedError'
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// const usageSet = new SafeSet(keyUsages);
|
|
318
|
+
switch (name) {
|
|
319
|
+
case 'ECDSA':
|
|
320
|
+
const checkUsages = ['sign', 'verify'];
|
|
321
|
+
if (hasAnyNotIn(keyUsages, checkUsages)) {
|
|
322
|
+
throw lazyDOMException(
|
|
323
|
+
'Unsupported key usage for an ECDSA key',
|
|
324
|
+
'SyntaxError'
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
break;
|
|
328
|
+
case 'ECDH':
|
|
329
|
+
if (hasAnyNotIn(keyUsages, ['deriveKey', 'deriveBits'])) {
|
|
330
|
+
throw lazyDOMException(
|
|
331
|
+
'Unsupported key usage for an ECDH key',
|
|
332
|
+
'SyntaxError'
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
// Fall through
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const options: GenerateKeyPairOptions = { namedCurve };
|
|
339
|
+
const [err, keypair] = await generateKeyPairPromise('ec', options);
|
|
340
|
+
|
|
341
|
+
if (err) {
|
|
342
|
+
throw lazyDOMException('ecGenerateKey (generateKeyPairPromise) failed', {
|
|
343
|
+
name: 'OperationError',
|
|
344
|
+
cause: err,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
let publicUsages: KeyUsage[] = [];
|
|
349
|
+
let privateUsages: KeyUsage[] = [];
|
|
350
|
+
switch (name) {
|
|
351
|
+
case 'ECDSA':
|
|
352
|
+
publicUsages = getUsagesUnion(keyUsages, 'verify');
|
|
353
|
+
privateUsages = getUsagesUnion(keyUsages, 'sign');
|
|
354
|
+
break;
|
|
355
|
+
case 'ECDH':
|
|
356
|
+
publicUsages = [];
|
|
357
|
+
privateUsages = getUsagesUnion(keyUsages, 'deriveKey', 'deriveBits');
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const keyAlgorithm = { name, namedCurve };
|
|
362
|
+
|
|
363
|
+
const pub = new PublicKeyObject(keypair?.publicKey as KeyObjectHandle);
|
|
364
|
+
const publicKey = new CryptoKey(pub, keyAlgorithm, publicUsages, true);
|
|
365
|
+
|
|
366
|
+
const priv = new PrivateKeyObject(keypair?.privateKey as KeyObjectHandle);
|
|
367
|
+
const privateKey = new CryptoKey(
|
|
368
|
+
priv,
|
|
369
|
+
keyAlgorithm,
|
|
370
|
+
privateUsages,
|
|
371
|
+
extractable
|
|
372
|
+
);
|
|
373
|
+
|
|
374
|
+
return { publicKey, privateKey };
|
|
375
|
+
};
|
package/src/keys.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from './Utils';
|
|
6
6
|
import type { KeyObjectHandle } from './NativeQuickCrypto/webcrypto';
|
|
7
7
|
import { NativeQuickCrypto } from './NativeQuickCrypto/NativeQuickCrypto';
|
|
8
|
+
import type { KeyPairKey } from './Cipher';
|
|
8
9
|
|
|
9
10
|
export const kNamedCurveAliases = {
|
|
10
11
|
'P-256': 'prime256v1',
|
|
@@ -28,16 +29,16 @@ export type AnyAlgorithm =
|
|
|
28
29
|
|
|
29
30
|
export type HashAlgorithm = 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512';
|
|
30
31
|
|
|
32
|
+
export type KeyPairType = 'rsa' | 'rsa-pss' | 'ec';
|
|
33
|
+
|
|
34
|
+
export type RSAKeyPairAlgorithm = 'RSASSA-PKCS1-v1_5' | 'RSA-PSS' | 'RSA-OAEP';
|
|
35
|
+
export type ECKeyPairAlgorithm = 'ECDSA' | 'ECDH';
|
|
36
|
+
export type CFRGKeyPairAlgorithm = 'Ed25519' | 'Ed448' | 'X25519' | 'X448';
|
|
37
|
+
|
|
31
38
|
export type KeyPairAlgorithm =
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
| 'Ed448'
|
|
36
|
-
| 'RSASSA-PKCS1-v1_5'
|
|
37
|
-
| 'RSA-PSS'
|
|
38
|
-
| 'RSA-OAEP'
|
|
39
|
-
| 'X25519'
|
|
40
|
-
| 'X448';
|
|
39
|
+
| RSAKeyPairAlgorithm
|
|
40
|
+
| ECKeyPairAlgorithm
|
|
41
|
+
| CFRGKeyPairAlgorithm;
|
|
41
42
|
|
|
42
43
|
export type SecretKeyAlgorithm =
|
|
43
44
|
| 'HMAC'
|
|
@@ -175,6 +176,11 @@ const encodingNames = {
|
|
|
175
176
|
[KeyEncoding.kKeyEncodingSEC1]: 'sec1',
|
|
176
177
|
};
|
|
177
178
|
|
|
179
|
+
export type CryptoKeyPair = {
|
|
180
|
+
publicKey: KeyPairKey;
|
|
181
|
+
privateKey: KeyPairKey;
|
|
182
|
+
};
|
|
183
|
+
|
|
178
184
|
function option(name: string, objName: string | undefined) {
|
|
179
185
|
return objName === undefined
|
|
180
186
|
? `options.${name}`
|
|
@@ -417,40 +423,41 @@ export function parsePrivateKeyEncoding(
|
|
|
417
423
|
}
|
|
418
424
|
|
|
419
425
|
function prepareSecretKey(
|
|
420
|
-
key:
|
|
426
|
+
key: BinaryLike,
|
|
421
427
|
encoding?: string,
|
|
422
428
|
bufferOnly = false
|
|
423
429
|
): any {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
if (key
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
if (key
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
430
|
+
try {
|
|
431
|
+
if (!bufferOnly) {
|
|
432
|
+
// TODO: maybe use `key.constructor.name === 'KeyObject'` ?
|
|
433
|
+
if (key instanceof KeyObject) {
|
|
434
|
+
if (key.type !== 'secret')
|
|
435
|
+
throw new Error(
|
|
436
|
+
`invalid KeyObject type: ${key.type}, expected 'secret'`
|
|
437
|
+
);
|
|
438
|
+
return key.handle;
|
|
439
|
+
}
|
|
440
|
+
// TODO: maybe use `key.constructor.name === 'CryptoKey'` ?
|
|
441
|
+
else if (key instanceof CryptoKey) {
|
|
442
|
+
if (key.type !== 'secret')
|
|
443
|
+
throw new Error(
|
|
444
|
+
`invalid CryptoKey type: ${key.type}, expected 'secret'`
|
|
445
|
+
);
|
|
446
|
+
return key.keyObject.handle;
|
|
447
|
+
}
|
|
440
448
|
}
|
|
441
|
-
}
|
|
442
449
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
450
|
+
if (key instanceof ArrayBuffer) {
|
|
451
|
+
return key;
|
|
452
|
+
}
|
|
446
453
|
|
|
447
|
-
if (typeof key === 'string') {
|
|
448
454
|
return binaryLikeToArrayBuffer(key, encoding);
|
|
455
|
+
} catch (error) {
|
|
456
|
+
throw new Error(
|
|
457
|
+
'Invalid argument type for "key". Need ArrayBuffer, TypedArray, KeyObject, CryptoKey, string',
|
|
458
|
+
{ cause: error }
|
|
459
|
+
);
|
|
449
460
|
}
|
|
450
|
-
|
|
451
|
-
throw new Error(
|
|
452
|
-
'Invalid argument type for "key". Need ArrayBuffer, KeyObject, CryptoKey, string'
|
|
453
|
-
);
|
|
454
461
|
}
|
|
455
462
|
|
|
456
463
|
export function createSecretKey(key: any, encoding?: string) {
|
|
@@ -516,18 +523,6 @@ export class CryptoKey {
|
|
|
516
523
|
}
|
|
517
524
|
}
|
|
518
525
|
|
|
519
|
-
// ObjectDefineProperties(CryptoKey.prototype, {
|
|
520
|
-
// type: kEnumerableProperty,
|
|
521
|
-
// extractable: kEnumerableProperty,
|
|
522
|
-
// algorithm: kEnumerableProperty,
|
|
523
|
-
// usages: kEnumerableProperty,
|
|
524
|
-
// [SymbolToStringTag]: {
|
|
525
|
-
// __proto__: null,
|
|
526
|
-
// configurable: true,
|
|
527
|
-
// value: 'CryptoKey',
|
|
528
|
-
// },
|
|
529
|
-
// });
|
|
530
|
-
|
|
531
526
|
class KeyObject {
|
|
532
527
|
handle: KeyObjectHandle;
|
|
533
528
|
type: 'public' | 'secret' | 'private' | 'unknown' = 'unknown';
|
|
@@ -568,14 +563,6 @@ class KeyObject {
|
|
|
568
563
|
// }
|
|
569
564
|
}
|
|
570
565
|
|
|
571
|
-
// ObjectDefineProperties(KeyObject.prototype, {
|
|
572
|
-
// [SymbolToStringTag]: {
|
|
573
|
-
// __proto__: null,
|
|
574
|
-
// configurable: true,
|
|
575
|
-
// value: 'KeyObject',
|
|
576
|
-
// },
|
|
577
|
-
// });
|
|
578
|
-
|
|
579
566
|
export class SecretKeyObject extends KeyObject {
|
|
580
567
|
constructor(handle: KeyObjectHandle) {
|
|
581
568
|
super('secret', handle);
|
|
@@ -616,12 +603,17 @@ class AsymmetricKeyObject extends KeyObject {
|
|
|
616
603
|
super(type, handle);
|
|
617
604
|
}
|
|
618
605
|
|
|
606
|
+
private _asymmetricKeyType?: AsymmetricKeyType;
|
|
607
|
+
|
|
619
608
|
get asymmetricKeyType(): AsymmetricKeyType {
|
|
620
|
-
|
|
609
|
+
if (!this._asymmetricKeyType) {
|
|
610
|
+
this._asymmetricKeyType = this.handle.getAsymmetricKeyType();
|
|
611
|
+
}
|
|
612
|
+
return this._asymmetricKeyType;
|
|
621
613
|
}
|
|
622
614
|
|
|
623
615
|
// get asymmetricKeyDetails() {
|
|
624
|
-
// switch (this.
|
|
616
|
+
// switch (this._asymmetricKeyType) {
|
|
625
617
|
// case 'rsa':
|
|
626
618
|
// case 'rsa-pss':
|
|
627
619
|
// case 'dsa':
|
|
@@ -676,3 +668,7 @@ export class PrivateKeyObject extends AsymmetricKeyObject {
|
|
|
676
668
|
return this.handle.export(format, type, cipher, passphrase);
|
|
677
669
|
}
|
|
678
670
|
}
|
|
671
|
+
|
|
672
|
+
export const isCryptoKey = (obj: any): boolean => {
|
|
673
|
+
return obj !== null && obj?.keyObject !== undefined;
|
|
674
|
+
};
|
package/src/random.ts
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
import { NativeQuickCrypto } from './NativeQuickCrypto/NativeQuickCrypto';
|
|
2
2
|
import { Buffer } from '@craftzdog/react-native-buffer';
|
|
3
|
+
import type { TypedArray } from './Utils';
|
|
3
4
|
|
|
4
5
|
const random = NativeQuickCrypto.random;
|
|
5
6
|
|
|
6
|
-
type TypedArray =
|
|
7
|
-
| Uint8Array
|
|
8
|
-
| Uint8ClampedArray
|
|
9
|
-
| Uint16Array
|
|
10
|
-
| Uint32Array
|
|
11
|
-
| Int8Array
|
|
12
|
-
| Int16Array
|
|
13
|
-
| Int32Array
|
|
14
|
-
| Float32Array
|
|
15
|
-
| Float64Array;
|
|
16
7
|
type ArrayBufferView = TypedArray | DataView | ArrayBufferLike | Buffer;
|
|
17
8
|
|
|
18
9
|
export function randomFill<T extends ArrayBufferView>(
|
|
@@ -266,7 +257,6 @@ function asyncRefillRandomIntCache() {
|
|
|
266
257
|
});
|
|
267
258
|
}
|
|
268
259
|
|
|
269
|
-
// Really just the Web Crypto API alternative
|
|
270
260
|
// to require('crypto').randomFillSync() with an
|
|
271
261
|
// additional limitation that the input buffer is
|
|
272
262
|
// not allowed to exceed 65536 bytes, and can only
|
package/src/subtle.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
createSecretKey,
|
|
8
8
|
type AnyAlgorithm,
|
|
9
9
|
type JWK,
|
|
10
|
+
type CryptoKeyPair,
|
|
10
11
|
} from './keys';
|
|
11
12
|
import {
|
|
12
13
|
hasAnyNotIn,
|
|
@@ -16,8 +17,9 @@ import {
|
|
|
16
17
|
lazyDOMException,
|
|
17
18
|
normalizeHashName,
|
|
18
19
|
HashContext,
|
|
20
|
+
type Operation,
|
|
19
21
|
} from './Utils';
|
|
20
|
-
import { ecImportKey, ecExportKey } from './ec';
|
|
22
|
+
import { ecImportKey, ecExportKey, ecGenerateKey, ecdsaSignVerify } from './ec';
|
|
21
23
|
import { pbkdf2DeriveBits } from './pbkdf2';
|
|
22
24
|
import { asyncDigest } from './Hash';
|
|
23
25
|
import { aesImportKey, getAlgorithmName } from './aes';
|
|
@@ -202,6 +204,87 @@ const importGenericSecretKey = async (
|
|
|
202
204
|
throw new Error(`Unable to import ${name} key with format ${format}`);
|
|
203
205
|
};
|
|
204
206
|
|
|
207
|
+
// const checkCryptoKeyUsages = (key: CryptoKey) => {
|
|
208
|
+
// if (
|
|
209
|
+
// (key.type === 'secret' || key.type === 'private') &&
|
|
210
|
+
// key.usages.length === 0
|
|
211
|
+
// ) {
|
|
212
|
+
// throw lazyDOMException(
|
|
213
|
+
// 'Usages cannot be empty when creating a key.',
|
|
214
|
+
// 'SyntaxError'
|
|
215
|
+
// );
|
|
216
|
+
// }
|
|
217
|
+
// };
|
|
218
|
+
|
|
219
|
+
const checkCryptoKeyPairUsages = (pair: CryptoKeyPair) => {
|
|
220
|
+
if (
|
|
221
|
+
!(pair.privateKey instanceof Buffer) &&
|
|
222
|
+
pair.privateKey &&
|
|
223
|
+
pair.privateKey.hasOwnProperty('keyUsages')
|
|
224
|
+
) {
|
|
225
|
+
const priv = pair.privateKey as CryptoKey;
|
|
226
|
+
if (priv.usages.length > 0) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
console.log(pair.privateKey);
|
|
231
|
+
throw lazyDOMException(
|
|
232
|
+
'Usages cannot be empty when creating a key.',
|
|
233
|
+
'SyntaxError'
|
|
234
|
+
);
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const signVerify = (
|
|
238
|
+
algorithm: SubtleAlgorithm,
|
|
239
|
+
key: CryptoKey,
|
|
240
|
+
data: BufferLike,
|
|
241
|
+
signature?: BufferLike
|
|
242
|
+
): ArrayBuffer | boolean => {
|
|
243
|
+
const usage: Operation = signature === undefined ? 'sign' : 'verify';
|
|
244
|
+
algorithm = normalizeAlgorithm(algorithm, usage);
|
|
245
|
+
|
|
246
|
+
if (!key.usages.includes(usage) || algorithm.name !== key.algorithm.name) {
|
|
247
|
+
throw lazyDOMException(
|
|
248
|
+
`Unable to use this key to ${usage}`,
|
|
249
|
+
'InvalidAccessError'
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
switch (algorithm.name) {
|
|
254
|
+
// case 'RSA-PSS':
|
|
255
|
+
// // Fall through
|
|
256
|
+
// case 'RSASSA-PKCS1-v1_5':
|
|
257
|
+
// return require('internal/crypto/rsa').rsaSignVerify(
|
|
258
|
+
// key,
|
|
259
|
+
// data,
|
|
260
|
+
// algorithm,
|
|
261
|
+
// signature
|
|
262
|
+
// );
|
|
263
|
+
case 'ECDSA':
|
|
264
|
+
return ecdsaSignVerify(key, data, algorithm, signature);
|
|
265
|
+
// case 'Ed25519':
|
|
266
|
+
// // Fall through
|
|
267
|
+
// case 'Ed448':
|
|
268
|
+
// return require('internal/crypto/cfrg').eddsaSignVerify(
|
|
269
|
+
// key,
|
|
270
|
+
// data,
|
|
271
|
+
// algorithm,
|
|
272
|
+
// signature
|
|
273
|
+
// );
|
|
274
|
+
// case 'HMAC':
|
|
275
|
+
// return require('internal/crypto/mac').hmacSignVerify(
|
|
276
|
+
// key,
|
|
277
|
+
// data,
|
|
278
|
+
// algorithm,
|
|
279
|
+
// signature
|
|
280
|
+
// );
|
|
281
|
+
}
|
|
282
|
+
throw lazyDOMException(
|
|
283
|
+
`Unrecognized algorithm name '${algorithm}' for '${usage}'`,
|
|
284
|
+
'NotSupportedError'
|
|
285
|
+
);
|
|
286
|
+
};
|
|
287
|
+
|
|
205
288
|
class Subtle {
|
|
206
289
|
async digest(
|
|
207
290
|
algorithm: SubtleAlgorithm | AnyAlgorithm,
|
|
@@ -360,6 +443,79 @@ class Subtle {
|
|
|
360
443
|
}
|
|
361
444
|
throw new Error(`'subtle.exportKey()' is not implemented for ${format}`);
|
|
362
445
|
}
|
|
446
|
+
|
|
447
|
+
async generateKey(
|
|
448
|
+
algorithm: SubtleAlgorithm,
|
|
449
|
+
extractable: boolean,
|
|
450
|
+
keyUsages: KeyUsage[]
|
|
451
|
+
): Promise<CryptoKey | CryptoKeyPair> {
|
|
452
|
+
algorithm = normalizeAlgorithm(algorithm, 'generateKey');
|
|
453
|
+
let result: CryptoKey | CryptoKeyPair;
|
|
454
|
+
switch (algorithm.name) {
|
|
455
|
+
// case 'RSASSA-PKCS1-v1_5':
|
|
456
|
+
// // Fall through
|
|
457
|
+
// case 'RSA-PSS':
|
|
458
|
+
// // Fall through
|
|
459
|
+
// case 'RSA-OAEP':
|
|
460
|
+
// resultType = 'CryptoKeyPair';
|
|
461
|
+
// result = await rsaKeyGenerate(algorithm, extractable, keyUsages);
|
|
462
|
+
// break;
|
|
463
|
+
// case 'Ed25519':
|
|
464
|
+
// // Fall through
|
|
465
|
+
// case 'Ed448':
|
|
466
|
+
// // Fall through
|
|
467
|
+
// case 'X25519':
|
|
468
|
+
// // Fall through
|
|
469
|
+
// case 'X448':
|
|
470
|
+
// resultType = 'CryptoKeyPair';
|
|
471
|
+
// result = await cfrgGenerateKey(algorithm, extractable, keyUsages);
|
|
472
|
+
// break;
|
|
473
|
+
case 'ECDSA':
|
|
474
|
+
// Fall through
|
|
475
|
+
case 'ECDH':
|
|
476
|
+
result = await ecGenerateKey(algorithm, extractable, keyUsages);
|
|
477
|
+
checkCryptoKeyPairUsages(result);
|
|
478
|
+
break;
|
|
479
|
+
// case 'HMAC':
|
|
480
|
+
// resultType = 'CryptoKey';
|
|
481
|
+
// result = await hmacGenerateKey(algorithm, extractable, keyUsages);
|
|
482
|
+
// break;
|
|
483
|
+
// case 'AES-CTR':
|
|
484
|
+
// // Fall through
|
|
485
|
+
// case 'AES-CBC':
|
|
486
|
+
// // Fall through
|
|
487
|
+
// case 'AES-GCM':
|
|
488
|
+
// // Fall through
|
|
489
|
+
// case 'AES-KW':
|
|
490
|
+
// resultType = 'CryptoKey';
|
|
491
|
+
// result = await aesGenerateKey(algorithm, extractable, keyUsages);
|
|
492
|
+
// break;
|
|
493
|
+
default:
|
|
494
|
+
throw new Error(
|
|
495
|
+
`'subtle.generateKey()' is not implemented for ${algorithm.name}.
|
|
496
|
+
Unrecognized algorithm name`
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return result;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
async sign(
|
|
504
|
+
algorithm: SubtleAlgorithm,
|
|
505
|
+
key: CryptoKey,
|
|
506
|
+
data: BufferLike
|
|
507
|
+
): Promise<ArrayBuffer> {
|
|
508
|
+
return signVerify(algorithm, key, data) as ArrayBuffer;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
async verify(
|
|
512
|
+
algorithm: SubtleAlgorithm,
|
|
513
|
+
key: CryptoKey,
|
|
514
|
+
signature: BufferLike,
|
|
515
|
+
data: BufferLike
|
|
516
|
+
): Promise<ArrayBuffer> {
|
|
517
|
+
return signVerify(algorithm, key, data, signature) as ArrayBuffer;
|
|
518
|
+
}
|
|
363
519
|
}
|
|
364
520
|
|
|
365
521
|
export const subtle = new Subtle();
|