autocert_test.go 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189
  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. "bytes"
  7. "context"
  8. "crypto"
  9. "crypto/ecdsa"
  10. "crypto/elliptic"
  11. "crypto/rand"
  12. "crypto/rsa"
  13. "crypto/tls"
  14. "crypto/x509"
  15. "crypto/x509/pkix"
  16. "encoding/asn1"
  17. "encoding/base64"
  18. "encoding/json"
  19. "fmt"
  20. "html/template"
  21. "io"
  22. "io/ioutil"
  23. "math/big"
  24. "net/http"
  25. "net/http/httptest"
  26. "reflect"
  27. "strings"
  28. "sync"
  29. "testing"
  30. "time"
  31. "golang.org/x/crypto/acme"
  32. "golang.org/x/crypto/acme/autocert/internal/acmetest"
  33. )
  34. var (
  35. exampleDomain = "example.org"
  36. exampleCertKey = certKey{domain: exampleDomain}
  37. exampleCertKeyRSA = certKey{domain: exampleDomain, isRSA: true}
  38. )
  39. var discoTmpl = template.Must(template.New("disco").Parse(`{
  40. "new-reg": "{{.}}/new-reg",
  41. "new-authz": "{{.}}/new-authz",
  42. "new-cert": "{{.}}/new-cert"
  43. }`))
  44. var authzTmpl = template.Must(template.New("authz").Parse(`{
  45. "status": "pending",
  46. "challenges": [
  47. {
  48. "uri": "{{.}}/challenge/1",
  49. "type": "tls-sni-01",
  50. "token": "token-01"
  51. },
  52. {
  53. "uri": "{{.}}/challenge/2",
  54. "type": "tls-sni-02",
  55. "token": "token-02"
  56. },
  57. {
  58. "uri": "{{.}}/challenge/dns-01",
  59. "type": "dns-01",
  60. "token": "token-dns-01"
  61. },
  62. {
  63. "uri": "{{.}}/challenge/http-01",
  64. "type": "http-01",
  65. "token": "token-http-01"
  66. }
  67. ]
  68. }`))
  69. type memCache struct {
  70. t *testing.T
  71. mu sync.Mutex
  72. keyData map[string][]byte
  73. }
  74. func (m *memCache) Get(ctx context.Context, key string) ([]byte, error) {
  75. m.mu.Lock()
  76. defer m.mu.Unlock()
  77. v, ok := m.keyData[key]
  78. if !ok {
  79. return nil, ErrCacheMiss
  80. }
  81. return v, nil
  82. }
  83. // filenameSafe returns whether all characters in s are printable ASCII
  84. // and safe to use in a filename on most filesystems.
  85. func filenameSafe(s string) bool {
  86. for _, c := range s {
  87. if c < 0x20 || c > 0x7E {
  88. return false
  89. }
  90. switch c {
  91. case '\\', '/', ':', '*', '?', '"', '<', '>', '|':
  92. return false
  93. }
  94. }
  95. return true
  96. }
  97. func (m *memCache) Put(ctx context.Context, key string, data []byte) error {
  98. if !filenameSafe(key) {
  99. m.t.Errorf("invalid characters in cache key %q", key)
  100. }
  101. m.mu.Lock()
  102. defer m.mu.Unlock()
  103. m.keyData[key] = data
  104. return nil
  105. }
  106. func (m *memCache) Delete(ctx context.Context, key string) error {
  107. m.mu.Lock()
  108. defer m.mu.Unlock()
  109. delete(m.keyData, key)
  110. return nil
  111. }
  112. func newMemCache(t *testing.T) *memCache {
  113. return &memCache{
  114. t: t,
  115. keyData: make(map[string][]byte),
  116. }
  117. }
  118. func (m *memCache) numCerts() int {
  119. m.mu.Lock()
  120. defer m.mu.Unlock()
  121. res := 0
  122. for key := range m.keyData {
  123. if strings.HasSuffix(key, "+token") ||
  124. strings.HasSuffix(key, "+key") ||
  125. strings.HasSuffix(key, "+http-01") {
  126. continue
  127. }
  128. res++
  129. }
  130. return res
  131. }
  132. func dummyCert(pub interface{}, san ...string) ([]byte, error) {
  133. return dateDummyCert(pub, time.Now(), time.Now().Add(90*24*time.Hour), san...)
  134. }
  135. func dateDummyCert(pub interface{}, start, end time.Time, san ...string) ([]byte, error) {
  136. // use EC key to run faster on 386
  137. key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  138. if err != nil {
  139. return nil, err
  140. }
  141. t := &x509.Certificate{
  142. SerialNumber: big.NewInt(1),
  143. NotBefore: start,
  144. NotAfter: end,
  145. BasicConstraintsValid: true,
  146. KeyUsage: x509.KeyUsageKeyEncipherment,
  147. DNSNames: san,
  148. }
  149. if pub == nil {
  150. pub = &key.PublicKey
  151. }
  152. return x509.CreateCertificate(rand.Reader, t, t, pub, key)
  153. }
  154. func decodePayload(v interface{}, r io.Reader) error {
  155. var req struct{ Payload string }
  156. if err := json.NewDecoder(r).Decode(&req); err != nil {
  157. return err
  158. }
  159. payload, err := base64.RawURLEncoding.DecodeString(req.Payload)
  160. if err != nil {
  161. return err
  162. }
  163. return json.Unmarshal(payload, v)
  164. }
  165. func clientHelloInfo(sni string, ecdsaSupport bool) *tls.ClientHelloInfo {
  166. hello := &tls.ClientHelloInfo{
  167. ServerName: sni,
  168. CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305},
  169. }
  170. if ecdsaSupport {
  171. hello.CipherSuites = append(hello.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305)
  172. }
  173. return hello
  174. }
  175. func TestGetCertificate(t *testing.T) {
  176. man := &Manager{Prompt: AcceptTOS}
  177. defer man.stopRenew()
  178. hello := clientHelloInfo("example.org", true)
  179. testGetCertificate(t, man, "example.org", hello)
  180. }
  181. func TestGetCertificate_trailingDot(t *testing.T) {
  182. man := &Manager{Prompt: AcceptTOS}
  183. defer man.stopRenew()
  184. hello := clientHelloInfo("example.org.", true)
  185. testGetCertificate(t, man, "example.org", hello)
  186. }
  187. func TestGetCertificate_ForceRSA(t *testing.T) {
  188. man := &Manager{
  189. Prompt: AcceptTOS,
  190. Cache: newMemCache(t),
  191. ForceRSA: true,
  192. }
  193. defer man.stopRenew()
  194. hello := clientHelloInfo(exampleDomain, true)
  195. testGetCertificate(t, man, exampleDomain, hello)
  196. // ForceRSA was deprecated and is now ignored.
  197. cert, err := man.cacheGet(context.Background(), exampleCertKey)
  198. if err != nil {
  199. t.Fatalf("man.cacheGet: %v", err)
  200. }
  201. if _, ok := cert.PrivateKey.(*ecdsa.PrivateKey); !ok {
  202. t.Errorf("cert.PrivateKey is %T; want *ecdsa.PrivateKey", cert.PrivateKey)
  203. }
  204. }
  205. func TestGetCertificate_nilPrompt(t *testing.T) {
  206. man := &Manager{}
  207. defer man.stopRenew()
  208. url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), "example.org")
  209. defer finish()
  210. man.Client = &acme.Client{DirectoryURL: url}
  211. hello := clientHelloInfo("example.org", true)
  212. if _, err := man.GetCertificate(hello); err == nil {
  213. t.Error("got certificate for example.org; wanted error")
  214. }
  215. }
  216. func TestGetCertificate_expiredCache(t *testing.T) {
  217. // Make an expired cert and cache it.
  218. pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  219. if err != nil {
  220. t.Fatal(err)
  221. }
  222. tmpl := &x509.Certificate{
  223. SerialNumber: big.NewInt(1),
  224. Subject: pkix.Name{CommonName: exampleDomain},
  225. NotAfter: time.Now(),
  226. }
  227. pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &pk.PublicKey, pk)
  228. if err != nil {
  229. t.Fatal(err)
  230. }
  231. tlscert := &tls.Certificate{
  232. Certificate: [][]byte{pub},
  233. PrivateKey: pk,
  234. }
  235. man := &Manager{Prompt: AcceptTOS, Cache: newMemCache(t)}
  236. defer man.stopRenew()
  237. if err := man.cachePut(context.Background(), exampleCertKey, tlscert); err != nil {
  238. t.Fatalf("man.cachePut: %v", err)
  239. }
  240. // The expired cached cert should trigger a new cert issuance
  241. // and return without an error.
  242. hello := clientHelloInfo(exampleDomain, true)
  243. testGetCertificate(t, man, exampleDomain, hello)
  244. }
  245. func TestGetCertificate_failedAttempt(t *testing.T) {
  246. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  247. w.WriteHeader(http.StatusBadRequest)
  248. }))
  249. defer ts.Close()
  250. d := createCertRetryAfter
  251. f := testDidRemoveState
  252. defer func() {
  253. createCertRetryAfter = d
  254. testDidRemoveState = f
  255. }()
  256. createCertRetryAfter = 0
  257. done := make(chan struct{})
  258. testDidRemoveState = func(ck certKey) {
  259. if ck != exampleCertKey {
  260. t.Errorf("testDidRemoveState: domain = %v; want %v", ck, exampleCertKey)
  261. }
  262. close(done)
  263. }
  264. man := &Manager{
  265. Prompt: AcceptTOS,
  266. Client: &acme.Client{
  267. DirectoryURL: ts.URL,
  268. },
  269. }
  270. defer man.stopRenew()
  271. hello := clientHelloInfo(exampleDomain, true)
  272. if _, err := man.GetCertificate(hello); err == nil {
  273. t.Error("GetCertificate: err is nil")
  274. }
  275. select {
  276. case <-time.After(5 * time.Second):
  277. t.Errorf("took too long to remove the %q state", exampleCertKey)
  278. case <-done:
  279. man.stateMu.Lock()
  280. defer man.stateMu.Unlock()
  281. if v, exist := man.state[exampleCertKey]; exist {
  282. t.Errorf("state exists for %v: %+v", exampleCertKey, v)
  283. }
  284. }
  285. }
  286. // testGetCertificate_tokenCache tests the fallback of token certificate fetches
  287. // to cache when Manager.certTokens misses. ecdsaSupport refers to the CA when
  288. // verifying the certificate token.
  289. func testGetCertificate_tokenCache(t *testing.T, ecdsaSupport bool) {
  290. man1 := &Manager{
  291. Cache: newMemCache(t),
  292. Prompt: AcceptTOS,
  293. }
  294. defer man1.stopRenew()
  295. man2 := &Manager{
  296. Cache: man1.Cache,
  297. Prompt: AcceptTOS,
  298. }
  299. defer man2.stopRenew()
  300. // Send the verification request to a different Manager from the one that
  301. // initiated the authorization, when they share caches.
  302. url, finish := startACMEServerStub(t, getCertificateFromManager(man2, ecdsaSupport), "example.org")
  303. defer finish()
  304. man1.Client = &acme.Client{DirectoryURL: url}
  305. hello := clientHelloInfo("example.org", true)
  306. if _, err := man1.GetCertificate(hello); err != nil {
  307. t.Error(err)
  308. }
  309. if _, err := man2.GetCertificate(hello); err != nil {
  310. t.Error(err)
  311. }
  312. }
  313. func TestGetCertificate_tokenCache(t *testing.T) {
  314. t.Run("ecdsaSupport=true", func(t *testing.T) {
  315. testGetCertificate_tokenCache(t, true)
  316. })
  317. t.Run("ecdsaSupport=false", func(t *testing.T) {
  318. testGetCertificate_tokenCache(t, false)
  319. })
  320. }
  321. func TestGetCertificate_ecdsaVsRSA(t *testing.T) {
  322. cache := newMemCache(t)
  323. man := &Manager{Prompt: AcceptTOS, Cache: cache}
  324. defer man.stopRenew()
  325. url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), "example.org")
  326. defer finish()
  327. man.Client = &acme.Client{DirectoryURL: url}
  328. cert, err := man.GetCertificate(clientHelloInfo("example.org", true))
  329. if err != nil {
  330. t.Error(err)
  331. }
  332. if _, ok := cert.Leaf.PublicKey.(*ecdsa.PublicKey); !ok {
  333. t.Error("an ECDSA client was served a non-ECDSA certificate")
  334. }
  335. cert, err = man.GetCertificate(clientHelloInfo("example.org", false))
  336. if err != nil {
  337. t.Error(err)
  338. }
  339. if _, ok := cert.Leaf.PublicKey.(*rsa.PublicKey); !ok {
  340. t.Error("a RSA client was served a non-RSA certificate")
  341. }
  342. if _, err := man.GetCertificate(clientHelloInfo("example.org", true)); err != nil {
  343. t.Error(err)
  344. }
  345. if _, err := man.GetCertificate(clientHelloInfo("example.org", false)); err != nil {
  346. t.Error(err)
  347. }
  348. if numCerts := cache.numCerts(); numCerts != 2 {
  349. t.Errorf("found %d certificates in cache; want %d", numCerts, 2)
  350. }
  351. }
  352. func TestGetCertificate_wrongCacheKeyType(t *testing.T) {
  353. cache := newMemCache(t)
  354. man := &Manager{Prompt: AcceptTOS, Cache: cache}
  355. defer man.stopRenew()
  356. url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), exampleDomain)
  357. defer finish()
  358. man.Client = &acme.Client{DirectoryURL: url}
  359. // Make an RSA cert and cache it without suffix.
  360. pk, err := rsa.GenerateKey(rand.Reader, 512)
  361. if err != nil {
  362. t.Fatal(err)
  363. }
  364. tmpl := &x509.Certificate{
  365. SerialNumber: big.NewInt(1),
  366. Subject: pkix.Name{CommonName: exampleDomain},
  367. NotAfter: time.Now().Add(90 * 24 * time.Hour),
  368. }
  369. pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &pk.PublicKey, pk)
  370. if err != nil {
  371. t.Fatal(err)
  372. }
  373. rsaCert := &tls.Certificate{
  374. Certificate: [][]byte{pub},
  375. PrivateKey: pk,
  376. }
  377. if err := man.cachePut(context.Background(), exampleCertKey, rsaCert); err != nil {
  378. t.Fatalf("man.cachePut: %v", err)
  379. }
  380. // The RSA cached cert should be silently ignored and replaced.
  381. cert, err := man.GetCertificate(clientHelloInfo(exampleDomain, true))
  382. if err != nil {
  383. t.Error(err)
  384. }
  385. if _, ok := cert.Leaf.PublicKey.(*ecdsa.PublicKey); !ok {
  386. t.Error("an ECDSA client was served a non-ECDSA certificate")
  387. }
  388. if numCerts := cache.numCerts(); numCerts != 1 {
  389. t.Errorf("found %d certificates in cache; want %d", numCerts, 1)
  390. }
  391. }
  392. func getCertificateFromManager(man *Manager, ecdsaSupport bool) func(string) error {
  393. return func(sni string) error {
  394. _, err := man.GetCertificate(clientHelloInfo(sni, ecdsaSupport))
  395. return err
  396. }
  397. }
  398. // startACMEServerStub runs an ACME server
  399. // The domain argument is the expected domain name of a certificate request.
  400. // TODO: Drop this in favour of x/crypto/acme/autocert/internal/acmetest.
  401. func startACMEServerStub(t *testing.T, getCertificate func(string) error, domain string) (url string, finish func()) {
  402. // echo token-02 | shasum -a 256
  403. // then divide result in 2 parts separated by dot
  404. tokenCertName := "4e8eb87631187e9ff2153b56b13a4dec.13a35d002e485d60ff37354b32f665d9.token.acme.invalid"
  405. verifyTokenCert := func() {
  406. if err := getCertificate(tokenCertName); err != nil {
  407. t.Errorf("verifyTokenCert: GetCertificate(%q): %v", tokenCertName, err)
  408. return
  409. }
  410. }
  411. // ACME CA server stub
  412. var ca *httptest.Server
  413. ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  414. w.Header().Set("Replay-Nonce", "nonce")
  415. if r.Method == "HEAD" {
  416. // a nonce request
  417. return
  418. }
  419. switch r.URL.Path {
  420. // discovery
  421. case "/":
  422. if err := discoTmpl.Execute(w, ca.URL); err != nil {
  423. t.Errorf("discoTmpl: %v", err)
  424. }
  425. // client key registration
  426. case "/new-reg":
  427. w.Write([]byte("{}"))
  428. // domain authorization
  429. case "/new-authz":
  430. w.Header().Set("Location", ca.URL+"/authz/1")
  431. w.WriteHeader(http.StatusCreated)
  432. if err := authzTmpl.Execute(w, ca.URL); err != nil {
  433. t.Errorf("authzTmpl: %v", err)
  434. }
  435. // accept tls-sni-02 challenge
  436. case "/challenge/2":
  437. verifyTokenCert()
  438. w.Write([]byte("{}"))
  439. // authorization status
  440. case "/authz/1":
  441. w.Write([]byte(`{"status": "valid"}`))
  442. // cert request
  443. case "/new-cert":
  444. var req struct {
  445. CSR string `json:"csr"`
  446. }
  447. decodePayload(&req, r.Body)
  448. b, _ := base64.RawURLEncoding.DecodeString(req.CSR)
  449. csr, err := x509.ParseCertificateRequest(b)
  450. if err != nil {
  451. t.Errorf("new-cert: CSR: %v", err)
  452. }
  453. if csr.Subject.CommonName != domain {
  454. t.Errorf("CommonName in CSR = %q; want %q", csr.Subject.CommonName, domain)
  455. }
  456. der, err := dummyCert(csr.PublicKey, domain)
  457. if err != nil {
  458. t.Errorf("new-cert: dummyCert: %v", err)
  459. }
  460. chainUp := fmt.Sprintf("<%s/ca-cert>; rel=up", ca.URL)
  461. w.Header().Set("Link", chainUp)
  462. w.WriteHeader(http.StatusCreated)
  463. w.Write(der)
  464. // CA chain cert
  465. case "/ca-cert":
  466. der, err := dummyCert(nil, "ca")
  467. if err != nil {
  468. t.Errorf("ca-cert: dummyCert: %v", err)
  469. }
  470. w.Write(der)
  471. default:
  472. t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
  473. }
  474. }))
  475. finish = func() {
  476. ca.Close()
  477. // make sure token cert was removed
  478. cancel := make(chan struct{})
  479. done := make(chan struct{})
  480. go func() {
  481. defer close(done)
  482. tick := time.NewTicker(100 * time.Millisecond)
  483. defer tick.Stop()
  484. for {
  485. if err := getCertificate(tokenCertName); err != nil {
  486. return
  487. }
  488. select {
  489. case <-tick.C:
  490. case <-cancel:
  491. return
  492. }
  493. }
  494. }()
  495. select {
  496. case <-done:
  497. case <-time.After(5 * time.Second):
  498. close(cancel)
  499. t.Error("token cert was not removed")
  500. <-done
  501. }
  502. }
  503. return ca.URL, finish
  504. }
  505. // tests man.GetCertificate flow using the provided hello argument.
  506. // The domain argument is the expected domain name of a certificate request.
  507. func testGetCertificate(t *testing.T, man *Manager, domain string, hello *tls.ClientHelloInfo) {
  508. url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), domain)
  509. defer finish()
  510. man.Client = &acme.Client{DirectoryURL: url}
  511. // simulate tls.Config.GetCertificate
  512. var tlscert *tls.Certificate
  513. var err error
  514. done := make(chan struct{})
  515. go func() {
  516. tlscert, err = man.GetCertificate(hello)
  517. close(done)
  518. }()
  519. select {
  520. case <-time.After(time.Minute):
  521. t.Fatal("man.GetCertificate took too long to return")
  522. case <-done:
  523. }
  524. if err != nil {
  525. t.Fatalf("man.GetCertificate: %v", err)
  526. }
  527. // verify the tlscert is the same we responded with from the CA stub
  528. if len(tlscert.Certificate) == 0 {
  529. t.Fatal("len(tlscert.Certificate) is 0")
  530. }
  531. cert, err := x509.ParseCertificate(tlscert.Certificate[0])
  532. if err != nil {
  533. t.Fatalf("x509.ParseCertificate: %v", err)
  534. }
  535. if len(cert.DNSNames) == 0 || cert.DNSNames[0] != domain {
  536. t.Errorf("cert.DNSNames = %v; want %q", cert.DNSNames, domain)
  537. }
  538. }
  539. func TestVerifyHTTP01(t *testing.T) {
  540. var (
  541. http01 http.Handler
  542. authzCount int // num. of created authorizations
  543. didAcceptHTTP01 bool
  544. )
  545. verifyHTTPToken := func() {
  546. r := httptest.NewRequest("GET", "/.well-known/acme-challenge/token-http-01", nil)
  547. w := httptest.NewRecorder()
  548. http01.ServeHTTP(w, r)
  549. if w.Code != http.StatusOK {
  550. t.Errorf("http token: w.Code = %d; want %d", w.Code, http.StatusOK)
  551. }
  552. if v := w.Body.String(); !strings.HasPrefix(v, "token-http-01.") {
  553. t.Errorf("http token value = %q; want 'token-http-01.' prefix", v)
  554. }
  555. }
  556. // ACME CA server stub, only the needed bits.
  557. // TODO: Replace this with x/crypto/acme/autocert/internal/acmetest.
  558. var ca *httptest.Server
  559. ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  560. w.Header().Set("Replay-Nonce", "nonce")
  561. if r.Method == "HEAD" {
  562. // a nonce request
  563. return
  564. }
  565. switch r.URL.Path {
  566. // Discovery.
  567. case "/":
  568. if err := discoTmpl.Execute(w, ca.URL); err != nil {
  569. t.Errorf("discoTmpl: %v", err)
  570. }
  571. // Client key registration.
  572. case "/new-reg":
  573. w.Write([]byte("{}"))
  574. // New domain authorization.
  575. case "/new-authz":
  576. authzCount++
  577. w.Header().Set("Location", fmt.Sprintf("%s/authz/%d", ca.URL, authzCount))
  578. w.WriteHeader(http.StatusCreated)
  579. if err := authzTmpl.Execute(w, ca.URL); err != nil {
  580. t.Errorf("authzTmpl: %v", err)
  581. }
  582. // Accept tls-sni-02.
  583. case "/challenge/2":
  584. w.Write([]byte("{}"))
  585. // Reject tls-sni-01.
  586. case "/challenge/1":
  587. http.Error(w, "won't accept tls-sni-01", http.StatusBadRequest)
  588. // Should not accept dns-01.
  589. case "/challenge/dns-01":
  590. t.Errorf("dns-01 challenge was accepted")
  591. http.Error(w, "won't accept dns-01", http.StatusBadRequest)
  592. // Accept http-01.
  593. case "/challenge/http-01":
  594. didAcceptHTTP01 = true
  595. verifyHTTPToken()
  596. w.Write([]byte("{}"))
  597. // Authorization statuses.
  598. // Make tls-sni-xxx invalid.
  599. case "/authz/1", "/authz/2":
  600. w.Write([]byte(`{"status": "invalid"}`))
  601. case "/authz/3", "/authz/4":
  602. w.Write([]byte(`{"status": "valid"}`))
  603. default:
  604. http.NotFound(w, r)
  605. t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
  606. }
  607. }))
  608. defer ca.Close()
  609. m := &Manager{
  610. Client: &acme.Client{
  611. DirectoryURL: ca.URL,
  612. },
  613. }
  614. http01 = m.HTTPHandler(nil)
  615. ctx := context.Background()
  616. client, err := m.acmeClient(ctx)
  617. if err != nil {
  618. t.Fatalf("m.acmeClient: %v", err)
  619. }
  620. if err := m.verify(ctx, client, "example.org"); err != nil {
  621. t.Errorf("m.verify: %v", err)
  622. }
  623. // Only tls-sni-01, tls-sni-02 and http-01 must be accepted
  624. // The dns-01 challenge is unsupported.
  625. if authzCount != 3 {
  626. t.Errorf("authzCount = %d; want 3", authzCount)
  627. }
  628. if !didAcceptHTTP01 {
  629. t.Error("did not accept http-01 challenge")
  630. }
  631. }
  632. func TestRevokeFailedAuthz(t *testing.T) {
  633. // Prefill authorization URIs expected to be revoked.
  634. // The challenges are selected in a specific order,
  635. // each tried within a newly created authorization.
  636. // This means each authorization URI corresponds to a different challenge type.
  637. revokedAuthz := map[string]bool{
  638. "/authz/0": false, // tls-sni-02
  639. "/authz/1": false, // tls-sni-01
  640. "/authz/2": false, // no viable challenge, but authz is created
  641. }
  642. var authzCount int // num. of created authorizations
  643. var revokeCount int // num. of revoked authorizations
  644. done := make(chan struct{}) // closed when revokeCount is 3
  645. // ACME CA server stub, only the needed bits.
  646. // TODO: Replace this with x/crypto/acme/autocert/internal/acmetest.
  647. var ca *httptest.Server
  648. ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  649. w.Header().Set("Replay-Nonce", "nonce")
  650. if r.Method == "HEAD" {
  651. // a nonce request
  652. return
  653. }
  654. switch r.URL.Path {
  655. // Discovery.
  656. case "/":
  657. if err := discoTmpl.Execute(w, ca.URL); err != nil {
  658. t.Errorf("discoTmpl: %v", err)
  659. }
  660. // Client key registration.
  661. case "/new-reg":
  662. w.Write([]byte("{}"))
  663. // New domain authorization.
  664. case "/new-authz":
  665. w.Header().Set("Location", fmt.Sprintf("%s/authz/%d", ca.URL, authzCount))
  666. w.WriteHeader(http.StatusCreated)
  667. if err := authzTmpl.Execute(w, ca.URL); err != nil {
  668. t.Errorf("authzTmpl: %v", err)
  669. }
  670. authzCount++
  671. // tls-sni-02 challenge "accept" request.
  672. case "/challenge/2":
  673. // Refuse.
  674. http.Error(w, "won't accept tls-sni-02 challenge", http.StatusBadRequest)
  675. // tls-sni-01 challenge "accept" request.
  676. case "/challenge/1":
  677. // Accept but the authorization will be "expired".
  678. w.Write([]byte("{}"))
  679. // Authorization requests.
  680. case "/authz/0", "/authz/1", "/authz/2":
  681. // Revocation requests.
  682. if r.Method == "POST" {
  683. var req struct{ Status string }
  684. if err := decodePayload(&req, r.Body); err != nil {
  685. t.Errorf("%s: decodePayload: %v", r.URL, err)
  686. }
  687. switch req.Status {
  688. case "deactivated":
  689. revokedAuthz[r.URL.Path] = true
  690. revokeCount++
  691. if revokeCount >= 3 {
  692. // Last authorization is revoked.
  693. defer close(done)
  694. }
  695. default:
  696. t.Errorf("%s: req.Status = %q; want 'deactivated'", r.URL, req.Status)
  697. }
  698. w.Write([]byte(`{"status": "invalid"}`))
  699. return
  700. }
  701. // Authorization status requests.
  702. // Simulate abandoned authorization, deleted by the CA.
  703. w.WriteHeader(http.StatusNotFound)
  704. default:
  705. http.NotFound(w, r)
  706. t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
  707. }
  708. }))
  709. defer ca.Close()
  710. m := &Manager{
  711. Client: &acme.Client{DirectoryURL: ca.URL},
  712. }
  713. // Should fail and revoke 3 authorizations.
  714. // The first 2 are tsl-sni-02 and tls-sni-01 challenges.
  715. // The third time an authorization is created but no viable challenge is found.
  716. // See revokedAuthz above for more explanation.
  717. if _, err := m.createCert(context.Background(), exampleCertKey); err == nil {
  718. t.Errorf("m.createCert returned nil error")
  719. }
  720. select {
  721. case <-time.After(3 * time.Second):
  722. t.Error("revocations took too long")
  723. case <-done:
  724. // revokeCount is at least 3.
  725. }
  726. for uri, ok := range revokedAuthz {
  727. if !ok {
  728. t.Errorf("%q authorization was not revoked", uri)
  729. }
  730. }
  731. }
  732. func TestHTTPHandlerDefaultFallback(t *testing.T) {
  733. tt := []struct {
  734. method, url string
  735. wantCode int
  736. wantLocation string
  737. }{
  738. {"GET", "http://example.org", 302, "https://example.org/"},
  739. {"GET", "http://example.org/foo", 302, "https://example.org/foo"},
  740. {"GET", "http://example.org/foo/bar/", 302, "https://example.org/foo/bar/"},
  741. {"GET", "http://example.org/?a=b", 302, "https://example.org/?a=b"},
  742. {"GET", "http://example.org/foo?a=b", 302, "https://example.org/foo?a=b"},
  743. {"GET", "http://example.org:80/foo?a=b", 302, "https://example.org:443/foo?a=b"},
  744. {"GET", "http://example.org:80/foo%20bar", 302, "https://example.org:443/foo%20bar"},
  745. {"GET", "http://[2602:d1:xxxx::c60a]:1234", 302, "https://[2602:d1:xxxx::c60a]:443/"},
  746. {"GET", "http://[2602:d1:xxxx::c60a]", 302, "https://[2602:d1:xxxx::c60a]/"},
  747. {"GET", "http://[2602:d1:xxxx::c60a]/foo?a=b", 302, "https://[2602:d1:xxxx::c60a]/foo?a=b"},
  748. {"HEAD", "http://example.org", 302, "https://example.org/"},
  749. {"HEAD", "http://example.org/foo", 302, "https://example.org/foo"},
  750. {"HEAD", "http://example.org/foo/bar/", 302, "https://example.org/foo/bar/"},
  751. {"HEAD", "http://example.org/?a=b", 302, "https://example.org/?a=b"},
  752. {"HEAD", "http://example.org/foo?a=b", 302, "https://example.org/foo?a=b"},
  753. {"POST", "http://example.org", 400, ""},
  754. {"PUT", "http://example.org", 400, ""},
  755. {"GET", "http://example.org/.well-known/acme-challenge/x", 404, ""},
  756. }
  757. var m Manager
  758. h := m.HTTPHandler(nil)
  759. for i, test := range tt {
  760. r := httptest.NewRequest(test.method, test.url, nil)
  761. w := httptest.NewRecorder()
  762. h.ServeHTTP(w, r)
  763. if w.Code != test.wantCode {
  764. t.Errorf("%d: w.Code = %d; want %d", i, w.Code, test.wantCode)
  765. t.Errorf("%d: body: %s", i, w.Body.Bytes())
  766. }
  767. if v := w.Header().Get("Location"); v != test.wantLocation {
  768. t.Errorf("%d: Location = %q; want %q", i, v, test.wantLocation)
  769. }
  770. }
  771. }
  772. func TestAccountKeyCache(t *testing.T) {
  773. m := Manager{Cache: newMemCache(t)}
  774. ctx := context.Background()
  775. k1, err := m.accountKey(ctx)
  776. if err != nil {
  777. t.Fatal(err)
  778. }
  779. k2, err := m.accountKey(ctx)
  780. if err != nil {
  781. t.Fatal(err)
  782. }
  783. if !reflect.DeepEqual(k1, k2) {
  784. t.Errorf("account keys don't match: k1 = %#v; k2 = %#v", k1, k2)
  785. }
  786. }
  787. func TestCache(t *testing.T) {
  788. ecdsaKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  789. if err != nil {
  790. t.Fatal(err)
  791. }
  792. cert, err := dummyCert(ecdsaKey.Public(), exampleDomain)
  793. if err != nil {
  794. t.Fatal(err)
  795. }
  796. ecdsaCert := &tls.Certificate{
  797. Certificate: [][]byte{cert},
  798. PrivateKey: ecdsaKey,
  799. }
  800. rsaKey, err := rsa.GenerateKey(rand.Reader, 512)
  801. if err != nil {
  802. t.Fatal(err)
  803. }
  804. cert, err = dummyCert(rsaKey.Public(), exampleDomain)
  805. if err != nil {
  806. t.Fatal(err)
  807. }
  808. rsaCert := &tls.Certificate{
  809. Certificate: [][]byte{cert},
  810. PrivateKey: rsaKey,
  811. }
  812. man := &Manager{Cache: newMemCache(t)}
  813. defer man.stopRenew()
  814. ctx := context.Background()
  815. if err := man.cachePut(ctx, exampleCertKey, ecdsaCert); err != nil {
  816. t.Fatalf("man.cachePut: %v", err)
  817. }
  818. if err := man.cachePut(ctx, exampleCertKeyRSA, rsaCert); err != nil {
  819. t.Fatalf("man.cachePut: %v", err)
  820. }
  821. res, err := man.cacheGet(ctx, exampleCertKey)
  822. if err != nil {
  823. t.Fatalf("man.cacheGet: %v", err)
  824. }
  825. if res == nil || !bytes.Equal(res.Certificate[0], ecdsaCert.Certificate[0]) {
  826. t.Errorf("man.cacheGet = %+v; want %+v", res, ecdsaCert)
  827. }
  828. res, err = man.cacheGet(ctx, exampleCertKeyRSA)
  829. if err != nil {
  830. t.Fatalf("man.cacheGet: %v", err)
  831. }
  832. if res == nil || !bytes.Equal(res.Certificate[0], rsaCert.Certificate[0]) {
  833. t.Errorf("man.cacheGet = %+v; want %+v", res, rsaCert)
  834. }
  835. }
  836. func TestHostWhitelist(t *testing.T) {
  837. policy := HostWhitelist("example.com", "example.org", "*.example.net")
  838. tt := []struct {
  839. host string
  840. allow bool
  841. }{
  842. {"example.com", true},
  843. {"example.org", true},
  844. {"one.example.com", false},
  845. {"two.example.org", false},
  846. {"three.example.net", false},
  847. {"dummy", false},
  848. }
  849. for i, test := range tt {
  850. err := policy(nil, test.host)
  851. if err != nil && test.allow {
  852. t.Errorf("%d: policy(%q): %v; want nil", i, test.host, err)
  853. }
  854. if err == nil && !test.allow {
  855. t.Errorf("%d: policy(%q): nil; want an error", i, test.host)
  856. }
  857. }
  858. }
  859. func TestValidCert(t *testing.T) {
  860. key1, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  861. if err != nil {
  862. t.Fatal(err)
  863. }
  864. key2, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  865. if err != nil {
  866. t.Fatal(err)
  867. }
  868. key3, err := rsa.GenerateKey(rand.Reader, 512)
  869. if err != nil {
  870. t.Fatal(err)
  871. }
  872. cert1, err := dummyCert(key1.Public(), "example.org")
  873. if err != nil {
  874. t.Fatal(err)
  875. }
  876. cert2, err := dummyCert(key2.Public(), "example.org")
  877. if err != nil {
  878. t.Fatal(err)
  879. }
  880. cert3, err := dummyCert(key3.Public(), "example.org")
  881. if err != nil {
  882. t.Fatal(err)
  883. }
  884. now := time.Now()
  885. early, err := dateDummyCert(key1.Public(), now.Add(time.Hour), now.Add(2*time.Hour), "example.org")
  886. if err != nil {
  887. t.Fatal(err)
  888. }
  889. expired, err := dateDummyCert(key1.Public(), now.Add(-2*time.Hour), now.Add(-time.Hour), "example.org")
  890. if err != nil {
  891. t.Fatal(err)
  892. }
  893. tt := []struct {
  894. ck certKey
  895. key crypto.Signer
  896. cert [][]byte
  897. ok bool
  898. }{
  899. {certKey{domain: "example.org"}, key1, [][]byte{cert1}, true},
  900. {certKey{domain: "example.org", isRSA: true}, key3, [][]byte{cert3}, true},
  901. {certKey{domain: "example.org"}, key1, [][]byte{cert1, cert2, cert3}, true},
  902. {certKey{domain: "example.org"}, key1, [][]byte{cert1, {1}}, false},
  903. {certKey{domain: "example.org"}, key1, [][]byte{{1}}, false},
  904. {certKey{domain: "example.org"}, key1, [][]byte{cert2}, false},
  905. {certKey{domain: "example.org"}, key2, [][]byte{cert1}, false},
  906. {certKey{domain: "example.org"}, key1, [][]byte{cert3}, false},
  907. {certKey{domain: "example.org"}, key3, [][]byte{cert1}, false},
  908. {certKey{domain: "example.net"}, key1, [][]byte{cert1}, false},
  909. {certKey{domain: "example.org"}, key1, [][]byte{early}, false},
  910. {certKey{domain: "example.org"}, key1, [][]byte{expired}, false},
  911. {certKey{domain: "example.org", isRSA: true}, key1, [][]byte{cert1}, false},
  912. {certKey{domain: "example.org"}, key3, [][]byte{cert3}, false},
  913. }
  914. for i, test := range tt {
  915. leaf, err := validCert(test.ck, test.cert, test.key)
  916. if err != nil && test.ok {
  917. t.Errorf("%d: err = %v", i, err)
  918. }
  919. if err == nil && !test.ok {
  920. t.Errorf("%d: err is nil", i)
  921. }
  922. if err == nil && test.ok && leaf == nil {
  923. t.Errorf("%d: leaf is nil", i)
  924. }
  925. }
  926. }
  927. type cacheGetFunc func(ctx context.Context, key string) ([]byte, error)
  928. func (f cacheGetFunc) Get(ctx context.Context, key string) ([]byte, error) {
  929. return f(ctx, key)
  930. }
  931. func (f cacheGetFunc) Put(ctx context.Context, key string, data []byte) error {
  932. return fmt.Errorf("unsupported Put of %q = %q", key, data)
  933. }
  934. func (f cacheGetFunc) Delete(ctx context.Context, key string) error {
  935. return fmt.Errorf("unsupported Delete of %q", key)
  936. }
  937. func TestManagerGetCertificateBogusSNI(t *testing.T) {
  938. m := Manager{
  939. Prompt: AcceptTOS,
  940. Cache: cacheGetFunc(func(ctx context.Context, key string) ([]byte, error) {
  941. return nil, fmt.Errorf("cache.Get of %s", key)
  942. }),
  943. }
  944. tests := []struct {
  945. name string
  946. wantErr string
  947. }{
  948. {"foo.com", "cache.Get of foo.com"},
  949. {"foo.com.", "cache.Get of foo.com"},
  950. {`a\b.com`, "acme/autocert: server name contains invalid character"},
  951. {`a/b.com`, "acme/autocert: server name contains invalid character"},
  952. {"", "acme/autocert: missing server name"},
  953. {"foo", "acme/autocert: server name component count invalid"},
  954. {".foo", "acme/autocert: server name component count invalid"},
  955. {"foo.", "acme/autocert: server name component count invalid"},
  956. {"fo.o", "cache.Get of fo.o"},
  957. }
  958. for _, tt := range tests {
  959. _, err := m.GetCertificate(clientHelloInfo(tt.name, true))
  960. got := fmt.Sprint(err)
  961. if got != tt.wantErr {
  962. t.Errorf("GetCertificate(SNI = %q) = %q; want %q", tt.name, got, tt.wantErr)
  963. }
  964. }
  965. }
  966. func TestCertRequest(t *testing.T) {
  967. key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  968. if err != nil {
  969. t.Fatal(err)
  970. }
  971. // An extension from RFC7633. Any will do.
  972. ext := pkix.Extension{
  973. Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1},
  974. Value: []byte("dummy"),
  975. }
  976. b, err := certRequest(key, "example.org", []pkix.Extension{ext}, "san.example.org")
  977. if err != nil {
  978. t.Fatalf("certRequest: %v", err)
  979. }
  980. r, err := x509.ParseCertificateRequest(b)
  981. if err != nil {
  982. t.Fatalf("ParseCertificateRequest: %v", err)
  983. }
  984. var found bool
  985. for _, v := range r.Extensions {
  986. if v.Id.Equal(ext.Id) {
  987. found = true
  988. break
  989. }
  990. }
  991. if !found {
  992. t.Errorf("want %v in Extensions: %v", ext, r.Extensions)
  993. }
  994. }
  995. func TestSupportsECDSA(t *testing.T) {
  996. tests := []struct {
  997. CipherSuites []uint16
  998. SignatureSchemes []tls.SignatureScheme
  999. SupportedCurves []tls.CurveID
  1000. ecdsaOk bool
  1001. }{
  1002. {[]uint16{
  1003. tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
  1004. }, nil, nil, false},
  1005. {[]uint16{
  1006. tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  1007. }, nil, nil, true},
  1008. // SignatureSchemes limits, not extends, CipherSuites
  1009. {[]uint16{
  1010. tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
  1011. }, []tls.SignatureScheme{
  1012. tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
  1013. }, nil, false},
  1014. {[]uint16{
  1015. tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  1016. }, []tls.SignatureScheme{
  1017. tls.PKCS1WithSHA256,
  1018. }, nil, false},
  1019. {[]uint16{
  1020. tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  1021. }, []tls.SignatureScheme{
  1022. tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
  1023. }, nil, true},
  1024. {[]uint16{
  1025. tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  1026. }, []tls.SignatureScheme{
  1027. tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
  1028. }, []tls.CurveID{
  1029. tls.CurveP521,
  1030. }, false},
  1031. {[]uint16{
  1032. tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  1033. }, []tls.SignatureScheme{
  1034. tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
  1035. }, []tls.CurveID{
  1036. tls.CurveP256,
  1037. tls.CurveP521,
  1038. }, true},
  1039. }
  1040. for i, tt := range tests {
  1041. result := supportsECDSA(&tls.ClientHelloInfo{
  1042. CipherSuites: tt.CipherSuites,
  1043. SignatureSchemes: tt.SignatureSchemes,
  1044. SupportedCurves: tt.SupportedCurves,
  1045. })
  1046. if result != tt.ecdsaOk {
  1047. t.Errorf("%d: supportsECDSA = %v; want %v", i, result, tt.ecdsaOk)
  1048. }
  1049. }
  1050. }
  1051. // TODO: add same end-to-end for http-01 challenge type.
  1052. func TestEndToEnd(t *testing.T) {
  1053. const domain = "example.org"
  1054. // ACME CA server
  1055. ca := acmetest.NewCAServer([]string{"tls-alpn-01"}, []string{domain})
  1056. defer ca.Close()
  1057. // User dummy server.
  1058. m := &Manager{
  1059. Prompt: AcceptTOS,
  1060. Client: &acme.Client{DirectoryURL: ca.URL},
  1061. }
  1062. us := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1063. w.Write([]byte("OK"))
  1064. }))
  1065. us.TLS = &tls.Config{
  1066. NextProtos: []string{"http/1.1", acme.ALPNProto},
  1067. GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
  1068. cert, err := m.GetCertificate(hello)
  1069. if err != nil {
  1070. t.Errorf("m.GetCertificate: %v", err)
  1071. }
  1072. return cert, err
  1073. },
  1074. }
  1075. us.StartTLS()
  1076. defer us.Close()
  1077. // In TLS-ALPN challenge verification, CA connects to the domain:443 in question.
  1078. // Because the domain won't resolve in tests, we need to tell the CA
  1079. // where to dial to instead.
  1080. ca.Resolve(domain, strings.TrimPrefix(us.URL, "https://"))
  1081. // A client visiting user dummy server.
  1082. tr := &http.Transport{
  1083. TLSClientConfig: &tls.Config{
  1084. RootCAs: ca.Roots,
  1085. ServerName: domain,
  1086. },
  1087. }
  1088. client := &http.Client{Transport: tr}
  1089. res, err := client.Get(us.URL)
  1090. if err != nil {
  1091. t.Logf("CA errors: %v", ca.Errors())
  1092. t.Fatal(err)
  1093. }
  1094. defer res.Body.Close()
  1095. b, err := ioutil.ReadAll(res.Body)
  1096. if err != nil {
  1097. t.Fatal(err)
  1098. }
  1099. if v := string(b); v != "OK" {
  1100. t.Errorf("user server response: %q; want 'OK'", v)
  1101. }
  1102. }