types.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  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 acme
  5. import (
  6. "crypto"
  7. "crypto/x509"
  8. "errors"
  9. "fmt"
  10. "net/http"
  11. "strings"
  12. "time"
  13. )
  14. // ACME status values of Account, Order, Authorization and Challenge objects.
  15. // See https://tools.ietf.org/html/rfc8555#section-7.1.6 for details.
  16. const (
  17. StatusDeactivated = "deactivated"
  18. StatusInvalid = "invalid"
  19. StatusReady = "ready"
  20. StatusPending = "pending"
  21. StatusProcessing = "processing"
  22. StatusRevoked = "revoked"
  23. StatusUnknown = "unknown"
  24. StatusValid = "valid"
  25. )
  26. // CRLReasonCode identifies the reason for a certificate revocation.
  27. type CRLReasonCode int
  28. // CRL reason codes as defined in RFC 5280.
  29. const (
  30. CRLReasonUnspecified CRLReasonCode = 0
  31. CRLReasonKeyCompromise CRLReasonCode = 1
  32. CRLReasonCACompromise CRLReasonCode = 2
  33. CRLReasonAffiliationChanged CRLReasonCode = 3
  34. CRLReasonSuperseded CRLReasonCode = 4
  35. CRLReasonCessationOfOperation CRLReasonCode = 5
  36. CRLReasonCertificateHold CRLReasonCode = 6
  37. CRLReasonRemoveFromCRL CRLReasonCode = 8
  38. CRLReasonPrivilegeWithdrawn CRLReasonCode = 9
  39. CRLReasonAACompromise CRLReasonCode = 10
  40. )
  41. var (
  42. // ErrUnsupportedKey is returned when an unsupported key type is encountered.
  43. ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")
  44. // ErrAccountAlreadyExists indicates that the Client's key has already been registered
  45. // with the CA. It is returned by Register method.
  46. ErrAccountAlreadyExists = errors.New("acme: account already exists")
  47. // ErrNoAccount indicates that the Client's key has not been registered with the CA.
  48. ErrNoAccount = errors.New("acme: account does not exist")
  49. )
  50. // Error is an ACME error, defined in Problem Details for HTTP APIs doc
  51. // http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.
  52. type Error struct {
  53. // StatusCode is The HTTP status code generated by the origin server.
  54. StatusCode int
  55. // ProblemType is a URI reference that identifies the problem type,
  56. // typically in a "urn:acme:error:xxx" form.
  57. ProblemType string
  58. // Detail is a human-readable explanation specific to this occurrence of the problem.
  59. Detail string
  60. // Instance indicates a URL that the client should direct a human user to visit
  61. // in order for instructions on how to agree to the updated Terms of Service.
  62. // In such an event CA sets StatusCode to 403, ProblemType to
  63. // "urn:ietf:params:acme:error:userActionRequired" and a Link header with relation
  64. // "terms-of-service" containing the latest TOS URL.
  65. Instance string
  66. // Header is the original server error response headers.
  67. // It may be nil.
  68. Header http.Header
  69. }
  70. func (e *Error) Error() string {
  71. return fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail)
  72. }
  73. // AuthorizationError indicates that an authorization for an identifier
  74. // did not succeed.
  75. // It contains all errors from Challenge items of the failed Authorization.
  76. type AuthorizationError struct {
  77. // URI uniquely identifies the failed Authorization.
  78. URI string
  79. // Identifier is an AuthzID.Value of the failed Authorization.
  80. Identifier string
  81. // Errors is a collection of non-nil error values of Challenge items
  82. // of the failed Authorization.
  83. Errors []error
  84. }
  85. func (a *AuthorizationError) Error() string {
  86. e := make([]string, len(a.Errors))
  87. for i, err := range a.Errors {
  88. e[i] = err.Error()
  89. }
  90. return fmt.Sprintf("acme: authorization error for %s: %s", a.Identifier, strings.Join(e, "; "))
  91. }
  92. // WaitOrderError is returned from Client's WaitOrder.
  93. // It indicates the order is unusable and the clients should start over with
  94. // AuthorizeOrder.
  95. type WaitOrderError struct {
  96. OrderURL string
  97. Status string
  98. }
  99. func (we *WaitOrderError) Error() string {
  100. return fmt.Sprintf("acme: wait order %s: status %s", we.OrderURL, we.Status)
  101. }
  102. // RateLimit reports whether err represents a rate limit error and
  103. // any Retry-After duration returned by the server.
  104. //
  105. // See the following for more details on rate limiting:
  106. // https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-5.6
  107. func RateLimit(err error) (time.Duration, bool) {
  108. e, ok := err.(*Error)
  109. if !ok {
  110. return 0, false
  111. }
  112. // Some CA implementations may return incorrect values.
  113. // Use case-insensitive comparison.
  114. if !strings.HasSuffix(strings.ToLower(e.ProblemType), ":ratelimited") {
  115. return 0, false
  116. }
  117. if e.Header == nil {
  118. return 0, true
  119. }
  120. return retryAfter(e.Header.Get("Retry-After")), true
  121. }
  122. // Account is a user account. It is associated with a private key.
  123. // Non-RFC8555 fields are empty when interfacing with a compliant CA.
  124. type Account struct {
  125. // URI is the account unique ID, which is also a URL used to retrieve
  126. // account data from the CA.
  127. // When interfacing with RFC8555-compliant CAs, URI is the "kid" field
  128. // value in JWS signed requests.
  129. URI string
  130. // Contact is a slice of contact info used during registration.
  131. // See https://tools.ietf.org/html/rfc8555#section-7.3 for supported
  132. // formats.
  133. Contact []string
  134. // Status indicates current account status as returned by the CA.
  135. // Possible values are StatusValid, StatusDeactivated, and StatusRevoked.
  136. Status string
  137. // OrdersURL is a URL from which a list of orders submitted by this account
  138. // can be fetched.
  139. OrdersURL string
  140. // The terms user has agreed to.
  141. // A value not matching CurrentTerms indicates that the user hasn't agreed
  142. // to the actual Terms of Service of the CA.
  143. //
  144. // It is non-RFC8555 compliant. Package users can store the ToS they agree to
  145. // during Client's Register call in the prompt callback function.
  146. AgreedTerms string
  147. // Actual terms of a CA.
  148. //
  149. // It is non-RFC8555 compliant. Use Directory's Terms field.
  150. // When a CA updates their terms and requires an account agreement,
  151. // a URL at which instructions to do so is available in Error's Instance field.
  152. CurrentTerms string
  153. // Authz is the authorization URL used to initiate a new authz flow.
  154. //
  155. // It is non-RFC8555 compliant. Use Directory's AuthzURL or OrderURL.
  156. Authz string
  157. // Authorizations is a URI from which a list of authorizations
  158. // granted to this account can be fetched via a GET request.
  159. //
  160. // It is non-RFC8555 compliant and is obsoleted by OrdersURL.
  161. Authorizations string
  162. // Certificates is a URI from which a list of certificates
  163. // issued for this account can be fetched via a GET request.
  164. //
  165. // It is non-RFC8555 compliant and is obsoleted by OrdersURL.
  166. Certificates string
  167. }
  168. // Directory is ACME server discovery data.
  169. // See https://tools.ietf.org/html/rfc8555#section-7.1.1 for more details.
  170. type Directory struct {
  171. // NonceURL indicates an endpoint where to fetch fresh nonce values from.
  172. NonceURL string
  173. // RegURL is an account endpoint URL, allowing for creating new accounts.
  174. // Pre-RFC8555 CAs also allow modifying existing accounts at this URL.
  175. RegURL string
  176. // OrderURL is used to initiate the certificate issuance flow
  177. // as described in RFC8555.
  178. OrderURL string
  179. // AuthzURL is used to initiate identifier pre-authorization flow.
  180. // Empty string indicates the flow is unsupported by the CA.
  181. AuthzURL string
  182. // CertURL is a new certificate issuance endpoint URL.
  183. // It is non-RFC8555 compliant and is obsoleted by OrderURL.
  184. CertURL string
  185. // RevokeURL is used to initiate a certificate revocation flow.
  186. RevokeURL string
  187. // KeyChangeURL allows to perform account key rollover flow.
  188. KeyChangeURL string
  189. // Term is a URI identifying the current terms of service.
  190. Terms string
  191. // Website is an HTTP or HTTPS URL locating a website
  192. // providing more information about the ACME server.
  193. Website string
  194. // CAA consists of lowercase hostname elements, which the ACME server
  195. // recognises as referring to itself for the purposes of CAA record validation
  196. // as defined in RFC6844.
  197. CAA []string
  198. // ExternalAccountRequired indicates that the CA requires for all account-related
  199. // requests to include external account binding information.
  200. ExternalAccountRequired bool
  201. }
  202. // Order represents a client's request for a certificate.
  203. // It tracks the request flow progress through to issuance.
  204. type Order struct {
  205. // URI uniquely identifies an order.
  206. URI string
  207. // Status represents the current status of the order.
  208. // It indicates which action the client should take.
  209. //
  210. // Possible values are StatusPending, StatusReady, StatusProcessing, StatusValid and StatusInvalid.
  211. // Pending means the CA does not believe that the client has fulfilled the requirements.
  212. // Ready indicates that the client has fulfilled all the requirements and can submit a CSR
  213. // to obtain a certificate. This is done with Client's CreateOrderCert.
  214. // Processing means the certificate is being issued.
  215. // Valid indicates the CA has issued the certificate. It can be downloaded
  216. // from the Order's CertURL. This is done with Client's FetchCert.
  217. // Invalid means the certificate will not be issued. Users should consider this order
  218. // abandoned.
  219. Status string
  220. // Expires is the timestamp after which CA considers this order invalid.
  221. Expires time.Time
  222. // Identifiers contains all identifier objects which the order pertains to.
  223. Identifiers []AuthzID
  224. // NotBefore is the requested value of the notBefore field in the certificate.
  225. NotBefore time.Time
  226. // NotAfter is the requested value of the notAfter field in the certificate.
  227. NotAfter time.Time
  228. // AuthzURLs represents authorizations to complete before a certificate
  229. // for identifiers specified in the order can be issued.
  230. // It also contains unexpired authorizations that the client has completed
  231. // in the past.
  232. //
  233. // Authorization objects can be fetched using Client's GetAuthorization method.
  234. //
  235. // The required authorizations are dictated by CA policies.
  236. // There may not be a 1:1 relationship between the identifiers and required authorizations.
  237. // Required authorizations can be identified by their StatusPending status.
  238. //
  239. // For orders in the StatusValid or StatusInvalid state these are the authorizations
  240. // which were completed.
  241. AuthzURLs []string
  242. // FinalizeURL is the endpoint at which a CSR is submitted to obtain a certificate
  243. // once all the authorizations are satisfied.
  244. FinalizeURL string
  245. // CertURL points to the certificate that has been issued in response to this order.
  246. CertURL string
  247. // The error that occurred while processing the order as received from a CA, if any.
  248. Error *Error
  249. }
  250. // OrderOption allows customizing Client.AuthorizeOrder call.
  251. type OrderOption interface {
  252. privateOrderOpt()
  253. }
  254. // WithOrderNotBefore sets order's NotBefore field.
  255. func WithOrderNotBefore(t time.Time) OrderOption {
  256. return orderNotBeforeOpt(t)
  257. }
  258. // WithOrderNotAfter sets order's NotAfter field.
  259. func WithOrderNotAfter(t time.Time) OrderOption {
  260. return orderNotAfterOpt(t)
  261. }
  262. type orderNotBeforeOpt time.Time
  263. func (orderNotBeforeOpt) privateOrderOpt() {}
  264. type orderNotAfterOpt time.Time
  265. func (orderNotAfterOpt) privateOrderOpt() {}
  266. // Authorization encodes an authorization response.
  267. type Authorization struct {
  268. // URI uniquely identifies a authorization.
  269. URI string
  270. // Status identifies the status of an authorization.
  271. Status string
  272. // Identifier is what the account is authorized to represent.
  273. Identifier AuthzID
  274. // Challenges that the client needs to fulfill in order to prove possession
  275. // of the identifier (for pending authorizations).
  276. // For final authorizations, the challenges that were used.
  277. Challenges []*Challenge
  278. // A collection of sets of challenges, each of which would be sufficient
  279. // to prove possession of the identifier.
  280. // Clients must complete a set of challenges that covers at least one set.
  281. // Challenges are identified by their indices in the challenges array.
  282. // If this field is empty, the client needs to complete all challenges.
  283. Combinations [][]int
  284. }
  285. // AuthzID is an identifier that an account is authorized to represent.
  286. type AuthzID struct {
  287. Type string // The type of identifier, "dns" or "ip".
  288. Value string // The identifier itself, e.g. "example.org".
  289. }
  290. // DomainIDs creates a slice of AuthzID with "dns" identifier type.
  291. func DomainIDs(names ...string) []AuthzID {
  292. a := make([]AuthzID, len(names))
  293. for i, v := range names {
  294. a[i] = AuthzID{Type: "dns", Value: v}
  295. }
  296. return a
  297. }
  298. // IPIDs creates a slice of AuthzID with "ip" identifier type.
  299. // Each element of addr is textual form of an address as defined
  300. // in RFC1123 Section 2.1 for IPv4 and in RFC5952 Section 4 for IPv6.
  301. func IPIDs(addr ...string) []AuthzID {
  302. a := make([]AuthzID, len(addr))
  303. for i, v := range addr {
  304. a[i] = AuthzID{Type: "ip", Value: v}
  305. }
  306. return a
  307. }
  308. // wireAuthzID is ACME JSON representation of authorization identifier objects.
  309. type wireAuthzID struct {
  310. Type string `json:"type"`
  311. Value string `json:"value"`
  312. }
  313. // wireAuthz is ACME JSON representation of Authorization objects.
  314. type wireAuthz struct {
  315. Status string
  316. Challenges []wireChallenge
  317. Combinations [][]int
  318. Identifier wireAuthzID
  319. }
  320. func (z *wireAuthz) authorization(uri string) *Authorization {
  321. a := &Authorization{
  322. URI: uri,
  323. Status: z.Status,
  324. Identifier: AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value},
  325. Combinations: z.Combinations, // shallow copy
  326. Challenges: make([]*Challenge, len(z.Challenges)),
  327. }
  328. for i, v := range z.Challenges {
  329. a.Challenges[i] = v.challenge()
  330. }
  331. return a
  332. }
  333. func (z *wireAuthz) error(uri string) *AuthorizationError {
  334. err := &AuthorizationError{
  335. URI: uri,
  336. Identifier: z.Identifier.Value,
  337. }
  338. for _, raw := range z.Challenges {
  339. if raw.Error != nil {
  340. err.Errors = append(err.Errors, raw.Error.error(nil))
  341. }
  342. }
  343. return err
  344. }
  345. // Challenge encodes a returned CA challenge.
  346. // Its Error field may be non-nil if the challenge is part of an Authorization
  347. // with StatusInvalid.
  348. type Challenge struct {
  349. // Type is the challenge type, e.g. "http-01", "tls-sni-02", "dns-01".
  350. Type string
  351. // URI is where a challenge response can be posted to.
  352. URI string
  353. // Token is a random value that uniquely identifies the challenge.
  354. Token string
  355. // Status identifies the status of this challenge.
  356. Status string
  357. // Error indicates the reason for an authorization failure
  358. // when this challenge was used.
  359. // The type of a non-nil value is *Error.
  360. Error error
  361. }
  362. // wireChallenge is ACME JSON challenge representation.
  363. type wireChallenge struct {
  364. URI string `json:"uri"`
  365. Type string
  366. Token string
  367. Status string
  368. Error *wireError
  369. }
  370. func (c *wireChallenge) challenge() *Challenge {
  371. v := &Challenge{
  372. URI: c.URI,
  373. Type: c.Type,
  374. Token: c.Token,
  375. Status: c.Status,
  376. }
  377. if v.Status == "" {
  378. v.Status = StatusPending
  379. }
  380. if c.Error != nil {
  381. v.Error = c.Error.error(nil)
  382. }
  383. return v
  384. }
  385. // wireError is a subset of fields of the Problem Details object
  386. // as described in https://tools.ietf.org/html/rfc7807#section-3.1.
  387. type wireError struct {
  388. Status int
  389. Type string
  390. Detail string
  391. Instance string
  392. }
  393. func (e *wireError) error(h http.Header) *Error {
  394. return &Error{
  395. StatusCode: e.Status,
  396. ProblemType: e.Type,
  397. Detail: e.Detail,
  398. Instance: e.Instance,
  399. Header: h,
  400. }
  401. }
  402. // CertOption is an optional argument type for the TLS ChallengeCert methods for
  403. // customizing a temporary certificate for TLS-based challenges.
  404. type CertOption interface {
  405. privateCertOpt()
  406. }
  407. // WithKey creates an option holding a private/public key pair.
  408. // The private part signs a certificate, and the public part represents the signee.
  409. func WithKey(key crypto.Signer) CertOption {
  410. return &certOptKey{key}
  411. }
  412. type certOptKey struct {
  413. key crypto.Signer
  414. }
  415. func (*certOptKey) privateCertOpt() {}
  416. // WithTemplate creates an option for specifying a certificate template.
  417. // See x509.CreateCertificate for template usage details.
  418. //
  419. // In TLS ChallengeCert methods, the template is also used as parent,
  420. // resulting in a self-signed certificate.
  421. // The DNSNames field of t is always overwritten for tls-sni challenge certs.
  422. func WithTemplate(t *x509.Certificate) CertOption {
  423. return (*certOptTemplate)(t)
  424. }
  425. type certOptTemplate x509.Certificate
  426. func (*certOptTemplate) privateCertOpt() {}