diff --git a/certificate/certificates.go b/certificate/certificates.go index 867e4ac5..d5daec72 100644 --- a/certificate/certificates.go +++ b/certificate/certificates.go @@ -58,6 +58,15 @@ type ObtainRequest struct { PreferredChain string } +// ObtainForCSRRequest The request to obtain a certificate matching the CSR passed into it. +// +// If bundle is true, the []byte contains both the issuer certificate and your issued certificate as a bundle. +type ObtainForCSRRequest struct { + CSR *x509.CertificateRequest + Bundle bool + PreferredChain string +} + type resolver interface { Solve(authorizations []acme.Authorization) error } @@ -146,12 +155,16 @@ func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) { // // This function will never return a partial certificate. // If one domain in the list fails, the whole certificate will fail. -func (c *Certifier) ObtainForCSR(csr x509.CertificateRequest, bundle bool, preferredChain string) (*Resource, error) { +func (c *Certifier) ObtainForCSR(request ObtainForCSRRequest) (*Resource, error) { + if request.CSR == nil { + return nil, errors.New("cannot obtain resource for CSR: CSR is missing") + } + // figure out what domains it concerns // start with the common name - domains := certcrypto.ExtractDomainsCSR(&csr) + domains := certcrypto.ExtractDomainsCSR(request.CSR) - if bundle { + if request.Bundle { log.Infof("[%s] acme: Obtaining bundled SAN certificate given a CSR", strings.Join(domains, ", ")) } else { log.Infof("[%s] acme: Obtaining SAN certificate given a CSR", strings.Join(domains, ", ")) @@ -179,7 +192,7 @@ func (c *Certifier) ObtainForCSR(csr x509.CertificateRequest, bundle bool, prefe log.Infof("[%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", ")) failures := make(obtainError) - cert, err := c.getForCSR(domains, order, bundle, csr.Raw, nil, preferredChain) + cert, err := c.getForCSR(domains, order, request.Bundle, request.CSR.Raw, nil, request.PreferredChain) if err != nil { for _, auth := range authz { failures[challenge.GetTargetedDomain(auth)] = err @@ -188,7 +201,7 @@ func (c *Certifier) ObtainForCSR(csr x509.CertificateRequest, bundle bool, prefe if cert != nil { // Add the CSR to the certificate so that it can be used for renewals. - cert.CSR = certcrypto.PEMEncode(&csr) + cert.CSR = certcrypto.PEMEncode(request.CSR) } // Do not return an empty failures map, @@ -394,7 +407,11 @@ func (c *Certifier) Renew(certRes Resource, bundle, mustStaple bool, preferredCh return nil, errP } - return c.ObtainForCSR(*csr, bundle, preferredChain) + return c.ObtainForCSR(ObtainForCSRRequest{ + CSR: csr, + Bundle: bundle, + PreferredChain: preferredChain, + }) } var privateKey crypto.PrivateKey diff --git a/cmd/cmd_renew.go b/cmd/cmd_renew.go index 49d024b4..8283b5f5 100644 --- a/cmd/cmd_renew.go +++ b/cmd/cmd_renew.go @@ -173,7 +173,11 @@ func renewForCSR(ctx *cli.Context, client *lego.Client, certsStorage *Certificat timeLeft := cert.NotAfter.Sub(time.Now().UTC()) log.Infof("[%s] acme: Trying renewal with %d hours remaining", domain, int(timeLeft.Hours())) - certRes, err := client.Certificate.ObtainForCSR(*csr, bundle, ctx.String("preferred-chain")) + certRes, err := client.Certificate.ObtainForCSR(certificate.ObtainForCSRRequest{ + CSR: csr, + Bundle: bundle, + PreferredChain: ctx.String("preferred-chain"), + }) if err != nil { log.Fatal(err) } diff --git a/cmd/cmd_run.go b/cmd/cmd_run.go index eacf2ed0..a6d0eb79 100644 --- a/cmd/cmd_run.go +++ b/cmd/cmd_run.go @@ -178,5 +178,9 @@ func obtainCertificate(ctx *cli.Context, client *lego.Client) (*certificate.Reso } // obtain a certificate for this CSR - return client.Certificate.ObtainForCSR(*csr, bundle, ctx.String("preferred-chain")) + return client.Certificate.ObtainForCSR(certificate.ObtainForCSRRequest{ + CSR: csr, + Bundle: bundle, + PreferredChain: ctx.String("preferred-chain"), + }) } diff --git a/e2e/challenges_test.go b/e2e/challenges_test.go index d5fae6a6..ec6909bb 100644 --- a/e2e/challenges_test.go +++ b/e2e/challenges_test.go @@ -307,7 +307,10 @@ func TestChallengeTLS_Client_ObtainForCSR(t *testing.T) { csr, err := x509.ParseCertificateRequest(csrRaw) require.NoError(t, err) - resource, err := client.Certificate.ObtainForCSR(*csr, true, "") + resource, err := client.Certificate.ObtainForCSR(certificate.ObtainForCSRRequest{ + CSR: csr, + Bundle: true, + }) require.NoError(t, err) require.NotNil(t, resource)