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

acme.go 33 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  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. // the ACME CA responded with a 4xx error code, 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. if res.StatusCode >= 400 && res.StatusCode <= 499 {
  385. // Non-retriable error. For instance, Let's Encrypt may return 404 Not Found
  386. // when requesting an expired authorization.
  387. defer res.Body.Close()
  388. return nil, responseError(res)
  389. }
  390. retry := res.Header.Get("Retry-After")
  391. if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
  392. res.Body.Close()
  393. if err := sleep(retry, 1); err != nil {
  394. return nil, err
  395. }
  396. continue
  397. }
  398. var raw wireAuthz
  399. err = json.NewDecoder(res.Body).Decode(&raw)
  400. res.Body.Close()
  401. if err != nil {
  402. if err := sleep(retry, 0); err != nil {
  403. return nil, err
  404. }
  405. continue
  406. }
  407. if raw.Status == StatusValid {
  408. return raw.authorization(url), nil
  409. }
  410. if raw.Status == StatusInvalid {
  411. return nil, raw.error(url)
  412. }
  413. if err := sleep(retry, 0); err != nil {
  414. return nil, err
  415. }
  416. }
  417. }
  418. // GetChallenge retrieves the current status of an challenge.
  419. //
  420. // A client typically polls a challenge status using this method.
  421. func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) {
  422. res, err := c.get(ctx, url)
  423. if err != nil {
  424. return nil, err
  425. }
  426. defer res.Body.Close()
  427. if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
  428. return nil, responseError(res)
  429. }
  430. v := wireChallenge{URI: url}
  431. if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
  432. return nil, fmt.Errorf("acme: invalid response: %v", err)
  433. }
  434. return v.challenge(), nil
  435. }
  436. // Accept informs the server that the client accepts one of its challenges
  437. // previously obtained with c.Authorize.
  438. //
  439. // The server will then perform the validation asynchronously.
  440. func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error) {
  441. auth, err := keyAuth(c.Key.Public(), chal.Token)
  442. if err != nil {
  443. return nil, err
  444. }
  445. req := struct {
  446. Resource string `json:"resource"`
  447. Type string `json:"type"`
  448. Auth string `json:"keyAuthorization"`
  449. }{
  450. Resource: "challenge",
  451. Type: chal.Type,
  452. Auth: auth,
  453. }
  454. res, err := c.retryPostJWS(ctx, c.Key, chal.URI, req)
  455. if err != nil {
  456. return nil, err
  457. }
  458. defer res.Body.Close()
  459. // Note: the protocol specifies 200 as the expected response code, but
  460. // letsencrypt seems to be returning 202.
  461. if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
  462. return nil, responseError(res)
  463. }
  464. var v wireChallenge
  465. if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
  466. return nil, fmt.Errorf("acme: invalid response: %v", err)
  467. }
  468. return v.challenge(), nil
  469. }
  470. // DNS01ChallengeRecord returns a DNS record value for a dns-01 challenge response.
  471. // A TXT record containing the returned value must be provisioned under
  472. // "_acme-challenge" name of the domain being validated.
  473. //
  474. // The token argument is a Challenge.Token value.
  475. func (c *Client) DNS01ChallengeRecord(token string) (string, error) {
  476. ka, err := keyAuth(c.Key.Public(), token)
  477. if err != nil {
  478. return "", err
  479. }
  480. b := sha256.Sum256([]byte(ka))
  481. return base64.RawURLEncoding.EncodeToString(b[:]), nil
  482. }
  483. // HTTP01ChallengeResponse returns the response for an http-01 challenge.
  484. // Servers should respond with the value to HTTP requests at the URL path
  485. // provided by HTTP01ChallengePath to validate the challenge and prove control
  486. // over a domain name.
  487. //
  488. // The token argument is a Challenge.Token value.
  489. func (c *Client) HTTP01ChallengeResponse(token string) (string, error) {
  490. return keyAuth(c.Key.Public(), token)
  491. }
  492. // HTTP01ChallengePath returns the URL path at which the response for an http-01 challenge
  493. // should be provided by the servers.
  494. // The response value can be obtained with HTTP01ChallengeResponse.
  495. //
  496. // The token argument is a Challenge.Token value.
  497. func (c *Client) HTTP01ChallengePath(token string) string {
  498. return "/.well-known/acme-challenge/" + token
  499. }
  500. // TLSSNI01ChallengeCert creates a certificate for TLS-SNI-01 challenge response.
  501. // Servers can present the certificate to validate the challenge and prove control
  502. // over a domain name.
  503. //
  504. // The implementation is incomplete in that the returned value is a single certificate,
  505. // computed only for Z0 of the key authorization. ACME CAs are expected to update
  506. // their implementations to use the newer version, TLS-SNI-02.
  507. // For more details on TLS-SNI-01 see https://tools.ietf.org/html/draft-ietf-acme-acme-01#section-7.3.
  508. //
  509. // The token argument is a Challenge.Token value.
  510. // If a WithKey option is provided, its private part signs the returned cert,
  511. // and the public part is used to specify the signee.
  512. // If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
  513. //
  514. // The returned certificate is valid for the next 24 hours and must be presented only when
  515. // the server name of the client hello matches exactly the returned name value.
  516. func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
  517. ka, err := keyAuth(c.Key.Public(), token)
  518. if err != nil {
  519. return tls.Certificate{}, "", err
  520. }
  521. b := sha256.Sum256([]byte(ka))
  522. h := hex.EncodeToString(b[:])
  523. name = fmt.Sprintf("%s.%s.acme.invalid", h[:32], h[32:])
  524. cert, err = tlsChallengeCert([]string{name}, opt)
  525. if err != nil {
  526. return tls.Certificate{}, "", err
  527. }
  528. return cert, name, nil
  529. }
  530. // TLSSNI02ChallengeCert creates a certificate for TLS-SNI-02 challenge response.
  531. // Servers can present the certificate to validate the challenge and prove control
  532. // over a domain name. For more details on TLS-SNI-02 see
  533. // https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-7.3.
  534. //
  535. // The token argument is a Challenge.Token value.
  536. // If a WithKey option is provided, its private part signs the returned cert,
  537. // and the public part is used to specify the signee.
  538. // If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
  539. //
  540. // The returned certificate is valid for the next 24 hours and must be presented only when
  541. // the server name in the client hello matches exactly the returned name value.
  542. func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
  543. b := sha256.Sum256([]byte(token))
  544. h := hex.EncodeToString(b[:])
  545. sanA := fmt.Sprintf("%s.%s.token.acme.invalid", h[:32], h[32:])
  546. ka, err := keyAuth(c.Key.Public(), token)
  547. if err != nil {
  548. return tls.Certificate{}, "", err
  549. }
  550. b = sha256.Sum256([]byte(ka))
  551. h = hex.EncodeToString(b[:])
  552. sanB := fmt.Sprintf("%s.%s.ka.acme.invalid", h[:32], h[32:])
  553. cert, err = tlsChallengeCert([]string{sanA, sanB}, opt)
  554. if err != nil {
  555. return tls.Certificate{}, "", err
  556. }
  557. return cert, sanA, nil
  558. }
  559. // doReg sends all types of registration requests.
  560. // The type of request is identified by typ argument, which is a "resource"
  561. // in the ACME spec terms.
  562. //
  563. // A non-nil acct argument indicates whether the intention is to mutate data
  564. // of the Account. Only Contact and Agreement of its fields are used
  565. // in such cases.
  566. func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Account) (*Account, error) {
  567. req := struct {
  568. Resource string `json:"resource"`
  569. Contact []string `json:"contact,omitempty"`
  570. Agreement string `json:"agreement,omitempty"`
  571. }{
  572. Resource: typ,
  573. }
  574. if acct != nil {
  575. req.Contact = acct.Contact
  576. req.Agreement = acct.AgreedTerms
  577. }
  578. res, err := c.retryPostJWS(ctx, c.Key, url, req)
  579. if err != nil {
  580. return nil, err
  581. }
  582. defer res.Body.Close()
  583. if res.StatusCode < 200 || res.StatusCode > 299 {
  584. return nil, responseError(res)
  585. }
  586. var v struct {
  587. Contact []string
  588. Agreement string
  589. Authorizations string
  590. Certificates string
  591. }
  592. if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
  593. return nil, fmt.Errorf("acme: invalid response: %v", err)
  594. }
  595. var tos string
  596. if v := linkHeader(res.Header, "terms-of-service"); len(v) > 0 {
  597. tos = v[0]
  598. }
  599. var authz string
  600. if v := linkHeader(res.Header, "next"); len(v) > 0 {
  601. authz = v[0]
  602. }
  603. return &Account{
  604. URI: res.Header.Get("Location"),
  605. Contact: v.Contact,
  606. AgreedTerms: v.Agreement,
  607. CurrentTerms: tos,
  608. Authz: authz,
  609. Authorizations: v.Authorizations,
  610. Certificates: v.Certificates,
  611. }, nil
  612. }
  613. // retryPostJWS will retry calls to postJWS if there is a badNonce error,
  614. // clearing the stored nonces after each error.
  615. // If the response was 4XX-5XX, then responseError is called on the body,
  616. // the body is closed, and the error returned.
  617. func (c *Client) retryPostJWS(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, error) {
  618. sleep := sleeper(ctx)
  619. for {
  620. res, err := c.postJWS(ctx, key, url, body)
  621. if err != nil {
  622. return nil, err
  623. }
  624. // handle errors 4XX-5XX with responseError
  625. if res.StatusCode >= 400 && res.StatusCode <= 599 {
  626. err := responseError(res)
  627. res.Body.Close()
  628. // according to spec badNonce is urn:ietf:params:acme:error:badNonce
  629. // however, acme servers in the wild return their version of the error
  630. // https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-5.4
  631. if ae, ok := err.(*Error); ok && strings.HasSuffix(strings.ToLower(ae.ProblemType), ":badnonce") {
  632. // clear any nonces that we might've stored that might now be
  633. // considered bad
  634. c.clearNonces()
  635. retry := res.Header.Get("Retry-After")
  636. if err := sleep(retry, 1); err != nil {
  637. return nil, err
  638. }
  639. continue
  640. }
  641. return nil, err
  642. }
  643. return res, nil
  644. }
  645. }
  646. // postJWS signs the body with the given key and POSTs it to the provided url.
  647. // The body argument must be JSON-serializable.
  648. func (c *Client) postJWS(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, error) {
  649. nonce, err := c.popNonce(ctx, url)
  650. if err != nil {
  651. return nil, err
  652. }
  653. b, err := jwsEncodeJSON(body, key, nonce)
  654. if err != nil {
  655. return nil, err
  656. }
  657. res, err := c.post(ctx, url, "application/jose+json", bytes.NewReader(b))
  658. if err != nil {
  659. return nil, err
  660. }
  661. c.addNonce(res.Header)
  662. return res, nil
  663. }
  664. // popNonce returns a nonce value previously stored with c.addNonce
  665. // or fetches a fresh one from the given URL.
  666. func (c *Client) popNonce(ctx context.Context, url string) (string, error) {
  667. c.noncesMu.Lock()
  668. defer c.noncesMu.Unlock()
  669. if len(c.nonces) == 0 {
  670. return c.fetchNonce(ctx, url)
  671. }
  672. var nonce string
  673. for nonce = range c.nonces {
  674. delete(c.nonces, nonce)
  675. break
  676. }
  677. return nonce, nil
  678. }
  679. // clearNonces clears any stored nonces
  680. func (c *Client) clearNonces() {
  681. c.noncesMu.Lock()
  682. defer c.noncesMu.Unlock()
  683. c.nonces = make(map[string]struct{})
  684. }
  685. // addNonce stores a nonce value found in h (if any) for future use.
  686. func (c *Client) addNonce(h http.Header) {
  687. v := nonceFromHeader(h)
  688. if v == "" {
  689. return
  690. }
  691. c.noncesMu.Lock()
  692. defer c.noncesMu.Unlock()
  693. if len(c.nonces) >= maxNonces {
  694. return
  695. }
  696. if c.nonces == nil {
  697. c.nonces = make(map[string]struct{})
  698. }
  699. c.nonces[v] = struct{}{}
  700. }
  701. func (c *Client) httpClient() *http.Client {
  702. if c.HTTPClient != nil {
  703. return c.HTTPClient
  704. }
  705. return http.DefaultClient
  706. }
  707. func (c *Client) get(ctx context.Context, urlStr string) (*http.Response, error) {
  708. req, err := http.NewRequest("GET", urlStr, nil)
  709. if err != nil {
  710. return nil, err
  711. }
  712. return c.do(ctx, req)
  713. }
  714. func (c *Client) head(ctx context.Context, urlStr string) (*http.Response, error) {
  715. req, err := http.NewRequest("HEAD", urlStr, nil)
  716. if err != nil {
  717. return nil, err
  718. }
  719. return c.do(ctx, req)
  720. }
  721. func (c *Client) post(ctx context.Context, urlStr, contentType string, body io.Reader) (*http.Response, error) {
  722. req, err := http.NewRequest("POST", urlStr, body)
  723. if err != nil {
  724. return nil, err
  725. }
  726. req.Header.Set("Content-Type", contentType)
  727. return c.do(ctx, req)
  728. }
  729. func (c *Client) do(ctx context.Context, req *http.Request) (*http.Response, error) {
  730. res, err := c.httpClient().Do(req.WithContext(ctx))
  731. if err != nil {
  732. select {
  733. case <-ctx.Done():
  734. // Prefer the unadorned context error.
  735. // (The acme package had tests assuming this, previously from ctxhttp's
  736. // behavior, predating net/http supporting contexts natively)
  737. // TODO(bradfitz): reconsider this in the future. But for now this
  738. // requires no test updates.
  739. return nil, ctx.Err()
  740. default:
  741. return nil, err
  742. }
  743. }
  744. return res, nil
  745. }
  746. func (c *Client) fetchNonce(ctx context.Context, url string) (string, error) {
  747. resp, err := c.head(ctx, url)
  748. if err != nil {
  749. return "", err
  750. }
  751. defer resp.Body.Close()
  752. nonce := nonceFromHeader(resp.Header)
  753. if nonce == "" {
  754. if resp.StatusCode > 299 {
  755. return "", responseError(resp)
  756. }
  757. return "", errors.New("acme: nonce not found")
  758. }
  759. return nonce, nil
  760. }
  761. func nonceFromHeader(h http.Header) string {
  762. return h.Get("Replay-Nonce")
  763. }
  764. func (c *Client) responseCert(ctx context.Context, res *http.Response, bundle bool) ([][]byte, error) {
  765. b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
  766. if err != nil {
  767. return nil, fmt.Errorf("acme: response stream: %v", err)
  768. }
  769. if len(b) > maxCertSize {
  770. return nil, errors.New("acme: certificate is too big")
  771. }
  772. cert := [][]byte{b}
  773. if !bundle {
  774. return cert, nil
  775. }
  776. // Append CA chain cert(s).
  777. // At least one is required according to the spec:
  778. // https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-6.3.1
  779. up := linkHeader(res.Header, "up")
  780. if len(up) == 0 {
  781. return nil, errors.New("acme: rel=up link not found")
  782. }
  783. if len(up) > maxChainLen {
  784. return nil, errors.New("acme: rel=up link is too large")
  785. }
  786. for _, url := range up {
  787. cc, err := c.chainCert(ctx, url, 0)
  788. if err != nil {
  789. return nil, err
  790. }
  791. cert = append(cert, cc...)
  792. }
  793. return cert, nil
  794. }
  795. // responseError creates an error of Error type from resp.
  796. func responseError(resp *http.Response) error {
  797. // don't care if ReadAll returns an error:
  798. // json.Unmarshal will fail in that case anyway
  799. b, _ := ioutil.ReadAll(resp.Body)
  800. e := &wireError{Status: resp.StatusCode}
  801. if err := json.Unmarshal(b, e); err != nil {
  802. // this is not a regular error response:
  803. // populate detail with anything we received,
  804. // e.Status will already contain HTTP response code value
  805. e.Detail = string(b)
  806. if e.Detail == "" {
  807. e.Detail = resp.Status
  808. }
  809. }
  810. return e.error(resp.Header)
  811. }
  812. // chainCert fetches CA certificate chain recursively by following "up" links.
  813. // Each recursive call increments the depth by 1, resulting in an error
  814. // if the recursion level reaches maxChainLen.
  815. //
  816. // First chainCert call starts with depth of 0.
  817. func (c *Client) chainCert(ctx context.Context, url string, depth int) ([][]byte, error) {
  818. if depth >= maxChainLen {
  819. return nil, errors.New("acme: certificate chain is too deep")
  820. }
  821. res, err := c.get(ctx, url)
  822. if err != nil {
  823. return nil, err
  824. }
  825. defer res.Body.Close()
  826. if res.StatusCode != http.StatusOK {
  827. return nil, responseError(res)
  828. }
  829. b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
  830. if err != nil {
  831. return nil, err
  832. }
  833. if len(b) > maxCertSize {
  834. return nil, errors.New("acme: certificate is too big")
  835. }
  836. chain := [][]byte{b}
  837. uplink := linkHeader(res.Header, "up")
  838. if len(uplink) > maxChainLen {
  839. return nil, errors.New("acme: certificate chain is too large")
  840. }
  841. for _, up := range uplink {
  842. cc, err := c.chainCert(ctx, up, depth+1)
  843. if err != nil {
  844. return nil, err
  845. }
  846. chain = append(chain, cc...)
  847. }
  848. return chain, nil
  849. }
  850. // linkHeader returns URI-Reference values of all Link headers
  851. // with relation-type rel.
  852. // See https://tools.ietf.org/html/rfc5988#section-5 for details.
  853. func linkHeader(h http.Header, rel string) []string {
  854. var links []string
  855. for _, v := range h["Link"] {
  856. parts := strings.Split(v, ";")
  857. for _, p := range parts {
  858. p = strings.TrimSpace(p)
  859. if !strings.HasPrefix(p, "rel=") {
  860. continue
  861. }
  862. if v := strings.Trim(p[4:], `"`); v == rel {
  863. links = append(links, strings.Trim(parts[0], "<>"))
  864. }
  865. }
  866. }
  867. return links
  868. }
  869. // sleeper returns a function that accepts the Retry-After HTTP header value
  870. // and an increment that's used with backoff to increasingly sleep on
  871. // consecutive calls until the context is done. If the Retry-After header
  872. // cannot be parsed, then backoff is used with a maximum sleep time of 10
  873. // seconds.
  874. func sleeper(ctx context.Context) func(ra string, inc int) error {
  875. var count int
  876. return func(ra string, inc int) error {
  877. count += inc
  878. d := backoff(count, 10*time.Second)
  879. d = retryAfter(ra, d)
  880. wakeup := time.NewTimer(d)
  881. defer wakeup.Stop()
  882. select {
  883. case <-ctx.Done():
  884. return ctx.Err()
  885. case <-wakeup.C:
  886. return nil
  887. }
  888. }
  889. }
  890. // retryAfter parses a Retry-After HTTP header value,
  891. // trying to convert v into an int (seconds) or use http.ParseTime otherwise.
  892. // It returns d if v cannot be parsed.
  893. func retryAfter(v string, d time.Duration) time.Duration {
  894. if i, err := strconv.Atoi(v); err == nil {
  895. return time.Duration(i) * time.Second
  896. }
  897. t, err := http.ParseTime(v)
  898. if err != nil {
  899. return d
  900. }
  901. return t.Sub(timeNow())
  902. }
  903. // backoff computes a duration after which an n+1 retry iteration should occur
  904. // using truncated exponential backoff algorithm.
  905. //
  906. // The n argument is always bounded between 0 and 30.
  907. // The max argument defines upper bound for the returned value.
  908. func backoff(n int, max time.Duration) time.Duration {
  909. if n < 0 {
  910. n = 0
  911. }
  912. if n > 30 {
  913. n = 30
  914. }
  915. var d time.Duration
  916. if x, err := rand.Int(rand.Reader, big.NewInt(1000)); err == nil {
  917. d = time.Duration(x.Int64()) * time.Millisecond
  918. }
  919. d += time.Duration(1<<uint(n)) * time.Second
  920. if d > max {
  921. return max
  922. }
  923. return d
  924. }
  925. // keyAuth generates a key authorization string for a given token.
  926. func keyAuth(pub crypto.PublicKey, token string) (string, error) {
  927. th, err := JWKThumbprint(pub)
  928. if err != nil {
  929. return "", err
  930. }
  931. return fmt.Sprintf("%s.%s", token, th), nil
  932. }
  933. // tlsChallengeCert creates a temporary certificate for TLS-SNI challenges
  934. // with the given SANs and auto-generated public/private key pair.
  935. // The Subject Common Name is set to the first SAN to aid debugging.
  936. // To create a cert with a custom key pair, specify WithKey option.
  937. func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
  938. var (
  939. key crypto.Signer
  940. tmpl *x509.Certificate
  941. )
  942. for _, o := range opt {
  943. switch o := o.(type) {
  944. case *certOptKey:
  945. if key != nil {
  946. return tls.Certificate{}, errors.New("acme: duplicate key option")
  947. }
  948. key = o.key
  949. case *certOptTemplate:
  950. var t = *(*x509.Certificate)(o) // shallow copy is ok
  951. tmpl = &t
  952. default:
  953. // package's fault, if we let this happen:
  954. panic(fmt.Sprintf("unsupported option type %T", o))
  955. }
  956. }
  957. if key == nil {
  958. var err error
  959. if key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader); err != nil {
  960. return tls.Certificate{}, err
  961. }
  962. }
  963. if tmpl == nil {
  964. tmpl = &x509.Certificate{
  965. SerialNumber: big.NewInt(1),
  966. NotBefore: time.Now(),
  967. NotAfter: time.Now().Add(24 * time.Hour),
  968. BasicConstraintsValid: true,
  969. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
  970. ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
  971. }
  972. }
  973. tmpl.DNSNames = san
  974. if len(san) > 0 {
  975. tmpl.Subject.CommonName = san[0]
  976. }
  977. der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, key.Public(), key)
  978. if err != nil {
  979. return tls.Certificate{}, err
  980. }
  981. return tls.Certificate{
  982. Certificate: [][]byte{der},
  983. PrivateKey: key,
  984. }, nil
  985. }
  986. // encodePEM returns b encoded as PEM with block of type typ.
  987. func encodePEM(typ string, b []byte) []byte {
  988. pb := &pem.Block{Type: typ, Bytes: b}
  989. return pem.EncodeToMemory(pb)
  990. }
  991. // timeNow is useful for testing for fixed current time.
  992. var timeNow = time.Now