Skip to content

Commit 3f311e4

Browse files
sigmavirus24gopherbot
authored andcommitted
acme: return error from pre-authorization when unsupported
Check the directory's AuthzURL to see if the server supports pre-authorization. If it's empty, then the server is not advertising support and we can encounter other bugs. Better to return early and give a clear error to the caller. From https://www.rfc-editor.org/rfc/rfc8555#section-7.4.1 If a CA wishes to allow pre-authorization within ACME, it can offer a "new authorization" resource in its directory by adding the field "newAuthz" with a URL for the newAuthz resource. Fixes golang/go#40839 Change-Id: Id3e92e8e2ae3c57285183d37544dd59b4988b3be Reviewed-on: https://go-review.googlesource.com/c/crypto/+/661675 Reviewed-by: Dmitri Shuralyov <[email protected]> Auto-Submit: Dmitri Shuralyov <[email protected]> Reviewed-by: Roland Shoemaker <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent 1f7c62c commit 3f311e4

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

acme/acme.go

+4
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ func (c *Client) authorize(ctx context.Context, typ, val string) (*Authorization
353353
if _, err := c.Discover(ctx); err != nil {
354354
return nil, err
355355
}
356+
if c.dir.AuthzURL == "" {
357+
// Pre-Authorization is unsupported
358+
return nil, errPreAuthorizationNotSupported
359+
}
356360

357361
type authzID struct {
358362
Type string `json:"type"`

acme/acme_test.go

+52
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"encoding/base64"
1616
"encoding/hex"
1717
"encoding/json"
18+
"errors"
1819
"fmt"
1920
"io"
2021
"math/big"
@@ -254,6 +255,57 @@ func TestAuthorizeValid(t *testing.T) {
254255
}
255256
}
256257

258+
func TestAuthorizeUnsupported(t *testing.T) {
259+
const (
260+
nonce = "https://example.com/acme/new-nonce"
261+
reg = "https://example.com/acme/new-acct"
262+
order = "https://example.com/acme/new-order"
263+
revoke = "https://example.com/acme/revoke-cert"
264+
keychange = "https://example.com/acme/key-change"
265+
metaTerms = "https://example.com/acme/terms/2017-5-30"
266+
metaWebsite = "https://www.example.com/"
267+
metaCAA = "example.com"
268+
)
269+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
270+
w.Header().Set("Replay-Nonce", "nonce")
271+
if r.Method == http.MethodHead {
272+
return
273+
}
274+
switch r.URL.Path {
275+
case "/": // Directory
276+
w.Header().Set("Content-Type", "application/json")
277+
fmt.Fprintf(w, `{
278+
"newNonce": %q,
279+
"newAccount": %q,
280+
"newOrder": %q,
281+
"revokeCert": %q,
282+
"keyChange": %q,
283+
"meta": {
284+
"termsOfService": %q,
285+
"website": %q,
286+
"caaIdentities": [%q],
287+
"externalAccountRequired": true
288+
}
289+
}`, nonce, reg, order, revoke, keychange, metaTerms, metaWebsite, metaCAA)
290+
w.WriteHeader(http.StatusOK)
291+
case "/acme/new-authz":
292+
w.WriteHeader(http.StatusBadRequest)
293+
}
294+
}))
295+
defer ts.Close()
296+
client := &Client{Key: testKey, DirectoryURL: ts.URL}
297+
dir, err := client.Discover(context.Background())
298+
if err != nil {
299+
t.Fatal(err)
300+
}
301+
if dir.AuthzURL != "" {
302+
t.Fatalf("expected AuthzURL to be empty, got %q", dir.AuthzURL)
303+
}
304+
if _, err := client.Authorize(context.Background(), "example.com"); !errors.Is(err, errPreAuthorizationNotSupported) {
305+
t.Errorf("expected err to indicate pre-authorization is unsupported, got %+v", err)
306+
}
307+
}
308+
257309
func TestWaitAuthorization(t *testing.T) {
258310
t.Run("wait loop", func(t *testing.T) {
259311
var count int

acme/types.go

+4
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ var (
5656

5757
// ErrNoAccount indicates that the Client's key has not been registered with the CA.
5858
ErrNoAccount = errors.New("acme: account does not exist")
59+
60+
// errPreAuthorizationNotSupported indicates that the server does not
61+
// support pre-authorization of identifiers.
62+
errPreAuthorizationNotSupported = errors.New("acme: pre-authorization is not supported")
5963
)
6064

6165
// A Subproblem describes an ACME subproblem as reported in an Error.

0 commit comments

Comments
 (0)