From 2ca0e8f9a0f9863555a26e984cde15efff9ef8f8 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Fri, 23 Sep 2016 10:17:51 -0400 Subject: Updating golang dependancies (#4075) --- .../golang.org/x/crypto/acme/internal/acme/acme.go | 473 ------------- .../x/crypto/acme/internal/acme/acme_test.go | 759 --------------------- .../golang.org/x/crypto/acme/internal/acme/jws.go | 67 -- .../x/crypto/acme/internal/acme/jws_test.go | 139 ---- .../x/crypto/acme/internal/acme/types.go | 181 ----- 5 files changed, 1619 deletions(-) delete mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/acme.go delete mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/acme_test.go delete mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/jws.go delete mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/jws_test.go delete mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/types.go (limited to 'vendor/golang.org/x/crypto/acme/internal') diff --git a/vendor/golang.org/x/crypto/acme/internal/acme/acme.go b/vendor/golang.org/x/crypto/acme/internal/acme/acme.go deleted file mode 100644 index 2732999f3..000000000 --- a/vendor/golang.org/x/crypto/acme/internal/acme/acme.go +++ /dev/null @@ -1,473 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package acme provides an ACME client implementation. -// See https://ietf-wg-acme.github.io/acme/ for details. -// -// This package is a work in progress and makes no API stability promises. -package acme - -import ( - "bytes" - "crypto/rsa" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "net/http" - "strconv" - "strings" - "time" - - "golang.org/x/net/context" -) - -// Client is an ACME client. -type Client struct { - // HTTPClient optionally specifies an HTTP client to use - // instead of http.DefaultClient. - HTTPClient *http.Client - - // Key is the account key used to register with a CA - // and sign requests. - Key *rsa.PrivateKey -} - -// Discover performs ACME server discovery using the provided discovery endpoint URL. -func (c *Client) Discover(url string) (*Directory, error) { - res, err := c.httpClient().Get(url) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode != http.StatusOK { - return nil, responseError(res) - } - var v struct { - Reg string `json:"new-reg"` - Authz string `json:"new-authz"` - Cert string `json:"new-cert"` - Revoke string `json:"revoke-cert"` - Meta struct { - Terms string `json:"terms-of-service"` - Website string `json:"website"` - CAA []string `json:"caa-identities"` - } - } - if json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, err - } - return &Directory{ - RegURL: v.Reg, - AuthzURL: v.Authz, - CertURL: v.Cert, - RevokeURL: v.Revoke, - Terms: v.Meta.Terms, - Website: v.Meta.Website, - CAA: v.Meta.CAA, - }, nil -} - -// CreateCert requests a new certificate. -// In the case where CA server does not provide the issued certificate in the response, -// CreateCert will poll certURL using c.FetchCert, which will result in additional round-trips. -// In such scenario the caller can cancel the polling with ctx. -// -// If the bundle is true, the returned value will also contain CA (the issuer) certificate. -// The url argument is an Directory.CertURL value, typically obtained from c.Discover. -// The csr is a DER encoded certificate signing request. -func (c *Client) CreateCert(ctx context.Context, url string, csr []byte, exp time.Duration, bundle bool) (der [][]byte, certURL string, err error) { - req := struct { - Resource string `json:"resource"` - CSR string `json:"csr"` - NotBefore string `json:"notBefore,omitempty"` - NotAfter string `json:"notAfter,omitempty"` - }{ - Resource: "new-cert", - CSR: base64.RawURLEncoding.EncodeToString(csr), - } - now := timeNow() - req.NotBefore = now.Format(time.RFC3339) - if exp > 0 { - req.NotAfter = now.Add(exp).Format(time.RFC3339) - } - - res, err := c.postJWS(url, req) - if err != nil { - return nil, "", err - } - defer res.Body.Close() - if res.StatusCode != http.StatusCreated { - return nil, "", responseError(res) - } - - curl := res.Header.Get("location") // cert permanent URL - if res.ContentLength == 0 { - // no cert in the body; poll until we get it - cert, err := c.FetchCert(ctx, curl, bundle) - return cert, curl, err - } - // slurp issued cert and ca, if requested - cert, err := responseCert(c.httpClient(), res, bundle) - return cert, curl, err -} - -// FetchCert retrieves already issued certificate from the given url, in DER format. -// It retries the request until the certificate is successfully retrieved, -// context is cancelled by the caller or an error response is received. -// -// The returned value will also contain CA (the issuer) certificate if bundle == true. -// -// http.DefaultClient is used if client argument is nil. -func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) { - for { - res, err := c.httpClient().Get(url) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode == http.StatusOK { - return responseCert(c.httpClient(), res, bundle) - } - if res.StatusCode > 299 { - return nil, responseError(res) - } - d, err := retryAfter(res.Header.Get("retry-after")) - if err != nil { - d = 3 * time.Second - } - select { - case <-time.After(d): - // retry - case <-ctx.Done(): - return nil, ctx.Err() - } - } -} - -// Register creates a new account registration by following the "new-reg" flow. -// It returns registered account. The a argument is not modified. -// -// The url argument is typically an Directory.RegURL obtained from c.Discover. -func (c *Client) Register(url string, a *Account) (*Account, error) { - return c.doReg(url, "new-reg", a) -} - -// GetReg retrieves an existing registration. -// The url argument is an Account.URI, typically obtained from c.Register. -func (c *Client) GetReg(url string) (*Account, error) { - a := &Account{URI: url} - return c.doReg(url, "reg", a) -} - -// UpdateReg updates an existing registration. -// It returns an updated account copy. The provided account is not modified. -// -// The url argument is an Account.URI, usually obtained with c.Register. -func (c *Client) UpdateReg(url string, a *Account) (*Account, error) { - return c.doReg(url, "reg", a) -} - -// 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. -// -// The url argument is an authz URL, usually obtained with c.Register. -func (c *Client) Authorize(url, domain string) (*Authorization, error) { - type authzID struct { - Type string `json:"type"` - Value string `json:"value"` - } - req := struct { - Resource string `json:"resource"` - Identifier authzID `json:"identifier"` - }{ - Resource: "new-authz", - Identifier: authzID{Type: "dns", Value: domain}, - } - res, err := c.postJWS(url, req) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode != http.StatusCreated { - return nil, responseError(res) - } - - var v wireAuthz - if err := json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, fmt.Errorf("Decode: %v", err) - } - if v.Status != StatusPending { - return nil, fmt.Errorf("Unexpected status: %s", v.Status) - } - return v.authorization(res.Header.Get("Location")), nil -} - -// GetAuthz retrieves the current status of an authorization flow. -// -// A client typically polls an authz status using this method. -func (c *Client) GetAuthz(url string) (*Authorization, error) { - res, err := c.httpClient().Get(url) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted { - return nil, responseError(res) - } - var v wireAuthz - if err := json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, fmt.Errorf("Decode: %v", err) - } - return v.authorization(url), nil -} - -// GetChallenge retrieves the current status of an challenge. -// -// A client typically polls a challenge status using this method. -func (c *Client) GetChallenge(url string) (*Challenge, error) { - res, err := c.httpClient().Get(url) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted { - return nil, responseError(res) - } - v := wireChallenge{URI: url} - if err := json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, fmt.Errorf("Decode: %v", err) - } - return v.challenge(), nil -} - -// Accept informs the server that the client accepts one of its challenges -// previously obtained with c.Authorize. -// -// The server will then perform the validation asynchronously. -func (c *Client) Accept(chal *Challenge) (*Challenge, error) { - req := struct { - Resource string `json:"resource"` - Type string `json:"type"` - Auth string `json:"keyAuthorization"` - }{ - Resource: "challenge", - Type: chal.Type, - Auth: keyAuth(&c.Key.PublicKey, chal.Token), - } - res, err := c.postJWS(chal.URI, req) - if err != nil { - return nil, err - } - defer res.Body.Close() - // Note: the protocol specifies 200 as the expected response code, but - // letsencrypt seems to be returning 202. - if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted { - return nil, responseError(res) - } - - var v wireChallenge - if err := json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, fmt.Errorf("Decode: %v", err) - } - return v.challenge(), nil -} - -// HTTP01Handler creates a new handler which responds to a http-01 challenge. -// The token argument is a Challenge.Token value. -func (c *Client) HTTP01Handler(token string) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if !strings.HasSuffix(r.URL.Path, token) { - w.WriteHeader(http.StatusNotFound) - return - } - w.Header().Set("content-type", "text/plain") - w.Write([]byte(keyAuth(&c.Key.PublicKey, token))) - }) -} - -func (c *Client) httpClient() *http.Client { - if c.HTTPClient != nil { - return c.HTTPClient - } - return http.DefaultClient -} - -// postJWS signs body and posts it to the provided url. -// The body argument must be JSON-serializable. -func (c *Client) postJWS(url string, body interface{}) (*http.Response, error) { - nonce, err := fetchNonce(c.httpClient(), url) - if err != nil { - return nil, err - } - b, err := jwsEncodeJSON(body, c.Key, nonce) - if err != nil { - return nil, err - } - req, err := http.NewRequest("POST", url, bytes.NewReader(b)) - if err != nil { - return nil, err - } - return c.httpClient().Do(req) -} - -// doReg sends all types of registration requests. -// The type of request is identified by typ argument, which is a "resource" -// in the ACME spec terms. -// -// A non-nil acct argument indicates whether the intention is to mutate data -// of the Account. Only Contact and Agreement of its fields are used -// in such cases. -// -// The fields of acct will be populate with the server response -// and may be overwritten. -func (c *Client) doReg(url string, typ string, acct *Account) (*Account, error) { - req := struct { - Resource string `json:"resource"` - Contact []string `json:"contact,omitempty"` - Agreement string `json:"agreement,omitempty"` - }{ - Resource: typ, - } - if acct != nil { - req.Contact = acct.Contact - req.Agreement = acct.AgreedTerms - } - res, err := c.postJWS(url, req) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode < 200 || res.StatusCode > 299 { - return nil, responseError(res) - } - - var v struct { - Contact []string - Agreement string - Authorizations string - Certificates string - } - if err := json.NewDecoder(res.Body).Decode(&v); err != nil { - return nil, fmt.Errorf("Decode: %v", err) - } - return &Account{ - URI: res.Header.Get("Location"), - Contact: v.Contact, - AgreedTerms: v.Agreement, - CurrentTerms: linkHeader(res.Header, "terms-of-service"), - Authz: linkHeader(res.Header, "next"), - Authorizations: v.Authorizations, - Certificates: v.Certificates, - }, nil -} - -func responseCert(client *http.Client, res *http.Response, bundle bool) ([][]byte, error) { - b, err := ioutil.ReadAll(res.Body) - if err != nil { - return nil, fmt.Errorf("ReadAll: %v", err) - } - cert := [][]byte{b} - if !bundle { - return cert, nil - } - - // append ca cert - up := linkHeader(res.Header, "up") - if up == "" { - return nil, errors.New("rel=up link not found") - } - res, err = client.Get(up) - if err != nil { - return nil, err - } - defer res.Body.Close() - if res.StatusCode != http.StatusOK { - return nil, responseError(res) - } - b, err = ioutil.ReadAll(res.Body) - if err != nil { - return nil, err - } - return append(cert, b), nil -} - -// responseError creates an error of Error type from resp. -func responseError(resp *http.Response) error { - // don't care if ReadAll returns an error: - // json.Unmarshal will fail in that case anyway - b, _ := ioutil.ReadAll(resp.Body) - e := struct { - Status int - Type string - Detail string - }{ - Status: resp.StatusCode, - } - if err := json.Unmarshal(b, &e); err != nil { - // this is not a regular error response: - // populate detail with anything we received, - // e.Status will already contain HTTP response code value - e.Detail = string(b) - if e.Detail == "" { - e.Detail = resp.Status - } - } - return &Error{ - StatusCode: e.Status, - ProblemType: e.Type, - Detail: e.Detail, - Header: resp.Header, - } -} - -func fetchNonce(client *http.Client, url string) (string, error) { - resp, err := client.Head(url) - if err != nil { - return "", nil - } - defer resp.Body.Close() - enc := resp.Header.Get("replay-nonce") - if enc == "" { - return "", errors.New("nonce not found") - } - return enc, nil -} - -func linkHeader(h http.Header, rel string) string { - for _, v := range h["Link"] { - parts := strings.Split(v, ";") - for _, p := range parts { - p = strings.TrimSpace(p) - if !strings.HasPrefix(p, "rel=") { - continue - } - if v := strings.Trim(p[4:], `"`); v == rel { - return strings.Trim(parts[0], "<>") - } - } - } - return "" -} - -func retryAfter(v string) (time.Duration, error) { - if i, err := strconv.Atoi(v); err == nil { - return time.Duration(i) * time.Second, nil - } - t, err := http.ParseTime(v) - if err != nil { - return 0, err - } - return t.Sub(timeNow()), nil -} - -// keyAuth generates a key authorization string for a given token. -func keyAuth(pub *rsa.PublicKey, token string) string { - return fmt.Sprintf("%s.%s", token, JWKThumbprint(pub)) -} - -// timeNow is useful for testing for fixed current time. -var timeNow = time.Now diff --git a/vendor/golang.org/x/crypto/acme/internal/acme/acme_test.go b/vendor/golang.org/x/crypto/acme/internal/acme/acme_test.go deleted file mode 100644 index f9d17c339..000000000 --- a/vendor/golang.org/x/crypto/acme/internal/acme/acme_test.go +++ /dev/null @@ -1,759 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package acme - -import ( - "crypto/rand" - "crypto/x509" - "crypto/x509/pkix" - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "math/big" - "net/http" - "net/http/httptest" - "reflect" - "strings" - "testing" - "time" - - "golang.org/x/net/context" -) - -// Decodes a JWS-encoded request and unmarshals the decoded JSON into a provided -// interface. -func decodeJWSRequest(t *testing.T, v interface{}, r *http.Request) { - // Decode request - var req struct{ Payload string } - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - t.Fatal(err) - } - payload, err := base64.RawURLEncoding.DecodeString(req.Payload) - if err != nil { - t.Fatal(err) - } - err = json.Unmarshal(payload, v) - if err != nil { - t.Fatal(err) - } -} - -func TestDiscover(t *testing.T) { - const ( - reg = "https://example.com/acme/new-reg" - authz = "https://example.com/acme/new-authz" - cert = "https://example.com/acme/new-cert" - revoke = "https://example.com/acme/revoke-cert" - ) - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("content-type", "application/json") - fmt.Fprintf(w, `{ - "new-reg": %q, - "new-authz": %q, - "new-cert": %q, - "revoke-cert": %q - }`, reg, authz, cert, revoke) - })) - defer ts.Close() - ep, err := (&Client{}).Discover(ts.URL) - if err != nil { - t.Fatal(err) - } - if ep.RegURL != reg { - t.Errorf("RegURL = %q; want %q", ep.RegURL, reg) - } - if ep.AuthzURL != authz { - t.Errorf("authzURL = %q; want %q", ep.AuthzURL, authz) - } - if ep.CertURL != cert { - t.Errorf("certURL = %q; want %q", ep.CertURL, cert) - } - if ep.RevokeURL != revoke { - t.Errorf("revokeURL = %q; want %q", ep.RevokeURL, revoke) - } -} - -func TestRegister(t *testing.T) { - contacts := []string{"mailto:admin@example.com"} - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string - Contact []string - Agreement string - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "new-reg" { - t.Errorf("j.Resource = %q; want new-reg", j.Resource) - } - if !reflect.DeepEqual(j.Contact, contacts) { - t.Errorf("j.Contact = %v; want %v", j.Contact, contacts) - } - - w.Header().Set("Location", "https://ca.tld/acme/reg/1") - w.Header().Set("Link", `;rel="next"`) - w.Header().Add("Link", `;rel="recover"`) - w.Header().Add("Link", `;rel="terms-of-service"`) - w.WriteHeader(http.StatusCreated) - b, _ := json.Marshal(contacts) - fmt.Fprintf(w, `{ - "key":%q, - "contact":%s - }`, testKeyThumbprint, b) - })) - defer ts.Close() - - c := Client{Key: testKey} - a := &Account{Contact: contacts} - var err error - if a, err = c.Register(ts.URL, a); err != nil { - t.Fatal(err) - } - if a.URI != "https://ca.tld/acme/reg/1" { - t.Errorf("a.URI = %q; want https://ca.tld/acme/reg/1", a.URI) - } - if a.Authz != "https://ca.tld/acme/new-authz" { - t.Errorf("a.Authz = %q; want https://ca.tld/acme/new-authz", a.Authz) - } - if a.CurrentTerms != "https://ca.tld/acme/terms" { - t.Errorf("a.CurrentTerms = %q; want https://ca.tld/acme/terms", a.CurrentTerms) - } - if !reflect.DeepEqual(a.Contact, contacts) { - t.Errorf("a.Contact = %v; want %v", a.Contact, contacts) - } -} - -func TestUpdateReg(t *testing.T) { - const terms = "https://ca.tld/acme/terms" - contacts := []string{"mailto:admin@example.com"} - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string - Contact []string - Agreement string - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "reg" { - t.Errorf("j.Resource = %q; want reg", j.Resource) - } - if j.Agreement != terms { - t.Errorf("j.Agreement = %q; want %q", j.Agreement, terms) - } - if !reflect.DeepEqual(j.Contact, contacts) { - t.Errorf("j.Contact = %v; want %v", j.Contact, contacts) - } - - w.Header().Set("Link", `;rel="next"`) - w.Header().Add("Link", `;rel="recover"`) - w.Header().Add("Link", fmt.Sprintf(`<%s>;rel="terms-of-service"`, terms)) - w.WriteHeader(http.StatusOK) - b, _ := json.Marshal(contacts) - fmt.Fprintf(w, `{ - "key":%q, - "contact":%s, - "agreement":%q - }`, testKeyThumbprint, b, terms) - })) - defer ts.Close() - - c := Client{Key: testKey} - a := &Account{Contact: contacts, AgreedTerms: terms} - var err error - if a, err = c.UpdateReg(ts.URL, a); err != nil { - t.Fatal(err) - } - if a.Authz != "https://ca.tld/acme/new-authz" { - t.Errorf("a.Authz = %q; want https://ca.tld/acme/new-authz", a.Authz) - } - if a.AgreedTerms != terms { - t.Errorf("a.AgreedTerms = %q; want %q", a.AgreedTerms, terms) - } - if a.CurrentTerms != terms { - t.Errorf("a.CurrentTerms = %q; want %q", a.CurrentTerms, terms) - } -} - -func TestGetReg(t *testing.T) { - const terms = "https://ca.tld/acme/terms" - const newTerms = "https://ca.tld/acme/new-terms" - contacts := []string{"mailto:admin@example.com"} - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string - Contact []string - Agreement string - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "reg" { - t.Errorf("j.Resource = %q; want reg", j.Resource) - } - if len(j.Contact) != 0 { - t.Errorf("j.Contact = %v", j.Contact) - } - if j.Agreement != "" { - t.Errorf("j.Agreement = %q", j.Agreement) - } - - w.Header().Set("Link", `;rel="next"`) - w.Header().Add("Link", `;rel="recover"`) - w.Header().Add("Link", fmt.Sprintf(`<%s>;rel="terms-of-service"`, newTerms)) - w.WriteHeader(http.StatusOK) - b, _ := json.Marshal(contacts) - fmt.Fprintf(w, `{ - "key":%q, - "contact":%s, - "agreement":%q - }`, testKeyThumbprint, b, terms) - })) - defer ts.Close() - - c := Client{Key: testKey} - a, err := c.GetReg(ts.URL) - if err != nil { - t.Fatal(err) - } - if a.Authz != "https://ca.tld/acme/new-authz" { - t.Errorf("a.AuthzURL = %q; want https://ca.tld/acme/new-authz", a.Authz) - } - if a.AgreedTerms != terms { - t.Errorf("a.AgreedTerms = %q; want %q", a.AgreedTerms, terms) - } - if a.CurrentTerms != newTerms { - t.Errorf("a.CurrentTerms = %q; want %q", a.CurrentTerms, newTerms) - } -} - -func TestAuthorize(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string - Identifier struct { - Type string - Value string - } - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "new-authz" { - t.Errorf("j.Resource = %q; want new-authz", j.Resource) - } - if j.Identifier.Type != "dns" { - t.Errorf("j.Identifier.Type = %q; want dns", j.Identifier.Type) - } - if j.Identifier.Value != "example.com" { - t.Errorf("j.Identifier.Value = %q; want example.com", j.Identifier.Value) - } - - w.Header().Set("Location", "https://ca.tld/acme/auth/1") - w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ - "identifier": {"type":"dns","value":"example.com"}, - "status":"pending", - "challenges":[ - { - "type":"http-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id1", - "token":"token1" - }, - { - "type":"tls-sni-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id2", - "token":"token2" - } - ], - "combinations":[[0],[1]]}`) - })) - defer ts.Close() - - cl := Client{Key: testKey} - auth, err := cl.Authorize(ts.URL, "example.com") - if err != nil { - t.Fatal(err) - } - - if auth.URI != "https://ca.tld/acme/auth/1" { - t.Errorf("URI = %q; want https://ca.tld/acme/auth/1", auth.URI) - } - if auth.Status != "pending" { - t.Errorf("Status = %q; want pending", auth.Status) - } - if auth.Identifier.Type != "dns" { - t.Errorf("Identifier.Type = %q; want dns", auth.Identifier.Type) - } - if auth.Identifier.Value != "example.com" { - t.Errorf("Identifier.Value = %q; want example.com", auth.Identifier.Value) - } - - if n := len(auth.Challenges); n != 2 { - t.Fatalf("len(auth.Challenges) = %d; want 2", n) - } - - c := auth.Challenges[0] - if c.Type != "http-01" { - t.Errorf("c.Type = %q; want http-01", c.Type) - } - if c.URI != "https://ca.tld/acme/challenge/publickey/id1" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id1", c.URI) - } - if c.Token != "token1" { - t.Errorf("c.Token = %q; want token1", c.Type) - } - - c = auth.Challenges[1] - if c.Type != "tls-sni-01" { - t.Errorf("c.Type = %q; want tls-sni-01", c.Type) - } - if c.URI != "https://ca.tld/acme/challenge/publickey/id2" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id2", c.URI) - } - if c.Token != "token2" { - t.Errorf("c.Token = %q; want token2", c.Type) - } - - combs := [][]int{{0}, {1}} - if !reflect.DeepEqual(auth.Combinations, combs) { - t.Errorf("auth.Combinations: %+v\nwant: %+v\n", auth.Combinations, combs) - } -} - -func TestPollAuthz(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - t.Errorf("r.Method = %q; want GET", r.Method) - } - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ - "identifier": {"type":"dns","value":"example.com"}, - "status":"pending", - "challenges":[ - { - "type":"http-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id1", - "token":"token1" - }, - { - "type":"tls-sni-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id2", - "token":"token2" - } - ], - "combinations":[[0],[1]]}`) - })) - defer ts.Close() - - cl := Client{Key: testKey} - auth, err := cl.GetAuthz(ts.URL) - if err != nil { - t.Fatal(err) - } - - if auth.Status != "pending" { - t.Errorf("Status = %q; want pending", auth.Status) - } - if auth.Identifier.Type != "dns" { - t.Errorf("Identifier.Type = %q; want dns", auth.Identifier.Type) - } - if auth.Identifier.Value != "example.com" { - t.Errorf("Identifier.Value = %q; want example.com", auth.Identifier.Value) - } - - if n := len(auth.Challenges); n != 2 { - t.Fatalf("len(set.Challenges) = %d; want 2", n) - } - - c := auth.Challenges[0] - if c.Type != "http-01" { - t.Errorf("c.Type = %q; want http-01", c.Type) - } - if c.URI != "https://ca.tld/acme/challenge/publickey/id1" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id1", c.URI) - } - if c.Token != "token1" { - t.Errorf("c.Token = %q; want token1", c.Type) - } - - c = auth.Challenges[1] - if c.Type != "tls-sni-01" { - t.Errorf("c.Type = %q; want tls-sni-01", c.Type) - } - if c.URI != "https://ca.tld/acme/challenge/publickey/id2" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id2", c.URI) - } - if c.Token != "token2" { - t.Errorf("c.Token = %q; want token2", c.Type) - } - - combs := [][]int{{0}, {1}} - if !reflect.DeepEqual(auth.Combinations, combs) { - t.Errorf("auth.Combinations: %+v\nwant: %+v\n", auth.Combinations, combs) - } -} - -func TestPollChallenge(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - t.Errorf("r.Method = %q; want GET", r.Method) - } - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ - "type":"http-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id1", - "token":"token1"}`) - })) - defer ts.Close() - - cl := Client{Key: testKey} - chall, err := cl.GetChallenge(ts.URL) - if err != nil { - t.Fatal(err) - } - - if chall.Status != "pending" { - t.Errorf("Status = %q; want pending", chall.Status) - } - if chall.Type != "http-01" { - t.Errorf("c.Type = %q; want http-01", chall.Type) - } - if chall.URI != "https://ca.tld/acme/challenge/publickey/id1" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id1", chall.URI) - } - if chall.Token != "token1" { - t.Errorf("c.Token = %q; want token1", chall.Type) - } -} - -func TestAcceptChallenge(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string - Type string - Auth string `json:"keyAuthorization"` - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "challenge" { - t.Errorf(`resource = %q; want "challenge"`, j.Resource) - } - if j.Type != "http-01" { - t.Errorf(`type = %q; want "http-01"`, j.Type) - } - keyAuth := "token1." + testKeyThumbprint - if j.Auth != keyAuth { - t.Errorf(`keyAuthorization = %q; want %q`, j.Auth, keyAuth) - } - - // Respond to request - w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, `{ - "type":"http-01", - "status":"pending", - "uri":"https://ca.tld/acme/challenge/publickey/id1", - "token":"token1", - "keyAuthorization":%q - }`, keyAuth) - })) - defer ts.Close() - - cl := Client{Key: testKey} - c, err := cl.Accept(&Challenge{ - URI: ts.URL, - Token: "token1", - Type: "http-01", - }) - if err != nil { - t.Fatal(err) - } - - if c.Type != "http-01" { - t.Errorf("c.Type = %q; want http-01", c.Type) - } - if c.URI != "https://ca.tld/acme/challenge/publickey/id1" { - t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id1", c.URI) - } - if c.Token != "token1" { - t.Errorf("c.Token = %q; want token1", c.Type) - } -} - -func TestNewCert(t *testing.T) { - notBefore := time.Now() - notAfter := notBefore.AddDate(0, 2, 0) - timeNow = func() time.Time { return notBefore } - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == "HEAD" { - w.Header().Set("replay-nonce", "test-nonce") - return - } - if r.Method != "POST" { - t.Errorf("r.Method = %q; want POST", r.Method) - } - - var j struct { - Resource string `json:"resource"` - CSR string `json:"csr"` - NotBefore string `json:"notBefore,omitempty"` - NotAfter string `json:"notAfter,omitempty"` - } - decodeJWSRequest(t, &j, r) - - // Test request - if j.Resource != "new-cert" { - t.Errorf(`resource = %q; want "new-cert"`, j.Resource) - } - if j.NotBefore != notBefore.Format(time.RFC3339) { - t.Errorf(`notBefore = %q; wanted %q`, j.NotBefore, notBefore.Format(time.RFC3339)) - } - if j.NotAfter != notAfter.Format(time.RFC3339) { - t.Errorf(`notAfter = %q; wanted %q`, j.NotAfter, notAfter.Format(time.RFC3339)) - } - - // Respond to request - template := x509.Certificate{ - SerialNumber: big.NewInt(int64(1)), - Subject: pkix.Name{ - Organization: []string{"goacme"}, - }, - NotBefore: notBefore, - NotAfter: notAfter, - - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, - BasicConstraintsValid: true, - } - - sampleCert, err := x509.CreateCertificate(rand.Reader, &template, &template, &testKey.PublicKey, testKey) - if err != nil { - t.Fatalf("Error creating certificate: %v", err) - } - - w.Header().Set("Location", "https://ca.tld/acme/cert/1") - w.WriteHeader(http.StatusCreated) - w.Write(sampleCert) - })) - defer ts.Close() - - csr := x509.CertificateRequest{ - Version: 0, - Subject: pkix.Name{ - CommonName: "example.com", - Organization: []string{"goacme"}, - }, - } - csrb, err := x509.CreateCertificateRequest(rand.Reader, &csr, testKey) - if err != nil { - t.Fatal(err) - } - - c := Client{Key: testKey} - cert, certURL, err := c.CreateCert(context.Background(), ts.URL, csrb, notAfter.Sub(notBefore), false) - if err != nil { - t.Fatal(err) - } - if cert == nil { - t.Errorf("cert is nil") - } - if certURL != "https://ca.tld/acme/cert/1" { - t.Errorf("certURL = %q; want https://ca.tld/acme/cert/1", certURL) - } -} - -func TestFetchCert(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte{1}) - })) - defer ts.Close() - res, err := (&Client{}).FetchCert(context.Background(), ts.URL, false) - if err != nil { - t.Fatalf("FetchCert: %v", err) - } - cert := [][]byte{{1}} - if !reflect.DeepEqual(res, cert) { - t.Errorf("res = %v; want %v", res, cert) - } -} - -func TestFetchCertRetry(t *testing.T) { - var count int - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if count < 1 { - w.Header().Set("retry-after", "0") - w.WriteHeader(http.StatusAccepted) - count++ - return - } - w.Write([]byte{1}) - })) - defer ts.Close() - res, err := (&Client{}).FetchCert(context.Background(), ts.URL, false) - if err != nil { - t.Fatalf("FetchCert: %v", err) - } - cert := [][]byte{{1}} - if !reflect.DeepEqual(res, cert) { - t.Errorf("res = %v; want %v", res, cert) - } -} - -func TestFetchCertCancel(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("retry-after", "0") - w.WriteHeader(http.StatusAccepted) - })) - defer ts.Close() - ctx, cancel := context.WithCancel(context.Background()) - done := make(chan struct{}) - var err error - go func() { - _, err = (&Client{}).FetchCert(ctx, ts.URL, false) - close(done) - }() - cancel() - <-done - if err != context.Canceled { - t.Errorf("err = %v; want %v", err, context.Canceled) - } -} - -func TestFetchNonce(t *testing.T) { - tests := []struct { - code int - nonce string - }{ - {http.StatusOK, "nonce1"}, - {http.StatusBadRequest, "nonce2"}, - {http.StatusOK, ""}, - } - var i int - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method != "HEAD" { - t.Errorf("%d: r.Method = %q; want HEAD", i, r.Method) - } - w.Header().Set("replay-nonce", tests[i].nonce) - w.WriteHeader(tests[i].code) - })) - defer ts.Close() - for ; i < len(tests); i++ { - test := tests[i] - n, err := fetchNonce(http.DefaultClient, ts.URL) - if n != test.nonce { - t.Errorf("%d: n=%q; want %q", i, n, test.nonce) - } - switch { - case err == nil && test.nonce == "": - t.Errorf("%d: n=%q, err=%v; want non-nil error", i, n, err) - case err != nil && test.nonce != "": - t.Errorf("%d: n=%q, err=%v; want %q", i, n, err, test.nonce) - } - } -} - -func TestLinkHeader(t *testing.T) { - h := http.Header{"Link": { - `;rel="next"`, - `; rel=recover`, - `; foo=bar; rel="terms-of-service"`, - }} - tests := []struct{ in, out string }{ - {"next", "https://example.com/acme/new-authz"}, - {"recover", "https://example.com/acme/recover-reg"}, - {"terms-of-service", "https://example.com/acme/terms"}, - {"empty", ""}, - } - for i, test := range tests { - if v := linkHeader(h, test.in); v != test.out { - t.Errorf("%d: parseLinkHeader(%q): %q; want %q", i, test.in, v, test.out) - } - } -} - -func TestErrorResponse(t *testing.T) { - s := `{ - "status": 400, - "type": "urn:acme:error:xxx", - "detail": "text" - }` - res := &http.Response{ - StatusCode: 400, - Status: "400 Bad Request", - Body: ioutil.NopCloser(strings.NewReader(s)), - Header: http.Header{"X-Foo": {"bar"}}, - } - err := responseError(res) - v, ok := err.(*Error) - if !ok { - t.Fatalf("err = %+v (%T); want *Error type", err, err) - } - if v.StatusCode != 400 { - t.Errorf("v.StatusCode = %v; want 400", v.StatusCode) - } - if v.ProblemType != "urn:acme:error:xxx" { - t.Errorf("v.ProblemType = %q; want urn:acme:error:xxx", v.ProblemType) - } - if v.Detail != "text" { - t.Errorf("v.Detail = %q; want text", v.Detail) - } - if !reflect.DeepEqual(v.Header, res.Header) { - t.Errorf("v.Header = %+v; want %+v", v.Header, res.Header) - } -} diff --git a/vendor/golang.org/x/crypto/acme/internal/acme/jws.go b/vendor/golang.org/x/crypto/acme/internal/acme/jws.go deleted file mode 100644 index c27752977..000000000 --- a/vendor/golang.org/x/crypto/acme/internal/acme/jws.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package acme - -import ( - "crypto" - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "encoding/base64" - "encoding/json" - "fmt" - "math/big" -) - -// jwsEncodeJSON signs claimset using provided key and a nonce. -// The result is serialized in JSON format. -// See https://tools.ietf.org/html/rfc7515#section-7. -func jwsEncodeJSON(claimset interface{}, key *rsa.PrivateKey, nonce string) ([]byte, error) { - jwk := jwkEncode(&key.PublicKey) - phead := fmt.Sprintf(`{"alg":"RS256","jwk":%s,"nonce":%q}`, jwk, nonce) - phead = base64.RawURLEncoding.EncodeToString([]byte(phead)) - cs, err := json.Marshal(claimset) - if err != nil { - return nil, err - } - payload := base64.RawURLEncoding.EncodeToString(cs) - h := sha256.New() - h.Write([]byte(phead + "." + payload)) - sig, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, h.Sum(nil)) - if err != nil { - return nil, err - } - enc := struct { - Protected string `json:"protected"` - Payload string `json:"payload"` - Sig string `json:"signature"` - }{ - Protected: phead, - Payload: payload, - Sig: base64.RawURLEncoding.EncodeToString(sig), - } - return json.Marshal(&enc) -} - -// jwkEncode encodes public part of an RSA key into a JWK. -// The result is also suitable for creating a JWK thumbprint. -func jwkEncode(pub *rsa.PublicKey) string { - n := pub.N - e := big.NewInt(int64(pub.E)) - // fields order is important - // see https://tools.ietf.org/html/rfc7638#section-3.3 for details - return fmt.Sprintf(`{"e":"%s","kty":"RSA","n":"%s"}`, - base64.RawURLEncoding.EncodeToString(e.Bytes()), - base64.RawURLEncoding.EncodeToString(n.Bytes()), - ) -} - -// JWKThumbprint creates a JWK thumbprint out of pub -// as specified in https://tools.ietf.org/html/rfc7638. -func JWKThumbprint(pub *rsa.PublicKey) string { - jwk := jwkEncode(pub) - b := sha256.Sum256([]byte(jwk)) - return base64.RawURLEncoding.EncodeToString(b[:]) -} diff --git a/vendor/golang.org/x/crypto/acme/internal/acme/jws_test.go b/vendor/golang.org/x/crypto/acme/internal/acme/jws_test.go deleted file mode 100644 index 7afd9507b..000000000 --- a/vendor/golang.org/x/crypto/acme/internal/acme/jws_test.go +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package acme - -import ( - "crypto/rsa" - "crypto/x509" - "encoding/base64" - "encoding/json" - "encoding/pem" - "math/big" - "testing" -) - -const testKeyPEM = ` ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEA4xgZ3eRPkwoRvy7qeRUbmMDe0V+xH9eWLdu0iheeLlrmD2mq -WXfP9IeSKApbn34g8TuAS9g5zhq8ELQ3kmjr+KV86GAMgI6VAcGlq3QrzpTCf/30 -Ab7+zawrfRaFONa1HwEzPY1KHnGVkxJc85gNkwYI9SY2RHXtvln3zs5wITNrdosq -EXeaIkVYBEhbhNu54pp3kxo6TuWLi9e6pXeWetEwmlBwtWZlPoib2j3TxLBksKZf -oyFyek380mHgJAumQ/I2fjj98/97mk3ihOY4AgVdCDj1z/GCoZkG5Rq7nbCGyosy -KWyDX00Zs+nNqVhoLeIvXC4nnWdJMZ6rogxyQQIDAQABAoIBACIEZTOI1Kao9nmV -9IeIsuaR1Y61b9neOF/MLmIVIZu+AAJFCMB4Iw11FV6sFodwpEyeZhx2WkpWVN+H -r19eGiLX3zsL0DOdqBJoSIHDWCCMxgnYJ6nvS0nRxX3qVrBp8R2g12Ub+gNPbmFm -ecf/eeERIVxfifd9VsyRu34eDEvcmKFuLYbElFcPh62xE3x12UZvV/sN7gXbawpP -G+w255vbE5MoaKdnnO83cTFlcHvhn24M/78qP7Te5OAeelr1R89kYxQLpuGe4fbS -zc6E3ym5Td6urDetGGrSY1Eu10/8sMusX+KNWkm+RsBRbkyKq72ks/qKpOxOa+c6 -9gm+Y8ECgYEA/iNUyg1ubRdH11p82l8KHtFC1DPE0V1gSZsX29TpM5jS4qv46K+s -8Ym1zmrORM8x+cynfPx1VQZQ34EYeCMIX212ryJ+zDATl4NE0I4muMvSiH9vx6Xc -7FmhNnaYzPsBL5Tm9nmtQuP09YEn8poiOJFiDs/4olnD5ogA5O4THGkCgYEA5MIL -qWYBUuqbEWLRtMruUtpASclrBqNNsJEsMGbeqBJmoMxdHeSZckbLOrqm7GlMyNRJ -Ne/5uWRGSzaMYuGmwsPpERzqEvYFnSrpjW5YtXZ+JtxFXNVfm9Z1gLLgvGpOUCIU -RbpoDckDe1vgUuk3y5+DjZihs+rqIJ45XzXTzBkCgYBWuf3segruJZy5rEKhTv+o -JqeUvRn0jNYYKFpLBeyTVBrbie6GkbUGNIWbrK05pC+c3K9nosvzuRUOQQL1tJbd -4gA3oiD9U4bMFNr+BRTHyZ7OQBcIXdz3t1qhuHVKtnngIAN1p25uPlbRFUNpshnt -jgeVoHlsBhApcs5DUc+pyQKBgDzeHPg/+g4z+nrPznjKnktRY1W+0El93kgi+J0Q -YiJacxBKEGTJ1MKBb8X6sDurcRDm22wMpGfd9I5Cv2v4GsUsF7HD/cx5xdih+G73 -c4clNj/k0Ff5Nm1izPUno4C+0IOl7br39IPmfpSuR6wH/h6iHQDqIeybjxyKvT1G -N0rRAoGBAKGD+4ZI/E1MoJ5CXB8cDDMHagbE3cq/DtmYzE2v1DFpQYu5I4PCm5c7 -EQeIP6dZtv8IMgtGIb91QX9pXvP0aznzQKwYIA8nZgoENCPfiMTPiEDT9e/0lObO -9XWsXpbSTsRPj0sv1rB+UzBJ0PgjK4q2zOF0sNo7b1+6nlM3BWPx ------END RSA PRIVATE KEY----- -` - -// This thumbprint is for the testKey defined above. -const testKeyThumbprint = "6nicxzh6WETQlrvdchkz-U3e3DOQZ4heJKU63rfqMqQ" - -var testKey *rsa.PrivateKey - -func init() { - d, _ := pem.Decode([]byte(testKeyPEM)) - if d == nil { - panic("no block found in testKeyPEM") - } - var err error - testKey, err = x509.ParsePKCS1PrivateKey(d.Bytes) - if err != nil { - panic(err.Error()) - } -} - -func TestJWSEncodeJSON(t *testing.T) { - claims := struct{ Msg string }{"Hello JWS"} - // JWS signed with testKey and "nonce" as the nonce value - // JSON-serialized JWS fields are split for easier testing - const ( - // {"alg":"RS256","jwk":{"e":"AQAB","kty":"RSA","n":"..."},"nonce":"nonce"} - protected = "eyJhbGciOiJSUzI1NiIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6" + - "IlJTQSIsIm4iOiI0eGdaM2VSUGt3b1J2eTdxZVJVYm1NRGUwVi14" + - "SDllV0xkdTBpaGVlTGxybUQybXFXWGZQOUllU0tBcGJuMzRnOFR1" + - "QVM5ZzV6aHE4RUxRM2ttanItS1Y4NkdBTWdJNlZBY0dscTNRcnpw" + - "VENmXzMwQWI3LXphd3JmUmFGT05hMUh3RXpQWTFLSG5HVmt4SmM4" + - "NWdOa3dZSTlTWTJSSFh0dmxuM3pzNXdJVE5yZG9zcUVYZWFJa1ZZ" + - "QkVoYmhOdTU0cHAza3hvNlR1V0xpOWU2cFhlV2V0RXdtbEJ3dFda" + - "bFBvaWIyajNUeExCa3NLWmZveUZ5ZWszODBtSGdKQXVtUV9JMmZq" + - "ajk4Xzk3bWszaWhPWTRBZ1ZkQ0RqMXpfR0NvWmtHNVJxN25iQ0d5" + - "b3N5S1d5RFgwMFpzLW5OcVZob0xlSXZYQzRubldkSk1aNnJvZ3h5" + - "UVEifSwibm9uY2UiOiJub25jZSJ9" - // {"Msg":"Hello JWS"} - payload = "eyJNc2ciOiJIZWxsbyBKV1MifQ" - signature = "eAGUikStX_UxyiFhxSLMyuyBcIB80GeBkFROCpap2sW3EmkU_ggF" + - "knaQzxrTfItICSAXsCLIquZ5BbrSWA_4vdEYrwWtdUj7NqFKjHRa" + - "zpLHcoR7r1rEHvkoP1xj49lS5fc3Wjjq8JUhffkhGbWZ8ZVkgPdC" + - "4tMBWiQDoth-x8jELP_3LYOB_ScUXi2mETBawLgOT2K8rA0Vbbmx" + - "hWNlOWuUf-8hL5YX4IOEwsS8JK_TrTq5Zc9My0zHJmaieqDV0UlP" + - "k0onFjPFkGm7MrPSgd0MqRG-4vSAg2O4hDo7rKv4n8POjjXlNQvM" + - "9IPLr8qZ7usYBKhEGwX3yq_eicAwBw" - ) - - b, err := jwsEncodeJSON(claims, testKey, "nonce") - if err != nil { - t.Fatal(err) - } - var jws struct{ Protected, Payload, Signature string } - if err := json.Unmarshal(b, &jws); err != nil { - t.Fatal(err) - } - if jws.Protected != protected { - t.Errorf("protected:\n%s\nwant:\n%s", jws.Protected, protected) - } - if jws.Payload != payload { - t.Errorf("payload:\n%s\nwant:\n%s", jws.Payload, payload) - } - if jws.Signature != signature { - t.Errorf("signature:\n%s\nwant:\n%s", jws.Signature, signature) - } -} - -func TestJWKThumbprint(t *testing.T) { - // Key example from RFC 7638 - const base64N = "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAt" + - "VT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn6" + - "4tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FD" + - "W2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n9" + - "1CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINH" + - "aQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw" - const base64E = "AQAB" - const expected = "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs" - - bytes, err := base64.RawURLEncoding.DecodeString(base64N) - if err != nil { - t.Fatalf("Error parsing example key N: %v", err) - } - n := new(big.Int).SetBytes(bytes) - - bytes, err = base64.RawURLEncoding.DecodeString(base64E) - if err != nil { - t.Fatalf("Error parsing example key E: %v", err) - } - e := new(big.Int).SetBytes(bytes) - - pub := &rsa.PublicKey{N: n, E: int(e.Uint64())} - th := JWKThumbprint(pub) - if th != expected { - t.Errorf("th = %q; want %q", th, expected) - } -} diff --git a/vendor/golang.org/x/crypto/acme/internal/acme/types.go b/vendor/golang.org/x/crypto/acme/internal/acme/types.go deleted file mode 100644 index e64dc118c..000000000 --- a/vendor/golang.org/x/crypto/acme/internal/acme/types.go +++ /dev/null @@ -1,181 +0,0 @@ -package acme - -import ( - "fmt" - "net/http" -) - -// ACME server response statuses used to describe Authorization and Challenge states. -const ( - StatusUnknown = "unknown" - StatusPending = "pending" - StatusProcessing = "processing" - StatusValid = "valid" - StatusInvalid = "invalid" - StatusRevoked = "revoked" -) - -// Account is a user account. It is associated with a private key. -type Account struct { - // URI is the account unique ID, which is also a URL used to retrieve - // account data from the CA. - URI string - - // Contact is a slice of contact info used during registration. - Contact []string - - // The terms user has agreed to. - // Zero value indicates that the user hasn't agreed yet. - AgreedTerms string - - // Actual terms of a CA. - CurrentTerms string - - // Authz is the authorization URL used to initiate a new authz flow. - Authz string - - // Authorizations is a URI from which a list of authorizations - // granted to this account can be fetched via a GET request. - Authorizations string - - // Certificates is a URI from which a list of certificates - // issued for this account can be fetched via a GET request. - Certificates string -} - -// Directory is ACME server discovery data. -type Directory struct { - // RegURL is an account endpoint URL, allowing for creating new - // and modifying existing accounts. - RegURL string - - // AuthzURL is used to initiate Identifier Authorization flow. - AuthzURL string - - // CertURL is a new certificate issuance endpoint URL. - CertURL string - - // RevokeURL is used to initiate a certificate revocation flow. - RevokeURL string - - // Term is a URI identifying the current terms of service. - Terms string - - // Website is an HTTP or HTTPS URL locating a website - // providing more information about the ACME server. - Website string - - // CAA consists of lowercase hostname elements, which the ACME server - // recognises as referring to itself for the purposes of CAA record validation - // as defined in RFC6844. - CAA []string -} - -// Challenge encodes a returned CA challenge. -type Challenge struct { - // Type is the challenge type, e.g. "http-01", "tls-sni-02", "dns-01". - Type string - - // URI is where a challenge response can be posted to. - URI string - - // Token is a random value that uniquely identifies the challenge. - Token string - - // Status identifies the status of this challenge. - Status string -} - -// Authorization encodes an authorization response. -type Authorization struct { - // URI uniquely identifies a authorization. - URI string - - // Status identifies the status of an authorization. - Status string - - // Identifier is what the account is authorized to represent. - Identifier AuthzID - - // Challenges that the client needs to fulfill in order to prove possession - // of the identifier (for pending authorizations). - // For final authorizations, the challenges that were used. - Challenges []*Challenge - - // A collection of sets of challenges, each of which would be sufficient - // to prove possession of the identifier. - // Clients must complete a set of challenges that covers at least one set. - // Challenges are identified by their indices in the challenges array. - // If this field is empty, the client needs to complete all challenges. - Combinations [][]int -} - -// AuthzID is an identifier that an account is authorized to represent. -type AuthzID struct { - Type string // The type of identifier, e.g. "dns". - Value string // The identifier itself, e.g. "example.org". -} - -// Error is an ACME error, defined in Problem Details for HTTP APIs doc -// http://tools.ietf.org/html/draft-ietf-appsawg-http-problem. -type Error struct { - // StatusCode is The HTTP status code generated by the origin server. - StatusCode int - // ProblemType is a URI reference that identifies the problem type, - // typically in a "urn:acme:error:xxx" form. - ProblemType string - // Detail is a human-readable explanation specific to this occurrence of the problem. - Detail string - // Header is the original server error response headers. - Header http.Header -} - -func (e *Error) Error() string { - return fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail) -} - -// wireAuthz is ACME JSON representation of Authorization objects. -type wireAuthz struct { - Status string - Challenges []wireChallenge - Combinations [][]int - Identifier struct { - Type string - Value string - } -} - -func (z *wireAuthz) authorization(uri string) *Authorization { - a := &Authorization{ - URI: uri, - Status: z.Status, - Identifier: AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value}, - Combinations: z.Combinations, // shallow copy - Challenges: make([]*Challenge, len(z.Challenges)), - } - for i, v := range z.Challenges { - a.Challenges[i] = v.challenge() - } - return a -} - -// wireChallenge is ACME JSON challenge representation. -type wireChallenge struct { - URI string `json:"uri"` - Type string - Token string - Status string -} - -func (c *wireChallenge) challenge() *Challenge { - v := &Challenge{ - URI: c.URI, - Type: c.Type, - Token: c.Token, - Status: c.Status, - } - if v.Status == "" { - v.Status = StatusPending - } - return v -} -- cgit v1.2.3-1-g7c22