Skip to main content

acme/api/
directory.rs

1use serde::{Deserialize, Serialize};
2
3/// Directory object for ACME client self-configuration.
4///
5/// See [RFC 8555 §7.1.1].
6///
7/// # Example JSON
8///
9/// ```json
10/// {
11///   "newNonce": "https://example.com/acme/new-nonce",
12///   "newAccount": "https://example.com/acme/new-account",
13///   "newOrder": "https://example.com/acme/new-order",
14///   "newAuthz": "https://example.com/acme/new-authz",
15///   "revokeCert": "https://example.com/acme/revoke-cert",
16///   "keyChange": "https://example.com/acme/key-change",
17///   "meta": {
18///     "termsOfService": "https://example.com/acme/terms/2017-5-30",
19///     "website": "https://www.example.com/",
20///     "caaIdentities": ["example.com"],
21///     "externalAccountRequired": false
22///   }
23/// }
24/// ```
25///
26/// [RFC 8555 §7.1.1]: https://datatracker.ietf.org/doc/html/rfc8555#section-7.1.1
27#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
28#[serde(rename_all = "camelCase")]
29pub struct Directory {
30    /// URL for new nonce requests.
31    pub new_nonce: String,
32
33    /// URL for new account requests.
34    pub new_account: String,
35
36    /// URL for new order requests.
37    pub new_order: String,
38
39    /// URL for new authorization requests.
40    ///
41    /// If the ACME server does not implement [pre-authorization], it MUST omit the `newAuthz` field
42    /// of the directory.
43    ///
44    /// [pre-authorization]: https://datatracker.ietf.org/doc/html/rfc8555#section-7.4.1
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub new_authz: Option<String>,
47
48    /// URL for certificate revocation requests.
49    pub revoke_cert: String,
50
51    /// URL for key change requests.
52    pub key_change: String,
53
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub meta: Option<DirectoryMeta>,
56}
57
58/// <https://datatracker.ietf.org/doc/html/rfc8555#section-9.7.6>
59#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
60#[serde(rename_all = "camelCase")]
61pub struct DirectoryMeta {
62    /// URL identifying the current terms of service.
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub terms_of_service: Option<String>,
65
66    /// URL locating a website providing more information about the ACME server.
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub website: Option<String>,
69
70    /// The hostnames that the ACME server recognizes as referring to itself for the purposes of
71    /// Certification Authority Authorization (CAA) record validation as defined in [RFC 6844].
72    ///
73    /// [RFC 6844]: https://datatracker.ietf.org/doc/html/rfc6844
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub caa_identities: Option<Vec<String>>,
76
77    /// If true, then the CA requires that all newAccount requests include an
78    /// `externalAccountBinding` field associating the new account with an external account.
79    #[serde(skip_serializing_if = "Option::is_none")]
80    pub external_account_required: Option<bool>,
81}
82
83impl DirectoryMeta {
84    pub fn external_account_required(&self) -> bool {
85        self.external_account_required.unwrap_or(false)
86    }
87}