-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Expand file tree
/
Copy pathPubKeyFromCSR.mjs
More file actions
79 lines (72 loc) · 2.84 KB
/
Copy pathPubKeyFromCSR.mjs
File metadata and controls
79 lines (72 loc) · 2.84 KB
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
70
71
72
73
74
75
76
77
78
79
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import forge from "node-forge";
const { asn1, pki, util } = forge;
/**
* Public Key from CSR operation
*/
class PubKeyFromCSR extends Operation {
/**
* PubKeyFromCSR constructor
*/
constructor() {
super();
this.name = "Public Key from CSR";
this.module = "PublicKey";
this.description = "Extracts the Public Key from a Certificate Signing Request. Currently only supports ECDSA and RSA.";
this.infoURL = "https://en.wikipedia.org/wiki/Certificate_signing_request";
this.inputType = "string";
this.outputType = "string";
this.args = [];
this.checks = [];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
let output = "";
let match;
const regex = /-----BEGIN (CERTIFICATE REQUEST)-----/g;
while ((match = regex.exec(input)) !== null) {
const indexBase64 = match.index + match[0].length;
const footer = `-----END ${match[1]}-----`;
const indexFooter = input.indexOf(footer, indexBase64);
if (indexFooter === -1) {
throw new OperationError(`CSR footer '${footer}' not found`);
}
const csrString = input.substring(match.index, indexFooter + footer.length);
let pubKeyPem;
try {
// RSA
const csr = pki.certificationRequestFromPem(csrString);
pubKeyPem = pki.publicKeyToPem(csr.publicKey);
} catch (e) {
if (!e.message.includes("OID is not RSA")) {
throw new OperationError(`Failed to parse CSR or extract public key: ${e}`);
}
// EC
try {
const csrDer = util.decode64(
csrString
.replace("-----BEGIN CERTIFICATE REQUEST-----", "")
.replace("-----END CERTIFICATE REQUEST-----", "")
.replace(/\s+/g, "")
);
const csrAsn1 = asn1.fromDer(csrDer);
const certReqInfo = csrAsn1.value[0];
const spki = certReqInfo.value[2];
const spkiDer = asn1.toDer(spki).getBytes();
const spkiB64 = util.encode64(spkiDer);
pubKeyPem = `-----BEGIN PUBLIC KEY-----\n${spkiB64.match(/.{1,64}/g).join("\n")}\n-----END PUBLIC KEY-----\n`;
} catch (err) {
throw new OperationError(`Failed to parse CSR or extract public key: ${err}`);
}
}
output += pubKeyPem;
}
return output;
}
}
export default PubKeyFromCSR;