26#include <unordered_set>
77 std::shared_ptr<ccf::crypto::KeyPair> service_key_,
78 bool override_time =
false)
80 using namespace std::chrono_literals;
81 using namespace std::chrono;
84 system_clock::duration delta(0);
105 ok = delta >= 100min;
123 "ACME: Ignoring certificate request due to {} recent failed "
124 "attempt(s) within {} seconds",
126 duration_cast<seconds>(delta).count());
134 auto cit = order.challenges.find(token);
135 if (cit != order.challenges.end())
139 cit->second.challenge_url,
140 [
this, order_url = order.order_url, &challenge = cit->second](
142 threading::ThreadMessaging::instance().add_task_after(
143 schedule_check_challenge(order_url, challenge),
144 std::chrono::milliseconds(0));
152 std::shared_ptr<ccf::crypto::KeyPair> new_account_key_pair)
155 new_account_key_pair :
158 "ACME: new account public key: {}",
169 const std::string& token,
const std::string& response) = 0;
180 llhttp_method method,
182 const std::vector<uint8_t>& body,
187 std::unique_lock<ccf::pal::Mutex> guard(
req_lock);
191 auto port = url.
port.empty() ?
"443" : url.
port;
193 "ACME: Requesting https://{}:{}{}", url.
host, port, url.
path);
196 r.
set_header(ccf::http::headers::ACCEPT,
"*/*");
198 ccf::http::headers::HOST, fmt::format(
"{}:{}", url.
host, url.
port));
202 ccf::http::headers::CONTENT_TYPE,
"application/jose+json");
206 std::string reqs(req.begin(), req.end());
212 [
this, expected_status, ok_callback](
215 std::vector<uint8_t>&& data) {
216 for (
auto& [k, v] : headers)
221 if (status != expected_status && status != HTTP_STATUS_OK)
224 "ACME: request failed with status={} and body={}",
226 std::string(data.begin(), data.end()));
232 "ACME: data: {}", std::string(data.begin(), data.end()));
238 nonces.push_back(*nonce_opt);
243 ok_callback(headers, data);
245 catch (
const std::exception& ex)
247 LOG_FAIL_FMT(
"ACME: response callback failed: {}", ex.what());
253 catch (
const std::exception& ex)
255 LOG_FAIL_FMT(
"ACME: failed to connect to ACME server: {}", ex.what());
260 llhttp_method method,
262 const std::vector<uint8_t>& body,
275 const std::vector<uint8_t>& data) {
282 jr = nlohmann::json::parse(data);
283 LOG_TRACE_FMT(
"ACME: json response: {}", jr.dump());
285 catch (
const std::exception& ex)
287 LOG_FAIL_FMT(
"ACME: response parser failed: {}", ex.what());
292 ok_callback(headers, jr);
298 const std::string& account_url,
299 const std::string& resource_url,
306 [=]() { post_as_get(account_url, resource_url, ok_callback); });
310 auto nonce = nonces.front();
312 auto header = mk_kid_header(account_url, nonce, resource_url);
313 JWS jws(header, *account_key_pair);
314 http::URL url = with_default_port(resource_url);
316 HTTP_POST, url, json_to_bytes(jws), HTTP_STATUS_OK, ok_callback);
321 const std::string& account_url,
322 const std::string& resource_url,
325 bool empty_payload =
false)
329 request_new_nonce([=]() {
331 account_url, resource_url, ok_callback, empty_payload);
336 auto nonce = nonces.front();
339 auto header = mk_kid_header(account_url, nonce, resource_url);
341 header, nlohmann::json::object_t(), *account_key_pair, empty_payload);
342 http::URL url = with_default_port(resource_url);
350 const std::vector<uint8_t>& data) {
353 ok_callback(headers, nlohmann::json::parse(data));
356 catch (
const std::exception& ex)
358 LOG_FAIL_FMT(
"ACME: request callback failed: {}", ex.what());
376 std::optional<std::chrono::system_clock::time_point> last_request =
378 size_t num_failed_attempts = 0;
408 const std::string& url,
const std::string& default_port =
"443")
413 r.
port = default_port;
418 static std::vector<uint8_t>
s2v(
const std::string& s)
420 return std::vector<uint8_t>(s.data(), s.data() + s.size());
425 return s2v(j.dump());
429 const nlohmann::json& j,
bool with_padding =
true)
438 const unsigned char* pp = sig.data();
439 ECDSA_SIG* sig_r_s = d2i_ECDSA_SIG(NULL, &pp, sig.size());
440 const BIGNUM* r = ECDSA_SIG_get0_r(sig_r_s);
441 const BIGNUM* s = ECDSA_SIG_get0_s(sig_r_s);
443 sig = std::vector<uint8_t>(2 * sz, 0);
444 BN_bn2binpad(r, sig.data(), sz);
445 BN_bn2binpad(s, sig.data() + sz, sz);
446 ECDSA_SIG_free(sig_r_s);
449 class JWS :
public nlohmann::json::object_t
453 const nlohmann::json& header_,
454 const nlohmann::json& payload_,
456 bool empty_payload =
false)
460 auto header_b64 = json_to_b64url(header_,
false);
461 auto payload_b64 = empty_payload ?
"" : json_to_b64url(payload_,
false);
462 set(header_b64, payload_b64, signer_);
473 const std::string& header_b64,
474 const std::string& payload_b64,
477 auto msg = header_b64 +
"." + payload_b64;
478 auto sig = signer.
sign(s2v(msg));
479 convert_signature_to_ieee_p1363(sig, signer);
482 (*this)[
"protected"] = header_b64;
483 (*this)[
"payload"] = payload_b64;
484 (*this)[
"signature"] = sig_b64;
488 class JWK :
public nlohmann::json::object_t
492 const std::string& kty,
493 const std::string& crv,
494 const std::string& x,
495 const std::string& y,
496 const std::optional<std::string>& alg = std::nullopt,
497 const std::optional<std::string>& use = std::nullopt,
498 const std::optional<std::string>& kid = std::nullopt)
500 (*this)[
"kty"] = kty;
501 (*this)[
"crv"] = crv;
505 (*this)[
"alg"] = *alg;
507 (*this)[
"use"] = *use;
509 (*this)[
"kid"] = *kid;
517 for (
const auto& [k, v] : headers)
528 static void expect(
const nlohmann::json& j,
const std::string& key)
530 if (!j.contains(key))
532 throw std::runtime_error(fmt::format(
"Missing key '{}'", key));
537 const nlohmann::json& j,
const std::string& key,
const std::string& value)
541 const auto k = j[key].get<std::string>();
544 throw std::runtime_error(fmt::format(
545 "Unexpected value for '{}': '{}' while expecting '{}'",
553 const std::shared_ptr<ccf::crypto::KeyPair>& key_pair)
555 std::string crv, alg;
567 throw std::runtime_error(
"Unsupported curve");
569 return std::make_pair(crv, alg);
574 auto oit = std::find_if(
575 active_orders.begin(),
577 [&order_url](
const Order& other) {
578 return order_url == other.order_url;
581 if (oit != active_orders.end())
595 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
596 for (
auto it = active_orders.begin(); it != active_orders.end();)
598 if (it->order_url == order_url)
600 for (
const auto& [_, challenge] : it->challenges)
602 on_challenge_finished(challenge.token);
604 it = active_orders.erase(it);
615 const std::string& account_url,
616 const std::string& nonce,
617 const std::string& resource_url)
623 auto crv_alg = get_crv_alg(account_key_pair);
626 {
"alg", crv_alg.second},
627 {
"kid", account_url},
629 {
"url", resource_url}};
644 request_new_account();
650 http::URL url = with_default_port(directory.at(
"newNonce"));
655 HTTP_STATUS_NO_CONTENT,
665 std::string new_account_url =
666 directory.at(
"newAccount").get<std::string>();
670 request_new_nonce([
this]() { request_new_account(); });
674 auto nonce = nonces.front();
677 auto crv_alg = get_crv_alg(account_key_pair);
678 auto key_coords = account_key_pair->coordinates();
686 nlohmann::json header = {
687 {
"alg", crv_alg.second},
690 {
"url", new_account_url}};
692 nlohmann::json payload = {
696 JWS jws(header, payload, *account_key_pair);
698 http::URL url = with_default_port(new_account_url);
705 expect_string(j,
"status",
"valid");
707 auto loc_opt = get_header_value(headers,
"location");
708 request_new_order(loc_opt.value_or(
""));
715 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
716 auto order = get_order(order_url);
723 if (!order->authorizations.empty())
725 request_authorization(*order, *order->authorizations.begin());
734 [
this, account_url]() { request_new_order(account_url); });
738 auto nonce = nonces.front();
742 mk_kid_header(account_url, nonce, directory.at(
"newOrder"));
744 nlohmann::json payload = {
746 nlohmann::json::array(
750 payload[
"identifiers"] += {{
"type",
"dns"}, {
"value", n}};
761 JWS jws(header, payload, *account_key_pair);
763 http::URL url = with_default_port(directory.at(
"newOrder"));
772 expect(j,
"finalize");
774 auto order_url_opt = get_header_value(headers,
"location");
777 throw std::runtime_error(
"Missing order location");
780 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
781 active_orders.emplace_back(
Order{
782 ACTIVE, account_url, *order_url_opt, j[
"finalize"],
"", {}, {}});
784 Order& order = active_orders.back();
786 const auto status = j[
"status"].get<std::string>();
787 if (status ==
"pending" && j.contains(
"authorizations"))
789 expect(j,
"authorizations");
791 j[
"authorizations"].get<std::unordered_set<std::string>>();
793 authorize_next_challenge(*order_url_opt);
795 else if (status ==
"ready")
797 expect(j,
"finalize");
799 request_finalization(*order_url_opt);
801 else if (status ==
"valid")
803 expect(j,
"certificate");
806 request_certificate(*order_url_opt);
810 LOG_FAIL_FMT(
"ACME: unknown order status '{}', aborting", status);
812 remove_order(*order_url_opt);
823 [
this, order_url = order.
order_url, authz_url](
825 LOG_TRACE_FMT(
"ACME: authorization reply: {}", j.dump());
826 expect_string(j,
"status",
"pending");
827 expect(j,
"challenges");
830 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
831 auto order = get_order(order_url);
838 bool found_match = false;
839 for (const auto& challenge : j[
"challenges"])
842 challenge.contains(
"type") &&
843 challenge[
"type"] == config.challenge_type)
845 expect_string(challenge,
"status",
"pending");
846 expect(challenge,
"token");
847 expect(challenge,
"url");
849 std::string token = challenge[
"token"];
850 std::string challenge_url = challenge[
"url"];
852 add_challenge(*order, token, authz_url, challenge_url);
858 order->authorizations.erase(authz_url);
862 throw std::runtime_error(fmt::format(
863 "Challenge type '{}' not offered", config.challenge_type));
867 authorize_next_challenge(order_url);
876 auto crv_alg = get_crv_alg(account_key_pair);
877 auto key_coords = account_key_pair->coordinates();
891 const std::string& token,
892 const std::string& authorization_url,
893 const std::string& challenge_url)
895 auto response = make_challenge_response();
898 token,
Challenge{token, authorization_url, challenge_url});
900 on_challenge(token, response);
907 order_url(order_url),
908 challenge(challenge),
917 const std::string& order_url,
Challenge& challenge)
919 return std::make_unique<threading::Tmsg<ChallengeWaitMsg>>(
920 [](std::unique_ptr<threading::Tmsg<ChallengeWaitMsg>> msg) {
921 std::string& order_url = msg->data.order_url;
922 Challenge& challenge = msg->data.challenge;
925 if (
client->check_challenge(order_url, challenge))
929 std::move(msg), std::chrono::seconds(5));
938 const std::string& order_url,
const Challenge& challenge)
940 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
941 auto order = get_order(order_url);
945 order->challenges.find(challenge.
token) == order->challenges.end())
951 "ACME: requesting challenge status for token '{}' ...",
958 [
this, order_url, challenge_token = challenge.
token](
960 const std::vector<uint8_t>& body) {
961 auto j = nlohmann::json::parse(body);
962 LOG_TRACE_FMT(
"ACME: authorization status: {}", j.dump());
965 const auto status = j[
"status"].get<std::string>();
966 if (status ==
"valid")
968 finish_challenge(order_url, challenge_token);
970 else if (status ==
"pending" || status ==
"processing")
972 if (j.contains(
"error"))
975 "ACME: challenge for token '{}' failed with the following "
979 finish_challenge(order_url, challenge_token);
989 "ACME: challenge for token '{}' failed with status '{}' ",
992 finish_challenge(order_url, challenge_token);
1002 const std::string& order_url,
const std::string& challenge_token)
1004 bool order_done =
false;
1007 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
1008 auto order = get_order(order_url);
1015 auto cit = order->challenges.find(challenge_token);
1016 if (cit == order->challenges.end())
1018 throw std::runtime_error(
1019 fmt::format(
"No active challenge for token '{}'", challenge_token));
1022 on_challenge_finished(cit->first);
1023 order->challenges.erase(cit);
1024 order_done = order->challenges.empty();
1029 request_finalization(order_url);
1035 std::unique_lock<ccf::pal::Mutex> guard2(orders_lock);
1036 auto order = get_order(order_url);
1043 LOG_TRACE_FMT(
"ACME: checking finalization of {}", order_url);
1051 const std::vector<uint8_t>& body) {
1052 auto j = nlohmann::json::parse(body);
1053 LOG_TRACE_FMT(
"ACME: finalization status: {}", j.dump());
1054 expect(j,
"status");
1055 const auto status = j[
"status"].get<std::string>();
1056 if (status ==
"valid")
1058 expect(j,
"certificate");
1060 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
1061 auto order = get_order(order_url);
1064 order->certificate_url = j[
"certificate"];
1067 request_certificate(order_url);
1069 else if (status ==
"invalid")
1072 remove_order(order_url);
1074 else if (status !=
"pending" && status !=
"processing")
1077 "ACME: unknown order status '{}'; aborting order", status);
1078 remove_order(order_url);
1089 order_url(order_url),
1096 std::unique_ptr<threading::Tmsg<FinalizationWaitMsg>>
1099 return std::make_unique<threading::Tmsg<FinalizationWaitMsg>>(
1100 [](std::unique_ptr<threading::Tmsg<FinalizationWaitMsg>> msg) {
1102 const std::string& order_url = msg->data.order_url;
1104 if (
client->check_finalization(order_url))
1108 std::move(msg), std::chrono::seconds(5));
1117 std::vector<ccf::crypto::SubjectAltName> alt_names;
1118 alt_names.push_back({config.service_dns_name,
false});
1119 for (
const auto& an : config.alternative_names)
1120 alt_names.push_back({an,
false});
1121 return service_key->create_csr_der(
1122 "CN=" + config.service_dns_name, alt_names);
1130 [
this, &order_url]() { request_finalization(order_url); });
1134 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
1135 auto order = get_order(order_url);
1142 auto nonce = nonces.front();
1146 mk_kid_header(order->account_url, nonce, order->finalize_url);
1148 auto csr = get_service_csr();
1150 nlohmann::json payload = {
1153 JWS jws(header, payload, *account_key_pair);
1155 http::URL url = with_default_port(order->finalize_url);
1161 [
this, order_url = order->order_url](
1163 LOG_TRACE_FMT(
"ACME: finalization status: {}", j.dump());
1164 expect(j,
"status");
1165 const auto status = j[
"status"].get<std::string>();
1166 if (status ==
"valid")
1168 expect(j,
"certificate");
1171 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
1172 auto order = get_order(order_url);
1175 order->certificate_url = j[
"certificate"];
1178 request_certificate(order_url);
1182 LOG_TRACE_FMT(
"ACME: scheduling finalization check");
1183 threading::ThreadMessaging::instance().add_task_after(
1184 schedule_check_finalization(order_url),
1185 std::chrono::milliseconds(0));
1196 [
this, &order_url]() { request_certificate(order_url); });
1200 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
1201 auto order = get_order(order_url);
1208 http::URL url = with_default_port(order->certificate_url);
1211 order->certificate_url,
1214 const std::vector<uint8_t>& data) {
1215 std::string c(data.data(), data.data() + data.size());
1216 LOG_TRACE_FMT(
"ACME: obtained certificate (chain): {}", c);
1220 remove_order(order_url);
1222 last_request = std::chrono::system_clock::now();
1223 num_failed_attempts = 0;
Definition acme_client.h:489
JWK(const std::string &kty, const std::string &crv, const std::string &x, const std::string &y, const std::optional< std::string > &alg=std::nullopt, const std::optional< std::string > &use=std::nullopt, const std::optional< std::string > &kid=std::nullopt)
Definition acme_client.h:491
Definition acme_client.h:450
virtual ~JWS()
Definition acme_client.h:469
JWS(const nlohmann::json &header_, ccf::crypto::KeyPair &signer_)
Definition acme_client.h:465
void set(const std::string &header_b64, const std::string &payload_b64, ccf::crypto::KeyPair &signer)
Definition acme_client.h:472
JWS(const nlohmann::json &header_, const nlohmann::json &payload_, ccf::crypto::KeyPair &signer_, bool empty_payload=false)
Definition acme_client.h:452
Definition acme_client.h:64
bool check_challenge(const std::string &order_url, const Challenge &challenge)
Definition acme_client.h:937
void get_certificate(std::shared_ptr< ccf::crypto::KeyPair > service_key_, bool override_time=false)
Definition acme_client.h:76
static std::vector< uint8_t > s2v(const std::string &s)
Definition acme_client.h:418
static void expect_string(const nlohmann::json &j, const std::string &key, const std::string &value)
Definition acme_client.h:536
void add_challenge(Order &order, const std::string &token, const std::string &authorization_url, const std::string &challenge_url)
Definition acme_client.h:889
std::list< std::string > nonces
Definition acme_client.h:371
void post_as_get_json(const std::string &account_url, const std::string &resource_url, std::function< bool(const ccf::http::HeaderMap &, const nlohmann::json &)> ok_callback, bool empty_payload=false)
Definition acme_client.h:320
bool has_active_orders() const
Definition acme_client.h:162
std::unique_ptr< threading::Tmsg< FinalizationWaitMsg > > schedule_check_finalization(const std::string &order_url)
Definition acme_client.h:1097
virtual void on_challenge_finished(const std::string &token)=0
virtual void on_challenge(const std::string &token, const std::string &response)=0
virtual void set_account_key(std::shared_ptr< ccf::crypto::KeyPair > new_account_key_pair)
Definition acme_client.h:151
static std::string json_to_b64url(const nlohmann::json &j, bool with_padding=true)
Definition acme_client.h:428
ccf::pal::Mutex req_lock
Definition acme_client.h:373
void start_challenge(const std::string &token)
Definition acme_client.h:130
void authorize_next_challenge(const std::string &order_url)
Definition acme_client.h:713
static http::URL with_default_port(const std::string &url, const std::string &default_port="443")
Definition acme_client.h:407
std::shared_ptr< ccf::crypto::KeyPair > service_key
Definition acme_client.h:366
nlohmann::json directory
Definition acme_client.h:369
void post_as_get(const std::string &account_url, const std::string &resource_url, std::function< bool(const ccf::http::HeaderMap &, const std::vector< uint8_t > &)> ok_callback)
Definition acme_client.h:297
std::optional< std::chrono::system_clock::time_point > last_request
Definition acme_client.h:376
void request_new_order(const std::string &account_url)
Definition acme_client.h:729
virtual std::vector< uint8_t > get_service_csr()
Definition acme_client.h:1115
size_t num_failed_attempts
Definition acme_client.h:378
static std::optional< std::string > get_header_value(const ccf::http::HeaderMap &headers, const std::string &name)
Definition acme_client.h:514
void request_directory()
Definition acme_client.h:634
virtual void on_certificate(const std::string &certificate)=0
bool check_finalization(const std::string &order_url)
Definition acme_client.h:1033
virtual void on_http_request(const http::URL &url, http::Request &&req, std::function< bool(http_status status, ccf::http::HeaderMap &&, std::vector< uint8_t > &&)> callback)=0
Order * get_order(const std::string &order_url)
Definition acme_client.h:572
static void expect(const nlohmann::json &j, const std::string &key)
Definition acme_client.h:528
void request_certificate(const std::string &order_url)
Definition acme_client.h:1191
nlohmann::json account
Definition acme_client.h:370
void request_authorization(Order &order, const std::string &authz_url)
Definition acme_client.h:818
std::shared_ptr< ccf::crypto::KeyPair > account_key_pair
Definition acme_client.h:367
void request_finalization(const std::string &order_url)
Definition acme_client.h:1125
virtual ~Client()
Definition acme_client.h:74
static void convert_signature_to_ieee_p1363(std::vector< uint8_t > &sig, const ccf::crypto::KeyPair &signer)
Definition acme_client.h:434
void request_new_nonce(std::function< void()> ok_callback)
Definition acme_client.h:648
void make_json_request(llhttp_method method, const http::URL &url, const std::vector< uint8_t > &body, http_status expected_status, std::function< void(const ccf::http::HeaderMap &headers, const nlohmann::json &)> ok_callback)
Definition acme_client.h:259
std::list< Order > active_orders
Definition acme_client.h:405
std::unique_ptr< threading::Tmsg< ChallengeWaitMsg > > schedule_check_challenge(const std::string &order_url, Challenge &challenge)
Definition acme_client.h:916
void finish_challenge(const std::string &order_url, const std::string &challenge_token)
Definition acme_client.h:1001
OrderStatus
Definition acme_client.h:388
@ ACTIVE
Definition acme_client.h:389
@ FINISHED
Definition acme_client.h:390
std::string make_challenge_response() const
Definition acme_client.h:874
static std::pair< std::string, std::string > get_crv_alg(const std::shared_ptr< ccf::crypto::KeyPair > &key_pair)
Definition acme_client.h:552
void make_request(llhttp_method method, const http::URL &url, const std::vector< uint8_t > &body, http_status expected_status, std::function< bool(const ccf::http::HeaderMap &, const std::vector< uint8_t > &)> ok_callback)
Definition acme_client.h:179
ccf::pal::Mutex orders_lock
Definition acme_client.h:374
ClientConfig config
Definition acme_client.h:365
void remove_order(const std::string &order_url)
Definition acme_client.h:591
nlohmann::json mk_kid_header(const std::string &account_url, const std::string &nonce, const std::string &resource_url)
Definition acme_client.h:614
Client(const ClientConfig &config, std::shared_ptr< ccf::crypto::KeyPair > account_key_pair=nullptr)
Definition acme_client.h:66
void request_new_account()
Definition acme_client.h:663
static std::vector< uint8_t > json_to_bytes(const nlohmann::json &j)
Definition acme_client.h:423
virtual PublicKey::Coordinates coordinates() const =0
virtual std::vector< uint8_t > sign(std::span< const uint8_t > d, MDType md_type={}) const =0
void set_body(const std::vector< uint8_t > *b)
Definition http_builder.h:74
void set_header(std::string k, const std::string &v)
Definition http_builder.h:45
Definition http_builder.h:106
std::vector< uint8_t > build_request(bool header_only=false) const
Definition http_builder.h:165
static ThreadMessaging & instance()
Definition thread_messaging.h:278
TaskQueue::TimerEntry add_task_after(std::unique_ptr< Tmsg< Payload > > msg, std::chrono::milliseconds ms)
Definition thread_messaging.h:320
llhttp_status http_status
Definition http_status.h:7
#define LOG_INFO_FMT
Definition logger.h:395
#define LOG_TRACE_FMT
Definition logger.h:378
#define LOG_DEBUG_FMT
Definition logger.h:380
#define LOG_FAIL_FMT
Definition logger.h:396
Definition acme_client.h:30
std::string b64url_from_raw(const uint8_t *data, size_t size, bool with_padding=true)
Definition base64.cpp:49
HashBytes sha256(const std::span< uint8_t const > &data)
Definition hash.cpp:24
@ SECP384R1
The SECP384R1 curve.
@ SECP256R1
The SECP256R1 curve.
KeyPairPtr make_key_pair(CurveID curve_id=service_identity_curve_choice)
Definition key_pair.cpp:35
std::map< std::string, std::string, std::less<> > HeaderMap
Definition http_header_map.h:10
std::mutex Mutex
Definition locking.h:17
Definition perf_client.h:26
URL parse_url_full(const std::string &url)
Definition http_parser.h:145
Definition json_schema.h:15
Definition ledger_secret.h:106
Definition acme_client.h:32
std::string directory_url
Definition acme_client.h:38
bool operator==(const ClientConfig &other) const =default
std::string challenge_type
Definition acme_client.h:54
std::optional< std::string > not_before
Definition acme_client.h:57
std::optional< std::string > not_after
Definition acme_client.h:58
std::vector< std::string > contact
Definition acme_client.h:47
std::string service_dns_name
Definition acme_client.h:41
std::vector< std::string > ca_certs
Definition acme_client.h:35
bool terms_of_service_agreed
Definition acme_client.h:51
std::vector< std::string > alternative_names
Definition acme_client.h:44
Definition acme_client.h:904
Challenge challenge
Definition acme_client.h:912
ChallengeWaitMsg(const std::string &order_url, Challenge challenge, Client *client)
Definition acme_client.h:905
std::string order_url
Definition acme_client.h:911
Client * client
Definition acme_client.h:913
Definition acme_client.h:381
std::string token
Definition acme_client.h:382
std::string challenge_url
Definition acme_client.h:384
std::string authorization_url
Definition acme_client.h:383
Definition acme_client.h:1087
FinalizationWaitMsg(const std::string &order_url, Client *client)
Definition acme_client.h:1088
std::string order_url
Definition acme_client.h:1092
Client * client
Definition acme_client.h:1093
Definition acme_client.h:395
std::map< std::string, Challenge > challenges
Definition acme_client.h:402
std::string finalize_url
Definition acme_client.h:399
std::string certificate_url
Definition acme_client.h:400
std::string account_url
Definition acme_client.h:397
std::unordered_set< std::string > authorizations
Definition acme_client.h:401
std::string order_url
Definition acme_client.h:398
std::vector< uint8_t > x
Definition public_key.h:143
Definition http_parser.h:136
std::string host
Definition http_parser.h:138
std::string port
Definition http_parser.h:139
std::string path
Definition http_parser.h:140