THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Browse Source

add letsencrypt to Gitea (#4189)

pull/4757/head
Fluf 9 months ago
parent
commit
b82c14b3d2
35 changed files with 4518 additions and 280 deletions
  1. 5
    1
      Gopkg.lock
  2. 1
    1
      Gopkg.toml
  3. 33
    0
      cmd/web.go
  4. 5
    0
      docs/content/doc/advanced/config-cheat-sheet.en-us.md
  5. 18
    0
      docs/content/doc/usage/https-support.md
  6. 12
    0
      modules/setting/setting.go
  7. 1065
    0
      vendor/golang.org/x/crypto/acme/acme.go
  8. 962
    0
      vendor/golang.org/x/crypto/acme/autocert/autocert.go
  9. 130
    0
      vendor/golang.org/x/crypto/acme/autocert/cache.go
  10. 160
    0
      vendor/golang.org/x/crypto/acme/autocert/listener.go
  11. 141
    0
      vendor/golang.org/x/crypto/acme/autocert/renewal.go
  12. 153
    0
      vendor/golang.org/x/crypto/acme/jws.go
  13. 329
    0
      vendor/golang.org/x/crypto/acme/types.go
  14. 10
    3
      vendor/golang.org/x/crypto/ed25519/ed25519.go
  15. 22
    0
      vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
  16. 223
    0
      vendor/golang.org/x/crypto/internal/chacha20/chacha_generic.go
  17. 43
    0
      vendor/golang.org/x/crypto/internal/chacha20/xor.go
  18. 33
    0
      vendor/golang.org/x/crypto/poly1305/poly1305.go
  19. 22
    0
      vendor/golang.org/x/crypto/poly1305/sum_amd64.go
  20. 125
    0
      vendor/golang.org/x/crypto/poly1305/sum_amd64.s
  21. 22
    0
      vendor/golang.org/x/crypto/poly1305/sum_arm.go
  22. 427
    0
      vendor/golang.org/x/crypto/poly1305/sum_arm.s
  23. 141
    0
      vendor/golang.org/x/crypto/poly1305/sum_ref.go
  24. 5
    3
      vendor/golang.org/x/crypto/ssh/certs.go
  25. 71
    71
      vendor/golang.org/x/crypto/ssh/channel.go
  26. 195
    53
      vendor/golang.org/x/crypto/ssh/cipher.go
  27. 55
    40
      vendor/golang.org/x/crypto/ssh/client_auth.go
  28. 15
    5
      vendor/golang.org/x/crypto/ssh/common.go
  29. 12
    12
      vendor/golang.org/x/crypto/ssh/kex.go
  30. 24
    23
      vendor/golang.org/x/crypto/ssh/keys.go
  31. 11
    11
      vendor/golang.org/x/crypto/ssh/messages.go
  32. 3
    3
      vendor/golang.org/x/crypto/ssh/mux.go
  33. 20
    7
      vendor/golang.org/x/crypto/ssh/server.go
  34. 1
    1
      vendor/golang.org/x/crypto/ssh/session.go
  35. 24
    46
      vendor/golang.org/x/crypto/ssh/transport.go

+ 5
- 1
Gopkg.lock View File

@@ -563,14 +563,18 @@
563 563
 [[projects]]
564 564
   name = "golang.org/x/crypto"
565 565
   packages = [
566
+    "acme",
567
+    "acme/autocert",
566 568
     "curve25519",
567 569
     "ed25519",
568 570
     "ed25519/internal/edwards25519",
571
+    "internal/chacha20",
569 572
     "md4",
570 573
     "pbkdf2",
574
+    "poly1305",
571 575
     "ssh"
572 576
   ]
573
-  revision = "9f005a07e0d31d45e6656d241bb5c0f2efd4bc94"
577
+  revision = "12dd70caea0268ac0d6c2707d0611ef601e7c64e"
574 578
 
575 579
 [[projects]]
576 580
   name = "golang.org/x/net"

+ 1
- 1
Gopkg.toml View File

@@ -15,7 +15,7 @@ ignored = ["google.golang.org/appengine*"]
15 15
   name = "code.gitea.io/sdk"
16 16
 
17 17
 [[constraint]]
18
-  revision = "9f005a07e0d31d45e6656d241bb5c0f2efd4bc94"
18
+  revision = "12dd70caea0268ac0d6c2707d0611ef601e7c64e"
19 19
   name = "golang.org/x/crypto"
20 20
 
21 21
 [[constraint]]

+ 33
- 0
cmd/web.go View File

@@ -5,6 +5,7 @@
5 5
 package cmd
6 6
 
7 7
 import (
8
+	"crypto/tls"
8 9
 	"fmt"
9 10
 	"net"
10 11
 	"net/http"
@@ -22,6 +23,7 @@ import (
22 23
 	"github.com/Unknwon/com"
23 24
 	context2 "github.com/gorilla/context"
24 25
 	"github.com/urfave/cli"
26
+	"golang.org/x/crypto/acme/autocert"
25 27
 	ini "gopkg.in/ini.v1"
26 28
 )
27 29
 
@@ -71,6 +73,33 @@ func runHTTPRedirector() {
71 73
 	}
72 74
 }
73 75
 
76
+func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler) error {
77
+	certManager := autocert.Manager{
78
+		Prompt:     autocert.AcceptTOS,
79
+		HostPolicy: autocert.HostWhitelist(domain),
80
+		Cache:      autocert.DirCache(directory),
81
+		Email:      email,
82
+	}
83
+	go http.ListenAndServe(listenAddr+":"+setting.PortToRedirect, certManager.HTTPHandler(http.HandlerFunc(runLetsEncryptFallbackHandler))) // all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validatio happens here)
84
+	server := &http.Server{
85
+		Addr:    listenAddr,
86
+		Handler: m,
87
+		TLSConfig: &tls.Config{
88
+			GetCertificate: certManager.GetCertificate,
89
+		},
90
+	}
91
+	return server.ListenAndServeTLS("", "")
92
+}
93
+
94
+func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) {
95
+	if r.Method != "GET" && r.Method != "HEAD" {
96
+		http.Error(w, "Use HTTPS", http.StatusBadRequest)
97
+		return
98
+	}
99
+	target := setting.AppURL + r.URL.RequestURI()
100
+	http.Redirect(w, r, target, http.StatusFound)
101
+}
102
+
74 103
 func runWeb(ctx *cli.Context) error {
75 104
 	if ctx.IsSet("config") {
76 105
 		setting.CustomConf = ctx.String("config")
@@ -143,6 +172,10 @@ func runWeb(ctx *cli.Context) error {
143 172
 	case setting.HTTP:
144 173
 		err = runHTTP(listenAddr, context2.ClearHandler(m))
145 174
 	case setting.HTTPS:
175
+		if setting.EnableLetsEncrypt {
176
+			err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, context2.ClearHandler(m))
177
+			break
178
+		}
146 179
 		if setting.RedirectOtherPort {
147 180
 			go runHTTPRedirector()
148 181
 		}

+ 5
- 0
docs/content/doc/advanced/config-cheat-sheet.en-us.md View File

@@ -125,6 +125,11 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
125 125
 - `REDIRECT_OTHER_PORT`: **false**: If true and `PROTOCOL` is https, redirects http requests
126 126
    on another (https) port.
127 127
 - `PORT_TO_REDIRECT`: **80**: Port used when `REDIRECT_OTHER_PORT` is true.
128
+- `ENABLE_LETSENCRYPT`: **false**: If enabled you must set `DOMAIN` to valid internet facing domain (ensure DNS is set and port 80 is accessible by letsencrypt validation server).
129
+   By using Lets Encrypt **you must consent** to their [terms of service](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf)
130
+- `LETSENCRYPT_ACCEPTTOS`: **false**: This is an explicit check that you accept the terms of service for Let's Encrypt
131
+- `LETSENCRYPT_DIRECTORY`: **https**: Directory that Letsencrypt will use to cache information such as certs and private keys
132
+- `LETSENCRYPT_EMAIL`: **email@example.com**: Email used by Letsencrypt to notify about problems with issued certificates. (No default)
128 133
 
129 134
 ## Database (`database`)
130 135
 

+ 18
- 0
docs/content/doc/usage/https-support.md View File

@@ -32,6 +32,24 @@ KEY_FILE = key.pem
32 32
 ```
33 33
 To learn more about the config values, please checkout the [Config Cheat Sheet](../config-cheat-sheet#server).
34 34
 
35
+## Using Let's Encrypt
36
+
37
+[Let's Encrypt](https://letsencrypt.org/) is a Certificate Authority that allows you to automatically request and renew SSL/TLS certificates. In addition to starting Gitea on your configured port, to request HTTPS certificates Gitea will also need to listed on port 80, and will set up an autoredirect to HTTPS for you. Let's Encrypt will need to be able to access Gitea via the Internet to verify your ownership of the domain.
38
+
39
+By using Lets Encrypt **you must consent** to their [terms of service](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf)
40
+
41
+```ini
42
+[server]
43
+PROTOCOL=https
44
+DOMAIN=git.example.com
45
+ENABLE_LETSENCRYPT=true
46
+LETSENCRYPT_ACCEPTTOS=true
47
+LETSENCRYPT_DIRECTORY=https
48
+LETSENCRYPT_EMAIL=email@example.com
49
+```
50
+
51
+To learn more about the config values, please checkout the [Config Cheat Sheet](../config-cheat-sheet#server).
52
+
35 53
 ## Using reverse proxy
36 54
 
37 55
 Setup up your reverse proxy like shown in the [reverse proxy guide](../reverse-proxies).

+ 12
- 0
modules/setting/setting.go View File

@@ -112,6 +112,10 @@ var (
112 112
 	UnixSocketPermission uint32
113 113
 	EnablePprof          bool
114 114
 	PprofDataPath        string
115
+	EnableLetsEncrypt    bool
116
+	LetsEncryptTOS       bool
117
+	LetsEncryptDirectory string
118
+	LetsEncryptEmail     string
115 119
 
116 120
 	SSH = struct {
117 121
 		Disabled             bool           `ini:"DISABLE_SSH"`
@@ -737,6 +741,14 @@ func NewContext() {
737 741
 		}
738 742
 		UnixSocketPermission = uint32(UnixSocketPermissionParsed)
739 743
 	}
744
+	EnableLetsEncrypt := sec.Key("ENABLE_LETSENCRYPT").MustBool(false)
745
+	LetsEncryptTOS := sec.Key("LETSENCRYPT_ACCEPTTOS").MustBool(false)
746
+	if !LetsEncryptTOS && EnableLetsEncrypt {
747
+		log.Warn("Failed to enable Let's Encrypt due to Let's Encrypt TOS not being accepted")
748
+		EnableLetsEncrypt = false
749
+	}
750
+	LetsEncryptDirectory = sec.Key("LETSENCRYPT_DIRECTORY").MustString("https")
751
+	LetsEncryptEmail = sec.Key("LETSENCRYPT_EMAIL").MustString("")
740 752
 	Domain = sec.Key("DOMAIN").MustString("localhost")
741 753
 	HTTPAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
742 754
 	HTTPPort = sec.Key("HTTP_PORT").MustString("3000")

+ 1065
- 0
vendor/golang.org/x/crypto/acme/acme.go
File diff suppressed because it is too large
View File


+ 962
- 0
vendor/golang.org/x/crypto/acme/autocert/autocert.go View File

@@ -0,0 +1,962 @@
1
+// Copyright 2016 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// Package autocert provides automatic access to certificates from Let's Encrypt
6
+// and any other ACME-based CA.
7
+//
8
+// This package is a work in progress and makes no API stability promises.
9
+package autocert
10
+
11
+import (
12
+	"bytes"
13
+	"context"
14
+	"crypto"
15
+	"crypto/ecdsa"
16
+	"crypto/elliptic"
17
+	"crypto/rand"
18
+	"crypto/rsa"
19
+	"crypto/tls"
20
+	"crypto/x509"
21
+	"crypto/x509/pkix"
22
+	"encoding/pem"
23
+	"errors"
24
+	"fmt"
25
+	"io"
26
+	mathrand "math/rand"
27
+	"net"
28
+	"net/http"
29
+	"path"
30
+	"strings"
31
+	"sync"
32
+	"time"
33
+
34
+	"golang.org/x/crypto/acme"
35
+)
36
+
37
+// createCertRetryAfter is how much time to wait before removing a failed state
38
+// entry due to an unsuccessful createCert call.
39
+// This is a variable instead of a const for testing.
40
+// TODO: Consider making it configurable or an exp backoff?
41
+var createCertRetryAfter = time.Minute
42
+
43
+// pseudoRand is safe for concurrent use.
44
+var pseudoRand *lockedMathRand
45
+
46
+func init() {
47
+	src := mathrand.NewSource(timeNow().UnixNano())
48
+	pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
49
+}
50
+
51
+// AcceptTOS is a Manager.Prompt function that always returns true to
52
+// indicate acceptance of the CA's Terms of Service during account
53
+// registration.
54
+func AcceptTOS(tosURL string) bool { return true }
55
+
56
+// HostPolicy specifies which host names the Manager is allowed to respond to.
57
+// It returns a non-nil error if the host should be rejected.
58
+// The returned error is accessible via tls.Conn.Handshake and its callers.
59
+// See Manager's HostPolicy field and GetCertificate method docs for more details.
60
+type HostPolicy func(ctx context.Context, host string) error
61
+
62
+// HostWhitelist returns a policy where only the specified host names are allowed.
63
+// Only exact matches are currently supported. Subdomains, regexp or wildcard
64
+// will not match.
65
+func HostWhitelist(hosts ...string) HostPolicy {
66
+	whitelist := make(map[string]bool, len(hosts))
67
+	for _, h := range hosts {
68
+		whitelist[h] = true
69
+	}
70
+	return func(_ context.Context, host string) error {
71
+		if !whitelist[host] {
72
+			return errors.New("acme/autocert: host not configured")
73
+		}
74
+		return nil
75
+	}
76
+}
77
+
78
+// defaultHostPolicy is used when Manager.HostPolicy is not set.
79
+func defaultHostPolicy(context.Context, string) error {
80
+	return nil
81
+}
82
+
83
+// Manager is a stateful certificate manager built on top of acme.Client.
84
+// It obtains and refreshes certificates automatically using "tls-sni-01",
85
+// "tls-sni-02" and "http-01" challenge types, as well as providing them
86
+// to a TLS server via tls.Config.
87
+//
88
+// You must specify a cache implementation, such as DirCache,
89
+// to reuse obtained certificates across program restarts.
90
+// Otherwise your server is very likely to exceed the certificate
91
+// issuer's request rate limits.
92
+type Manager struct {
93
+	// Prompt specifies a callback function to conditionally accept a CA's Terms of Service (TOS).
94
+	// The registration may require the caller to agree to the CA's TOS.
95
+	// If so, Manager calls Prompt with a TOS URL provided by the CA. Prompt should report
96
+	// whether the caller agrees to the terms.
97
+	//
98
+	// To always accept the terms, the callers can use AcceptTOS.
99
+	Prompt func(tosURL string) bool
100
+
101
+	// Cache optionally stores and retrieves previously-obtained certificates.
102
+	// If nil, certs will only be cached for the lifetime of the Manager.
103
+	//
104
+	// Manager passes the Cache certificates data encoded in PEM, with private/public
105
+	// parts combined in a single Cache.Put call, private key first.
106
+	Cache Cache
107
+
108
+	// HostPolicy controls which domains the Manager will attempt
109
+	// to retrieve new certificates for. It does not affect cached certs.
110
+	//
111
+	// If non-nil, HostPolicy is called before requesting a new cert.
112
+	// If nil, all hosts are currently allowed. This is not recommended,
113
+	// as it opens a potential attack where clients connect to a server
114
+	// by IP address and pretend to be asking for an incorrect host name.
115
+	// Manager will attempt to obtain a certificate for that host, incorrectly,
116
+	// eventually reaching the CA's rate limit for certificate requests
117
+	// and making it impossible to obtain actual certificates.
118
+	//
119
+	// See GetCertificate for more details.
120
+	HostPolicy HostPolicy
121
+
122
+	// RenewBefore optionally specifies how early certificates should
123
+	// be renewed before they expire.
124
+	//
125
+	// If zero, they're renewed 30 days before expiration.
126
+	RenewBefore time.Duration
127
+
128
+	// Client is used to perform low-level operations, such as account registration
129
+	// and requesting new certificates.
130
+	// If Client is nil, a zero-value acme.Client is used with acme.LetsEncryptURL
131
+	// directory endpoint and a newly-generated ECDSA P-256 key.
132
+	//
133
+	// Mutating the field after the first call of GetCertificate method will have no effect.
134
+	Client *acme.Client
135
+
136
+	// Email optionally specifies a contact email address.
137
+	// This is used by CAs, such as Let's Encrypt, to notify about problems
138
+	// with issued certificates.
139
+	//
140
+	// If the Client's account key is already registered, Email is not used.
141
+	Email string
142
+
143
+	// ForceRSA makes the Manager generate certificates with 2048-bit RSA keys.
144
+	//
145
+	// If false, a default is used. Currently the default
146
+	// is EC-based keys using the P-256 curve.
147
+	ForceRSA bool
148
+
149
+	clientMu sync.Mutex
150
+	client   *acme.Client // initialized by acmeClient method
151
+
152
+	stateMu sync.Mutex
153
+	state   map[string]*certState // keyed by domain name
154
+
155
+	// renewal tracks the set of domains currently running renewal timers.
156
+	// It is keyed by domain name.
157
+	renewalMu sync.Mutex
158
+	renewal   map[string]*domainRenewal
159
+
160
+	// tokensMu guards the rest of the fields: tryHTTP01, certTokens and httpTokens.
161
+	tokensMu sync.RWMutex
162
+	// tryHTTP01 indicates whether the Manager should try "http-01" challenge type
163
+	// during the authorization flow.
164
+	tryHTTP01 bool
165
+	// httpTokens contains response body values for http-01 challenges
166
+	// and is keyed by the URL path at which a challenge response is expected
167
+	// to be provisioned.
168
+	// The entries are stored for the duration of the authorization flow.
169
+	httpTokens map[string][]byte
170
+	// certTokens contains temporary certificates for tls-sni challenges
171
+	// and is keyed by token domain name, which matches server name of ClientHello.
172
+	// Keys always have ".acme.invalid" suffix.
173
+	// The entries are stored for the duration of the authorization flow.
174
+	certTokens map[string]*tls.Certificate
175
+}
176
+
177
+// GetCertificate implements the tls.Config.GetCertificate hook.
178
+// It provides a TLS certificate for hello.ServerName host, including answering
179
+// *.acme.invalid (TLS-SNI) challenges. All other fields of hello are ignored.
180
+//
181
+// If m.HostPolicy is non-nil, GetCertificate calls the policy before requesting
182
+// a new cert. A non-nil error returned from m.HostPolicy halts TLS negotiation.
183
+// The error is propagated back to the caller of GetCertificate and is user-visible.
184
+// This does not affect cached certs. See HostPolicy field description for more details.
185
+func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
186
+	if m.Prompt == nil {
187
+		return nil, errors.New("acme/autocert: Manager.Prompt not set")
188
+	}
189
+
190
+	name := hello.ServerName
191
+	if name == "" {
192
+		return nil, errors.New("acme/autocert: missing server name")
193
+	}
194
+	if !strings.Contains(strings.Trim(name, "."), ".") {
195
+		return nil, errors.New("acme/autocert: server name component count invalid")
196
+	}
197
+	if strings.ContainsAny(name, `/\`) {
198
+		return nil, errors.New("acme/autocert: server name contains invalid character")
199
+	}
200
+
201
+	// In the worst-case scenario, the timeout needs to account for caching, host policy,
202
+	// domain ownership verification and certificate issuance.
203
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
204
+	defer cancel()
205
+
206
+	// check whether this is a token cert requested for TLS-SNI challenge
207
+	if strings.HasSuffix(name, ".acme.invalid") {
208
+		m.tokensMu.RLock()
209
+		defer m.tokensMu.RUnlock()
210
+		if cert := m.certTokens[name]; cert != nil {
211
+			return cert, nil
212
+		}
213
+		if cert, err := m.cacheGet(ctx, name); err == nil {
214
+			return cert, nil
215
+		}
216
+		// TODO: cache error results?
217
+		return nil, fmt.Errorf("acme/autocert: no token cert for %q", name)
218
+	}
219
+
220
+	// regular domain
221
+	name = strings.TrimSuffix(name, ".") // golang.org/issue/18114
222
+	cert, err := m.cert(ctx, name)
223
+	if err == nil {
224
+		return cert, nil
225
+	}
226
+	if err != ErrCacheMiss {
227
+		return nil, err
228
+	}
229
+
230
+	// first-time
231
+	if err := m.hostPolicy()(ctx, name); err != nil {
232
+		return nil, err
233
+	}
234
+	cert, err = m.createCert(ctx, name)
235
+	if err != nil {
236
+		return nil, err
237
+	}
238
+	m.cachePut(ctx, name, cert)
239
+	return cert, nil
240
+}
241
+
242
+// HTTPHandler configures the Manager to provision ACME "http-01" challenge responses.
243
+// It returns an http.Handler that responds to the challenges and must be
244
+// running on port 80. If it receives a request that is not an ACME challenge,
245
+// it delegates the request to the optional fallback handler.
246
+//
247
+// If fallback is nil, the returned handler redirects all GET and HEAD requests
248
+// to the default TLS port 443 with 302 Found status code, preserving the original
249
+// request path and query. It responds with 400 Bad Request to all other HTTP methods.
250
+// The fallback is not protected by the optional HostPolicy.
251
+//
252
+// Because the fallback handler is run with unencrypted port 80 requests,
253
+// the fallback should not serve TLS-only requests.
254
+//
255
+// If HTTPHandler is never called, the Manager will only use TLS SNI
256
+// challenges for domain verification.
257
+func (m *Manager) HTTPHandler(fallback http.Handler) http.Handler {
258
+	m.tokensMu.Lock()
259
+	defer m.tokensMu.Unlock()
260
+	m.tryHTTP01 = true
261
+
262
+	if fallback == nil {
263
+		fallback = http.HandlerFunc(handleHTTPRedirect)
264
+	}
265
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
266
+		if !strings.HasPrefix(r.URL.Path, "/.well-known/acme-challenge/") {
267
+			fallback.ServeHTTP(w, r)
268
+			return
269
+		}
270
+		// A reasonable context timeout for cache and host policy only,
271
+		// because we don't wait for a new certificate issuance here.
272
+		ctx, cancel := context.WithTimeout(r.Context(), time.Minute)
273
+		defer cancel()
274
+		if err := m.hostPolicy()(ctx, r.Host); err != nil {
275
+			http.Error(w, err.Error(), http.StatusForbidden)
276
+			return
277
+		}
278
+		data, err := m.httpToken(ctx, r.URL.Path)
279
+		if err != nil {
280
+			http.Error(w, err.Error(), http.StatusNotFound)
281
+			return
282
+		}
283
+		w.Write(data)
284
+	})
285
+}
286
+
287
+func handleHTTPRedirect(w http.ResponseWriter, r *http.Request) {
288
+	if r.Method != "GET" && r.Method != "HEAD" {
289
+		http.Error(w, "Use HTTPS", http.StatusBadRequest)
290
+		return
291
+	}
292
+	target := "https://" + stripPort(r.Host) + r.URL.RequestURI()
293
+	http.Redirect(w, r, target, http.StatusFound)
294
+}
295
+
296
+func stripPort(hostport string) string {
297
+	host, _, err := net.SplitHostPort(hostport)
298
+	if err != nil {
299
+		return hostport
300
+	}
301
+	return net.JoinHostPort(host, "443")
302
+}
303
+
304
+// cert returns an existing certificate either from m.state or cache.
305
+// If a certificate is found in cache but not in m.state, the latter will be filled
306
+// with the cached value.
307
+func (m *Manager) cert(ctx context.Context, name string) (*tls.Certificate, error) {
308
+	m.stateMu.Lock()
309
+	if s, ok := m.state[name]; ok {
310
+		m.stateMu.Unlock()
311
+		s.RLock()
312
+		defer s.RUnlock()
313
+		return s.tlscert()
314
+	}
315
+	defer m.stateMu.Unlock()
316
+	cert, err := m.cacheGet(ctx, name)
317
+	if err != nil {
318
+		return nil, err
319
+	}
320
+	signer, ok := cert.PrivateKey.(crypto.Signer)
321
+	if !ok {
322
+		return nil, errors.New("acme/autocert: private key cannot sign")
323
+	}
324
+	if m.state == nil {
325
+		m.state = make(map[string]*certState)
326
+	}
327
+	s := &certState{
328
+		key:  signer,
329
+		cert: cert.Certificate,
330
+		leaf: cert.Leaf,
331
+	}
332
+	m.state[name] = s
333
+	go m.renew(name, s.key, s.leaf.NotAfter)
334
+	return cert, nil
335
+}
336
+
337
+// cacheGet always returns a valid certificate, or an error otherwise.
338
+// If a cached certficate exists but is not valid, ErrCacheMiss is returned.
339
+func (m *Manager) cacheGet(ctx context.Context, domain string) (*tls.Certificate, error) {
340
+	if m.Cache == nil {
341
+		return nil, ErrCacheMiss
342
+	}
343
+	data, err := m.Cache.Get(ctx, domain)
344
+	if err != nil {
345
+		return nil, err
346
+	}
347
+
348
+	// private
349
+	priv, pub := pem.Decode(data)
350
+	if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
351
+		return nil, ErrCacheMiss
352
+	}
353
+	privKey, err := parsePrivateKey(priv.Bytes)
354
+	if err != nil {
355
+		return nil, err
356
+	}
357
+
358
+	// public
359
+	var pubDER [][]byte
360
+	for len(pub) > 0 {
361
+		var b *pem.Block
362
+		b, pub = pem.Decode(pub)
363
+		if b == nil {
364
+			break
365
+		}
366
+		pubDER = append(pubDER, b.Bytes)
367
+	}
368
+	if len(pub) > 0 {
369
+		// Leftover content not consumed by pem.Decode. Corrupt. Ignore.
370
+		return nil, ErrCacheMiss
371
+	}
372
+
373
+	// verify and create TLS cert
374
+	leaf, err := validCert(domain, pubDER, privKey)
375
+	if err != nil {
376
+		return nil, ErrCacheMiss
377
+	}
378
+	tlscert := &tls.Certificate{
379
+		Certificate: pubDER,
380
+		PrivateKey:  privKey,
381
+		Leaf:        leaf,
382
+	}
383
+	return tlscert, nil
384
+}
385
+
386
+func (m *Manager) cachePut(ctx context.Context, domain string, tlscert *tls.Certificate) error {
387
+	if m.Cache == nil {
388
+		return nil
389
+	}
390
+
391
+	// contains PEM-encoded data
392
+	var buf bytes.Buffer
393
+
394
+	// private
395
+	switch key := tlscert.PrivateKey.(type) {
396
+	case *ecdsa.PrivateKey:
397
+		if err := encodeECDSAKey(&buf, key); err != nil {
398
+			return err
399
+		}
400
+	case *rsa.PrivateKey:
401
+		b := x509.MarshalPKCS1PrivateKey(key)
402
+		pb := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: b}
403
+		if err := pem.Encode(&buf, pb); err != nil {
404
+			return err
405
+		}
406
+	default:
407
+		return errors.New("acme/autocert: unknown private key type")
408
+	}
409
+
410
+	// public
411
+	for _, b := range tlscert.Certificate {
412
+		pb := &pem.Block{Type: "CERTIFICATE", Bytes: b}
413
+		if err := pem.Encode(&buf, pb); err != nil {
414
+			return err
415
+		}
416
+	}
417
+
418
+	return m.Cache.Put(ctx, domain, buf.Bytes())
419
+}
420
+
421
+func encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {
422
+	b, err := x509.MarshalECPrivateKey(key)
423
+	if err != nil {
424
+		return err
425
+	}
426
+	pb := &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
427
+	return pem.Encode(w, pb)
428
+}
429
+
430
+// createCert starts the domain ownership verification and returns a certificate
431
+// for that domain upon success.
432
+//
433
+// If the domain is already being verified, it waits for the existing verification to complete.
434
+// Either way, createCert blocks for the duration of the whole process.
435
+func (m *Manager) createCert(ctx context.Context, domain string) (*tls.Certificate, error) {
436
+	// TODO: maybe rewrite this whole piece using sync.Once
437
+	state, err := m.certState(domain)
438
+	if err != nil {
439
+		return nil, err
440
+	}
441
+	// state may exist if another goroutine is already working on it
442
+	// in which case just wait for it to finish
443
+	if !state.locked {
444
+		state.RLock()
445
+		defer state.RUnlock()
446
+		return state.tlscert()
447
+	}
448
+
449
+	// We are the first; state is locked.
450
+	// Unblock the readers when domain ownership is verified
451
+	// and we got the cert or the process failed.
452
+	defer state.Unlock()
453
+	state.locked = false
454
+
455
+	der, leaf, err := m.authorizedCert(ctx, state.key, domain)
456
+	if err != nil {
457
+		// Remove the failed state after some time,
458
+		// making the manager call createCert again on the following TLS hello.
459
+		time.AfterFunc(createCertRetryAfter, func() {
460
+			defer testDidRemoveState(domain)
461
+			m.stateMu.Lock()
462
+			defer m.stateMu.Unlock()
463
+			// Verify the state hasn't changed and it's still invalid
464
+			// before deleting.
465
+			s, ok := m.state[domain]
466
+			if !ok {
467
+				return
468
+			}
469
+			if _, err := validCert(domain, s.cert, s.key); err == nil {
470
+				return
471
+			}
472
+			delete(m.state, domain)
473
+		})
474
+		return nil, err
475
+	}
476
+	state.cert = der
477
+	state.leaf = leaf
478
+	go m.renew(domain, state.key, state.leaf.NotAfter)
479
+	return state.tlscert()
480
+}
481
+
482
+// certState returns a new or existing certState.
483
+// If a new certState is returned, state.exist is false and the state is locked.
484
+// The returned error is non-nil only in the case where a new state could not be created.
485
+func (m *Manager) certState(domain string) (*certState, error) {
486
+	m.stateMu.Lock()
487
+	defer m.stateMu.Unlock()
488
+	if m.state == nil {
489
+		m.state = make(map[string]*certState)
490
+	}
491
+	// existing state
492
+	if state, ok := m.state[domain]; ok {
493
+		return state, nil
494
+	}
495
+
496
+	// new locked state
497
+	var (
498
+		err error
499
+		key crypto.Signer
500
+	)
501
+	if m.ForceRSA {
502
+		key, err = rsa.GenerateKey(rand.Reader, 2048)
503
+	} else {
504
+		key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
505
+	}
506
+	if err != nil {
507
+		return nil, err
508
+	}
509
+
510
+	state := &certState{
511
+		key:    key,
512
+		locked: true,
513
+	}
514
+	state.Lock() // will be unlocked by m.certState caller
515
+	m.state[domain] = state
516
+	return state, nil
517
+}
518
+
519
+// authorizedCert starts the domain ownership verification process and requests a new cert upon success.
520
+// The key argument is the certificate private key.
521
+func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain string) (der [][]byte, leaf *x509.Certificate, err error) {
522
+	client, err := m.acmeClient(ctx)
523
+	if err != nil {
524
+		return nil, nil, err
525
+	}
526
+
527
+	if err := m.verify(ctx, client, domain); err != nil {
528
+		return nil, nil, err
529
+	}
530
+	csr, err := certRequest(key, domain)
531
+	if err != nil {
532
+		return nil, nil, err
533
+	}
534
+	der, _, err = client.CreateCert(ctx, csr, 0, true)
535
+	if err != nil {
536
+		return nil, nil, err
537
+	}
538
+	leaf, err = validCert(domain, der, key)
539
+	if err != nil {
540
+		return nil, nil, err
541
+	}
542
+	return der, leaf, nil
543
+}
544
+
545
+// verify runs the identifier (domain) authorization flow
546
+// using each applicable ACME challenge type.
547
+func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string) error {
548
+	// The list of challenge types we'll try to fulfill
549
+	// in this specific order.
550
+	challengeTypes := []string{"tls-sni-02", "tls-sni-01"}
551
+	m.tokensMu.RLock()
552
+	if m.tryHTTP01 {
553
+		challengeTypes = append(challengeTypes, "http-01")
554
+	}
555
+	m.tokensMu.RUnlock()
556
+
557
+	var nextTyp int // challengeType index of the next challenge type to try
558
+	for {
559
+		// Start domain authorization and get the challenge.
560
+		authz, err := client.Authorize(ctx, domain)
561
+		if err != nil {
562
+			return err
563
+		}
564
+		// No point in accepting challenges if the authorization status
565
+		// is in a final state.
566
+		switch authz.Status {
567
+		case acme.StatusValid:
568
+			return nil // already authorized
569
+		case acme.StatusInvalid:
570
+			return fmt.Errorf("acme/autocert: invalid authorization %q", authz.URI)
571
+		}
572
+
573
+		// Pick the next preferred challenge.
574
+		var chal *acme.Challenge
575
+		for chal == nil && nextTyp < len(challengeTypes) {
576
+			chal = pickChallenge(challengeTypes[nextTyp], authz.Challenges)
577
+			nextTyp++
578
+		}
579
+		if chal == nil {
580
+			return fmt.Errorf("acme/autocert: unable to authorize %q; tried %q", domain, challengeTypes)
581
+		}
582
+		cleanup, err := m.fulfill(ctx, client, chal)
583
+		if err != nil {
584
+			continue
585
+		}
586
+		defer cleanup()
587
+		if _, err := client.Accept(ctx, chal); err != nil {
588
+			continue
589
+		}
590
+
591
+		// A challenge is fulfilled and accepted: wait for the CA to validate.
592
+		if _, err := client.WaitAuthorization(ctx, authz.URI); err == nil {
593
+			return nil
594
+		}
595
+	}
596
+}
597
+
598
+// fulfill provisions a response to the challenge chal.
599
+// The cleanup is non-nil only if provisioning succeeded.
600
+func (m *Manager) fulfill(ctx context.Context, client *acme.Client, chal *acme.Challenge) (cleanup func(), err error) {
601
+	switch chal.Type {
602
+	case "tls-sni-01":
603
+		cert, name, err := client.TLSSNI01ChallengeCert(chal.Token)
604
+		if err != nil {
605
+			return nil, err
606
+		}
607
+		m.putCertToken(ctx, name, &cert)
608
+		return func() { go m.deleteCertToken(name) }, nil
609
+	case "tls-sni-02":
610
+		cert, name, err := client.TLSSNI02ChallengeCert(chal.Token)
611
+		if err != nil {
612
+			return nil, err
613
+		}
614
+		m.putCertToken(ctx, name, &cert)
615
+		return func() { go m.deleteCertToken(name) }, nil
616
+	case "http-01":
617
+		resp, err := client.HTTP01ChallengeResponse(chal.Token)
618
+		if err != nil {
619
+			return nil, err
620
+		}
621
+		p := client.HTTP01ChallengePath(chal.Token)
622
+		m.putHTTPToken(ctx, p, resp)
623
+		return func() { go m.deleteHTTPToken(p) }, nil
624
+	}
625
+	return nil, fmt.Errorf("acme/autocert: unknown challenge type %q", chal.Type)
626
+}
627
+
628
+func pickChallenge(typ string, chal []*acme.Challenge) *acme.Challenge {
629
+	for _, c := range chal {
630
+		if c.Type == typ {
631
+			return c
632
+		}
633
+	}
634
+	return nil
635
+}
636
+
637
+// putCertToken stores the cert under the named key in both m.certTokens map
638
+// and m.Cache.
639
+func (m *Manager) putCertToken(ctx context.Context, name string, cert *tls.Certificate) {
640
+	m.tokensMu.Lock()
641
+	defer m.tokensMu.Unlock()
642
+	if m.certTokens == nil {
643
+		m.certTokens = make(map[string]*tls.Certificate)
644
+	}
645
+	m.certTokens[name] = cert
646
+	m.cachePut(ctx, name, cert)
647
+}
648
+
649
+// deleteCertToken removes the token certificate for the specified domain name
650
+// from both m.certTokens map and m.Cache.
651
+func (m *Manager) deleteCertToken(name string) {
652
+	m.tokensMu.Lock()
653
+	defer m.tokensMu.Unlock()
654
+	delete(m.certTokens, name)
655
+	if m.Cache != nil {
656
+		m.Cache.Delete(context.Background(), name)
657
+	}
658
+}
659
+
660
+// httpToken retrieves an existing http-01 token value from an in-memory map
661
+// or the optional cache.
662
+func (m *Manager) httpToken(ctx context.Context, tokenPath string) ([]byte, error) {
663
+	m.tokensMu.RLock()
664
+	defer m.tokensMu.RUnlock()
665
+	if v, ok := m.httpTokens[tokenPath]; ok {
666
+		return v, nil
667
+	}
668
+	if m.Cache == nil {
669
+		return nil, fmt.Errorf("acme/autocert: no token at %q", tokenPath)
670
+	}
671
+	return m.Cache.Get(ctx, httpTokenCacheKey(tokenPath))
672
+}
673
+
674
+// putHTTPToken stores an http-01 token value using tokenPath as key
675
+// in both in-memory map and the optional Cache.
676
+//
677
+// It ignores any error returned from Cache.Put.
678
+func (m *Manager) putHTTPToken(ctx context.Context, tokenPath, val string) {
679
+	m.tokensMu.Lock()
680
+	defer m.tokensMu.Unlock()
681
+	if m.httpTokens == nil {
682
+		m.httpTokens = make(map[string][]byte)
683
+	}
684
+	b := []byte(val)
685
+	m.httpTokens[tokenPath] = b
686
+	if m.Cache != nil {
687
+		m.Cache.Put(ctx, httpTokenCacheKey(tokenPath), b)
688
+	}
689
+}
690
+
691
+// deleteHTTPToken removes an http-01 token value from both in-memory map
692
+// and the optional Cache, ignoring any error returned from the latter.
693
+//
694
+// If m.Cache is non-nil, it blocks until Cache.Delete returns without a timeout.
695
+func (m *Manager) deleteHTTPToken(tokenPath string) {
696
+	m.tokensMu.Lock()
697
+	defer m.tokensMu.Unlock()
698
+	delete(m.httpTokens, tokenPath)
699
+	if m.Cache != nil {
700
+		m.Cache.Delete(context.Background(), httpTokenCacheKey(tokenPath))
701
+	}
702
+}
703
+
704
+// httpTokenCacheKey returns a key at which an http-01 token value may be stored
705
+// in the Manager's optional Cache.
706
+func httpTokenCacheKey(tokenPath string) string {
707
+	return "http-01-" + path.Base(tokenPath)
708
+}
709
+
710
+// renew starts a cert renewal timer loop, one per domain.
711
+//
712
+// The loop is scheduled in two cases:
713
+// - a cert was fetched from cache for the first time (wasn't in m.state)
714
+// - a new cert was created by m.createCert
715
+//
716
+// The key argument is a certificate private key.
717
+// The exp argument is the cert expiration time (NotAfter).
718
+func (m *Manager) renew(domain string, key crypto.Signer, exp time.Time) {
719
+	m.renewalMu.Lock()
720
+	defer m.renewalMu.Unlock()
721
+	if m.renewal[domain] != nil {
722
+		// another goroutine is already on it
723
+		return
724
+	}
725
+	if m.renewal == nil {
726
+		m.renewal = make(map[string]*domainRenewal)
727
+	}
728
+	dr := &domainRenewal{m: m, domain: domain, key: key}
729
+	m.renewal[domain] = dr
730
+	dr.start(exp)
731
+}
732
+
733
+// stopRenew stops all currently running cert renewal timers.
734
+// The timers are not restarted during the lifetime of the Manager.
735
+func (m *Manager) stopRenew() {
736
+	m.renewalMu.Lock()
737
+	defer m.renewalMu.Unlock()
738
+	for name, dr := range m.renewal {
739
+		delete(m.renewal, name)
740
+		dr.stop()
741
+	}
742
+}
743
+
744
+func (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {
745
+	const keyName = "acme_account.key"
746
+
747
+	genKey := func() (*ecdsa.PrivateKey, error) {
748
+		return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
749
+	}
750
+
751
+	if m.Cache == nil {
752
+		return genKey()
753
+	}
754
+
755
+	data, err := m.Cache.Get(ctx, keyName)
756
+	if err == ErrCacheMiss {
757
+		key, err := genKey()
758
+		if err != nil {
759
+			return nil, err
760
+		}
761
+		var buf bytes.Buffer
762
+		if err := encodeECDSAKey(&buf, key); err != nil {
763
+			return nil, err
764
+		}
765
+		if err := m.Cache.Put(ctx, keyName, buf.Bytes()); err != nil {
766
+			return nil, err
767
+		}
768
+		return key, nil
769
+	}
770
+	if err != nil {
771
+		return nil, err
772
+	}
773
+
774
+	priv, _ := pem.Decode(data)
775
+	if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
776
+		return nil, errors.New("acme/autocert: invalid account key found in cache")
777
+	}
778
+	return parsePrivateKey(priv.Bytes)
779
+}
780
+
781
+func (m *Manager) acmeClient(ctx context.Context) (*acme.Client, error) {
782
+	m.clientMu.Lock()
783
+	defer m.clientMu.Unlock()
784
+	if m.client != nil {
785
+		return m.client, nil
786
+	}
787
+
788
+	client := m.Client
789
+	if client == nil {
790
+		client = &acme.Client{DirectoryURL: acme.LetsEncryptURL}
791
+	}
792
+	if client.Key == nil {
793
+		var err error
794
+		client.Key, err = m.accountKey(ctx)
795
+		if err != nil {
796
+			return nil, err
797
+		}
798
+	}
799
+	var contact []string
800
+	if m.Email != "" {
801
+		contact = []string{"mailto:" + m.Email}
802
+	}
803
+	a := &acme.Account{Contact: contact}
804
+	_, err := client.Register(ctx, a, m.Prompt)
805
+	if ae, ok := err.(*acme.Error); err == nil || ok && ae.StatusCode == http.StatusConflict {
806
+		// conflict indicates the key is already registered
807
+		m.client = client
808
+		err = nil
809
+	}
810
+	return m.client, err
811
+}
812
+
813
+func (m *Manager) hostPolicy() HostPolicy {
814
+	if m.HostPolicy != nil {
815
+		return m.HostPolicy
816
+	}
817
+	return defaultHostPolicy
818
+}
819
+
820
+func (m *Manager) renewBefore() time.Duration {
821
+	if m.RenewBefore > renewJitter {
822
+		return m.RenewBefore
823
+	}
824
+	return 720 * time.Hour // 30 days
825
+}
826
+
827
+// certState is ready when its mutex is unlocked for reading.
828
+type certState struct {
829
+	sync.RWMutex
830
+	locked bool              // locked for read/write
831
+	key    crypto.Signer     // private key for cert
832
+	cert   [][]byte          // DER encoding
833
+	leaf   *x509.Certificate // parsed cert[0]; always non-nil if cert != nil
834
+}
835
+
836
+// tlscert creates a tls.Certificate from s.key and s.cert.
837
+// Callers should wrap it in s.RLock() and s.RUnlock().
838
+func (s *certState) tlscert() (*tls.Certificate, error) {
839
+	if s.key == nil {
840
+		return nil, errors.New("acme/autocert: missing signer")
841
+	}
842
+	if len(s.cert) == 0 {
843
+		return nil, errors.New("acme/autocert: missing certificate")
844
+	}
845
+	return &tls.Certificate{
846
+		PrivateKey:  s.key,
847
+		Certificate: s.cert,
848
+		Leaf:        s.leaf,
849
+	}, nil
850
+}
851
+
852
+// certRequest creates a certificate request for the given common name cn
853
+// and optional SANs.
854
+func certRequest(key crypto.Signer, cn string, san ...string) ([]byte, error) {
855
+	req := &x509.CertificateRequest{
856
+		Subject:  pkix.Name{CommonName: cn},
857
+		DNSNames: san,
858
+	}
859
+	return x509.CreateCertificateRequest(rand.Reader, req, key)
860
+}
861
+
862
+// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
863
+// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
864
+// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
865
+//
866
+// Inspired by parsePrivateKey in crypto/tls/tls.go.
867
+func parsePrivateKey(der []byte) (crypto.Signer, error) {
868
+	if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
869
+		return key, nil
870
+	}
871
+	if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
872
+		switch key := key.(type) {
873
+		case *rsa.PrivateKey:
874
+			return key, nil
875
+		case *ecdsa.PrivateKey:
876
+			return key, nil
877
+		default:
878
+			return nil, errors.New("acme/autocert: unknown private key type in PKCS#8 wrapping")
879
+		}
880
+	}
881
+	if key, err := x509.ParseECPrivateKey(der); err == nil {
882
+		return key, nil
883
+	}
884
+
885
+	return nil, errors.New("acme/autocert: failed to parse private key")
886
+}
887
+
888
+// validCert parses a cert chain provided as der argument and verifies the leaf, der[0],
889
+// corresponds to the private key, as well as the domain match and expiration dates.
890
+// It doesn't do any revocation checking.
891
+//
892
+// The returned value is the verified leaf cert.
893
+func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certificate, err error) {
894
+	// parse public part(s)
895
+	var n int
896
+	for _, b := range der {
897
+		n += len(b)
898
+	}
899
+	pub := make([]byte, n)
900
+	n = 0
901
+	for _, b := range der {
902
+		n += copy(pub[n:], b)
903
+	}
904
+	x509Cert, err := x509.ParseCertificates(pub)
905
+	if len(x509Cert) == 0 {
906
+		return nil, errors.New("acme/autocert: no public key found")
907
+	}
908
+	// verify the leaf is not expired and matches the domain name
909
+	leaf = x509Cert[0]
910
+	now := timeNow()
911
+	if now.Before(leaf.NotBefore) {
912
+		return nil, errors.New("acme/autocert: certificate is not valid yet")
913
+	}
914
+	if now.After(leaf.NotAfter) {
915
+		return nil, errors.New("acme/autocert: expired certificate")
916
+	}
917
+	if err := leaf.VerifyHostname(domain); err != nil {
918
+		return nil, err
919
+	}
920
+	// ensure the leaf corresponds to the private key
921
+	switch pub := leaf.PublicKey.(type) {
922
+	case *rsa.PublicKey:
923
+		prv, ok := key.(*rsa.PrivateKey)
924
+		if !ok {
925
+			return nil, errors.New("acme/autocert: private key type does not match public key type")
926
+		}
927
+		if pub.N.Cmp(prv.N) != 0 {
928
+			return nil, errors.New("acme/autocert: private key does not match public key")
929
+		}
930
+	case *ecdsa.PublicKey:
931
+		prv, ok := key.(*ecdsa.PrivateKey)
932
+		if !ok {
933
+			return nil, errors.New("acme/autocert: private key type does not match public key type")
934
+		}
935
+		if pub.X.Cmp(prv.X) != 0 || pub.Y.Cmp(prv.Y) != 0 {
936
+			return nil, errors.New("acme/autocert: private key does not match public key")
937
+		}
938
+	default:
939
+		return nil, errors.New("acme/autocert: unknown public key algorithm")
940
+	}
941
+	return leaf, nil
942
+}
943
+
944
+type lockedMathRand struct {
945
+	sync.Mutex
946
+	rnd *mathrand.Rand
947
+}
948
+
949
+func (r *lockedMathRand) int63n(max int64) int64 {
950
+	r.Lock()
951
+	n := r.rnd.Int63n(max)
952
+	r.Unlock()
953
+	return n
954
+}
955
+
956
+// For easier testing.
957
+var (
958
+	timeNow = time.Now
959
+
960
+	// Called when a state is removed.
961
+	testDidRemoveState = func(domain string) {}
962
+)

+ 130
- 0
vendor/golang.org/x/crypto/acme/autocert/cache.go View File

@@ -0,0 +1,130 @@
1
+// Copyright 2016 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+package autocert
6
+
7
+import (
8
+	"context"
9
+	"errors"
10
+	"io/ioutil"
11
+	"os"
12
+	"path/filepath"
13
+)
14
+
15
+// ErrCacheMiss is returned when a certificate is not found in cache.
16
+var ErrCacheMiss = errors.New("acme/autocert: certificate cache miss")
17
+
18
+// Cache is used by Manager to store and retrieve previously obtained certificates
19
+// as opaque data.
20
+//
21
+// The key argument of the methods refers to a domain name but need not be an FQDN.
22
+// Cache implementations should not rely on the key naming pattern.
23
+type Cache interface {
24
+	// Get returns a certificate data for the specified key.
25
+	// If there's no such key, Get returns ErrCacheMiss.
26
+	Get(ctx context.Context, key string) ([]byte, error)
27
+
28
+	// Put stores the data in the cache under the specified key.
29
+	// Underlying implementations may use any data storage format,
30
+	// as long as the reverse operation, Get, results in the original data.
31
+	Put(ctx context.Context, key string, data []byte) error
32
+
33
+	// Delete removes a certificate data from the cache under the specified key.
34
+	// If there's no such key in the cache, Delete returns nil.
35
+	Delete(ctx context.Context, key string) error
36
+}
37
+
38
+// DirCache implements Cache using a directory on the local filesystem.
39
+// If the directory does not exist, it will be created with 0700 permissions.
40
+type DirCache string
41
+
42
+// Get reads a certificate data from the specified file name.
43
+func (d DirCache) Get(ctx context.Context, name string) ([]byte, error) {
44
+	name = filepath.Join(string(d), name)
45
+	var (
46
+		data []byte
47
+		err  error
48
+		done = make(chan struct{})
49
+	)
50
+	go func() {
51
+		data, err = ioutil.ReadFile(name)
52
+		close(done)
53
+	}()
54
+	select {
55
+	case <-ctx.Done():
56
+		return nil, ctx.Err()
57
+	case <-done:
58
+	}
59
+	if os.IsNotExist(err) {
60
+		return nil, ErrCacheMiss
61
+	}
62
+	return data, err
63
+}
64
+
65
+// Put writes the certificate data to the specified file name.
66
+// The file will be created with 0600 permissions.
67
+func (d DirCache) Put(ctx context.Context, name string, data []byte) error {
68
+	if err := os.MkdirAll(string(d), 0700); err != nil {
69
+		return err
70
+	}
71
+
72
+	done := make(chan struct{})
73
+	var err error
74
+	go func() {
75
+		defer close(done)
76
+		var tmp string
77
+		if tmp, err = d.writeTempFile(name, data); err != nil {
78
+			return
79
+		}
80
+		select {
81
+		case <-ctx.Done():
82
+			// Don't overwrite the file if the context was canceled.
83
+		default:
84
+			newName := filepath.Join(string(d), name)
85
+			err = os.Rename(tmp, newName)
86
+		}
87
+	}()
88
+	select {
89
+	case <-ctx.Done():
90
+		return ctx.Err()
91
+	case <-done:
92
+	}
93
+	return err
94
+}
95
+
96
+// Delete removes the specified file name.
97
+func (d DirCache) Delete(ctx context.Context, name string) error {
98
+	name = filepath.Join(string(d), name)
99
+	var (
100
+		err  error
101
+		done = make(chan struct{})
102
+	)
103
+	go func() {
104
+		err = os.Remove(name)
105
+		close(done)
106
+	}()
107
+	select {
108
+	case <-ctx.Done():
109
+		return ctx.Err()
110
+	case <-done:
111
+	}
112
+	if err != nil && !os.IsNotExist(err) {
113
+		return err
114
+	}
115
+	return nil
116
+}
117
+
118
+// writeTempFile writes b to a temporary file, closes the file and returns its path.
119
+func (d DirCache) writeTempFile(prefix string, b []byte) (string, error) {
120
+	// TempFile uses 0600 permissions
121
+	f, err := ioutil.TempFile(string(d), prefix)
122
+	if err != nil {
123
+		return "", err
124
+	}
125
+	if _, err := f.Write(b); err != nil {
126
+		f.Close()
127
+		return "", err
128
+	}
129
+	return f.Name(), f.Close()
130
+}

+ 160
- 0
vendor/golang.org/x/crypto/acme/autocert/listener.go View File

@@ -0,0 +1,160 @@
1
+// Copyright 2017 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+package autocert
6
+
7
+import (
8
+	"crypto/tls"
9
+	"log"
10
+	"net"
11
+	"os"
12
+	"path/filepath"
13
+	"runtime"
14
+	"time"
15
+)
16
+
17
+// NewListener returns a net.Listener that listens on the standard TLS
18
+// port (443) on all interfaces and returns *tls.Conn connections with
19
+// LetsEncrypt certificates for the provided domain or domains.
20
+//
21
+// It enables one-line HTTPS servers:
22
+//
23
+//     log.Fatal(http.Serve(autocert.NewListener("example.com"), handler))
24
+//
25
+// NewListener is a convenience function for a common configuration.
26
+// More complex or custom configurations can use the autocert.Manager
27
+// type instead.
28
+//
29
+// Use of this function implies acceptance of the LetsEncrypt Terms of
30
+// Service. If domains is not empty, the provided domains are passed
31
+// to HostWhitelist. If domains is empty, the listener will do
32
+// LetsEncrypt challenges for any requested domain, which is not
33
+// recommended.
34
+//
35
+// Certificates are cached in a "golang-autocert" directory under an
36
+// operating system-specific cache or temp directory. This may not
37
+// be suitable for servers spanning multiple machines.
38
+//
39
+// The returned listener uses a *tls.Config that enables HTTP/2, and
40
+// should only be used with servers that support HTTP/2.
41
+//
42
+// The returned Listener also enables TCP keep-alives on the accepted
43
+// connections. The returned *tls.Conn are returned before their TLS
44
+// handshake has completed.
45
+func NewListener(domains ...string) net.Listener {
46
+	m := &Manager{
47
+		Prompt: AcceptTOS,
48
+	}
49
+	if len(domains) > 0 {
50
+		m.HostPolicy = HostWhitelist(domains...)
51
+	}
52
+	dir := cacheDir()
53
+	if err := os.MkdirAll(dir, 0700); err != nil {
54
+		log.Printf("warning: autocert.NewListener not using a cache: %v", err)
55
+	} else {
56
+		m.Cache = DirCache(dir)
57
+	}
58
+	return m.Listener()
59
+}
60
+
61
+// Listener listens on the standard TLS port (443) on all interfaces
62
+// and returns a net.Listener returning *tls.Conn connections.
63
+//
64
+// The returned listener uses a *tls.Config that enables HTTP/2, and
65
+// should only be used with servers that support HTTP/2.
66
+//
67
+// The returned Listener also enables TCP keep-alives on the accepted
68
+// connections. The returned *tls.Conn are returned before their TLS
69
+// handshake has completed.
70
+//
71
+// Unlike NewListener, it is the caller's responsibility to initialize
72
+// the Manager m's Prompt, Cache, HostPolicy, and other desired options.
73
+func (m *Manager) Listener() net.Listener {
74
+	ln := &listener{
75
+		m: m,
76
+		conf: &tls.Config{
77
+			GetCertificate: m.GetCertificate,           // bonus: panic on nil m
78
+			NextProtos:     []string{"h2", "http/1.1"}, // Enable HTTP/2
79
+		},
80
+	}
81
+	ln.tcpListener, ln.tcpListenErr = net.Listen("tcp", ":443")
82
+	return ln
83
+}
84
+
85
+type listener struct {
86
+	m    *Manager
87
+	conf *tls.Config
88
+
89
+	tcpListener  net.Listener
90
+	tcpListenErr error
91
+}
92
+
93
+func (ln *listener) Accept() (net.Conn, error) {
94
+	if ln.tcpListenErr != nil {
95
+		return nil, ln.tcpListenErr
96
+	}
97
+	conn, err := ln.tcpListener.Accept()
98
+	if err != nil {
99
+		return nil, err
100
+	}
101
+	tcpConn := conn.(*net.TCPConn)
102
+
103
+	// Because Listener is a convenience function, help out with
104
+	// this too.  This is not possible for the caller to set once
105
+	// we return a *tcp.Conn wrapping an inaccessible net.Conn.
106
+	// If callers don't want this, they can do things the manual
107
+	// way and tweak as needed. But this is what net/http does
108
+	// itself, so copy that. If net/http changes, we can change
109
+	// here too.
110
+	tcpConn.SetKeepAlive(true)
111
+	tcpConn.SetKeepAlivePeriod(3 * time.Minute)
112
+
113
+	return tls.Server(tcpConn, ln.conf), nil
114
+}
115
+
116
+func (ln *listener) Addr() net.Addr {
117
+	if ln.tcpListener != nil {
118
+		return ln.tcpListener.Addr()
119
+	}
120
+	// net.Listen failed. Return something non-nil in case callers
121
+	// call Addr before Accept:
122
+	return &net.TCPAddr{IP: net.IP{0, 0, 0, 0}, Port: 443}
123
+}
124
+
125
+func (ln *listener) Close() error {
126
+	if ln.tcpListenErr != nil {
127
+		return ln.tcpListenErr
128
+	}
129
+	return ln.tcpListener.Close()
130
+}
131
+
132
+func homeDir() string {
133
+	if runtime.GOOS == "windows" {
134
+		return os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
135
+	}
136
+	if h := os.Getenv("HOME"); h != "" {
137
+		return h
138
+	}
139
+	return "/"
140
+}
141
+
142
+func cacheDir() string {
143
+	const base = "golang-autocert"
144
+	switch runtime.GOOS {
145
+	case "darwin":
146
+		return filepath.Join(homeDir(), "Library", "Caches", base)
147
+	case "windows":
148
+		for _, ev := range []string{"APPDATA", "CSIDL_APPDATA", "TEMP", "TMP"} {
149
+			if v := os.Getenv(ev); v != "" {
150
+				return filepath.Join(v, base)
151
+			}
152
+		}
153
+		// Worst case:
154
+		return filepath.Join(homeDir(), base)
155
+	}
156
+	if xdg := os.Getenv("XDG_CACHE_HOME"); xdg != "" {
157
+		return filepath.Join(xdg, base)
158
+	}
159
+	return filepath.Join(homeDir(), ".cache", base)
160
+}

+ 141
- 0
vendor/golang.org/x/crypto/acme/autocert/renewal.go View File

@@ -0,0 +1,141 @@
1
+// Copyright 2016 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+package autocert
6
+
7
+import (
8
+	"context"
9
+	"crypto"
10
+	"sync"
11
+	"time"
12
+)
13
+
14
+// renewJitter is the maximum deviation from Manager.RenewBefore.
15
+const renewJitter = time.Hour
16
+
17
+// domainRenewal tracks the state used by the periodic timers
18
+// renewing a single domain's cert.
19
+type domainRenewal struct {
20
+	m      *Manager
21
+	domain string
22
+	key    crypto.Signer
23
+
24
+	timerMu sync.Mutex
25
+	timer   *time.Timer
26
+}
27
+
28
+// start starts a cert renewal timer at the time
29
+// defined by the certificate expiration time exp.
30
+//
31
+// If the timer is already started, calling start is a noop.
32
+func (dr *domainRenewal) start(exp time.Time) {
33
+	dr.timerMu.Lock()
34
+	defer dr.timerMu.Unlock()
35
+	if dr.timer != nil {
36
+		return
37
+	}
38
+	dr.timer = time.AfterFunc(dr.next(exp), dr.renew)
39
+}
40
+
41
+// stop stops the cert renewal timer.
42
+// If the timer is already stopped, calling stop is a noop.
43
+func (dr *domainRenewal) stop() {
44
+	dr.timerMu.Lock()
45
+	defer dr.timerMu.Unlock()
46
+	if dr.timer == nil {
47
+		return
48
+	}
49
+	dr.timer.Stop()
50
+	dr.timer = nil
51
+}
52
+
53
+// renew is called periodically by a timer.
54
+// The first renew call is kicked off by dr.start.
55
+func (dr *domainRenewal) renew() {
56
+	dr.timerMu.Lock()
57
+	defer dr.timerMu.Unlock()
58
+	if dr.timer == nil {
59
+		return
60
+	}
61
+
62
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
63
+	defer cancel()
64
+	// TODO: rotate dr.key at some point?
65
+	next, err := dr.do(ctx)
66
+	if err != nil {
67
+		next = renewJitter / 2
68
+		next += time.Duration(pseudoRand.int63n(int64(next)))
69
+	}
70
+	dr.timer = time.AfterFunc(next, dr.renew)
71
+	testDidRenewLoop(next, err)
72
+}
73
+
74
+// updateState locks and replaces the relevant Manager.state item with the given
75
+// state. It additionally updates dr.key with the given state's key.
76
+func (dr *domainRenewal) updateState(state *certState) {
77
+	dr.m.stateMu.Lock()
78
+	defer dr.m.stateMu.Unlock()
79
+	dr.key = state.key
80
+	dr.m.state[dr.domain] = state
81
+}
82
+
83
+// do is similar to Manager.createCert but it doesn't lock a Manager.state item.
84
+// Instead, it requests a new certificate independently and, upon success,
85
+// replaces dr.m.state item with a new one and updates cache for the given domain.
86
+//
87
+// It may lock and update the Manager.state if the expiration date of the currently
88
+// cached cert is far enough in the future.
89
+//
90
+// The returned value is a time interval after which the renewal should occur again.
91
+func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {
92
+	// a race is likely unavoidable in a distributed environment
93
+	// but we try nonetheless
94
+	if tlscert, err := dr.m.cacheGet(ctx, dr.domain); err == nil {
95
+		next := dr.next(tlscert.Leaf.NotAfter)
96
+		if next > dr.m.renewBefore()+renewJitter {
97
+			signer, ok := tlscert.PrivateKey.(crypto.Signer)
98
+			if ok {
99
+				state := &certState{
100
+					key:  signer,
101
+					cert: tlscert.Certificate,
102
+					leaf: tlscert.Leaf,
103
+				}
104
+				dr.updateState(state)
105
+				return next, nil
106
+			}
107
+		}
108
+	}
109
+
110
+	der, leaf, err := dr.m.authorizedCert(ctx, dr.key, dr.domain)
111
+	if err != nil {
112
+		return 0, err
113
+	}
114
+	state := &certState{
115
+		key:  dr.key,
116
+		cert: der,
117
+		leaf: leaf,
118
+	}
119
+	tlscert, err := state.tlscert()
120
+	if err != nil {
121
+		return 0, err
122
+	}
123
+	if err := dr.m.cachePut(ctx, dr.domain, tlscert); err != nil {
124
+		return 0, err
125
+	}
126
+	dr.updateState(state)
127
+	return dr.next(leaf.NotAfter), nil
128
+}
129
+
130
+func (dr *domainRenewal) next(expiry time.Time) time.Duration {
131
+	d := expiry.Sub(timeNow()) - dr.m.renewBefore()
132
+	// add a bit of randomness to renew deadline
133
+	n := pseudoRand.int63n(int64(renewJitter))
134
+	d -= time.Duration(n)
135
+	if d < 0 {
136
+		return 0
137
+	}
138
+	return d
139
+}
140
+
141
+var testDidRenewLoop = func(next time.Duration, err error) {}

+ 153
- 0
vendor/golang.org/x/crypto/acme/jws.go View File

@@ -0,0 +1,153 @@
1
+// Copyright 2015 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+package acme
6
+
7
+import (
8
+	"crypto"
9
+	"crypto/ecdsa"
10
+	"crypto/rand"
11
+	"crypto/rsa"
12
+	"crypto/sha256"
13
+	_ "crypto/sha512" // need for EC keys
14
+	"encoding/base64"
15
+	"encoding/json"
16
+	"fmt"
17
+	"math/big"
18
+)
19
+
20
+// jwsEncodeJSON signs claimset using provided key and a nonce.
21
+// The result is serialized in JSON format.
22
+// See https://tools.ietf.org/html/rfc7515#section-7.
23
+func jwsEncodeJSON(claimset interface{}, key crypto.Signer, nonce string) ([]byte, error) {
24
+	jwk, err := jwkEncode(key.Public())
25
+	if err != nil {
26
+		return nil, err
27
+	}
28
+	alg, sha := jwsHasher(key)
29
+	if alg == "" || !sha.Available() {
30
+		return nil, ErrUnsupportedKey
31
+	}
32
+	phead := fmt.Sprintf(`{"alg":%q,"jwk":%s,"nonce":%q}`, alg, jwk, nonce)
33
+	phead = base64.RawURLEncoding.EncodeToString([]byte(phead))
34
+	cs, err := json.Marshal(claimset)
35
+	if err != nil {
36
+		return nil, err
37
+	}
38
+	payload := base64.RawURLEncoding.EncodeToString(cs)
39
+	hash := sha.New()
40
+	hash.Write([]byte(phead + "." + payload))
41
+	sig, err := jwsSign(key, sha, hash.Sum(nil))
42
+	if err != nil {
43
+		return nil, err
44
+	}
45
+
46
+	enc := struct {
47
+		Protected string `json:"protected"`
48
+		Payload   string `json:"payload"`
49
+		Sig       string `json:"signature"`
50
+	}{
51
+		Protected: phead,
52
+		Payload:   payload,
53
+		Sig:       base64.RawURLEncoding.EncodeToString(sig),
54
+	}
55
+	return json.Marshal(&enc)
56
+}
57
+
58
+// jwkEncode encodes public part of an RSA or ECDSA key into a JWK.
59
+// The result is also suitable for creating a JWK thumbprint.
60
+// https://tools.ietf.org/html/rfc7517
61
+func jwkEncode(pub crypto.PublicKey) (string, error) {
62
+	switch pub := pub.(type) {
63
+	case *rsa.PublicKey:
64
+		// https://tools.ietf.org/html/rfc7518#section-6.3.1
65
+		n := pub.N
66
+		e := big.NewInt(int64(pub.E))
67
+		// Field order is important.
68
+		// See https://tools.ietf.org/html/rfc7638#section-3.3 for details.
69
+		return fmt.Sprintf(`{"e":"%s","kty":"RSA","n":"%s"}`,
70
+			base64.RawURLEncoding.EncodeToString(e.Bytes()),
71
+			base64.RawURLEncoding.EncodeToString(n.Bytes()),
72
+		), nil
73
+	case *ecdsa.PublicKey:
74
+		// https://tools.ietf.org/html/rfc7518#section-6.2.1
75
+		p := pub.Curve.Params()
76
+		n := p.BitSize / 8
77
+		if p.BitSize%8 != 0 {
78
+			n++
79
+		}
80
+		x := pub.X.Bytes()
81
+		if n > len(x) {
82
+			x = append(make([]byte, n-len(x)), x...)
83
+		}
84
+		y := pub.Y.Bytes()
85
+		if n > len(y) {
86
+			y = append(make([]byte, n-len(y)), y...)
87
+		}
88
+		// Field order is important.
89
+		// See https://tools.ietf.org/html/rfc7638#section-3.3 for details.
90
+		return fmt.Sprintf(`{"crv":"%s","kty":"EC","x":"%s","y":"%s"}`,
91
+			p.Name,
92
+			base64.RawURLEncoding.EncodeToString(x),
93
+			base64.RawURLEncoding.EncodeToString(y),
94
+		), nil
95
+	}
96
+	return "", ErrUnsupportedKey
97
+}
98
+
99
+// jwsSign signs the digest using the given key.
100
+// It returns ErrUnsupportedKey if the key type is unknown.
101
+// The hash is used only for RSA keys.
102
+func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) {
103
+	switch key := key.(type) {
104
+	case *rsa.PrivateKey:
105
+		return key.Sign(rand.Reader, digest, hash)
106
+	case *ecdsa.PrivateKey:
107
+		r, s, err := ecdsa.Sign(rand.Reader, key, digest)
108
+		if err != nil {
109
+			return nil, err
110
+		}
111
+		rb, sb := r.Bytes(), s.Bytes()
112
+		size := key.Params().BitSize / 8
113
+		if size%8 > 0 {
114
+			size++
115
+		}
116
+		sig := make([]byte, size*2)
117
+		copy(sig[size-len(rb):], rb)
118
+		copy(sig[size*2-len(sb):], sb)
119
+		return sig, nil
120
+	}
121
+	return nil, ErrUnsupportedKey
122
+}
123
+
124
+// jwsHasher indicates suitable JWS algorithm name and a hash function
125
+// to use for signing a digest with the provided key.
126
+// It returns ("", 0) if the key is not supported.
127
+func jwsHasher(key crypto.Signer) (string, crypto.Hash) {
128
+	switch key := key.(type) {
129
+	case *rsa.PrivateKey:
130
+		return "RS256", crypto.SHA256
131
+	case *ecdsa.PrivateKey:
132
+		switch key.Params().Name {
133
+		case "P-256":
134
+			return "ES256", crypto.SHA256
135
+		case "P-384":
136
+			return "ES384", crypto.SHA384
137
+		case "P-521":
138
+			return "ES512", crypto.SHA512
139
+		}
140
+	}
141
+	return "", 0
142
+}
143
+
144
+// JWKThumbprint creates a JWK thumbprint out of pub
145
+// as specified in https://tools.ietf.org/html/rfc7638.
146
+func JWKThumbprint(pub crypto.PublicKey) (string, error) {
147
+	jwk, err := jwkEncode(pub)
148
+	if err != nil {
149
+		return "", err
150
+	}
151
+	b := sha256.Sum256([]byte(jwk))
152
+	return base64.RawURLEncoding.EncodeToString(b[:]), nil
153
+}

+ 329
- 0
vendor/golang.org/x/crypto/acme/types.go View File

@@ -0,0 +1,329 @@
1
+// Copyright 2016 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+package acme
6
+
7
+import (
8
+	"crypto"
9
+	"crypto/x509"
10
+	"errors"
11
+	"fmt"
12
+	"net/http"
13
+	"strings"
14
+	"time"
15
+)
16
+
17
+// ACME server response statuses used to describe Authorization and Challenge states.
18
+const (
19
+	StatusUnknown    = "unknown"
20
+	StatusPending    = "pending"
21
+	StatusProcessing = "processing"
22
+	StatusValid      = "valid"
23
+	StatusInvalid    = "invalid"
24
+	StatusRevoked    = "revoked"
25
+)
26
+
27
+// CRLReasonCode identifies the reason for a certificate revocation.
28
+type CRLReasonCode int
29
+
30
+// CRL reason codes as defined in RFC 5280.
31
+const (
32
+	CRLReasonUnspecified          CRLReasonCode = 0
33
+	CRLReasonKeyCompromise        CRLReasonCode = 1
34
+	CRLReasonCACompromise         CRLReasonCode = 2
35
+	CRLReasonAffiliationChanged   CRLReasonCode = 3
36
+	CRLReasonSuperseded           CRLReasonCode = 4
37
+	CRLReasonCessationOfOperation CRLReasonCode = 5
38
+	CRLReasonCertificateHold      CRLReasonCode = 6
39
+	CRLReasonRemoveFromCRL        CRLReasonCode = 8
40
+	CRLReasonPrivilegeWithdrawn   CRLReasonCode = 9
41
+	CRLReasonAACompromise         CRLReasonCode = 10
42
+)
43
+
44
+// ErrUnsupportedKey is returned when an unsupported key type is encountered.
45
+var ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")
46
+
47
+// Error is an ACME error, defined in Problem Details for HTTP APIs doc
48
+// http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.
49
+type Error struct {
50
+	// StatusCode is The HTTP status code generated by the origin server.
51
+	StatusCode int
52
+	// ProblemType is a URI reference that identifies the problem type,
53
+	// typically in a "urn:acme:error:xxx" form.
54
+	ProblemType string
55
+	// Detail is a human-readable explanation specific to this occurrence of the problem.
56
+	Detail string
57
+	// Header is the original server error response headers.
58
+	// It may be nil.
59
+	Header http.Header
60
+}
61
+
62
+func (e *Error) Error() string {
63
+	return fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail)
64
+}
65
+
66
+// AuthorizationError indicates that an authorization for an identifier
67
+// did not succeed.
68
+// It contains all errors from Challenge items of the failed Authorization.
69
+type AuthorizationError struct {
70
+	// URI uniquely identifies the failed Authorization.
71
+	URI string
72
+
73
+	// Identifier is an AuthzID.Value of the failed Authorization.
74
+	Identifier string
75
+
76
+	// Errors is a collection of non-nil error values of Challenge items
77
+	// of the failed Authorization.
78
+	Errors []error
79
+}
80
+
81
+func (a *AuthorizationError) Error() string {
82
+	e := make([]string, len(a.Errors))
83
+	for i, err := range a.Errors {
84
+		e[i] = err.Error()
85
+	}
86
+	return fmt.Sprintf("acme: authorization error for %s: %s", a.Identifier, strings.Join(e, "; "))
87
+}
88
+
89
+// RateLimit reports whether err represents a rate limit error and
90
+// any Retry-After duration returned by the server.
91
+//
92
+// See the following for more details on rate limiting:
93
+// https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-5.6
94
+func RateLimit(err error) (time.Duration, bool) {
95
+	e, ok := err.(*Error)
96
+	if !ok {
97
+		return 0, false
98
+	}
99
+	// Some CA implementations may return incorrect values.
100
+	// Use case-insensitive comparison.
101
+	if !strings.HasSuffix(strings.ToLower(e.ProblemType), ":ratelimited") {
102
+		return 0, false
103
+	}
104
+	if e.Header == nil {
105
+		return 0, true
106
+	}
107
+	return retryAfter(e.Header.Get("Retry-After"), 0), true
108
+}
109
+
110
+// Account is a user account. It is associated with a private key.
111
+type Account struct {
112
+	// URI is the account unique ID, which is also a URL used to retrieve
113
+	// account data from the CA.
114
+	URI string
115
+
116
+	// Contact is a slice of contact info used during registration.
117
+	Contact []string
118
+
119
+	// The terms user has agreed to.
120
+	// A value not matching CurrentTerms indicates that the user hasn't agreed
121
+	// to the actual Terms of Service of the CA.
122
+	AgreedTerms string
123
+
124
+	// Actual terms of a CA.
125
+	CurrentTerms string
126
+
127
+	// Authz is the authorization URL used to initiate a new authz flow.
128
+	Authz string
129
+
130
+	// Authorizations is a URI from which a list of authorizations
131
+	// granted to this account can be fetched via a GET request.
132
+	Authorizations string
133
+
134
+	// Certificates is a URI from which a list of certificates
135
+	// issued for this account can be fetched via a GET request.
136
+	Certificates string
137
+}
138
+
139
+// Directory is ACME server discovery data.
140
+type Directory struct {
141
+	// RegURL is an account endpoint URL, allowing for creating new
142
+	// and modifying existing accounts.
143
+	RegURL string
144
+
145
+	// AuthzURL is used to initiate Identifier Authorization flow.
146
+	AuthzURL string
147
+
148
+	// CertURL is a new certificate issuance endpoint URL.
149
+	CertURL string
150
+
151
+	// RevokeURL is used to initiate a certificate revocation flow.
152
+	RevokeURL string
153
+
154
+	// Term is a URI identifying the current terms of service.
155
+	Terms string
156
+
157
+	// Website is an HTTP or HTTPS URL locating a website
158
+	// providing more information about the ACME server.
159
+	Website string
160
+
161
+	// CAA consists of lowercase hostname elements, which the ACME server
162
+	// recognises as referring to itself for the purposes of CAA record validation
163
+	// as defined in RFC6844.
164
+	CAA []string
165
+}
166
+
167
+// Challenge encodes a returned CA challenge.
168
+// Its Error field may be non-nil if the challenge is part of an Authorization
169
+// with StatusInvalid.
170
+type Challenge struct {
171
+	// Type is the challenge type, e.g. "http-01", "tls-sni-02", "dns-01".
172
+	Type string
173
+
174
+	// URI is where a challenge response can be posted to.
175
+	URI string
176
+
177
+	// Token is a random value that uniquely identifies the challenge.
178
+	Token string
179
+
180
+	// Status identifies the status of this challenge.
181
+	Status string
182
+
183
+	// Error indicates the reason for an authorization failure
184
+	// when this challenge was used.
185
+	// The type of a non-nil value is *Error.
186
+	Error error
187
+}
188
+
189
+// Authorization encodes an authorization response.
190
+type Authorization struct {
191
+	// URI uniquely identifies a authorization.
192
+	URI string
193
+
194
+	// Status identifies the status of an authorization.
195
+	Status string
196
+
197
+	// Identifier is what the account is authorized to represent.
198
+	Identifier AuthzID
199
+
200
+	// Challenges that the client needs to fulfill in order to prove possession
201
+	// of the identifier (for pending authorizations).
202
+	// For final authorizations, the challenges that were used.
203
+	Challenges []*Challenge
204
+
205
+	// A collection of sets of challenges, each of which would be sufficient
206
+	// to prove possession of the identifier.
207
+	// Clients must complete a set of challenges that covers at least one set.
208
+	// Challenges are identified by their indices in the challenges array.
209
+	// If this field is empty, the client needs to complete all challenges.
210
+	Combinations [][]int
211
+}
212
+
213
+// AuthzID is an identifier that an account is authorized to represent.
214
+type AuthzID struct {
215
+	Type  string // The type of identifier, e.g. "dns".
216
+	Value string // The identifier itself, e.g. "example.org".
217
+}
218
+
219
+// wireAuthz is ACME JSON representation of Authorization objects.
220
+type wireAuthz struct {
221
+	Status       string
222
+	Challenges   []wireChallenge
223
+	Combinations [][]int
224
+	Identifier   struct {
225
+		Type  string
226
+		Value string
227
+	}
228
+}
229
+
230
+func (z *wireAuthz) authorization(uri string) *Authorization {
231
+	a := &Authorization{
232
+		URI:          uri,
233
+		Status:       z.Status,
234
+		Identifier:   AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value},
235
+		Combinations: z.Combinations, // shallow copy
236
+		Challenges:   make([]*Challenge, len(z.Challenges)),
237
+	}
238
+	for i, v := range z.Challenges {
239
+		a.Challenges[i] = v.challenge()
240
+	}
241
+	return a
242
+}
243
+
244
+func (z *wireAuthz) error(uri string) *AuthorizationError {
245
+	err := &AuthorizationError{
246
+		URI:        uri,
247
+		Identifier: z.Identifier.Value,
248
+	}
249
+	for _, raw := range z.Challenges {
250
+		if raw.Error != nil {
251
+			err.Errors = append(err.Errors, raw.Error.error(nil))
252
+		}
253
+	}
254
+	return err
255
+}
256
+
257
+// wireChallenge is ACME JSON challenge representation.
258
+type wireChallenge struct {
259
+	URI    string `json:"uri"`
260
+	Type   string
261
+	Token  string
262
+	Status string
263
+	Error  *wireError
264
+}
265
+
266
+func (c *wireChallenge) challenge() *Challenge {
267
+	v := &Challenge{
268
+		URI:    c.URI,
269
+		Type:   c.Type,
270
+		Token:  c.Token,
271
+		Status: c.Status,
272
+	}
273
+	if v.Status == "" {
274
+		v.Status = StatusPending
275
+	}
276
+	if c.Error != nil {
277
+		v.Error = c.Error.error(nil)
278
+	}
279
+	return v
280
+}
281
+
282
+// wireError is a subset of fields of the Problem Details object
283
+// as described in https://tools.ietf.org/html/rfc7807#section-3.1.
284
+type wireError struct {
285
+	Status int
286
+	Type   string
287
+	Detail string
288
+}
289
+
290
+func (e *wireError) error(h http.Header) *Error {
291
+	return &Error{
292
+		StatusCode:  e.Status,
293
+		ProblemType: e.Type,
294
+		Detail:      e.Detail,
295
+		Header:      h,
296
+	}
297
+}
298
+
299
+// CertOption is an optional argument type for the TLSSNIxChallengeCert methods for
300
+// customizing a temporary certificate for TLS-SNI challenges.
301
+type CertOption interface {
302
+	privateCertOpt()
303
+}
304
+
305
+// WithKey creates an option holding a private/public key pair.
306
+// The private part signs a certificate, and the public part represents the signee.
307
+func WithKey(key crypto.Signer) CertOption {
308
+	return &certOptKey{key}
309
+}
310
+
311
+type certOptKey struct {
312
+	key crypto.Signer
313
+}
314
+
315
+func (*certOptKey) privateCertOpt() {}
316
+
317
+// WithTemplate creates an option for specifying a certificate template.
318
+// See x509.CreateCertificate for template usage details.
319
+//
320
+// In TLSSNIxChallengeCert methods, the template is also used as parent,
321
+// resulting in a self-signed certificate.
322
+// The DNSNames field of t is always overwritten for tls-sni challenge certs.
323
+func WithTemplate(t *x509.Certificate) CertOption {
324
+	return (*certOptTemplate)(t)
325
+}
326
+
327
+type certOptTemplate x509.Certificate
328
+
329
+func (*certOptTemplate) privateCertOpt() {}

+ 10
- 3
vendor/golang.org/x/crypto/ed25519/ed25519.go View File

@@ -171,9 +171,16 @@ func Verify(publicKey PublicKey, message, sig []byte) bool {
171 171
 	edwards25519.ScReduce(&hReduced, &digest)
172 172
 
173 173
 	var R edwards25519.ProjectiveGroupElement
174
-	var b [32]byte
175
-	copy(b[:], sig[32:])
176
-	edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &b)
174
+	var s [32]byte
175
+	copy(s[:], sig[32:])
176
+
177
+	// https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in
178
+	// the range [0, order) in order to prevent signature malleability.
179
+	if !edwards25519.ScMinimal(&s) {
180
+		return false
181
+	}
182
+
183
+	edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &s)
177 184
 
178 185
 	var checkR [32]byte
179 186
 	R.ToBytes(&checkR)

+ 22
- 0
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go View File

@@ -4,6 +4,8 @@
4 4
 
5 5
 package edwards25519
6 6
 
7
+import "encoding/binary"
8
+
7 9
 // This code is a port of the public domain, “ref10” implementation of ed25519
8 10
 // from SUPERCOP.
9 11
 
@@ -1769,3 +1771,23 @@ func ScReduce(out *[32]byte, s *[64]byte) {
1769 1771
 	out[30] = byte(s11 >> 9)
1770 1772
 	out[31] = byte(s11 >> 17)
1771 1773
 }
1774
+
1775
+// order is the order of Curve25519 in little-endian form.
1776
+var order = [4]uint64{0x5812631a5cf5d3ed, 0x14def9dea2f79cd6, 0, 0x1000000000000000}
1777
+
1778
+// ScMinimal returns true if the given scalar is less than the order of the
1779
+// curve.
1780
+func ScMinimal(scalar *[32]byte) bool {
1781
+	for i := 3; ; i-- {
1782
+		v := binary.LittleEndian.Uint64(scalar[i*8:])
1783
+		if v > order[i] {
1784
+			return false
1785
+		} else if v < order[i] {
1786
+			break
1787
+		} else if i == 0 {
1788
+			return false
1789
+		}
1790
+	}
1791
+
1792
+	return true
1793
+}

+ 223
- 0
vendor/golang.org/x/crypto/internal/chacha20/chacha_generic.go View File

@@ -0,0 +1,223 @@
1
+// Copyright 2016 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// Package ChaCha20 implements the core ChaCha20 function as specified
6
+// in https://tools.ietf.org/html/rfc7539#section-2.3.
7
+package chacha20
8
+
9
+import (
10
+	"crypto/cipher"
11
+	"encoding/binary"
12
+)
13
+
14
+// assert that *Cipher implements cipher.Stream
15
+var _ cipher.Stream = (*Cipher)(nil)
16
+
17
+// Cipher is a stateful instance of ChaCha20 using a particular key
18
+// and nonce. A *Cipher implements the cipher.Stream interface.
19
+type Cipher struct {
20
+	key     [8]uint32
21
+	nonce   [3]uint32
22
+	counter uint32   // incremented after each block
23
+	buf     [64]byte // buffer for unused keystream bytes
24
+	len     int      // number of unused keystream bytes at end of buf
25
+}
26
+
27
+// New creates a new ChaCha20 stream cipher with the given key and nonce.
28
+// The initial counter value is set to 0.
29
+func New(key [8]uint32, nonce [3]uint32) *Cipher {
30
+	return &Cipher{key: key, nonce: nonce}
31
+}
32
+
33
+// XORKeyStream XORs each byte in the given slice with a byte from the
34
+// cipher's key stream. Dst and src must overlap entirely or not at all.
35
+//
36
+// If len(dst) < len(src), XORKeyStream will panic. It is acceptable
37
+// to pass a dst bigger than src, and in that case, XORKeyStream will
38
+// only update dst[:len(src)] and will not touch the rest of dst.
39
+//
40
+// Multiple calls to XORKeyStream behave as if the concatenation of
41
+// the src buffers was passed in a single run. That is, Cipher
42
+// maintains state and does not reset at each XORKeyStream call.
43
+func (s *Cipher) XORKeyStream(dst, src []byte) {
44
+	// xor src with buffered keystream first
45
+	if s.len != 0 {
46
+		buf := s.buf[len(s.buf)-s.len:]
47
+		if len(src) < len(buf) {
48
+			buf = buf[:len(src)]
49
+		}
50
+		td, ts := dst[:len(buf)], src[:len(buf)] // BCE hint
51
+		for i, b := range buf {
52
+			td[i] = ts[i] ^ b
53
+		}
54
+		s.len -= len(buf)
55
+		if s.len != 0 {
56
+			return
57
+		}
58
+		s.buf = [len(s.buf)]byte{} // zero the empty buffer
59
+		src = src[len(buf):]
60
+		dst = dst[len(buf):]
61
+	}
62
+
63
+	if len(src) == 0 {
64
+		return
65
+	}
66
+
67
+	// set up a 64-byte buffer to pad out the final block if needed
68
+	// (hoisted out of the main loop to avoid spills)
69
+	rem := len(src) % 64  // length of final block
70
+	fin := len(src) - rem // index of final block
71
+	if rem > 0 {
72
+		copy(s.buf[len(s.buf)-64:], src[fin:])
73
+	}
74
+
75
+	// qr calculates a quarter round
76
+	qr := func(a, b, c, d uint32) (uint32, uint32, uint32, uint32) {
77
+		a += b
78
+		d ^= a
79
+		d = (d << 16) | (d >> 16)
80
+		c += d
81
+		b ^= c
82
+		b = (b << 12) | (b >> 20)
83
+		a += b
84
+		d ^= a
85
+		d = (d << 8) | (d >> 24)
86
+		c += d
87
+		b ^= c
88
+		b = (b << 7) | (b >> 25)
89
+		return a, b, c, d
90
+	}
91
+
92
+	// ChaCha20 constants
93
+	const (
94
+		j0 = 0x61707865
95
+		j1 = 0x3320646e
96
+		j2 = 0x79622d32
97
+		j3 = 0x6b206574
98
+	)
99
+
100
+	// pre-calculate most of the first round
101
+	s1, s5, s9, s13 := qr(j1, s.key[1], s.key[5], s.nonce[0])
102
+	s2, s6, s10, s14 := qr(j2, s.key[2], s.key[6], s.nonce[1])
103
+	s3, s7, s11, s15 := qr(j3, s.key[3], s.key[7], s.nonce[2])
104
+
105
+	n := len(src)
106
+	src, dst = src[:n:n], dst[:n:n] // BCE hint
107
+	for i := 0; i < n; i += 64 {
108
+		// calculate the remainder of the first round
109
+		s0, s4, s8, s12 := qr(j0, s.key[0], s.key[4], s.counter)
110
+
111
+		// execute the second round
112
+		x0, x5, x10, x15 := qr(s0, s5, s10, s15)
113
+		x1, x6, x11, x12 := qr(s1, s6, s11, s12)
114
+		x2, x7, x8, x13 := qr(s2, s7, s8, s13)
115
+		x3, x4, x9, x14 := qr(s3, s4, s9, s14)
116
+
117
+		// execute the remaining 18 rounds
118
+		for i := 0; i < 9; i++ {
119
+			x0, x4, x8, x12 = qr(x0, x4, x8, x12)
120
+			x1, x5, x9, x13 = qr(x1, x5, x9, x13)
121
+			x2, x6, x10, x14 = qr(x2, x6, x10, x14)
122
+			x3, x7, x11, x15 = qr(x3, x7, x11, x15)
123
+
124
+			x0, x5, x10, x15 = qr(x0, x5, x10, x15)
125
+			x1, x6, x11, x12 = qr(x1, x6, x11, x12)
126
+			x2, x7, x8, x13 = qr(x2, x7, x8, x13)
127
+			x3, x4, x9, x14 = qr(x3, x4, x9, x14)
128
+		}
129
+
130
+		x0 += j0
131
+		x1 += j1
132
+		x2 += j2
133
+		x3 += j3
134
+
135
+		x4 += s.key[0]
136
+		x5 += s.key[1]
137
+		x6 += s.key[2]
138
+		x7 += s.key[3]
139
+		x8 += s.key[4]
140
+		x9 += s.key[5]
141
+		x10 += s.key[6]
142
+		x11 += s.key[7]
143
+
144
+		x12 += s.counter
145
+		x13 += s.nonce[0]
146
+		x14 += s.nonce[1]
147
+		x15 += s.nonce[2]
148
+
149
+		// increment the counter
150
+		s.counter += 1
151
+		if s.counter == 0 {
152
+			panic("chacha20: counter overflow")
153
+		}
154
+
155
+		// pad to 64 bytes if needed
156
+		in, out := src[i:], dst[i:]
157
+		if i == fin {
158
+			// src[fin:] has already been copied into s.buf before
159
+			// the main loop
160
+			in, out = s.buf[len(s.buf)-64:], s.buf[len(s.buf)-64:]
161
+		}
162
+		in, out = in[:64], out[:64] // BCE hint
163
+
164
+		// XOR the key stream with the source and write out the result
165
+		xor(out[0:], in[0:], x0)
166
+		xor(out[4:], in[4:], x1)
167
+		xor(out[8:], in[8:], x2)
168
+		xor(out[12:], in[12:], x3)
169
+		xor(out[16:], in[16:], x4)
170
+		xor(out[20:], in[20:], x5)
171
+		xor(out[24:], in[24:], x6)
172
+		xor(out[28:], in[28:], x7)
173
+		xor(out[32:], in[32:], x8)
174
+		xor(out[36:], in[36:], x9)
175
+		xor(out[40:], in[40:], x10)
176
+		xor(out[44:], in[44:], x11)
177
+		xor(out[48:], in[48:], x12)
178
+		xor(out[52:], in[52:], x13)
179
+		xor(out[56:], in[56:], x14)
180
+		xor(out[60:], in[60:], x15)
181
+	}
182
+	// copy any trailing bytes out of the buffer and into dst
183
+	if rem != 0 {
184
+		s.len = 64 - rem
185
+		copy(dst[fin:], s.buf[len(s.buf)-64:])
186
+	}
187
+}
188
+
189
+// Advance discards bytes in the key stream until the next 64 byte block
190
+// boundary is reached and updates the counter accordingly. If the key
191
+// stream is already at a block boundary no bytes will be discarded and
192
+// the counter will be unchanged.
193
+func (s *Cipher) Advance() {
194
+	s.len -= s.len % 64
195
+	if s.len == 0 {
196
+		s.buf = [len(s.buf)]byte{}
197
+	}
198
+}
199
+
200
+// XORKeyStream crypts bytes from in to out using the given key and counters.
201
+// In and out must overlap entirely or not at all. Counter contains the raw
202
+// ChaCha20 counter bytes (i.e. block counter followed by nonce).
203
+func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
204
+	s := Cipher{
205
+		key: [8]uint32{
206
+			binary.LittleEndian.Uint32(key[0:4]),
207
+			binary.LittleEndian.Uint32(key[4:8]),
208
+			binary.LittleEndian.Uint32(key[8:12]),
209
+			binary.LittleEndian.Uint32(key[12:16]),
210
+			binary.LittleEndian.Uint32(key[16:20]),
211
+			binary.LittleEndian.Uint32(key[20:24]),
212
+			binary.LittleEndian.Uint32(key[24:28]),
213
+			binary.LittleEndian.Uint32(key[28:32]),
214
+		},
215
+		nonce: [3]uint32{
216
+			binary.LittleEndian.Uint32(counter[4:8]),
217
+			binary.LittleEndian.Uint32(counter[8:12]),
218
+			binary.LittleEndian.Uint32(counter[12:16]),
219
+		},
220
+		counter: binary.LittleEndian.Uint32(counter[0:4]),
221
+	}
222
+	s.XORKeyStream(out, in)
223
+}

+ 43
- 0
vendor/golang.org/x/crypto/internal/chacha20/xor.go View File

@@ -0,0 +1,43 @@
1
+// Copyright 2018 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found src the LICENSE file.
4
+
5
+package chacha20
6
+
7
+import (
8
+	"runtime"
9
+)
10
+
11
+// Platforms that have fast unaligned 32-bit little endian accesses.
12
+const unaligned = runtime.GOARCH == "386" ||
13
+	runtime.GOARCH == "amd64" ||
14
+	runtime.GOARCH == "arm64" ||
15
+	runtime.GOARCH == "ppc64le" ||
16
+	runtime.GOARCH == "s390x"
17
+
18
+// xor reads a little endian uint32 from src, XORs it with u and
19
+// places the result in little endian byte order in dst.
20
+func xor(dst, src []byte, u uint32) {
21
+	_, _ = src[3], dst[3] // eliminate bounds checks
22
+	if unaligned {
23
+		// The compiler should optimize this code into
24
+		// 32-bit unaligned little endian loads and stores.
25
+		// TODO: delete once the compiler does a reliably
26
+		// good job with the generic code below.
27
+		// See issue #25111 for more details.
28
+		v := uint32(src[0])
29
+		v |= uint32(src[1]) << 8
30
+		v |= uint32(src[2]) << 16
31
+		v |= uint32(src[3]) << 24
32
+		v ^= u
33
+		dst[0] = byte(v)
34
+		dst[1] = byte(v >> 8)
35
+		dst[2] = byte(v >> 16)
36
+		dst[3] = byte(v >> 24)
37
+	} else {
38
+		dst[0] = src[0] ^ byte(u)
39
+		dst[1] = src[1] ^ byte(u>>8)
40
+		dst[2] = src[2] ^ byte(u>>16)
41
+		dst[3] = src[3] ^ byte(u>>24)
42
+	}
43
+}

+ 33
- 0
vendor/golang.org/x/crypto/poly1305/poly1305.go View File

@@ -0,0 +1,33 @@
1
+// Copyright 2012 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+/*
6
+Package poly1305 implements Poly1305 one-time message authentication code as
7
+specified in https://cr.yp.to/mac/poly1305-20050329.pdf.
8
+
9
+Poly1305 is a fast, one-time authentication function. It is infeasible for an
10
+attacker to generate an authenticator for a message without the key. However, a
11
+key must only be used for a single message. Authenticating two different
12
+messages with the same key allows an attacker to forge authenticators for other
13
+messages with the same key.
14
+
15
+Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was
16
+used with a fixed key in order to generate one-time keys from an nonce.
17
+However, in this package AES isn't used and the one-time key is specified
18
+directly.
19
+*/
20
+package poly1305 // import "golang.org/x/crypto/poly1305"
21
+
22
+import "crypto/subtle"
23
+
24
+// TagSize is the size, in bytes, of a poly1305 authenticator.
25
+const TagSize = 16
26
+
27
+// Verify returns true if mac is a valid authenticator for m with the given
28
+// key.
29
+func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
30
+	var tmp [16]byte
31
+	Sum(&tmp, m, key)
32
+	return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
33
+}

+ 22
- 0
vendor/golang.org/x/crypto/poly1305/sum_amd64.go View File

@@ -0,0 +1,22 @@
1
+// Copyright 2012 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// +build amd64,!gccgo,!appengine
6
+
7
+package poly1305
8
+
9
+// This function is implemented in sum_amd64.s
10
+//go:noescape
11
+func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
12
+
13
+// Sum generates an authenticator for m using a one-time key and puts the
14
+// 16-byte result into out. Authenticating two different messages with the same
15
+// key allows an attacker to forge messages at will.
16
+func Sum(out *[16]byte, m []byte, key *[32]byte) {
17
+	var mPtr *byte
18
+	if len(m) > 0 {
19
+		mPtr = &m[0]
20
+	}
21
+	poly1305(out, mPtr, uint64(len(m)), key)
22
+}

+ 125
- 0
vendor/golang.org/x/crypto/poly1305/sum_amd64.s View File

@@ -0,0 +1,125 @@
1
+// Copyright 2012 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// +build amd64,!gccgo,!appengine
6
+
7
+#include "textflag.h"
8
+
9
+#define POLY1305_ADD(msg, h0, h1, h2) \
10
+	ADDQ 0(msg), h0;  \
11
+	ADCQ 8(msg), h1;  \
12
+	ADCQ $1, h2;      \
13
+	LEAQ 16(msg), msg
14
+
15
+#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3) \
16
+	MOVQ  r0, AX;                  \
17
+	MULQ  h0;                      \
18
+	MOVQ  AX, t0;                  \
19
+	MOVQ  DX, t1;                  \
20
+	MOVQ  r0, AX;                  \
21
+	MULQ  h1;                      \
22
+	ADDQ  AX, t1;                  \
23
+	ADCQ  $0, DX;                  \
24
+	MOVQ  r0, t2;                  \
25
+	IMULQ h2, t2;                  \
26
+	ADDQ  DX, t2;                  \
27
+	                               \
28
+	MOVQ  r1, AX;                  \
29
+	MULQ  h0;                      \
30
+	ADDQ  AX, t1;                  \
31
+	ADCQ  $0, DX;                  \
32
+	MOVQ  DX, h0;                  \
33
+	MOVQ  r1, t3;                  \
34
+	IMULQ h2, t3;                  \
35
+	MOVQ  r1, AX;                  \
36
+	MULQ  h1;                      \
37
+	ADDQ  AX, t2;                  \
38
+	ADCQ  DX, t3;                  \
39
+	ADDQ  h0, t2;                  \
40
+	ADCQ  $0, t3;                  \
41
+	                               \
42
+	MOVQ  t0, h0;                  \
43
+	MOVQ  t1, h1;                  \
44
+	MOVQ  t2, h2;                  \
45
+	ANDQ  $3, h2;                  \
46
+	MOVQ  t2, t0;                  \
47
+	ANDQ  $0xFFFFFFFFFFFFFFFC, t0; \
48
+	ADDQ  t0, h0;                  \
49
+	ADCQ  t3, h1;                  \
50
+	ADCQ  $0, h2;                  \
51
+	SHRQ  $2, t3, t2;              \
52
+	SHRQ  $2, t3;                  \
53
+	ADDQ  t2, h0;                  \
54
+	ADCQ  t3, h1;                  \
55
+	ADCQ  $0, h2
56
+
57
+DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
58
+DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
59
+GLOBL ·poly1305Mask<>(SB), RODATA, $16
60
+
61
+// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key)
62
+TEXT ·poly1305(SB), $0-32
63
+	MOVQ out+0(FP), DI
64
+	MOVQ m+8(FP), SI
65
+	MOVQ mlen+16(FP), R15
66
+	MOVQ key+24(FP), AX
67
+
68
+	MOVQ 0(AX), R11
69
+	MOVQ 8(AX), R12
70
+	ANDQ ·poly1305Mask<>(SB), R11   // r0
71
+	ANDQ ·poly1305Mask<>+8(SB), R12 // r1
72
+	XORQ R8, R8                    // h0
73
+	XORQ R9, R9                    // h1
74
+	XORQ R10, R10                  // h2
75
+
76
+	CMPQ R15, $16
77
+	JB   bytes_between_0_and_15
78
+
79
+loop:
80
+	POLY1305_ADD(SI, R8, R9, R10)
81
+
82
+multiply:
83
+	POLY1305_MUL(R8, R9, R10, R11, R12, BX, CX, R13, R14)
84
+	SUBQ $16, R15
85
+	CMPQ R15, $16
86
+	JAE  loop
87
+
88
+bytes_between_0_and_15:
89
+	TESTQ R15, R15
90
+	JZ    done
91
+	MOVQ  $1, BX
92
+	XORQ  CX, CX
93
+	XORQ  R13, R13
94
+	ADDQ  R15, SI
95
+
96
+flush_buffer:
97
+	SHLQ $8, BX, CX
98
+	SHLQ $8, BX
99
+	MOVB -1(SI), R13
100
+	XORQ R13, BX
101
+	DECQ SI
102
+	DECQ R15
103
+	JNZ  flush_buffer
104
+
105
+	ADDQ BX, R8
106
+	ADCQ CX, R9
107
+	ADCQ $0, R10
108
+	MOVQ $16, R15
109
+	JMP  multiply
110
+
111
+done:
112
+	MOVQ    R8, AX
113
+	MOVQ    R9, BX
114
+	SUBQ    $0xFFFFFFFFFFFFFFFB, AX
115
+	SBBQ    $0xFFFFFFFFFFFFFFFF, BX
116
+	SBBQ    $3, R10
117
+	CMOVQCS R8, AX
118
+	CMOVQCS R9, BX
119
+	MOVQ    key+24(FP), R8
120
+	ADDQ    16(R8), AX
121
+	ADCQ    24(R8), BX
122
+
123
+	MOVQ AX, 0(DI)
124
+	MOVQ BX, 8(DI)
125
+	RET

+ 22
- 0
vendor/golang.org/x/crypto/poly1305/sum_arm.go View File

@@ -0,0 +1,22 @@
1
+// Copyright 2015 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// +build arm,!gccgo,!appengine,!nacl
6
+
7
+package poly1305
8
+
9
+// This function is implemented in sum_arm.s
10
+//go:noescape
11
+func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]byte)
12
+
13
+// Sum generates an authenticator for m using a one-time key and puts the
14
+// 16-byte result into out. Authenticating two different messages with the same
15
+// key allows an attacker to forge messages at will.
16
+func Sum(out *[16]byte, m []byte, key *[32]byte) {
17
+	var mPtr *byte
18
+	if len(m) > 0 {
19
+		mPtr = &m[0]
20
+	}
21
+	poly1305_auth_armv6(out, mPtr, uint32(len(m)), key)
22
+}

+ 427
- 0
vendor/golang.org/x/crypto/poly1305/sum_arm.s View File

@@ -0,0 +1,427 @@
1
+// Copyright 2015 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// +build arm,!gccgo,!appengine,!nacl
6
+
7
+#include "textflag.h"
8
+
9
+// This code was translated into a form compatible with 5a from the public
10
+// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305.
11
+
12
+DATA ·poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff
13
+DATA ·poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03
14
+DATA ·poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff
15
+DATA ·poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff
16
+DATA ·poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff
17
+GLOBL ·poly1305_init_constants_armv6<>(SB), 8, $20
18
+
19
+// Warning: the linker may use R11 to synthesize certain instructions. Please
20
+// take care and verify that no synthetic instructions use it.
21
+
22
+TEXT poly1305_init_ext_armv6<>(SB), NOSPLIT, $0
23
+	// Needs 16 bytes of stack and 64 bytes of space pointed to by R0.  (It
24
+	// might look like it's only 60 bytes of space but the final four bytes
25
+	// will be written by another function.) We need to skip over four
26
+	// bytes of stack because that's saving the value of 'g'.
27
+	ADD       $4, R13, R8
28
+	MOVM.IB   [R4-R7], (R8)
29
+	MOVM.IA.W (R1), [R2-R5]
30
+	MOVW      $·poly1305_init_constants_armv6<>(SB), R7
31
+	MOVW      R2, R8
32
+	MOVW      R2>>26, R9
33
+	MOVW      R3>>20, g
34
+	MOVW      R4>>14, R11
35