From 6a14e2c2a8881d5e90f1ee363ec4662a3f87402b Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Thu, 30 Jul 2020 15:18:14 -0600 Subject: caddytls: Replace lego with acmez (#3621) * Replace lego with acmez; upgrade CertMagic * Update integration test --- modules/caddytls/acmeissuer.go | 67 ++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 39 deletions(-) (limited to 'modules/caddytls/acmeissuer.go') diff --git a/modules/caddytls/acmeissuer.go b/modules/caddytls/acmeissuer.go index 195ddeb..8fe308d 100644 --- a/modules/caddytls/acmeissuer.go +++ b/modules/caddytls/acmeissuer.go @@ -24,7 +24,9 @@ import ( "github.com/caddyserver/caddy/v2" "github.com/caddyserver/certmagic" - "github.com/go-acme/lego/v3/challenge" + "github.com/mholt/acmez" + "github.com/mholt/acmez/acme" + "go.uber.org/zap" ) func init() { @@ -56,7 +58,7 @@ type ACMEIssuer struct { // If using an ACME CA that requires an external account // binding, specify the CA-provided credentials here. - ExternalAccount *ExternalAccountBinding `json:"external_account,omitempty"` + ExternalAccount *acme.EAB `json:"external_account,omitempty"` // Time to wait before timing out an ACME operation. ACMETimeout caddy.Duration `json:"acme_timeout,omitempty"` @@ -72,6 +74,7 @@ type ACMEIssuer struct { rootPool *x509.CertPool template certmagic.ACMEManager magic *certmagic.Config + logger *zap.Logger } // CaddyModule returns the Caddy module information. @@ -84,25 +87,29 @@ func (ACMEIssuer) CaddyModule() caddy.ModuleInfo { // Provision sets up m. func (m *ACMEIssuer) Provision(ctx caddy.Context) error { + m.logger = ctx.Logger(m) + // DNS providers if m.Challenges != nil && m.Challenges.DNS != nil && m.Challenges.DNS.ProviderRaw != nil { val, err := ctx.LoadModule(m.Challenges.DNS, "ProviderRaw") if err != nil { return fmt.Errorf("loading DNS provider module: %v", err) } - // TODO: For a temporary amount of time, we are allowing the use of - // DNS providers from go-acme/lego since there are so many implemented - // for it -- they are adapted as Caddy modules in this repository: - // https://github.com/caddy-dns/lego-deprecated - that module is - // a challenge.Provider value, so we use it directly. The user must set - // environment variables to configure it. Remove this shim once a sufficient - // number of DNS providers are implemented for the libdns APIs instead. - if grandfatheredProvider, ok := val.(challenge.Provider); ok { - m.Challenges.DNS.provider = grandfatheredProvider + + if deprecatedProvider, ok := val.(acmez.Solver); ok { + // TODO: For a temporary amount of time, we are allowing the use of DNS + // providers from go-acme/lego since there are so many providers implemented + // using that API -- they are adapted as an all-in-one Caddy module in this + // repository: https://github.com/caddy-dns/lego-deprecated - the module is a + // acmez.Solver type, so we use it directly. The user must set environment + // variables to configure it. Remove this shim once a sufficient number of + // DNS providers are implemented for the libdns APIs instead. + m.Challenges.DNS.solver = deprecatedProvider } else { - m.Challenges.DNS.provider = &solver{ - recordManager: val.(recordManager), - TTL: time.Duration(m.Challenges.DNS.TTL), + m.Challenges.DNS.solver = &certmagic.DNS01Solver{ + DNSProvider: val.(certmagic.ACMEDNSProvider), + TTL: time.Duration(m.Challenges.DNS.TTL), + PropagationTimeout: time.Duration(m.Challenges.DNS.PropagationTimeout), } } } @@ -137,16 +144,8 @@ func (m *ACMEIssuer) makeIssuerTemplate() (certmagic.ACMEManager, error) { Email: m.Email, CertObtainTimeout: time.Duration(m.ACMETimeout), TrustedRoots: m.rootPool, - } - - if m.ExternalAccount != nil { - if m.ExternalAccount.KeyID == "" || m.ExternalAccount.HMAC == "" { - 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: m.ExternalAccount.HMAC, - } + ExternalAccount: m.ExternalAccount, + Logger: m.logger, } if m.Challenges != nil { @@ -159,7 +158,7 @@ func (m *ACMEIssuer) makeIssuerTemplate() (certmagic.ACMEManager, error) { template.AltTLSALPNPort = m.Challenges.TLSALPN.AlternatePort } if m.Challenges.DNS != nil { - template.DNSProvider = m.Challenges.DNS.provider + template.DNS01Solver = m.Challenges.DNS.solver } template.ListenHost = m.Challenges.BindHost } @@ -180,8 +179,8 @@ func (m *ACMEIssuer) SetConfig(cfg *certmagic.Config) { // we find the right place to do that just once and then re-use? // PreCheck implements the certmagic.PreChecker interface. -func (m *ACMEIssuer) PreCheck(names []string, interactive bool) error { - return certmagic.NewACMEManager(m.magic, m.template).PreCheck(names, interactive) +func (m *ACMEIssuer) PreCheck(ctx context.Context, names []string, interactive bool) error { + return certmagic.NewACMEManager(m.magic, m.template).PreCheck(ctx, names, interactive) } // Issue obtains a certificate for the given csr. @@ -195,8 +194,8 @@ func (m *ACMEIssuer) IssuerKey() string { } // Revoke revokes the given certificate. -func (m *ACMEIssuer) Revoke(ctx context.Context, cert certmagic.CertificateResource) error { - return certmagic.NewACMEManager(m.magic, m.template).Revoke(ctx, cert) +func (m *ACMEIssuer) Revoke(ctx context.Context, cert certmagic.CertificateResource, reason int) error { + return certmagic.NewACMEManager(m.magic, m.template).Revoke(ctx, cert, reason) } // onDemandAskRequest makes a request to the ask URL @@ -227,16 +226,6 @@ func onDemandAskRequest(ask string, name string) error { return nil } -// 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 HMAC. - HMAC string `json:"hmac,omitempty"` -} - // Interface guards var ( _ certmagic.PreChecker = (*ACMEIssuer)(nil) -- cgit v1.2.3