UNPKG

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