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.
- 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 +10 -24
- package/lib/commonjs/keys.js.map +1 -1
- package/lib/commonjs/random.js +6 -0
- 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 +8 -24
- package/lib/module/keys.js.map +1 -1
- package/lib/module/random.js +6 -0
- 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 +1 -0
- 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 +11 -8
- 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 +2 -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 +12 -0
- package/src/ec.ts +114 -90
- package/src/keys.ts +26 -31
- package/src/random.ts +12 -1
- package/src/subtle.ts +157 -1
package/src/Cipher.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
validateInt32,
|
|
15
15
|
type BinaryLikeNode,
|
|
16
16
|
} from './Utils';
|
|
17
|
-
import { type InternalCipher,
|
|
17
|
+
import { type InternalCipher, KeyVariant } from './NativeQuickCrypto/Cipher';
|
|
18
18
|
import type {
|
|
19
19
|
CipherCCMOptions,
|
|
20
20
|
CipherCCMTypes,
|
|
@@ -34,11 +34,21 @@ import { Buffer } from '@craftzdog/react-native-buffer';
|
|
|
34
34
|
import { Buffer as SBuffer } from 'safe-buffer';
|
|
35
35
|
import { constants } from './constants';
|
|
36
36
|
import {
|
|
37
|
+
CryptoKey,
|
|
37
38
|
parsePrivateKeyEncoding,
|
|
38
39
|
parsePublicKeyEncoding,
|
|
39
40
|
preparePrivateKey,
|
|
40
41
|
preparePublicOrPrivateKey,
|
|
42
|
+
type CryptoKeyPair,
|
|
43
|
+
type KeyPairType,
|
|
44
|
+
type NamedCurve,
|
|
41
45
|
} from './keys';
|
|
46
|
+
import type { KeyObjectHandle } from './NativeQuickCrypto/webcrypto';
|
|
47
|
+
|
|
48
|
+
export enum ECCurve {
|
|
49
|
+
OPENSSL_EC_EXPLICIT_CURVE,
|
|
50
|
+
OPENSSL_EC_NAMED_CURVE,
|
|
51
|
+
}
|
|
42
52
|
|
|
43
53
|
// make sure that nextTick is there
|
|
44
54
|
global.process.nextTick = setImmediate;
|
|
@@ -428,8 +438,8 @@ export const privateDecrypt = rsaFunctionFor(
|
|
|
428
438
|
// \__, |\___|_| |_|\___|_| \__,_|\__\___|_|\_\___|\__, |_| \__,_|_|_|
|
|
429
439
|
// __/ | __/ |
|
|
430
440
|
// |___/ |___/
|
|
431
|
-
type GenerateKeyPairOptions = {
|
|
432
|
-
modulusLength
|
|
441
|
+
export type GenerateKeyPairOptions = {
|
|
442
|
+
modulusLength?: number; // Key size in bits (RSA, DSA).
|
|
433
443
|
publicExponent?: number; // Public exponent (RSA). Default: 0x10001.
|
|
434
444
|
hashAlgorithm?: string; // Name of the message digest (RSA-PSS).
|
|
435
445
|
mgf1HashAlgorithm?: string; // string Name of the message digest used by MGF1 (RSA-PSS).
|
|
@@ -446,11 +456,27 @@ type GenerateKeyPairOptions = {
|
|
|
446
456
|
hash?: any;
|
|
447
457
|
mgf1Hash?: any;
|
|
448
458
|
};
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
459
|
+
|
|
460
|
+
export type KeyPairKey = Buffer | KeyObjectHandle | CryptoKey | undefined;
|
|
461
|
+
|
|
462
|
+
export type GenerateKeyPairReturn = [
|
|
463
|
+
error?: Error,
|
|
464
|
+
privateKey?: KeyPairKey,
|
|
465
|
+
publicKey?: KeyPairKey,
|
|
466
|
+
];
|
|
467
|
+
|
|
468
|
+
export type GenerateKeyPairCallback = (
|
|
469
|
+
error?: Error,
|
|
470
|
+
publicKey?: KeyPairKey,
|
|
471
|
+
privateKey?: KeyPairKey
|
|
472
|
+
) => GenerateKeyPairReturn | void;
|
|
473
|
+
|
|
474
|
+
export type KeyPair = {
|
|
475
|
+
publicKey?: KeyPairKey;
|
|
476
|
+
privateKey?: KeyPairKey;
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
export type GenerateKeyPairPromiseReturn = [error?: Error, keypair?: KeyPair];
|
|
454
480
|
|
|
455
481
|
function parseKeyEncoding(
|
|
456
482
|
keyType: string,
|
|
@@ -505,14 +531,15 @@ function parseKeyEncoding(
|
|
|
505
531
|
];
|
|
506
532
|
}
|
|
507
533
|
|
|
534
|
+
/** On node a very complex "job" chain is created, we are going for a far simpler approach and calling
|
|
535
|
+
* an internal function that basically executes the same byte shuffling on the native side
|
|
536
|
+
*/
|
|
508
537
|
function internalGenerateKeyPair(
|
|
509
538
|
isAsync: boolean,
|
|
510
|
-
type:
|
|
539
|
+
type: KeyPairType,
|
|
511
540
|
options: GenerateKeyPairOptions | undefined,
|
|
512
|
-
callback
|
|
513
|
-
) {
|
|
514
|
-
// On node a very complex "job" chain is created, we are going for a far simpler approach and calling
|
|
515
|
-
// an internal function that basically executes the same byte shuffling on the native side
|
|
541
|
+
callback?: GenerateKeyPairCallback
|
|
542
|
+
): GenerateKeyPairReturn | void {
|
|
516
543
|
const encoding = parseKeyEncoding(type, options);
|
|
517
544
|
|
|
518
545
|
// if (options !== undefined)
|
|
@@ -520,11 +547,11 @@ function internalGenerateKeyPair(
|
|
|
520
547
|
|
|
521
548
|
switch (type) {
|
|
522
549
|
case 'rsa-pss':
|
|
523
|
-
|
|
550
|
+
// fallthrough
|
|
551
|
+
case 'rsa':
|
|
524
552
|
validateObject<GenerateKeyPairOptions>(options, 'options');
|
|
525
553
|
const { modulusLength } = options!;
|
|
526
|
-
validateUint32(modulusLength, 'options.modulusLength');
|
|
527
|
-
|
|
554
|
+
validateUint32(modulusLength as number, 'options.modulusLength');
|
|
528
555
|
let { publicExponent } = options!;
|
|
529
556
|
if (publicExponent == null) {
|
|
530
557
|
publicExponent = 0x10001;
|
|
@@ -535,37 +562,36 @@ function internalGenerateKeyPair(
|
|
|
535
562
|
if (type === 'rsa') {
|
|
536
563
|
if (isAsync) {
|
|
537
564
|
NativeQuickCrypto.generateKeyPair(
|
|
538
|
-
|
|
539
|
-
modulusLength,
|
|
565
|
+
KeyVariant.RSA_SSA_PKCS1_v1_5,
|
|
566
|
+
modulusLength as number,
|
|
540
567
|
publicExponent,
|
|
541
568
|
...encoding
|
|
542
569
|
)
|
|
543
570
|
.then(([err, publicKey, privateKey]) => {
|
|
544
|
-
if (
|
|
571
|
+
if (publicKey instanceof Buffer) {
|
|
545
572
|
publicKey = Buffer.from(publicKey);
|
|
546
573
|
}
|
|
547
|
-
if (
|
|
574
|
+
if (privateKey instanceof Buffer) {
|
|
548
575
|
privateKey = Buffer.from(privateKey);
|
|
549
576
|
}
|
|
550
|
-
callback
|
|
577
|
+
callback!(err, publicKey, privateKey);
|
|
551
578
|
})
|
|
552
579
|
.catch((err) => {
|
|
553
|
-
callback
|
|
580
|
+
callback!(err, undefined, undefined);
|
|
554
581
|
});
|
|
555
|
-
return;
|
|
556
582
|
} else {
|
|
557
583
|
let [err, publicKey, privateKey] =
|
|
558
584
|
NativeQuickCrypto.generateKeyPairSync(
|
|
559
|
-
|
|
560
|
-
modulusLength,
|
|
585
|
+
KeyVariant.RSA_SSA_PKCS1_v1_5,
|
|
586
|
+
modulusLength as number,
|
|
561
587
|
publicExponent,
|
|
562
588
|
...encoding
|
|
563
589
|
);
|
|
564
590
|
|
|
565
|
-
if (
|
|
591
|
+
if (publicKey instanceof Buffer) {
|
|
566
592
|
publicKey = Buffer.from(publicKey);
|
|
567
593
|
}
|
|
568
|
-
if (
|
|
594
|
+
if (privateKey instanceof Buffer) {
|
|
569
595
|
privateKey = Buffer.from(privateKey);
|
|
570
596
|
}
|
|
571
597
|
|
|
@@ -609,15 +635,15 @@ function internalGenerateKeyPair(
|
|
|
609
635
|
}
|
|
610
636
|
|
|
611
637
|
return NativeQuickCrypto.generateKeyPairSync(
|
|
612
|
-
|
|
613
|
-
modulusLength,
|
|
638
|
+
KeyVariant.RSA_PSS,
|
|
639
|
+
modulusLength as number,
|
|
614
640
|
publicExponent,
|
|
615
641
|
hashAlgorithm || hash,
|
|
616
642
|
mgf1HashAlgorithm || mgf1Hash,
|
|
617
643
|
saltLength,
|
|
618
644
|
...encoding
|
|
619
645
|
);
|
|
620
|
-
|
|
646
|
+
|
|
621
647
|
// case 'dsa': {
|
|
622
648
|
// validateObject(options, 'options');
|
|
623
649
|
// const { modulusLength } = options!;
|
|
@@ -634,21 +660,57 @@ function internalGenerateKeyPair(
|
|
|
634
660
|
// // divisorLength,
|
|
635
661
|
// // ...encoding);
|
|
636
662
|
// }
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
663
|
+
|
|
664
|
+
case 'ec':
|
|
665
|
+
validateObject<GenerateKeyPairOptions>(options, 'options');
|
|
666
|
+
const { namedCurve } = options!;
|
|
667
|
+
validateString(namedCurve, 'options.namedCurve');
|
|
668
|
+
let paramEncodingFlag = ECCurve.OPENSSL_EC_NAMED_CURVE;
|
|
669
|
+
const { paramEncoding } = options!;
|
|
670
|
+
if (paramEncoding == null || paramEncoding === 'named')
|
|
671
|
+
paramEncodingFlag = ECCurve.OPENSSL_EC_NAMED_CURVE;
|
|
672
|
+
else if (paramEncoding === 'explicit')
|
|
673
|
+
paramEncodingFlag = ECCurve.OPENSSL_EC_EXPLICIT_CURVE;
|
|
674
|
+
else
|
|
675
|
+
throw new Error(
|
|
676
|
+
`Invalid Argument options.paramEncoding ${paramEncoding}`
|
|
677
|
+
);
|
|
678
|
+
|
|
679
|
+
if (isAsync) {
|
|
680
|
+
NativeQuickCrypto.generateKeyPair(
|
|
681
|
+
KeyVariant.EC,
|
|
682
|
+
namedCurve as NamedCurve,
|
|
683
|
+
paramEncodingFlag,
|
|
684
|
+
...encoding
|
|
685
|
+
)
|
|
686
|
+
.then(([err, publicKey, privateKey]) => {
|
|
687
|
+
if (publicKey instanceof Buffer) {
|
|
688
|
+
publicKey = Buffer.from(publicKey);
|
|
689
|
+
}
|
|
690
|
+
if (privateKey instanceof Buffer) {
|
|
691
|
+
privateKey = Buffer.from(privateKey);
|
|
692
|
+
}
|
|
693
|
+
callback?.(err, publicKey, privateKey);
|
|
694
|
+
})
|
|
695
|
+
.catch((err) => {
|
|
696
|
+
callback?.(err, undefined, undefined);
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
let [err, publicKey, privateKey] = NativeQuickCrypto.generateKeyPairSync(
|
|
701
|
+
KeyVariant.EC,
|
|
702
|
+
namedCurve as NamedCurve,
|
|
703
|
+
paramEncodingFlag,
|
|
704
|
+
...encoding
|
|
705
|
+
);
|
|
706
|
+
if (publicKey instanceof Buffer) {
|
|
707
|
+
publicKey = Buffer.from(publicKey);
|
|
708
|
+
}
|
|
709
|
+
if (privateKey instanceof Buffer) {
|
|
710
|
+
privateKey = Buffer.from(privateKey);
|
|
711
|
+
}
|
|
712
|
+
return [err, publicKey, privateKey];
|
|
713
|
+
|
|
652
714
|
// case 'ed25519':
|
|
653
715
|
// case 'ed448':
|
|
654
716
|
// case 'x25519':
|
|
@@ -712,48 +774,50 @@ function internalGenerateKeyPair(
|
|
|
712
774
|
default:
|
|
713
775
|
// Fall through
|
|
714
776
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
777
|
+
const err = new Error(`
|
|
778
|
+
Invalid Argument options: '${type}' scheme not supported for generateKey().
|
|
779
|
+
Currently not all encryption methods are supported in quick-crypto. Check
|
|
780
|
+
implementation_coverage.md for status.
|
|
781
|
+
`);
|
|
782
|
+
return [err, undefined, undefined];
|
|
718
783
|
}
|
|
719
784
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
type: string,
|
|
723
|
-
callback: GenerateKeyPairCallback
|
|
724
|
-
): void;
|
|
725
|
-
export function generateKeyPair(
|
|
726
|
-
type: string,
|
|
785
|
+
export const generateKeyPair = (
|
|
786
|
+
type: KeyPairType,
|
|
727
787
|
options: GenerateKeyPairOptions,
|
|
728
788
|
callback: GenerateKeyPairCallback
|
|
729
|
-
): void
|
|
730
|
-
export function generateKeyPair(
|
|
731
|
-
type: string,
|
|
732
|
-
options?: GenerateKeyPairCallback | GenerateKeyPairOptions,
|
|
733
|
-
callback?: GenerateKeyPairCallback
|
|
734
|
-
) {
|
|
735
|
-
if (typeof options === 'function') {
|
|
736
|
-
callback = options;
|
|
737
|
-
options = undefined;
|
|
738
|
-
}
|
|
739
|
-
|
|
789
|
+
): void => {
|
|
740
790
|
validateFunction(callback);
|
|
741
|
-
|
|
742
791
|
internalGenerateKeyPair(true, type, options, callback);
|
|
743
|
-
}
|
|
792
|
+
};
|
|
744
793
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
794
|
+
// Promisify generateKeyPair
|
|
795
|
+
// (attempted to use util.promisify, to no avail)
|
|
796
|
+
export const generateKeyPairPromise = (
|
|
797
|
+
type: KeyPairType,
|
|
798
|
+
options: GenerateKeyPairOptions
|
|
799
|
+
): Promise<GenerateKeyPairPromiseReturn> => {
|
|
800
|
+
return new Promise((resolve, reject) => {
|
|
801
|
+
generateKeyPair(type, options, (err, publicKey, privateKey) => {
|
|
802
|
+
if (err) {
|
|
803
|
+
reject([err, undefined]);
|
|
804
|
+
} else {
|
|
805
|
+
resolve([undefined, { publicKey, privateKey }]);
|
|
806
|
+
}
|
|
807
|
+
});
|
|
808
|
+
});
|
|
748
809
|
};
|
|
810
|
+
|
|
811
|
+
// generateKeyPairSync
|
|
812
|
+
export function generateKeyPairSync(type: KeyPairType): CryptoKeyPair;
|
|
749
813
|
export function generateKeyPairSync(
|
|
750
|
-
type:
|
|
814
|
+
type: KeyPairType,
|
|
751
815
|
options: GenerateKeyPairOptions
|
|
752
|
-
):
|
|
816
|
+
): CryptoKeyPair;
|
|
753
817
|
export function generateKeyPairSync(
|
|
754
|
-
type:
|
|
818
|
+
type: KeyPairType,
|
|
755
819
|
options?: GenerateKeyPairOptions
|
|
756
|
-
):
|
|
820
|
+
): CryptoKeyPair {
|
|
757
821
|
const [_, publicKey, privateKey] = internalGenerateKeyPair(
|
|
758
822
|
false,
|
|
759
823
|
type,
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import type { GenerateKeyPairReturn } from '../Cipher';
|
|
1
2
|
import type { BinaryLike } from '../Utils';
|
|
2
3
|
import type { Buffer } from '@craftzdog/react-native-buffer';
|
|
3
4
|
|
|
4
|
-
// TODO
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
// TODO: until shared, keep in sync with C++ side (cpp/Utils/MGLUtils.h)
|
|
6
|
+
export enum KeyVariant {
|
|
7
|
+
RSA_SSA_PKCS1_v1_5,
|
|
8
|
+
RSA_PSS,
|
|
9
|
+
RSA_OAEP,
|
|
10
|
+
DSA,
|
|
11
|
+
EC,
|
|
12
|
+
NID,
|
|
13
|
+
DH,
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
export type InternalCipher = {
|
|
@@ -56,15 +60,11 @@ export type PrivateDecryptMethod = (
|
|
|
56
60
|
) => Buffer;
|
|
57
61
|
|
|
58
62
|
export type GenerateKeyPairMethod = (
|
|
59
|
-
keyVariant:
|
|
60
|
-
modulusLength: number,
|
|
61
|
-
publicExponent: number,
|
|
63
|
+
keyVariant: KeyVariant,
|
|
62
64
|
...rest: any[]
|
|
63
|
-
) => Promise<
|
|
65
|
+
) => Promise<GenerateKeyPairReturn>;
|
|
64
66
|
|
|
65
67
|
export type GenerateKeyPairSyncMethod = (
|
|
66
|
-
keyVariant:
|
|
67
|
-
modulusLength: number,
|
|
68
|
-
publicExponent: number,
|
|
68
|
+
keyVariant: KeyVariant,
|
|
69
69
|
...rest: any[]
|
|
70
|
-
) =>
|
|
70
|
+
) => GenerateKeyPairReturn;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
// TODO Add real types to sign/verify, the problem is that because of encryption schemes
|
|
2
|
+
|
|
3
|
+
import type { KeyObjectHandle } from './webcrypto';
|
|
4
|
+
|
|
2
5
|
// they will have variable amount of parameters
|
|
3
6
|
export type InternalSign = {
|
|
4
7
|
init: (algorithm: string) => void;
|
|
@@ -15,3 +18,27 @@ export type InternalVerify = {
|
|
|
15
18
|
export type CreateSignMethod = () => InternalSign;
|
|
16
19
|
|
|
17
20
|
export type CreateVerifyMethod = () => InternalVerify;
|
|
21
|
+
|
|
22
|
+
export enum DSASigEnc {
|
|
23
|
+
kSigEncDER,
|
|
24
|
+
kSigEncP1363,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export enum SignMode {
|
|
28
|
+
kSignJobModeSign,
|
|
29
|
+
kSignJobModeVerify,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type SignVerify = (
|
|
33
|
+
mode: SignMode,
|
|
34
|
+
handle: KeyObjectHandle,
|
|
35
|
+
unused1: undefined,
|
|
36
|
+
unused2: undefined,
|
|
37
|
+
unused3: undefined,
|
|
38
|
+
data: ArrayBuffer,
|
|
39
|
+
digest: string | undefined,
|
|
40
|
+
salt_length: number | undefined,
|
|
41
|
+
padding: number | undefined,
|
|
42
|
+
dsa_encoding: DSASigEnc | undefined,
|
|
43
|
+
signature: ArrayBuffer | undefined
|
|
44
|
+
) => ArrayBuffer | boolean;
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
KWebCryptoKeyFormat,
|
|
8
8
|
NamedCurve,
|
|
9
9
|
} from '../keys';
|
|
10
|
+
import type { SignVerify } from './sig';
|
|
10
11
|
|
|
11
12
|
type KeyDetail = {
|
|
12
13
|
length?: number;
|
|
@@ -43,4 +44,5 @@ type CreateKeyObjectHandle = () => KeyObjectHandle;
|
|
|
43
44
|
export type webcrypto = {
|
|
44
45
|
ecExportKey: ECExportKey;
|
|
45
46
|
createKeyObjectHandle: CreateKeyObjectHandle;
|
|
47
|
+
signVerify: SignVerify;
|
|
46
48
|
};
|
package/src/Utils.ts
CHANGED
|
@@ -508,6 +508,8 @@ export const normalizeAlgorithm = (
|
|
|
508
508
|
|
|
509
509
|
// 4.
|
|
510
510
|
let algName = algorithm.name;
|
|
511
|
+
// @ts-expect-error
|
|
512
|
+
if (algName === undefined) return { name: undefined };
|
|
511
513
|
|
|
512
514
|
// 5.
|
|
513
515
|
let desiredType: string | null | undefined;
|
|
@@ -600,6 +602,16 @@ export const validateByteLength = (
|
|
|
600
602
|
}
|
|
601
603
|
};
|
|
602
604
|
|
|
605
|
+
export const getUsagesUnion = (usageSet: KeyUsage[], ...usages: KeyUsage[]) => {
|
|
606
|
+
const newset: KeyUsage[] = [];
|
|
607
|
+
for (let n = 0; n < usages.length; n++) {
|
|
608
|
+
if (!usages[n] || usages[n] === undefined) continue;
|
|
609
|
+
if (usageSet.includes(usages[n] as KeyUsage))
|
|
610
|
+
newset.push(usages[n] as KeyUsage);
|
|
611
|
+
}
|
|
612
|
+
return newset;
|
|
613
|
+
};
|
|
614
|
+
|
|
603
615
|
const kKeyOps: {
|
|
604
616
|
[key in KeyUsage]: number;
|
|
605
617
|
} = {
|
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
|
+
};
|