acme: add StatusValid to expected values for Authorize
Let's Encrypt may respond with the "valid" value in status field to authorization requests: https://github.com/letsencrypt/boulder/blob/0543691d9e2cbcc1b94baf3b9fab4e64ca2750ef/ra/ra.go#L373-L402 The spec isn't clear on this: https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-6.4 Either way, this change follows common sense and should not produce unexpected results. Change-Id: Iac55aa1fb17d458f6d62e8da875ed86e3e4afbc3 Reviewed-on: https://go-review.googlesource.com/27432 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
@@ -404,6 +404,11 @@ func (m *Manager) verify(ctx context.Context, domain string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// maybe don't need to at all
|
||||
if authz.Status == acme.StatusValid {
|
||||
return nil
|
||||
}
|
||||
|
||||
// pick a challenge: prefer tls-sni-02 over tls-sni-01
|
||||
// TODO: consider authz.Combinations
|
||||
var chal *acme.Challenge
|
||||
|
||||
@@ -302,6 +302,10 @@ func (c *Client) UpdateReg(ctx context.Context, a *Account) (*Account, error) {
|
||||
// Authorize performs the initial step in an authorization flow.
|
||||
// The caller will then need to choose from and perform a set of returned
|
||||
// challenges using c.Accept in order to successfully complete authorization.
|
||||
//
|
||||
// If an authorization has been previously granted, the CA may return
|
||||
// a valid authorization (Authorization.Status is StatusValid). If so, the caller
|
||||
// need not fulfill any challenge and can proceed to requesting a certificate.
|
||||
func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization, error) {
|
||||
if _, err := c.Discover(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -331,7 +335,7 @@ func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization,
|
||||
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
|
||||
return nil, fmt.Errorf("acme: invalid response: %v", err)
|
||||
}
|
||||
if v.Status != StatusPending {
|
||||
if v.Status != StatusPending && v.Status != StatusValid {
|
||||
return nil, fmt.Errorf("acme: unexpected status: %s", v.Status)
|
||||
}
|
||||
return v.authorization(res.Header.Get("Location")), nil
|
||||
|
||||
@@ -368,6 +368,23 @@ func TestAuthorize(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizeValid(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "HEAD" {
|
||||
w.Header().Set("replay-nonce", "nonce")
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Write([]byte(`{"status":"valid"}`))
|
||||
}))
|
||||
defer ts.Close()
|
||||
client := Client{Key: testKey, dir: &Directory{AuthzURL: ts.URL}}
|
||||
_, err := client.Authorize(context.Background(), "example.com")
|
||||
if err != nil {
|
||||
t.Errorf("err = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPollAuthz(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" {
|
||||
|
||||
Reference in New Issue
Block a user