autocert_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  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. package autocert
  5. import (
  6. "context"
  7. "crypto"
  8. "crypto/ecdsa"
  9. "crypto/elliptic"
  10. "crypto/rand"
  11. "crypto/rsa"
  12. "crypto/tls"
  13. "crypto/x509"
  14. "crypto/x509/pkix"
  15. "encoding/base64"
  16. "encoding/json"
  17. "fmt"
  18. "html/template"
  19. "io"
  20. "math/big"
  21. "net/http"
  22. "net/http/httptest"
  23. "reflect"
  24. "strings"
  25. "sync"
  26. "testing"
  27. "time"
  28. "golang.org/x/crypto/acme"
  29. )
  30. var discoTmpl = template.Must(template.New("disco").Parse(`{
  31. "new-reg": "{{.}}/new-reg",
  32. "new-authz": "{{.}}/new-authz",
  33. "new-cert": "{{.}}/new-cert"
  34. }`))
  35. var authzTmpl = template.Must(template.New("authz").Parse(`{
  36. "status": "pending",
  37. "challenges": [
  38. {
  39. "uri": "{{.}}/challenge/1",
  40. "type": "tls-sni-01",
  41. "token": "token-01"
  42. },
  43. {
  44. "uri": "{{.}}/challenge/2",
  45. "type": "tls-sni-02",
  46. "token": "token-02"
  47. },
  48. {
  49. "uri": "{{.}}/challenge/dns-01",
  50. "type": "dns-01",
  51. "token": "token-dns-01"
  52. },
  53. {
  54. "uri": "{{.}}/challenge/http-01",
  55. "type": "http-01",
  56. "token": "token-http-01"
  57. }
  58. ]
  59. }`))
  60. type memCache struct {
  61. mu sync.Mutex
  62. keyData map[string][]byte
  63. }
  64. func (m *memCache) Get(ctx context.Context, key string) ([]byte, error) {
  65. m.mu.Lock()
  66. defer m.mu.Unlock()
  67. v, ok := m.keyData[key]
  68. if !ok {
  69. return nil, ErrCacheMiss
  70. }
  71. return v, nil
  72. }
  73. func (m *memCache) Put(ctx context.Context, key string, data []byte) error {
  74. m.mu.Lock()
  75. defer m.mu.Unlock()
  76. m.keyData[key] = data
  77. return nil
  78. }
  79. func (m *memCache) Delete(ctx context.Context, key string) error {
  80. m.mu.Lock()
  81. defer m.mu.Unlock()
  82. delete(m.keyData, key)
  83. return nil
  84. }
  85. func newMemCache() *memCache {
  86. return &memCache{
  87. keyData: make(map[string][]byte),
  88. }
  89. }
  90. func dummyCert(pub interface{}, san ...string) ([]byte, error) {
  91. return dateDummyCert(pub, time.Now(), time.Now().Add(90*24*time.Hour), san...)
  92. }
  93. func dateDummyCert(pub interface{}, start, end time.Time, san ...string) ([]byte, error) {
  94. // use EC key to run faster on 386
  95. key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  96. if err != nil {
  97. return nil, err
  98. }
  99. t := &x509.Certificate{
  100. SerialNumber: big.NewInt(1),
  101. NotBefore: start,
  102. NotAfter: end,
  103. BasicConstraintsValid: true,
  104. KeyUsage: x509.KeyUsageKeyEncipherment,
  105. DNSNames: san,
  106. }
  107. if pub == nil {
  108. pub = &key.PublicKey
  109. }
  110. return x509.CreateCertificate(rand.Reader, t, t, pub, key)
  111. }
  112. func decodePayload(v interface{}, r io.Reader) error {
  113. var req struct{ Payload string }
  114. if err := json.NewDecoder(r).Decode(&req); err != nil {
  115. return err
  116. }
  117. payload, err := base64.RawURLEncoding.DecodeString(req.Payload)
  118. if err != nil {
  119. return err
  120. }
  121. return json.Unmarshal(payload, v)
  122. }
  123. func TestGetCertificate(t *testing.T) {
  124. man := &Manager{Prompt: AcceptTOS}
  125. defer man.stopRenew()
  126. hello := &tls.ClientHelloInfo{ServerName: "example.org"}
  127. testGetCertificate(t, man, "example.org", hello)
  128. }
  129. func TestGetCertificate_trailingDot(t *testing.T) {
  130. man := &Manager{Prompt: AcceptTOS}
  131. defer man.stopRenew()
  132. hello := &tls.ClientHelloInfo{ServerName: "example.org."}
  133. testGetCertificate(t, man, "example.org", hello)
  134. }
  135. func TestGetCertificate_ForceRSA(t *testing.T) {
  136. man := &Manager{
  137. Prompt: AcceptTOS,
  138. Cache: newMemCache(),
  139. ForceRSA: true,
  140. }
  141. defer man.stopRenew()
  142. hello := &tls.ClientHelloInfo{ServerName: "example.org"}
  143. testGetCertificate(t, man, "example.org", hello)
  144. cert, err := man.cacheGet(context.Background(), "example.org")
  145. if err != nil {
  146. t.Fatalf("man.cacheGet: %v", err)
  147. }
  148. if _, ok := cert.PrivateKey.(*rsa.PrivateKey); !ok {
  149. t.Errorf("cert.PrivateKey is %T; want *rsa.PrivateKey", cert.PrivateKey)
  150. }
  151. }
  152. func TestGetCertificate_nilPrompt(t *testing.T) {
  153. man := &Manager{}
  154. defer man.stopRenew()
  155. url, finish := startACMEServerStub(t, man, "example.org")
  156. defer finish()
  157. key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  158. if err != nil {
  159. t.Fatal(err)
  160. }
  161. man.Client = &acme.Client{
  162. Key: key,
  163. DirectoryURL: url,
  164. }
  165. hello := &tls.ClientHelloInfo{ServerName: "example.org"}
  166. if _, err := man.GetCertificate(hello); err == nil {
  167. t.Error("got certificate for example.org; wanted error")
  168. }
  169. }
  170. func TestGetCertificate_expiredCache(t *testing.T) {
  171. // Make an expired cert and cache it.
  172. pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  173. if err != nil {
  174. t.Fatal(err)
  175. }
  176. tmpl := &x509.Certificate{
  177. SerialNumber: big.NewInt(1),
  178. Subject: pkix.Name{CommonName: "example.org"},
  179. NotAfter: time.Now(),
  180. }
  181. pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &pk.PublicKey, pk)
  182. if err != nil {
  183. t.Fatal(err)
  184. }
  185. tlscert := &tls.Certificate{
  186. Certificate: [][]byte{pub},
  187. PrivateKey: pk,
  188. }
  189. man := &Manager{Prompt: AcceptTOS, Cache: newMemCache()}
  190. defer man.stopRenew()
  191. if err := man.cachePut(context.Background(), "example.org", tlscert); err != nil {
  192. t.Fatalf("man.cachePut: %v", err)
  193. }
  194. // The expired cached cert should trigger a new cert issuance
  195. // and return without an error.
  196. hello := &tls.ClientHelloInfo{ServerName: "example.org"}
  197. testGetCertificate(t, man, "example.org", hello)
  198. }
  199. func TestGetCertificate_failedAttempt(t *testing.T) {
  200. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  201. w.WriteHeader(http.StatusBadRequest)
  202. }))
  203. defer ts.Close()
  204. const example = "example.org"
  205. d := createCertRetryAfter
  206. f := testDidRemoveState
  207. defer func() {
  208. createCertRetryAfter = d
  209. testDidRemoveState = f
  210. }()
  211. createCertRetryAfter = 0
  212. done := make(chan struct{})
  213. testDidRemoveState = func(domain string) {
  214. if domain != example {
  215. t.Errorf("testDidRemoveState: domain = %q; want %q", domain, example)
  216. }
  217. close(done)
  218. }
  219. key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  220. if err != nil {
  221. t.Fatal(err)
  222. }
  223. man := &Manager{
  224. Prompt: AcceptTOS,
  225. Client: &acme.Client{
  226. Key: key,
  227. DirectoryURL: ts.URL,
  228. },
  229. }
  230. defer man.stopRenew()
  231. hello := &tls.ClientHelloInfo{ServerName: example}
  232. if _, err := man.GetCertificate(hello); err == nil {
  233. t.Error("GetCertificate: err is nil")
  234. }
  235. select {
  236. case <-time.After(5 * time.Second):
  237. t.Errorf("took too long to remove the %q state", example)
  238. case <-done:
  239. man.stateMu.Lock()
  240. defer man.stateMu.Unlock()
  241. if v, exist := man.state[example]; exist {
  242. t.Errorf("state exists for %q: %+v", example, v)
  243. }
  244. }
  245. }
  246. // startACMEServerStub runs an ACME server
  247. // The domain argument is the expected domain name of a certificate request.
  248. func startACMEServerStub(t *testing.T, man *Manager, domain string) (url string, finish func()) {
  249. // echo token-02 | shasum -a 256
  250. // then divide result in 2 parts separated by dot
  251. tokenCertName := "4e8eb87631187e9ff2153b56b13a4dec.13a35d002e485d60ff37354b32f665d9.token.acme.invalid"
  252. verifyTokenCert := func() {
  253. hello := &tls.ClientHelloInfo{ServerName: tokenCertName}
  254. _, err := man.GetCertificate(hello)
  255. if err != nil {
  256. t.Errorf("verifyTokenCert: GetCertificate(%q): %v", tokenCertName, err)
  257. return
  258. }
  259. }
  260. // ACME CA server stub
  261. var ca *httptest.Server
  262. ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  263. w.Header().Set("Replay-Nonce", "nonce")
  264. if r.Method == "HEAD" {
  265. // a nonce request
  266. return
  267. }
  268. switch r.URL.Path {
  269. // discovery
  270. case "/":
  271. if err := discoTmpl.Execute(w, ca.URL); err != nil {
  272. t.Errorf("discoTmpl: %v", err)
  273. }
  274. // client key registration
  275. case "/new-reg":
  276. w.Write([]byte("{}"))
  277. // domain authorization
  278. case "/new-authz":
  279. w.Header().Set("Location", ca.URL+"/authz/1")
  280. w.WriteHeader(http.StatusCreated)
  281. if err := authzTmpl.Execute(w, ca.URL); err != nil {
  282. t.Errorf("authzTmpl: %v", err)
  283. }
  284. // accept tls-sni-02 challenge
  285. case "/challenge/2":
  286. verifyTokenCert()
  287. w.Write([]byte("{}"))
  288. // authorization status
  289. case "/authz/1":
  290. w.Write([]byte(`{"status": "valid"}`))
  291. // cert request
  292. case "/new-cert":
  293. var req struct {
  294. CSR string `json:"csr"`
  295. }
  296. decodePayload(&req, r.Body)
  297. b, _ := base64.RawURLEncoding.DecodeString(req.CSR)
  298. csr, err := x509.ParseCertificateRequest(b)
  299. if err != nil {
  300. t.Errorf("new-cert: CSR: %v", err)
  301. }
  302. if csr.Subject.CommonName != domain {
  303. t.Errorf("CommonName in CSR = %q; want %q", csr.Subject.CommonName, domain)
  304. }
  305. der, err := dummyCert(csr.PublicKey, domain)
  306. if err != nil {
  307. t.Errorf("new-cert: dummyCert: %v", err)
  308. }
  309. chainUp := fmt.Sprintf("<%s/ca-cert>; rel=up", ca.URL)
  310. w.Header().Set("Link", chainUp)
  311. w.WriteHeader(http.StatusCreated)
  312. w.Write(der)
  313. // CA chain cert
  314. case "/ca-cert":
  315. der, err := dummyCert(nil, "ca")
  316. if err != nil {
  317. t.Errorf("ca-cert: dummyCert: %v", err)
  318. }
  319. w.Write(der)
  320. default:
  321. t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
  322. }
  323. }))
  324. finish = func() {
  325. ca.Close()
  326. // make sure token cert was removed
  327. cancel := make(chan struct{})
  328. done := make(chan struct{})
  329. go func() {
  330. defer close(done)
  331. tick := time.NewTicker(100 * time.Millisecond)
  332. defer tick.Stop()
  333. for {
  334. hello := &tls.ClientHelloInfo{ServerName: tokenCertName}
  335. if _, err := man.GetCertificate(hello); err != nil {
  336. return
  337. }
  338. select {
  339. case <-tick.C:
  340. case <-cancel:
  341. return
  342. }
  343. }
  344. }()
  345. select {
  346. case <-done:
  347. case <-time.After(5 * time.Second):
  348. close(cancel)
  349. t.Error("token cert was not removed")
  350. <-done
  351. }
  352. }
  353. return ca.URL, finish
  354. }
  355. // tests man.GetCertificate flow using the provided hello argument.
  356. // The domain argument is the expected domain name of a certificate request.
  357. func testGetCertificate(t *testing.T, man *Manager, domain string, hello *tls.ClientHelloInfo) {
  358. url, finish := startACMEServerStub(t, man, domain)
  359. defer finish()
  360. // use EC key to run faster on 386
  361. key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  362. if err != nil {
  363. t.Fatal(err)
  364. }
  365. man.Client = &acme.Client{
  366. Key: key,
  367. DirectoryURL: url,
  368. }
  369. // simulate tls.Config.GetCertificate
  370. var tlscert *tls.Certificate
  371. done := make(chan struct{})
  372. go func() {
  373. tlscert, err = man.GetCertificate(hello)
  374. close(done)
  375. }()
  376. select {
  377. case <-time.After(time.Minute):
  378. t.Fatal("man.GetCertificate took too long to return")
  379. case <-done:
  380. }
  381. if err != nil {
  382. t.Fatalf("man.GetCertificate: %v", err)
  383. }
  384. // verify the tlscert is the same we responded with from the CA stub
  385. if len(tlscert.Certificate) == 0 {
  386. t.Fatal("len(tlscert.Certificate) is 0")
  387. }
  388. cert, err := x509.ParseCertificate(tlscert.Certificate[0])
  389. if err != nil {
  390. t.Fatalf("x509.ParseCertificate: %v", err)
  391. }
  392. if len(cert.DNSNames) == 0 || cert.DNSNames[0] != domain {
  393. t.Errorf("cert.DNSNames = %v; want %q", cert.DNSNames, domain)
  394. }
  395. }
  396. func TestVerifyHTTP01(t *testing.T) {
  397. var (
  398. http01 http.Handler
  399. authzCount int // num. of created authorizations
  400. didAcceptHTTP01 bool
  401. )
  402. verifyHTTPToken := func() {
  403. r := httptest.NewRequest("GET", "/.well-known/acme-challenge/token-http-01", nil)
  404. w := httptest.NewRecorder()
  405. http01.ServeHTTP(w, r)
  406. if w.Code != http.StatusOK {
  407. t.Errorf("http token: w.Code = %d; want %d", w.Code, http.StatusOK)
  408. }
  409. if v := string(w.Body.Bytes()); !strings.HasPrefix(v, "token-http-01.") {
  410. t.Errorf("http token value = %q; want 'token-http-01.' prefix", v)
  411. }
  412. }
  413. // ACME CA server stub, only the needed bits.
  414. // TODO: Merge this with startACMEServerStub, making it a configurable CA for testing.
  415. var ca *httptest.Server
  416. ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  417. w.Header().Set("Replay-Nonce", "nonce")
  418. if r.Method == "HEAD" {
  419. // a nonce request
  420. return
  421. }
  422. switch r.URL.Path {
  423. // Discovery.
  424. case "/":
  425. if err := discoTmpl.Execute(w, ca.URL); err != nil {
  426. t.Errorf("discoTmpl: %v", err)
  427. }
  428. // Client key registration.
  429. case "/new-reg":
  430. w.Write([]byte("{}"))
  431. // New domain authorization.
  432. case "/new-authz":
  433. authzCount++
  434. w.Header().Set("Location", fmt.Sprintf("%s/authz/%d", ca.URL, authzCount))
  435. w.WriteHeader(http.StatusCreated)
  436. if err := authzTmpl.Execute(w, ca.URL); err != nil {
  437. t.Errorf("authzTmpl: %v", err)
  438. }
  439. // Accept tls-sni-02.
  440. case "/challenge/2":
  441. w.Write([]byte("{}"))
  442. // Reject tls-sni-01.
  443. case "/challenge/1":
  444. http.Error(w, "won't accept tls-sni-01", http.StatusBadRequest)
  445. // Should not accept dns-01.
  446. case "/challenge/dns-01":
  447. t.Errorf("dns-01 challenge was accepted")
  448. http.Error(w, "won't accept dns-01", http.StatusBadRequest)
  449. // Accept http-01.
  450. case "/challenge/http-01":
  451. didAcceptHTTP01 = true
  452. verifyHTTPToken()
  453. w.Write([]byte("{}"))
  454. // Authorization statuses.
  455. // Make tls-sni-xxx invalid.
  456. case "/authz/1", "/authz/2":
  457. w.Write([]byte(`{"status": "invalid"}`))
  458. case "/authz/3", "/authz/4":
  459. w.Write([]byte(`{"status": "valid"}`))
  460. default:
  461. http.NotFound(w, r)
  462. t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
  463. }
  464. }))
  465. defer ca.Close()
  466. key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  467. if err != nil {
  468. t.Fatal(err)
  469. }
  470. m := &Manager{
  471. Client: &acme.Client{
  472. Key: key,
  473. DirectoryURL: ca.URL,
  474. },
  475. }
  476. http01 = m.HTTPHandler(nil)
  477. if err := m.verify(context.Background(), m.Client, "example.org"); err != nil {
  478. t.Errorf("m.verify: %v", err)
  479. }
  480. // Only tls-sni-01, tls-sni-02 and http-01 must be accepted
  481. // The dns-01 challenge is unsupported.
  482. if authzCount != 3 {
  483. t.Errorf("authzCount = %d; want 3", authzCount)
  484. }
  485. if !didAcceptHTTP01 {
  486. t.Error("did not accept http-01 challenge")
  487. }
  488. }
  489. func TestHTTPHandlerDefaultFallback(t *testing.T) {
  490. tt := []struct {
  491. method, url string
  492. wantCode int
  493. wantLocation string
  494. }{
  495. {"GET", "http://example.org", 302, "https://example.org/"},
  496. {"GET", "http://example.org/foo", 302, "https://example.org/foo"},
  497. {"GET", "http://example.org/foo/bar/", 302, "https://example.org/foo/bar/"},
  498. {"GET", "http://example.org/?a=b", 302, "https://example.org/?a=b"},
  499. {"GET", "http://example.org/foo?a=b", 302, "https://example.org/foo?a=b"},
  500. {"GET", "http://example.org:80/foo?a=b", 302, "https://example.org:443/foo?a=b"},
  501. {"GET", "http://example.org:80/foo%20bar", 302, "https://example.org:443/foo%20bar"},
  502. {"GET", "http://[2602:d1:xxxx::c60a]:1234", 302, "https://[2602:d1:xxxx::c60a]:443/"},
  503. {"GET", "http://[2602:d1:xxxx::c60a]", 302, "https://[2602:d1:xxxx::c60a]/"},
  504. {"GET", "http://[2602:d1:xxxx::c60a]/foo?a=b", 302, "https://[2602:d1:xxxx::c60a]/foo?a=b"},
  505. {"HEAD", "http://example.org", 302, "https://example.org/"},
  506. {"HEAD", "http://example.org/foo", 302, "https://example.org/foo"},
  507. {"HEAD", "http://example.org/foo/bar/", 302, "https://example.org/foo/bar/"},
  508. {"HEAD", "http://example.org/?a=b", 302, "https://example.org/?a=b"},
  509. {"HEAD", "http://example.org/foo?a=b", 302, "https://example.org/foo?a=b"},
  510. {"POST", "http://example.org", 400, ""},
  511. {"PUT", "http://example.org", 400, ""},
  512. {"GET", "http://example.org/.well-known/acme-challenge/x", 404, ""},
  513. }
  514. var m Manager
  515. h := m.HTTPHandler(nil)
  516. for i, test := range tt {
  517. r := httptest.NewRequest(test.method, test.url, nil)
  518. w := httptest.NewRecorder()
  519. h.ServeHTTP(w, r)
  520. if w.Code != test.wantCode {
  521. t.Errorf("%d: w.Code = %d; want %d", i, w.Code, test.wantCode)
  522. t.Errorf("%d: body: %s", i, w.Body.Bytes())
  523. }
  524. if v := w.Header().Get("Location"); v != test.wantLocation {
  525. t.Errorf("%d: Location = %q; want %q", i, v, test.wantLocation)
  526. }
  527. }
  528. }
  529. func TestAccountKeyCache(t *testing.T) {
  530. m := Manager{Cache: newMemCache()}
  531. ctx := context.Background()
  532. k1, err := m.accountKey(ctx)
  533. if err != nil {
  534. t.Fatal(err)
  535. }
  536. k2, err := m.accountKey(ctx)
  537. if err != nil {
  538. t.Fatal(err)
  539. }
  540. if !reflect.DeepEqual(k1, k2) {
  541. t.Errorf("account keys don't match: k1 = %#v; k2 = %#v", k1, k2)
  542. }
  543. }
  544. func TestCache(t *testing.T) {
  545. privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  546. if err != nil {
  547. t.Fatal(err)
  548. }
  549. tmpl := &x509.Certificate{
  550. SerialNumber: big.NewInt(1),
  551. Subject: pkix.Name{CommonName: "example.org"},
  552. NotAfter: time.Now().Add(time.Hour),
  553. }
  554. pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &privKey.PublicKey, privKey)
  555. if err != nil {
  556. t.Fatal(err)
  557. }
  558. tlscert := &tls.Certificate{
  559. Certificate: [][]byte{pub},
  560. PrivateKey: privKey,
  561. }
  562. man := &Manager{Cache: newMemCache()}
  563. defer man.stopRenew()
  564. ctx := context.Background()
  565. if err := man.cachePut(ctx, "example.org", tlscert); err != nil {
  566. t.Fatalf("man.cachePut: %v", err)
  567. }
  568. res, err := man.cacheGet(ctx, "example.org")
  569. if err != nil {
  570. t.Fatalf("man.cacheGet: %v", err)
  571. }
  572. if res == nil {
  573. t.Fatal("res is nil")
  574. }
  575. }
  576. func TestHostWhitelist(t *testing.T) {
  577. policy := HostWhitelist("example.com", "example.org", "*.example.net")
  578. tt := []struct {
  579. host string
  580. allow bool
  581. }{
  582. {"example.com", true},
  583. {"example.org", true},
  584. {"one.example.com", false},
  585. {"two.example.org", false},
  586. {"three.example.net", false},
  587. {"dummy", false},
  588. }
  589. for i, test := range tt {
  590. err := policy(nil, test.host)
  591. if err != nil && test.allow {
  592. t.Errorf("%d: policy(%q): %v; want nil", i, test.host, err)
  593. }
  594. if err == nil && !test.allow {
  595. t.Errorf("%d: policy(%q): nil; want an error", i, test.host)
  596. }
  597. }
  598. }
  599. func TestValidCert(t *testing.T) {
  600. key1, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  601. if err != nil {
  602. t.Fatal(err)
  603. }
  604. key2, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  605. if err != nil {
  606. t.Fatal(err)
  607. }
  608. key3, err := rsa.GenerateKey(rand.Reader, 512)
  609. if err != nil {
  610. t.Fatal(err)
  611. }
  612. cert1, err := dummyCert(key1.Public(), "example.org")
  613. if err != nil {
  614. t.Fatal(err)
  615. }
  616. cert2, err := dummyCert(key2.Public(), "example.org")
  617. if err != nil {
  618. t.Fatal(err)
  619. }
  620. cert3, err := dummyCert(key3.Public(), "example.org")
  621. if err != nil {
  622. t.Fatal(err)
  623. }
  624. now := time.Now()
  625. early, err := dateDummyCert(key1.Public(), now.Add(time.Hour), now.Add(2*time.Hour), "example.org")
  626. if err != nil {
  627. t.Fatal(err)
  628. }
  629. expired, err := dateDummyCert(key1.Public(), now.Add(-2*time.Hour), now.Add(-time.Hour), "example.org")
  630. if err != nil {
  631. t.Fatal(err)
  632. }
  633. tt := []struct {
  634. domain string
  635. key crypto.Signer
  636. cert [][]byte
  637. ok bool
  638. }{
  639. {"example.org", key1, [][]byte{cert1}, true},
  640. {"example.org", key3, [][]byte{cert3}, true},
  641. {"example.org", key1, [][]byte{cert1, cert2, cert3}, true},
  642. {"example.org", key1, [][]byte{cert1, {1}}, false},
  643. {"example.org", key1, [][]byte{{1}}, false},
  644. {"example.org", key1, [][]byte{cert2}, false},
  645. {"example.org", key2, [][]byte{cert1}, false},
  646. {"example.org", key1, [][]byte{cert3}, false},
  647. {"example.org", key3, [][]byte{cert1}, false},
  648. {"example.net", key1, [][]byte{cert1}, false},
  649. {"example.org", key1, [][]byte{early}, false},
  650. {"example.org", key1, [][]byte{expired}, false},
  651. }
  652. for i, test := range tt {
  653. leaf, err := validCert(test.domain, test.cert, test.key)
  654. if err != nil && test.ok {
  655. t.Errorf("%d: err = %v", i, err)
  656. }
  657. if err == nil && !test.ok {
  658. t.Errorf("%d: err is nil", i)
  659. }
  660. if err == nil && test.ok && leaf == nil {
  661. t.Errorf("%d: leaf is nil", i)
  662. }
  663. }
  664. }
  665. type cacheGetFunc func(ctx context.Context, key string) ([]byte, error)
  666. func (f cacheGetFunc) Get(ctx context.Context, key string) ([]byte, error) {
  667. return f(ctx, key)
  668. }
  669. func (f cacheGetFunc) Put(ctx context.Context, key string, data []byte) error {
  670. return fmt.Errorf("unsupported Put of %q = %q", key, data)
  671. }
  672. func (f cacheGetFunc) Delete(ctx context.Context, key string) error {
  673. return fmt.Errorf("unsupported Delete of %q", key)
  674. }
  675. func TestManagerGetCertificateBogusSNI(t *testing.T) {
  676. m := Manager{
  677. Prompt: AcceptTOS,
  678. Cache: cacheGetFunc(func(ctx context.Context, key string) ([]byte, error) {
  679. return nil, fmt.Errorf("cache.Get of %s", key)
  680. }),
  681. }
  682. tests := []struct {
  683. name string
  684. wantErr string
  685. }{
  686. {"foo.com", "cache.Get of foo.com"},
  687. {"foo.com.", "cache.Get of foo.com"},
  688. {`a\b.com`, "acme/autocert: server name contains invalid character"},
  689. {`a/b.com`, "acme/autocert: server name contains invalid character"},
  690. {"", "acme/autocert: missing server name"},
  691. {"foo", "acme/autocert: server name component count invalid"},
  692. {".foo", "acme/autocert: server name component count invalid"},
  693. {"foo.", "acme/autocert: server name component count invalid"},
  694. {"fo.o", "cache.Get of fo.o"},
  695. }
  696. for _, tt := range tests {
  697. _, err := m.GetCertificate(&tls.ClientHelloInfo{ServerName: tt.name})
  698. got := fmt.Sprint(err)
  699. if got != tt.wantErr {
  700. t.Errorf("GetCertificate(SNI = %q) = %q; want %q", tt.name, got, tt.wantErr)
  701. }
  702. }
  703. }