The base set of tests for all certificate and keypair storage strategies. Any Greenlock greenlock-store- plugin should be able to pass these tests.
Go to file
AJ ONeal 59cf216047 v3.0.0: storage strategy test harness for Greenlock v2.7+ (and v3) 2019-04-08 01:27:04 -06:00
.gitignore v3.0.0: storage strategy test harness for Greenlock v2.7+ (and v3) 2019-04-08 01:27:04 -06:00
LICENSE v3.0.0: storage strategy test harness for Greenlock v2.7+ (and v3) 2019-04-08 01:27:04 -06:00
README.md v3.0.0: storage strategy test harness for Greenlock v2.7+ (and v3) 2019-04-08 01:27:04 -06:00
example.js v3.0.0: storage strategy test harness for Greenlock v2.7+ (and v3) 2019-04-08 01:27:04 -06:00
index.js v3.0.0: storage strategy test harness for Greenlock v2.7+ (and v3) 2019-04-08 01:27:04 -06:00
package.json v3.0.0: storage strategy test harness for Greenlock v2.7+ (and v3) 2019-04-08 01:27:04 -06:00

README.md

greenlock-store-test

| A Root Project |

The test harness you should use when writing a certificate and keypair storage strategy for Greenlock v2.7+ (and v3).

All implementations MUST pass these tests, which is a very easy thing to do (just 3 getter/setter pairs to implement).

The tests account for single-domain certificates (example.com) as well as multiple domain certs (SAN / AltName), wildcards (*.example.com), and valid private / localhost certificates. As someone creating a challenge strategy that's not something you have to take special consideration for - just pass the tests.

Install

npm install --save-dev greenlock-store-test@3.x

Usage

var tester = require('greenlock-store-test');

//var store = require('greenlock-store-memory').create({});
//var store = require('greenlock-store-fs').create({});
var store = require('./YOUR-STORAGE-STRATEGY').create({});

// All of these tests can pass locally, standalone without any ACME integration.
tester.test(store).then(function () {
  console.info("PASS");
});

Overview

The most generic implementation, with no special considerations or custom logic, ends up looking like this:

tester.test({


  // ACME user account
  accounts: {
    setKeypair: function (opts) {
      // { account: { id: '...' } // you may or may not receive 'id'
      // , email: 'jon.doe@example.com'
      // , keypair: { privateKeyPem: '...', privateKeyJwk: {...} }
      // }

      var id = opts.account.id || opts.email;
      return DB.Keypairs.save(id, JSON.stringify(opts.keypair));
    }
  , checkKeypair: function (opts) {
      // you receive the same options as setKeypair() above
      var id = opts.account.id || opts.email;
      return DB.Keypairs.get(id).then(function (k) { return JSON.parse(k); });
    }
  }


  // Site Keys & Certificates
, certificates: {

    // Site Keys (privkey.pem a.k.a. example.com.key)
    setKeypair: function (opts) {
      // { certificate: { kid: '...', id: '...' } // you may or may not receive 'kid' or 'id'
      // , subject: 'foo.example.com'
      // , keypair: { privateKeyPem: '...', privateKeyJwk: {...} }
      // }

      var id = opts.certificate.kid || opts.certificate.id || opts.subject;
      return DB.Keypairs.save(id, JSON.stringify(opts.keypair));
    }
  , checkKeypair: function (opts) {
      // you receive the same options as setKeypair() above
      var id = opts.certificate.kid || opts.certificate.id || opts.subject;
      return DB.Keypairs.get(id).then(function (x) { return JSON.parse(x); });
    }

    // Certificates (fullchain.pem a.k.a. cert.pem a.k.a. example.com.crt)
  , set: function (opts) {
      // { certificate: { id: '...' } // you may or may not receive 'id'
      // , subject: 'foo.example.com'
      // , pems: { cert: '...', chain: '...', ... }
      // }

      var id = opts.certificate.id || opts.subject;
      return DB.Certificates.save(id, JSON.stringify(opts.keypair));
    }
  , set: function (opts) {
      // { certificate: { id: '...' } // you may or may not receive 'id'
      // , subject: 'foo.example.com'
      // , pems: { cert: '...', chain: '...', ... }
      // }

      var id = opts.certificate.id || opts.subject;
      return DB.Certificates.save(id, JSON.stringify(opts.keypair));
    }
  }
}).then(function () {
  console.info("PASS");
});

Note: The DB.x.y() is where you do your magic up to connect to a database or API or whatever and keep stuff safe.

Examples

See the reference implementations (they work):