Skip to content

Commit

Permalink
acme: remove support for pre-RFC 8555 ACME spec
Browse files Browse the repository at this point in the history
LetsEncrypt removed it anyway.

No API changes. Just a lot of deleted code.

Fixes golang/go#46654

Change-Id: I6e22f95bbc771abde8a445d7a7cc09d11f5eff93
  • Loading branch information
bradfitz authored and benburkert committed Oct 27, 2021
1 parent 089bfa5 commit 5bd4f74
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 1,490 deletions.
428 changes: 65 additions & 363 deletions acme/acme.go

Large diffs are not rendered by default.

651 changes: 11 additions & 640 deletions acme/acme_test.go

Large diffs are not rendered by default.

100 changes: 14 additions & 86 deletions acme/autocert/autocert.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ var createCertRetryAfter = time.Minute
// pseudoRand is safe for concurrent use.
var pseudoRand *lockedMathRand

var errPreRFC = errors.New("autocert: ACME server doesn't support RFC 8555")

func init() {
src := mathrand.NewSource(time.Now().UnixNano())
pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
Expand Down Expand Up @@ -658,99 +660,25 @@ func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, ck cert
if err != nil {
return nil, nil, err
}
if dir.OrderURL == "" {
return nil, nil, errPreRFC
}

var chain [][]byte
switch {
// Pre-RFC legacy CA.
case dir.OrderURL == "":
if err := m.verify(ctx, client, ck.domain); err != nil {
return nil, nil, err
}
der, _, err := client.CreateCert(ctx, csr, 0, true)
if err != nil {
return nil, nil, err
}
chain = der
// RFC 8555 compliant CA.
default:
o, err := m.verifyRFC(ctx, client, ck.domain)
if err != nil {
return nil, nil, err
}
der, _, err := client.CreateOrderCert(ctx, o.FinalizeURL, csr, true)
if err != nil {
return nil, nil, err
}
chain = der
o, err := m.verifyRFC(ctx, client, ck.domain)
if err != nil {
return nil, nil, err
}
leaf, err = validCert(ck, chain, key, m.now())
der, _, err = client.CreateOrderCert(ctx, o.FinalizeURL, csr, true)
if err != nil {
return nil, nil, err
}
return chain, leaf, nil
}

// verify runs the identifier (domain) pre-authorization flow for legacy CAs
// using each applicable ACME challenge type.
func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string) error {
// Remove all hanging authorizations to reduce rate limit quotas
// after we're done.
var authzURLs []string
defer func() {
go m.deactivatePendingAuthz(authzURLs)
}()

// errs accumulates challenge failure errors, printed if all fail
errs := make(map[*acme.Challenge]error)
challengeTypes := m.supportedChallengeTypes()
var nextTyp int // challengeType index of the next challenge type to try
for {
// Start domain authorization and get the challenge.
authz, err := client.Authorize(ctx, domain)
if err != nil {
return err
}
authzURLs = append(authzURLs, authz.URI)
// No point in accepting challenges if the authorization status
// is in a final state.
switch authz.Status {
case acme.StatusValid:
return nil // already authorized
case acme.StatusInvalid:
return fmt.Errorf("acme/autocert: invalid authorization %q", authz.URI)
}

// Pick the next preferred challenge.
var chal *acme.Challenge
for chal == nil && nextTyp < len(challengeTypes) {
chal = pickChallenge(challengeTypes[nextTyp], authz.Challenges)
nextTyp++
}
if chal == nil {
errorMsg := fmt.Sprintf("acme/autocert: unable to authorize %q", domain)
for chal, err := range errs {
errorMsg += fmt.Sprintf("; challenge %q failed with error: %v", chal.Type, err)
}
return errors.New(errorMsg)
}
cleanup, err := m.fulfill(ctx, client, chal, domain)
if err != nil {
errs[chal] = err
continue
}
defer cleanup()
if _, err := client.Accept(ctx, chal); err != nil {
errs[chal] = err
continue
}
chain := der

// A challenge is fulfilled and accepted: wait for the CA to validate.
if _, err := client.WaitAuthorization(ctx, authz.URI); err != nil {
errs[chal] = err
continue
}
return nil
leaf, err = validCert(ck, chain, key, m.now())
if err != nil {
return nil, nil, err
}
return chain, leaf, nil
}

// verifyRFC runs the identifier (domain) order-based authorization flow for RFC compliant CAs
Expand Down
Loading

0 comments on commit 5bd4f74

Please sign in to comment.