diff --git a/acme/client.go b/acme/client.go index 40b245a3..f1bf5c76 100644 --- a/acme/client.go +++ b/acme/client.go @@ -67,14 +67,6 @@ func NewClient(caURL string, usr User, keyBits int, optPort string) (*Client, er return nil, fmt.Errorf("invalid private key: %v", err) } - jws := &jws{privKey: privKey} - - // REVIEW: best possibility? - // Add all available solvers with the right index as per ACME - // spec to this map. Otherwise they won`t be found. - solvers := make(map[string]solver) - solvers["simpleHttp"] = &simpleHTTPChallenge{jws: jws, optPort: optPort} - if !strings.HasSuffix(caURL, "/directory") { caURL = caURL + "/directory" } @@ -103,6 +95,14 @@ func NewClient(caURL string, usr User, keyBits int, optPort string) (*Client, er return nil, errors.New("directory missing revoke certificate URL") } + jws := &jws{privKey: privKey, directoryURL: caURL} + + // REVIEW: best possibility? + // Add all available solvers with the right index as per ACME + // spec to this map. Otherwise they won`t be found. + solvers := make(map[string]solver) + solvers["simpleHttp"] = &simpleHTTPChallenge{jws: jws, optPort: optPort} + return &Client{directory: dir, user: usr, jws: jws, keyBits: keyBits, solvers: solvers}, nil } diff --git a/acme/jws.go b/acme/jws.go index c5c496a1..ede8eff4 100644 --- a/acme/jws.go +++ b/acme/jws.go @@ -4,7 +4,6 @@ import ( "bytes" "crypto/ecdsa" "crypto/rsa" - "errors" "fmt" "net/http" @@ -12,8 +11,9 @@ import ( ) type jws struct { - privKey *rsa.PrivateKey - nonces []string + directoryURL string + privKey *rsa.PrivateKey + nonces []string } func keyAsJWK(key interface{}) *jose.JsonWebKey { @@ -30,13 +30,6 @@ func keyAsJWK(key interface{}) *jose.JsonWebKey { // Posts a JWS signed message to the specified URL func (j *jws) post(url string, content []byte) (*http.Response, error) { - if len(j.nonces) == 0 { - err := j.getNonce(url) - if err != nil { - return nil, fmt.Errorf("Could not get a nonce for request: %s\n\t\tError: %v", url, err) - } - } - signedContent, err := j.signContent(content) if err != nil { return nil, err @@ -77,8 +70,8 @@ func (j *jws) getNonceFromResponse(resp *http.Response) error { return nil } -func (j *jws) getNonce(url string) error { - resp, err := http.Head(url) +func (j *jws) getNonce() error { + resp, err := http.Head(j.directoryURL) if err != nil { return err } @@ -89,7 +82,10 @@ func (j *jws) getNonce(url string) error { func (j *jws) Nonce() (string, error) { nonce := "" if len(j.nonces) == 0 { - return nonce, errors.New("No nonce available.") + err := j.getNonce() + if err != nil { + return nonce, err + } } nonce, j.nonces = j.nonces[len(j.nonces)-1], j.nonces[:len(j.nonces)-1] diff --git a/acme/simple_http_challenge_test.go b/acme/simple_http_challenge_test.go index 95924d92..541d4e29 100644 --- a/acme/simple_http_challenge_test.go +++ b/acme/simple_http_challenge_test.go @@ -69,13 +69,13 @@ func TestSimpleHTTPConnectionRefusal(t *testing.T) { func TestSimpleHTTPUnexpectedServerState(t *testing.T) { privKey, _ := generatePrivateKey(rsakey, 512) - jws := &jws{privKey: privKey.(*rsa.PrivateKey)} ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Replay-Nonce", "12345") w.Write([]byte("{\"type\":\"simpleHttp\",\"status\":\"what\",\"uri\":\"http://some.url\",\"token\":\"4\"}")) })) + jws := &jws{privKey: privKey.(*rsa.PrivateKey), directoryURL: ts.URL} solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"} clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "4"} @@ -120,7 +120,6 @@ func TestSimpleHTTPChallengeServerUnexpectedDomain(t *testing.T) { func TestSimpleHTTPServerError(t *testing.T) { privKey, _ := generatePrivateKey(rsakey, 512) - jws := &jws{privKey: privKey.(*rsa.PrivateKey)} ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == "HEAD" { @@ -132,6 +131,7 @@ func TestSimpleHTTPServerError(t *testing.T) { } })) + jws := &jws{privKey: privKey.(*rsa.PrivateKey), directoryURL: ts.URL} solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"} clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "6"} @@ -147,13 +147,13 @@ func TestSimpleHTTPServerError(t *testing.T) { func TestSimpleHTTPInvalidServerState(t *testing.T) { privKey, _ := generatePrivateKey(rsakey, 512) - jws := &jws{privKey: privKey.(*rsa.PrivateKey)} ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Replay-Nonce", "12345") w.Write([]byte("{\"type\":\"simpleHttp\",\"status\":\"invalid\",\"uri\":\"http://some.url\",\"token\":\"7\"}")) })) + jws := &jws{privKey: privKey.(*rsa.PrivateKey), directoryURL: ts.URL} solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"} clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "7"} @@ -169,13 +169,13 @@ func TestSimpleHTTPInvalidServerState(t *testing.T) { func TestSimpleHTTPValidServerResponse(t *testing.T) { privKey, _ := generatePrivateKey(rsakey, 512) - jws := &jws{privKey: privKey.(*rsa.PrivateKey)} ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Replay-Nonce", "12345") w.Write([]byte("{\"type\":\"simpleHttp\",\"status\":\"valid\",\"uri\":\"http://some.url\",\"token\":\"8\"}")) })) + jws := &jws{privKey: privKey.(*rsa.PrivateKey), directoryURL: ts.URL} solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"} clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "8"} @@ -186,10 +186,10 @@ func TestSimpleHTTPValidServerResponse(t *testing.T) { func TestSimpleHTTPValidFull(t *testing.T) { privKey, _ := generatePrivateKey(rsakey, 512) - jws := &jws{privKey: privKey.(*rsa.PrivateKey)} ts := httptest.NewServer(nil) + jws := &jws{privKey: privKey.(*rsa.PrivateKey), directoryURL: ts.URL} solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"} clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "9"}