summaryrefslogtreecommitdiffstats
path: root/modules/md/md.h
diff options
context:
space:
mode:
Diffstat (limited to 'modules/md/md.h')
-rw-r--r--modules/md/md.h218
1 files changed, 129 insertions, 89 deletions
diff --git a/modules/md/md.h b/modules/md/md.h
index 60f8852..035ccba 100644
--- a/modules/md/md.h
+++ b/modules/md/md.h
@@ -17,19 +17,22 @@
#ifndef mod_md_md_h
#define mod_md_md_h
+#include <apr_time.h>
+
+#include "md_time.h"
#include "md_version.h"
struct apr_array_header_t;
struct apr_hash_t;
struct md_json_t;
struct md_cert_t;
+struct md_job_t;
struct md_pkey_t;
+struct md_result_t;
struct md_store_t;
struct md_srv_conf_t;
struct md_pkey_spec_t;
-#define MD_TLSSNI01_DNS_SUFFIX ".acme.invalid"
-
#define MD_PKEY_RSA_BITS_MIN 2048
#define MD_PKEY_RSA_BITS_DEF 2048
@@ -37,13 +40,22 @@ struct md_pkey_spec_t;
#define MD_HSTS_HEADER "Strict-Transport-Security"
#define MD_HSTS_MAX_AGE_DEFAULT 15768000
+#define PROTO_ACME_TLS_1 "acme-tls/1"
+
+#define MD_TIME_LIFE_NORM (apr_time_from_sec(100 * MD_SECS_PER_DAY))
+#define MD_TIME_RENEW_WINDOW_DEF (apr_time_from_sec(33 * MD_SECS_PER_DAY))
+#define MD_TIME_WARN_WINDOW_DEF (apr_time_from_sec(10 * MD_SECS_PER_DAY))
+#define MD_TIME_OCSP_KEEP_NORM (apr_time_from_sec(7 * MD_SECS_PER_DAY))
+
+#define MD_OTHER "other"
+
typedef enum {
- MD_S_UNKNOWN, /* MD has not been analysed yet */
- MD_S_INCOMPLETE, /* MD is missing necessary information, cannot go live */
- MD_S_COMPLETE, /* MD has all necessary information, can go live */
- MD_S_EXPIRED, /* MD is complete, but credentials have expired */
- MD_S_ERROR, /* MD data is flawed, unable to be processed as is */
- MD_S_MISSING, /* MD is missing config information, cannot proceed */
+ MD_S_UNKNOWN = 0, /* MD has not been analysed yet */
+ MD_S_INCOMPLETE = 1, /* MD is missing necessary information, cannot go live */
+ MD_S_COMPLETE = 2, /* MD has all necessary information, can go live */
+ MD_S_EXPIRED_DEPRECATED = 3, /* deprecated */
+ MD_S_ERROR = 4, /* MD data is flawed, unable to be processed as is */
+ MD_S_MISSING_INFORMATION = 5, /* User has not agreed to ToS */
} md_state_t;
typedef enum {
@@ -54,30 +66,11 @@ typedef enum {
} md_require_t;
typedef enum {
- MD_SV_TEXT,
- MD_SV_JSON,
- MD_SV_CERT,
- MD_SV_PKEY,
- MD_SV_CHAIN,
-} md_store_vtype_t;
-
-typedef enum {
- MD_SG_NONE,
- MD_SG_ACCOUNTS,
- MD_SG_CHALLENGES,
- MD_SG_DOMAINS,
- MD_SG_STAGING,
- MD_SG_ARCHIVE,
- MD_SG_TMP,
- MD_SG_COUNT,
-} md_store_group_t;
-
-typedef enum {
- MD_DRIVE_DEFAULT = -1, /* default value */
- MD_DRIVE_MANUAL, /* manually triggered transmission of credentials */
- MD_DRIVE_AUTO, /* automatic process performed by httpd */
- MD_DRIVE_ALWAYS, /* always driven by httpd, even if not used in any vhost */
-} md_drive_mode_t;
+ MD_RENEW_DEFAULT = -1, /* default value */
+ MD_RENEW_MANUAL, /* manually triggered renewal of certificate */
+ MD_RENEW_AUTO, /* automatic process performed by httpd */
+ MD_RENEW_ALWAYS, /* always renewed by httpd, even if not necessary */
+} md_renew_mode_t;
typedef struct md_t md_t;
struct md_t {
@@ -85,90 +78,142 @@ struct md_t {
struct apr_array_header_t *domains; /* all DNS names this MD includes */
struct apr_array_header_t *contacts; /* list of contact uris, e.g. mailto:xxx */
- int transitive; /* != 0 iff VirtualHost names/aliases are auto-added */
- md_require_t require_https; /* Iff https: is required for this MD */
-
- int drive_mode; /* mode of obtaining credentials */
- struct md_pkey_spec_t *pkey_spec;/* specification for generating new private keys */
- int must_staple; /* certificates should set the OCSP Must Staple extension */
- apr_interval_time_t renew_norm; /* if > 0, normalized cert lifetime */
- apr_interval_time_t renew_window;/* time before expiration that starts renewal */
+ struct md_pkeys_spec_t *pks; /* specification for generating private keys */
+ md_timeslice_t *renew_window; /* time before expiration that starts renewal */
+ md_timeslice_t *warn_window; /* time before expiration that warnings are sent out */
- const char *ca_url; /* url of CA certificate service */
const char *ca_proto; /* protocol used vs CA (e.g. ACME) */
+ struct apr_array_header_t *ca_urls; /* urls of CAs */
+ const char *ca_effective; /* url of CA used */
const char *ca_account; /* account used at CA */
- const char *ca_agreement; /* accepted agreement uri between CA and user */
+ const char *ca_agreement; /* accepted agreement uri between CA and user */
struct apr_array_header_t *ca_challenges; /* challenge types configured for this MD */
+ struct apr_array_header_t *cert_files; /* != NULL iff pubcerts explicitly configured */
+ struct apr_array_header_t *pkey_files; /* != NULL iff privkeys explicitly configured */
+ const char *ca_eab_kid; /* optional KEYID for external account binding */
+ const char *ca_eab_hmac; /* optional HMAC for external account binding */
- md_state_t state; /* state of this MD */
- apr_time_t valid_from; /* When the credentials start to be valid. 0 if unknown */
- apr_time_t expires; /* When the credentials expire. 0 if unknown */
- const char *cert_url; /* url where cert has been created, remember during drive */
+ const char *state_descr; /* description of state of NULL */
+ struct apr_array_header_t *acme_tls_1_domains; /* domains supporting "acme-tls/1" protocol */
+ const char *dns01_cmd; /* DNS challenge command, override global command */
+
const struct md_srv_conf_t *sc; /* server config where it was defined or NULL */
const char *defn_name; /* config file this MD was defined */
unsigned defn_line_number; /* line number of definition */
+ const char *configured_name; /* name this MD was configured with, if different */
+
+ int renew_mode; /* mode of obtaining credentials */
+ md_require_t require_https; /* Iff https: is required for this MD */
+ md_state_t state; /* state of this MD */
+ int transitive; /* != 0 iff VirtualHost names/aliases are auto-added */
+ int must_staple; /* certificates should set the OCSP Must Staple extension */
+ int stapling; /* if OCSP stapling is enabled */
+ int watched; /* if certificate is supervised (renew or expiration warning) */
};
#define MD_KEY_ACCOUNT "account"
+#define MD_KEY_ACME_TLS_1 "acme-tls/1"
+#define MD_KEY_ACTIVATION_DELAY "activation-delay"
+#define MD_KEY_ACTIVITY "activity"
#define MD_KEY_AGREEMENT "agreement"
+#define MD_KEY_AUTHORIZATIONS "authorizations"
#define MD_KEY_BITS "bits"
#define MD_KEY_CA "ca"
#define MD_KEY_CA_URL "ca-url"
#define MD_KEY_CERT "cert"
+#define MD_KEY_CERT_FILES "cert-files"
+#define MD_KEY_CERTIFICATE "certificate"
+#define MD_KEY_CHALLENGE "challenge"
#define MD_KEY_CHALLENGES "challenges"
+#define MD_KEY_CMD_DNS01 "cmd-dns-01"
+#define MD_KEY_DNS01_VERSION "cmd-dns-01-version"
+#define MD_KEY_COMPLETE "complete"
#define MD_KEY_CONTACT "contact"
#define MD_KEY_CONTACTS "contacts"
#define MD_KEY_CSR "csr"
+#define MD_KEY_CURVE "curve"
#define MD_KEY_DETAIL "detail"
#define MD_KEY_DISABLED "disabled"
#define MD_KEY_DIR "dir"
#define MD_KEY_DOMAIN "domain"
#define MD_KEY_DOMAINS "domains"
-#define MD_KEY_DRIVE_MODE "drive-mode"
+#define MD_KEY_EAB "eab"
+#define MD_KEY_EAB_REQUIRED "externalAccountRequired"
+#define MD_KEY_ENTRIES "entries"
+#define MD_KEY_ERRORED "errored"
+#define MD_KEY_ERROR "error"
#define MD_KEY_ERRORS "errors"
#define MD_KEY_EXPIRES "expires"
+#define MD_KEY_FINALIZE "finalize"
+#define MD_KEY_FINISHED "finished"
+#define MD_KEY_FROM "from"
+#define MD_KEY_GOOD "good"
+#define MD_KEY_HMAC "hmac"
#define MD_KEY_HTTP "http"
#define MD_KEY_HTTPS "https"
#define MD_KEY_ID "id"
#define MD_KEY_IDENTIFIER "identifier"
#define MD_KEY_KEY "key"
+#define MD_KEY_KID "kid"
#define MD_KEY_KEYAUTHZ "keyAuthorization"
+#define MD_KEY_LAST "last"
+#define MD_KEY_LAST_RUN "last-run"
#define MD_KEY_LOCATION "location"
+#define MD_KEY_LOG "log"
+#define MD_KEY_MDS "managed-domains"
+#define MD_KEY_MESSAGE "message"
#define MD_KEY_MUST_STAPLE "must-staple"
#define MD_KEY_NAME "name"
+#define MD_KEY_NEXT_RUN "next-run"
+#define MD_KEY_NOTIFIED "notified"
+#define MD_KEY_NOTIFIED_RENEWED "notified-renewed"
+#define MD_KEY_OCSP "ocsp"
+#define MD_KEY_OCSPS "ocsps"
+#define MD_KEY_ORDERS "orders"
#define MD_KEY_PERMANENT "permanent"
#define MD_KEY_PKEY "privkey"
-#define MD_KEY_PROCESSED "processed"
+#define MD_KEY_PKEY_FILES "pkey-files"
+#define MD_KEY_PROBLEM "problem"
#define MD_KEY_PROTO "proto"
+#define MD_KEY_READY "ready"
#define MD_KEY_REGISTRATION "registration"
#define MD_KEY_RENEW "renew"
+#define MD_KEY_RENEW_AT "renew-at"
+#define MD_KEY_RENEW_MODE "renew-mode"
+#define MD_KEY_RENEWAL "renewal"
+#define MD_KEY_RENEWING "renewing"
#define MD_KEY_RENEW_WINDOW "renew-window"
#define MD_KEY_REQUIRE_HTTPS "require-https"
#define MD_KEY_RESOURCE "resource"
+#define MD_KEY_RESPONSE "response"
+#define MD_KEY_REVOKED "revoked"
+#define MD_KEY_SERIAL "serial"
+#define MD_KEY_SHA256_FINGERPRINT "sha256-fingerprint"
+#define MD_KEY_STAPLING "stapling"
#define MD_KEY_STATE "state"
+#define MD_KEY_STATE_DESCR "state-descr"
#define MD_KEY_STATUS "status"
#define MD_KEY_STORE "store"
+#define MD_KEY_SUBPROBLEMS "subproblems"
#define MD_KEY_TEMPORARY "temporary"
+#define MD_KEY_TOS "termsOfService"
#define MD_KEY_TOKEN "token"
+#define MD_KEY_TOTAL "total"
#define MD_KEY_TRANSITIVE "transitive"
#define MD_KEY_TYPE "type"
+#define MD_KEY_UNKNOWN "unknown"
+#define MD_KEY_UNTIL "until"
#define MD_KEY_URL "url"
+#define MD_KEY_URLS "urls"
#define MD_KEY_URI "uri"
-#define MD_KEY_VALID_FROM "validFrom"
+#define MD_KEY_VALID "valid"
+#define MD_KEY_VALID_FROM "valid-from"
#define MD_KEY_VALUE "value"
#define MD_KEY_VERSION "version"
-
-#define MD_FN_MD "md.json"
-#define MD_FN_JOB "job.json"
-#define MD_FN_PRIVKEY "privkey.pem"
-#define MD_FN_PUBCERT "pubcert.pem"
-#define MD_FN_CERT "cert.pem"
-#define MD_FN_CHAIN "chain.pem"
-#define MD_FN_HTTPD_JSON "httpd.json"
-
-#define MD_FN_FALLBACK_PKEY "fallback-privkey.pem"
-#define MD_FN_FALLBACK_CERT "fallback-cert.pem"
+#define MD_KEY_WATCHED "watched"
+#define MD_KEY_WHEN "when"
+#define MD_KEY_WARN_WINDOW "warn-window"
/* Check if a string member of a new MD (n) has
* a value and if it differs from the old MD o
@@ -223,12 +268,6 @@ md_t *md_get_by_domain(struct apr_array_header_t *mds, const char *domain);
md_t *md_get_by_dns_overlap(struct apr_array_header_t *mds, const md_t *md);
/**
- * Find the managed domain in the list that, for the given md,
- * has the same name, or the most number of overlaps in domains
- */
-md_t *md_find_closest_match(apr_array_header_t *mds, const md_t *md);
-
-/**
* Create and empty md record, structures initialized.
*/
md_t *md_create_empty(apr_pool_t *p);
@@ -248,43 +287,44 @@ md_t *md_clone(apr_pool_t *p, const md_t *src);
*/
md_t *md_copy(apr_pool_t *p, const md_t *src);
-/**
- * Create a merged md with the settings of add overlaying the ones from base.
- */
-md_t *md_merge(apr_pool_t *p, const md_t *add, const md_t *base);
-
/**
* Convert the managed domain into a JSON representation and vice versa.
*
* This reads and writes the following information: name, domains, ca_url, ca_proto and state.
*/
-struct md_json_t *md_to_json (const md_t *md, apr_pool_t *p);
+struct md_json_t *md_to_json(const md_t *md, apr_pool_t *p);
md_t *md_from_json(struct md_json_t *json, apr_pool_t *p);
/**
- * Determine if MD should renew its cert (if it has one)
+ * Same as md_to_json(), but with sensitive fields stripped.
*/
-int md_should_renew(const md_t *md);
+struct md_json_t *md_to_public_json(const md_t *md, apr_pool_t *p);
+
+int md_is_covered_by_alt_names(const md_t *md, const struct apr_array_header_t* alt_names);
+
+/* how many certificates this domain has/will eventually have. */
+int md_cert_count(const md_t *md);
+
+const char *md_get_ca_name_from_url(apr_pool_t *p, const char *url);
+apr_status_t md_get_ca_url_from_name(const char **purl, apr_pool_t *p, const char *name);
+
+/**************************************************************************************************/
+/* notifications */
+
+typedef apr_status_t md_job_notify_cb(struct md_job_t *job, const char *reason,
+ struct md_result_t *result, apr_pool_t *p, void *baton);
/**************************************************************************************************/
/* domain credentials */
-typedef struct md_creds_t md_creds_t;
-struct md_creds_t {
- struct md_pkey_t *privkey;
- struct apr_array_header_t *pubcert; /* complete md_cert* chain */
- struct md_cert_t *cert;
- int expired;
+typedef struct md_pubcert_t md_pubcert_t;
+struct md_pubcert_t {
+ struct apr_array_header_t *certs; /* chain of const md_cert*, leaf cert first */
+ struct apr_array_header_t *alt_names; /* alt-names of leaf cert */
+ const char *cert_file; /* file path of chain */
+ const char *key_file; /* file path of key for leaf cert */
};
-/* TODO: not sure this is a good idea, testing some readability and debuggabiltiy of
- * cascaded apr_status_t checks. */
-#define MD_CHK_VARS const char *md_chk_
-#define MD_LAST_CHK md_chk_
-#define MD_CHK_STEP(c, status, s) (md_chk_ = s, (void)md_chk_, status == (rv = (c)))
-#define MD_CHK(c, status) MD_CHK_STEP(c, status, #c)
-#define MD_IS_ERR(c, err) (md_chk_ = #c, APR_STATUS_IS_##err((rv = (c))))
-#define MD_CHK_SUCCESS(c) MD_CHK(c, APR_SUCCESS)
-#define MD_OK(c) MD_CHK_SUCCESS(c)
+#define MD_OK(c) (APR_SUCCESS == (rv = c))
#endif /* mod_md_md_h */