types.go 17 KB

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