summaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/crypto/acme
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/crypto/acme')
-rw-r--r--vendor/golang.org/x/crypto/acme/acme.go4
-rw-r--r--vendor/golang.org/x/crypto/acme/autocert/autocert.go8
-rw-r--r--vendor/golang.org/x/crypto/acme/jws.go54
-rw-r--r--vendor/golang.org/x/crypto/acme/rfc8555.go30
-rw-r--r--vendor/golang.org/x/crypto/acme/types.go22
-rw-r--r--vendor/golang.org/x/crypto/acme/version_go112.go1
6 files changed, 104 insertions, 15 deletions
diff --git a/vendor/golang.org/x/crypto/acme/acme.go b/vendor/golang.org/x/crypto/acme/acme.go
index 6e6c9d13..174cfe8b 100644
--- a/vendor/golang.org/x/crypto/acme/acme.go
+++ b/vendor/golang.org/x/crypto/acme/acme.go
@@ -363,6 +363,10 @@ func AcceptTOS(tosURL string) bool { return true }
// Also see Error's Instance field for when a CA requires already registered accounts to agree
// to an updated Terms of Service.
func (c *Client) Register(ctx context.Context, acct *Account, prompt func(tosURL string) bool) (*Account, error) {
+ if c.Key == nil {
+ return nil, errors.New("acme: client.Key must be set to Register")
+ }
+
dir, err := c.Discover(ctx)
if err != nil {
return nil, err
diff --git a/vendor/golang.org/x/crypto/acme/autocert/autocert.go b/vendor/golang.org/x/crypto/acme/autocert/autocert.go
index 2ea9e231..c7fbc54c 100644
--- a/vendor/golang.org/x/crypto/acme/autocert/autocert.go
+++ b/vendor/golang.org/x/crypto/acme/autocert/autocert.go
@@ -1133,11 +1133,11 @@ func (s *certState) tlscert() (*tls.Certificate, error) {
}, nil
}
-// certRequest generates a CSR for the given common name cn and optional SANs.
-func certRequest(key crypto.Signer, cn string, ext []pkix.Extension, san ...string) ([]byte, error) {
+// certRequest generates a CSR for the given common name.
+func certRequest(key crypto.Signer, name string, ext []pkix.Extension) ([]byte, error) {
req := &x509.CertificateRequest{
- Subject: pkix.Name{CommonName: cn},
- DNSNames: san,
+ Subject: pkix.Name{CommonName: name},
+ DNSNames: []string{name},
ExtraExtensions: ext,
}
return x509.CreateCertificateRequest(rand.Reader, req, key)
diff --git a/vendor/golang.org/x/crypto/acme/jws.go b/vendor/golang.org/x/crypto/acme/jws.go
index 76e3fdac..8c3eccec 100644
--- a/vendor/golang.org/x/crypto/acme/jws.go
+++ b/vendor/golang.org/x/crypto/acme/jws.go
@@ -7,6 +7,7 @@ package acme
import (
"crypto"
"crypto/ecdsa"
+ "crypto/hmac"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
@@ -14,6 +15,7 @@ import (
"encoding/asn1"
"encoding/base64"
"encoding/json"
+ "errors"
"fmt"
"math/big"
)
@@ -31,6 +33,14 @@ const noKeyID = keyID("")
// See https://tools.ietf.org/html/rfc8555#section-6.3 for more details.
const noPayload = ""
+// jsonWebSignature can be easily serialized into a JWS following
+// https://tools.ietf.org/html/rfc7515#section-3.2.
+type jsonWebSignature struct {
+ Protected string `json:"protected"`
+ Payload string `json:"payload"`
+ Sig string `json:"signature"`
+}
+
// jwsEncodeJSON signs claimset using provided key and a nonce.
// The result is serialized in JSON format containing either kid or jwk
// fields based on the provided keyID value.
@@ -71,12 +81,7 @@ func jwsEncodeJSON(claimset interface{}, key crypto.Signer, kid keyID, nonce, ur
if err != nil {
return nil, err
}
-
- enc := struct {
- Protected string `json:"protected"`
- Payload string `json:"payload"`
- Sig string `json:"signature"`
- }{
+ enc := jsonWebSignature{
Protected: phead,
Payload: payload,
Sig: base64.RawURLEncoding.EncodeToString(sig),
@@ -84,6 +89,43 @@ func jwsEncodeJSON(claimset interface{}, key crypto.Signer, kid keyID, nonce, ur
return json.Marshal(&enc)
}
+// jwsWithMAC creates and signs a JWS using the given key and the HS256
+// algorithm. kid and url are included in the protected header. rawPayload
+// should not be base64-URL-encoded.
+func jwsWithMAC(key []byte, kid, url string, rawPayload []byte) (*jsonWebSignature, error) {
+ if len(key) == 0 {
+ return nil, errors.New("acme: cannot sign JWS with an empty MAC key")
+ }
+ header := struct {
+ Algorithm string `json:"alg"`
+ KID string `json:"kid"`
+ URL string `json:"url,omitempty"`
+ }{
+ // Only HMAC-SHA256 is supported.
+ Algorithm: "HS256",
+ KID: kid,
+ URL: url,
+ }
+ rawProtected, err := json.Marshal(header)
+ if err != nil {
+ return nil, err
+ }
+ protected := base64.RawURLEncoding.EncodeToString(rawProtected)
+ payload := base64.RawURLEncoding.EncodeToString(rawPayload)
+
+ h := hmac.New(sha256.New, key)
+ if _, err := h.Write([]byte(protected + "." + payload)); err != nil {
+ return nil, err
+ }
+ mac := h.Sum(nil)
+
+ return &jsonWebSignature{
+ Protected: protected,
+ Payload: payload,
+ Sig: base64.RawURLEncoding.EncodeToString(mac),
+ }, nil
+}
+
// jwkEncode encodes public part of an RSA or ECDSA key into a JWK.
// The result is also suitable for creating a JWK thumbprint.
// https://tools.ietf.org/html/rfc7517
diff --git a/vendor/golang.org/x/crypto/acme/rfc8555.go b/vendor/golang.org/x/crypto/acme/rfc8555.go
index dfb57a66..073cee58 100644
--- a/vendor/golang.org/x/crypto/acme/rfc8555.go
+++ b/vendor/golang.org/x/crypto/acme/rfc8555.go
@@ -37,22 +37,32 @@ func (c *Client) DeactivateReg(ctx context.Context) error {
return nil
}
-// registerRFC is quivalent to c.Register but for CAs implementing RFC 8555.
+// registerRFC is equivalent to c.Register but for CAs implementing RFC 8555.
// It expects c.Discover to have already been called.
-// TODO: Implement externalAccountBinding.
func (c *Client) registerRFC(ctx context.Context, acct *Account, prompt func(tosURL string) bool) (*Account, error) {
c.cacheMu.Lock() // guard c.kid access
defer c.cacheMu.Unlock()
req := struct {
- TermsAgreed bool `json:"termsOfServiceAgreed,omitempty"`
- Contact []string `json:"contact,omitempty"`
+ TermsAgreed bool `json:"termsOfServiceAgreed,omitempty"`
+ Contact []string `json:"contact,omitempty"`
+ ExternalAccountBinding *jsonWebSignature `json:"externalAccountBinding,omitempty"`
}{
Contact: acct.Contact,
}
if c.dir.Terms != "" {
req.TermsAgreed = prompt(c.dir.Terms)
}
+
+ // set 'externalAccountBinding' field if requested
+ if acct.ExternalAccountBinding != nil {
+ eabJWS, err := c.encodeExternalAccountBinding(acct.ExternalAccountBinding)
+ if err != nil {
+ return nil, fmt.Errorf("acme: failed to encode external account binding: %v", err)
+ }
+ req.ExternalAccountBinding = eabJWS
+ }
+
res, err := c.post(ctx, c.Key, c.dir.RegURL, req, wantStatus(
http.StatusOK, // account with this key already registered
http.StatusCreated, // new account created
@@ -75,7 +85,17 @@ func (c *Client) registerRFC(ctx context.Context, acct *Account, prompt func(tos
return a, nil
}
-// updateGegRFC is equivalent to c.UpdateReg but for CAs implementing RFC 8555.
+// encodeExternalAccountBinding will encode an external account binding stanza
+// as described in https://tools.ietf.org/html/rfc8555#section-7.3.4.
+func (c *Client) encodeExternalAccountBinding(eab *ExternalAccountBinding) (*jsonWebSignature, error) {
+ jwk, err := jwkEncode(c.Key.Public())
+ if err != nil {
+ return nil, err
+ }
+ return jwsWithMAC(eab.Key, eab.KID, c.dir.RegURL, []byte(jwk))
+}
+
+// updateRegRFC is equivalent to c.UpdateReg but for CAs implementing RFC 8555.
// It expects c.Discover to have already been called.
func (c *Client) updateRegRFC(ctx context.Context, a *Account) (*Account, error) {
url := string(c.accountKID(ctx))
diff --git a/vendor/golang.org/x/crypto/acme/types.go b/vendor/golang.org/x/crypto/acme/types.go
index e959cafc..e751bf52 100644
--- a/vendor/golang.org/x/crypto/acme/types.go
+++ b/vendor/golang.org/x/crypto/acme/types.go
@@ -199,6 +199,28 @@ type Account struct {
//
// It is non-RFC 8555 compliant and is obsoleted by OrdersURL.
Certificates string
+
+ // ExternalAccountBinding represents an arbitrary binding to an account of
+ // the CA which the ACME server is tied to.
+ // See https://tools.ietf.org/html/rfc8555#section-7.3.4 for more details.
+ ExternalAccountBinding *ExternalAccountBinding
+}
+
+// ExternalAccountBinding contains the data needed to form a request with
+// an external account binding.
+// See https://tools.ietf.org/html/rfc8555#section-7.3.4 for more details.
+type ExternalAccountBinding struct {
+ // KID is the Key ID of the symmetric MAC key that the CA provides to
+ // identify an external account from ACME.
+ KID string
+
+ // Key is the bytes of the symmetric key that the CA provides to identify
+ // the account. Key must correspond to the KID.
+ Key []byte
+}
+
+func (e *ExternalAccountBinding) String() string {
+ return fmt.Sprintf("&{KID: %q, Key: redacted}", e.KID)
}
// Directory is ACME server discovery data.
diff --git a/vendor/golang.org/x/crypto/acme/version_go112.go b/vendor/golang.org/x/crypto/acme/version_go112.go
index b58f2456..b9efdb59 100644
--- a/vendor/golang.org/x/crypto/acme/version_go112.go
+++ b/vendor/golang.org/x/crypto/acme/version_go112.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build go1.12
// +build go1.12
package acme