Added support for ECDSA CSR public key extraction.

This commit is contained in:
Fra3zz 2026-03-22 12:53:38 -05:00
parent 7e0f774895
commit f7b85f7935
No known key found for this signature in database
GPG Key ID: B76D7C7952C2FFB5

View File

@ -2,6 +2,8 @@ import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs"; import OperationError from "../errors/OperationError.mjs";
import forge from "node-forge"; import forge from "node-forge";
const { asn1, pki, util } = forge;
/** /**
* Public Key from CSR operation * Public Key from CSR operation
*/ */
@ -12,7 +14,6 @@ class PubKeyFromCSR extends Operation {
*/ */
constructor() { constructor() {
super(); super();
this.name = "Public Key from CSR"; this.name = "Public Key from CSR";
this.module = "PublicKey"; this.module = "PublicKey";
this.description = "Extracts the Public Key from a Certificate Signing Request."; this.description = "Extracts the Public Key from a Certificate Signing Request.";
@ -33,7 +34,6 @@ class PubKeyFromCSR extends Operation {
let match; let match;
const regex = /-----BEGIN (CERTIFICATE REQUEST)-----/g; const regex = /-----BEGIN (CERTIFICATE REQUEST)-----/g;
while ((match = regex.exec(input)) !== null) { while ((match = regex.exec(input)) !== null) {
// find corresponding end tag
const indexBase64 = match.index + match[0].length; const indexBase64 = match.index + match[0].length;
const footer = `-----END ${match[1]}-----`; const footer = `-----END ${match[1]}-----`;
const indexFooter = input.indexOf(footer, indexBase64); const indexFooter = input.indexOf(footer, indexBase64);
@ -41,16 +41,35 @@ class PubKeyFromCSR extends Operation {
throw new OperationError(`CSR footer '${footer}' not found`); throw new OperationError(`CSR footer '${footer}' not found`);
} }
const csrString = input.substring(match.index, indexFooter + footer.length); const csrString = input.substring(match.index, indexFooter + footer.length);
let pubKey;
let pubKeyPem;
try { try {
// Parse the CSR and extract the public key. // RSA
pubKey = forge.pki.certificationRequestFromPem(csrString).publicKey; const csr = pki.certificationRequestFromPem(csrString);
} catch (err) { pubKeyPem = pki.publicKeyToPem(csr.publicKey);
throw new OperationError(`Failed to parse CSR or extract public key: ${err}`); } 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}`);
}
} }
// Convert the extracted public key object to PEM format.
const pubKeyPem = forge.pki.publicKeyToPem(pubKey);
output += pubKeyPem; output += pubKeyPem;
} }
return output; return output;