Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Subash committed Sep 23, 2020
1 parent c4f7a2b commit 6317461
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 36 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
},
"homepage": "https://github.com/Subash/mkcert#readme",
"dependencies": {
"commander": "^5.1.0",
"commander": "^6.1.0",
"is-ip": "^3.1.0",
"node-forge": "^0.10.0",
"random-int": "^2.0.1"
Expand Down
18 changes: 5 additions & 13 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,68 +6,61 @@ const fs = require('fs');
const mkcert = require('./mkcert');

async function createCA({ organization, countryCode, state, locality, validity, key, cert }) {
// validate days
validity = Number.parseInt(validity, 10);
if(!validity || validity < 0) return console.error('`--validity` must be at least 1 day.');

// create the certificate
let ca;
try {
ca = await mkcert.createCA({ organization, countryCode, state, locality, validityDays: validity });
} catch (err) {
return console.error(`Failed to create the certificate. Error: ${err.message}`);
}

// write certificates
key = path.resolve(key);
fs.writeFileSync(key, ca.key);
console.log(`CA Private Key: ${key}`);

cert = path.resolve(cert);
fs.writeFileSync(cert, ca.cert);
console.log(`CA Certificate: ${cert}`);

console.log('Please keep the private key in a secure location.');
}

async function createCert({ domains, caKey, caCert, validity, key, cert }) {
// validate days
validity = Number.parseInt(validity, 10);
if(!validity || validity < 0) return console.error('`--validity` must be at least 1 day.');

// validate addresses
domains = domains.split(',').map( str=> str.trim()); // split comma separated list of addresses
domains = domains.split(',').map( str=> str.trim()); // split the comma separated list of addresses
if(!domains.length) return console.error('`--domains` must be a comma separated list of ip/domains.');

// read CA data
const ca = {};

// read CA key
try {
ca.key = fs.readFileSync(path.resolve(caKey), 'utf-8');
} catch(err) {
return console.error(`Unable to read \`${caKey}\`. Please run \`mkcert create-ca\` to create a new certificate authority.`);
}

// read CA certificate
try {
ca.cert = fs.readFileSync(path.resolve(caCert), 'utf-8');
} catch(err) {
return console.error(`Unable to read \`${caCert}\`. Please run \`mkcert create-ca\` to create a new certificate authority.`);
}

// create the certificate
let tls;
try {
tls = await mkcert.createCert({ domains, validityDays: validity, caKey: ca.key, caCert: ca.cert });
} catch (err) {
return console.error(`Failed to create the certificate. Error: ${err.message}`);
}

// write certificates
key = path.resolve(key);
fs.writeFileSync(key, tls.key);
console.log(`Private Key: ${key}`);

cert = path.resolve(cert);
fs.writeFileSync(cert, `${tls.cert}\n${ca.cert}`); // create full chain by combining ca and domain certificate
fs.writeFileSync(cert, `${tls.cert}\n${ca.cert}`); // create full chain certificate file by combining ca and domain certificate
console.log(`Certificate: ${cert}`);
}

Expand Down Expand Up @@ -102,5 +95,4 @@ program
.version(pkg.version)
.parse(process.argv);

// show help by default
if(process.argv.length < 3) program.outputHelp();
23 changes: 8 additions & 15 deletions src/mkcert.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
const isIp = require('is-ip');
const forge = require('node-forge');
const { promisify } = require('util');
const isIp = require('is-ip');
const randomInt = require('random-int');
const pki = forge.pki;
const generateKeyPair = promisify(pki.rsa.generateKeyPair.bind(pki.rsa));

async function generateCert({ subject, issuer, extensions, validityDays, signWith }) {
const serial = randomInt(50000, 99999).toString();
const keyPair = await generateKeyPair({ bits: 2048, workers: 4 });
const cert = pki.createCertificate();
const serial = randomInt(50000, 99999).toString(); // generate a random number between 50K and 100K

// use the provided private key to sign the certificate if that exists
// otherwise sign the certificate with own key
signWith = signWith? pki.privateKeyFromPem(signWith): keyPair.privateKey;

// public key
cert.publicKey = keyPair.publicKey;
cert.serialNumber = Buffer.from(serial).toString('hex'); // hex encode the serial number

// validity
cert.serialNumber = Buffer.from(serial).toString('hex'); // serial number must be hex encoded
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setDate(cert.validity.notAfter.getDate() + validityDays);

cert.setSubject(subject);
cert.setIssuer(issuer);
cert.setExtensions(extensions);

// sign the certificate with it's own private key if no separate signing key is provided
signWith = signWith? pki.privateKeyFromPem(signWith): keyPair.privateKey;
cert.sign(signWith, forge.md.sha256.create());

return {
Expand All @@ -44,7 +39,7 @@ async function createCA({ organization, countryCode, state, locality, validityDa
{ name: 'organizationName', value: organization }
];

// certificate extensions for a CA
// required certificate extensions for a certificate authority
const extensions = [
{ name: 'basicConstraints', cA: true, critical: true },
{ name: 'keyUsage', keyCertSign: true, critical: true }
Expand All @@ -64,7 +59,7 @@ async function createCert({ domains, validityDays, caKey, caCert }) {
{ name: 'commonName', value: domains[0] } // use the first address as common name
];

// certificate extensions for a domain certificate
// required certificate extensions for a tls certificate
const extensions = [
{ name: 'basicConstraints', cA: false, critical: true },
{ name: 'keyUsage', digitalSignature: true, keyEncipherment: true, critical: true },
Expand All @@ -76,10 +71,8 @@ async function createCert({ domains, validityDays, caKey, caCert }) {
})}
];

// parse CA certificate
const ca = pki.certificateFromPem(caCert);

// create the cert
return await generateCert({
subject: attributes,
issuer: ca.subject.attributes,
Expand Down

0 comments on commit 6317461

Please sign in to comment.