From e5f6f4c4a3bf5cde010749986c0848b70aed6797 Mon Sep 17 00:00:00 2001 From: xenolf Date: Sat, 26 Sep 2015 22:59:16 +0200 Subject: [PATCH] Changed the client to pull the urls down from the directory on the CA server. CA Url now needs to point to the root of the CA --- acme/client.go | 29 +++++++++++++++++++++-------- acme/client_test.go | 14 ++++++++++---- acme/messages.go | 7 +++++++ cli.go | 2 +- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/acme/client.go b/acme/client.go index d0f0ea19..d2ae18db 100644 --- a/acme/client.go +++ b/acme/client.go @@ -41,11 +41,11 @@ type solver interface { // Client is the user-friendy way to ACME type Client struct { - regURL string - user User - jws *jws - keyBits int - solvers map[string]solver + directory directory + user User + jws *jws + keyBits int + solvers map[string]solver } // NewClient creates a new client for the set user. @@ -53,7 +53,6 @@ func NewClient(caURL string, usr User, keyBits int, optPort string) *Client { if err := usr.GetPrivateKey().Validate(); err != nil { logger().Fatalf("Could not validate the private account key of %s\n\t%v", usr.GetEmail(), err) } - jws := &jws{privKey: usr.GetPrivateKey()} // REVIEW: best possibility? @@ -62,7 +61,21 @@ func NewClient(caURL string, usr User, keyBits int, optPort string) *Client { solvers := make(map[string]solver) solvers["simpleHttp"] = &simpleHTTPChallenge{jws: jws, optPort: optPort} - return &Client{regURL: caURL, user: usr, jws: jws, keyBits: keyBits, solvers: solvers} + dirResp, err := http.Get(caURL + "/directory") + if err != nil { + logger().Fatalf("Could not get directory from CA URL. Please check the URL.\n\t%v", err) + } + var dir directory + decoder := json.NewDecoder(dirResp.Body) + err = decoder.Decode(&dir) + if err != nil { + logger().Fatalf("Could not parse directory response from CA URL.\n\t%v", err) + } + if dir.NewRegURL == "" || dir.NewAuthzURL == "" || dir.NewCertURL == "" || dir.RevokeCertURL == "" { + logger().Fatal("The directory returned by the server was invalid.") + } + + return &Client{directory: dir, user: usr, jws: jws, keyBits: keyBits, solvers: solvers} } // Register the current account to the ACME server. @@ -73,7 +86,7 @@ func (c *Client) Register() (*RegistrationResource, error) { return nil, err } - resp, err := c.jws.post(c.regURL, jsonBytes) + resp, err := c.jws.post(c.directory.NewRegURL, jsonBytes) if err != nil { return nil, err } diff --git a/acme/client_test.go b/acme/client_test.go index 690d2cb8..d55f4984 100644 --- a/acme/client_test.go +++ b/acme/client_test.go @@ -3,6 +3,9 @@ package acme import ( "crypto/rand" "crypto/rsa" + "encoding/json" + "net/http" + "net/http/httptest" "testing" ) @@ -17,7 +20,13 @@ func TestNewClient(t *testing.T) { regres: new(RegistrationResource), privatekey: key, } - caURL, optPort := "https://foobar", "1234" + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + data, _ := json.Marshal(directory{NewAuthzURL: "http://test", NewCertURL: "http://test", NewRegURL: "http://test", RevokeCertURL: "http://test"}) + w.Write(data) + })) + + caURL, optPort := ts.URL, "1234" client := NewClient(caURL, user, keyBits, optPort) if client.jws == nil { @@ -27,9 +36,6 @@ func TestNewClient(t *testing.T) { t.Errorf("Expected jws.privKey to be %p but was %p", expected, actual) } - if client.regURL != caURL { - t.Errorf("Expected regURL to be '%s' but was '%s'", caURL, client.regURL) - } if client.keyBits != keyBits { t.Errorf("Expected keyBits to be %d but was %d", keyBits, client.keyBits) } diff --git a/acme/messages.go b/acme/messages.go index 037bd207..fdfadc4b 100644 --- a/acme/messages.go +++ b/acme/messages.go @@ -2,6 +2,13 @@ package acme import "time" +type directory struct { + NewAuthzURL string `json:"new-authz"` + NewCertURL string `json:"new-cert"` + NewRegURL string `json:"new-reg"` + RevokeCertURL string `json:"revoke-cert"` +} + type registrationMessage struct { Resource string `json:"resource"` Contact []string `json:"contact"` diff --git a/cli.go b/cli.go index d5ef2fe3..64ff213f 100644 --- a/cli.go +++ b/cli.go @@ -91,7 +91,7 @@ func main() { }, cli.StringFlag{ Name: "server, s", - Value: "https://acme-staging.api.letsencrypt.org/acme/new-reg", + Value: "https://acme-staging.api.letsencrypt.org/", Usage: "CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client.", }, cli.StringFlag{