react-native-quick-crypto 1.0.11 → 1.0.13
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/android/CMakeLists.txt +7 -0
- package/cpp/cipher/CCMCipher.cpp +4 -1
- package/cpp/cipher/ChaCha20Cipher.cpp +3 -1
- package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +5 -5
- package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +1 -2
- package/cpp/cipher/HybridCipher.cpp +10 -1
- package/cpp/cipher/HybridCipher.hpp +2 -0
- package/cpp/cipher/HybridRsaCipher.cpp +0 -13
- package/cpp/cipher/XChaCha20Poly1305Cipher.cpp +7 -5
- package/cpp/cipher/XChaCha20Poly1305Cipher.hpp +1 -2
- package/cpp/cipher/XSalsa20Cipher.cpp +4 -0
- package/cpp/cipher/XSalsa20Poly1305Cipher.cpp +7 -5
- package/cpp/cipher/XSalsa20Poly1305Cipher.hpp +1 -2
- package/cpp/ecdh/HybridECDH.cpp +20 -133
- package/cpp/keys/HybridKeyObjectHandle.cpp +144 -141
- package/cpp/keys/HybridKeyObjectHandle.hpp +6 -3
- package/cpp/keys/KeyObjectData.hpp +2 -0
- package/cpp/kmac/HybridKmac.cpp +83 -0
- package/cpp/kmac/HybridKmac.hpp +31 -0
- package/cpp/mldsa/HybridMlDsaKeyPair.cpp +11 -20
- package/cpp/mldsa/HybridMlDsaKeyPair.hpp +4 -2
- package/cpp/mlkem/HybridMlKemKeyPair.cpp +319 -0
- package/cpp/mlkem/HybridMlKemKeyPair.hpp +48 -0
- package/cpp/sign/SignUtils.hpp +9 -26
- package/cpp/utils/QuickCryptoUtils.cpp +44 -0
- package/cpp/utils/QuickCryptoUtils.hpp +39 -0
- package/cpp/x509/HybridX509Certificate.cpp +174 -0
- package/cpp/x509/HybridX509Certificate.hpp +51 -0
- package/lib/commonjs/cipher.js +15 -2
- package/lib/commonjs/cipher.js.map +1 -1
- package/lib/commonjs/dhKeyPair.js +3 -3
- package/lib/commonjs/dhKeyPair.js.map +1 -1
- package/lib/commonjs/dsa.js +3 -3
- package/lib/commonjs/dsa.js.map +1 -1
- package/lib/commonjs/ec.js +18 -18
- package/lib/commonjs/ec.js.map +1 -1
- package/lib/commonjs/ed.js +9 -9
- package/lib/commonjs/ed.js.map +1 -1
- package/lib/commonjs/hash.js +17 -12
- package/lib/commonjs/hash.js.map +1 -1
- package/lib/commonjs/hkdf.js.map +1 -1
- package/lib/commonjs/index.js +22 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/keys/classes.js +2 -2
- package/lib/commonjs/keys/classes.js.map +1 -1
- package/lib/commonjs/keys/index.js +24 -0
- package/lib/commonjs/keys/index.js.map +1 -1
- package/lib/commonjs/keys/publicCipher.js +2 -2
- package/lib/commonjs/keys/publicCipher.js.map +1 -1
- package/lib/commonjs/keys/signVerify.js +0 -2
- package/lib/commonjs/keys/signVerify.js.map +1 -1
- package/lib/commonjs/mlkem.js +219 -0
- package/lib/commonjs/mlkem.js.map +1 -0
- package/lib/commonjs/pbkdf2.js +18 -1
- package/lib/commonjs/pbkdf2.js.map +1 -1
- package/lib/commonjs/rsa.js +7 -7
- package/lib/commonjs/rsa.js.map +1 -1
- package/lib/commonjs/specs/kmac.nitro.js +6 -0
- package/lib/commonjs/specs/kmac.nitro.js.map +1 -0
- package/lib/commonjs/specs/mlKemKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/mlKemKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/x509certificate.nitro.js +6 -0
- package/lib/commonjs/specs/x509certificate.nitro.js.map +1 -0
- package/lib/commonjs/subtle.js +292 -112
- package/lib/commonjs/subtle.js.map +1 -1
- package/lib/commonjs/utils/conversion.js +3 -3
- package/lib/commonjs/utils/conversion.js.map +1 -1
- package/lib/commonjs/utils/hashnames.js +31 -0
- package/lib/commonjs/utils/hashnames.js.map +1 -1
- package/lib/commonjs/utils/types.js.map +1 -1
- package/lib/commonjs/x509certificate.js +189 -0
- package/lib/commonjs/x509certificate.js.map +1 -0
- package/lib/module/cipher.js +16 -3
- package/lib/module/cipher.js.map +1 -1
- package/lib/module/dhKeyPair.js +1 -1
- package/lib/module/dhKeyPair.js.map +1 -1
- package/lib/module/dsa.js +1 -1
- package/lib/module/dsa.js.map +1 -1
- package/lib/module/ec.js +6 -6
- package/lib/module/ec.js.map +1 -1
- package/lib/module/ed.js +1 -1
- package/lib/module/ed.js.map +1 -1
- package/lib/module/hash.js +17 -12
- package/lib/module/hash.js.map +1 -1
- package/lib/module/hkdf.js.map +1 -1
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/keys/classes.js +2 -2
- package/lib/module/keys/classes.js.map +1 -1
- package/lib/module/keys/index.js +25 -1
- package/lib/module/keys/index.js.map +1 -1
- package/lib/module/keys/publicCipher.js +2 -2
- package/lib/module/keys/publicCipher.js.map +1 -1
- package/lib/module/keys/signVerify.js +0 -2
- package/lib/module/keys/signVerify.js.map +1 -1
- package/lib/module/mlkem.js +211 -0
- package/lib/module/mlkem.js.map +1 -0
- package/lib/module/pbkdf2.js +18 -1
- package/lib/module/pbkdf2.js.map +1 -1
- package/lib/module/rsa.js +1 -1
- package/lib/module/rsa.js.map +1 -1
- package/lib/module/specs/kmac.nitro.js +4 -0
- package/lib/module/specs/kmac.nitro.js.map +1 -0
- package/lib/module/specs/mlKemKeyPair.nitro.js +4 -0
- package/lib/module/specs/mlKemKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/x509certificate.nitro.js +4 -0
- package/lib/module/specs/x509certificate.nitro.js.map +1 -0
- package/lib/module/subtle.js +292 -112
- package/lib/module/subtle.js.map +1 -1
- package/lib/module/utils/conversion.js +3 -4
- package/lib/module/utils/conversion.js.map +1 -1
- package/lib/module/utils/hashnames.js +31 -0
- package/lib/module/utils/hashnames.js.map +1 -1
- package/lib/module/utils/types.js.map +1 -1
- package/lib/module/x509certificate.js +184 -0
- package/lib/module/x509certificate.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/typescript/cipher.d.ts +3 -0
- package/lib/typescript/cipher.d.ts.map +1 -1
- package/lib/typescript/dhKeyPair.d.ts +1 -1
- package/lib/typescript/dhKeyPair.d.ts.map +1 -1
- package/lib/typescript/dsa.d.ts +1 -1
- package/lib/typescript/dsa.d.ts.map +1 -1
- package/lib/typescript/ec.d.ts +1 -1
- package/lib/typescript/ec.d.ts.map +1 -1
- package/lib/typescript/ed.d.ts +1 -1
- package/lib/typescript/ed.d.ts.map +1 -1
- package/lib/typescript/hash.d.ts.map +1 -1
- package/lib/typescript/hkdf.d.ts +2 -6
- package/lib/typescript/hkdf.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +15 -4
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/keys/classes.d.ts +5 -5
- package/lib/typescript/keys/classes.d.ts.map +1 -1
- package/lib/typescript/keys/index.d.ts +2 -2
- package/lib/typescript/keys/index.d.ts.map +1 -1
- package/lib/typescript/keys/signVerify.d.ts.map +1 -1
- package/lib/typescript/mlkem.d.ts +30 -0
- package/lib/typescript/mlkem.d.ts.map +1 -0
- package/lib/typescript/pbkdf2.d.ts +2 -2
- package/lib/typescript/pbkdf2.d.ts.map +1 -1
- package/lib/typescript/rsa.d.ts +1 -1
- package/lib/typescript/rsa.d.ts.map +1 -1
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts +1 -0
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -1
- package/lib/typescript/specs/kmac.nitro.d.ts +10 -0
- package/lib/typescript/specs/kmac.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts +18 -0
- package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/x509certificate.nitro.d.ts +34 -0
- package/lib/typescript/specs/x509certificate.nitro.d.ts.map +1 -0
- package/lib/typescript/subtle.d.ts +10 -0
- package/lib/typescript/subtle.d.ts.map +1 -1
- package/lib/typescript/utils/conversion.d.ts.map +1 -1
- package/lib/typescript/utils/hashnames.d.ts +1 -1
- package/lib/typescript/utils/hashnames.d.ts.map +1 -1
- package/lib/typescript/utils/types.d.ts +13 -7
- package/lib/typescript/utils/types.d.ts.map +1 -1
- package/lib/typescript/x509certificate.d.ts +64 -0
- package/lib/typescript/x509certificate.d.ts.map +1 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +3 -0
- package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +30 -0
- package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +30 -0
- package/nitrogen/generated/shared/c++/AsymmetricKeyType.hpp +12 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +1 -0
- package/nitrogen/generated/shared/c++/HybridKmacSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridKmacSpec.hpp +66 -0
- package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.cpp +31 -0
- package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.hpp +74 -0
- package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.cpp +46 -0
- package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.hpp +96 -0
- package/package.json +4 -1
- package/src/cipher.ts +17 -3
- package/src/dhKeyPair.ts +1 -1
- package/src/dsa.ts +1 -1
- package/src/ec.ts +9 -9
- package/src/ed.ts +2 -2
- package/src/hash.ts +34 -11
- package/src/hkdf.ts +2 -7
- package/src/index.ts +7 -0
- package/src/keys/classes.ts +10 -9
- package/src/keys/index.ts +37 -2
- package/src/keys/publicCipher.ts +2 -2
- package/src/keys/signVerify.ts +0 -5
- package/src/mlkem.ts +350 -0
- package/src/pbkdf2.ts +34 -5
- package/src/rsa.ts +1 -1
- package/src/specs/keyObjectHandle.nitro.ts +5 -0
- package/src/specs/kmac.nitro.ts +12 -0
- package/src/specs/mlKemKeyPair.nitro.ts +32 -0
- package/src/specs/x509certificate.nitro.ts +38 -0
- package/src/subtle.ts +551 -125
- package/src/utils/conversion.ts +10 -4
- package/src/utils/hashnames.ts +33 -2
- package/src/utils/types.ts +42 -5
- package/src/x509certificate.ts +277 -0
package/src/mlkem.ts
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import { NitroModules } from 'react-native-nitro-modules';
|
|
2
|
+
import type { MlKemKeyPair } from './specs/mlKemKeyPair.nitro';
|
|
3
|
+
import {
|
|
4
|
+
CryptoKey,
|
|
5
|
+
KeyObject,
|
|
6
|
+
PublicKeyObject,
|
|
7
|
+
PrivateKeyObject,
|
|
8
|
+
isCryptoKey,
|
|
9
|
+
} from './keys';
|
|
10
|
+
import type {
|
|
11
|
+
CryptoKeyPair,
|
|
12
|
+
KeyUsage,
|
|
13
|
+
SubtleAlgorithm,
|
|
14
|
+
EncapsulateResult,
|
|
15
|
+
BinaryLike,
|
|
16
|
+
} from './utils';
|
|
17
|
+
import {
|
|
18
|
+
hasAnyNotIn,
|
|
19
|
+
lazyDOMException,
|
|
20
|
+
getUsagesUnion,
|
|
21
|
+
KFormatType,
|
|
22
|
+
KeyEncoding,
|
|
23
|
+
isStringOrBuffer,
|
|
24
|
+
binaryLikeToArrayBuffer as toAB,
|
|
25
|
+
} from './utils';
|
|
26
|
+
|
|
27
|
+
export type MlKemVariant = 'ML-KEM-512' | 'ML-KEM-768' | 'ML-KEM-1024';
|
|
28
|
+
|
|
29
|
+
type MlKemKeyType = 'ml-kem-512' | 'ml-kem-768' | 'ml-kem-1024';
|
|
30
|
+
|
|
31
|
+
type KeyInput = BinaryLike | KeyObject | CryptoKey | KeyInputObject;
|
|
32
|
+
|
|
33
|
+
export interface KeyInputObject {
|
|
34
|
+
key: BinaryLike | KeyObject | CryptoKey;
|
|
35
|
+
format?: 'pem' | 'der';
|
|
36
|
+
type?: 'pkcs1' | 'pkcs8' | 'spki' | 'sec1';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const ML_KEM_VARIANTS: Record<MlKemKeyType, MlKemVariant> = {
|
|
40
|
+
'ml-kem-512': 'ML-KEM-512',
|
|
41
|
+
'ml-kem-768': 'ML-KEM-768',
|
|
42
|
+
'ml-kem-1024': 'ML-KEM-1024',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
function isMlKemKeyType(type: string): type is MlKemKeyType {
|
|
46
|
+
return type in ML_KEM_VARIANTS;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function unpackEncapsulateResult(packed: ArrayBuffer): EncapsulateResult {
|
|
50
|
+
const view = new DataView(packed);
|
|
51
|
+
const ciphertextLen = view.getUint32(0, true);
|
|
52
|
+
const sharedKeyLen = view.getUint32(4, true);
|
|
53
|
+
const headerSize = 8;
|
|
54
|
+
const ciphertext = packed.slice(headerSize, headerSize + ciphertextLen);
|
|
55
|
+
const sharedKey = packed.slice(
|
|
56
|
+
headerSize + ciphertextLen,
|
|
57
|
+
headerSize + ciphertextLen + sharedKeyLen,
|
|
58
|
+
);
|
|
59
|
+
return { ciphertext, sharedKey };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class MlKem {
|
|
63
|
+
variant: MlKemVariant;
|
|
64
|
+
native: MlKemKeyPair;
|
|
65
|
+
|
|
66
|
+
constructor(variant: MlKemVariant) {
|
|
67
|
+
this.variant = variant;
|
|
68
|
+
this.native = NitroModules.createHybridObject<MlKemKeyPair>('MlKemKeyPair');
|
|
69
|
+
this.native.setVariant(variant);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async generateKeyPair(): Promise<void> {
|
|
73
|
+
await this.native.generateKeyPair(
|
|
74
|
+
KFormatType.DER,
|
|
75
|
+
KeyEncoding.SPKI,
|
|
76
|
+
KFormatType.DER,
|
|
77
|
+
KeyEncoding.PKCS8,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
generateKeyPairSync(): void {
|
|
82
|
+
this.native.generateKeyPairSync(
|
|
83
|
+
KFormatType.DER,
|
|
84
|
+
KeyEncoding.SPKI,
|
|
85
|
+
KFormatType.DER,
|
|
86
|
+
KeyEncoding.PKCS8,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
getPublicKey(): ArrayBuffer {
|
|
91
|
+
return this.native.getPublicKey();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
getPrivateKey(): ArrayBuffer {
|
|
95
|
+
return this.native.getPrivateKey();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
setPublicKey(keyData: ArrayBuffer, format: number, type: number): void {
|
|
99
|
+
this.native.setPublicKey(keyData, format, type);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
setPrivateKey(keyData: ArrayBuffer, format: number, type: number): void {
|
|
103
|
+
this.native.setPrivateKey(keyData, format, type);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async encapsulate(): Promise<EncapsulateResult> {
|
|
107
|
+
const packed = await this.native.encapsulate();
|
|
108
|
+
return unpackEncapsulateResult(packed);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
encapsulateSync(): EncapsulateResult {
|
|
112
|
+
const packed = this.native.encapsulateSync();
|
|
113
|
+
return unpackEncapsulateResult(packed);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async decapsulate(ciphertext: ArrayBuffer): Promise<ArrayBuffer> {
|
|
117
|
+
return this.native.decapsulate(ciphertext);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
decapsulateSync(ciphertext: ArrayBuffer): ArrayBuffer {
|
|
121
|
+
return this.native.decapsulateSync(ciphertext);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function prepareKey(
|
|
126
|
+
key: KeyInput,
|
|
127
|
+
isPublic: boolean,
|
|
128
|
+
): { keyObject: KeyObject } {
|
|
129
|
+
if (key instanceof KeyObject) {
|
|
130
|
+
if (isPublic) {
|
|
131
|
+
if (key.type === 'secret') {
|
|
132
|
+
throw new Error('Cannot use secret key for encapsulation');
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
if (key.type !== 'private') {
|
|
136
|
+
throw new Error('Key must be a private key for decapsulation');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return { keyObject: key };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (isCryptoKey(key)) {
|
|
143
|
+
const cryptoKey = key as CryptoKey;
|
|
144
|
+
return prepareKey(cryptoKey.keyObject, isPublic);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (isStringOrBuffer(key)) {
|
|
148
|
+
const isPem = typeof key === 'string' && key.includes('-----BEGIN');
|
|
149
|
+
const format = isPem ? KFormatType.PEM : undefined;
|
|
150
|
+
const keyType = isPublic ? 'public' : 'private';
|
|
151
|
+
const keyData = toAB(key);
|
|
152
|
+
const keyObject = KeyObject.createKeyObject(keyType, keyData, format);
|
|
153
|
+
return { keyObject };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (typeof key === 'object' && 'key' in key) {
|
|
157
|
+
const keyObj = key as KeyInputObject;
|
|
158
|
+
const { key: data, format, type } = keyObj;
|
|
159
|
+
|
|
160
|
+
if (data instanceof KeyObject) {
|
|
161
|
+
return { keyObject: data };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (isCryptoKey(data)) {
|
|
165
|
+
return { keyObject: (data as CryptoKey).keyObject };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (!isStringOrBuffer(data)) {
|
|
169
|
+
throw new Error('Invalid key data type');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const isPem =
|
|
173
|
+
format === 'pem' ||
|
|
174
|
+
(typeof data === 'string' && data.includes('-----BEGIN'));
|
|
175
|
+
const kFormat = isPem
|
|
176
|
+
? KFormatType.PEM
|
|
177
|
+
: format === 'der'
|
|
178
|
+
? KFormatType.DER
|
|
179
|
+
: undefined;
|
|
180
|
+
|
|
181
|
+
let kType: KeyEncoding | undefined;
|
|
182
|
+
if (type === 'pkcs8') kType = KeyEncoding.PKCS8;
|
|
183
|
+
else if (type === 'pkcs1') kType = KeyEncoding.PKCS1;
|
|
184
|
+
else if (type === 'sec1') kType = KeyEncoding.SEC1;
|
|
185
|
+
else if (type === 'spki') kType = KeyEncoding.SPKI;
|
|
186
|
+
|
|
187
|
+
const keyType = isPublic ? 'public' : 'private';
|
|
188
|
+
const keyData = toAB(data);
|
|
189
|
+
const keyObject = KeyObject.createKeyObject(
|
|
190
|
+
keyType,
|
|
191
|
+
keyData,
|
|
192
|
+
kFormat,
|
|
193
|
+
kType,
|
|
194
|
+
);
|
|
195
|
+
return { keyObject };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
throw new Error('Invalid key input');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function getVariantFromKey(keyObject: KeyObject): MlKemVariant {
|
|
202
|
+
const keyType = keyObject.handle.getAsymmetricKeyType();
|
|
203
|
+
if (!isMlKemKeyType(keyType)) {
|
|
204
|
+
throw new Error(
|
|
205
|
+
`Key is not an ML-KEM key. Got asymmetricKeyType: ${keyType}`,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
return ML_KEM_VARIANTS[keyType];
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export function encapsulate(
|
|
212
|
+
key: KeyInput,
|
|
213
|
+
callback?: (err: Error | null, result?: EncapsulateResult) => void,
|
|
214
|
+
): EncapsulateResult | void {
|
|
215
|
+
const doEncapsulate = (): EncapsulateResult => {
|
|
216
|
+
if (key === null || key === undefined) {
|
|
217
|
+
throw new Error('Public key is required for encapsulation');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const { keyObject } = prepareKey(key, true);
|
|
221
|
+
const variant = getVariantFromKey(keyObject);
|
|
222
|
+
const mlkem = new MlKem(variant);
|
|
223
|
+
|
|
224
|
+
const keyData = keyObject.handle.exportKey(
|
|
225
|
+
KFormatType.DER,
|
|
226
|
+
KeyEncoding.SPKI,
|
|
227
|
+
);
|
|
228
|
+
mlkem.setPublicKey(keyData, KFormatType.DER, KeyEncoding.SPKI);
|
|
229
|
+
|
|
230
|
+
return mlkem.encapsulateSync();
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
if (callback) {
|
|
234
|
+
try {
|
|
235
|
+
const result = doEncapsulate();
|
|
236
|
+
process.nextTick(callback, null, result);
|
|
237
|
+
} catch (err) {
|
|
238
|
+
process.nextTick(callback, err as Error);
|
|
239
|
+
}
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return doEncapsulate();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export function decapsulate(
|
|
247
|
+
key: KeyInput,
|
|
248
|
+
ciphertext: BinaryLike,
|
|
249
|
+
callback?: (err: Error | null, result?: ArrayBuffer) => void,
|
|
250
|
+
): ArrayBuffer | void {
|
|
251
|
+
const doDecapsulate = (): ArrayBuffer => {
|
|
252
|
+
if (key === null || key === undefined) {
|
|
253
|
+
throw new Error('Private key is required for decapsulation');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const { keyObject } = prepareKey(key, false);
|
|
257
|
+
const variant = getVariantFromKey(keyObject);
|
|
258
|
+
const mlkem = new MlKem(variant);
|
|
259
|
+
|
|
260
|
+
const keyData = keyObject.handle.exportKey(
|
|
261
|
+
KFormatType.DER,
|
|
262
|
+
KeyEncoding.PKCS8,
|
|
263
|
+
);
|
|
264
|
+
mlkem.setPrivateKey(keyData, KFormatType.DER, KeyEncoding.PKCS8);
|
|
265
|
+
|
|
266
|
+
const ciphertextBuffer = toAB(ciphertext) as ArrayBuffer;
|
|
267
|
+
return mlkem.decapsulateSync(ciphertextBuffer);
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
if (callback) {
|
|
271
|
+
try {
|
|
272
|
+
const result = doDecapsulate();
|
|
273
|
+
process.nextTick(callback, null, result);
|
|
274
|
+
} catch (err) {
|
|
275
|
+
process.nextTick(callback, err as Error);
|
|
276
|
+
}
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return doDecapsulate();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export async function mlkem_generateKeyPairWebCrypto(
|
|
284
|
+
variant: MlKemVariant,
|
|
285
|
+
extractable: boolean,
|
|
286
|
+
keyUsages: KeyUsage[],
|
|
287
|
+
): Promise<CryptoKeyPair> {
|
|
288
|
+
if (
|
|
289
|
+
hasAnyNotIn(keyUsages, [
|
|
290
|
+
'encapsulateBits',
|
|
291
|
+
'encapsulateKey',
|
|
292
|
+
'decapsulateBits',
|
|
293
|
+
'decapsulateKey',
|
|
294
|
+
])
|
|
295
|
+
) {
|
|
296
|
+
throw lazyDOMException(
|
|
297
|
+
`Unsupported key usage for ${variant}`,
|
|
298
|
+
'SyntaxError',
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const publicUsages = getUsagesUnion(
|
|
303
|
+
keyUsages,
|
|
304
|
+
'encapsulateBits',
|
|
305
|
+
'encapsulateKey',
|
|
306
|
+
);
|
|
307
|
+
const privateUsages = getUsagesUnion(
|
|
308
|
+
keyUsages,
|
|
309
|
+
'decapsulateBits',
|
|
310
|
+
'decapsulateKey',
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
if (privateUsages.length === 0) {
|
|
314
|
+
throw lazyDOMException('Usages cannot be empty', 'SyntaxError');
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const mlkem = new MlKem(variant);
|
|
318
|
+
await mlkem.generateKeyPair();
|
|
319
|
+
|
|
320
|
+
const publicKeyData = mlkem.getPublicKey();
|
|
321
|
+
const privateKeyData = mlkem.getPrivateKey();
|
|
322
|
+
|
|
323
|
+
const pub = KeyObject.createKeyObject(
|
|
324
|
+
'public',
|
|
325
|
+
publicKeyData,
|
|
326
|
+
KFormatType.DER,
|
|
327
|
+
KeyEncoding.SPKI,
|
|
328
|
+
) as PublicKeyObject;
|
|
329
|
+
const publicKey = new CryptoKey(
|
|
330
|
+
pub,
|
|
331
|
+
{ name: variant } as SubtleAlgorithm,
|
|
332
|
+
publicUsages,
|
|
333
|
+
true,
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
const priv = KeyObject.createKeyObject(
|
|
337
|
+
'private',
|
|
338
|
+
privateKeyData,
|
|
339
|
+
KFormatType.DER,
|
|
340
|
+
KeyEncoding.PKCS8,
|
|
341
|
+
) as PrivateKeyObject;
|
|
342
|
+
const privateKey = new CryptoKey(
|
|
343
|
+
priv,
|
|
344
|
+
{ name: variant } as SubtleAlgorithm,
|
|
345
|
+
privateUsages,
|
|
346
|
+
extractable,
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
return { publicKey, privateKey };
|
|
350
|
+
}
|
package/src/pbkdf2.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
lazyDOMException,
|
|
9
9
|
normalizeHashName,
|
|
10
10
|
} from './utils';
|
|
11
|
-
import type {
|
|
11
|
+
import type { SubtleAlgorithm } from './utils';
|
|
12
12
|
import type { Pbkdf2 } from './specs/pbkdf2.nitro';
|
|
13
13
|
import { promisify } from 'util';
|
|
14
14
|
import type { CryptoKey } from './keys';
|
|
@@ -31,6 +31,33 @@ function getNative(): Pbkdf2 {
|
|
|
31
31
|
return native;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
const MAX_INT32 = 2147483647;
|
|
35
|
+
|
|
36
|
+
function validateParameters(iterations: number, keylen: number): void {
|
|
37
|
+
if (typeof iterations !== 'number') {
|
|
38
|
+
throw new TypeError('Iterations not a number');
|
|
39
|
+
}
|
|
40
|
+
if (typeof keylen !== 'number') {
|
|
41
|
+
throw new TypeError('Key length not a number');
|
|
42
|
+
}
|
|
43
|
+
if (
|
|
44
|
+
iterations < 1 ||
|
|
45
|
+
!Number.isFinite(iterations) ||
|
|
46
|
+
!Number.isInteger(iterations) ||
|
|
47
|
+
iterations > MAX_INT32
|
|
48
|
+
) {
|
|
49
|
+
throw new TypeError('Bad iterations');
|
|
50
|
+
}
|
|
51
|
+
if (
|
|
52
|
+
keylen < 0 ||
|
|
53
|
+
!Number.isFinite(keylen) ||
|
|
54
|
+
!Number.isInteger(keylen) ||
|
|
55
|
+
keylen > MAX_INT32
|
|
56
|
+
) {
|
|
57
|
+
throw new TypeError('Bad key length');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
34
61
|
function sanitizeInput(input: BinaryLike, errorMsg: string): ArrayBuffer {
|
|
35
62
|
try {
|
|
36
63
|
return binaryLikeToArrayBuffer(input);
|
|
@@ -51,6 +78,7 @@ export function pbkdf2(
|
|
|
51
78
|
if (callback === undefined || typeof callback !== 'function') {
|
|
52
79
|
throw new Error('No callback provided to pbkdf2');
|
|
53
80
|
}
|
|
81
|
+
validateParameters(iterations, keylen);
|
|
54
82
|
const sanitizedPassword = sanitizeInput(password, WRONG_PASS);
|
|
55
83
|
const sanitizedSalt = sanitizeInput(salt, WRONG_SALT);
|
|
56
84
|
const normalizedDigest = normalizeHashName(digest, HashContext.Node);
|
|
@@ -79,12 +107,13 @@ export function pbkdf2Sync(
|
|
|
79
107
|
salt: Salt,
|
|
80
108
|
iterations: number,
|
|
81
109
|
keylen: number,
|
|
82
|
-
digest
|
|
110
|
+
digest: string,
|
|
83
111
|
): Buffer {
|
|
112
|
+
validateParameters(iterations, keylen);
|
|
84
113
|
const sanitizedPassword = sanitizeInput(password, WRONG_PASS);
|
|
85
114
|
const sanitizedSalt = sanitizeInput(salt, WRONG_SALT);
|
|
86
115
|
|
|
87
|
-
const algo =
|
|
116
|
+
const algo = normalizeHashName(digest, HashContext.Node);
|
|
88
117
|
getNative();
|
|
89
118
|
const result: ArrayBuffer = native.pbkdf2Sync(
|
|
90
119
|
sanitizedPassword,
|
|
@@ -104,7 +133,7 @@ const pbkdf2WithDigest = (
|
|
|
104
133
|
salt: Salt,
|
|
105
134
|
iterations: number,
|
|
106
135
|
keylen: number,
|
|
107
|
-
digest:
|
|
136
|
+
digest: string,
|
|
108
137
|
callback: Pbkdf2Callback,
|
|
109
138
|
) => pbkdf2(password, salt, iterations, keylen, digest, callback);
|
|
110
139
|
|
|
@@ -142,7 +171,7 @@ export async function pbkdf2DeriveBits(
|
|
|
142
171
|
sanitizedSalt,
|
|
143
172
|
iterations,
|
|
144
173
|
length / 8,
|
|
145
|
-
normalizedHash
|
|
174
|
+
normalizedHash,
|
|
146
175
|
);
|
|
147
176
|
if (!result) {
|
|
148
177
|
throw lazyDOMException(
|
package/src/rsa.ts
CHANGED
|
@@ -27,6 +27,11 @@ export interface KeyObjectHandle
|
|
|
27
27
|
passphrase?: ArrayBuffer,
|
|
28
28
|
): boolean;
|
|
29
29
|
initECRaw(namedCurve: string, keyData: ArrayBuffer): boolean;
|
|
30
|
+
initPqcRaw(
|
|
31
|
+
algorithmName: string,
|
|
32
|
+
keyData: ArrayBuffer,
|
|
33
|
+
isPublic: boolean,
|
|
34
|
+
): boolean;
|
|
30
35
|
initJwk(keyData: JWK, namedCurve?: NamedCurve): KeyType | undefined;
|
|
31
36
|
keyDetail(): KeyDetail;
|
|
32
37
|
keyEquals(other: KeyObjectHandle): boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
|
|
3
|
+
export interface Kmac extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
|
|
4
|
+
createKmac(
|
|
5
|
+
algorithm: string,
|
|
6
|
+
key: ArrayBuffer,
|
|
7
|
+
outputLength: number,
|
|
8
|
+
customization?: ArrayBuffer,
|
|
9
|
+
): void;
|
|
10
|
+
update(data: ArrayBuffer): void;
|
|
11
|
+
digest(): ArrayBuffer;
|
|
12
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
|
|
3
|
+
export interface MlKemKeyPair
|
|
4
|
+
extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
|
|
5
|
+
setVariant(variant: string): void;
|
|
6
|
+
|
|
7
|
+
generateKeyPair(
|
|
8
|
+
publicFormat: number,
|
|
9
|
+
publicType: number,
|
|
10
|
+
privateFormat: number,
|
|
11
|
+
privateType: number,
|
|
12
|
+
): Promise<void>;
|
|
13
|
+
|
|
14
|
+
generateKeyPairSync(
|
|
15
|
+
publicFormat: number,
|
|
16
|
+
publicType: number,
|
|
17
|
+
privateFormat: number,
|
|
18
|
+
privateType: number,
|
|
19
|
+
): void;
|
|
20
|
+
|
|
21
|
+
getPublicKey(): ArrayBuffer;
|
|
22
|
+
getPrivateKey(): ArrayBuffer;
|
|
23
|
+
|
|
24
|
+
setPublicKey(keyData: ArrayBuffer, format: number, type: number): void;
|
|
25
|
+
setPrivateKey(keyData: ArrayBuffer, format: number, type: number): void;
|
|
26
|
+
|
|
27
|
+
encapsulate(): Promise<ArrayBuffer>;
|
|
28
|
+
encapsulateSync(): ArrayBuffer;
|
|
29
|
+
|
|
30
|
+
decapsulate(ciphertext: ArrayBuffer): Promise<ArrayBuffer>;
|
|
31
|
+
decapsulateSync(ciphertext: ArrayBuffer): ArrayBuffer;
|
|
32
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
import type { KeyObjectHandle } from './keyObjectHandle.nitro';
|
|
3
|
+
|
|
4
|
+
export interface X509CertificateHandle
|
|
5
|
+
extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
|
|
6
|
+
init(buffer: ArrayBuffer): void;
|
|
7
|
+
|
|
8
|
+
subject(): string;
|
|
9
|
+
subjectAltName(): string;
|
|
10
|
+
issuer(): string;
|
|
11
|
+
infoAccess(): string;
|
|
12
|
+
validFrom(): string;
|
|
13
|
+
validTo(): string;
|
|
14
|
+
validFromDate(): number;
|
|
15
|
+
validToDate(): number;
|
|
16
|
+
signatureAlgorithm(): string;
|
|
17
|
+
signatureAlgorithmOid(): string;
|
|
18
|
+
serialNumber(): string;
|
|
19
|
+
|
|
20
|
+
fingerprint(): string;
|
|
21
|
+
fingerprint256(): string;
|
|
22
|
+
fingerprint512(): string;
|
|
23
|
+
|
|
24
|
+
raw(): ArrayBuffer;
|
|
25
|
+
pem(): string;
|
|
26
|
+
|
|
27
|
+
publicKey(): KeyObjectHandle;
|
|
28
|
+
keyUsage(): string[];
|
|
29
|
+
|
|
30
|
+
ca(): boolean;
|
|
31
|
+
checkIssued(other: X509CertificateHandle): boolean;
|
|
32
|
+
checkPrivateKey(key: KeyObjectHandle): boolean;
|
|
33
|
+
verify(key: KeyObjectHandle): boolean;
|
|
34
|
+
|
|
35
|
+
checkHost(name: string, flags: number): string | undefined;
|
|
36
|
+
checkEmail(email: string, flags: number): string | undefined;
|
|
37
|
+
checkIP(ip: string): string | undefined;
|
|
38
|
+
}
|