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
|
return responses, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Certifier) deactivateAuthorizations(order acme.ExtendedOrder) {
|
func (c *Certifier) deactivateAuthorizations(order acme.ExtendedOrder, force bool) {
|
||||||
for _, authzURL := range order.Authorizations {
|
for _, authzURL := range order.Authorizations {
|
||||||
auth, err := c.core.Authorizations.Get(authzURL)
|
auth, err := c.core.Authorizations.Get(authzURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -68,7 +68,7 @@ func (c *Certifier) deactivateAuthorizations(order acme.ExtendedOrder) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if auth.Status == acme.StatusValid {
|
if auth.Status == acme.StatusValid && !force {
|
||||||
log.Infof("Skipping deactivating of valid auth: %s", authzURL)
|
log.Infof("Skipping deactivating of valid auth: %s", authzURL)
|
||||||
continue
|
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 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 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 {
|
type ObtainRequest struct {
|
||||||
Domains []string
|
Domains []string
|
||||||
Bundle bool
|
Bundle bool
|
||||||
PrivateKey crypto.PrivateKey
|
PrivateKey crypto.PrivateKey
|
||||||
MustStaple bool
|
MustStaple bool
|
||||||
PreferredChain string
|
PreferredChain string
|
||||||
|
AlwaysDeactivateAuthorizations bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObtainForCSRRequest The request to obtain a certificate matching the CSR passed into it.
|
// 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 {
|
type ObtainForCSRRequest struct {
|
||||||
CSR *x509.CertificateRequest
|
CSR *x509.CertificateRequest
|
||||||
Bundle bool
|
Bundle bool
|
||||||
PreferredChain string
|
PreferredChain string
|
||||||
|
AlwaysDeactivateAuthorizations bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type resolver interface {
|
type resolver interface {
|
||||||
|
@ -117,14 +125,14 @@ func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) {
|
||||||
authz, err := c.getAuthorizations(order)
|
authz, err := c.getAuthorizations(order)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If any challenge fails, return. Do not generate partial SAN certificates.
|
// If any challenge fails, return. Do not generate partial SAN certificates.
|
||||||
c.deactivateAuthorizations(order)
|
c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.resolver.Solve(authz)
|
err = c.resolver.Solve(authz)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If any challenge fails, return. Do not generate partial SAN certificates.
|
// If any challenge fails, return. Do not generate partial SAN certificates.
|
||||||
c.deactivateAuthorizations(order)
|
c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
|
||||||
return nil, err
|
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
|
// Do not return an empty failures map, because
|
||||||
// it would still be a non-nil error value
|
// it would still be a non-nil error value
|
||||||
if len(failures) > 0 {
|
if len(failures) > 0 {
|
||||||
|
@ -178,14 +190,14 @@ func (c *Certifier) ObtainForCSR(request ObtainForCSRRequest) (*Resource, error)
|
||||||
authz, err := c.getAuthorizations(order)
|
authz, err := c.getAuthorizations(order)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If any challenge fails, return. Do not generate partial SAN certificates.
|
// If any challenge fails, return. Do not generate partial SAN certificates.
|
||||||
c.deactivateAuthorizations(order)
|
c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.resolver.Solve(authz)
|
err = c.resolver.Solve(authz)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If any challenge fails, return. Do not generate partial SAN certificates.
|
// If any challenge fails, return. Do not generate partial SAN certificates.
|
||||||
c.deactivateAuthorizations(order)
|
c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
|
||||||
return nil, err
|
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 {
|
if cert != nil {
|
||||||
// Add the CSR to the certificate so that it can be used for renewals.
|
// Add the CSR to the certificate so that it can be used for renewals.
|
||||||
cert.CSR = certcrypto.PEMEncode(request.CSR)
|
cert.CSR = certcrypto.PEMEncode(request.CSR)
|
||||||
|
|
|
@ -62,6 +62,10 @@ func createRenew() cli.Command {
|
||||||
Name: "preferred-chain",
|
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.",
|
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.",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,11 +131,12 @@ func renewForDomains(ctx *cli.Context, client *lego.Client, certsStorage *Certif
|
||||||
}
|
}
|
||||||
|
|
||||||
request := certificate.ObtainRequest{
|
request := certificate.ObtainRequest{
|
||||||
Domains: merge(certDomains, domains),
|
Domains: merge(certDomains, domains),
|
||||||
Bundle: bundle,
|
Bundle: bundle,
|
||||||
PrivateKey: privateKey,
|
PrivateKey: privateKey,
|
||||||
MustStaple: ctx.Bool("must-staple"),
|
MustStaple: ctx.Bool("must-staple"),
|
||||||
PreferredChain: ctx.String("preferred-chain"),
|
PreferredChain: ctx.String("preferred-chain"),
|
||||||
|
AlwaysDeactivateAuthorizations: ctx.Bool("always-deactivate-authorizations"),
|
||||||
}
|
}
|
||||||
certRes, err := client.Certificate.Obtain(request)
|
certRes, err := client.Certificate.Obtain(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -174,9 +179,10 @@ func renewForCSR(ctx *cli.Context, client *lego.Client, certsStorage *Certificat
|
||||||
log.Infof("[%s] acme: Trying renewal with %d hours remaining", domain, int(timeLeft.Hours()))
|
log.Infof("[%s] acme: Trying renewal with %d hours remaining", domain, int(timeLeft.Hours()))
|
||||||
|
|
||||||
certRes, err := client.Certificate.ObtainForCSR(certificate.ObtainForCSRRequest{
|
certRes, err := client.Certificate.ObtainForCSR(certificate.ObtainForCSRRequest{
|
||||||
CSR: csr,
|
CSR: csr,
|
||||||
Bundle: bundle,
|
Bundle: bundle,
|
||||||
PreferredChain: ctx.String("preferred-chain"),
|
PreferredChain: ctx.String("preferred-chain"),
|
||||||
|
AlwaysDeactivateAuthorizations: ctx.Bool("always-deactivate-authorizations"),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
|
@ -47,6 +47,10 @@ func createRun() cli.Command {
|
||||||
Name: "preferred-chain",
|
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.",
|
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.",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,10 +167,11 @@ func obtainCertificate(ctx *cli.Context, client *lego.Client) (*certificate.Reso
|
||||||
if len(domains) > 0 {
|
if len(domains) > 0 {
|
||||||
// obtain a certificate, generating a new private key
|
// obtain a certificate, generating a new private key
|
||||||
request := certificate.ObtainRequest{
|
request := certificate.ObtainRequest{
|
||||||
Domains: domains,
|
Domains: domains,
|
||||||
Bundle: bundle,
|
Bundle: bundle,
|
||||||
MustStaple: ctx.Bool("must-staple"),
|
MustStaple: ctx.Bool("must-staple"),
|
||||||
PreferredChain: ctx.String("preferred-chain"),
|
PreferredChain: ctx.String("preferred-chain"),
|
||||||
|
AlwaysDeactivateAuthorizations: ctx.Bool("always-deactivate-authorizations"),
|
||||||
}
|
}
|
||||||
return client.Certificate.Obtain(request)
|
return client.Certificate.Obtain(request)
|
||||||
}
|
}
|
||||||
|
@ -179,8 +184,9 @@ func obtainCertificate(ctx *cli.Context, client *lego.Client) (*certificate.Reso
|
||||||
|
|
||||||
// obtain a certificate for this CSR
|
// obtain a certificate for this CSR
|
||||||
return client.Certificate.ObtainForCSR(certificate.ObtainForCSRRequest{
|
return client.Certificate.ObtainForCSR(certificate.ObtainForCSRRequest{
|
||||||
CSR: csr,
|
CSR: csr,
|
||||||
Bundle: bundle,
|
Bundle: bundle,
|
||||||
PreferredChain: ctx.String("preferred-chain"),
|
PreferredChain: ctx.String("preferred-chain"),
|
||||||
|
AlwaysDeactivateAuthorizations: ctx.Bool("always-deactivate-authorizations"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue