You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1058 lines
32 KiB

  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package acme provides an implementation of the
  5. // Automatic Certificate Management Environment (ACME) spec.
  6. // See https://tools.ietf.org/html/draft-ietf-acme-acme-02 for details.
  7. //
  8. // Most common scenarios will want to use autocert subdirectory instead,
  9. // which provides automatic access to certificates from Let's Encrypt
  10. // and any other ACME-based CA.
  11. //
  12. // This package is a work in progress and makes no API stability promises.
  13. package acme
  14. import (
  15. "bytes"
  16. "context"
  17. "crypto"
  18. "crypto/ecdsa"
  19. "crypto/elliptic"
  20. "crypto/rand"
  21. "crypto/sha256"
  22. "crypto/tls"
  23. "crypto/x509"
  24. "encoding/base64"
  25. "encoding/hex"
  26. "encoding/json"
  27. "encoding/pem"
  28. "errors"
  29. "fmt"
  30. "io"
  31. "io/ioutil"
  32. "math/big"
  33. "net/http"
  34. "strconv"
  35. "strings"
  36. "sync"
  37. "time"
  38. )
  39. // LetsEncryptURL is the Directory endpoint of Let's Encrypt CA.
  40. const LetsEncryptURL = "https://acme-v01.api.letsencrypt.org/directory"
  41. const (
  42. maxChainLen = 5 // max depth and breadth of a certificate chain
  43. maxCertSize = 1 << 20 // max size of a certificate, in bytes
  44. // Max number of collected nonces kept in memory.
  45. // Expect usual peak of 1 or 2.
  46. maxNonces = 100
  47. )
  48. // Client is an ACME client.
  49. // The only required field is Key. An example of creating a client with a new key
  50. // is as follows:
  51. //
  52. // key, err := rsa.GenerateKey(rand.Reader, 2048)
  53. // if err != nil {
  54. // log.Fatal(err)
  55. // }
  56. // client := &Client{Key: key}
  57. //
  58. type Client struct {
  59. // Key is the account key used to register with a CA and sign requests.
  60. // Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey.
  61. Key crypto.Signer
  62. // HTTPClient optionally specifies an HTTP client to use
  63. // instead of http.DefaultClient.
  64. HTTPClient *http.Client
  65. // DirectoryURL points to the CA directory endpoint.
  66. // If empty, LetsEncryptURL is used.
  67. // Mutating this value after a successful call of Client's Discover method
  68. // will have no effect.
  69. DirectoryURL string
  70. dirMu sync.Mutex // guards writes to dir
  71. dir *Directory // cached result of Client's Discover method
  72. noncesMu sync.Mutex
  73. nonces map[string]struct{} // nonces collected from previous responses
  74. }
  75. // Discover performs ACME server discovery using c.DirectoryURL.
  76. //
  77. // It caches successful result. So, subsequent calls will not result in
  78. // a network round-trip. This also means mutating c.DirectoryURL after successful call
  79. // of this method will have no effect.
  80. func (c *Client) Discover(ctx context.Context) (Directory, error) {
  81. c.dirMu.Lock()
  82. defer c.dirMu.Unlock()
  83. if c.dir != nil {
  84. return *c.dir, nil
  85. }
  86. dirURL := c.DirectoryURL
  87. if dirURL == "" {
  88. dirURL = LetsEncryptURL
  89. }
  90. res, err := c.get(ctx, dirURL)
  91. if err != nil {
  92. return Directory{}, err
  93. }
  94. defer res.Body.Close()
  95. c.addNonce(res.Header)
  96. if res.StatusCode != http.StatusOK {
  97. return Directory{}, responseError(res)
  98. }
  99. var v struct {
  100. Reg string `json:"new-reg"`
  101. Authz string `json:"new-authz"`
  102. Cert string `json:"new-cert"`
  103. Revoke string `json:"revoke-cert"`
  104. Meta struct {
  105. Terms string `json:"terms-of-service"`
  106. Website string `json:"website"`
  107. CAA []string `json:"caa-identities"`
  108. }
  109. }
  110. if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
  111. return Directory{}, err
  112. }
  113. c.dir = &Directory{
  114. RegURL: v.Reg,
  115. AuthzURL: v.Authz,
  116. CertURL: v.Cert,
  117. RevokeURL: v.Revoke,
  118. Terms: v.Meta.Terms,
  119. Website: v.Meta.Website,
  120. CAA: v.Meta.CAA,
  121. }
  122. return *c.dir, nil
  123. }
  124. // CreateCert requests a new certificate using the Certificate Signing Request csr encoded in DER format.
  125. // The exp argument indicates the desired certificate validity duration. CA may issue a certificate
  126. // with a different duration.
  127. // If the bundle argument is true, the returned value will also contain the CA (issuer) certificate chain.
  128. //
  129. // In the case where CA server does not provide the issued certificate in the response,
  130. // CreateCert will poll certURL using c.FetchCert, which will result in additional round-trips.
  131. // In such a scenario, the caller can cancel the polling with ctx.
  132. //
  133. // CreateCert returns an error if the CA's response or chain was unreasonably large.
  134. // Callers are encouraged to parse the returned value to ensure the certificate is valid and has the expected features.
  135. func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration, bundle bool) (der [][]byte, certURL string, err error) {
  136. if _, err := c.Discover(ctx); err != nil {
  137. return nil, "", err
  138. }
  139. req := struct {
  140. Resource string `json:"resource"`
  141. CSR string `json:"csr"`
  142. NotBefore string `json:"notBefore,omitempty"`
  143. NotAfter string `json:"notAfter,omitempty"`
  144. }{
  145. Resource: "new-cert",
  146. CSR: base64.RawURLEncoding.EncodeToString(csr),
  147. }
  148. now := timeNow()
  149. req.NotBefore = now.Format(time.RFC3339)
  150. if exp > 0 {
  151. req.NotAfter = now.Add(exp).Format(time.RFC3339)
  152. }
  153. res, err := c.retryPostJWS(ctx, c.Key, c.dir.CertURL, req)
  154. if err != nil {
  155. return nil, "", err
  156. }
  157. defer res.Body.Close()
  158. if res.StatusCode != http.StatusCreated {
  159. return nil, "", responseError(res)
  160. }
  161. curl := res.Header.Get("Location") // cert permanent URL
  162. if res.ContentLength == 0 {
  163. // no cert in the body; poll until we get it
  164. cert, err := c.FetchCert(ctx, curl, bundle)
  165. return cert, curl, err
  166. }
  167. // slurp issued cert and CA chain, if requested
  168. cert, err := c.responseCert(ctx, res, bundle)
  169. return cert, curl, err
  170. }
  171. // FetchCert retrieves already issued certificate from the given url, in DER format.
  172. // It retries the request until the certificate is successfully retrieved,
  173. // context is cancelled by the caller or an error response is received.
  174. //
  175. // The returned value will also contain the CA (issuer) certificate if the bundle argument is true.
  176. //
  177. // FetchCert returns an error if the CA's response or chain was unreasonably large.
  178. // Callers are encouraged to parse the returned value to ensure the certificate is valid
  179. // and has expected features.
  180. func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) {
  181. for {
  182. res, err := c.get(ctx, url)
  183. if err != nil {
  184. return nil, err
  185. }
  186. defer res.Body.Close()
  187. if res.StatusCode == http.StatusOK {
  188. return c.responseCert(ctx, res, bundle)
  189. }
  190. if res.StatusCode > 299 {
  191. return nil, responseError(res)
  192. }
  193. d := retryAfter(res.Header.Get("Retry-After"), 3*time.Second)
  194. select {
  195. case <-time.After(d):
  196. // retry
  197. case <-ctx.Done():
  198. return nil, ctx.Err()
  199. }
  200. }
  201. }
  202. // RevokeCert revokes a previously issued certificate cert, provided in DER format.
  203. //
  204. // The key argument, used to sign the request, must be authorized
  205. // to revoke the certificate. It's up to the CA to decide which keys are authorized.
  206. // For instance, the key pair of the certificate may be authorized.
  207. // If the key is nil, c.Key is used instead.
  208. func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error {
  209. if _, err := c.Discover(ctx); err != nil {
  210. return err
  211. }
  212. body := &struct {
  213. Resource string `json:"resource"`
  214. Cert string `json:"certificate"`
  215. Reason int `json:"reason"`
  216. }{
  217. Resource: "revoke-cert",
  218. Cert: base64.RawURLEncoding.EncodeToString(cert),
  219. Reason: int(reason),
  220. }
  221. if key == nil {
  222. key = c.Key
  223. }
  224. res, err := c.retryPostJWS(ctx, key, c.dir.RevokeURL, body)
  225. if err != nil {
  226. return err
  227. }
  228. defer res.Body.Close()
  229. if res.StatusCode != http.StatusOK {
  230. return responseError(res)
  231. }
  232. return nil
  233. }
  234. // AcceptTOS always returns true to indicate the acceptance of a CA's Terms of Service
  235. // during account registration. See Register method of Client for more details.
  236. func AcceptTOS(tosURL string) bool { return true }
  237. // Register creates a new account registration by following the "new-reg" flow.
  238. // It returns the registered account. The account is not modified.
  239. //
  240. // The registration may require the caller to agree to the CA's Terms of Service (TOS).
  241. // If so, and the account has not indicated the acceptance of the terms (see Account for details),
  242. // Register calls prompt with a TOS URL provided by the CA. Prompt should report
  243. // whether the caller agrees to the terms. To always accept the terms, the caller can use AcceptTOS.
  244. func (c *Client) Register(ctx context.Context, a *Account, prompt func(tosURL string) bool) (*Account, error) {
  245. if _, err := c.Discover(ctx); err != nil {
  246. return nil, err
  247. }
  248. var err error
  249. if a, err = c.doReg(ctx, c.dir.RegURL, "new-reg", a); err != nil {
  250. return nil, err
  251. }
  252. var accept bool
  253. if a.CurrentTerms != "" && a.CurrentTerms != a.AgreedTerms {
  254. accept = prompt(a.CurrentTerms)
  255. }
  256. if accept {
  257. a.AgreedTerms = a.CurrentTerms
  258. a, err = c.UpdateReg(ctx, a)
  259. }
  260. return a, err
  261. }
  262. // GetReg retrieves an existing registration.
  263. // The url argument is an Account URI.
  264. func (c *Client) GetReg(ctx context.Context, url string) (*Account, error) {
  265. a, err := c.doReg(ctx, url, "reg", nil)
  266. if err != nil {
  267. return nil, err
  268. }
  269. a.URI = url
  270. return a, nil
  271. }
  272. // UpdateReg updates an existing registration.
  273. // It returns an updated account copy. The provided account is not modified.
  274. func (c *Client) UpdateReg(ctx context.Context, a *Account) (*Account, error) {
  275. uri := a.URI
  276. a, err := c.doReg(ctx, uri, "reg", a)
  277. if err != nil {
  278. return nil, err
  279. }
  280. a.URI = uri
  281. return a, nil
  282. }
  283. // Authorize performs the initial step in an authorization flow.
  284. // The caller will then need to choose from and perform a set of returned
  285. // challenges using c.Accept in order to successfully complete authorization.
  286. //
  287. // If an authorization has been previously granted, the CA may return
  288. // a valid authorization (Authorization.Status is StatusValid). If so, the caller
  289. // need not fulfill any challenge and can proceed to requesting a certificate.
  290. func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization, error) {
  291. if _, err := c.Discover(ctx); err != nil {
  292. return nil, err
  293. }
  294. type authzID struct {
  295. Type string `json:"type"`
  296. Value string `json:"value"`
  297. }
  298. req := struct {
  299. Resource string `json:"resource"`
  300. Identifier authzID `json:"identifier"`
  301. }{
  302. Resource: "new-authz",
  303. Identifier: authzID{Type: "dns", Value: domain},
  304. }
  305. res, err := c.retryPostJWS(ctx, c.Key, c.dir.AuthzURL, req)
  306. if err != nil {
  307. return nil, err
  308. }
  309. defer res.Body.Close()
  310. if res.StatusCode != http.StatusCreated {
  311. return nil, responseError(res)
  312. }
  313. var v wireAuthz
  314. if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
  315. return nil, fmt.Errorf("acme: invalid response: %v", err)
  316. }
  317. if v.Status != StatusPending && v.Status != StatusValid {
  318. return nil, fmt.Errorf("acme: unexpected status: %s", v.Status)
  319. }
  320. return v.authorization(res.Header.Get("Location")), nil
  321. }
  322. // GetAuthorization retrieves an authorization identified by the given URL.
  323. //
  324. // If a caller needs to poll an authorization until its status is final,
  325. // see the WaitAuthorization method.
  326. func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error) {
  327. res, err := c.get(ctx, url)
  328. if err != nil {
  329. return nil, err
  330. }
  331. defer res.Body.Close()
  332. if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
  333. return nil, responseError(res)
  334. }
  335. var v wireAuthz
  336. if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
  337. return nil, fmt.Errorf("acme: invalid response: %v", err)
  338. }
  339. return v.authorization(url), nil
  340. }
  341. // RevokeAuthorization relinquishes an existing authorization identified
  342. // by the given URL.
  343. // The url argument is an Authorization.URI value.
  344. //
  345. // If successful, the caller will be required to obtain a new authorization
  346. // using the Authorize method before being able to request a new certificate
  347. // for the domain associated with the authorization.
  348. //
  349. // It does not revoke existing certificates.
  350. func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
  351. req := struct {
  352. Resource string `json:"resource"`
  353. Status string `json:"status"`
  354. Delete bool `json:"delete"`
  355. }{
  356. Resource: "authz",
  357. Status: "deactivated",
  358. Delete: true,
  359. }
  360. res, err := c.retryPostJWS(ctx, c.Key, url, req)
  361. if err != nil {
  362. return err
  363. }
  364. defer res.Body.Close()
  365. if res.StatusCode != http.StatusOK {
  366. return responseError(res)
  367. }
  368. return nil
  369. }
  370. // WaitAuthorization polls an authorization at the given URL
  371. // until it is in one of the final states, StatusValid or StatusInvalid,
  372. // or the context is done.
  373. //
  374. // It returns a non-nil Authorization only if its Status is StatusValid.
  375. // In all other cases WaitAuthorization returns an error.
  376. // If the Status is StatusInvalid, the returned error is of type *AuthorizationError.
  377. func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error) {
  378. sleep := sleeper(ctx)
  379. for {
  380. res, err := c.get(ctx, url)
  381. if err != nil {
  382. return nil, err
  383. }
  384. retry := res.Header.Get("Retry-After")
  385. if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
  386. res.Body.Close()
  387. if err := sleep(retry, 1); err != nil {
  388. return nil, err
  389. }
  390. continue
  391. }
  392. var raw wireAuthz
  393. err = json.NewDecoder(res.Body).Decode(&raw)
  394. res.Body.Close()
  395. if err != nil {
  396. if err := sleep(retry, 0); err != nil {
  397. return nil, err
  398. }
  399. continue
  400. }
  401. if raw.Status == StatusValid {
  402. return raw.authorization(url), nil
  403. }
  404. if raw.Status == StatusInvalid {
  405. return nil, raw.error(url)
  406. }
  407. if err := sleep(retry, 0); err != nil {
  408. return nil, err
  409. }
  410. }
  411. }
  412. // GetChallenge retrieves the current status of an challenge.
  413. //
  414. // A client typically polls a challenge status using this method.
  415. func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) {
  416. res, err := c.get(ctx, url)
  417. if err != nil {
  418. return nil, err
  419. }
  420. defer res.Body.Close()
  421. if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
  422. return nil, responseError(res)
  423. }
  424. v := wireChallenge{URI: url}
  425. if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
  426. return nil, fmt.Errorf("acme: invalid response: %v", err)
  427. }
  428. return v.challenge(), nil
  429. }
  430. // Accept informs the server that the client accepts one of its challenges
  431. // previously obtained with c.Authorize.
  432. //
  433. // The server will then perform the validation asynchronously.
  434. func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error) {
  435. auth, err := keyAuth(c.Key.Public(), chal.Token)
  436. if err != nil {
  437. return nil, err
  438. }
  439. req := struct {
  440. Resource string `json:"resource"`
  441. Type string `json:"type"`
  442. Auth string `json:"keyAuthorization"`
  443. }{
  444. Resource: "challenge",
  445. Type: chal.Type,
  446. Auth: auth,
  447. }
  448. res, err := c.retryPostJWS(ctx, c.Key, chal.URI, req)
  449. if err != nil {
  450. return nil, err
  451. }
  452. defer res.Body.Close()
  453. // Note: the protocol specifies 200 as the expected response code, but
  454. // letsencrypt seems to be returning 202.
  455. if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
  456. return nil, responseError(res)
  457. }
  458. var v wireChallenge
  459. if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
  460. return nil, fmt.Errorf("acme: invalid response: %v", err)
  461. }
  462. return v.challenge(), nil
  463. }
  464. // DNS01ChallengeRecord returns a DNS record value for a dns-01 challenge response.
  465. // A TXT record containing the returned value must be provisioned under
  466. // "_acme-challenge" name of the domain being validated.
  467. //
  468. // The token argument is a Challenge.Token value.
  469. func (c *Client) DNS01ChallengeRecord(token string) (string, error) {
  470. ka, err := keyAuth(c.Key.Public(), token)
  471. if err != nil {
  472. return "", err
  473. }
  474. b := sha256.Sum256([]byte(ka))
  475. return base64.RawURLEncoding.EncodeToString(b[:]), nil
  476. }
  477. // HTTP01ChallengeResponse returns the response for an http-01 challenge.
  478. // Servers should respond with the value to HTTP requests at the URL path
  479. // provided by HTTP01ChallengePath to validate the challenge and prove control
  480. // over a domain name.
  481. //
  482. // The token argument is a Challenge.Token value.
  483. func (c *Client) HTTP01ChallengeResponse(token string) (string, error) {
  484. return keyAuth(c.Key.Public(), token)
  485. }
  486. // HTTP01ChallengePath returns the URL path at which the response for an http-01 challenge
  487. // should be provided by the servers.
  488. // The response value can be obtained with HTTP01ChallengeResponse.
  489. //
  490. // The token argument is a Challenge.Token value.
  491. func (c *Client) HTTP01ChallengePath(token string) string {
  492. return "/.well-known/acme-challenge/" + token
  493. }
  494. // TLSSNI01ChallengeCert creates a certificate for TLS-SNI-01 challenge response.
  495. // Servers can present the certificate to validate the challenge and prove control
  496. // over a domain name.
  497. //
  498. // The implementation is incomplete in that the returned value is a single certificate,
  499. // computed only for Z0 of the key authorization. ACME CAs are expected to update
  500. // their implementations to use the newer version, TLS-SNI-02.
  501. // For more details on TLS-SNI-01 see https://tools.ietf.org/html/draft-ietf-acme-acme-01#section-7.3.
  502. //
  503. // The token argument is a Challenge.Token value.
  504. // If a WithKey option is provided, its private part signs the returned cert,
  505. // and the public part is used to specify the signee.
  506. // If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
  507. //
  508. // The returned certificate is valid for the next 24 hours and must be presented only when
  509. // the server name of the client hello matches exactly the returned name value.
  510. func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
  511. ka, err := keyAuth(c.Key.Public(), token)
  512. if err != nil {
  513. return tls.Certificate{}, "", err
  514. }
  515. b := sha256.Sum256([]byte(ka))
  516. h := hex.EncodeToString(b[:])
  517. name = fmt.Sprintf("%s.%s.acme.invalid", h[:32], h[32:])
  518. cert, err = tlsChallengeCert([]string{name}, opt)
  519. if err != nil {
  520. return tls.Certificate{}, "", err
  521. }
  522. return cert, name, nil
  523. }
  524. // TLSSNI02ChallengeCert creates a certificate for TLS-SNI-02 challenge response.
  525. // Servers can present the certificate to validate the challenge and prove control
  526. // over a domain name. For more details on TLS-SNI-02 see
  527. // https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-7.3.
  528. //
  529. // The token argument is a Challenge.Token value.
  530. // If a WithKey option is provided, its private part signs the returned cert,
  531. // and the public part is used to specify the signee.
  532. // If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
  533. //
  534. // The returned certificate is valid for the next 24 hours and must be presented only when
  535. // the server name in the client hello matches exactly the returned name value.
  536. func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
  537. b := sha256.Sum256([]byte(token))
  538. h := hex.EncodeToString(b[:])
  539. sanA := fmt.Sprintf("%s.%s.token.acme.invalid", h[:32], h[32:])
  540. ka, err := keyAuth(c.Key.Public(), token)
  541. if err != nil {
  542. return tls.Certificate{}, "", err
  543. }
  544. b = sha256.Sum256([]byte(ka))
  545. h = hex.EncodeToString(b[:])
  546. sanB := fmt.Sprintf("%s.%s.ka.acme.invalid", h[:32], h[32:])
  547. cert, err = tlsChallengeCert([]string{sanA, sanB}, opt)
  548. if err != nil {
  549. return tls.Certificate{}, "", err
  550. }
  551. return cert, sanA, nil
  552. }
  553. // doReg sends all types of registration requests.
  554. // The type of request is identified by typ argument, which is a "resource"
  555. // in the ACME spec terms.
  556. //
  557. // A non-nil acct argument indicates whether the intention is to mutate data
  558. // of the Account. Only Contact and Agreement of its fields are used
  559. // in such cases.
  560. func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Account) (*Account, error) {
  561. req := struct {
  562. Resource string `json:"resource"`
  563. Contact []string `json:"contact,omitempty"`
  564. Agreement string `json:"agreement,omitempty"`
  565. }{
  566. Resource: typ,
  567. }
  568. if acct != nil {
  569. req.Contact = acct.Contact
  570. req.Agreement = acct.AgreedTerms
  571. }
  572. res, err := c.retryPostJWS(ctx, c.Key, url, req)
  573. if err != nil {
  574. return nil, err
  575. }
  576. defer res.Body.Close()
  577. if res.StatusCode < 200 || res.StatusCode > 299 {
  578. return nil, responseError(res)
  579. }
  580. var v struct {
  581. Contact []string
  582. Agreement string
  583. Authorizations string
  584. Certificates string
  585. }
  586. if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
  587. return nil, fmt.Errorf("acme: invalid response: %v", err)
  588. }
  589. var tos string
  590. if v := linkHeader(res.Header, "terms-of-service"); len(v) > 0 {
  591. tos = v[0]
  592. }
  593. var authz string
  594. if v := linkHeader(res.Header, "next"); len(v) > 0 {
  595. authz = v[0]
  596. }
  597. return &Account{
  598. URI: res.Header.Get("Location"),
  599. Contact: v.Contact,
  600. AgreedTerms: v.Agreement,
  601. CurrentTerms: tos,
  602. Authz: authz,
  603. Authorizations: v.Authorizations,
  604. Certificates: v.Certificates,
  605. }, nil
  606. }
  607. // retryPostJWS will retry calls to postJWS if there is a badNonce error,
  608. // clearing the stored nonces after each error.
  609. // If the response was 4XX-5XX, then responseError is called on the body,
  610. // the body is closed, and the error returned.
  611. func (c *Client) retryPostJWS(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, error) {
  612. sleep := sleeper(ctx)
  613. for {
  614. res, err := c.postJWS(ctx, key, url, body)
  615. if err != nil {
  616. return nil, err
  617. }
  618. // handle errors 4XX-5XX with responseError
  619. if res.StatusCode >= 400 && res.StatusCode <= 599 {
  620. err := responseError(res)
  621. res.Body.Close()
  622. // according to spec badNonce is urn:ietf:params:acme:error:badNonce
  623. // however, acme servers in the wild return their version of the error
  624. // https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-5.4
  625. if ae, ok := err.(*Error); ok && strings.HasSuffix(strings.ToLower(ae.ProblemType), ":badnonce") {
  626. // clear any nonces that we might've stored that might now be
  627. // considered bad
  628. c.clearNonces()
  629. retry := res.Header.Get("Retry-After")
  630. if err := sleep(retry, 1); err != nil {
  631. return nil, err
  632. }
  633. continue
  634. }
  635. return nil, err
  636. }
  637. return res, nil
  638. }
  639. }
  640. // postJWS signs the body with the given key and POSTs it to the provided url.
  641. // The body argument must be JSON-serializable.
  642. func (c *Client) postJWS(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, error) {
  643. nonce, err := c.popNonce(ctx, url)
  644. if err != nil {
  645. return nil, err
  646. }
  647. b, err := jwsEncodeJSON(body, key, nonce)
  648. if err != nil {
  649. return nil, err
  650. }
  651. res, err := c.post(ctx, url, "application/jose+json", bytes.NewReader(b))
  652. if err != nil {
  653. return nil, err
  654. }
  655. c.addNonce(res.Header)
  656. return res, nil
  657. }
  658. // popNonce returns a nonce value previously stored with c.addNonce
  659. // or fetches a fresh one from the given URL.
  660. func (c *Client) popNonce(ctx context.Context, url string) (string, error) {
  661. c.noncesMu.Lock()
  662. defer c.noncesMu.Unlock()
  663. if len(c.nonces) == 0 {
  664. return c.fetchNonce(ctx, url)
  665. }
  666. var nonce string
  667. for nonce = range c.nonces {
  668. delete(c.nonces, nonce)
  669. break
  670. }
  671. return nonce, nil
  672. }
  673. // clearNonces clears any stored nonces
  674. func (c *Client) clearNonces() {
  675. c.noncesMu.Lock()
  676. defer c.noncesMu.Unlock()
  677. c.nonces = make(map[string]struct{})
  678. }
  679. // addNonce stores a nonce value found in h (if any) for future use.
  680. func (c *Client) addNonce(h http.Header) {
  681. v := nonceFromHeader(h)
  682. if v == "" {
  683. return
  684. }
  685. c.noncesMu.Lock()
  686. defer c.noncesMu.Unlock()
  687. if len(c.nonces) >= maxNonces {
  688. return
  689. }
  690. if c.nonces == nil {
  691. c.nonces = make(map[string]struct{})
  692. }
  693. c.nonces[v] = struct{}{}
  694. }
  695. func (c *Client) httpClient() *http.Client {
  696. if c.HTTPClient != nil {
  697. return c.HTTPClient
  698. }
  699. return http.DefaultClient
  700. }
  701. func (c *Client) get(ctx context.Context, urlStr string) (*http.Response, error) {
  702. req, err := http.NewRequest("GET", urlStr, nil)
  703. if err != nil {
  704. return nil, err
  705. }
  706. return c.do(ctx, req)
  707. }
  708. func (c *Client) head(ctx context.Context, urlStr string) (*http.Response, error) {
  709. req, err := http.NewRequest("HEAD", urlStr, nil)
  710. if err != nil {
  711. return nil, err
  712. }
  713. return c.do(ctx, req)
  714. }
  715. func (c *Client) post(ctx context.Context, urlStr, contentType string, body io.Reader) (*http.Response, error) {
  716. req, err := http.NewRequest("POST", urlStr, body)
  717. if err != nil {
  718. return nil, err
  719. }
  720. req.Header.Set("Content-Type", contentType)
  721. return c.do(ctx, req)
  722. }
  723. func (c *Client) do(ctx context.Context, req *http.Request) (*http.Response, error) {
  724. res, err := c.httpClient().Do(req.WithContext(ctx))
  725. if err != nil {
  726. select {
  727. case <-ctx.Done():
  728. // Prefer the unadorned context error.
  729. // (The acme package had tests assuming this, previously from ctxhttp's
  730. // behavior, predating net/http supporting contexts natively)
  731. // TODO(bradfitz): reconsider this in the future. But for now this
  732. // requires no test updates.
  733. return nil, ctx.Err()
  734. default:
  735. return nil, err
  736. }
  737. }
  738. return res, nil
  739. }
  740. func (c *Client) fetchNonce(ctx context.Context, url string) (string, error) {
  741. resp, err := c.head(ctx, url)
  742. if err != nil {
  743. return "", err
  744. }
  745. defer resp.Body.Close()
  746. nonce := nonceFromHeader(resp.Header)
  747. if nonce == "" {
  748. if resp.StatusCode > 299 {
  749. return "", responseError(resp)
  750. }
  751. return "", errors.New("acme: nonce not found")
  752. }
  753. return nonce, nil
  754. }
  755. func nonceFromHeader(h http.Header) string {
  756. return h.Get("Replay-Nonce")
  757. }
  758. func (c *Client) responseCert(ctx context.Context, res *http.Response, bundle bool) ([][]byte, error) {
  759. b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
  760. if err != nil {
  761. return nil, fmt.Errorf("acme: response stream: %v", err)
  762. }
  763. if len(b) > maxCertSize {
  764. return nil, errors.New("acme: certificate is too big")
  765. }
  766. cert := [][]byte{b}
  767. if !bundle {
  768. return cert, nil
  769. }
  770. // Append CA chain cert(s).
  771. // At least one is required according to the spec:
  772. // https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-6.3.1
  773. up := linkHeader(res.Header, "up")
  774. if len(up) == 0 {
  775. return nil, errors.New("acme: rel=up link not found")
  776. }
  777. if len(up) > maxChainLen {
  778. return nil, errors.New("acme: rel=up link is too large")
  779. }
  780. for _, url := range up {
  781. cc, err := c.chainCert(ctx, url, 0)
  782. if err != nil {
  783. return nil, err
  784. }
  785. cert = append(cert, cc...)
  786. }
  787. return cert, nil
  788. }
  789. // responseError creates an error of Error type from resp.
  790. func responseError(resp *http.Response) error {
  791. // don't care if ReadAll returns an error:
  792. // json.Unmarshal will fail in that case anyway
  793. b, _ := ioutil.ReadAll(resp.Body)
  794. e := &wireError{Status: resp.StatusCode}
  795. if err := json.Unmarshal(b, e); err != nil {
  796. // this is not a regular error response:
  797. // populate detail with anything we received,
  798. // e.Status will already contain HTTP response code value
  799. e.Detail = string(b)
  800. if e.Detail == "" {
  801. e.Detail = resp.Status
  802. }
  803. }
  804. return e.error(resp.Header)
  805. }
  806. // chainCert fetches CA certificate chain recursively by following "up" links.
  807. // Each recursive call increments the depth by 1, resulting in an error
  808. // if the recursion level reaches maxChainLen.
  809. //
  810. // First chainCert call starts with depth of 0.
  811. func (c *Client) chainCert(ctx context.Context, url string, depth int) ([][]byte, error) {
  812. if depth >= maxChainLen {
  813. return nil, errors.New("acme: certificate chain is too deep")
  814. }
  815. res, err := c.get(ctx, url)
  816. if err != nil {
  817. return nil, err
  818. }
  819. defer res.Body.Close()
  820. if res.StatusCode != http.StatusOK {
  821. return nil, responseError(res)
  822. }
  823. b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
  824. if err != nil {
  825. return nil, err
  826. }
  827. if len(b) > maxCertSize {
  828. return nil, errors.New("acme: certificate is too big")
  829. }
  830. chain := [][]byte{b}
  831. uplink := linkHeader(res.Header, "up")
  832. if len(uplink) > maxChainLen {
  833. return nil, errors.New("acme: certificate chain is too large")
  834. }
  835. for _, up := range uplink {
  836. cc, err := c.chainCert(ctx, up, depth+1)
  837. if err != nil {
  838. return nil, err
  839. }
  840. chain = append(chain, cc...)
  841. }
  842. return chain, nil
  843. }
  844. // linkHeader returns URI-Reference values of all Link headers
  845. // with relation-type rel.
  846. // See https://tools.ietf.org/html/rfc5988#section-5 for details.
  847. func linkHeader(h http.Header, rel string) []string {
  848. var links []string
  849. for _, v := range h["Link"] {
  850. parts := strings.Split(v, ";")
  851. for _, p := range parts {
  852. p = strings.TrimSpace(p)
  853. if !strings.HasPrefix(p, "rel=") {
  854. continue
  855. }
  856. if v := strings.Trim(p[4:], `"`); v == rel {
  857. links = append(links, strings.Trim(parts[0], "<>"))
  858. }
  859. }
  860. }
  861. return links
  862. }
  863. // sleeper returns a function that accepts the Retry-After HTTP header value
  864. // and an increment that's used with backoff to increasingly sleep on
  865. // consecutive calls until the context is done. If the Retry-After header
  866. // cannot be parsed, then backoff is used with a maximum sleep time of 10
  867. // seconds.
  868. func sleeper(ctx context.Context) func(ra string, inc int) error {
  869. var count int
  870. return func(ra string, inc int) error {
  871. count += inc
  872. d := backoff(count, 10*time.Second)
  873. d = retryAfter(ra, d)
  874. wakeup := time.NewTimer(d)
  875. defer wakeup.Stop()
  876. select {
  877. case <-ctx.Done():
  878. return ctx.Err()
  879. case <-wakeup.C:
  880. return nil
  881. }
  882. }
  883. }
  884. // retryAfter parses a Retry-After HTTP header value,
  885. // trying to convert v into an int (seconds) or use http.ParseTime otherwise.
  886. // It returns d if v cannot be parsed.
  887. func retryAfter(v string, d time.Duration) time.Duration {
  888. if i, err := strconv.Atoi(v); err == nil {
  889. return time.Duration(i) * time.Second
  890. }
  891. t, err := http.ParseTime(v)
  892. if err != nil {
  893. return d
  894. }
  895. return t.Sub(timeNow())
  896. }
  897. // backoff computes a duration after which an n+1 retry iteration should occur
  898. // using truncated exponential backoff algorithm.
  899. //
  900. // The n argument is always bounded between 0 and 30.
  901. // The max argument defines upper bound for the returned value.
  902. func backoff(n int, max time.Duration) time.Duration {
  903. if n < 0 {
  904. n = 0
  905. }
  906. if n > 30 {
  907. n = 30
  908. }
  909. var d time.Duration
  910. if x, err := rand.Int(rand.Reader, big.NewInt(1000)); err == nil {
  911. d = time.Duration(x.Int64()) * time.Millisecond
  912. }
  913. d += time.Duration(1<<uint(n)) * time.Second
  914. if d > max {
  915. return max
  916. }
  917. return d
  918. }
  919. // keyAuth generates a key authorization string for a given token.
  920. func keyAuth(pub crypto.PublicKey, token string) (string, error) {
  921. th, err := JWKThumbprint(pub)
  922. if err != nil {
  923. return "", err
  924. }
  925. return fmt.Sprintf("%s.%s", token, th), nil
  926. }
  927. // tlsChallengeCert creates a temporary certificate for TLS-SNI challenges
  928. // with the given SANs and auto-generated public/private key pair.
  929. // The Subject Common Name is set to the first SAN to aid debugging.
  930. // To create a cert with a custom key pair, specify WithKey option.
  931. func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
  932. var (
  933. key crypto.Signer
  934. tmpl *x509.Certificate
  935. )
  936. for _, o := range opt {
  937. switch o := o.(type) {
  938. case *certOptKey:
  939. if key != nil {
  940. return tls.Certificate{}, errors.New("acme: duplicate key option")
  941. }
  942. key = o.key
  943. case *certOptTemplate:
  944. var t = *(*x509.Certificate)(o) // shallow copy is ok
  945. tmpl = &t
  946. default:
  947. // package's fault, if we let this happen:
  948. panic(fmt.Sprintf("unsupported option type %T", o))
  949. }
  950. }
  951. if key == nil {
  952. var err error
  953. if key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader); err != nil {
  954. return tls.Certificate{}, err
  955. }
  956. }
  957. if tmpl == nil {
  958. tmpl = &x509.Certificate{
  959. SerialNumber: big.NewInt(1),
  960. NotBefore: time.Now(),
  961. NotAfter: time.Now().Add(24 * time.Hour),
  962. BasicConstraintsValid: true,
  963. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
  964. ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
  965. }
  966. }
  967. tmpl.DNSNames = san
  968. if len(san) > 0 {
  969. tmpl.Subject.CommonName = san[0]
  970. }
  971. der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, key.Public(), key)
  972. if err != nil {
  973. return tls.Certificate{}, err
  974. }
  975. return tls.Certificate{
  976. Certificate: [][]byte{der},
  977. PrivateKey: key,
  978. }, nil
  979. }
  980. // encodePEM returns b encoded as PEM with block of type typ.
  981. func encodePEM(typ string, b []byte) []byte {
  982. pb := &pem.Block{Type: typ, Bytes: b}
  983. return pem.EncodeToMemory(pb)
  984. }
  985. // timeNow is useful for testing for fixed current time.
  986. var timeNow = time.Now