53 lines
2.3 KiB
JavaScript
53 lines
2.3 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const forge = require('node-forge');
|
|
|
|
const rootDir = path.resolve(__dirname, '..');
|
|
const rawConfigText = fs.readFileSync(path.join(rootDir, 'config.json'), 'utf8');
|
|
const configText = rawConfigText.charCodeAt(0) === 0xfeff ? rawConfigText.slice(1) : rawConfigText;
|
|
const config = JSON.parse(configText);
|
|
const certDir = path.resolve(rootDir, config.certDir || 'certs');
|
|
const keyPath = path.join(certDir, 'rootCA.key.pem');
|
|
const certPath = path.join(certDir, 'rootCA.cert.pem');
|
|
const certDerPath = path.join(certDir, 'rootCA.cert.cer');
|
|
|
|
fs.mkdirSync(certDir, { recursive: true });
|
|
|
|
if (fs.existsSync(keyPath) || fs.existsSync(certPath) || fs.existsSync(certDerPath)) {
|
|
console.error('Root CA already exists. Delete certs/rootCA.* first if you intentionally want to regenerate it.');
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log('Generating 2048-bit RSA root CA...');
|
|
const keys = forge.pki.rsa.generateKeyPair(2048);
|
|
const cert = forge.pki.createCertificate();
|
|
cert.publicKey = keys.publicKey;
|
|
cert.serialNumber = forge.util.bytesToHex(forge.random.getBytesSync(16)).replace(/^00/, '01');
|
|
cert.validity.notBefore = new Date(Date.now() - 60 * 1000);
|
|
cert.validity.notAfter = new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000);
|
|
cert.setSubject([
|
|
{ name: 'commonName', value: 'Local Node MITM Proxy Root CA' },
|
|
{ name: 'organizationName', value: 'Local Development' },
|
|
{ shortName: 'OU', value: 'Debug Proxy' },
|
|
]);
|
|
cert.setIssuer(cert.subject.attributes);
|
|
cert.setExtensions([
|
|
{ name: 'basicConstraints', cA: true, critical: true },
|
|
{ name: 'keyUsage', keyCertSign: true, cRLSign: true, critical: true },
|
|
{ name: 'subjectKeyIdentifier' },
|
|
]);
|
|
cert.sign(keys.privateKey, forge.md.sha256.create());
|
|
|
|
const keyPem = forge.pki.privateKeyToPem(keys.privateKey);
|
|
const certPem = forge.pki.certificateToPem(cert);
|
|
const certDer = Buffer.from(forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes(), 'binary');
|
|
|
|
fs.writeFileSync(keyPath, keyPem, 'utf8');
|
|
fs.writeFileSync(certPath, certPem, 'utf8');
|
|
fs.writeFileSync(certDerPath, certDer);
|
|
|
|
console.log(`Created private key: ${keyPath}`);
|
|
console.log(`Created PEM cert: ${certPath}`);
|
|
console.log(`Created DER cert: ${certDerPath}`);
|
|
console.log('Keep rootCA.key.pem private. Anyone with it can mint trusted certificates on this machine.');
|