autocert_test.go 24 KB

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