本站源代码
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.

123 lines
3.4KB

  1. // Copyright 2019 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
  5. import (
  6. "context"
  7. "encoding/json"
  8. "fmt"
  9. "net/http"
  10. )
  11. // DeactivateReg permanently disables an existing account associated with c.Key.
  12. // A deactivated account can no longer request certificate issuance or access
  13. // resources related to the account, such as orders or authorizations.
  14. //
  15. // It works only with RFC8555 compliant CAs.
  16. func (c *Client) DeactivateReg(ctx context.Context) error {
  17. url := string(c.accountKID(ctx))
  18. if url == "" {
  19. return ErrNoAccount
  20. }
  21. req := json.RawMessage(`{"status": "deactivated"}`)
  22. res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))
  23. if err != nil {
  24. return err
  25. }
  26. res.Body.Close()
  27. return nil
  28. }
  29. // registerRFC is quivalent to c.Register but for RFC-compliant CAs.
  30. // It expects c.Discover to have already been called.
  31. // TODO: Implement externalAccountBinding.
  32. func (c *Client) registerRFC(ctx context.Context, acct *Account, prompt func(tosURL string) bool) (*Account, error) {
  33. c.cacheMu.Lock() // guard c.kid access
  34. defer c.cacheMu.Unlock()
  35. req := struct {
  36. TermsAgreed bool `json:"termsOfServiceAgreed,omitempty"`
  37. Contact []string `json:"contact,omitempty"`
  38. }{
  39. Contact: acct.Contact,
  40. }
  41. if c.dir.Terms != "" {
  42. req.TermsAgreed = prompt(c.dir.Terms)
  43. }
  44. res, err := c.post(ctx, c.Key, c.dir.RegURL, req, wantStatus(
  45. http.StatusOK, // account with this key already registered
  46. http.StatusCreated, // new account created
  47. ))
  48. if err != nil {
  49. return nil, err
  50. }
  51. defer res.Body.Close()
  52. a, err := responseAccount(res)
  53. if err != nil {
  54. return nil, err
  55. }
  56. // Cache Account URL even if we return an error to the caller.
  57. // It is by all means a valid and usable "kid" value for future requests.
  58. c.kid = keyID(a.URI)
  59. if res.StatusCode == http.StatusOK {
  60. return nil, ErrAccountAlreadyExists
  61. }
  62. return a, nil
  63. }
  64. // updateGegRFC is equivalent to c.UpdateReg but for RFC-compliant CAs.
  65. // It expects c.Discover to have already been called.
  66. func (c *Client) updateRegRFC(ctx context.Context, a *Account) (*Account, error) {
  67. url := string(c.accountKID(ctx))
  68. if url == "" {
  69. return nil, ErrNoAccount
  70. }
  71. req := struct {
  72. Contact []string `json:"contact,omitempty"`
  73. }{
  74. Contact: a.Contact,
  75. }
  76. res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))
  77. if err != nil {
  78. return nil, err
  79. }
  80. defer res.Body.Close()
  81. return responseAccount(res)
  82. }
  83. // getGegRFC is equivalent to c.GetReg but for RFC-compliant CAs.
  84. // It expects c.Discover to have already been called.
  85. func (c *Client) getRegRFC(ctx context.Context) (*Account, error) {
  86. req := json.RawMessage(`{"onlyReturnExisting": true}`)
  87. res, err := c.post(ctx, c.Key, c.dir.RegURL, req, wantStatus(http.StatusOK))
  88. if e, ok := err.(*Error); ok && e.ProblemType == "urn:ietf:params:acme:error:accountDoesNotExist" {
  89. return nil, ErrNoAccount
  90. }
  91. if err != nil {
  92. return nil, err
  93. }
  94. defer res.Body.Close()
  95. return responseAccount(res)
  96. }
  97. func responseAccount(res *http.Response) (*Account, error) {
  98. var v struct {
  99. Status string
  100. Contact []string
  101. Orders string
  102. }
  103. if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
  104. return nil, fmt.Errorf("acme: invalid response: %v", err)
  105. }
  106. return &Account{
  107. URI: res.Header.Get("Location"),
  108. Status: v.Status,
  109. Contact: v.Contact,
  110. OrdersURL: v.Orders,
  111. }, nil
  112. }
上海开阖软件有限公司 沪ICP备12045867号-1