From be16524403dd66e920cf69653affe6d77320ff57 Mon Sep 17 00:00:00 2001
From: ale <ale@incal.net>
Date: Mon, 11 Nov 2019 21:10:18 +0000
Subject: [PATCH] Update ACME client library

---
 vendor/golang.org/x/crypto/acme/acme.go       | 363 +++++++++++-----
 vendor/golang.org/x/crypto/acme/http.go       |  46 +-
 vendor/golang.org/x/crypto/acme/jws.go        |  79 ++--
 vendor/golang.org/x/crypto/acme/rfc8555.go    | 392 ++++++++++++++++++
 vendor/golang.org/x/crypto/acme/types.go      | 307 ++++++++++++--
 .../golang.org/x/crypto/acme/version_go112.go |  27 ++
 vendor/vendor.json                            |   6 +-
 7 files changed, 1052 insertions(+), 168 deletions(-)
 create mode 100644 vendor/golang.org/x/crypto/acme/rfc8555.go
 create mode 100644 vendor/golang.org/x/crypto/acme/version_go112.go

diff --git a/vendor/golang.org/x/crypto/acme/acme.go b/vendor/golang.org/x/crypto/acme/acme.go
index 7df64764..02fde12d 100644
--- a/vendor/golang.org/x/crypto/acme/acme.go
+++ b/vendor/golang.org/x/crypto/acme/acme.go
@@ -4,7 +4,10 @@
 
 // Package acme provides an implementation of the
 // Automatic Certificate Management Environment (ACME) spec.
-// See https://tools.ietf.org/html/draft-ietf-acme-acme-02 for details.
+// The intial implementation was based on ACME draft-02 and
+// is now being extended to comply with RFC 8555.
+// See https://tools.ietf.org/html/draft-ietf-acme-acme-02
+// and https://tools.ietf.org/html/rfc8555 for details.
 //
 // Most common scenarios will want to use autocert subdirectory instead,
 // which provides automatic access to certificates from Let's Encrypt
