forked from TrueCloudLab/lego
Add AlwaysDeactivateAuthorizations flag to ObtainRequest (#1480)
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
This commit is contained in:
parent
d2e526e8dd
commit
6d0e0e16b4
4 changed files with 59 additions and 31 deletions
|
@ -60,7 +60,7 @@ func (c *Certifier) getAuthorizations(order acme.ExtendedOrder) ([]acme.Authoriz
|
|||
return responses, nil
|
||||
}
|
||||
|
||||
func (c *Certifier) deactivateAuthorizations(order acme.ExtendedOrder) {
|
||||
func (c *Certifier) deactivateAuthorizations(order acme.ExtendedOrder, force bool) {
|
||||
for _, authzURL := range order.Authorizations {
|
||||
auth, err := c.core.Authorizations.Get(authzURL)
|
||||
if err != nil {
|
||||
|
@ -68,7 +68,7 @@ func (c *Certifier) deactivateAuthorizations(order acme.ExtendedOrder) {
|
|||
continue
|
||||
}
|
||||
|
||||
if auth.Status == acme.StatusValid {
|
||||
if auth.Status == acme.StatusValid && !force {
|
||||
log.Infof("Skipping deactivating of valid auth: %s", authzURL)
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -49,22 +49,30 @@ type Resource struct {
|
|||
// If you do not want that you can supply your own private key in the privateKey parameter.
|
||||
// If this parameter is non-nil it will be used instead of generating a new one.
|
||||
//
|
||||
// If bundle is true, the []byte contains both the issuer certificate and your issued certificate as a bundle.
|
||||
// If `Bundle` is true, the `[]byte` contains both the issuer certificate and your issued certificate as a bundle.
|
||||
//
|
||||
// If `AlwaysDeactivateAuthorizations` is true, the authorizations are also relinquished if the obtain request was successful.
|
||||
// See https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.2.
|
||||
type ObtainRequest struct {
|
||||
Domains []string
|
||||
Bundle bool
|
||||
PrivateKey crypto.PrivateKey
|
||||
MustStaple bool
|
||||
PreferredChain string
|
||||
AlwaysDeactivateAuthorizations bool
|
||||
}
|
||||
|
||||
// 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.
|
||||
// If `Bundle` is true, the `[]byte` contains both the issuer certificate and your issued certificate as a bundle.
|
||||
//
|
||||
// If `AlwaysDeactivateAuthorizations` is true, the authorizations are also relinquished if the obtain request was successful.
|
||||
// See https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.2.
|
||||
type ObtainForCSRRequest struct {
|
||||
CSR *x509.CertificateRequest
|
||||
Bundle bool
|
||||
PreferredChain string
|
||||
AlwaysDeactivateAuthorizations bool
|
||||
}
|
||||
|
||||
type resolver interface {
|
||||
|
@ -117,14 +125,14 @@ func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) {
|
|||
authz, err := c.getAuthorizations(order)
|
||||
if err != nil {
|
||||
// If any challenge fails, return. Do not generate partial SAN certificates.
|
||||
c.deactivateAuthorizations(order)
|
||||
c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = c.resolver.Solve(authz)
|
||||
if err != nil {
|
||||
// If any challenge fails, return. Do not generate partial SAN certificates.
|
||||
c.deactivateAuthorizations(order)
|
||||
c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -138,6 +146,10 @@ func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if request.AlwaysDeactivateAuthorizations {
|
||||
c.deactivateAuthorizations(order, true)
|
||||
}
|
||||
|
||||
// Do not return an empty failures map, because
|
||||
// it would still be a non-nil error value
|
||||
if len(failures) > 0 {
|
||||
|
@ -178,14 +190,14 @@ func (c *Certifier) ObtainForCSR(request ObtainForCSRRequest) (*Resource, error)
|
|||
authz, err := c.getAuthorizations(order)
|
||||
if err != nil {
|
||||
// If any challenge fails, return. Do not generate partial SAN certificates.
|
||||
c.deactivateAuthorizations(order)
|
||||
c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = c.resolver.Solve(authz)
|
||||
if err != nil {
|
||||
// If any challenge fails, return. Do not generate partial SAN certificates.
|
||||
c.deactivateAuthorizations(order)
|
||||
c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -199,6 +211,10 @@ func (c *Certifier) ObtainForCSR(request ObtainForCSRRequest) (*Resource, error)
|
|||
}
|
||||
}
|
||||
|
||||
if request.AlwaysDeactivateAuthorizations {
|
||||
c.deactivateAuthorizations(order, true)
|
||||
}
|
||||
|
||||
if cert != nil {
|
||||
// Add the CSR to the certificate so that it can be used for renewals.
|
||||
cert.CSR = certcrypto.PEMEncode(request.CSR)
|
||||
|
|
|
@ -62,6 +62,10 @@ func createRenew() cli.Command {
|
|||
Name: "preferred-chain",
|
||||
Usage: "If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used.",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "always-deactivate-authorizations",
|
||||
Usage: "Force the authorizations to be relinquished even if the certificate request was successful.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -132,6 +136,7 @@ func renewForDomains(ctx *cli.Context, client *lego.Client, certsStorage *Certif
|
|||
PrivateKey: privateKey,
|
||||
MustStaple: ctx.Bool("must-staple"),
|
||||
PreferredChain: ctx.String("preferred-chain"),
|
||||
AlwaysDeactivateAuthorizations: ctx.Bool("always-deactivate-authorizations"),
|
||||
}
|
||||
certRes, err := client.Certificate.Obtain(request)
|
||||
if err != nil {
|
||||
|
@ -177,6 +182,7 @@ func renewForCSR(ctx *cli.Context, client *lego.Client, certsStorage *Certificat
|
|||
CSR: csr,
|
||||
Bundle: bundle,
|
||||
PreferredChain: ctx.String("preferred-chain"),
|
||||
AlwaysDeactivateAuthorizations: ctx.Bool("always-deactivate-authorizations"),
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
|
|
@ -47,6 +47,10 @@ func createRun() cli.Command {
|
|||
Name: "preferred-chain",
|
||||
Usage: "If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used.",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "always-deactivate-authorizations",
|
||||
Usage: "Force the authorizations to be relinquished even if the certificate request was successful.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +171,7 @@ func obtainCertificate(ctx *cli.Context, client *lego.Client) (*certificate.Reso
|
|||
Bundle: bundle,
|
||||
MustStaple: ctx.Bool("must-staple"),
|
||||
PreferredChain: ctx.String("preferred-chain"),
|
||||
AlwaysDeactivateAuthorizations: ctx.Bool("always-deactivate-authorizations"),
|
||||
}
|
||||
return client.Certificate.Obtain(request)
|
||||
}
|
||||
|
@ -182,5 +187,6 @@ func obtainCertificate(ctx *cli.Context, client *lego.Client) (*certificate.Reso
|
|||
CSR: csr,
|
||||
Bundle: bundle,
|
||||
PreferredChain: ctx.String("preferred-chain"),
|
||||
AlwaysDeactivateAuthorizations: ctx.Bool("always-deactivate-authorizations"),
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue