diff --git a/pkg/acme/acme.go b/pkg/acme/acme.go index e569fc2da9..a84b0532fe 100644 --- a/pkg/acme/acme.go +++ b/pkg/acme/acme.go @@ -21,6 +21,7 @@ import ( type CertConfig struct { CertName string `json:"cert_name"` Names []string `json:"names"` + UseECC bool `json:"use_ecc"` } type Client interface { @@ -36,8 +37,8 @@ type certManager struct { cfg *models.DNSConfig domains map[string]*models.DomainConfig originalDomains []*models.DomainConfig - client *acme.Client + account *Account waitedOnce bool } @@ -64,13 +65,11 @@ func commonNew(cfg *models.DNSConfig, storage Storage, email string, server stri domains: map[string]*models.DomainConfig{}, } - client, err := c.createAcmeClient() + acct, err := c.getOrCreateAccount() if err != nil { return nil, err } - client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.TLSALPN01}) - client.SetChallengeProvider(acme.DNS01, c) - c.client = client + c.account = acct return c, nil } @@ -97,8 +96,10 @@ func (c *certManager) IssueOrRenewCert(cfg *CertConfig, renewUnder int, verbose return false, err } + var client *acme.Client + var action = func() (*acme.CertificateResource, error) { - return c.client.ObtainCertificate(cfg.Names, true, nil, true) + return client.ObtainCertificate(cfg.Names, true, nil, true) } if existing == nil { @@ -120,11 +121,22 @@ func (c *certManager) IssueOrRenewCert(cfg *CertConfig, renewUnder int, verbose } else { log.Println("Renewing cert") action = func() (*acme.CertificateResource, error) { - return c.client.RenewCertificate(*existing, true, true) + return client.RenewCertificate(*existing, true, true) } } } + kt := acme.RSA2048 + if cfg.UseECC { + kt = acme.EC256 + } + client, err = acme.NewClient(c.acmeDirectory, c.account, kt) + if err != nil { + return false, err + } + client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.TLSALPN01}) + client.SetChallengeProvider(acme.DNS01, c) + acme.PreCheckDNS = c.preCheckDNS defer func() { acme.PreCheckDNS = acmePreCheck }() diff --git a/pkg/acme/registration.go b/pkg/acme/registration.go index 41977408b6..dd76245529 100644 --- a/pkg/acme/registration.go +++ b/pkg/acme/registration.go @@ -9,26 +9,21 @@ import ( "github.com/xenolf/lego/acme" ) -func (c *certManager) createAcmeClient() (*acme.Client, error) { +func (c *certManager) getOrCreateAccount() (*Account, error) { account, err := c.storage.GetAccount(c.acmeHost) if err != nil { return nil, err } - if account == nil { - // register new - account, err = c.createAccount(c.email) - if err != nil { - return nil, err - } - if err := c.storage.StoreAccount(c.acmeHost, account); err != nil { - return nil, err - } + if account != nil { + return account, nil } - client, err := acme.NewClient(c.acmeDirectory, account, acme.RSA2048) // TODO: possibly make configurable on a cert-by cert basis + // register new + account, err = c.createAccount(c.email) if err != nil { return nil, err } - return client, nil + err = c.storage.StoreAccount(c.acmeHost, account) + return account, err } func (c *certManager) createAccount(email string) (*Account, error) { @@ -40,11 +35,11 @@ func (c *certManager) createAccount(email string) (*Account, error) { key: privateKey, Email: c.email, } - c.client, err = acme.NewClient(c.acmeDirectory, acct, acme.EC384) + client, err := acme.NewClient(c.acmeDirectory, acct, acme.EC384) if err != nil { return nil, err } - reg, err := c.client.Register(true) + reg, err := client.Register(true) if err != nil { return nil, err } diff --git a/pkg/acme/storage.go b/pkg/acme/storage.go index e0e5e0c890..c8d3356833 100644 --- a/pkg/acme/storage.go +++ b/pkg/acme/storage.go @@ -2,6 +2,7 @@ package acme import "github.com/xenolf/lego/acme" +// Storage is an abstracrion around how certificates, keys, and account info are stored on disk or elsewhere. type Storage interface { // Get Existing certificate, or return nil if it does not exist GetCertificate(name string) (*acme.CertificateResource, error)