Skip to content

Commit 9e31193

Browse files
committed
added SAN support
1 parent b11e779 commit 9e31193

22 files changed

Lines changed: 76 additions & 63 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ your environment:
2525
| *Variable* | *Description* |
2626
| :--------------------- |:--------------|
2727
| `acme-directory-url` | Change to production url - https://acme-v01.api.letsencrypt.org if ready for real certificate. |
28-
| `acme-domains` | Array of domains to receive certificates for. |
2928
| `acme-account-email` | Email of user requesting certificate. |
3029
| `s3-account-bucket` | An S3 bucket to place account keys/config data into. You will need to create this bucket and assign the [IAM role](AWS.md) to read/write. |
3130
| `s3-cert-bucket` | An S3 bucket to place domain certificate data into. You will need to create this bucket and assign the [IAM role](AWS.md) to read/write. |
3231
| `s3-folder` | A folder within the above buckets to place the files under, in case there are other contents of these buckets. |
32+
| `certificate-info` | Object containing certificate information mapping certificate names to domains. |
3333

3434
## Execution
3535
Follow these steps to get started:

ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ Please feel free to file issues on this repository if you have questions, concer
1313
* ~~" " ELB's.~~
1414
~~* Different run modes: local file writing via nodejs vs Lambda + S3.~~
1515
* Tests
16-
* Support SAN in same certificate (let's encrypt allows up to 100 names per certificate)
16+
* ~~Support SAN in same certificate (let's encrypt allows up to 100 names per certificate)~~

app.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,30 @@ const generateCertificate = require('./src/acme/generateCertificate')
22
const isExpired = require('./src/util/isExpired')
33
const config = require('./config/default.json')
44

5-
const single = (domain) =>
6-
isExpired(domain)
5+
const single = (key, domains) =>
6+
isExpired(key)
77
.then((expired) =>
88
(expired
9-
? generateCertificate(domain)
9+
? generateCertificate({key, domains})
1010
: {
1111
err: false,
12-
msg: `Certificate for ${domain} is still valid, going back to bed.`
12+
msg: `Certificate for ${key} is still valid, going back to bed.`
1313
}
1414
)
1515
)
1616
.catch((err) => ({
1717
err: true,
18-
msg: `Updating cert for ${domain}, received err ${err}, ${err.stack}`
18+
msg: `Updating cert for ${key}, received err ${err}, ${err.stack}`
1919
}))
2020

21-
const certificates = (domains) => domains.map(single)
21+
const certificates = (certDefinitions) =>
22+
Object.keys(certDefinitions)
23+
.map((certKey) =>
24+
single(certKey, certDefinitions[certKey])
25+
)
2226

2327
const updateCertificates = (options, context) =>
24-
Promise.all(certificates(config['acme-domains']))
28+
Promise.all(certificates(config['certificate-info']))
2529
.then((msgs) => context.succeed(msgs))
2630

27-
module.exports = { handler : updateCertificates }
31+
module.exports = { handler: updateCertificates }

bin/local.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
var cert = require("../app.js")
1+
const cert = require('../app.js')
22

3-
var testContext = {
4-
succeed: function succeed(data) {
3+
const testContext = {
4+
succeed: (data) => {
55
console.log(data)
66
process.exit(0)
77
}
8-
};
8+
}
99

1010
cert.handler({}, testContext)

bin/write_pems.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,33 @@ const config = require('../config/default.json')
33
const fs = require('fs')
44

55
const testContext = {
6-
succeed: function succeed(data) {
6+
succeed: (data) => {
77
console.log(data)
88
process.exit(0)
99
}
1010
}
1111

12-
const getPEMsForDomain = (domain) =>
12+
const getPEMsForCertInfo = (key) =>
1313
readFile(
1414
config['s3-cert-bucket'],
1515
config['s3-folder'],
16-
`${domain}.json`
16+
`${key}.json`
1717
)
1818
.then((data) => JSON.parse(data.Body.toString()))
1919
.then((certJSON) => {
20-
console.log(`About to write PEM files for ${domain}..`)
20+
console.log(`About to write PEM files for ${key}..`)
2121
try {
22-
fs.writeFileSync(`./${domain}.pem`, certJSON.cert.toString())
23-
fs.writeFileSync(`./${domain}-chain.pem`, certJSON.issuerCert.toString())
24-
fs.writeFileSync(`./${domain}-key.pem`, certJSON.key.privateKeyPem.toString())
22+
fs.writeFileSync(`./${key}.pem`, certJSON.cert.toString())
23+
fs.writeFileSync(`./${key}-chain.pem`, certJSON.issuerCert.toString())
24+
fs.writeFileSync(`./${key}-key.pem`, certJSON.key.privateKeyPem.toString())
2525
} catch (e) {
26-
console.log(JSON.stringify(e.stack))
26+
console.error('Error writing pem files', e)
2727
}
2828
})
2929
.catch()
3030

3131
const getAllPEMs = (sync) =>
32-
Promise.all(config['acme-domains'].map(getPEMsForDomain))
32+
Promise.all(Object.keys(config['certificate-info']).map(getPEMsForCertInfo))
3333
.then(() => sync.succeed('Wrote PEM files..'))
3434

35-
3635
getAllPEMs(testContext)

config/default.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
"s3-account-bucket": "<your-s3-account-config-bucket>",
33
"s3-cert-bucket": "<your-s3-ssl-cert-bucket>",
44
"s3-folder": "<folder-under-bucket>",
5+
"certificate-info": {
6+
"cert-name1": ["<first-domain-needing-certificate>", "<second-domain-needing-certificate>"],
7+
"cert-name2": ["<third-domain-needing-certificate>", "<fourth-domain-needing-certificate>"]
8+
},
59
"acme-dns-retry": 30,
610
"acme-dns-retry-delay-ms": 2000,
7-
"acme-domains": ["<domain-needing-certificate>", "<optional-second-domain>"],
811
"acme-account-file": "<where-to-save-generated-account-registration>",
912
"acme-account-email": "<email-of-responsible-person>",
1013
"acme-account-key-bits": 2048,

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@
2323
"author": "Larry Anderson",
2424
"license": "ISC",
2525
"dependencies": {
26-
"aws-sdk": "~2.4.14",
26+
"aws-sdk": "^2.20.0",
2727
"es6-promisify": "^4.1.0",
2828
"node-forge": "^0.6.45",
2929
"rsa-compat": "^1.2.7",
30-
"superagent": "~1.8.4",
31-
"superagent-promise": "^1.1.0"
30+
"superagent": "^3.5.0"
3231
},
3332
"devDependencies": {
3433
"archiver": "^1.2.0",

src/acme/authorize/getChallenges.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,22 @@ const validateChallenges = (domain, accountKeyPair, challengeResponse) => {
1212
])
1313
}
1414

15-
const getChallenges = (domain, keypair, authzUrl) =>
16-
sendSignedRequest({
17-
resource: 'new-authz',
18-
identifier: {
19-
type: 'dns',
20-
value: domain
21-
}
22-
}, keypair, authzUrl)
23-
.then((data) => validateChallenges(domain, keypair, data.body))
15+
const getChallenges = (domains, keypair, authzUrl) =>
16+
Promise.all(
17+
domains.map((domain) =>
18+
sendSignedRequest({
19+
resource: 'new-authz',
20+
identifier: {
21+
type: 'dns',
22+
value: domain
23+
}
24+
}, keypair, authzUrl)
25+
.then((data) => validateChallenges(domain, keypair, data.body))
26+
)
27+
)
28+
.catch((err) => {
29+
console.error('Experienced error getting challenges', err)
30+
throw err
31+
})
2432

2533
module.exports = getChallenges

src/acme/authorize/sendDNSChallengeValidation.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const sendDNSChallengeValidation = (dnsChallenge, acctKeyPair) =>
88
}, acctKeyPair, dnsChallenge.uri)
99
.then((data) => data.body)
1010
.catch((e) => {
11-
console.log(`Couldn't send DNS challenge verification ${JSON.stringify(e)}.`)
11+
console.error(`Couldn't send DNS challenge verification.`, e)
1212
throw e
1313
})
1414

src/acme/authorize/updateDNSChallenge.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const updateDNSChallenge = (domain, dnsChallenge, acctKeyPair) =>
1717
.then((id) => updateTXTRecord(id, domain, urlB64(getTokenDigest(dnsChallenge, acctKeyPair))))
1818
.then((updated) => validateDNSChallenge(domain, dnsChallenge, acctKeyPair))
1919
.catch((e) => {
20-
console.log(`Couldn't write token digest to DNS record.`)
20+
console.error(`Couldn't write token digest to DNS record.`, e)
2121
throw e
2222
})
2323

0 commit comments

Comments
 (0)