Skip to content

Commit 32db794

Browse files
acme: fix deadlock when Client.Key is nil
When methods that use POSTs are called on a acme.Client which has a nil Key field it will cause a deadlock due to an infinite loop in the code that looks up the account KID. This change adds a check for the key being nil, and errors out if that is the case. Also adds a test for this behavior. Fixes golang/go#38790 Change-Id: I65ff6bbbade7ed2d85306895904a976089730bbf Reviewed-on: https://go-review.googlesource.com/c/crypto/+/233164 Trust: Roland Shoemaker <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 0a44fdf commit 32db794

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

acme/http.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"crypto"
1111
"crypto/rand"
1212
"encoding/json"
13+
"errors"
1314
"fmt"
1415
"io/ioutil"
1516
"math/big"
@@ -215,6 +216,9 @@ func (c *Client) post(ctx context.Context, key crypto.Signer, url string, body i
215216
func (c *Client) postNoRetry(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, *http.Request, error) {
216217
kid := noKeyID
217218
if key == nil {
219+
if c.Key == nil {
220+
return nil, nil, errors.New("acme: Client.Key must be populated to make POST requests")
221+
}
218222
key = c.Key
219223
kid = c.accountKID(ctx)
220224
}

acme/http_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,18 @@ func TestUserAgent(t *testing.T) {
238238
}
239239
}
240240
}
241+
242+
func TestAccountKidLoop(t *testing.T) {
243+
// if Client.postNoRetry is called with a nil key argument
244+
// then Client.Key must be set, otherwise we fall into an
245+
// infinite loop (which also causes a deadlock).
246+
client := &Client{dir: &Directory{OrderURL: ":)"}}
247+
_, _, err := client.postNoRetry(context.Background(), nil, "", nil)
248+
if err == nil {
249+
t.Fatal("Client.postNoRetry didn't fail with a nil key")
250+
}
251+
expected := "acme: Client.Key must be populated to make POST requests"
252+
if err.Error() != expected {
253+
t.Fatalf("Unexpected error returned: wanted %q, got %q", expected, err.Error())
254+
}
255+
}

0 commit comments

Comments
 (0)