fix: update version to 0.5.0, add support for PEM and PFX formats, and implement certificate conversion functionality
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import * as forge from 'node-forge';
|
||||
|
||||
export interface PemBundle {
|
||||
privateKeyPem: string;
|
||||
certPem: string;
|
||||
chainPem: string;
|
||||
}
|
||||
|
||||
export function pemToPfx(privateKeyPem: string, certPem: string, chainPem: string, password = ''): Buffer {
|
||||
const key = forge.pki.privateKeyFromPem(privateKeyPem);
|
||||
const cert = forge.pki.certificateFromPem(certPem);
|
||||
const chain = chainPem
|
||||
.split(/(?=-----BEGIN CERTIFICATE-----)/)
|
||||
.filter(Boolean)
|
||||
.map(p => forge.pki.certificateFromPem(p));
|
||||
|
||||
const p12 = forge.pkcs12.toPkcs12Asn1(key, [cert, ...chain], password, { algorithm: '3des' });
|
||||
const der = forge.asn1.toDer(p12).getBytes();
|
||||
return Buffer.from(der, 'binary');
|
||||
}
|
||||
|
||||
export function pfxToPem(pfxBuffer: Buffer, password = ''): PemBundle {
|
||||
const p12Asn1 = forge.asn1.fromDer(forge.util.createBuffer(pfxBuffer.toString('binary')));
|
||||
const p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, password);
|
||||
|
||||
const keyBags = p12.getBags({ bagType: forge.pki.oids.pkcs8ShroudedKeyBag });
|
||||
const certBags = p12.getBags({ bagType: forge.pki.oids.certBag });
|
||||
|
||||
const keyBag = keyBags[forge.pki.oids.pkcs8ShroudedKeyBag]?.[0];
|
||||
const allCertBags = certBags[forge.pki.oids.certBag] ?? [];
|
||||
|
||||
if (!keyBag?.key) throw new Error('No private key found in PFX');
|
||||
if (allCertBags.length === 0) throw new Error('No certificates found in PFX');
|
||||
|
||||
const [first, ...rest] = allCertBags.map(bag => forge.pki.certificateToPem(bag.cert!));
|
||||
return {
|
||||
privateKeyPem: forge.pki.privateKeyToPem(keyBag.key),
|
||||
certPem: first,
|
||||
chainPem: rest.join(''),
|
||||
};
|
||||
}
|
||||
|
||||
export function parsePemBundle(bundle: string): PemBundle {
|
||||
const blocks = bundle.match(/-----BEGIN [^-]+-----[\s\S]+?-----END [^-]+-----/g) ?? [];
|
||||
const privateKeyPem = blocks.find(b => b.includes('PRIVATE KEY')) ?? '';
|
||||
const certs = blocks.filter(b => b.includes('CERTIFICATE'));
|
||||
return {
|
||||
privateKeyPem,
|
||||
certPem: certs[0] ?? '',
|
||||
chainPem: certs.slice(1).join(''),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user