Compare commits

...

20 Commits

Author SHA1 Message Date
AJ ONeal 7cdb42db7a Merge branch 'tests' into template 2019-03-30 10:19:19 -06:00
CaptEmulation 37a7fd55b7 update template 2019-02-17 11:44:58 -06:00
AJ ONeal e96ab294b6 Merge branch 'tests' into template 2016-09-02 16:38:11 -06:00
AJ ONeal 7bdf8804a3 Merge branch 'readme' into template 2016-09-02 15:46:58 -06:00
AJ ONeal 718e081495 Merge branch 'tests' into template 2016-09-02 15:46:42 -06:00
AJ ONeal 258ad19f77 better comments 2016-09-02 15:45:57 -06:00
AJ ONeal 861872499e update readme 2016-09-02 14:25:07 -06:00
AJ ONeal 03a4db1034 merge readme 2016-08-13 15:49:13 -06:00
AJ ONeal b0eff828bb merge with tests branch 2016-08-13 15:44:54 -06:00
AJ ONeal b3102ded8d update README.md 2016-08-13 15:29:14 -06:00
AJ ONeal 8f13081270 add README.md 2016-08-13 15:28:52 -06:00
AJ ONeal 00157ab870 update template, add tests 2016-08-13 15:11:09 -06:00
AJ ONeal a0bda23683 merge README.md 2016-08-13 15:07:41 -06:00
AJ ONeal e120d2dcc2 add API brief 2016-08-12 15:21:35 -06:00
AJ ONeal f8f7a75c99 update README 2016-08-12 15:07:04 -06:00
AJ ONeal dfa5f79e0d merge SPEC 2016-08-12 15:06:50 -06:00
AJ ONeal 5af14f1147 Initial commit 2016-08-12 15:01:18 -06:00
AJ ONeal bbf5168fb7 Create index.js 2016-08-11 23:42:28 -06:00
AJ ONeal 5a5848614b Update README.md 2016-08-11 23:22:41 -06:00
AJ ONeal ee294fce8c Initial commit 2016-08-11 23:20:20 -06:00
4 changed files with 283 additions and 0 deletions

37
.gitignore vendored Normal file
View File

@ -0,0 +1,37 @@
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 Daplie, Inc
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

99
README.md Normal file
View File

