normalize all *Pem *Key* etc to keypair and *Keypair
This commit is contained in:
parent
2c7b7e1bcf
commit
ee48f4a477
41
README.md
41
README.md
|
@ -77,7 +77,9 @@ LeCore.registerNewAccount(options, cb) // returns "regr" registration dat
|
|||
|
||||
{ newRegUrl: '<url>' // no defaults, specify acmeUrls.newAuthz
|
||||
, email: '<email>' // valid email (server checks MX records)
|
||||
, accountPrivateKeyPem: '<ASCII PEM>' // callback to allow user interaction for tosUrl
|
||||
, accountKeypair: { // privateKeyPem or privateKeyJwt
|
||||
privateKeyPem: '<ASCII PEM>'
|
||||
}
|
||||
, agreeToTerms: fn (tosUrl, cb) {} // must specify agree=tosUrl to continue (or falsey to end)
|
||||
}
|
||||
|
||||
|
@ -87,8 +89,12 @@ LeCore.getCertificate(options, cb) // returns (err, pems={ key, cert,
|
|||
{ newAuthzUrl: '<url>' // specify acmeUrls.newAuthz
|
||||
, newCertUrl: '<url>' // specify acmeUrls.newCert
|
||||
|
||||
, domainPrivateKeyPem: '<ASCII PEM>'
|
||||
, accountPrivateKeyPem: '<ASCII PEM>'
|
||||
, domainKeypair: {
|
||||
privateKeyPem: '<ASCII PEM>'
|
||||
}
|
||||
, accountKeypair: {
|
||||
privateKeyPem: '<ASCII PEM>'
|
||||
}
|
||||
, domains: ['example.com']
|
||||
|
||||
, setChallenge: fn (hostname, key, val, cb)
|
||||
|
@ -118,19 +124,6 @@ LeCore.Acme // Signs requests with JWK
|
|||
acme.post(url, body, cb) // POST with signature
|
||||
acme.parseLinks(link) // (internal) parses 'link' header
|
||||
acme.getNonce(url, cb) // (internal) HEAD request to get 'replay-nonce' strings
|
||||
|
||||
// Note: some of these are not async,
|
||||
// but they will be soon. Don't rely
|
||||
// on their API yet.
|
||||
|
||||
// Crypto Helpers
|
||||
LeCore.leCrypto
|
||||
generateRsaKeypair(bitLen, exponent, cb); // returns { privateKeyPem, privateKeyJwk, publicKeyPem, publicKeyMd5 }
|
||||
thumbprint(lePubKey) // generates public key thumbprint
|
||||
generateSignature(lePrivKey, bodyBuf, nonce) // generates a signature
|
||||
privateJwkToPems(jwk) // { n: '...', e: '...', iq: '...', ... } to PEMs
|
||||
privatePemToJwk // PEM to JWK (see line above)
|
||||
importPemPrivateKey(privateKeyPem) // (internal) returns abstract private key
|
||||
```
|
||||
|
||||
For testing and development, you can also inject the dependencies you want to use:
|
||||
|
@ -161,16 +154,18 @@ This is how you **register an ACME account** and **get an HTTPS certificate**
|
|||
'use strict';
|
||||
|
||||
var LeCore = require('letiny-core');
|
||||
var RSA = require('rsa-compat').RSA;
|
||||
|
||||
var email = 'user@example.com'; // CHANGE TO YOUR EMAIL
|
||||
var domains = 'example.com'; // CHANGE TO YOUR DOMAIN
|
||||
var acmeDiscoveryUrl = LeCore.stagingServerUrl; // CHANGE to production, when ready
|
||||
|
||||
var accountPrivateKeyPem = null;
|
||||
var domainPrivateKeyPem = null;
|
||||
var accountKeypair = null; // { privateKeyPem: null, privateKeyJwk: null };
|
||||
var domainKeypair = null; // same as above
|
||||
var acmeUrls = null;
|
||||
|
||||
LeCore.leCrypto.generateRsaKeypair(2048, 65537, function (err, pems) {
|
||||
RSA.generateKeypair(2048, 65537, function (err, keypair) {
|
||||
accountKeypair = keypair;
|
||||
// ...
|
||||
LeCore.getAcmeUrls(acmeDiscoveryUrl, function (err, urls) {
|
||||
// ...
|
||||
|
@ -182,7 +177,7 @@ function runDemo() {
|
|||
LeCore.registerNewAccount(
|
||||
{ newRegUrl: acmeUrls.newReg
|
||||
, email: email
|
||||
, accountPrivateKeyPem: accountPrivateKeyPem
|
||||
, accountKeypair: accountKeypair
|
||||
, agreeToTerms: function (tosUrl, done) {
|
||||
|
||||
// agree to the exact version of these terms
|
||||
|
@ -195,8 +190,8 @@ function runDemo() {
|
|||
{ newAuthzUrl: acmeUrls.newAuthz
|
||||
, newCertUrl: acmeUrls.newCert
|
||||
|
||||
, domainPrivateKeyPem: domainPrivateKeyPem
|
||||
, accountPrivateKeyPem: accountPrivateKeyPem
|
||||
, domainKeypair: domainKeypair
|
||||
, accountKeypair: accountKeypair
|
||||
, domains: domains
|
||||
|
||||
, setChallenge: challengeStore.set
|
||||
|
@ -323,4 +318,4 @@ MPL 2.0
|
|||
All of the code is available under the MPL-2.0.
|
||||
|
||||
Some of the files are original work not modified from `letiny`
|
||||
and are made available under MIT as well (check file headers).
|
||||
and are made available under MIT and Apache-2.0 as well (check file headers).
|
||||
|
|
|
@ -19,9 +19,6 @@ function _toStandardBase64(str) {
|
|||
|
||||
module.exports.create = function (deps) {
|
||||
var request=deps.request;
|
||||
//var importPemPrivateKey = deps.leCrypto.importPemPrivateKey;
|
||||
//var thumbprinter = deps.leCrypto.thumbprint;
|
||||
//var generateCsr = deps.leCrypto.generateCsr || deps.leCrypto.generateCSR;
|
||||
var Acme = deps.Acme;
|
||||
var RSA = deps.RSA;
|
||||
|
||||
|
@ -164,7 +161,7 @@ module.exports.create = function (deps) {
|
|||
}
|
||||
challenge=httpChallenges[0];
|
||||
|
||||
thumbprint=RSA.thumbprint(state.accountKeyPair);
|
||||
thumbprint=RSA.thumbprint(state.accountKeypair);
|
||||
keyAuthorization=challenge.token+'.'+thumbprint;
|
||||
state.responseUrl=challenge.uri;
|
||||
|
||||
|
@ -226,7 +223,7 @@ module.exports.create = function (deps) {
|
|||
}
|
||||
|
||||
function getCertificate() {
|
||||
var csr=RSA.generateCsrWeb64(state.certPrivateKey, state.validatedDomains);
|
||||
var csr=RSA.generateCsrWeb64(RSA.exportPrivateKeyPem(state.certKeypair), state.validatedDomains);
|
||||
log('Requesting certificate...');
|
||||
state.acme.post(state.newCertUrl, {
|
||||
resource:'new-cert',
|
||||
|
@ -335,7 +332,7 @@ module.exports.create = function (deps) {
|
|||
|
||||
cb(null, {
|
||||
cert: cert
|
||||
, key: state.certPrivateKeyPem
|
||||
, key: RSA.exportPrivateKeyPem(state.certKeypair)
|
||||
, ca: state.caCert
|
||||
});
|
||||
}
|
||||
|
@ -360,11 +357,11 @@ module.exports.create = function (deps) {
|
|||
if (!options.newCertUrl) {
|
||||
return handleErr(new Error("options.newCertUrl must be the new certificate url"));
|
||||
}
|
||||
if (!options.accountPrivateKeyPem) {
|
||||
return handleErr(new Error("options.accountPrivateKeyPem must be an ascii private key pem"));
|
||||
if (!options.accountKeypair) {
|
||||
return handleErr(new Error("options.accountKeypair must be an object with `privateKeyPem` and/or `privateKeyJwk`"));
|
||||
}
|
||||
if (!options.domainPrivateKeyPem) {
|
||||
return handleErr(new Error("options.domainPrivateKeyPem must be an ascii private key pem"));
|
||||
if (!options.domainKeypair) {
|
||||
return handleErr(new Error("options.domainKeypair must be an object with `privateKeyPem` and/or `privateKeyJwk`"));
|
||||
}
|
||||
if (!options.setChallenge) {
|
||||
return handleErr(new Error("options.setChallenge must be function(hostname, challengeKey, tokenValue, done) {}"));
|
||||
|
@ -378,11 +375,9 @@ module.exports.create = function (deps) {
|
|||
|
||||
state.domains = options.domains.slice(0); // copy array
|
||||
try {
|
||||
state.accountKeyPem=options.accountPrivateKeyPem;
|
||||
state.accountKeyPair=RSA.import({ privateKeyPem: state.accountKeyPem });
|
||||
state.acme=new Acme(state.accountKeyPair);
|
||||
state.certPrivateKeyPem=options.domainPrivateKeyPem;
|
||||
state.certPrivateKey=RSA.import({ privateKeyPem: state.certPrivateKeyPem });
|
||||
state.acme = new Acme(state.accountKeypair);
|
||||
state.accountKeypair = options.accountKeypair;
|
||||
state.certKeypair = options.domainKeypair;
|
||||
} catch(err) {
|
||||
return handleErr(err, 'Failed to parse privateKey');
|
||||
}
|
||||
|
|
|
@ -103,8 +103,8 @@ module.exports.create = function (deps) {
|
|||
|
||||
var state = {};
|
||||
|
||||
if (!options.accountPrivateKeyPem) {
|
||||
return handleErr(new Error("options.accountPrivateKeyPem must be an ascii private key pem"));
|
||||
if (!options.accountKeypair) {
|
||||
return handleErr(new Error("options.accountKeypair must be an object with `privateKeyPem` and/or `privateKeyJwk`"));
|
||||
}
|
||||
if (!options.agreeToTerms) {
|
||||
cb(new Error("options.agreeToTerms must be function (tosUrl, fn => (err, true))"));
|
||||
|
@ -119,9 +119,8 @@ module.exports.create = function (deps) {
|
|||
return;
|
||||
}
|
||||
|
||||
state.accountKeyPem=options.accountPrivateKeyPem;
|
||||
state.accountKeyPair=RSA.import({ privateKeyPem: state.accountKeyPem });
|
||||
state.acme=new Acme(state.accountKeyPair);
|
||||
state.accountKeypair = options.accountKeypair;
|
||||
state.acme=new Acme(state.accountKeypair);
|
||||
|
||||
register();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue