added fork, privateKey and accountKey options
This commit is contained in:
parent
d1c2dd4dcf
commit
31b25af1cb
|
@ -1,3 +1,9 @@
|
||||||
|
0.0.5-beta / 2015-12
|
||||||
|
=======================
|
||||||
|
|
||||||
|
* Added fork option
|
||||||
|
* Added accountKey and privateKey options
|
||||||
|
|
||||||
0.0.4-beta / 2015-12-13
|
0.0.4-beta / 2015-12-13
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ app
|
||||||
.option('-c, --cert <path>', 'path to save your certificate (cert.pem)')
|
.option('-c, --cert <path>', 'path to save your certificate (cert.pem)')
|
||||||
.option('-k, --key <path>', 'path to save your private key (privkey.pem)')
|
.option('-k, --key <path>', 'path to save your private key (privkey.pem)')
|
||||||
.option('-i, --ca <path>', 'path to save issuer certificate (cacert.pem)')
|
.option('-i, --ca <path>', 'path to save issuer certificate (cacert.pem)')
|
||||||
|
.option('-a, --account <path>', 'path of the account key (optional)')
|
||||||
.option('--pfx <path>', 'path to save PKCS#12 certificate (optional)')
|
.option('--pfx <path>', 'path to save PKCS#12 certificate (optional)')
|
||||||
.option('--password <password>', 'password for PKCS#12 certificate (optional)')
|
.option('--password <password>', 'password for PKCS#12 certificate (optional)')
|
||||||
.option('--aes', 'use AES instead of 3DES for PKCS#12')
|
.option('--aes', 'use AES instead of 3DES for PKCS#12')
|
||||||
|
@ -47,6 +48,7 @@ letiny.getCert({
|
||||||
certFile:app.cert || (app.pfx ? false : 'cert.pem'),
|
certFile:app.cert || (app.pfx ? false : 'cert.pem'),
|
||||||
keyFile:app.key || (app.pfx ? false : 'privkey.pem'),
|
keyFile:app.key || (app.pfx ? false : 'privkey.pem'),
|
||||||
caFile:app.ca || (app.pfx ? false : 'cacert.pem'),
|
caFile:app.ca || (app.pfx ? false : 'cacert.pem'),
|
||||||
|
accountKey:app.account,
|
||||||
pfxFile:app.pfx,
|
pfxFile:app.pfx,
|
||||||
pfxPassword:app.password,
|
pfxPassword:app.password,
|
||||||
aes:app.aes,
|
aes:app.aes,
|
||||||
|
|
|
@ -11,7 +11,7 @@ var _DEBUG, NOOP=new Function(), log=NOOP,
|
||||||
mkdirp=require('mkdirp').sync, request=require('request'),
|
mkdirp=require('mkdirp').sync, request=require('request'),
|
||||||
forge=require('node-forge'), pki=forge.pki,
|
forge=require('node-forge'), pki=forge.pki,
|
||||||
cryptoUtil=require('./crypto-util'), util=require('./acme-util'),
|
cryptoUtil=require('./crypto-util'), util=require('./acme-util'),
|
||||||
fs=require('fs'), path=require('path');
|
fs=require('fs'), path=require('path'), child=require('child_process');
|
||||||
|
|
||||||
function Acme(privateKey) {
|
function Acme(privateKey) {
|
||||||
this.privateKey=privateKey;
|
this.privateKey=privateKey;
|
||||||
|
@ -131,23 +131,81 @@ function getCert(options, cb) {
|
||||||
log=NOOP;
|
log=NOOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
makeAccountKeyPair();
|
if (options.fork && !~process.argv.indexOf('--letiny-fork')) {
|
||||||
|
state.child=child.fork(__filename, ['--letiny-fork']);
|
||||||
|
if (options.challenge) {
|
||||||
|
return cb(new Error('fork+challenge not supported yet'));
|
||||||
|
}
|
||||||
|
state.child.send({request:options});
|
||||||
|
state.child.on('message', function(msg) {
|
||||||
|
var res;
|
||||||
|
if (msg.result) {
|
||||||
|
res=msg.result;
|
||||||
|
cb(res.err ? new Error(res.err) : null, res.cert, res.key, res.ca);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
function makeAccountKeyPair() {
|
if (options.accountKey) {
|
||||||
|
if (options.accountKey.length>255) {
|
||||||
|
state.accountKeyPEM=options.accountKey;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
state.accountKeyPEM=fs.readFileSync(options.accountKey);
|
||||||
|
} catch(err) {
|
||||||
|
if (err.code==='ENOENT') {
|
||||||
|
makeAccountKeyPair(true);
|
||||||
|
} else {
|
||||||
|
return handleErr(err, 'Failed to load accountKey');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
state.accountKeyPair=cryptoUtil.importPemPrivateKey(state.accountKeyPEM);
|
||||||
|
} catch(err) {
|
||||||
|
return handleErr(err, 'Failed to parse accountKey');
|
||||||
|
}
|
||||||
|
initAcme();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
makeAccountKeyPair();
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeAccountKeyPair(save) {
|
||||||
var keypair;
|
var keypair;
|
||||||
log('Generating account keypair...');
|
log('Generating account keypair...');
|
||||||
keypair=pki.rsa.generateKeyPair(2048);
|
keypair=pki.rsa.generateKeyPair(2048);
|
||||||
state.accountKeyPair=cryptoUtil.importPemPrivateKey(pki.privateKeyToPem(keypair.privateKey));
|
state.accountKeyPEM=pki.privateKeyToPem(keypair.privateKey);
|
||||||
|
state.accountKeyPair=cryptoUtil.importPemPrivateKey(state.accountKeyPEM);
|
||||||
|
if (save) {
|
||||||
|
try {
|
||||||
|
fs.writeFileSync(options.accountKey, state.accountKeyPEM);
|
||||||
|
} catch(err) {
|
||||||
|
return handleErr(err, 'Failed to save accountKey');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initAcme();
|
||||||
|
}
|
||||||
|
|
||||||
|
function initAcme() {
|
||||||
state.acme=new Acme(state.accountKeyPair);
|
state.acme=new Acme(state.accountKeyPair);
|
||||||
makeKeyPair();
|
makeKeyPair();
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeKeyPair() {
|
function makeKeyPair() {
|
||||||
var keypair;
|
var keypair;
|
||||||
|
if (options.privateKey) {
|
||||||
|
state.certPrivateKeyPEM=options.privateKey;
|
||||||
|
} else {
|
||||||
log('Generating cert keypair...');
|
log('Generating cert keypair...');
|
||||||
keypair=pki.rsa.generateKeyPair(2048);
|
keypair=pki.rsa.generateKeyPair(2048);
|
||||||
state.certPrivateKeyPEM=pki.privateKeyToPem(keypair.privateKey);
|
state.certPrivateKeyPEM=pki.privateKeyToPem(keypair.privateKey);
|
||||||
|
}
|
||||||
|
try {
|
||||||
state.certPrivateKey=cryptoUtil.importPemPrivateKey(state.certPrivateKeyPEM);
|
state.certPrivateKey=cryptoUtil.importPemPrivateKey(state.certPrivateKeyPEM);
|
||||||
|
} catch(err) {
|
||||||
|
return handleErr(err, 'Failed to parse privateKey');
|
||||||
|
}
|
||||||
register();
|
register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,5 +517,22 @@ function parseLink(link) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (~process.argv.indexOf('--letiny-fork')) {
|
||||||
|
process.on('message', function(msg) {
|
||||||
|
if (msg.request) {
|
||||||
|
getCert(msg.request.options, function(err, cert, key, ca) {
|
||||||
|
process.send({
|
||||||
|
result:{
|
||||||
|
err:err ? err.stack : null,
|
||||||
|
cert:cert,
|
||||||
|
key:key,
|
||||||
|
ca:ca
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
exports.getCert=getCert;
|
exports.getCert=getCert;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "letiny",
|
"name": "letiny",
|
||||||
"version": "0.0.4-beta",
|
"version": "0.0.5-beta",
|
||||||
"description": "Tiny ACME client library and CLI",
|
"description": "Tiny ACME client library and CLI",
|
||||||
"author": "Anatol Sommer <anatol@anatol.at>",
|
"author": "Anatol Sommer <anatol@anatol.at>",
|
||||||
"license": "MPL",
|
"license": "MPL-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/anatolsommer/letiny.git"
|
"url": "https://github.com/anatolsommer/letiny.git"
|
||||||
|
|
Loading…
Reference in New Issue