-
Notifications
You must be signed in to change notification settings - Fork 8
/
rsa-common.ts
69 lines (62 loc) · 2.38 KB
/
rsa-common.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { crypto } from "@ndn/util";
import type * as asn1 from "@yoursunny/asn1";
import type { CryptoAlgorithm } from "../key/mod";
import { extractSpkiAlgorithm } from "./impl-spki";
import type { RSA } from "./rsa";
export type RsaModulusLength = 2048 | 4096;
export namespace RsaModulusLength {
export const Default: RsaModulusLength = 2048;
export const Choices: readonly RsaModulusLength[] = [2048, 4096];
}
export abstract class RsaCommon implements CryptoAlgorithm<{}, true, RSA.GenParams> {
constructor(protected readonly name: string, hash: AlgorithmIdentifier = "SHA-256") {
this.importParams = { name, hash };
this.genParams = {
...this.importParams,
publicExponent: Uint8Array.of(0x01, 0x00, 0x01),
modulusLength: RsaModulusLength.Default,
};
}
public abstract readonly uuid: string;
public abstract readonly keyUsages: Record<"private" | "public", readonly KeyUsage[]>;
protected readonly importParams: RsaHashedImportParams;
protected readonly genParams: RsaHashedKeyGenParams;
async cryptoGenerate({ modulusLength = RsaModulusLength.Default, importPkcs8 }: RSA.GenParams, extractable: boolean) {
let privateKey: CryptoKey;
let publicKey: CryptoKey;
if (importPkcs8) {
const [pkcs8, spki] = importPkcs8;
[privateKey, publicKey] = await Promise.all([
crypto.subtle.importKey("pkcs8", pkcs8, this.importParams, extractable, this.keyUsages.private),
crypto.subtle.importKey("spki", spki, this.importParams, true, this.keyUsages.public),
]);
} else {
const genParams: RsaHashedKeyGenParams = {
...this.genParams,
modulusLength,
};
({ privateKey, publicKey } = await crypto.subtle.generateKey(genParams, extractable,
[...this.keyUsages.private, ...this.keyUsages.public]));
}
const spki = new Uint8Array(await crypto.subtle.exportKey("spki", publicKey));
return {
privateKey,
publicKey,
jwkImportParams: this.importParams,
spki,
info: {},
};
}
public async importSpki(spki: Uint8Array, der: asn1.ElementBuffer) {
if (extractSpkiAlgorithm(der) !== "2A864886F70D010101") { // 1.2.840.113549.1.1.1
throw new Error("not RSA key");
}
const key = await crypto.subtle.importKey(
"spki", spki, this.importParams, true, this.keyUsages.public);
return {
publicKey: key,
spki,
info: {},
};
}
}