@ -0,0 +1,99 @@
# le-store-SPEC
The reference implementation, specification, template, and tests for creating an le-store- strategy.
The reference implementation is completely in-memory.
See [Help Wanted: Database Plugins (for saving certs)](https://github.com/Daplie/node-letsencrypt/issues/39)
How to create a custom strategy
===============================
READ THIS README:
Believe it or not, most of your answers are either right here
or in the comments in the sample code in `index.js`.
Now, let's say there's some new database AwesomeDB that
we want to make a plugin for, here's how we'd start:
```bash
# First create you repo on github or wherever
# Then clone it
git clone git@github.com:AwesomeDB/le-store-awesome.git
pushd le-store-awesome
# IMPORTANT: we pull in the 'template' branch, which has the skeleton code
git pull https://github.com/Daplie/le-store-SPEC.git template
git push
```
Or, if you already have some code and just need to merge in the tests:
```bash
git pull https://github.com/Daplie/le-store-SPEC.git tests
```
Next, Just run the tests
```
node tests/basic.js
```
Note: you should not modify the tests that come from the tests branch,
but rather create separate files for your own tests.
API
===
```
* getOptions()
* accounts.
* checkKeypair(opts, cb)
* setKeypair(opts, keypair, cb)
* check(opts, cb)
* set(opts, reg, cb)
* certificates.
* checkKeypair(opts, cb)
* setKeypair(opts, keypair, cb)
* check(opts, cb)
* set(opts, certs, cb)
```
Keypairs
--------
For convenience, the keypair object will always contain **both** PEM and JWK
versions of the private and/or public keys when being passed to the `*Keypair` functions.
**set**
`setKeypair` will always be called with `email` and **all three** forms of the keypair:
`privateKeyPem`, `publicKeyPem`, and `privateKeyJwk`. It's easy to generate `publicKeyJwk`
from `privateKeyJwk` because it is just a copy of the public fields `e` and `n`.
```
// keypair looks like this
{ privateKeyPem: '...'
, publicKeyPem: '...'
, privateKeyJwk: { ... }
}
```
**check**
`checkKeypair` may be called with any of `email`, `accountId`, and `keypair` - which will
contain only `publicKeyPem` and `publicKeyJwk`.
```
// opts looks like this
{
email: '...@...'
, accountId: '...'
, keypair: {
publicKeyPem: '...'
, publicKeyJwk: { ... }
}
}
```

126
index.js Normal file
View File

@ -0,0 +1,126 @@
'use strict';
module.exports.create = function (options) {
var defaults = {};
var accounts = {
// Accounts
setKeypair: function (opts, keypair, cb) {
// opts.email // optional
// opts.accountId // optional - same as returned from acounts.set(opts, reg)
// SAVE to db (as PEM and/or JWK) and index each domain in domains to this keypair
// keypair = { privateKeyPem: '...', privateKeyJwk: { ... } }
cb(null, keypair);
}
// Accounts
, checkKeypair: function (opts, cb) {
// opts.email // optional
// opts.accountId // optional - same as returned from acounts.set(opts, reg)
// check db and return null or keypair object with one
// (or both) of privateKeyPem or privateKeyJwk
cb(null, { privateKeyPem: '...', privateKeyJwk: {} });
}
// Accounts
, check: function (opts, cb) {
// opts.email // optional
// opts.accountId // optional - same as returned from acounts.set(opts, reg)
// opts.domains // optional - same as set in certificates.set(opts, certs)
// return account from db if it exists, otherwise null
cb(null, { id: '...', keypair: { privateKeyJwk: {} }/*, domains: []*/ });
}
// Accounts
, set: function (opts, reg, cb) {
// opts.email
// reg.keypair
// reg.receipt // response from acme server
// You must implement a method to deterministically generate 'id'
// For example, you could do this:
// var id = crypto.createHash('sha256').update(reg.keypair.publicKeyPem).digest('hex');
cb(null, { id: '...', email: opts.email, keypair: reg.keypair, receipt: reg.receipt });
}
};
var certificates = {
// Certificates
setKeypair: function (opts, keypair, cb) {
// opts.domains - this is an array, but you nly need the first (or any) of them
// SAVE to db (as PEM and/or JWK) and index each domain in domains to this keypair
cb(null, keypair);
}
// Certificates
, checkKeypair: function (opts, cb) {
// opts.domains - this is an array, but you only need the first (or any) of them
// check db and return null or keypair object with one of privateKeyPem or privateKeyJwk
cb(null, { privateKeyPem: '...', privateKeyJwk: {} });
}
// Certificates
, check: function (opts, cb) {
// You will be provided one of these (which should be tried in this order)
// opts.domains
// opts.email // optional
// opts.accountId // optional
// return certificate PEMs from db if they exist, otherwise null
// optionally include expiresAt and issuedAt, if they are known exactly
// (otherwise they will be read from the cert itself later)
cb(null, { privkey: 'PEM', cert: 'PEM', chain: 'PEM', domains: [], accountId: '...' });
}
// Certificates
, set: function (opts, cb) {
// opts.domains // each of these must be indexed
// opts.email // optional, should be indexed
// opts.accountId // optional - same as set by you in accounts.set(opts, keypair) above
// opts.certs.privkey
// opts.certs.cert
// opts.certs.chain
// SAVE to the database, index the email address, the accountId, and alias the domains
cb(null, { privkey: 'PEM', cert: 'PEM', chain: 'PEM' });
}
};
return {
getOptions: function () {
// merge options with default settings and then return them
return options;
}
, accounts: accounts
, certificates: certificates
};
};