@@ -41,7 +44,7 @@ import (
 
 const (
 	// LetsEncryptURL is the Directory endpoint of Let's Encrypt CA.
-	LetsEncryptURL = "https://acme-v01.api.letsencrypt.org/directory"
+	LetsEncryptURL = "https://acme-v02.api.letsencrypt.org/directory"
 
 	// ALPNProto is the ALPN protocol name used by a CA server when validating
 	// tls-alpn-01 challenges.
@@ -57,7 +60,10 @@ var idPeACMEIdentifierV1 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 30, 1}
 
 const (
 	maxChainLen = 5       // max depth and breadth of a certificate chain
-	maxCertSize = 1 << 20 // max size of a certificate, in bytes
+	maxCertSize = 1 << 20 // max size of a certificate, in DER bytes
+	// Used for decoding certs from application/pem-certificate-chain response,
+	// the default when in RFC mode.
+	maxCertChainSize = maxCertSize * maxChainLen
 
 	// Max number of collected nonces kept in memory.
 	// Expect usual peak of 1 or 2.
@@ -77,6 +83,10 @@ const (
 type Client struct {
 	// Key is the account key used to register with a CA and sign requests.
 	// Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey.
+	//
+	// The following algorithms are supported:
+	// RS256, ES256, ES384 and ES512.
+	// See RFC7518 for more details about the algorithms.
 	Key crypto.Signer
 
 	// HTTPClient optionally specifies an HTTP client to use
@@ -105,30 +115,60 @@ type Client struct {
 	// The jitter is a random value up to 1 second.
 	RetryBackoff func(n int, r *http.Request, resp *http.Response) time.Duration
 
-	dirMu sync.Mutex // guards writes to dir
-	dir   *Directory // cached result of Client's Discover method
+	// UserAgent is prepended to the User-Agent header sent to the ACME server,
+	// which by default is this package's name and version.
+	//
+	// Reusable libraries and tools in particular should set this value to be
+	// identifiable by the server, in case they are causing issues.
+	UserAgent string
+
+	cacheMu sync.Mutex
+	dir     *Directory // cached result of Client's Discover method
+	kid     keyID      // cached Account.URI obtained from registerRFC or getAccountRFC
 
 	noncesMu sync.Mutex
 	nonces   map[string]struct{} // nonces collected from previous responses
 }
 
+// accountKID returns a key ID associated with c.Key, the account identity
+// provided by the CA during RFC based registration.
+// It assumes c.Discover has already been called.
+//
+// accountKID requires at most one network roundtrip.
+// It caches only successful result.
+//
+// When in pre-RFC mode or when c.getRegRFC responds with an error, accountKID
+// returns noKeyID.
+func (c *Client) accountKID(ctx context.Context) keyID {
+	c.cacheMu.Lock()
+	defer c.cacheMu.Unlock()
+	if !c.dir.rfcCompliant() {
+		return noKeyID
+	}
+	if c.kid != noKeyID {
+		return c.kid
+	}
+	a, err := c.getRegRFC(ctx)
+	if err != nil {
+		return noKeyID
+	}
+	c.kid = keyID(a.URI)
+	return c.kid
+}
+
 // Discover performs ACME server discovery using c.DirectoryURL.
 //
 // It caches successful result. So, subsequent calls will not result in
 // a network round-trip. This also means mutating c.DirectoryURL after successful call
 // of this method will have no effect.
 func (c *Client) Discover(ctx context.Context) (Directory, error) {
-	c.dirMu.Lock()
-	defer c.dirMu.Unlock()
+	c.cacheMu.Lock()
+	defer c.cacheMu.Unlock()
 	if c.dir != nil {
 		return *c.dir, nil
 	}
 
-	dirURL := c.DirectoryURL
-	if dirURL == "" {
-		dirURL = LetsEncryptURL
-	}
-	res, err := c.get(ctx, dirURL, wantStatus(http.StatusOK))
+	res, err := c.get(ctx, c.directoryURL(), wantStatus(http.StatusOK))
 	if err != nil {
 		return Directory{}, err
 	}
@@ -136,32 +176,68 @@ func (c *Client) Discover(ctx context.Context) (Directory, error) {
 	c.addNonce(res.Header)
 
 	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"`
+		Reg          string `json:"new-reg"`
+		RegRFC       string `json:"newAccount"`
+		Authz        string `json:"new-authz"`
+		AuthzRFC     string `json:"newAuthz"`
+		OrderRFC     string `json:"newOrder"`
+		Cert         string `json:"new-cert"`
+		Revoke       string `json:"revoke-cert"`
+		RevokeRFC    string `json:"revokeCert"`
+		NonceRFC     string `json:"newNonce"`
+		KeyChangeRFC string `json:"keyChange"`
+		Meta         struct {
+			Terms           string   `json:"terms-of-service"`
+			TermsRFC        string   `json:"termsOfService"`
+			WebsiteRFC      string   `json:"website"`
+			CAA             []string `json:"caa-identities"`
+			CAARFC          []string `json:"caaIdentities"`
+			ExternalAcctRFC bool     `json:"externalAccountRequired"`
 		}
 	}
 	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
 		return Directory{}, err
 	}
+	if v.OrderRFC == "" {
+		// Non-RFC compliant ACME CA.
+		c.dir = &Directory{
+			RegURL:    v.Reg,
+			AuthzURL:  v.Authz,
+			CertURL:   v.Cert,
+			RevokeURL: v.Revoke,
+			Terms:     v.Meta.Terms,
+			Website:   v.Meta.WebsiteRFC,
+			CAA:       v.Meta.CAA,
+		}
+		return *c.dir, nil
+	}
+	// RFC compliant ACME CA.
 	c.dir = &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,
+		RegURL:                  v.RegRFC,
+		AuthzURL:                v.AuthzRFC,
+		OrderURL:                v.OrderRFC,
+		RevokeURL:               v.RevokeRFC,
+		NonceURL:                v.NonceRFC,
+		KeyChangeURL:            v.KeyChangeRFC,
+		Terms:                   v.Meta.TermsRFC,
+		Website:                 v.Meta.WebsiteRFC,
+		CAA:                     v.Meta.CAARFC,
+		ExternalAccountRequired: v.Meta.ExternalAcctRFC,
 	}
 	return *c.dir, nil
 }
 
+func (c *Client) directoryURL() string {
+	if c.DirectoryURL != "" {
+		return c.DirectoryURL
+	}
+	return LetsEncryptURL
+}
+
 // CreateCert requests a new certificate using the Certificate Signing Request csr encoded in DER format.
+// It is incompatible with RFC 8555. Callers should use CreateOrderCert when interfacing
+// with an RFC-compliant CA.
+//
 // The exp argument indicates the desired certificate validity duration. CA may issue a certificate
 // with a different duration.
 // If the bundle argument is true, the returned value will also contain the CA (issuer) certificate chain.
@@ -192,7 +268,7 @@ func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration,
 		req.NotAfter = now.Add(exp).Format(time.RFC3339)
 	}
 
-	res, err := c.post(ctx, c.Key, c.dir.CertURL, req, wantStatus(http.StatusCreated))
+	res, err := c.post(ctx, nil, c.dir.CertURL, req, wantStatus(http.StatusCreated))
 	if err != nil {
 		return nil, "", err
 	}
@@ -213,12 +289,22 @@ func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration,
 // 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 the CA (issuer) certificate if the bundle argument is true.
+// If the bundle argument is true, the returned value also contains the CA (issuer)
+// certificate chain.
 //
 // FetchCert returns an error if the CA's response or chain was unreasonably large.
 // Callers are encouraged to parse the returned value to ensure the certificate is valid
 // and has expected features.
 func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) {
+	dir, err := c.Discover(ctx)
+	if err != nil {
+		return nil, err
+	}
+	if dir.rfcCompliant() {
+		return c.fetchCertRFC(ctx, url, bundle)
+	}
+
+	// Legacy non-authenticated GET request.
 	res, err := c.get(ctx, url, wantStatus(http.StatusOK))
 	if err != nil {
 		return nil, err
@@ -233,10 +319,15 @@ func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]by
 // For instance, the key pair of the certificate may be authorized.
 // If the key is nil, c.Key is used instead.
 func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error {
-	if _, err := c.Discover(ctx); err != nil {
+	dir, err := c.Discover(ctx)
+	if err != nil {
 		return err
 	}
+	if dir.rfcCompliant() {
+		return c.revokeCertRFC(ctx, key, cert, reason)
+	}
 
+	// Legacy CA.
 	body := &struct {
 		Resource string `json:"resource"`
 		Cert     string `json:"certificate"`
@@ -246,10 +337,7 @@ func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte,
 		Cert:     base64.RawURLEncoding.EncodeToString(cert),
 		Reason:   int(reason),
 	}
-	if key == nil {
-		key = c.Key
-	}
-	res, err := c.post(ctx, key, c.dir.RevokeURL, body, wantStatus(http.StatusOK))
+	res, err := c.post(ctx, key, dir.RevokeURL, body, wantStatus(http.StatusOK))
 	if err != nil {
 		return err
 	}
@@ -261,20 +349,30 @@ func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte,
 // during account registration. See Register method of Client for more details.
 func AcceptTOS(tosURL string) bool { return true }
 
-// Register creates a new account registration by following the "new-reg" flow.
-// It returns the registered account. The account is not modified.
+// Register creates a new account with the CA using c.Key.
+// It returns the registered account. The account acct is not modified.
 //
 // The registration may require the caller to agree to the CA's Terms of Service (TOS).
 // If so, and the account has not indicated the acceptance of the terms (see Account for details),
 // Register calls prompt with a TOS URL provided by the CA. Prompt should report
 // whether the caller agrees to the terms. To always accept the terms, the caller can use AcceptTOS.
-func (c *Client) Register(ctx context.Context, a *Account, prompt func(tosURL string) bool) (*Account, error) {
-	if _, err := c.Discover(ctx); err != nil {
+//
+// When interfacing with an RFC-compliant CA, non-RFC 8555 fields of acct are ignored
+// and prompt is called if Directory's Terms field is non-zero.
+// 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) {
+	dir, err := c.Discover(ctx)
+	if err != nil {
 		return nil, err
 	}
+	if dir.rfcCompliant() {
+		return c.registerRFC(ctx, acct, prompt)
+	}
 
-	var err error
-	if a, err = c.doReg(ctx, c.dir.RegURL, "new-reg", a); err != nil {
+	// Legacy ACME draft registration flow.
+	a, err := c.doReg(ctx, dir.RegURL, "new-reg", acct)
+	if err != nil {
 		return nil, err
 	}
 	var accept bool
@@ -288,9 +386,20 @@ func (c *Client) Register(ctx context.Context, a *Account, prompt func(tosURL st
 	return a, err
 }
 
-// GetReg retrieves an existing registration.
-// The url argument is an Account URI.
+// GetReg retrieves an existing account associated with c.Key.
+//
+// The url argument is an Account URI used with pre-RFC 8555 CAs.
+// It is ignored when interfacing with an RFC-compliant CA.
 func (c *Client) GetReg(ctx context.Context, url string) (*Account, error) {
+	dir, err := c.Discover(ctx)
+	if err != nil {
+		return nil, err
+	}
+	if dir.rfcCompliant() {
+		return c.getRegRFC(ctx)
+	}
+
+	// Legacy CA.
 	a, err := c.doReg(ctx, url, "reg", nil)
 	if err != nil {
 		return nil, err
@@ -301,9 +410,21 @@ func (c *Client) GetReg(ctx context.Context, url string) (*Account, error) {
 
 // UpdateReg updates an existing registration.
 // It returns an updated account copy. The provided account is not modified.
-func (c *Client) UpdateReg(ctx context.Context, a *Account) (*Account, error) {
-	uri := a.URI
-	a, err := c.doReg(ctx, uri, "reg", a)
+//
+// When interfacing with RFC-compliant CAs, a.URI is ignored and the account URL
+// associated with c.Key is used instead.
+func (c *Client) UpdateReg(ctx context.Context, acct *Account) (*Account, error) {
+	dir, err := c.Discover(ctx)
+	if err != nil {
+		return nil, err
+	}
+	if dir.rfcCompliant() {
+		return c.updateRegRFC(ctx, acct)
+	}
+
+	// Legacy CA.
+	uri := acct.URI
+	a, err := c.doReg(ctx, uri, "reg", acct)
 	if err != nil {
 		return nil, err
 	}
@@ -311,14 +432,36 @@ func (c *Client) UpdateReg(ctx context.Context, a *Account) (*Account, error) {
 	return a, nil
 }
 
-// Authorize performs the initial step in an authorization flow.
+// Authorize performs the initial step in the pre-authorization flow,
+// as opposed to order-based 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.
 //
+// Once complete, the caller can use AuthorizeOrder which the CA
+// should provision with the already satisfied authorization.
+// For pre-RFC CAs, the caller can proceed directly to requesting a certificate
+// using CreateCert method.
+//
 // If an authorization has been previously granted, the CA may return
-// a valid authorization (Authorization.Status is StatusValid). If so, the caller
-// need not fulfill any challenge and can proceed to requesting a certificate.
+// a valid authorization which has its Status field set to StatusValid.
+//
+// More about pre-authorization can be found at
+// https://tools.ietf.org/html/rfc8555#section-7.4.1.
 func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization, error) {
+	return c.authorize(ctx, "dns", domain)
+}
+
+// AuthorizeIP is the same as Authorize but requests IP address authorization.
+// Clients which successfully obtain such authorization may request to issue
+// a certificate for IP addresses.
+//
+// See the ACME spec extension for more details about IP address identifiers:
+// https://tools.ietf.org/html/draft-ietf-acme-ip.
+func (c *Client) AuthorizeIP(ctx context.Context, ipaddr string) (*Authorization, error) {
+	return c.authorize(ctx, "ip", ipaddr)
+}
+
+func (c *Client) authorize(ctx context.Context, typ, val string) (*Authorization, error) {
 	if _, err := c.Discover(ctx); err != nil {
 		return nil, err
 	}
@@ -332,9 +475,9 @@ func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization,
 		Identifier authzID `json:"identifier"`
 	}{
 		Resource:   "new-authz",
-		Identifier: authzID{Type: "dns", Value: domain},
+		Identifier: authzID{Type: typ, Value: val},
 	}
-	res, err := c.post(ctx, c.Key, c.dir.AuthzURL, req, wantStatus(http.StatusCreated))
+	res, err := c.post(ctx, nil, c.dir.AuthzURL, req, wantStatus(http.StatusCreated))
 	if err != nil {
 		return nil, err
 	}
@@ -355,7 +498,17 @@ func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization,
 // If a caller needs to poll an authorization until its status is final,
 // see the WaitAuthorization method.
 func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error) {
-	res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
+	dir, err := c.Discover(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	var res *http.Response
+	if dir.rfcCompliant() {
+		res, err = c.postAsGet(ctx, url, wantStatus(http.StatusOK))
+	} else {
+		res, err = c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
+	}
 	if err != nil {
 		return nil, err
 	}
@@ -372,11 +525,16 @@ func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorizati
 // The url argument is an Authorization.URI value.
 //
 // If successful, the caller will be required to obtain a new authorization
-// using the Authorize method before being able to request a new certificate
-// for the domain associated with the authorization.
+// using the Authorize or AuthorizeOrder methods before being able to request
+// a new certificate for the domain associated with the authorization.
 //
 // It does not revoke existing certificates.
 func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
+	// Required for c.accountKID() when in RFC mode.
+	if _, err := c.Discover(ctx); err != nil {
+		return err
+	}
+
 	req := struct {
 		Resource string `json:"resource"`
 		Status   string `json:"status"`
@@ -386,7 +544,7 @@ func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
 		Status:   "deactivated",
 		Delete:   true,
 	}
-	res, err := c.post(ctx, c.Key, url, req, wantStatus(http.StatusOK))
+	res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))
 	if err != nil {
 		return err
 	}
@@ -402,8 +560,18 @@ func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
 // In all other cases WaitAuthorization returns an error.
 // If the Status is StatusInvalid, the returned error is of type *AuthorizationError.
 func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error) {
+	// Required for c.accountKID() when in RFC mode.
+	dir, err := c.Discover(ctx)
+	if err != nil {
+		return nil, err
+	}
+	getfn := c.postAsGet
+	if !dir.rfcCompliant() {
+		getfn = c.get
+	}
+
 	for {
-		res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
+		res, err := getfn(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
 		if err != nil {
 			return nil, err
 		}
@@ -446,10 +614,21 @@ func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorizat
 //
 // A client typically polls a challenge status using this method.
 func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) {
-	res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
+	// Required for c.accountKID() when in RFC mode.
+	dir, err := c.Discover(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	getfn := c.postAsGet
+	if !dir.rfcCompliant() {
+		getfn = c.get
+	}
+	res, err := getfn(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
 	if err != nil {
 		return nil, err
 	}
+
 	defer res.Body.Close()
 	v := wireChallenge{URI: url}
 	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
@@ -463,21 +642,29 @@ func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, erro
 //
 // The server will then perform the validation asynchronously.
 func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error) {
-	auth, err := keyAuth(c.Key.Public(), chal.Token)
+	// Required for c.accountKID() when in RFC mode.
+	dir, err := c.Discover(ctx)
 	if err != nil {
 		return nil, err
 	}
 
-	req := struct {
-		Resource string `json:"resource"`
-		Type     string `json:"type"`
-		Auth     string `json:"keyAuthorization"`
-	}{
-		Resource: "challenge",
-		Type:     chal.Type,
-		Auth:     auth,
+	var req interface{} = json.RawMessage("{}") // RFC-compliant CA
+	if !dir.rfcCompliant() {
+		auth, err := keyAuth(c.Key.Public(), chal.Token)
+		if err != nil {
+			return nil, err
+		}
+		req = struct {
+			Resource string `json:"resource"`
+			Type     string `json:"type"`
+			Auth     string `json:"keyAuthorization"`
+		}{
+			Resource: "challenge",
+			Type:     chal.Type,
+			Auth:     auth,
+		}
 	}
-	res, err := c.post(ctx, c.Key, chal.URI, req, wantStatus(
+	res, err := c.post(ctx, nil, chal.URI, req, wantStatus(
 		http.StatusOK,       // according to the spec
 		http.StatusAccepted, // Let's Encrypt: see https://goo.gl/WsJ7VT (acme-divergences.md)
 	))
@@ -527,21 +714,8 @@ func (c *Client) HTTP01ChallengePath(token string) string {
 }
 
 // TLSSNI01ChallengeCert creates a certificate for TLS-SNI-01 challenge response.
-// Servers can present the certificate to validate the challenge and prove control
-// over a domain name.
-//
-// The implementation is incomplete in that the returned value is a single certificate,
-// computed only for Z0 of the key authorization. ACME CAs are expected to update
-// their implementations to use the newer version, TLS-SNI-02.
-// For more details on TLS-SNI-01 see https://tools.ietf.org/html/draft-ietf-acme-acme-01#section-7.3.
-//
-// The token argument is a Challenge.Token value.
-// If a WithKey option is provided, its private part signs the returned cert,
-// and the public part is used to specify the signee.
-// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
 //
-// The returned certificate is valid for the next 24 hours and must be presented only when
-// the server name of the TLS ClientHello matches exactly the returned name value.
+// Deprecated: This challenge type is unused in both draft-02 and RFC versions of ACME spec.
 func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
 	ka, err := keyAuth(c.Key.Public(), token)
 	if err != nil {
@@ -558,17 +732,8 @@ func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tl
 }
 
 // TLSSNI02ChallengeCert creates a certificate for TLS-SNI-02 challenge response.
-// Servers can present the certificate to validate the challenge and prove control
-// over a domain name. For more details on TLS-SNI-02 see
-// https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-7.3.
-//
-// The token argument is a Challenge.Token value.
-// If a WithKey option is provided, its private part signs the returned cert,
-// and the public part is used to specify the signee.
-// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
 //
-// The returned certificate is valid for the next 24 hours and must be presented only when
-// the server name in the TLS ClientHello matches exactly the returned name value.
+// Deprecated: This challenge type is unused in both draft-02 and RFC versions of ACME spec.
 func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
 	b := sha256.Sum256([]byte(token))
 	h := hex.EncodeToString(b[:])
@@ -635,7 +800,7 @@ func (c *Client) TLSALPN01ChallengeCert(token, domain string, opt ...CertOption)
 	return tlsChallengeCert([]string{domain}, newOpt)
 }
 
-// doReg sends all types of registration requests.
+// doReg sends all types of registration requests the old way (pre-RFC world).
 // The type of request is identified by typ argument, which is a "resource"
 // in the ACME spec terms.
 //
@@ -654,7 +819,7 @@ func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Accoun
 		req.Contact = acct.Contact
 		req.Agreement = acct.AgreedTerms
 	}
-	res, err := c.post(ctx, c.Key, url, req, wantStatus(
+	res, err := c.post(ctx, nil, url, req, wantStatus(
 		http.StatusOK,       // updates and deletes
 		http.StatusCreated,  // new account creation
 		http.StatusAccepted, // Let's Encrypt divergent implementation
@@ -693,12 +858,22 @@ func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Accoun
 }
 
 // popNonce returns a nonce value previously stored with c.addNonce
-// or fetches a fresh one from the given URL.
+// or fetches a fresh one from c.dir.NonceURL.
+// If NonceURL is empty, it first tries c.directoryURL() and, failing that,
+// the provided url.
 func (c *Client) popNonce(ctx context.Context, url string) (string, error) {
 	c.noncesMu.Lock()
 	defer c.noncesMu.Unlock()
 	if len(c.nonces) == 0 {
-		return c.fetchNonce(ctx, url)
+		if c.dir != nil && c.dir.NonceURL != "" {
+			return c.fetchNonce(ctx, c.dir.NonceURL)
+		}
+		dirURL := c.directoryURL()
+		v, err := c.fetchNonce(ctx, dirURL)
+		if err != nil && url != dirURL {
+			v, err = c.fetchNonce(ctx, url)
+		}
+		return v, err
 	}
 	var nonce string
 	for nonce = range c.nonces {
diff --git a/vendor/golang.org/x/crypto/acme/http.go b/vendor/golang.org/x/crypto/acme/http.go
index a43ce6a5..c51943e7 100644
--- a/vendor/golang.org/x/crypto/acme/http.go
+++ b/vendor/golang.org/x/crypto/acme/http.go
@@ -155,8 +155,16 @@ func (c *Client) get(ctx context.Context, url string, ok resOkay) (*http.Respons
 	}
 }
 
+// postAsGet is POST-as-GET, a replacement for GET in RFC8555
+// as described in https://tools.ietf.org/html/rfc8555#section-6.3.
+// It makes a POST request in KID form with zero JWS payload.
+// See nopayload doc comments in jws.go.
+func (c *Client) postAsGet(ctx context.Context, url string, ok resOkay) (*http.Response, error) {
+	return c.post(ctx, nil, url, noPayload, ok)
+}
+
 // post issues a signed POST request in JWS format using the provided key
-// to the specified URL.
+// to the specified URL. If key is nil, c.Key is used instead.
 // It returns a non-error value only when ok reports true.
 //
 // post retries unsuccessful attempts according to c.RetryBackoff
@@ -193,14 +201,28 @@ func (c *Client) post(ctx context.Context, key crypto.Signer, url string, body i
 }
 
 // postNoRetry signs the body with the given key and POSTs it to the provided url.
-// The body argument must be JSON-serializable.
 // It is used by c.post to retry unsuccessful attempts.
+// The body argument must be JSON-serializable.
+//
+// If key argument is nil, c.Key is used to sign the request.
+// If key argument is nil and c.accountKID returns a non-zero keyID,
+// the request is sent in KID form. Otherwise, JWK form is used.
+//
+// In practice, when interfacing with RFC-compliant CAs most requests are sent in KID form
+// and JWK is used only when KID is unavailable: new account endpoint and certificate
+// revocation requests authenticated by a cert key.
+// See jwsEncodeJSON for other details.
 func (c *Client) postNoRetry(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, *http.Request, error) {
+	kid := noKeyID
+	if key == nil {
+		key = c.Key
+		kid = c.accountKID(ctx)
+	}
 	nonce, err := c.popNonce(ctx, url)
 	if err != nil {
 		return nil, nil, err
 	}
-	b, err := jwsEncodeJSON(body, key, nonce)
+	b, err := jwsEncodeJSON(body, key, kid, nonce, url)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -219,6 +241,7 @@ func (c *Client) postNoRetry(ctx context.Context, key crypto.Signer, url string,
 
 // doNoRetry issues a request req, replacing its context (if any) with ctx.
 func (c *Client) doNoRetry(ctx context.Context, req *http.Request) (*http.Response, error) {
+	req.Header.Set("User-Agent", c.userAgent())
 	res, err := c.httpClient().Do(req.WithContext(ctx))
 	if err != nil {
 		select {
@@ -243,6 +266,23 @@ func (c *Client) httpClient() *http.Client {
 	return http.DefaultClient
 }
 
+// packageVersion is the version of the module that contains this package, for
+// sending as part of the User-Agent header. It's set in version_go112.go.
+var packageVersion string
+
+// userAgent returns the User-Agent header value. It includes the package name,
+// the module version (if available), and the c.UserAgent value (if set).
+func (c *Client) userAgent() string {
+	ua := "golang.org/x/crypto/acme"
+	if packageVersion != "" {
+		ua += "@" + packageVersion
+	}
+	if c.UserAgent != "" {
+		ua = c.UserAgent + " " + ua
+	}
+	return ua
+}
+
 // isBadNonce reports whether err is an ACME "badnonce" error.
 func isBadNonce(err error) bool {
 	// According to the spec badNonce is urn:ietf:params:acme:error:badNonce.
diff --git a/vendor/golang.org/x/crypto/acme/jws.go b/vendor/golang.org/x/crypto/acme/jws.go
index 6cbca25d..cac8b678 100644
--- a/vendor/golang.org/x/crypto/acme/jws.go
+++ b/vendor/golang.org/x/crypto/acme/jws.go
@@ -17,25 +17,53 @@ import (
 	"math/big"
 )
 
+// keyID is the account identity provided by a CA during registration.
+type keyID string
+
+// noKeyID indicates that jwsEncodeJSON should compute and use JWK instead of a KID.
+// See jwsEncodeJSON for details.
+const noKeyID = keyID("")
+
+// noPayload indicates jwsEncodeJSON will encode zero-length octet string
+// in a JWS request. This is called POST-as-GET in RFC 8555 and is used to make
+// authenticated GET requests via POSTing with an empty payload.
+// See https://tools.ietf.org/html/rfc8555#section-6.3 for more details.
+const noPayload = ""
+
 // jwsEncodeJSON signs claimset using provided key and a nonce.
-// The result is serialized in JSON format.
+// The result is serialized in JSON format containing either kid or jwk
+// fields based on the provided keyID value.
+//
+// If kid is non-empty, its quoted value is inserted in the protected head
+// as "kid" field value. Otherwise, JWK is computed using jwkEncode and inserted
+// as "jwk" field value. The "jwk" and "kid" fields are mutually exclusive.
+//
 // See https://tools.ietf.org/html/rfc7515#section-7.
-func jwsEncodeJSON(claimset interface{}, key crypto.Signer, nonce string) ([]byte, error) {
-	jwk, err := jwkEncode(key.Public())
-	if err != nil {
-		return nil, err
-	}
-	alg, sha := jwsHasher(key)
+func jwsEncodeJSON(claimset interface{}, key crypto.Signer, kid keyID, nonce, url string) ([]byte, error) {
+	alg, sha := jwsHasher(key.Public())
 	if alg == "" || !sha.Available() {
 		return nil, ErrUnsupportedKey
 	}
-	phead := fmt.Sprintf(`{"alg":%q,"jwk":%s,"nonce":%q}`, alg, jwk, nonce)
+	var phead string
+	switch kid {
+	case noKeyID:
+		jwk, err := jwkEncode(key.Public())
+		if err != nil {
+			return nil, err
+		}
+		phead = fmt.Sprintf(`{"alg":%q,"jwk":%s,"nonce":%q,"url":%q}`, alg, jwk, nonce, url)
+	default:
+		phead = fmt.Sprintf(`{"alg":%q,"kid":%q,"nonce":%q,"url":%q}`, alg, kid, nonce, url)
+	}
 	phead = base64.RawURLEncoding.EncodeToString([]byte(phead))
-	cs, err := json.Marshal(claimset)
-	if err != nil {
-		return nil, err
+	var payload string
+	if claimset != noPayload {
+		cs, err := json.Marshal(claimset)
+		if err != nil {
+			return nil, err
+		}
+		payload = base64.RawURLEncoding.EncodeToString(cs)
 	}
-	payload := base64.RawURLEncoding.EncodeToString(cs)
 	hash := sha.New()
 	hash.Write([]byte(phead + "." + payload))
 	sig, err := jwsSign(key, sha, hash.Sum(nil))
@@ -97,13 +125,16 @@ func jwkEncode(pub crypto.PublicKey) (string, error) {
 }
 
 // jwsSign signs the digest using the given key.
-// It returns ErrUnsupportedKey if the key type is unknown.
-// The hash is used only for RSA keys.
+// The hash is unused for ECDSA keys.
+//
+// Note: non-stdlib crypto.Signer implementations are expected to return
+// the signature in the format as specified in RFC7518.
+// See https://tools.ietf.org/html/rfc7518 for more details.
 func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) {
-	switch key := key.(type) {
-	case *rsa.PrivateKey:
-		return key.Sign(rand.Reader, digest, hash)
-	case *ecdsa.PrivateKey:
+	if key, ok := key.(*ecdsa.PrivateKey); ok {
+		// The key.Sign method of ecdsa returns ASN1-encoded signature.
+		// So, we use the package Sign function instead
+		// to get R and S values directly and format the result accordingly.
 		r, s, err := ecdsa.Sign(rand.Reader, key, digest)
 		if err != nil {
 			return nil, err
@@ -118,18 +149,18 @@ func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error)
 		copy(sig[size*2-len(sb):], sb)
 		return sig, nil
 	}
-	return nil, ErrUnsupportedKey
+	return key.Sign(rand.Reader, digest, hash)
 }
 
 // jwsHasher indicates suitable JWS algorithm name and a hash function
 // to use for signing a digest with the provided key.
 // It returns ("", 0) if the key is not supported.
-func jwsHasher(key crypto.Signer) (string, crypto.Hash) {
-	switch key := key.(type) {
-	case *rsa.PrivateKey:
+func jwsHasher(pub crypto.PublicKey) (string, crypto.Hash) {
+	switch pub := pub.(type) {
+	case *rsa.PublicKey:
 		return "RS256", crypto.SHA256
-	case *ecdsa.PrivateKey:
-		switch key.Params().Name {
+	case *ecdsa.PublicKey:
+		switch pub.Params().Name {
 		case "P-256":
 			return "ES256", crypto.SHA256
 		case "P-384":
diff --git a/vendor/golang.org/x/crypto/acme/rfc8555.go b/vendor/golang.org/x/crypto/acme/rfc8555.go
new file mode 100644
index 00000000..dfb57a66
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/rfc8555.go
@@ -0,0 +1,392 @@
+// Copyright 2019 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 (
+	"context"
+	"crypto"
+	"encoding/base64"
+	"encoding/json"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"time"
+)
+
+// DeactivateReg permanently disables an existing account associated with c.Key.
+// A deactivated account can no longer request certificate issuance or access
+// resources related to the account, such as orders or authorizations.
+//
+// It only works with CAs implementing RFC 8555.
+func (c *Client) DeactivateReg(ctx context.Context) error {
+	url := string(c.accountKID(ctx))
+	if url == "" {
+		return ErrNoAccount
+	}
+	req := json.RawMessage(`{"status": "deactivated"}`)
+	res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))
+	if err != nil {
+		return err
+	}
+	res.Body.Close()
+	return nil
+}
+
+// registerRFC is quivalent 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"`
+	}{
+		Contact: acct.Contact,
+	}
+	if c.dir.Terms != "" {
+		req.TermsAgreed = prompt(c.dir.Terms)
+	}
+	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
+	))
+	if err != nil {
+		return nil, err
+	}
+
+	defer res.Body.Close()
+	a, err := responseAccount(res)
+	if err != nil {
+		return nil, err
+	}
+	// Cache Account URL even if we return an error to the caller.
+	// It is by all means a valid and usable "kid" value for future requests.
+	c.kid = keyID(a.URI)
+	if res.StatusCode == http.StatusOK {
+		return nil, ErrAccountAlreadyExists
+	}
+	return a, nil
+}
+
+// updateGegRFC 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))
+	if url == "" {
+		return nil, ErrNoAccount
+	}
+	req := struct {
+		Contact []string `json:"contact,omitempty"`
+	}{
+		Contact: a.Contact,
+	}
+	res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+	return responseAccount(res)
+}
+
+// getGegRFC is equivalent to c.GetReg but for CAs implementing RFC 8555.
+// It expects c.Discover to have already been called.
+func (c *Client) getRegRFC(ctx context.Context) (*Account, error) {
+	req := json.RawMessage(`{"onlyReturnExisting": true}`)
+	res, err := c.post(ctx, c.Key, c.dir.RegURL, req, wantStatus(http.StatusOK))
+	if e, ok := err.(*Error); ok && e.ProblemType == "urn:ietf:params:acme:error:accountDoesNotExist" {
+		return nil, ErrNoAccount
+	}
+	if err != nil {
+		return nil, err
+	}
+
+	defer res.Body.Close()
+	return responseAccount(res)
+}
+
+func responseAccount(res *http.Response) (*Account, error) {
+	var v struct {
+		Status  string
+		Contact []string
+		Orders  string
+	}
+	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
+		return nil, fmt.Errorf("acme: invalid account response: %v", err)
+	}
+	return &Account{
+		URI:       res.Header.Get("Location"),
+		Status:    v.Status,
+		Contact:   v.Contact,
+		OrdersURL: v.Orders,
+	}, nil
+}
+
+// AuthorizeOrder initiates the order-based application for certificate issuance,
+// as opposed to pre-authorization in Authorize.
+// It is only supported by CAs implementing RFC 8555.
+//
+// The caller then needs to fetch each authorization with GetAuthorization,
+// identify those with StatusPending status and fulfill a challenge using Accept.
+// Once all authorizations are satisfied, the caller will typically want to poll
+// order status using WaitOrder until it's in StatusReady state.
+// To finalize the order and obtain a certificate, the caller submits a CSR with CreateOrderCert.
+func (c *Client) AuthorizeOrder(ctx context.Context, id []AuthzID, opt ...OrderOption) (*Order, error) {
+	dir, err := c.Discover(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	req := struct {
+		Identifiers []wireAuthzID `json:"identifiers"`
+		NotBefore   string        `json:"notBefore,omitempty"`
+		NotAfter    string        `json:"notAfter,omitempty"`
+	}{}
+	for _, v := range id {
+		req.Identifiers = append(req.Identifiers, wireAuthzID{
+			Type:  v.Type,
+			Value: v.Value,
+		})
+	}
+	for _, o := range opt {
+		switch o := o.(type) {
+		case orderNotBeforeOpt:
+			req.NotBefore = time.Time(o).Format(time.RFC3339)
+		case orderNotAfterOpt:
+			req.NotAfter = time.Time(o).Format(time.RFC3339)
+		default:
+			// Package's fault if we let this happen.
+			panic(fmt.Sprintf("unsupported order option type %T", o))
+		}
+	}
+
+	res, err := c.post(ctx, nil, dir.OrderURL, req, wantStatus(http.StatusCreated))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+	return responseOrder(res)
+}
+
+// GetOrder retrives an order identified by the given URL.
+// For orders created with AuthorizeOrder, the url value is Order.URI.
+//
+// If a caller needs to poll an order until its status is final,
+// see the WaitOrder method.
+func (c *Client) GetOrder(ctx context.Context, url string) (*Order, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+
+	res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+	return responseOrder(res)
+}
+
+// WaitOrder polls an order from the given URL until it is in one of the final states,
+// StatusReady, StatusValid or StatusInvalid, the CA responded with a non-retryable error
+// or the context is done.
+//
+// It returns a non-nil Order only if its Status is StatusReady or StatusValid.
+// In all other cases WaitOrder returns an error.
+// If the Status is StatusInvalid, the returned error is of type *OrderError.
+func (c *Client) WaitOrder(ctx context.Context, url string) (*Order, error) {
+	if _, err := c.Discover(ctx); err != nil {
+		return nil, err
+	}
+	for {
+		res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))
+		if err != nil {
+			return nil, err
+		}
+		o, err := responseOrder(res)
+		res.Body.Close()
+		switch {
+		case err != nil:
+			// Skip and retry.
+		case o.Status == StatusInvalid:
+			return nil, &OrderError{OrderURL: o.URI, Status: o.Status}
+		case o.Status == StatusReady || o.Status == StatusValid:
+			return o, nil
+		}
+
+		d := retryAfter(res.Header.Get("Retry-After"))
+		if d == 0 {
+			// Default retry-after.
+			// Same reasoning as in WaitAuthorization.
+			d = time.Second
+		}
+		t := time.NewTimer(d)
+		select {
+		case <-ctx.Done():
+			t.Stop()
+			return nil, ctx.Err()
+		case <-t.C:
+			// Retry.
+		}
+	}
+}
+
+func responseOrder(res *http.Response) (*Order, error) {
+	var v struct {
+		Status         string
+		Expires        time.Time
+		Identifiers    []wireAuthzID
+		NotBefore      time.Time
+		NotAfter       time.Time
+		Error          *wireError
+		Authorizations []string
+		Finalize       string
+		Certificate    string
+	}
+	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
+		return nil, fmt.Errorf("acme: error reading order: %v", err)
+	}
+	o := &Order{
+		URI:         res.Header.Get("Location"),
+		Status:      v.Status,
+		Expires:     v.Expires,
+		NotBefore:   v.NotBefore,
+		NotAfter:    v.NotAfter,
+		AuthzURLs:   v.Authorizations,
+		FinalizeURL: v.Finalize,
+		CertURL:     v.Certificate,
+	}
+	for _, id := range v.Identifiers {
+		o.Identifiers = append(o.Identifiers, AuthzID{Type: id.Type, Value: id.Value})
+	}
+	if v.Error != nil {
+		o.Error = v.Error.error(nil /* headers */)
+	}
+	return o, nil
+}
+
+// CreateOrderCert submits the CSR (Certificate Signing Request) to a CA at the specified URL.
+// The URL is the FinalizeURL field of an Order created with AuthorizeOrder.
+//
+// If the bundle argument is true, the returned value also contain the CA (issuer)
+// certificate chain. Otherwise, only a leaf certificate is returned.
+// The returned URL can be used to re-fetch the certificate using FetchCert.
+//
+// This method is only supported by CAs implementing RFC 8555. See CreateCert for pre-RFC CAs.
+//
+// CreateOrderCert returns an error if the CA's response is unreasonably large.
+// Callers are encouraged to parse the returned value to ensure the certificate is valid and has the expected features.
+func (c *Client) CreateOrderCert(ctx context.Context, url string, csr []byte, bundle bool) (der [][]byte, certURL string, err error) {
+	if _, err := c.Discover(ctx); err != nil { // required by c.accountKID
+		return nil, "", err
+	}
+
+	// RFC describes this as "finalize order" request.
+	req := struct {
+		CSR string `json:"csr"`
+	}{
+		CSR: base64.RawURLEncoding.EncodeToString(csr),
+	}
+	res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))
+	if err != nil {
+		return nil, "", err
+	}
+	defer res.Body.Close()
+	o, err := responseOrder(res)
+	if err != nil {
+		return nil, "", err
+	}
+
+	// Wait for CA to issue the cert if they haven't.
+	if o.Status != StatusValid {
+		o, err = c.WaitOrder(ctx, o.URI)
+	}
+	if err != nil {
+		return nil, "", err
+	}
+	// The only acceptable status post finalize and WaitOrder is "valid".
+	if o.Status != StatusValid {
+		return nil, "", &OrderError{OrderURL: o.URI, Status: o.Status}
+	}
+	crt, err := c.fetchCertRFC(ctx, o.CertURL, bundle)
+	return crt, o.CertURL, err
+}
+
+// fetchCertRFC downloads issued certificate from the given URL.
+// It expects the CA to respond with PEM-encoded certificate chain.
+//
+// The URL argument is the CertURL field of Order.
+func (c *Client) fetchCertRFC(ctx context.Context, url string, bundle bool) ([][]byte, error) {
+	res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+
+	// Get all the bytes up to a sane maximum.
+	// Account very roughly for base64 overhead.
+	const max = maxCertChainSize + maxCertChainSize/33
+	b, err := ioutil.ReadAll(io.LimitReader(res.Body, max+1))
+	if err != nil {
+		return nil, fmt.Errorf("acme: fetch cert response stream: %v", err)
+	}
+	if len(b) > max {
+		return nil, errors.New("acme: certificate chain is too big")
+	}
+
+	// Decode PEM chain.
+	var chain [][]byte
+	for {
+		var p *pem.Block
+		p, b = pem.Decode(b)
+		if p == nil {
+			break
+		}
+		if p.Type != "CERTIFICATE" {
+			return nil, fmt.Errorf("acme: invalid PEM cert type %q", p.Type)
+		}
+
+		chain = append(chain, p.Bytes)
+		if !bundle {
+			return chain, nil
+		}
+		if len(chain) > maxChainLen {
+			return nil, errors.New("acme: certificate chain is too long")
+		}
+	}
+	if len(chain) == 0 {
+		return nil, errors.New("acme: certificate chain is empty")
+	}
+	return chain, nil
+}
+
+// sends a cert revocation request in either JWK form when key is non-nil or KID form otherwise.
+func (c *Client) revokeCertRFC(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error {
+	req := &struct {
+		Cert   string `json:"certificate"`
+		Reason int    `json:"reason"`
+	}{
+		Cert:   base64.RawURLEncoding.EncodeToString(cert),
+		Reason: int(reason),
+	}
+	res, err := c.post(ctx, key, c.dir.RevokeURL, req, wantStatus(http.StatusOK))
+	if err != nil {
+		if isAlreadyRevoked(err) {
+			// Assume it is not an error to revoke an already revoked cert.
+			return nil
+		}
+		return err
+	}
+	defer res.Body.Close()
+	return nil
+}
+
+func isAlreadyRevoked(err error) bool {
+	e, ok := err.(*Error)
+	return ok && e.ProblemType == "urn:ietf:params:acme:error:alreadyRevoked"
+}
diff --git a/vendor/golang.org/x/crypto/acme/types.go b/vendor/golang.org/x/crypto/acme/types.go
index 54792c06..9c59097a 100644
--- a/vendor/golang.org/x/crypto/acme/types.go
+++ b/vendor/golang.org/x/crypto/acme/types.go
@@ -14,14 +14,18 @@ import (
 	"time"
 )
 
-// ACME server response statuses used to describe Authorization and Challenge states.
+// ACME status values of Account, Order, Authorization and Challenge objects.
+// See https://tools.ietf.org/html/rfc8555#section-7.1.6 for details.
 const (
-	StatusUnknown    = "unknown"
-	StatusPending    = "pending"
-	StatusProcessing = "processing"
-	StatusValid      = "valid"
-	StatusInvalid    = "invalid"
-	StatusRevoked    = "revoked"
+	StatusDeactivated = "deactivated"
+	StatusExpired     = "expired"
+	StatusInvalid     = "invalid"
+	StatusPending     = "pending"
+	StatusProcessing  = "processing"
+	StatusReady       = "ready"
+	StatusRevoked     = "revoked"
+	StatusUnknown     = "unknown"
+	StatusValid       = "valid"
 )
 
 // CRLReasonCode identifies the reason for a certificate revocation.
@@ -41,8 +45,17 @@ const (
 	CRLReasonAACompromise         CRLReasonCode = 10
 )
 
-// ErrUnsupportedKey is returned when an unsupported key type is encountered.
-var ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")
+var (
+	// ErrUnsupportedKey is returned when an unsupported key type is encountered.
+	ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")
+
+	// ErrAccountAlreadyExists indicates that the Client's key has already been registered
+	// with the CA. It is returned by Register method.
+	ErrAccountAlreadyExists = errors.New("acme: account already exists")
+
+	// ErrNoAccount indicates that the Client's key has not been registered with the CA.
+	ErrNoAccount = errors.New("acme: account does not exist")
+)
 
 // Error is an ACME error, defined in Problem Details for HTTP APIs doc
 // http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.
@@ -54,6 +67,12 @@ type Error struct {
 	ProblemType string
 	// Detail is a human-readable explanation specific to this occurrence of the problem.
 	Detail string
+	// Instance indicates a URL that the client should direct a human user to visit
+	// in order for instructions on how to agree to the updated Terms of Service.
+	// In such an event CA sets StatusCode to 403, ProblemType to
+	// "urn:ietf:params:acme:error:userActionRequired" and a Link header with relation
+	// "terms-of-service" containing the latest TOS URL.
+	Instance string
 	// Header is the original server error response headers.
 	// It may be nil.
 	Header http.Header
@@ -86,6 +105,21 @@ func (a *AuthorizationError) Error() string {
 	return fmt.Sprintf("acme: authorization error for %s: %s", a.Identifier, strings.Join(e, "; "))
 }
 
+// OrderError is returned from Client's order related methods.
+// It indicates the order is unusable and the clients should start over with
+// AuthorizeOrder.
+//
+// The clients can still fetch the order object from CA using GetOrder
+// to inspect its state.
+type OrderError struct {
+	OrderURL string
+	Status   string
+}
+
+func (oe *OrderError) Error() string {
+	return fmt.Sprintf("acme: order %s status: %s", oe.OrderURL, oe.Status)
+}
+
 // RateLimit reports whether err represents a rate limit error and
 // any Retry-After duration returned by the server.
 //
@@ -108,49 +142,88 @@ func RateLimit(err error) (time.Duration, bool) {
 }
 
 // Account is a user account. It is associated with a private key.
+// Non-RFC 8555 fields are empty when interfacing with a compliant CA.
 type Account struct {
 	// URI is the account unique ID, which is also a URL used to retrieve
 	// account data from the CA.
+	// When interfacing with RFC 8555-compliant CAs, URI is the "kid" field
+	// value in JWS signed requests.
 	URI string
 
 	// Contact is a slice of contact info used during registration.
+	// See https://tools.ietf.org/html/rfc8555#section-7.3 for supported
+	// formats.
 	Contact []string
 
+	// Status indicates current account status as returned by the CA.
+	// Possible values are StatusValid, StatusDeactivated, and StatusRevoked.
+	Status string
+
+	// OrdersURL is a URL from which a list of orders submitted by this account
+	// can be fetched.
+	OrdersURL string
+
 	// The terms user has agreed to.
 	// A value not matching CurrentTerms indicates that the user hasn't agreed
 	// to the actual Terms of Service of the CA.
+	//
+	// It is non-RFC 8555 compliant. Package users can store the ToS they agree to
+	// during Client's Register call in the prompt callback function.
 	AgreedTerms string
 
 	// Actual terms of a CA.
+	//
+	// It is non-RFC 8555 compliant. Use Directory's Terms field.
+	// When a CA updates their terms and requires an account agreement,
+	// a URL at which instructions to do so is available in Error's Instance field.
 	CurrentTerms string
 
 	// Authz is the authorization URL used to initiate a new authz flow.
+	//
+	// It is non-RFC 8555 compliant. Use Directory's AuthzURL or OrderURL.
 	Authz string
 
 	// Authorizations is a URI from which a list of authorizations
 	// granted to this account can be fetched via a GET request.
+	//
+	// It is non-RFC 8555 compliant and is obsoleted by OrdersURL.
 	Authorizations string
 
 	// Certificates is a URI from which a list of certificates
 	// issued for this account can be fetched via a GET request.
+	//
+	// It is non-RFC 8555 compliant and is obsoleted by OrdersURL.
 	Certificates string
 }
 
 // Directory is ACME server discovery data.
+// See https://tools.ietf.org/html/rfc8555#section-7.1.1 for more details.
 type Directory struct {
-	// RegURL is an account endpoint URL, allowing for creating new
-	// and modifying existing accounts.
+	// NonceURL indicates an endpoint where to fetch fresh nonce values from.
+	NonceURL string
+
+	// RegURL is an account endpoint URL, allowing for creating new accounts.
+	// Pre-RFC 8555 CAs also allow modifying existing accounts at this URL.
 	RegURL string
 
-	// AuthzURL is used to initiate Identifier Authorization flow.
+	// OrderURL is used to initiate the certificate issuance flow
+	// as described in RFC 8555.
+	OrderURL string
+
+	// AuthzURL is used to initiate identifier pre-authorization flow.
+	// Empty string indicates the flow is unsupported by the CA.
 	AuthzURL string
 
 	// CertURL is a new certificate issuance endpoint URL.
+	// It is non-RFC 8555 compliant and is obsoleted by OrderURL.
 	CertURL string
 
 	// RevokeURL is used to initiate a certificate revocation flow.
 	RevokeURL string
 
+	// KeyChangeURL allows to perform account key rollover flow.
+	KeyChangeURL string
+
 	// Term is a URI identifying the current terms of service.
 	Terms string
 
@@ -162,44 +235,126 @@ type Directory struct {
 	// recognises as referring to itself for the purposes of CAA record validation
 	// as defined in RFC6844.
 	CAA []string
+
+	// ExternalAccountRequired indicates that the CA requires for all account-related
+	// requests to include external account binding information.
+	ExternalAccountRequired bool
 }
 
-// Challenge encodes a returned CA challenge.
-// Its Error field may be non-nil if the challenge is part of an Authorization
-// with StatusInvalid.
-type Challenge struct {
-	// Type is the challenge type, e.g. "http-01", "tls-sni-02", "dns-01".
-	Type string
+// rfcCompliant reports whether the ACME server implements RFC 8555.
+// Note that some servers may have incomplete RFC implementation
+// even if the returned value is true.
+// If rfcCompliant reports false, the server most likely implements draft-02.
+func (d *Directory) rfcCompliant() bool {
+	return d.OrderURL != ""
+}
 
-	// URI is where a challenge response can be posted to.
+// Order represents a client's request for a certificate.
+// It tracks the request flow progress through to issuance.
+type Order struct {
+	// URI uniquely identifies an order.
 	URI string
 
-	// Token is a random value that uniquely identifies the challenge.
-	Token string
-
-	// Status identifies the status of this challenge.
+	// Status represents the current status of the order.
+	// It indicates which action the client should take.
+	//
+	// Possible values are StatusPending, StatusReady, StatusProcessing, StatusValid and StatusInvalid.
+	// Pending means the CA does not believe that the client has fulfilled the requirements.
+	// Ready indicates that the client has fulfilled all the requirements and can submit a CSR
+	// to obtain a certificate. This is done with Client's CreateOrderCert.
+	// Processing means the certificate is being issued.
+	// Valid indicates the CA has issued the certificate. It can be downloaded
+	// from the Order's CertURL. This is done with Client's FetchCert.
+	// Invalid means the certificate will not be issued. Users should consider this order
+	// abandoned.
 	Status string
 
-	// Error indicates the reason for an authorization failure
-	// when this challenge was used.
-	// The type of a non-nil value is *Error.
-	Error error
+	// Expires is the timestamp after which CA considers this order invalid.
+	Expires time.Time
+
+	// Identifiers contains all identifier objects which the order pertains to.
+	Identifiers []AuthzID
+
+	// NotBefore is the requested value of the notBefore field in the certificate.
+	NotBefore time.Time
+
+	// NotAfter is the requested value of the notAfter field in the certificate.
+	NotAfter time.Time
+
+	// AuthzURLs represents authorizations to complete before a certificate
+	// for identifiers specified in the order can be issued.
+	// It also contains unexpired authorizations that the client has completed
+	// in the past.
+	//
+	// Authorization objects can be fetched using Client's GetAuthorization method.
+	//
+	// The required authorizations are dictated by CA policies.
+	// There may not be a 1:1 relationship between the identifiers and required authorizations.
+	// Required authorizations can be identified by their StatusPending status.
+	//
+	// For orders in the StatusValid or StatusInvalid state these are the authorizations
+	// which were completed.
+	AuthzURLs []string
+
+	// FinalizeURL is the endpoint at which a CSR is submitted to obtain a certificate
+	// once all the authorizations are satisfied.
+	FinalizeURL string
+
+	// CertURL points to the certificate that has been issued in response to this order.
+	CertURL string
+
+	// The error that occurred while processing the order as received from a CA, if any.
+	Error *Error
+}
+
+// OrderOption allows customizing Client.AuthorizeOrder call.
+type OrderOption interface {
+	privateOrderOpt()
+}
+
+// WithOrderNotBefore sets order's NotBefore field.
+func WithOrderNotBefore(t time.Time) OrderOption {
+	return orderNotBeforeOpt(t)
 }
 
+// WithOrderNotAfter sets order's NotAfter field.
+func WithOrderNotAfter(t time.Time) OrderOption {
+	return orderNotAfterOpt(t)
+}
+
+type orderNotBeforeOpt time.Time
+
+func (orderNotBeforeOpt) privateOrderOpt() {}
+
+type orderNotAfterOpt time.Time
+
+func (orderNotAfterOpt) privateOrderOpt() {}
+
 // Authorization encodes an authorization response.
 type Authorization struct {
 	// URI uniquely identifies a authorization.
 	URI string
 
-	// Status identifies the status of an authorization.
+	// Status is the current status of an authorization.
+	// Possible values are StatusPending, StatusValid, StatusInvalid, StatusDeactivated,
+	// StatusExpired and StatusRevoked.
 	Status string
 
 	// Identifier is what the account is authorized to represent.
 	Identifier AuthzID
 
+	// The timestamp after which the CA considers the authorization invalid.
+	Expires time.Time
+
+	// Wildcard is true for authorizations of a wildcard domain name.
+	Wildcard bool
+
 	// 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.
+	// For valid authorizations, the challenge that was validated.
+	// For invalid authorizations, the challenge that was attempted and failed.
+	//
+	// RFC 8555 compatible CAs require users to fuflfill only one of the challenges.
 	Challenges []*Challenge
 
 	// A collection of sets of challenges, each of which would be sufficient
@@ -207,24 +362,51 @@ type Authorization struct {
 	// 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.
+	//
+	// This field is unused in RFC 8555.
 	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".
+	Type  string // The type of identifier, "dns" or "ip".
 	Value string // The identifier itself, e.g. "example.org".
 }
 
+// DomainIDs creates a slice of AuthzID with "dns" identifier type.
+func DomainIDs(names ...string) []AuthzID {
+	a := make([]AuthzID, len(names))
+	for i, v := range names {
+		a[i] = AuthzID{Type: "dns", Value: v}
+	}
+	return a
+}
+
+// IPIDs creates a slice of AuthzID with "ip" identifier type.
+// Each element of addr is textual form of an address as defined
+// in RFC1123 Section 2.1 for IPv4 and in RFC5952 Section 4 for IPv6.
+func IPIDs(addr ...string) []AuthzID {
+	a := make([]AuthzID, len(addr))
+	for i, v := range addr {
+		a[i] = AuthzID{Type: "ip", Value: v}
+	}
+	return a
+}
+
+// wireAuthzID is ACME JSON representation of authorization identifier objects.
+type wireAuthzID struct {
+	Type  string `json:"type"`
+	Value string `json:"value"`
+}
+
 // wireAuthz is ACME JSON representation of Authorization objects.
 type wireAuthz struct {
+	Identifier   wireAuthzID
 	Status       string
+	Expires      time.Time
+	Wildcard     bool
 	Challenges   []wireChallenge
 	Combinations [][]int
-	Identifier   struct {
-		Type  string
-		Value string
-	}
 }
 
 func (z *wireAuthz) authorization(uri string) *Authorization {
@@ -232,8 +414,10 @@ func (z *wireAuthz) authorization(uri string) *Authorization {
 		URI:          uri,
 		Status:       z.Status,
 		Identifier:   AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value},
-		Combinations: z.Combinations, // shallow copy
+		Expires:      z.Expires,
+		Wildcard:     z.Wildcard,
 		Challenges:   make([]*Challenge, len(z.Challenges)),
+		Combinations: z.Combinations, // shallow copy
 	}
 	for i, v := range z.Challenges {
 		a.Challenges[i] = v.challenge()
@@ -254,22 +438,55 @@ func (z *wireAuthz) error(uri string) *AuthorizationError {
 	return err
 }
 
+// Challenge encodes a returned CA challenge.
+// Its Error field may be non-nil if the challenge is part of an Authorization
+// with StatusInvalid.
+type Challenge struct {
+	// Type is the challenge type, e.g. "http-01", "tls-alpn-01", "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.
+	// In RFC 8555, possible values are StatusPending, StatusProcessing, StatusValid,
+	// and StatusInvalid.
+	Status string
+
+	// Validated is the time at which the CA validated this challenge.
+	// Always zero value in pre-RFC 8555.
+	Validated time.Time
+
+	// Error indicates the reason for an authorization failure
+	// when this challenge was used.
+	// The type of a non-nil value is *Error.
+	Error error
+}
+
 // wireChallenge is ACME JSON challenge representation.
 type wireChallenge struct {
-	URI    string `json:"uri"`
-	Type   string
-	Token  string
-	Status string
-	Error  *wireError
+	URL       string `json:"url"` // RFC
+	URI       string `json:"uri"` // pre-RFC
+	Type      string
+	Token     string
+	Status    string
+	Validated time.Time
+	Error     *wireError
 }
 
 func (c *wireChallenge) challenge() *Challenge {
 	v := &Challenge{
-		URI:    c.URI,
+		URI:    c.URL,
 		Type:   c.Type,
 		Token:  c.Token,
 		Status: c.Status,
 	}
+	if v.URI == "" {
+		v.URI = c.URI // c.URL was empty; use legacy
+	}
 	if v.Status == "" {
 		v.Status = StatusPending
 	}
@@ -282,9 +499,10 @@ func (c *wireChallenge) challenge() *Challenge {
 // wireError is a subset of fields of the Problem Details object
 // as described in https://tools.ietf.org/html/rfc7807#section-3.1.
 type wireError struct {
-	Status int
-	Type   string
-	Detail string
+	Status   int
+	Type     string
+	Detail   string
+	Instance string
 }
 
 func (e *wireError) error(h http.Header) *Error {
@@ -292,6 +510,7 @@ func (e *wireError) error(h http.Header) *Error {
 		StatusCode:  e.Status,
 		ProblemType: e.Type,
 		Detail:      e.Detail,
+		Instance:    e.Instance,
 		Header:      h,
 	}
 }
diff --git a/vendor/golang.org/x/crypto/acme/version_go112.go b/vendor/golang.org/x/crypto/acme/version_go112.go
new file mode 100644
index 00000000..b58f2456
--- /dev/null
+++ b/vendor/golang.org/x/crypto/acme/version_go112.go
@@ -0,0 +1,27 @@
+// Copyright 2019 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.
+
+// +build go1.12
+
+package acme
+
+import "runtime/debug"
+
+func init() {
+	// Set packageVersion if the binary was built in modules mode and x/crypto
+	// was not replaced with a different module.
+	info, ok := debug.ReadBuildInfo()
+	if !ok {
+		return
+	}
+	for _, m := range info.Deps {
+		if m.Path != "golang.org/x/crypto" {
+			continue
+		}
+		if m.Replace == nil {
+			packageVersion = m.Version
+		}
+		break
+	}
+}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 89bed601..aff5a0ef 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -267,10 +267,10 @@
 			"revisionTime": "2018-11-12T17:26:09Z"
 		},
 		{
-			"checksumSHA1": "/pfkYB22L5MtzxrfIHQ0tWylnZw=",
+			"checksumSHA1": "ZP/ynTcYY5bDTh2LhgGVrptepm4=",
 			"path": "golang.org/x/crypto/acme",
-			"revision": "e84da0312774c21d64ee2317962ef669b27ffb41",
-			"revisionTime": "2018-10-24T13:26:30Z"
+			"revision": "bd318be0434a57050ed475e0f45c3dbb16c09c2e",
+			"revisionTime": "2019-11-05T15:52:03Z"
 		},
 		{
 			"checksumSHA1": "2LpxYGSf068307b7bhAuVjvzLLc=",
-- 
GitLab