1 |
|
2 |
|
3 |
|
4 |
|
5 | 'use strict';
|
6 |
|
7 | var core = require('webcrypto-core');
|
8 | var buffer = require('buffer');
|
9 | var crypto = require('crypto');
|
10 | var process = require('process');
|
11 | var tslib = require('tslib');
|
12 | var jsonSchema = require('@peculiar/json-schema');
|
13 | var pvtsutils = require('pvtsutils');
|
14 | var asn1Schema = require('@peculiar/asn1-schema');
|
15 |
|
16 | function _interopNamespaceDefault(e) {
|
17 | var n = Object.create(null);
|
18 | if (e) {
|
19 | Object.keys(e).forEach(function (k) {
|
20 | if (k !== 'default') {
|
21 | var d = Object.getOwnPropertyDescriptor(e, k);
|
22 | Object.defineProperty(n, k, d.get ? d : {
|
23 | enumerable: true,
|
24 | get: function () { return e[k]; }
|
25 | });
|
26 | }
|
27 | });
|
28 | }
|
29 | n.default = e;
|
30 | return Object.freeze(n);
|
31 | }
|
32 |
|
33 | var core__namespace = _interopNamespaceDefault(core);
|
34 | var crypto__namespace = _interopNamespaceDefault(crypto);
|
35 | var process__namespace = _interopNamespaceDefault(process);
|
36 |
|
37 | const JsonBase64UrlConverter = {
|
38 | fromJSON: (value) => buffer.Buffer.from(pvtsutils.Convert.FromBase64Url(value)),
|
39 | toJSON: (value) => pvtsutils.Convert.ToBase64Url(value),
|
40 | };
|
41 |
|
42 | class CryptoKey extends core__namespace.CryptoKey {
|
43 | constructor() {
|
44 | super(...arguments);
|
45 | this.data = buffer.Buffer.alloc(0);
|
46 | this.algorithm = { name: "" };
|
47 | this.extractable = false;
|
48 | this.type = "secret";
|
49 | this.usages = [];
|
50 | this.kty = "oct";
|
51 | this.alg = "";
|
52 | }
|
53 | }
|
54 | tslib.__decorate([
|
55 | jsonSchema.JsonProp({ name: "ext", type: jsonSchema.JsonPropTypes.Boolean, optional: true })
|
56 | ], CryptoKey.prototype, "extractable", void 0);
|
57 | tslib.__decorate([
|
58 | jsonSchema.JsonProp({ name: "key_ops", type: jsonSchema.JsonPropTypes.String, repeated: true, optional: true })
|
59 | ], CryptoKey.prototype, "usages", void 0);
|
60 | tslib.__decorate([
|
61 | jsonSchema.JsonProp({ type: jsonSchema.JsonPropTypes.String })
|
62 | ], CryptoKey.prototype, "kty", void 0);
|
63 | tslib.__decorate([
|
64 | jsonSchema.JsonProp({ type: jsonSchema.JsonPropTypes.String, optional: true })
|
65 | ], CryptoKey.prototype, "alg", void 0);
|
66 |
|
67 | class SymmetricKey extends CryptoKey {
|
68 | constructor() {
|
69 | super(...arguments);
|
70 | this.kty = "oct";
|
71 | this.type = "secret";
|
72 | }
|
73 | }
|
74 |
|
75 | class AsymmetricKey extends CryptoKey {
|
76 | }
|
77 |
|
78 | class AesCryptoKey extends SymmetricKey {
|
79 | get alg() {
|
80 | switch (this.algorithm.name.toUpperCase()) {
|
81 | case "AES-CBC":
|
82 | return `A${this.algorithm.length}CBC`;
|
83 | case "AES-CTR":
|
84 | return `A${this.algorithm.length}CTR`;
|
85 | case "AES-GCM":
|
86 | return `A${this.algorithm.length}GCM`;
|
87 | case "AES-KW":
|
88 | return `A${this.algorithm.length}KW`;
|
89 | case "AES-CMAC":
|
90 | return `A${this.algorithm.length}CMAC`;
|
91 | case "AES-ECB":
|
92 | return `A${this.algorithm.length}ECB`;
|
93 | default:
|
94 | throw new core__namespace.AlgorithmError("Unsupported algorithm name");
|
95 | }
|
96 | }
|
97 | set alg(value) {
|
98 | }
|
99 | }
|
100 | tslib.__decorate([
|
101 | jsonSchema.JsonProp({ name: "k", converter: JsonBase64UrlConverter })
|
102 | ], AesCryptoKey.prototype, "data", void 0);
|
103 |
|
104 | class AesCrypto {
|
105 | static async generateKey(algorithm, extractable, keyUsages) {
|
106 | const key = new AesCryptoKey();
|
107 | key.algorithm = algorithm;
|
108 | key.extractable = extractable;
|
109 | key.usages = keyUsages;
|
110 | key.data = crypto.randomBytes(algorithm.length >> 3);
|
111 | return key;
|
112 | }
|
113 | static async exportKey(format, key) {
|
114 | if (!(key instanceof AesCryptoKey)) {
|
115 | throw new Error("key: Is not AesCryptoKey");
|
116 | }
|
117 | switch (format.toLowerCase()) {
|
118 | case "jwk":
|
119 | return jsonSchema.JsonSerializer.toJSON(key);
|
120 | case "raw":
|
121 | return new Uint8Array(key.data).buffer;
|
122 | default:
|
123 | throw new core__namespace.OperationError("format: Must be 'jwk' or 'raw'");
|
124 | }
|
125 | }
|
126 | static async importKey(format, keyData, algorithm, extractable, keyUsages) {
|
127 | let key;
|
128 | switch (format.toLowerCase()) {
|
129 | case "jwk":
|
130 | key = jsonSchema.JsonParser.fromJSON(keyData, { targetSchema: AesCryptoKey });
|
131 | break;
|
132 | case "raw":
|
133 | key = new AesCryptoKey();
|
134 | key.data = buffer.Buffer.from(keyData);
|
135 | break;
|
136 | default:
|
137 | throw new core__namespace.OperationError("format: Must be 'jwk' or 'raw'");
|
138 | }
|
139 | key.algorithm = algorithm;
|
140 | key.algorithm.length = key.data.length << 3;
|
141 | key.extractable = extractable;
|
142 | key.usages = keyUsages;
|
143 | switch (key.algorithm.length) {
|
144 | case 128:
|
145 | case 192:
|
146 | case 256:
|
147 | break;
|
148 | default:
|
149 | throw new core__namespace.OperationError("keyData: Is wrong key length");
|
150 | }
|
151 | return key;
|
152 | }
|
153 | static async encrypt(algorithm, key, data) {
|
154 | switch (algorithm.name.toUpperCase()) {
|
155 | case "AES-CBC":
|
156 | return this.encryptAesCBC(algorithm, key, buffer.Buffer.from(data));
|
157 | case "AES-CTR":
|
158 | return this.encryptAesCTR(algorithm, key, buffer.Buffer.from(data));
|
159 | case "AES-GCM":
|
160 | return this.encryptAesGCM(algorithm, key, buffer.Buffer.from(data));
|
161 | case "AES-KW":
|
162 | return this.encryptAesKW(algorithm, key, buffer.Buffer.from(data));
|
163 | case "AES-ECB":
|
164 | return this.encryptAesECB(algorithm, key, buffer.Buffer.from(data));
|
165 | default:
|
166 | throw new core__namespace.OperationError("algorithm: Is not recognized");
|
167 | }
|
168 | }
|
169 | static async decrypt(algorithm, key, data) {
|
170 | if (!(key instanceof AesCryptoKey)) {
|
171 | throw new Error("key: Is not AesCryptoKey");
|
172 | }
|
173 | switch (algorithm.name.toUpperCase()) {
|
174 | case "AES-CBC":
|
175 | return this.decryptAesCBC(algorithm, key, buffer.Buffer.from(data));
|
176 | case "AES-CTR":
|
177 | return this.decryptAesCTR(algorithm, key, buffer.Buffer.from(data));
|
178 | case "AES-GCM":
|
179 | return this.decryptAesGCM(algorithm, key, buffer.Buffer.from(data));
|
180 | case "AES-KW":
|
181 | return this.decryptAesKW(algorithm, key, buffer.Buffer.from(data));
|
182 | case "AES-ECB":
|
183 | return this.decryptAesECB(algorithm, key, buffer.Buffer.from(data));
|
184 | default:
|
185 | throw new core__namespace.OperationError("algorithm: Is not recognized");
|
186 | }
|
187 | }
|
188 | static async encryptAesCBC(algorithm, key, data) {
|
189 | const cipher = crypto.createCipheriv(`aes-${key.algorithm.length}-cbc`, key.data, new Uint8Array(algorithm.iv));
|
190 | let enc = cipher.update(data);
|
191 | enc = buffer.Buffer.concat([enc, cipher.final()]);
|
192 | const res = new Uint8Array(enc).buffer;
|
193 | return res;
|
194 | }
|
195 | static async decryptAesCBC(algorithm, key, data) {
|
196 | const decipher = crypto.createDecipheriv(`aes-${key.algorithm.length}-cbc`, key.data, new Uint8Array(algorithm.iv));
|
197 | let dec = decipher.update(data);
|
198 | dec = buffer.Buffer.concat([dec, decipher.final()]);
|
199 | return new Uint8Array(dec).buffer;
|
200 | }
|
201 | static async encryptAesCTR(algorithm, key, data) {
|
202 | const cipher = crypto.createCipheriv(`aes-${key.algorithm.length}-ctr`, key.data, buffer.Buffer.from(algorithm.counter));
|
203 | let enc = cipher.update(data);
|
204 | enc = buffer.Buffer.concat([enc, cipher.final()]);
|
205 | const res = new Uint8Array(enc).buffer;
|
206 | return res;
|
207 | }
|
208 | static async decryptAesCTR(algorithm, key, data) {
|
209 | const decipher = crypto.createDecipheriv(`aes-${key.algorithm.length}-ctr`, key.data, new Uint8Array(algorithm.counter));
|
210 | let dec = decipher.update(data);
|
211 | dec = buffer.Buffer.concat([dec, decipher.final()]);
|
212 | return new Uint8Array(dec).buffer;
|
213 | }
|
214 | static async encryptAesGCM(algorithm, key, data) {
|
215 | const cipher = crypto.createCipheriv(`aes-${key.algorithm.length}-gcm`, key.data, buffer.Buffer.from(algorithm.iv), {
|
216 | authTagLength: (algorithm.tagLength || 128) >> 3,
|
217 | });
|
218 | if (algorithm.additionalData) {
|
219 | cipher.setAAD(buffer.Buffer.from(algorithm.additionalData));
|
220 | }
|
221 | let enc = cipher.update(data);
|
222 | enc = buffer.Buffer.concat([enc, cipher.final(), cipher.getAuthTag()]);
|
223 | const res = new Uint8Array(enc).buffer;
|
224 | return res;
|
225 | }
|
226 | static async decryptAesGCM(algorithm, key, data) {
|
227 | const decipher = crypto.createDecipheriv(`aes-${key.algorithm.length}-gcm`, key.data, new Uint8Array(algorithm.iv));
|
228 | const tagLength = (algorithm.tagLength || 128) >> 3;
|
229 | const enc = data.slice(0, data.length - tagLength);
|
230 | const tag = data.slice(data.length - tagLength);
|
231 | if (algorithm.additionalData) {
|
232 | decipher.setAAD(buffer.Buffer.from(algorithm.additionalData));
|
233 | }
|
234 | decipher.setAuthTag(tag);
|
235 | let dec = decipher.update(enc);
|
236 | dec = buffer.Buffer.concat([dec, decipher.final()]);
|
237 | return new Uint8Array(dec).buffer;
|
238 | }
|
239 | static async encryptAesKW(algorithm, key, data) {
|
240 | const cipher = crypto.createCipheriv(`id-aes${key.algorithm.length}-wrap`, key.data, this.AES_KW_IV);
|
241 | let enc = cipher.update(data);
|
242 | enc = buffer.Buffer.concat([enc, cipher.final()]);
|
243 | return new Uint8Array(enc).buffer;
|
244 | }
|
245 | static async decryptAesKW(algorithm, key, data) {
|
246 | const decipher = crypto.createDecipheriv(`id-aes${key.algorithm.length}-wrap`, key.data, this.AES_KW_IV);
|
247 | let dec = decipher.update(data);
|
248 | dec = buffer.Buffer.concat([dec, decipher.final()]);
|
249 | return new Uint8Array(dec).buffer;
|
250 | }
|
251 | static async encryptAesECB(algorithm, key, data) {
|
252 | const cipher = crypto.createCipheriv(`aes-${key.algorithm.length}-ecb`, key.data, new Uint8Array(0));
|
253 | let enc = cipher.update(data);
|
254 | enc = buffer.Buffer.concat([enc, cipher.final()]);
|
255 | const res = new Uint8Array(enc).buffer;
|
256 | return res;
|
257 | }
|
258 | static async decryptAesECB(algorithm, key, data) {
|
259 | const decipher = crypto.createDecipheriv(`aes-${key.algorithm.length}-ecb`, key.data, new Uint8Array(0));
|
260 | let dec = decipher.update(data);
|
261 | dec = buffer.Buffer.concat([dec, decipher.final()]);
|
262 | return new Uint8Array(dec).buffer;
|
263 | }
|
264 | }
|
265 | AesCrypto.AES_KW_IV = buffer.Buffer.from("A6A6A6A6A6A6A6A6", "hex");
|
266 |
|
267 | const keyStorage = new WeakMap();
|
268 | function getCryptoKey(key) {
|
269 | const res = keyStorage.get(key);
|
270 | if (!res) {
|
271 | throw new core__namespace.OperationError("Cannot get CryptoKey from secure storage");
|
272 | }
|
273 | return res;
|
274 | }
|
275 | function setCryptoKey(value) {
|
276 | const key = core__namespace.CryptoKey.create(value.algorithm, value.type, value.extractable, value.usages);
|
277 | Object.freeze(key);
|
278 | keyStorage.set(key, value);
|
279 | return key;
|
280 | }
|
281 |
|
282 | class AesCbcProvider extends core__namespace.AesCbcProvider {
|
283 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
284 | const key = await AesCrypto.generateKey({
|
285 | name: this.name,
|
286 | length: algorithm.length,
|
287 | }, extractable, keyUsages);
|
288 | return setCryptoKey(key);
|
289 | }
|
290 | async onEncrypt(algorithm, key, data) {
|
291 | return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
292 | }
|
293 | async onDecrypt(algorithm, key, data) {
|
294 | return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
295 | }
|
296 | async onExportKey(format, key) {
|
297 | return AesCrypto.exportKey(format, getCryptoKey(key));
|
298 | }
|
299 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
300 | const key = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages);
|
301 | return setCryptoKey(key);
|
302 | }
|
303 | checkCryptoKey(key, keyUsage) {
|
304 | super.checkCryptoKey(key, keyUsage);
|
305 | if (!(getCryptoKey(key) instanceof AesCryptoKey)) {
|
306 | throw new TypeError("key: Is not a AesCryptoKey");
|
307 | }
|
308 | }
|
309 | }
|
310 |
|
311 | const zero = buffer.Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
312 | const rb = buffer.Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135]);
|
313 | const blockSize = 16;
|
314 | function bitShiftLeft(buffer$1) {
|
315 | const shifted = buffer.Buffer.alloc(buffer$1.length);
|
316 | const last = buffer$1.length - 1;
|
317 | for (let index = 0; index < last; index++) {
|
318 | shifted[index] = buffer$1[index] << 1;
|
319 | if (buffer$1[index + 1] & 0x80) {
|
320 | shifted[index] += 0x01;
|
321 | }
|
322 | }
|
323 | shifted[last] = buffer$1[last] << 1;
|
324 | return shifted;
|
325 | }
|
326 | function xor(a, b) {
|
327 | const length = Math.min(a.length, b.length);
|
328 | const output = buffer.Buffer.alloc(length);
|
329 | for (let index = 0; index < length; index++) {
|
330 | output[index] = a[index] ^ b[index];
|
331 | }
|
332 | return output;
|
333 | }
|
334 | function aes(key, message) {
|
335 | const cipher = crypto__namespace.createCipheriv(`aes${key.length << 3}`, key, zero);
|
336 | const result = cipher.update(message);
|
337 | cipher.final();
|
338 | return result;
|
339 | }
|
340 | function getMessageBlock(message, blockIndex) {
|
341 | const block = buffer.Buffer.alloc(blockSize);
|
342 | const start = blockIndex * blockSize;
|
343 | const end = start + blockSize;
|
344 | message.copy(block, 0, start, end);
|
345 | return block;
|
346 | }
|
347 | function getPaddedMessageBlock(message, blockIndex) {
|
348 | const block = buffer.Buffer.alloc(blockSize);
|
349 | const start = blockIndex * blockSize;
|
350 | const end = message.length;
|
351 | block.fill(0);
|
352 | message.copy(block, 0, start, end);
|
353 | block[end - start] = 0x80;
|
354 | return block;
|
355 | }
|
356 | function generateSubkeys(key) {
|
357 | const l = aes(key, zero);
|
358 | let subkey1 = bitShiftLeft(l);
|
359 | if (l[0] & 0x80) {
|
360 | subkey1 = xor(subkey1, rb);
|
361 | }
|
362 | let subkey2 = bitShiftLeft(subkey1);
|
363 | if (subkey1[0] & 0x80) {
|
364 | subkey2 = xor(subkey2, rb);
|
365 | }
|
366 | return { subkey1, subkey2 };
|
367 | }
|
368 | function aesCmac(key, message) {
|
369 | const subkeys = generateSubkeys(key);
|
370 | let blockCount = Math.ceil(message.length / blockSize);
|
371 | let lastBlockCompleteFlag;
|
372 | let lastBlock;
|
373 | if (blockCount === 0) {
|
374 | blockCount = 1;
|
375 | lastBlockCompleteFlag = false;
|
376 | }
|
377 | else {
|
378 | lastBlockCompleteFlag = (message.length % blockSize === 0);
|
379 | }
|
380 | const lastBlockIndex = blockCount - 1;
|
381 | if (lastBlockCompleteFlag) {
|
382 | lastBlock = xor(getMessageBlock(message, lastBlockIndex), subkeys.subkey1);
|
383 | }
|
384 | else {
|
385 | lastBlock = xor(getPaddedMessageBlock(message, lastBlockIndex), subkeys.subkey2);
|
386 | }
|
387 | let x = zero;
|
388 | let y;
|
389 | for (let index = 0; index < lastBlockIndex; index++) {
|
390 | y = xor(x, getMessageBlock(message, index));
|
391 | x = aes(key, y);
|
392 | }
|
393 | y = xor(lastBlock, x);
|
394 | return aes(key, y);
|
395 | }
|
396 | class AesCmacProvider extends core__namespace.AesCmacProvider {
|
397 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
398 | const key = await AesCrypto.generateKey({
|
399 | name: this.name,
|
400 | length: algorithm.length,
|
401 | }, extractable, keyUsages);
|
402 | return setCryptoKey(key);
|
403 | }
|
404 | async onSign(algorithm, key, data) {
|
405 | const result = aesCmac(getCryptoKey(key).data, buffer.Buffer.from(data));
|
406 | return new Uint8Array(result).buffer;
|
407 | }
|
408 | async onVerify(algorithm, key, signature, data) {
|
409 | const signature2 = await this.sign(algorithm, key, data);
|
410 | return buffer.Buffer.from(signature).compare(buffer.Buffer.from(signature2)) === 0;
|
411 | }
|
412 | async onExportKey(format, key) {
|
413 | return AesCrypto.exportKey(format, getCryptoKey(key));
|
414 | }
|
415 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
416 | const res = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages);
|
417 | return setCryptoKey(res);
|
418 | }
|
419 | checkCryptoKey(key, keyUsage) {
|
420 | super.checkCryptoKey(key, keyUsage);
|
421 | if (!(getCryptoKey(key) instanceof AesCryptoKey)) {
|
422 | throw new TypeError("key: Is not a AesCryptoKey");
|
423 | }
|
424 | }
|
425 | }
|
426 |
|
427 | class AesCtrProvider extends core__namespace.AesCtrProvider {
|
428 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
429 | const key = await AesCrypto.generateKey({
|
430 | name: this.name,
|
431 | length: algorithm.length,
|
432 | }, extractable, keyUsages);
|
433 | return setCryptoKey(key);
|
434 | }
|
435 | async onEncrypt(algorithm, key, data) {
|
436 | return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
437 | }
|
438 | async onDecrypt(algorithm, key, data) {
|
439 | return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
440 | }
|
441 | async onExportKey(format, key) {
|
442 | return AesCrypto.exportKey(format, getCryptoKey(key));
|
443 | }
|
444 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
445 | const res = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages);
|
446 | return setCryptoKey(res);
|
447 | }
|
448 | checkCryptoKey(key, keyUsage) {
|
449 | super.checkCryptoKey(key, keyUsage);
|
450 | if (!(getCryptoKey(key) instanceof AesCryptoKey)) {
|
451 | throw new TypeError("key: Is not a AesCryptoKey");
|
452 | }
|
453 | }
|
454 | }
|
455 |
|
456 | class AesGcmProvider extends core__namespace.AesGcmProvider {
|
457 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
458 | const key = await AesCrypto.generateKey({
|
459 | name: this.name,
|
460 | length: algorithm.length,
|
461 | }, extractable, keyUsages);
|
462 | return setCryptoKey(key);
|
463 | }
|
464 | async onEncrypt(algorithm, key, data) {
|
465 | return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
466 | }
|
467 | async onDecrypt(algorithm, key, data) {
|
468 | return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
469 | }
|
470 | async onExportKey(format, key) {
|
471 | return AesCrypto.exportKey(format, getCryptoKey(key));
|
472 | }
|
473 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
474 | const res = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages);
|
475 | return setCryptoKey(res);
|
476 | }
|
477 | checkCryptoKey(key, keyUsage) {
|
478 | super.checkCryptoKey(key, keyUsage);
|
479 | if (!(getCryptoKey(key) instanceof AesCryptoKey)) {
|
480 | throw new TypeError("key: Is not a AesCryptoKey");
|
481 | }
|
482 | }
|
483 | }
|
484 |
|
485 | class AesKwProvider extends core__namespace.AesKwProvider {
|
486 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
487 | const res = await AesCrypto.generateKey({
|
488 | name: this.name,
|
489 | length: algorithm.length,
|
490 | }, extractable, keyUsages);
|
491 | return setCryptoKey(res);
|
492 | }
|
493 | async onExportKey(format, key) {
|
494 | return AesCrypto.exportKey(format, getCryptoKey(key));
|
495 | }
|
496 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
497 | const res = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages);
|
498 | return setCryptoKey(res);
|
499 | }
|
500 | async onEncrypt(algorithm, key, data) {
|
501 | return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
502 | }
|
503 | async onDecrypt(algorithm, key, data) {
|
504 | return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
505 | }
|
506 | checkCryptoKey(key, keyUsage) {
|
507 | super.checkCryptoKey(key, keyUsage);
|
508 | if (!(getCryptoKey(key) instanceof AesCryptoKey)) {
|
509 | throw new TypeError("key: Is not a AesCryptoKey");
|
510 | }
|
511 | }
|
512 | }
|
513 |
|
514 | class AesEcbProvider extends core__namespace.AesEcbProvider {
|
515 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
516 | const key = await AesCrypto.generateKey({
|
517 | name: this.name,
|
518 | length: algorithm.length,
|
519 | }, extractable, keyUsages);
|
520 | return setCryptoKey(key);
|
521 | }
|
522 | async onEncrypt(algorithm, key, data) {
|
523 | return AesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
524 | }
|
525 | async onDecrypt(algorithm, key, data) {
|
526 | return AesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
527 | }
|
528 | async onExportKey(format, key) {
|
529 | return AesCrypto.exportKey(format, getCryptoKey(key));
|
530 | }
|
531 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
532 | const res = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages);
|
533 | return setCryptoKey(res);
|
534 | }
|
535 | checkCryptoKey(key, keyUsage) {
|
536 | super.checkCryptoKey(key, keyUsage);
|
537 | if (!(getCryptoKey(key) instanceof AesCryptoKey)) {
|
538 | throw new TypeError("key: Is not a AesCryptoKey");
|
539 | }
|
540 | }
|
541 | }
|
542 |
|
543 | class DesCryptoKey extends SymmetricKey {
|
544 | get alg() {
|
545 | switch (this.algorithm.name.toUpperCase()) {
|
546 | case "DES-CBC":
|
547 | return `DES-CBC`;
|
548 | case "DES-EDE3-CBC":
|
549 | return `3DES-CBC`;
|
550 | default:
|
551 | throw new core__namespace.AlgorithmError("Unsupported algorithm name");
|
552 | }
|
553 | }
|
554 | set alg(value) {
|
555 | }
|
556 | }
|
557 | tslib.__decorate([
|
558 | jsonSchema.JsonProp({ name: "k", converter: JsonBase64UrlConverter })
|
559 | ], DesCryptoKey.prototype, "data", void 0);
|
560 |
|
561 | class DesCrypto {
|
562 | static async generateKey(algorithm, extractable, keyUsages) {
|
563 | const key = new DesCryptoKey();
|
564 | key.algorithm = algorithm;
|
565 | key.extractable = extractable;
|
566 | key.usages = keyUsages;
|
567 | key.data = crypto.randomBytes(algorithm.length >> 3);
|
568 | return key;
|
569 | }
|
570 | static async exportKey(format, key) {
|
571 | switch (format.toLowerCase()) {
|
572 | case "jwk":
|
573 | return jsonSchema.JsonSerializer.toJSON(key);
|
574 | case "raw":
|
575 | return new Uint8Array(key.data).buffer;
|
576 | default:
|
577 | throw new core__namespace.OperationError("format: Must be 'jwk' or 'raw'");
|
578 | }
|
579 | }
|
580 | static async importKey(format, keyData, algorithm, extractable, keyUsages) {
|
581 | let key;
|
582 | switch (format.toLowerCase()) {
|
583 | case "jwk":
|
584 | key = jsonSchema.JsonParser.fromJSON(keyData, { targetSchema: DesCryptoKey });
|
585 | break;
|
586 | case "raw":
|
587 | key = new DesCryptoKey();
|
588 | key.data = buffer.Buffer.from(keyData);
|
589 | break;
|
590 | default:
|
591 | throw new core__namespace.OperationError("format: Must be 'jwk' or 'raw'");
|
592 | }
|
593 | key.algorithm = algorithm;
|
594 | key.extractable = extractable;
|
595 | key.usages = keyUsages;
|
596 | return key;
|
597 | }
|
598 | static async encrypt(algorithm, key, data) {
|
599 | switch (algorithm.name.toUpperCase()) {
|
600 | case "DES-CBC":
|
601 | return this.encryptDesCBC(algorithm, key, buffer.Buffer.from(data));
|
602 | case "DES-EDE3-CBC":
|
603 | return this.encryptDesEDE3CBC(algorithm, key, buffer.Buffer.from(data));
|
604 | default:
|
605 | throw new core__namespace.OperationError("algorithm: Is not recognized");
|
606 | }
|
607 | }
|
608 | static async decrypt(algorithm, key, data) {
|
609 | if (!(key instanceof DesCryptoKey)) {
|
610 | throw new Error("key: Is not DesCryptoKey");
|
611 | }
|
612 | switch (algorithm.name.toUpperCase()) {
|
613 | case "DES-CBC":
|
614 | return this.decryptDesCBC(algorithm, key, buffer.Buffer.from(data));
|
615 | case "DES-EDE3-CBC":
|
616 | return this.decryptDesEDE3CBC(algorithm, key, buffer.Buffer.from(data));
|
617 | default:
|
618 | throw new core__namespace.OperationError("algorithm: Is not recognized");
|
619 | }
|
620 | }
|
621 | static async encryptDesCBC(algorithm, key, data) {
|
622 | const cipher = crypto.createCipheriv(`des-cbc`, key.data, new Uint8Array(algorithm.iv));
|
623 | let enc = cipher.update(data);
|
624 | enc = buffer.Buffer.concat([enc, cipher.final()]);
|
625 | const res = new Uint8Array(enc).buffer;
|
626 | return res;
|
627 | }
|
628 | static async decryptDesCBC(algorithm, key, data) {
|
629 | const decipher = crypto.createDecipheriv(`des-cbc`, key.data, new Uint8Array(algorithm.iv));
|
630 | let dec = decipher.update(data);
|
631 | dec = buffer.Buffer.concat([dec, decipher.final()]);
|
632 | return new Uint8Array(dec).buffer;
|
633 | }
|
634 | static async encryptDesEDE3CBC(algorithm, key, data) {
|
635 | const cipher = crypto.createCipheriv(`des-ede3-cbc`, key.data, buffer.Buffer.from(algorithm.iv));
|
636 | let enc = cipher.update(data);
|
637 | enc = buffer.Buffer.concat([enc, cipher.final()]);
|
638 | const res = new Uint8Array(enc).buffer;
|
639 | return res;
|
640 | }
|
641 | static async decryptDesEDE3CBC(algorithm, key, data) {
|
642 | const decipher = crypto.createDecipheriv(`des-ede3-cbc`, key.data, new Uint8Array(algorithm.iv));
|
643 | let dec = decipher.update(data);
|
644 | dec = buffer.Buffer.concat([dec, decipher.final()]);
|
645 | return new Uint8Array(dec).buffer;
|
646 | }
|
647 | }
|
648 |
|
649 | class DesCbcProvider extends core__namespace.DesProvider {
|
650 | constructor() {
|
651 | super(...arguments);
|
652 | this.keySizeBits = 64;
|
653 | this.ivSize = 8;
|
654 | this.name = "DES-CBC";
|
655 | }
|
656 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
657 | const key = await DesCrypto.generateKey({
|
658 | name: this.name,
|
659 | length: this.keySizeBits,
|
660 | }, extractable, keyUsages);
|
661 | return setCryptoKey(key);
|
662 | }
|
663 | async onEncrypt(algorithm, key, data) {
|
664 | return DesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
665 | }
|
666 | async onDecrypt(algorithm, key, data) {
|
667 | return DesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
668 | }
|
669 | async onExportKey(format, key) {
|
670 | return DesCrypto.exportKey(format, getCryptoKey(key));
|
671 | }
|
672 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
673 | const key = await DesCrypto.importKey(format, keyData, { name: this.name, length: this.keySizeBits }, extractable, keyUsages);
|
674 | if (key.data.length !== (this.keySizeBits >> 3)) {
|
675 | throw new core__namespace.OperationError("keyData: Wrong key size");
|
676 | }
|
677 | return setCryptoKey(key);
|
678 | }
|
679 | checkCryptoKey(key, keyUsage) {
|
680 | super.checkCryptoKey(key, keyUsage);
|
681 | if (!(getCryptoKey(key) instanceof DesCryptoKey)) {
|
682 | throw new TypeError("key: Is not a DesCryptoKey");
|
683 | }
|
684 | }
|
685 | }
|
686 |
|
687 | class DesEde3CbcProvider extends core__namespace.DesProvider {
|
688 | constructor() {
|
689 | super(...arguments);
|
690 | this.keySizeBits = 192;
|
691 | this.ivSize = 8;
|
692 | this.name = "DES-EDE3-CBC";
|
693 | }
|
694 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
695 | const key = await DesCrypto.generateKey({
|
696 | name: this.name,
|
697 | length: this.keySizeBits,
|
698 | }, extractable, keyUsages);
|
699 | return setCryptoKey(key);
|
700 | }
|
701 | async onEncrypt(algorithm, key, data) {
|
702 | return DesCrypto.encrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
703 | }
|
704 | async onDecrypt(algorithm, key, data) {
|
705 | return DesCrypto.decrypt(algorithm, getCryptoKey(key), new Uint8Array(data));
|
706 | }
|
707 | async onExportKey(format, key) {
|
708 | return DesCrypto.exportKey(format, getCryptoKey(key));
|
709 | }
|
710 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
711 | const key = await DesCrypto.importKey(format, keyData, { name: this.name, length: this.keySizeBits }, extractable, keyUsages);
|
712 | if (key.data.length !== (this.keySizeBits >> 3)) {
|
713 | throw new core__namespace.OperationError("keyData: Wrong key size");
|
714 | }
|
715 | return setCryptoKey(key);
|
716 | }
|
717 | checkCryptoKey(key, keyUsage) {
|
718 | super.checkCryptoKey(key, keyUsage);
|
719 | if (!(getCryptoKey(key) instanceof DesCryptoKey)) {
|
720 | throw new TypeError("key: Is not a DesCryptoKey");
|
721 | }
|
722 | }
|
723 | }
|
724 |
|
725 | function getJwkAlgorithm(algorithm) {
|
726 | switch (algorithm.name.toUpperCase()) {
|
727 | case "RSA-OAEP": {
|
728 | const mdSize = /(\d+)$/.exec(algorithm.hash.name)[1];
|
729 | return `RSA-OAEP${mdSize !== "1" ? `-${mdSize}` : ""}`;
|
730 | }
|
731 | case "RSASSA-PKCS1-V1_5":
|
732 | return `RS${/(\d+)$/.exec(algorithm.hash.name)[1]}`;
|
733 | case "RSA-PSS":
|
734 | return `PS${/(\d+)$/.exec(algorithm.hash.name)[1]}`;
|
735 | case "RSA-PKCS1":
|
736 | return `RS1`;
|
737 | default:
|
738 | throw new core__namespace.OperationError("algorithm: Is not recognized");
|
739 | }
|
740 | }
|
741 |
|
742 | class RsaPrivateKey extends AsymmetricKey {
|
743 | constructor() {
|
744 | super(...arguments);
|
745 | this.type = "private";
|
746 | }
|
747 | getKey() {
|
748 | const keyInfo = asn1Schema.AsnParser.parse(this.data, core__namespace.asn1.PrivateKeyInfo);
|
749 | return asn1Schema.AsnParser.parse(keyInfo.privateKey, core__namespace.asn1.RsaPrivateKey);
|
750 | }
|
751 | toJSON() {
|
752 | const key = this.getKey();
|
753 | const json = {
|
754 | kty: "RSA",
|
755 | alg: getJwkAlgorithm(this.algorithm),
|
756 | key_ops: this.usages,
|
757 | ext: this.extractable,
|
758 | };
|
759 | return Object.assign(json, jsonSchema.JsonSerializer.toJSON(key));
|
760 | }
|
761 | fromJSON(json) {
|
762 | const key = jsonSchema.JsonParser.fromJSON(json, { targetSchema: core__namespace.asn1.RsaPrivateKey });
|
763 | const keyInfo = new core__namespace.asn1.PrivateKeyInfo();
|
764 | keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
765 | keyInfo.privateKeyAlgorithm.parameters = null;
|
766 | keyInfo.privateKey = asn1Schema.AsnSerializer.serialize(key);
|
767 | this.data = buffer.Buffer.from(asn1Schema.AsnSerializer.serialize(keyInfo));
|
768 | }
|
769 | }
|
770 |
|
771 | class RsaPublicKey extends AsymmetricKey {
|
772 | constructor() {
|
773 | super(...arguments);
|
774 | this.type = "public";
|
775 | }
|
776 | getKey() {
|
777 | const keyInfo = asn1Schema.AsnParser.parse(this.data, core__namespace.asn1.PublicKeyInfo);
|
778 | return asn1Schema.AsnParser.parse(keyInfo.publicKey, core__namespace.asn1.RsaPublicKey);
|
779 | }
|
780 | toJSON() {
|
781 | const key = this.getKey();
|
782 | const json = {
|
783 | kty: "RSA",
|
784 | alg: getJwkAlgorithm(this.algorithm),
|
785 | key_ops: this.usages,
|
786 | ext: this.extractable,
|
787 | };
|
788 | return Object.assign(json, jsonSchema.JsonSerializer.toJSON(key));
|
789 | }
|
790 | fromJSON(json) {
|
791 | const key = jsonSchema.JsonParser.fromJSON(json, { targetSchema: core__namespace.asn1.RsaPublicKey });
|
792 | const keyInfo = new core__namespace.asn1.PublicKeyInfo();
|
793 | keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
794 | keyInfo.publicKeyAlgorithm.parameters = null;
|
795 | keyInfo.publicKey = asn1Schema.AsnSerializer.serialize(key);
|
796 | this.data = buffer.Buffer.from(asn1Schema.AsnSerializer.serialize(keyInfo));
|
797 | }
|
798 | }
|
799 |
|
800 | class RsaCrypto {
|
801 | static async generateKey(algorithm, extractable, keyUsages) {
|
802 | const privateKey = new RsaPrivateKey();
|
803 | privateKey.algorithm = algorithm;
|
804 | privateKey.extractable = extractable;
|
805 | privateKey.usages = keyUsages.filter((usage) => this.privateKeyUsages.indexOf(usage) !== -1);
|
806 | const publicKey = new RsaPublicKey();
|
807 | publicKey.algorithm = algorithm;
|
808 | publicKey.extractable = true;
|
809 | publicKey.usages = keyUsages.filter((usage) => this.publicKeyUsages.indexOf(usage) !== -1);
|
810 | const publicExponent = buffer.Buffer.concat([
|
811 | buffer.Buffer.alloc(4 - algorithm.publicExponent.byteLength, 0),
|
812 | buffer.Buffer.from(algorithm.publicExponent),
|
813 | ]).readInt32BE(0);
|
814 | const keys = crypto.generateKeyPairSync("rsa", {
|
815 | modulusLength: algorithm.modulusLength,
|
816 | publicExponent,
|
817 | publicKeyEncoding: {
|
818 | format: "der",
|
819 | type: "spki",
|
820 | },
|
821 | privateKeyEncoding: {
|
822 | format: "der",
|
823 | type: "pkcs8",
|
824 | },
|
825 | });
|
826 | privateKey.data = keys.privateKey;
|
827 | publicKey.data = keys.publicKey;
|
828 | const res = {
|
829 | privateKey,
|
830 | publicKey,
|
831 | };
|
832 | return res;
|
833 | }
|
834 | static async exportKey(format, key) {
|
835 | switch (format.toLowerCase()) {
|
836 | case "jwk":
|
837 | return jsonSchema.JsonSerializer.toJSON(key);
|
838 | case "pkcs8":
|
839 | case "spki":
|
840 | return new Uint8Array(key.data).buffer;
|
841 | default:
|
842 | throw new core__namespace.OperationError("format: Must be 'jwk', 'pkcs8' or 'spki'");
|
843 | }
|
844 | }
|
845 | static async importKey(format, keyData, algorithm, extractable, keyUsages) {
|
846 | switch (format.toLowerCase()) {
|
847 | case "jwk": {
|
848 | const jwk = keyData;
|
849 | if (jwk.d) {
|
850 | const asnKey = jsonSchema.JsonParser.fromJSON(keyData, { targetSchema: core__namespace.asn1.RsaPrivateKey });
|
851 | return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
852 | }
|
853 | else {
|
854 | const asnKey = jsonSchema.JsonParser.fromJSON(keyData, { targetSchema: core__namespace.asn1.RsaPublicKey });
|
855 | return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
856 | }
|
857 | }
|
858 | case "spki": {
|
859 | const keyInfo = asn1Schema.AsnParser.parse(new Uint8Array(keyData), core__namespace.asn1.PublicKeyInfo);
|
860 | const asnKey = asn1Schema.AsnParser.parse(keyInfo.publicKey, core__namespace.asn1.RsaPublicKey);
|
861 | return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
862 | }
|
863 | case "pkcs8": {
|
864 | const keyInfo = asn1Schema.AsnParser.parse(new Uint8Array(keyData), core__namespace.asn1.PrivateKeyInfo);
|
865 | const asnKey = asn1Schema.AsnParser.parse(keyInfo.privateKey, core__namespace.asn1.RsaPrivateKey);
|
866 | return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
867 | }
|
868 | default:
|
869 | throw new core__namespace.OperationError("format: Must be 'jwk', 'pkcs8' or 'spki'");
|
870 | }
|
871 | }
|
872 | static async sign(algorithm, key, data) {
|
873 | switch (algorithm.name.toUpperCase()) {
|
874 | case "RSA-PSS":
|
875 | case "RSASSA-PKCS1-V1_5":
|
876 | return this.signRsa(algorithm, key, data);
|
877 | default:
|
878 | throw new core__namespace.OperationError("algorithm: Is not recognized");
|
879 | }
|
880 | }
|
881 | static async verify(algorithm, key, signature, data) {
|
882 | switch (algorithm.name.toUpperCase()) {
|
883 | case "RSA-PSS":
|
884 | case "RSASSA-PKCS1-V1_5":
|
885 | return this.verifySSA(algorithm, key, data, signature);
|
886 | default:
|
887 | throw new core__namespace.OperationError("algorithm: Is not recognized");
|
888 | }
|
889 | }
|
890 | static async encrypt(algorithm, key, data) {
|
891 | switch (algorithm.name.toUpperCase()) {
|
892 | case "RSA-OAEP":
|
893 | return this.encryptOAEP(algorithm, key, data);
|
894 | default:
|
895 | throw new core__namespace.OperationError("algorithm: Is not recognized");
|
896 | }
|
897 | }
|
898 | static async decrypt(algorithm, key, data) {
|
899 | switch (algorithm.name.toUpperCase()) {
|
900 | case "RSA-OAEP":
|
901 | return this.decryptOAEP(algorithm, key, data);
|
902 | default:
|
903 | throw new core__namespace.OperationError("algorithm: Is not recognized");
|
904 | }
|
905 | }
|
906 | static importPrivateKey(asnKey, algorithm, extractable, keyUsages) {
|
907 | const keyInfo = new core__namespace.asn1.PrivateKeyInfo();
|
908 | keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
909 | keyInfo.privateKeyAlgorithm.parameters = null;
|
910 | keyInfo.privateKey = asn1Schema.AsnSerializer.serialize(asnKey);
|
911 | const key = new RsaPrivateKey();
|
912 | key.data = buffer.Buffer.from(asn1Schema.AsnSerializer.serialize(keyInfo));
|
913 | key.algorithm = Object.assign({}, algorithm);
|
914 | key.algorithm.publicExponent = new Uint8Array(asnKey.publicExponent);
|
915 | key.algorithm.modulusLength = asnKey.modulus.byteLength << 3;
|
916 | key.extractable = extractable;
|
917 | key.usages = keyUsages;
|
918 | return key;
|
919 | }
|
920 | static importPublicKey(asnKey, algorithm, extractable, keyUsages) {
|
921 | const keyInfo = new core__namespace.asn1.PublicKeyInfo();
|
922 | keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
923 | keyInfo.publicKeyAlgorithm.parameters = null;
|
924 | keyInfo.publicKey = asn1Schema.AsnSerializer.serialize(asnKey);
|
925 | const key = new RsaPublicKey();
|
926 | key.data = buffer.Buffer.from(asn1Schema.AsnSerializer.serialize(keyInfo));
|
927 | key.algorithm = Object.assign({}, algorithm);
|
928 | key.algorithm.publicExponent = new Uint8Array(asnKey.publicExponent);
|
929 | key.algorithm.modulusLength = asnKey.modulus.byteLength << 3;
|
930 | key.extractable = extractable;
|
931 | key.usages = keyUsages;
|
932 | return key;
|
933 | }
|
934 | static getCryptoAlgorithm(alg) {
|
935 | switch (alg.hash.name.toUpperCase()) {
|
936 | case "SHA-1":
|
937 | return "RSA-SHA1";
|
938 | case "SHA-256":
|
939 | return "RSA-SHA256";
|
940 | case "SHA-384":
|
941 | return "RSA-SHA384";
|
942 | case "SHA-512":
|
943 | return "RSA-SHA512";
|
944 | case "SHA3-256":
|
945 | return "RSA-SHA3-256";
|
946 | case "SHA3-384":
|
947 | return "RSA-SHA3-384";
|
948 | case "SHA3-512":
|
949 | return "RSA-SHA3-512";
|
950 | default:
|
951 | throw new core__namespace.OperationError("algorithm.hash: Is not recognized");
|
952 | }
|
953 | }
|
954 | static signRsa(algorithm, key, data) {
|
955 | const cryptoAlg = this.getCryptoAlgorithm(key.algorithm);
|
956 | const signer = crypto.createSign(cryptoAlg);
|
957 | signer.update(buffer.Buffer.from(data));
|
958 | if (!key.pem) {
|
959 | key.pem = `-----BEGIN PRIVATE KEY-----\n${key.data.toString("base64")}\n-----END PRIVATE KEY-----`;
|
960 | }
|
961 | const options = {
|
962 | key: key.pem,
|
963 | };
|
964 | if (algorithm.name.toUpperCase() === "RSA-PSS") {
|
965 | options.padding = crypto.constants.RSA_PKCS1_PSS_PADDING;
|
966 | options.saltLength = algorithm.saltLength;
|
967 | }
|
968 | const signature = signer.sign(options);
|
969 | return new Uint8Array(signature).buffer;
|
970 | }
|
971 | static verifySSA(algorithm, key, data, signature) {
|
972 | const cryptoAlg = this.getCryptoAlgorithm(key.algorithm);
|
973 | const signer = crypto.createVerify(cryptoAlg);
|
974 | signer.update(buffer.Buffer.from(data));
|
975 | if (!key.pem) {
|
976 | key.pem = `-----BEGIN PUBLIC KEY-----\n${key.data.toString("base64")}\n-----END PUBLIC KEY-----`;
|
977 | }
|
978 | const options = {
|
979 | key: key.pem,
|
980 | };
|
981 | if (algorithm.name.toUpperCase() === "RSA-PSS") {
|
982 | options.padding = crypto.constants.RSA_PKCS1_PSS_PADDING;
|
983 | options.saltLength = algorithm.saltLength;
|
984 | }
|
985 | const ok = signer.verify(options, signature);
|
986 | return ok;
|
987 | }
|
988 | static encryptOAEP(algorithm, key, data) {
|
989 | const options = {
|
990 | key: `-----BEGIN PUBLIC KEY-----\n${key.data.toString("base64")}\n-----END PUBLIC KEY-----`,
|
991 | padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
992 | };
|
993 | if (algorithm.label) ;
|
994 | return new Uint8Array(crypto.publicEncrypt(options, data)).buffer;
|
995 | }
|
996 | static decryptOAEP(algorithm, key, data) {
|
997 | const options = {
|
998 | key: `-----BEGIN PRIVATE KEY-----\n${key.data.toString("base64")}\n-----END PRIVATE KEY-----`,
|
999 | padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
1000 | };
|
1001 | if (algorithm.label) ;
|
1002 | return new Uint8Array(crypto.privateDecrypt(options, data)).buffer;
|
1003 | }
|
1004 | }
|
1005 | RsaCrypto.publicKeyUsages = ["verify", "encrypt", "wrapKey"];
|
1006 | RsaCrypto.privateKeyUsages = ["sign", "decrypt", "unwrapKey"];
|
1007 |
|
1008 | class RsaSsaProvider extends core__namespace.RsaSsaProvider {
|
1009 | constructor() {
|
1010 | super(...arguments);
|
1011 | this.hashAlgorithms = [
|
1012 | "SHA-1", "SHA-256", "SHA-384", "SHA-512",
|
1013 | "shake128", "shake256",
|
1014 | "SHA3-256", "SHA3-384", "SHA3-512"
|
1015 | ];
|
1016 | }
|
1017 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
1018 | const keys = await RsaCrypto.generateKey({
|
1019 | ...algorithm,
|
1020 | name: this.name,
|
1021 | }, extractable, keyUsages);
|
1022 | return {
|
1023 | privateKey: setCryptoKey(keys.privateKey),
|
1024 | publicKey: setCryptoKey(keys.publicKey),
|
1025 | };
|
1026 | }
|
1027 | async onSign(algorithm, key, data) {
|
1028 | return RsaCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data));
|
1029 | }
|
1030 | async onVerify(algorithm, key, signature, data) {
|
1031 | return RsaCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data));
|
1032 | }
|
1033 | async onExportKey(format, key) {
|
1034 | return RsaCrypto.exportKey(format, getCryptoKey(key));
|
1035 | }
|
1036 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
1037 | const key = await RsaCrypto.importKey(format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages);
|
1038 | return setCryptoKey(key);
|
1039 | }
|
1040 | checkCryptoKey(key, keyUsage) {
|
1041 | super.checkCryptoKey(key, keyUsage);
|
1042 | const internalKey = getCryptoKey(key);
|
1043 | if (!(internalKey instanceof RsaPrivateKey || internalKey instanceof RsaPublicKey)) {
|
1044 | throw new TypeError("key: Is not RSA CryptoKey");
|
1045 | }
|
1046 | }
|
1047 | }
|
1048 |
|
1049 | class RsaPssProvider extends core__namespace.RsaPssProvider {
|
1050 | constructor() {
|
1051 | super(...arguments);
|
1052 | this.hashAlgorithms = [
|
1053 | "SHA-1", "SHA-256", "SHA-384", "SHA-512",
|
1054 | "shake128", "shake256",
|
1055 | "SHA3-256", "SHA3-384", "SHA3-512"
|
1056 | ];
|
1057 | }
|
1058 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
1059 | const keys = await RsaCrypto.generateKey({
|
1060 | ...algorithm,
|
1061 | name: this.name,
|
1062 | }, extractable, keyUsages);
|
1063 | return {
|
1064 | privateKey: setCryptoKey(keys.privateKey),
|
1065 | publicKey: setCryptoKey(keys.publicKey),
|
1066 | };
|
1067 | }
|
1068 | async onSign(algorithm, key, data) {
|
1069 | return RsaCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data));
|
1070 | }
|
1071 | async onVerify(algorithm, key, signature, data) {
|
1072 | return RsaCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data));
|
1073 | }
|
1074 | async onExportKey(format, key) {
|
1075 | return RsaCrypto.exportKey(format, getCryptoKey(key));
|
1076 | }
|
1077 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
1078 | const key = await RsaCrypto.importKey(format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages);
|
1079 | return setCryptoKey(key);
|
1080 | }
|
1081 | checkCryptoKey(key, keyUsage) {
|
1082 | super.checkCryptoKey(key, keyUsage);
|
1083 | const internalKey = getCryptoKey(key);
|
1084 | if (!(internalKey instanceof RsaPrivateKey || internalKey instanceof RsaPublicKey)) {
|
1085 | throw new TypeError("key: Is not RSA CryptoKey");
|
1086 | }
|
1087 | }
|
1088 | }
|
1089 |
|
1090 | class ShaCrypto {
|
1091 | static size(algorithm) {
|
1092 | switch (algorithm.name.toUpperCase()) {
|
1093 | case "SHA-1":
|
1094 | return 160;
|
1095 | case "SHA-256":
|
1096 | case "SHA3-256":
|
1097 | return 256;
|
1098 | case "SHA-384":
|
1099 | case "SHA3-384":
|
1100 | return 384;
|
1101 | case "SHA-512":
|
1102 | case "SHA3-512":
|
1103 | return 512;
|
1104 | default:
|
1105 | throw new Error("Unrecognized name");
|
1106 | }
|
1107 | }
|
1108 | static getAlgorithmName(algorithm) {
|
1109 | switch (algorithm.name.toUpperCase()) {
|
1110 | case "SHA-1":
|
1111 | return "sha1";
|
1112 | case "SHA-256":
|
1113 | return "sha256";
|
1114 | case "SHA-384":
|
1115 | return "sha384";
|
1116 | case "SHA-512":
|
1117 | return "sha512";
|
1118 | case "SHA3-256":
|
1119 | return "sha3-256";
|
1120 | case "SHA3-384":
|
1121 | return "sha3-384";
|
1122 | case "SHA3-512":
|
1123 | return "sha3-512";
|
1124 | default:
|
1125 | throw new Error("Unrecognized name");
|
1126 | }
|
1127 | }
|
1128 | static digest(algorithm, data) {
|
1129 | const hashAlg = this.getAlgorithmName(algorithm);
|
1130 | const hash = crypto.createHash(hashAlg)
|
1131 | .update(buffer.Buffer.from(data)).digest();
|
1132 | return new Uint8Array(hash).buffer;
|
1133 | }
|
1134 | }
|
1135 |
|
1136 | class RsaOaepProvider extends core__namespace.RsaOaepProvider {
|
1137 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
1138 | const keys = await RsaCrypto.generateKey({
|
1139 | ...algorithm,
|
1140 | name: this.name,
|
1141 | }, extractable, keyUsages);
|
1142 | return {
|
1143 | privateKey: setCryptoKey(keys.privateKey),
|
1144 | publicKey: setCryptoKey(keys.publicKey),
|
1145 | };
|
1146 | }
|
1147 | async onEncrypt(algorithm, key, data) {
|
1148 | const internalKey = getCryptoKey(key);
|
1149 | const dataView = new Uint8Array(data);
|
1150 | const keySize = Math.ceil(internalKey.algorithm.modulusLength >> 3);
|
1151 | const hashSize = ShaCrypto.size(internalKey.algorithm.hash) >> 3;
|
1152 | const dataLength = dataView.byteLength;
|
1153 | const psLength = keySize - dataLength - 2 * hashSize - 2;
|
1154 | if (dataLength > keySize - 2 * hashSize - 2) {
|
1155 | throw new Error("Data too large");
|
1156 | }
|
1157 | const message = new Uint8Array(keySize);
|
1158 | const seed = message.subarray(1, hashSize + 1);
|
1159 | const dataBlock = message.subarray(hashSize + 1);
|
1160 | dataBlock.set(dataView, hashSize + psLength + 1);
|
1161 | const labelHash = crypto.createHash(internalKey.algorithm.hash.name.replace("-", ""))
|
1162 | .update(core__namespace.BufferSourceConverter.toUint8Array(algorithm.label || new Uint8Array(0)))
|
1163 | .digest();
|
1164 | dataBlock.set(labelHash, 0);
|
1165 | dataBlock[hashSize + psLength] = 1;
|
1166 | crypto.randomFillSync(seed);
|
1167 | const dataBlockMask = this.mgf1(internalKey.algorithm.hash, seed, dataBlock.length);
|
1168 | for (let i = 0; i < dataBlock.length; i++) {
|
1169 | dataBlock[i] ^= dataBlockMask[i];
|
1170 | }
|
1171 | const seedMask = this.mgf1(internalKey.algorithm.hash, dataBlock, seed.length);
|
1172 | for (let i = 0; i < seed.length; i++) {
|
1173 | seed[i] ^= seedMask[i];
|
1174 | }
|
1175 | if (!internalKey.pem) {
|
1176 | internalKey.pem = `-----BEGIN PUBLIC KEY-----\n${internalKey.data.toString("base64")}\n-----END PUBLIC KEY-----`;
|
1177 | }
|
1178 | const pkcs0 = crypto.publicEncrypt({
|
1179 | key: internalKey.pem,
|
1180 | padding: crypto.constants.RSA_NO_PADDING,
|
1181 | }, buffer.Buffer.from(message));
|
1182 | return new Uint8Array(pkcs0).buffer;
|
1183 | }
|
1184 | async onDecrypt(algorithm, key, data) {
|
1185 | const internalKey = getCryptoKey(key);
|
1186 | const keySize = Math.ceil(internalKey.algorithm.modulusLength >> 3);
|
1187 | const hashSize = ShaCrypto.size(internalKey.algorithm.hash) >> 3;
|
1188 | const dataLength = data.byteLength;
|
1189 | if (dataLength !== keySize) {
|
1190 | throw new Error("Bad data");
|
1191 | }
|
1192 | if (!internalKey.pem) {
|
1193 | internalKey.pem = `-----BEGIN PRIVATE KEY-----\n${internalKey.data.toString("base64")}\n-----END PRIVATE KEY-----`;
|
1194 | }
|
1195 | let pkcs0 = crypto.privateDecrypt({
|
1196 | key: internalKey.pem,
|
1197 | padding: crypto.constants.RSA_NO_PADDING,
|
1198 | }, buffer.Buffer.from(data));
|
1199 | const z = pkcs0[0];
|
1200 | const seed = pkcs0.subarray(1, hashSize + 1);
|
1201 | const dataBlock = pkcs0.subarray(hashSize + 1);
|
1202 | if (z !== 0) {
|
1203 | throw new Error("Decryption failed");
|
1204 | }
|
1205 | const seedMask = this.mgf1(internalKey.algorithm.hash, dataBlock, seed.length);
|
1206 | for (let i = 0; i < seed.length; i++) {
|
1207 | seed[i] ^= seedMask[i];
|
1208 | }
|
1209 | const dataBlockMask = this.mgf1(internalKey.algorithm.hash, seed, dataBlock.length);
|
1210 | for (let i = 0; i < dataBlock.length; i++) {
|
1211 | dataBlock[i] ^= dataBlockMask[i];
|
1212 | }
|
1213 | const labelHash = crypto.createHash(internalKey.algorithm.hash.name.replace("-", ""))
|
1214 | .update(core__namespace.BufferSourceConverter.toUint8Array(algorithm.label || new Uint8Array(0)))
|
1215 | .digest();
|
1216 | for (let i = 0; i < hashSize; i++) {
|
1217 | if (labelHash[i] !== dataBlock[i]) {
|
1218 | throw new Error("Decryption failed");
|
1219 | }
|
1220 | }
|
1221 | let psEnd = hashSize;
|
1222 | for (; psEnd < dataBlock.length; psEnd++) {
|
1223 | const psz = dataBlock[psEnd];
|
1224 | if (psz === 1) {
|
1225 | break;
|
1226 | }
|
1227 | if (psz !== 0) {
|
1228 | throw new Error("Decryption failed");
|
1229 | }
|
1230 | }
|
1231 | if (psEnd === dataBlock.length) {
|
1232 | throw new Error("Decryption failed");
|
1233 | }
|
1234 | pkcs0 = dataBlock.subarray(psEnd + 1);
|
1235 | return new Uint8Array(pkcs0).buffer;
|
1236 | }
|
1237 | async onExportKey(format, key) {
|
1238 | return RsaCrypto.exportKey(format, getCryptoKey(key));
|
1239 | }
|
1240 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
1241 | const key = await RsaCrypto.importKey(format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages);
|
1242 | return setCryptoKey(key);
|
1243 | }
|
1244 | checkCryptoKey(key, keyUsage) {
|
1245 | super.checkCryptoKey(key, keyUsage);
|
1246 | const internalKey = getCryptoKey(key);
|
1247 | if (!(internalKey instanceof RsaPrivateKey || internalKey instanceof RsaPublicKey)) {
|
1248 | throw new TypeError("key: Is not RSA CryptoKey");
|
1249 | }
|
1250 | }
|
1251 | mgf1(algorithm, seed, length = 0) {
|
1252 | const hashSize = ShaCrypto.size(algorithm) >> 3;
|
1253 | const mask = new Uint8Array(length);
|
1254 | const counter = new Uint8Array(4);
|
1255 | const chunks = Math.ceil(length / hashSize);
|
1256 | for (let i = 0; i < chunks; i++) {
|
1257 | counter[0] = i >>> 24;
|
1258 | counter[1] = (i >>> 16) & 255;
|
1259 | counter[2] = (i >>> 8) & 255;
|
1260 | counter[3] = i & 255;
|
1261 | const submask = mask.subarray(i * hashSize);
|
1262 | let chunk = crypto.createHash(algorithm.name.replace("-", ""))
|
1263 | .update(seed)
|
1264 | .update(counter)
|
1265 | .digest();
|
1266 | if (chunk.length > submask.length) {
|
1267 | chunk = chunk.subarray(0, submask.length);
|
1268 | }
|
1269 | submask.set(chunk);
|
1270 | }
|
1271 | return mask;
|
1272 | }
|
1273 | }
|
1274 |
|
1275 | class RsaEsProvider extends core__namespace.ProviderCrypto {
|
1276 | constructor() {
|
1277 | super(...arguments);
|
1278 | this.name = "RSAES-PKCS1-v1_5";
|
1279 | this.usages = {
|
1280 | publicKey: ["encrypt", "wrapKey"],
|
1281 | privateKey: ["decrypt", "unwrapKey"],
|
1282 | };
|
1283 | }
|
1284 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
1285 | const keys = await RsaCrypto.generateKey({
|
1286 | ...algorithm,
|
1287 | name: this.name,
|
1288 | }, extractable, keyUsages);
|
1289 | return {
|
1290 | privateKey: setCryptoKey(keys.privateKey),
|
1291 | publicKey: setCryptoKey(keys.publicKey),
|
1292 | };
|
1293 | }
|
1294 | checkGenerateKeyParams(algorithm) {
|
1295 | this.checkRequiredProperty(algorithm, "publicExponent");
|
1296 | if (!(algorithm.publicExponent && algorithm.publicExponent instanceof Uint8Array)) {
|
1297 | throw new TypeError("publicExponent: Missing or not a Uint8Array");
|
1298 | }
|
1299 | const publicExponent = pvtsutils.Convert.ToBase64(algorithm.publicExponent);
|
1300 | if (!(publicExponent === "Aw==" || publicExponent === "AQAB")) {
|
1301 | throw new TypeError("publicExponent: Must be [3] or [1,0,1]");
|
1302 | }
|
1303 | this.checkRequiredProperty(algorithm, "modulusLength");
|
1304 | switch (algorithm.modulusLength) {
|
1305 | case 1024:
|
1306 | case 2048:
|
1307 | case 4096:
|
1308 | break;
|
1309 | default:
|
1310 | throw new TypeError("modulusLength: Must be 1024, 2048, or 4096");
|
1311 | }
|
1312 | }
|
1313 | async onEncrypt(algorithm, key, data) {
|
1314 | const options = this.toCryptoOptions(key);
|
1315 | const enc = crypto__namespace.publicEncrypt(options, new Uint8Array(data));
|
1316 | return new Uint8Array(enc).buffer;
|
1317 | }
|
1318 | async onDecrypt(algorithm, key, data) {
|
1319 | const options = this.toCryptoOptions(key);
|
1320 | const dec = crypto__namespace.privateDecrypt(options, new Uint8Array(data));
|
1321 | return new Uint8Array(dec).buffer;
|
1322 | }
|
1323 | async onExportKey(format, key) {
|
1324 | return RsaCrypto.exportKey(format, getCryptoKey(key));
|
1325 | }
|
1326 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
1327 | const key = await RsaCrypto.importKey(format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages);
|
1328 | return setCryptoKey(key);
|
1329 | }
|
1330 | checkCryptoKey(key, keyUsage) {
|
1331 | super.checkCryptoKey(key, keyUsage);
|
1332 | const internalKey = getCryptoKey(key);
|
1333 | if (!(internalKey instanceof RsaPrivateKey || internalKey instanceof RsaPublicKey)) {
|
1334 | throw new TypeError("key: Is not RSA CryptoKey");
|
1335 | }
|
1336 | }
|
1337 | toCryptoOptions(key) {
|
1338 | const type = key.type.toUpperCase();
|
1339 | return {
|
1340 | key: `-----BEGIN ${type} KEY-----\n${getCryptoKey(key).data.toString("base64")}\n-----END ${type} KEY-----`,
|
1341 | padding: crypto__namespace.constants.RSA_PKCS1_PADDING,
|
1342 | };
|
1343 | }
|
1344 | }
|
1345 |
|
1346 | const namedOIDs = {
|
1347 | "1.2.840.10045.3.1.7": "P-256",
|
1348 | "P-256": "1.2.840.10045.3.1.7",
|
1349 | "1.3.132.0.34": "P-384",
|
1350 | "P-384": "1.3.132.0.34",
|
1351 | "1.3.132.0.35": "P-521",
|
1352 | "P-521": "1.3.132.0.35",
|
1353 | "1.3.132.0.10": "K-256",
|
1354 | "K-256": "1.3.132.0.10",
|
1355 | "brainpoolP160r1": "1.3.36.3.3.2.8.1.1.1",
|
1356 | "1.3.36.3.3.2.8.1.1.1": "brainpoolP160r1",
|
1357 | "brainpoolP160t1": "1.3.36.3.3.2.8.1.1.2",
|
1358 | "1.3.36.3.3.2.8.1.1.2": "brainpoolP160t1",
|
1359 | "brainpoolP192r1": "1.3.36.3.3.2.8.1.1.3",
|
1360 | "1.3.36.3.3.2.8.1.1.3": "brainpoolP192r1",
|
1361 | "brainpoolP192t1": "1.3.36.3.3.2.8.1.1.4",
|
1362 | "1.3.36.3.3.2.8.1.1.4": "brainpoolP192t1",
|
1363 | "brainpoolP224r1": "1.3.36.3.3.2.8.1.1.5",
|
1364 | "1.3.36.3.3.2.8.1.1.5": "brainpoolP224r1",
|
1365 | "brainpoolP224t1": "1.3.36.3.3.2.8.1.1.6",
|
1366 | "1.3.36.3.3.2.8.1.1.6": "brainpoolP224t1",
|
1367 | "brainpoolP256r1": "1.3.36.3.3.2.8.1.1.7",
|
1368 | "1.3.36.3.3.2.8.1.1.7": "brainpoolP256r1",
|
1369 | "brainpoolP256t1": "1.3.36.3.3.2.8.1.1.8",
|
1370 | "1.3.36.3.3.2.8.1.1.8": "brainpoolP256t1",
|
1371 | "brainpoolP320r1": "1.3.36.3.3.2.8.1.1.9",
|
1372 | "1.3.36.3.3.2.8.1.1.9": "brainpoolP320r1",
|
1373 | "brainpoolP320t1": "1.3.36.3.3.2.8.1.1.10",
|
1374 | "1.3.36.3.3.2.8.1.1.10": "brainpoolP320t1",
|
1375 | "brainpoolP384r1": "1.3.36.3.3.2.8.1.1.11",
|
1376 | "1.3.36.3.3.2.8.1.1.11": "brainpoolP384r1",
|
1377 | "brainpoolP384t1": "1.3.36.3.3.2.8.1.1.12",
|
1378 | "1.3.36.3.3.2.8.1.1.12": "brainpoolP384t1",
|
1379 | "brainpoolP512r1": "1.3.36.3.3.2.8.1.1.13",
|
1380 | "1.3.36.3.3.2.8.1.1.13": "brainpoolP512r1",
|
1381 | "brainpoolP512t1": "1.3.36.3.3.2.8.1.1.14",
|
1382 | "1.3.36.3.3.2.8.1.1.14": "brainpoolP512t1",
|
1383 | };
|
1384 | function getOidByNamedCurve$1(namedCurve) {
|
1385 | const oid = namedOIDs[namedCurve];
|
1386 | if (!oid) {
|
1387 | throw new core__namespace.OperationError(`Cannot convert WebCrypto named curve '${namedCurve}' to OID`);
|
1388 | }
|
1389 | return oid;
|
1390 | }
|
1391 |
|
1392 | class EcPrivateKey extends AsymmetricKey {
|
1393 | constructor() {
|
1394 | super(...arguments);
|
1395 | this.type = "private";
|
1396 | }
|
1397 | getKey() {
|
1398 | const keyInfo = asn1Schema.AsnParser.parse(this.data, core__namespace.asn1.PrivateKeyInfo);
|
1399 | return asn1Schema.AsnParser.parse(keyInfo.privateKey, core__namespace.asn1.EcPrivateKey);
|
1400 | }
|
1401 | toJSON() {
|
1402 | const key = this.getKey();
|
1403 | const json = {
|
1404 | kty: "EC",
|
1405 | crv: this.algorithm.namedCurve,
|
1406 | key_ops: this.usages,
|
1407 | ext: this.extractable,
|
1408 | };
|
1409 | return Object.assign(json, jsonSchema.JsonSerializer.toJSON(key));
|
1410 | }
|
1411 | fromJSON(json) {
|
1412 | if (!json.crv) {
|
1413 | throw new core__namespace.OperationError(`Cannot get named curve from JWK. Property 'crv' is required`);
|
1414 | }
|
1415 | const keyInfo = new core__namespace.asn1.PrivateKeyInfo();
|
1416 | keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
1417 | keyInfo.privateKeyAlgorithm.parameters = asn1Schema.AsnSerializer.serialize(new core__namespace.asn1.ObjectIdentifier(getOidByNamedCurve$1(json.crv)));
|
1418 | const key = jsonSchema.JsonParser.fromJSON(json, { targetSchema: core__namespace.asn1.EcPrivateKey });
|
1419 | keyInfo.privateKey = asn1Schema.AsnSerializer.serialize(key);
|
1420 | this.data = buffer.Buffer.from(asn1Schema.AsnSerializer.serialize(keyInfo));
|
1421 | return this;
|
1422 | }
|
1423 | }
|
1424 |
|
1425 | class EcPublicKey extends AsymmetricKey {
|
1426 | constructor() {
|
1427 | super(...arguments);
|
1428 | this.type = "public";
|
1429 | }
|
1430 | getKey() {
|
1431 | const keyInfo = asn1Schema.AsnParser.parse(this.data, core__namespace.asn1.PublicKeyInfo);
|
1432 | return new core__namespace.asn1.EcPublicKey(keyInfo.publicKey);
|
1433 | }
|
1434 | toJSON() {
|
1435 | const key = this.getKey();
|
1436 | const json = {
|
1437 | kty: "EC",
|
1438 | crv: this.algorithm.namedCurve,
|
1439 | key_ops: this.usages,
|
1440 | ext: this.extractable,
|
1441 | };
|
1442 | return Object.assign(json, jsonSchema.JsonSerializer.toJSON(key));
|
1443 | }
|
1444 | fromJSON(json) {
|
1445 | if (!json.crv) {
|
1446 | throw new core__namespace.OperationError(`Cannot get named curve from JWK. Property 'crv' is required`);
|
1447 | }
|
1448 | const key = jsonSchema.JsonParser.fromJSON(json, { targetSchema: core__namespace.asn1.EcPublicKey });
|
1449 | const keyInfo = new core__namespace.asn1.PublicKeyInfo();
|
1450 | keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
1451 | keyInfo.publicKeyAlgorithm.parameters = asn1Schema.AsnSerializer.serialize(new core__namespace.asn1.ObjectIdentifier(getOidByNamedCurve$1(json.crv)));
|
1452 | keyInfo.publicKey = asn1Schema.AsnSerializer.toASN(key).valueHex;
|
1453 | this.data = buffer.Buffer.from(asn1Schema.AsnSerializer.serialize(keyInfo));
|
1454 | return this;
|
1455 | }
|
1456 | }
|
1457 |
|
1458 | class Sha1Provider extends core__namespace.ProviderCrypto {
|
1459 | constructor() {
|
1460 | super(...arguments);
|
1461 | this.name = "SHA-1";
|
1462 | this.usages = [];
|
1463 | }
|
1464 | async onDigest(algorithm, data) {
|
1465 | return ShaCrypto.digest(algorithm, data);
|
1466 | }
|
1467 | }
|
1468 |
|
1469 | class Sha256Provider extends core__namespace.ProviderCrypto {
|
1470 | constructor() {
|
1471 | super(...arguments);
|
1472 | this.name = "SHA-256";
|
1473 | this.usages = [];
|
1474 | }
|
1475 | async onDigest(algorithm, data) {
|
1476 | return ShaCrypto.digest(algorithm, data);
|
1477 | }
|
1478 | }
|
1479 |
|
1480 | class Sha384Provider extends core__namespace.ProviderCrypto {
|
1481 | constructor() {
|
1482 | super(...arguments);
|
1483 | this.name = "SHA-384";
|
1484 | this.usages = [];
|
1485 | }
|
1486 | async onDigest(algorithm, data) {
|
1487 | return ShaCrypto.digest(algorithm, data);
|
1488 | }
|
1489 | }
|
1490 |
|
1491 | class Sha512Provider extends core__namespace.ProviderCrypto {
|
1492 | constructor() {
|
1493 | super(...arguments);
|
1494 | this.name = "SHA-512";
|
1495 | this.usages = [];
|
1496 | }
|
1497 | async onDigest(algorithm, data) {
|
1498 | return ShaCrypto.digest(algorithm, data);
|
1499 | }
|
1500 | }
|
1501 |
|
1502 | class Sha3256Provider extends core__namespace.ProviderCrypto {
|
1503 | constructor() {
|
1504 | super(...arguments);
|
1505 | this.name = "SHA3-256";
|
1506 | this.usages = [];
|
1507 | }
|
1508 | async onDigest(algorithm, data) {
|
1509 | return ShaCrypto.digest(algorithm, data);
|
1510 | }
|
1511 | }
|
1512 |
|
1513 | class Sha3384Provider extends core__namespace.ProviderCrypto {
|
1514 | constructor() {
|
1515 | super(...arguments);
|
1516 | this.name = "SHA3-384";
|
1517 | this.usages = [];
|
1518 | }
|
1519 | async onDigest(algorithm, data) {
|
1520 | return ShaCrypto.digest(algorithm, data);
|
1521 | }
|
1522 | }
|
1523 |
|
1524 | class Sha3512Provider extends core__namespace.ProviderCrypto {
|
1525 | constructor() {
|
1526 | super(...arguments);
|
1527 | this.name = "SHA3-512";
|
1528 | this.usages = [];
|
1529 | }
|
1530 | async onDigest(algorithm, data) {
|
1531 | return ShaCrypto.digest(algorithm, data);
|
1532 | }
|
1533 | }
|
1534 |
|
1535 | class EcCrypto {
|
1536 | static async generateKey(algorithm, extractable, keyUsages) {
|
1537 | const privateKey = new EcPrivateKey();
|
1538 | privateKey.algorithm = algorithm;
|
1539 | privateKey.extractable = extractable;
|
1540 | privateKey.usages = keyUsages.filter((usage) => this.privateKeyUsages.indexOf(usage) !== -1);
|
1541 | const publicKey = new EcPublicKey();
|
1542 | publicKey.algorithm = algorithm;
|
1543 | publicKey.extractable = true;
|
1544 | publicKey.usages = keyUsages.filter((usage) => this.publicKeyUsages.indexOf(usage) !== -1);
|
1545 | const keys = crypto.generateKeyPairSync("ec", {
|
1546 | namedCurve: this.getOpenSSLNamedCurve(algorithm.namedCurve),
|
1547 | publicKeyEncoding: {
|
1548 | format: "der",
|
1549 | type: "spki",
|
1550 | },
|
1551 | privateKeyEncoding: {
|
1552 | format: "der",
|
1553 | type: "pkcs8",
|
1554 | },
|
1555 | });
|
1556 | privateKey.data = keys.privateKey;
|
1557 | publicKey.data = keys.publicKey;
|
1558 | const res = {
|
1559 | privateKey,
|
1560 | publicKey,
|
1561 | };
|
1562 | return res;
|
1563 | }
|
1564 | static async sign(algorithm, key, data) {
|
1565 | const cryptoAlg = ShaCrypto.getAlgorithmName(algorithm.hash);
|
1566 | const signer = crypto.createSign(cryptoAlg);
|
1567 | signer.update(buffer.Buffer.from(data));
|
1568 | if (!key.pem) {
|
1569 | key.pem = `-----BEGIN PRIVATE KEY-----\n${key.data.toString("base64")}\n-----END PRIVATE KEY-----`;
|
1570 | }
|
1571 | const options = {
|
1572 | key: key.pem,
|
1573 | };
|
1574 | const signature = signer.sign(options);
|
1575 | const ecSignature = asn1Schema.AsnParser.parse(signature, core__namespace.asn1.EcDsaSignature);
|
1576 | const signatureRaw = core__namespace.EcUtils.encodeSignature(ecSignature, core__namespace.EcCurves.get(key.algorithm.namedCurve).size);
|
1577 | return signatureRaw.buffer;
|
1578 | }
|
1579 | static async verify(algorithm, key, signature, data) {
|
1580 | const cryptoAlg = ShaCrypto.getAlgorithmName(algorithm.hash);
|
1581 | const signer = crypto.createVerify(cryptoAlg);
|
1582 | signer.update(buffer.Buffer.from(data));
|
1583 | if (!key.pem) {
|
1584 | key.pem = `-----BEGIN PUBLIC KEY-----\n${key.data.toString("base64")}\n-----END PUBLIC KEY-----`;
|
1585 | }
|
1586 | const options = {
|
1587 | key: key.pem,
|
1588 | };
|
1589 | const ecSignature = new core__namespace.asn1.EcDsaSignature();
|
1590 | const namedCurve = core__namespace.EcCurves.get(key.algorithm.namedCurve);
|
1591 | const signaturePoint = core__namespace.EcUtils.decodeSignature(signature, namedCurve.size);
|
1592 | ecSignature.r = pvtsutils.BufferSourceConverter.toArrayBuffer(signaturePoint.r);
|
1593 | ecSignature.s = pvtsutils.BufferSourceConverter.toArrayBuffer(signaturePoint.s);
|
1594 | const ecSignatureRaw = buffer.Buffer.from(asn1Schema.AsnSerializer.serialize(ecSignature));
|
1595 | const ok = signer.verify(options, ecSignatureRaw);
|
1596 | return ok;
|
1597 | }
|
1598 | static async deriveBits(algorithm, baseKey, length) {
|
1599 | const cryptoAlg = this.getOpenSSLNamedCurve(baseKey.algorithm.namedCurve);
|
1600 | const ecdh = crypto.createECDH(cryptoAlg);
|
1601 | const asnPrivateKey = asn1Schema.AsnParser.parse(baseKey.data, core__namespace.asn1.PrivateKeyInfo);
|
1602 | const asnEcPrivateKey = asn1Schema.AsnParser.parse(asnPrivateKey.privateKey, core__namespace.asn1.EcPrivateKey);
|
1603 | ecdh.setPrivateKey(buffer.Buffer.from(asnEcPrivateKey.privateKey));
|
1604 | const asnPublicKey = asn1Schema.AsnParser.parse(algorithm.public.data, core__namespace.asn1.PublicKeyInfo);
|
1605 | const bits = ecdh.computeSecret(buffer.Buffer.from(asnPublicKey.publicKey));
|
1606 | if (length === null) {
|
1607 | return bits;
|
1608 | }
|
1609 | return new Uint8Array(bits).buffer.slice(0, length >> 3);
|
1610 | }
|
1611 | static async exportKey(format, key) {
|
1612 | switch (format.toLowerCase()) {
|
1613 | case "jwk":
|
1614 | return jsonSchema.JsonSerializer.toJSON(key);
|
1615 | case "pkcs8":
|
1616 | case "spki":
|
1617 | return new Uint8Array(key.data).buffer;
|
1618 | case "raw": {
|
1619 | const publicKeyInfo = asn1Schema.AsnParser.parse(key.data, core__namespace.asn1.PublicKeyInfo);
|
1620 | return publicKeyInfo.publicKey;
|
1621 | }
|
1622 | default:
|
1623 | throw new core__namespace.OperationError("format: Must be 'jwk', 'raw', pkcs8' or 'spki'");
|
1624 | }
|
1625 | }
|
1626 | static async importKey(format, keyData, algorithm, extractable, keyUsages) {
|
1627 | switch (format.toLowerCase()) {
|
1628 | case "jwk": {
|
1629 | const jwk = keyData;
|
1630 | if (jwk.d) {
|
1631 | const asnKey = jsonSchema.JsonParser.fromJSON(keyData, { targetSchema: core__namespace.asn1.EcPrivateKey });
|
1632 | return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
1633 | }
|
1634 | else {
|
1635 | const asnKey = jsonSchema.JsonParser.fromJSON(keyData, { targetSchema: core__namespace.asn1.EcPublicKey });
|
1636 | return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
1637 | }
|
1638 | }
|
1639 | case "raw": {
|
1640 | const asnKey = new core__namespace.asn1.EcPublicKey(keyData);
|
1641 | return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
1642 | }
|
1643 | case "spki": {
|
1644 | const keyInfo = asn1Schema.AsnParser.parse(new Uint8Array(keyData), core__namespace.asn1.PublicKeyInfo);
|
1645 | const asnKey = new core__namespace.asn1.EcPublicKey(keyInfo.publicKey);
|
1646 | this.assertKeyParameters(keyInfo.publicKeyAlgorithm.parameters, algorithm.namedCurve);
|
1647 | return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
1648 | }
|
1649 | case "pkcs8": {
|
1650 | const keyInfo = asn1Schema.AsnParser.parse(new Uint8Array(keyData), core__namespace.asn1.PrivateKeyInfo);
|
1651 | const asnKey = asn1Schema.AsnParser.parse(keyInfo.privateKey, core__namespace.asn1.EcPrivateKey);
|
1652 | this.assertKeyParameters(keyInfo.privateKeyAlgorithm.parameters, algorithm.namedCurve);
|
1653 | return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
1654 | }
|
1655 | default:
|
1656 | throw new core__namespace.OperationError("format: Must be 'jwk', 'raw', 'pkcs8' or 'spki'");
|
1657 | }
|
1658 | }
|
1659 | static assertKeyParameters(parameters, namedCurve) {
|
1660 | if (!parameters) {
|
1661 | throw new core__namespace.CryptoError("Key info doesn't have required parameters");
|
1662 | }
|
1663 | let namedCurveIdentifier = "";
|
1664 | try {
|
1665 | namedCurveIdentifier = asn1Schema.AsnParser.parse(parameters, core__namespace.asn1.ObjectIdentifier).value;
|
1666 | }
|
1667 | catch (e) {
|
1668 | throw new core__namespace.CryptoError("Cannot read key info parameters");
|
1669 | }
|
1670 | if (getOidByNamedCurve$1(namedCurve) !== namedCurveIdentifier) {
|
1671 | throw new core__namespace.CryptoError("Key info parameter doesn't match to named curve");
|
1672 | }
|
1673 | }
|
1674 | static async importPrivateKey(asnKey, algorithm, extractable, keyUsages) {
|
1675 | const keyInfo = new core__namespace.asn1.PrivateKeyInfo();
|
1676 | keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
1677 | keyInfo.privateKeyAlgorithm.parameters = asn1Schema.AsnSerializer.serialize(new core__namespace.asn1.ObjectIdentifier(getOidByNamedCurve$1(algorithm.namedCurve)));
|
1678 | keyInfo.privateKey = asn1Schema.AsnSerializer.serialize(asnKey);
|
1679 | const key = new EcPrivateKey();
|
1680 | key.data = buffer.Buffer.from(asn1Schema.AsnSerializer.serialize(keyInfo));
|
1681 | key.algorithm = Object.assign({}, algorithm);
|
1682 | key.extractable = extractable;
|
1683 | key.usages = keyUsages;
|
1684 | return key;
|
1685 | }
|
1686 | static async importPublicKey(asnKey, algorithm, extractable, keyUsages) {
|
1687 | const keyInfo = new core__namespace.asn1.PublicKeyInfo();
|
1688 | keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
1689 | const namedCurve = getOidByNamedCurve$1(algorithm.namedCurve);
|
1690 | keyInfo.publicKeyAlgorithm.parameters = asn1Schema.AsnSerializer.serialize(new core__namespace.asn1.ObjectIdentifier(namedCurve));
|
1691 | keyInfo.publicKey = asnKey.value;
|
1692 | const key = new EcPublicKey();
|
1693 | key.data = buffer.Buffer.from(asn1Schema.AsnSerializer.serialize(keyInfo));
|
1694 | key.algorithm = Object.assign({}, algorithm);
|
1695 | key.extractable = extractable;
|
1696 | key.usages = keyUsages;
|
1697 | return key;
|
1698 | }
|
1699 | static getOpenSSLNamedCurve(curve) {
|
1700 | switch (curve.toUpperCase()) {
|
1701 | case "P-256":
|
1702 | return "prime256v1";
|
1703 | case "K-256":
|
1704 | return "secp256k1";
|
1705 | case "P-384":
|
1706 | return "secp384r1";
|
1707 | case "P-521":
|
1708 | return "secp521r1";
|
1709 | default:
|
1710 | return curve;
|
1711 | }
|
1712 | }
|
1713 | }
|
1714 | EcCrypto.publicKeyUsages = ["verify"];
|
1715 | EcCrypto.privateKeyUsages = ["sign", "deriveKey", "deriveBits"];
|
1716 |
|
1717 | class EcdsaProvider extends core__namespace.EcdsaProvider {
|
1718 | constructor() {
|
1719 | super(...arguments);
|
1720 | this.namedCurves = core__namespace.EcCurves.names;
|
1721 | this.hashAlgorithms = [
|
1722 | "SHA-1", "SHA-256", "SHA-384", "SHA-512",
|
1723 | "shake128", "shake256",
|
1724 | "SHA3-256", "SHA3-384", "SHA3-512"
|
1725 | ];
|
1726 | }
|
1727 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
1728 | const keys = await EcCrypto.generateKey({
|
1729 | ...algorithm,
|
1730 | name: this.name,
|
1731 | }, extractable, keyUsages);
|
1732 | return {
|
1733 | privateKey: setCryptoKey(keys.privateKey),
|
1734 | publicKey: setCryptoKey(keys.publicKey),
|
1735 | };
|
1736 | }
|
1737 | async onSign(algorithm, key, data) {
|
1738 | return EcCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data));
|
1739 | }
|
1740 | async onVerify(algorithm, key, signature, data) {
|
1741 | return EcCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data));
|
1742 | }
|
1743 | async onExportKey(format, key) {
|
1744 | return EcCrypto.exportKey(format, getCryptoKey(key));
|
1745 | }
|
1746 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
1747 | const key = await EcCrypto.importKey(format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages);
|
1748 | return setCryptoKey(key);
|
1749 | }
|
1750 | checkCryptoKey(key, keyUsage) {
|
1751 | super.checkCryptoKey(key, keyUsage);
|
1752 | const internalKey = getCryptoKey(key);
|
1753 | if (!(internalKey instanceof EcPrivateKey || internalKey instanceof EcPublicKey)) {
|
1754 | throw new TypeError("key: Is not EC CryptoKey");
|
1755 | }
|
1756 | }
|
1757 | }
|
1758 |
|
1759 | class EcdhProvider extends core__namespace.EcdhProvider {
|
1760 | constructor() {
|
1761 | super(...arguments);
|
1762 | this.namedCurves = core__namespace.EcCurves.names;
|
1763 | }
|
1764 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
1765 | const keys = await EcCrypto.generateKey({
|
1766 | ...algorithm,
|
1767 | name: this.name,
|
1768 | }, extractable, keyUsages);
|
1769 | return {
|
1770 | privateKey: setCryptoKey(keys.privateKey),
|
1771 | publicKey: setCryptoKey(keys.publicKey),
|
1772 | };
|
1773 | }
|
1774 | async onExportKey(format, key) {
|
1775 | return EcCrypto.exportKey(format, getCryptoKey(key));
|
1776 | }
|
1777 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
1778 | const key = await EcCrypto.importKey(format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages);
|
1779 | return setCryptoKey(key);
|
1780 | }
|
1781 | checkCryptoKey(key, keyUsage) {
|
1782 | super.checkCryptoKey(key, keyUsage);
|
1783 | const internalKey = getCryptoKey(key);
|
1784 | if (!(internalKey instanceof EcPrivateKey || internalKey instanceof EcPublicKey)) {
|
1785 | throw new TypeError("key: Is not EC CryptoKey");
|
1786 | }
|
1787 | }
|
1788 | async onDeriveBits(algorithm, baseKey, length) {
|
1789 | const bits = await EcCrypto.deriveBits({ ...algorithm, public: getCryptoKey(algorithm.public) }, getCryptoKey(baseKey), length);
|
1790 | return bits;
|
1791 | }
|
1792 | }
|
1793 |
|
1794 | const edOIDs = {
|
1795 | [core__namespace.asn1.idEd448]: "Ed448",
|
1796 | "ed448": core__namespace.asn1.idEd448,
|
1797 | [core__namespace.asn1.idX448]: "X448",
|
1798 | "x448": core__namespace.asn1.idX448,
|
1799 | [core__namespace.asn1.idEd25519]: "Ed25519",
|
1800 | "ed25519": core__namespace.asn1.idEd25519,
|
1801 | [core__namespace.asn1.idX25519]: "X25519",
|
1802 | "x25519": core__namespace.asn1.idX25519,
|
1803 | };
|
1804 | function getOidByNamedCurve(namedCurve) {
|
1805 | const oid = edOIDs[namedCurve.toLowerCase()];
|
1806 | if (!oid) {
|
1807 | throw new core__namespace.OperationError(`Cannot convert WebCrypto named curve '${namedCurve}' to OID`);
|
1808 | }
|
1809 | return oid;
|
1810 | }
|
1811 |
|
1812 | class EdPrivateKey extends AsymmetricKey {
|
1813 | constructor() {
|
1814 | super(...arguments);
|
1815 | this.type = "private";
|
1816 | }
|
1817 | getKey() {
|
1818 | const keyInfo = asn1Schema.AsnParser.parse(this.data, core__namespace.asn1.PrivateKeyInfo);
|
1819 | return asn1Schema.AsnParser.parse(keyInfo.privateKey, core__namespace.asn1.CurvePrivateKey);
|
1820 | }
|
1821 | toJSON() {
|
1822 | const key = this.getKey();
|
1823 | const json = {
|
1824 | kty: "OKP",
|
1825 | crv: this.algorithm.namedCurve,
|
1826 | key_ops: this.usages,
|
1827 | ext: this.extractable,
|
1828 | };
|
1829 | return Object.assign(json, jsonSchema.JsonSerializer.toJSON(key));
|
1830 | }
|
1831 | fromJSON(json) {
|
1832 | if (!json.crv) {
|
1833 | throw new core__namespace.OperationError(`Cannot get named curve from JWK. Property 'crv' is required`);
|
1834 | }
|
1835 | const keyInfo = new core__namespace.asn1.PrivateKeyInfo();
|
1836 | keyInfo.privateKeyAlgorithm.algorithm = getOidByNamedCurve(json.crv);
|
1837 | const key = jsonSchema.JsonParser.fromJSON(json, { targetSchema: core__namespace.asn1.CurvePrivateKey });
|
1838 | keyInfo.privateKey = asn1Schema.AsnSerializer.serialize(key);
|
1839 | this.data = buffer.Buffer.from(asn1Schema.AsnSerializer.serialize(keyInfo));
|
1840 | return this;
|
1841 | }
|
1842 | }
|
1843 |
|
1844 | class EdPublicKey extends AsymmetricKey {
|
1845 | constructor() {
|
1846 | super(...arguments);
|
1847 | this.type = "public";
|
1848 | }
|
1849 | getKey() {
|
1850 | const keyInfo = asn1Schema.AsnParser.parse(this.data, core__namespace.asn1.PublicKeyInfo);
|
1851 | return keyInfo.publicKey;
|
1852 | }
|
1853 | toJSON() {
|
1854 | const key = this.getKey();
|
1855 | const json = {
|
1856 | kty: "OKP",
|
1857 | crv: this.algorithm.namedCurve,
|
1858 | key_ops: this.usages,
|
1859 | ext: this.extractable,
|
1860 | };
|
1861 | return Object.assign(json, {
|
1862 | x: pvtsutils.Convert.ToBase64Url(key)
|
1863 | });
|
1864 | }
|
1865 | fromJSON(json) {
|
1866 | if (!json.crv) {
|
1867 | throw new core__namespace.OperationError(`Cannot get named curve from JWK. Property 'crv' is required`);
|
1868 | }
|
1869 | if (!json.x) {
|
1870 | throw new core__namespace.OperationError(`Cannot get property from JWK. Property 'x' is required`);
|
1871 | }
|
1872 | const keyInfo = new core__namespace.asn1.PublicKeyInfo();
|
1873 | keyInfo.publicKeyAlgorithm.algorithm = getOidByNamedCurve(json.crv);
|
1874 | keyInfo.publicKey = pvtsutils.Convert.FromBase64Url(json.x);
|
1875 | this.data = buffer.Buffer.from(asn1Schema.AsnSerializer.serialize(keyInfo));
|
1876 | return this;
|
1877 | }
|
1878 | }
|
1879 |
|
1880 | class EdCrypto {
|
1881 | static async generateKey(algorithm, extractable, keyUsages) {
|
1882 | const privateKey = new EdPrivateKey();
|
1883 | privateKey.algorithm = algorithm;
|
1884 | privateKey.extractable = extractable;
|
1885 | privateKey.usages = keyUsages.filter((usage) => this.privateKeyUsages.indexOf(usage) !== -1);
|
1886 | const publicKey = new EdPublicKey();
|
1887 | publicKey.algorithm = algorithm;
|
1888 | publicKey.extractable = true;
|
1889 | publicKey.usages = keyUsages.filter((usage) => this.publicKeyUsages.indexOf(usage) !== -1);
|
1890 | const type = algorithm.namedCurve.toLowerCase();
|
1891 | const keys = crypto.generateKeyPairSync(type, {
|
1892 | publicKeyEncoding: {
|
1893 | format: "der",
|
1894 | type: "spki",
|
1895 | },
|
1896 | privateKeyEncoding: {
|
1897 | format: "der",
|
1898 | type: "pkcs8",
|
1899 | },
|
1900 | });
|
1901 | privateKey.data = keys.privateKey;
|
1902 | publicKey.data = keys.publicKey;
|
1903 | const res = {
|
1904 | privateKey,
|
1905 | publicKey,
|
1906 | };
|
1907 | return res;
|
1908 | }
|
1909 | static async sign(algorithm, key, data) {
|
1910 | if (!key.pem) {
|
1911 | key.pem = `-----BEGIN PRIVATE KEY-----\n${key.data.toString("base64")}\n-----END PRIVATE KEY-----`;
|
1912 | }
|
1913 | const options = {
|
1914 | key: key.pem,
|
1915 | };
|
1916 | const signature = crypto.sign(null, buffer.Buffer.from(data), options);
|
1917 | return core__namespace.BufferSourceConverter.toArrayBuffer(signature);
|
1918 | }
|
1919 | static async verify(algorithm, key, signature, data) {
|
1920 | if (!key.pem) {
|
1921 | key.pem = `-----BEGIN PUBLIC KEY-----\n${key.data.toString("base64")}\n-----END PUBLIC KEY-----`;
|
1922 | }
|
1923 | const options = {
|
1924 | key: key.pem,
|
1925 | };
|
1926 | const ok = crypto.verify(null, buffer.Buffer.from(data), options, buffer.Buffer.from(signature));
|
1927 | return ok;
|
1928 | }
|
1929 | static async deriveBits(algorithm, baseKey, length) {
|
1930 | const publicKey = crypto.createPublicKey({
|
1931 | key: algorithm.public.data,
|
1932 | format: "der",
|
1933 | type: "spki",
|
1934 | });
|
1935 | const privateKey = crypto.createPrivateKey({
|
1936 | key: baseKey.data,
|
1937 | format: "der",
|
1938 | type: "pkcs8",
|
1939 | });
|
1940 | const bits = crypto.diffieHellman({
|
1941 | publicKey,
|
1942 | privateKey,
|
1943 | });
|
1944 | return new Uint8Array(bits).buffer.slice(0, length >> 3);
|
1945 | }
|
1946 | static async exportKey(format, key) {
|
1947 | switch (format.toLowerCase()) {
|
1948 | case "jwk":
|
1949 | return jsonSchema.JsonSerializer.toJSON(key);
|
1950 | case "pkcs8":
|
1951 | case "spki":
|
1952 | return new Uint8Array(key.data).buffer;
|
1953 | case "raw": {
|
1954 | const publicKeyInfo = asn1Schema.AsnParser.parse(key.data, core__namespace.asn1.PublicKeyInfo);
|
1955 | return publicKeyInfo.publicKey;
|
1956 | }
|
1957 | default:
|
1958 | throw new core__namespace.OperationError("format: Must be 'jwk', 'raw', pkcs8' or 'spki'");
|
1959 | }
|
1960 | }
|
1961 | static async importKey(format, keyData, algorithm, extractable, keyUsages) {
|
1962 | switch (format.toLowerCase()) {
|
1963 | case "jwk": {
|
1964 | const jwk = keyData;
|
1965 | if (jwk.d) {
|
1966 | const asnKey = jsonSchema.JsonParser.fromJSON(keyData, { targetSchema: core__namespace.asn1.CurvePrivateKey });
|
1967 | return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
1968 | }
|
1969 | else {
|
1970 | if (!jwk.x) {
|
1971 | throw new TypeError("keyData: Cannot get required 'x' filed");
|
1972 | }
|
1973 | return this.importPublicKey(pvtsutils.Convert.FromBase64Url(jwk.x), algorithm, extractable, keyUsages);
|
1974 | }
|
1975 | }
|
1976 | case "raw": {
|
1977 | return this.importPublicKey(keyData, algorithm, extractable, keyUsages);
|
1978 | }
|
1979 | case "spki": {
|
1980 | const keyInfo = asn1Schema.AsnParser.parse(new Uint8Array(keyData), core__namespace.asn1.PublicKeyInfo);
|
1981 | return this.importPublicKey(keyInfo.publicKey, algorithm, extractable, keyUsages);
|
1982 | }
|
1983 | case "pkcs8": {
|
1984 | const keyInfo = asn1Schema.AsnParser.parse(new Uint8Array(keyData), core__namespace.asn1.PrivateKeyInfo);
|
1985 | const asnKey = asn1Schema.AsnParser.parse(keyInfo.privateKey, core__namespace.asn1.CurvePrivateKey);
|
1986 | return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
1987 | }
|
1988 | default:
|
1989 | throw new core__namespace.OperationError("format: Must be 'jwk', 'raw', 'pkcs8' or 'spki'");
|
1990 | }
|
1991 | }
|
1992 | static importPrivateKey(asnKey, algorithm, extractable, keyUsages) {
|
1993 | const key = new EdPrivateKey();
|
1994 | key.fromJSON({
|
1995 | crv: algorithm.namedCurve,
|
1996 | d: pvtsutils.Convert.ToBase64Url(asnKey.d),
|
1997 | });
|
1998 | key.algorithm = Object.assign({}, algorithm);
|
1999 | key.extractable = extractable;
|
2000 | key.usages = keyUsages;
|
2001 | return key;
|
2002 | }
|
2003 | static async importPublicKey(asnKey, algorithm, extractable, keyUsages) {
|
2004 | const key = new EdPublicKey();
|
2005 | key.fromJSON({
|
2006 | crv: algorithm.namedCurve,
|
2007 | x: pvtsutils.Convert.ToBase64Url(asnKey),
|
2008 | });
|
2009 | key.algorithm = Object.assign({}, algorithm);
|
2010 | key.extractable = extractable;
|
2011 | key.usages = keyUsages;
|
2012 | return key;
|
2013 | }
|
2014 | }
|
2015 | EdCrypto.publicKeyUsages = ["verify"];
|
2016 | EdCrypto.privateKeyUsages = ["sign", "deriveKey", "deriveBits"];
|
2017 |
|
2018 | class EdDsaProvider extends core__namespace.EdDsaProvider {
|
2019 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
2020 | const keys = await EdCrypto.generateKey({
|
2021 | name: this.name,
|
2022 | namedCurve: algorithm.namedCurve.replace(/^ed/i, "Ed"),
|
2023 | }, extractable, keyUsages);
|
2024 | return {
|
2025 | privateKey: setCryptoKey(keys.privateKey),
|
2026 | publicKey: setCryptoKey(keys.publicKey),
|
2027 | };
|
2028 | }
|
2029 | async onSign(algorithm, key, data) {
|
2030 | return EdCrypto.sign(algorithm, getCryptoKey(key), new Uint8Array(data));
|
2031 | }
|
2032 | async onVerify(algorithm, key, signature, data) {
|
2033 | return EdCrypto.verify(algorithm, getCryptoKey(key), new Uint8Array(signature), new Uint8Array(data));
|
2034 | }
|
2035 | async onExportKey(format, key) {
|
2036 | return EdCrypto.exportKey(format, getCryptoKey(key));
|
2037 | }
|
2038 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
2039 | const key = await EdCrypto.importKey(format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages);
|
2040 | return setCryptoKey(key);
|
2041 | }
|
2042 | }
|
2043 |
|
2044 | class EcdhEsProvider extends core__namespace.EcdhEsProvider {
|
2045 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
2046 | const keys = await EdCrypto.generateKey({
|
2047 | name: this.name,
|
2048 | namedCurve: algorithm.namedCurve.toUpperCase(),
|
2049 | }, extractable, keyUsages);
|
2050 | return {
|
2051 | privateKey: setCryptoKey(keys.privateKey),
|
2052 | publicKey: setCryptoKey(keys.publicKey),
|
2053 | };
|
2054 | }
|
2055 | async onDeriveBits(algorithm, baseKey, length) {
|
2056 | const bits = await EdCrypto.deriveBits({ ...algorithm, public: getCryptoKey(algorithm.public) }, getCryptoKey(baseKey), length);
|
2057 | return bits;
|
2058 | }
|
2059 | async onExportKey(format, key) {
|
2060 | return EdCrypto.exportKey(format, getCryptoKey(key));
|
2061 | }
|
2062 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
2063 | const key = await EdCrypto.importKey(format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages);
|
2064 | return setCryptoKey(key);
|
2065 | }
|
2066 | }
|
2067 |
|
2068 | class PbkdfCryptoKey extends CryptoKey {
|
2069 | }
|
2070 |
|
2071 | class Pbkdf2Provider extends core__namespace.Pbkdf2Provider {
|
2072 | async onDeriveBits(algorithm, baseKey, length) {
|
2073 | return new Promise((resolve, reject) => {
|
2074 | const salt = core__namespace.BufferSourceConverter.toArrayBuffer(algorithm.salt);
|
2075 | const hash = algorithm.hash.name.replace("-", "");
|
2076 | crypto.pbkdf2(getCryptoKey(baseKey).data, buffer.Buffer.from(salt), algorithm.iterations, length >> 3, hash, (err, derivedBits) => {
|
2077 | if (err) {
|
2078 | reject(err);
|
2079 | }
|
2080 | else {
|
2081 | resolve(new Uint8Array(derivedBits).buffer);
|
2082 | }
|
2083 | });
|
2084 | });
|
2085 | }
|
2086 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
2087 | if (format === "raw") {
|
2088 | const key = new PbkdfCryptoKey();
|
2089 | key.data = buffer.Buffer.from(keyData);
|
2090 | key.algorithm = { name: this.name };
|
2091 | key.extractable = false;
|
2092 | key.usages = keyUsages;
|
2093 | return setCryptoKey(key);
|
2094 | }
|
2095 | throw new core__namespace.OperationError("format: Must be 'raw'");
|
2096 | }
|
2097 | checkCryptoKey(key, keyUsage) {
|
2098 | super.checkCryptoKey(key, keyUsage);
|
2099 | if (!(getCryptoKey(key) instanceof PbkdfCryptoKey)) {
|
2100 | throw new TypeError("key: Is not PBKDF CryptoKey");
|
2101 | }
|
2102 | }
|
2103 | }
|
2104 |
|
2105 | class HmacCryptoKey extends CryptoKey {
|
2106 | get alg() {
|
2107 | const hash = this.algorithm.hash.name.toUpperCase();
|
2108 | return `HS${hash.replace("SHA-", "")}`;
|
2109 | }
|
2110 | set alg(value) {
|
2111 | }
|
2112 | }
|
2113 | tslib.__decorate([
|
2114 | jsonSchema.JsonProp({ name: "k", converter: JsonBase64UrlConverter })
|
2115 | ], HmacCryptoKey.prototype, "data", void 0);
|
2116 |
|
2117 | class HmacProvider extends core__namespace.HmacProvider {
|
2118 | async onGenerateKey(algorithm, extractable, keyUsages) {
|
2119 | const length = (algorithm.length || this.getDefaultLength(algorithm.hash.name)) >> 3 << 3;
|
2120 | const key = new HmacCryptoKey();
|
2121 | key.algorithm = {
|
2122 | ...algorithm,
|
2123 | length,
|
2124 | name: this.name,
|
2125 | };
|
2126 | key.extractable = extractable;
|
2127 | key.usages = keyUsages;
|
2128 | key.data = crypto.randomBytes(length >> 3);
|
2129 | return setCryptoKey(key);
|
2130 | }
|
2131 | async onSign(algorithm, key, data) {
|
2132 | const cryptoAlg = ShaCrypto.getAlgorithmName(key.algorithm.hash);
|
2133 | const hmac = crypto.createHmac(cryptoAlg, getCryptoKey(key).data)
|
2134 | .update(buffer.Buffer.from(data)).digest();
|
2135 | return new Uint8Array(hmac).buffer;
|
2136 | }
|
2137 | async onVerify(algorithm, key, signature, data) {
|
2138 | const cryptoAlg = ShaCrypto.getAlgorithmName(key.algorithm.hash);
|
2139 | const hmac = crypto.createHmac(cryptoAlg, getCryptoKey(key).data)
|
2140 | .update(buffer.Buffer.from(data)).digest();
|
2141 | return hmac.compare(buffer.Buffer.from(signature)) === 0;
|
2142 | }
|
2143 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
2144 | let key;
|
2145 | switch (format.toLowerCase()) {
|
2146 | case "jwk":
|
2147 | key = jsonSchema.JsonParser.fromJSON(keyData, { targetSchema: HmacCryptoKey });
|
2148 | break;
|
2149 | case "raw":
|
2150 | key = new HmacCryptoKey();
|
2151 | key.data = buffer.Buffer.from(keyData);
|
2152 | break;
|
2153 | default:
|
2154 | throw new core__namespace.OperationError("format: Must be 'jwk' or 'raw'");
|
2155 | }
|
2156 | key.algorithm = {
|
2157 | hash: { name: algorithm.hash.name },
|
2158 | name: this.name,
|
2159 | length: key.data.length << 3,
|
2160 | };
|
2161 | key.extractable = extractable;
|
2162 | key.usages = keyUsages;
|
2163 | return setCryptoKey(key);
|
2164 | }
|
2165 | async onExportKey(format, key) {
|
2166 | switch (format.toLowerCase()) {
|
2167 | case "jwk":
|
2168 | return jsonSchema.JsonSerializer.toJSON(getCryptoKey(key));
|
2169 | case "raw":
|
2170 | return new Uint8Array(getCryptoKey(key).data).buffer;
|
2171 | default:
|
2172 | throw new core__namespace.OperationError("format: Must be 'jwk' or 'raw'");
|
2173 | }
|
2174 | }
|
2175 | checkCryptoKey(key, keyUsage) {
|
2176 | super.checkCryptoKey(key, keyUsage);
|
2177 | if (!(getCryptoKey(key) instanceof HmacCryptoKey)) {
|
2178 | throw new TypeError("key: Is not HMAC CryptoKey");
|
2179 | }
|
2180 | }
|
2181 | }
|
2182 |
|
2183 | class HkdfCryptoKey extends CryptoKey {
|
2184 | }
|
2185 |
|
2186 | class HkdfProvider extends core__namespace.HkdfProvider {
|
2187 | async onImportKey(format, keyData, algorithm, extractable, keyUsages) {
|
2188 | if (format.toLowerCase() !== "raw") {
|
2189 | throw new core__namespace.OperationError("Operation not supported");
|
2190 | }
|
2191 | const key = new HkdfCryptoKey();
|
2192 | key.data = buffer.Buffer.from(keyData);
|
2193 | key.algorithm = { name: this.name };
|
2194 | key.extractable = extractable;
|
2195 | key.usages = keyUsages;
|
2196 | return setCryptoKey(key);
|
2197 | }
|
2198 | async onDeriveBits(params, baseKey, length) {
|
2199 | const hash = params.hash.name.replace("-", "");
|
2200 | const hashLength = crypto.createHash(hash).digest().length;
|
2201 | const byteLength = length / 8;
|
2202 | const info = core.BufferSourceConverter.toUint8Array(params.info);
|
2203 | const PRK = crypto.createHmac(hash, core.BufferSourceConverter.toUint8Array(params.salt))
|
2204 | .update(core.BufferSourceConverter.toUint8Array(getCryptoKey(baseKey).data))
|
2205 | .digest();
|
2206 | const blocks = [buffer.Buffer.alloc(0)];
|
2207 | const blockCount = Math.ceil(byteLength / hashLength) + 1;
|
2208 | for (let i = 1; i < blockCount; ++i) {
|
2209 | blocks.push(crypto.createHmac(hash, PRK)
|
2210 | .update(buffer.Buffer.concat([blocks[i - 1], info, buffer.Buffer.from([i])]))
|
2211 | .digest());
|
2212 | }
|
2213 | return buffer.Buffer.concat(blocks).slice(0, byteLength);
|
2214 | }
|
2215 | checkCryptoKey(key, keyUsage) {
|
2216 | super.checkCryptoKey(key, keyUsage);
|
2217 | if (!(getCryptoKey(key) instanceof HkdfCryptoKey)) {
|
2218 | throw new TypeError("key: Is not HKDF CryptoKey");
|
2219 | }
|
2220 | }
|
2221 | }
|
2222 |
|
2223 | class ShakeCrypto {
|
2224 | static digest(algorithm, data) {
|
2225 | const hash = crypto.createHash(algorithm.name.toLowerCase(), { outputLength: algorithm.length })
|
2226 | .update(buffer.Buffer.from(data)).digest();
|
2227 | return new Uint8Array(hash).buffer;
|
2228 | }
|
2229 | }
|
2230 |
|
2231 | class Shake128Provider extends core__namespace.Shake128Provider {
|
2232 | async onDigest(algorithm, data) {
|
2233 | return ShakeCrypto.digest(algorithm, data);
|
2234 | }
|
2235 | }
|
2236 |
|
2237 | class Shake256Provider extends core__namespace.Shake256Provider {
|
2238 | async onDigest(algorithm, data) {
|
2239 | return ShakeCrypto.digest(algorithm, data);
|
2240 | }
|
2241 | }
|
2242 |
|
2243 | class SubtleCrypto extends core__namespace.SubtleCrypto {
|
2244 | constructor() {
|
2245 | var _a;
|
2246 | super();
|
2247 | this.providers.set(new AesCbcProvider());
|
2248 | this.providers.set(new AesCtrProvider());
|
2249 | this.providers.set(new AesGcmProvider());
|
2250 | this.providers.set(new AesCmacProvider());
|
2251 | this.providers.set(new AesKwProvider());
|
2252 | this.providers.set(new AesEcbProvider());
|
2253 | const ciphers = crypto__namespace.getCiphers();
|
2254 | if (ciphers.includes("des-cbc")) {
|
2255 | this.providers.set(new DesCbcProvider());
|
2256 | }
|
2257 | this.providers.set(new DesEde3CbcProvider());
|
2258 | this.providers.set(new RsaSsaProvider());
|
2259 | this.providers.set(new RsaPssProvider());
|
2260 | this.providers.set(new RsaOaepProvider());
|
2261 | this.providers.set(new RsaEsProvider());
|
2262 | this.providers.set(new EcdsaProvider());
|
2263 | this.providers.set(new EcdhProvider());
|
2264 | this.providers.set(new Sha1Provider());
|
2265 | this.providers.set(new Sha256Provider());
|
2266 | this.providers.set(new Sha384Provider());
|
2267 | this.providers.set(new Sha512Provider());
|
2268 | this.providers.set(new Pbkdf2Provider());
|
2269 | this.providers.set(new HmacProvider());
|
2270 | this.providers.set(new HkdfProvider());
|
2271 | const nodeMajorVersion = (_a = /^v(\d+)/.exec(process__namespace.version)) === null || _a === void 0 ? void 0 : _a[1];
|
2272 | if (nodeMajorVersion && parseInt(nodeMajorVersion, 10) >= 12) {
|
2273 | this.providers.set(new Shake128Provider());
|
2274 | this.providers.set(new Shake256Provider());
|
2275 | }
|
2276 | const hashes = crypto__namespace.getHashes();
|
2277 | if (hashes.includes("sha3-256")) {
|
2278 | this.providers.set(new Sha3256Provider());
|
2279 | }
|
2280 | if (hashes.includes("sha3-384")) {
|
2281 | this.providers.set(new Sha3384Provider());
|
2282 | }
|
2283 | if (hashes.includes("sha3-512")) {
|
2284 | this.providers.set(new Sha3512Provider());
|
2285 | }
|
2286 | if (nodeMajorVersion && parseInt(nodeMajorVersion, 10) >= 14) {
|
2287 | this.providers.set(new EdDsaProvider());
|
2288 | this.providers.set(new EcdhEsProvider());
|
2289 | }
|
2290 | }
|
2291 | }
|
2292 |
|
2293 | class Crypto extends core__namespace.Crypto {
|
2294 | constructor() {
|
2295 | super(...arguments);
|
2296 | this.subtle = new SubtleCrypto();
|
2297 | }
|
2298 | getRandomValues(array) {
|
2299 | if (!ArrayBuffer.isView(array)) {
|
2300 | throw new TypeError("Failed to execute 'getRandomValues' on 'Crypto': parameter 1 is not of type 'ArrayBufferView'");
|
2301 | }
|
2302 | const buffer$1 = buffer.Buffer.from(array.buffer, array.byteOffset, array.byteLength);
|
2303 | crypto.randomFillSync(buffer$1);
|
2304 | return array;
|
2305 | }
|
2306 | }
|
2307 |
|
2308 | Object.defineProperty(exports, "CryptoKey", {
|
2309 | enumerable: true,
|
2310 | get: function () { return core.CryptoKey; }
|
2311 | });
|
2312 | exports.Crypto = Crypto;
|