summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2020-03-31 21:08:02 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2020-03-31 21:08:02 -0600
commit9fb0b1e838e216f90d20c9a32e948ad60dcca07d (patch)
tree45f79c1e0f314ac2801a0eb3f5254f2dec1a90b7 /modules
parent244b839f9813ae68c5527e6aadadaff0642c1a00 (diff)
caddytls: Add support for externalAccountBinding ACME extension
Diffstat (limited to 'modules')
-rw-r--r--modules/caddytls/acmeissuer.go39
1 files changed, 36 insertions, 3 deletions
diff --git a/modules/caddytls/acmeissuer.go b/modules/caddytls/acmeissuer.go
index 0e43046..133d007 100644
--- a/modules/caddytls/acmeissuer.go
+++ b/modules/caddytls/acmeissuer.go
@@ -17,6 +17,7 @@ package caddytls
import (
"context"
"crypto/x509"
+ "encoding/base64"
"fmt"
"io/ioutil"
"net/url"
@@ -54,6 +55,10 @@ type ACMEIssuer struct {
// other than ACME transactions.
Email string `json:"email,omitempty"`
+ // If using an ACME CA that requires an external account
+ // binding, specify the CA-provided credentials here.
+ ExternalAccount *ExternalAccountBinding `json:"external_account,omitempty"`
+
// Time to wait before timing out an ACME operation.
ACMETimeout caddy.Duration `json:"acme_timeout,omitempty"`
@@ -107,12 +112,16 @@ func (m *ACMEIssuer) Provision(ctx caddy.Context) error {
}
}
- m.template = m.makeIssuerTemplate()
+ var err error
+ m.template, err = m.makeIssuerTemplate()
+ if err != nil {
+ return err
+ }
return nil
}
-func (m *ACMEIssuer) makeIssuerTemplate() certmagic.ACMEManager {
+func (m *ACMEIssuer) makeIssuerTemplate() (certmagic.ACMEManager, error) {
template := certmagic.ACMEManager{
CA: m.CA,
Email: m.Email,
@@ -120,6 +129,20 @@ func (m *ACMEIssuer) makeIssuerTemplate() certmagic.ACMEManager {
TrustedRoots: m.rootPool,
}
+ if m.ExternalAccount != nil {
+ hmac, err := base64.StdEncoding.DecodeString(m.ExternalAccount.EncodedHMAC)
+ if err != nil {
+ return template, err
+ }
+ if m.ExternalAccount.KeyID == "" || len(hmac) == 0 {
+ return template, fmt.Errorf("when an external account binding is specified, both key ID and HMAC are required")
+ }
+ template.ExternalAccount = &certmagic.ExternalAccountBinding{
+ KeyID: m.ExternalAccount.KeyID,
+ HMAC: hmac,
+ }
+ }
+
if m.Challenges != nil {
if m.Challenges.HTTP != nil {
template.DisableHTTPChallenge = m.Challenges.HTTP.Disabled
@@ -132,7 +155,7 @@ func (m *ACMEIssuer) makeIssuerTemplate() certmagic.ACMEManager {
template.DNSProvider = m.Challenges.DNS
}
- return template
+ return template, nil
}
// SetConfig sets the associated certmagic config for this issuer.
@@ -201,6 +224,16 @@ type DNSProviderMaker interface {
NewDNSProvider() (challenge.Provider, error)
}
+// ExternalAccountBinding contains information for
+// binding an external account to an ACME account.
+type ExternalAccountBinding struct {
+ // The key identifier.
+ KeyID string `json:"key_id,omitempty"`
+
+ // The base64-encoded HMAC.
+ EncodedHMAC string `json:"hmac,omitempty"`
+}
+
// Interface guards
var (
_ certmagic.PreChecker = (*ACMEIssuer)(nil)