|
|
@ -1,13 +1,13 @@ |
|
|
|
'use strict'; |
|
|
|
|
|
|
|
var PromiseA = require('bluebird'); |
|
|
|
var RSA = PromiseA.promisifyAll(require('rsa-compat').RSA); |
|
|
|
var mkdirpAsync = PromiseA.promisify(require('mkdirp')); |
|
|
|
var path = require('path'); |
|
|
|
var fs = PromiseA.promisifyAll(require('fs')); |
|
|
|
var sfs = require('safe-replace'); |
|
|
|
var LE = require('../'); |
|
|
|
var LeCore = PromiseA.promisifyAll(require('letiny-core')); |
|
|
|
var leCrypto = PromiseA.promisifyAll(LeCore.leCrypto); |
|
|
|
var Accounts = require('./accounts'); |
|
|
|
|
|
|
|
var merge = require('./common').merge; |
|
|
@ -166,7 +166,7 @@ function writeCertificateAsync(args, defaults, handlers) { |
|
|
|
var obj = args.pyobj; |
|
|
|
var result = args.pems; |
|
|
|
|
|
|
|
result.fullchain = result.cert + '\n' + result.ca; |
|
|
|
result.fullchain = result.cert + '\n' + (result.chain || result.ca); |
|
|
|
obj.checkpoints = parseInt(obj.checkpoints, 10) || 0; |
|
|
|
|
|
|
|
var liveDir = args.liveDir || path.join(args.configDir, 'live', args.domains[0]); |
|
|
@ -193,18 +193,28 @@ function writeCertificateAsync(args, defaults, handlers) { |
|
|
|
return mkdirpAsync(archiveDir).then(function () { |
|
|
|
return PromiseA.all([ |
|
|
|
sfs.writeFileAsync(certArchive, result.cert, 'ascii') |
|
|
|
, sfs.writeFileAsync(chainArchive, result.ca || result.chain, 'ascii') |
|
|
|
, sfs.writeFileAsync(chainArchive, (result.chain || result.ca), 'ascii') |
|
|
|
, sfs.writeFileAsync(fullchainArchive, result.fullchain, 'ascii') |
|
|
|
, sfs.writeFileAsync(privkeyArchive, result.key || result.privkey || args.domainPrivateKeyPem, 'ascii') |
|
|
|
, sfs.writeFileAsync( |
|
|
|
privkeyArchive |
|
|
|
// TODO nix args.key, args.domainPrivateKeyPem ??
|
|
|
|
, (result.privkey || result.key) || RSA.exportPrivatePem(args.domainKeypair) |
|
|
|
, 'ascii' |
|
|
|
) |
|
|
|
]); |
|
|
|
}).then(function () { |
|
|
|
return mkdirpAsync(liveDir); |
|
|
|
}).then(function () { |
|
|
|
return PromiseA.all([ |
|
|
|
sfs.writeFileAsync(certPath, result.cert, 'ascii') |
|
|
|
, sfs.writeFileAsync(chainPath, result.ca || result.chain, 'ascii') |
|
|
|
, sfs.writeFileAsync(chainPath, (result.chain || result.ca), 'ascii') |
|
|
|
, sfs.writeFileAsync(fullchainPath, result.fullchain, 'ascii') |
|
|
|
, sfs.writeFileAsync(privkeyPath, result.key || result.privkey || args.domainPrivateKeyPem, 'ascii') |
|
|
|
, sfs.writeFileAsync( |
|
|
|
privkeyPath |
|
|
|
// TODO nix args.key, args.domainPrivateKeyPem ??
|
|
|
|
, (result.privkey || result.key) || RSA.exportPrivatePem(args.domainKeypair) |
|
|
|
, 'ascii' |
|
|
|
) |
|
|
|
]); |
|
|
|
}).then(function () { |
|
|
|
obj.checkpoints += 1; |
|
|
@ -219,10 +229,14 @@ function writeCertificateAsync(args, defaults, handlers) { |
|
|
|
, fullchainPath: fullchainPath |
|
|
|
, privkeyPath: privkeyPath |
|
|
|
|
|
|
|
// TODO nix keypair
|
|
|
|
, keypair: args.domainKeypair |
|
|
|
|
|
|
|
// TODO nix args.key, args.domainPrivateKeyPem ??
|
|
|
|
// some ambiguity here...
|
|
|
|
, privkey: result.key || result.privkey || args.domainPrivateKeyPem |
|
|
|
, fullchain: result.fullchain || result.cert |
|
|
|
, chain: result.ca || result.chain |
|
|
|
, privkey: (result.privkey || result.key) || RSA.exportPrivatePem(args.domainKeypair) |
|
|
|
, fullchain: result.fullchain || (result.cert + '\n' + result.chain) |
|
|
|
, chain: (result.chain || result.ca) |
|
|
|
// especially this one... might be cert only, might be fullchain
|
|
|
|
, cert: result.cert |
|
|
|
|
|
|
@ -235,21 +249,39 @@ function writeCertificateAsync(args, defaults, handlers) { |
|
|
|
function getCertificateAsync(args, defaults, handlers) { |
|
|
|
var account = args.account; |
|
|
|
var promise; |
|
|
|
var keypairOpts = { public: true, pem: true }; |
|
|
|
|
|
|
|
if (!args.domainKeyPath) { |
|
|
|
// TODO use default path ???
|
|
|
|
if (args.debug) { |
|
|
|
console.log('[domainKeyPath]: none'); |
|
|
|
} |
|
|
|
promise = RSA.generateKeypairAsync(args.rsaKeySize, 65537, keypairOpts); |
|
|
|
} |
|
|
|
|
|
|
|
if (args.domainKeyPath) { |
|
|
|
// TODO use existing pre-generated key if avaibale
|
|
|
|
console.warn("[LE /lib/core.js] retrieve from domainKeyPath NOT IMPLEMENTED (please file an issue to remind me about this)"); |
|
|
|
promise = leCrypto.generateRsaKeypairAsync(args.rsaKeySize, 65537); |
|
|
|
} else { |
|
|
|
promise = leCrypto.generateRsaKeypairAsync(args.rsaKeySize, 65537); |
|
|
|
if (args.debug) { |
|
|
|
console.log('[domainKeyPath]:', args.domainKeyPath); |
|
|
|
} |
|
|
|
promise = fs.readFileAsync(args.domainKeyPath, 'ascii').then(function (pem) { |
|
|
|
return RSA.import({ privateKeyPem: pem }); |
|
|
|
}, function (/*err*/) { |
|
|
|
return RSA.generateKeypairAsync(args.rsaKeySize, 65537, keypairOpts).then(function (keypair) { |
|
|
|
return mkdirpAsync(path.dirname(args.domainKeyPath)).then(function () { |
|
|
|
return fs.writeFileAsync(args.domainKeyPath, keypair.privateKeyPem, 'ascii').then(function () { |
|
|
|
return keypair; |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
return promise.then(function (domainKey) { |
|
|
|
return promise.then(function (domainKeypair) { |
|
|
|
if (args.debug) { |
|
|
|
console.log("[letsencrypt/lib/core.js] get certificate"); |
|
|
|
} |
|
|
|
|
|
|
|
args.domainPrivateKeyPem = args.domainPrivateKeyPem || domainKey.privateKeyPem; |
|
|
|
args.domainKeypair = domainKeypair; |
|
|
|
//args.registration = domainKey;
|
|
|
|
|
|
|
|
return LeCore.getCertificateAsync({ |
|
|
@ -258,8 +290,8 @@ function getCertificateAsync(args, defaults, handlers) { |
|
|
|
, newAuthzUrl: args._acmeUrls.newAuthz |
|
|
|
, newCertUrl: args._acmeUrls.newCert |
|
|
|
|
|
|
|
, accountPrivateKeyPem: account.privateKeyPem |
|
|
|
, domainPrivateKeyPem: domainKey.privateKeyPem |
|
|
|
, accountKeypair: RSA.import(account.keypair) |
|
|
|
, domainKeypair: domainKeypair |
|
|
|
, domains: args.domains |
|
|
|
|
|
|
|
//
|
|
|
@ -302,6 +334,7 @@ function getCertificateAsync(args, defaults, handlers) { |
|
|
|
} |
|
|
|
}); |
|
|
|
}).then(function (results) { |
|
|
|
// { cert, chain, fullchain, privkey }
|
|
|
|
args.pems = results; |
|
|
|
return writeCertificateAsync(args, defaults, handlers); |
|
|
|
}); |
|
|
@ -335,6 +368,7 @@ function getOrCreateDomainCertificate(args, defaults, handlers) { |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// returns 'account' from lib/accounts { meta, regr, keypair, accountId (id) }
|
|
|
|
function getOrCreateAcmeAccount(args, defaults, handlers) { |
|
|
|
var pyconf = PromiseA.promisifyAll(require('pyconf')); |
|
|
|
|
|
|
|