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;
178 std::vector<uint8_t>&&)> callback) = 0;
181 llhttp_method method,
183 const std::vector<uint8_t>& body,
188 std::unique_lock<ccf::pal::Mutex> guard(
req_lock);
192 auto port = url.
port.empty() ?
"443" : url.
port;
194 "ACME: Requesting https://{}:{}{}", url.
host, port, url.
path);
197 r.
set_header(ccf::http::headers::ACCEPT,
"*/*");
199 ccf::http::headers::HOST, fmt::format(
"{}:{}", url.
host, url.
port));
203 ccf::http::headers::CONTENT_TYPE,
"application/jose+json");
207 std::string reqs(req.begin(), req.end());
213 [
this, expected_status, ok_callback](
216 std::vector<uint8_t>&& data) {
217 for (
auto& [k, v] : headers)
222 if (status != expected_status && status != HTTP_STATUS_OK)
225 "ACME: request failed with status={} and body={}",
227 std::string(data.begin(), data.end()));
233 "ACME: data: {}", std::string(data.begin(), data.end()));
239 nonces.push_back(*nonce_opt);
244 ok_callback(headers, data);
246 catch (
const std::exception& ex)
248 LOG_FAIL_FMT(
"ACME: response callback failed: {}", ex.what());
254 catch (
const std::exception& ex)
256 LOG_FAIL_FMT(
"ACME: failed to connect to ACME server: {}", ex.what());
261 llhttp_method method,
263 const std::vector<uint8_t>& body,
276 const std::vector<uint8_t>& data) {
283 jr = nlohmann::json::parse(data);
284 LOG_TRACE_FMT(
"ACME: json response: {}", jr.dump());
286 catch (
const std::exception& ex)
288 LOG_FAIL_FMT(
"ACME: response parser failed: {}", ex.what());
293 ok_callback(headers, jr);
299 const std::string& account_url,
300 const std::string& resource_url,
307 [&,
this]() { post_as_get(account_url, resource_url, ok_callback); });
311 auto nonce = nonces.front();
313 auto header = mk_kid_header(account_url, nonce, resource_url);
314 JWS jws(header, *account_key_pair);
315 http::URL url = with_default_port(resource_url);
317 HTTP_POST, url, json_to_bytes(jws), HTTP_STATUS_OK, ok_callback);
322 const std::string& account_url,
323 const std::string& resource_url,
326 bool empty_payload =
false)
330 request_new_nonce([&,
this]() {
332 account_url, resource_url, ok_callback, empty_payload);
337 auto nonce = nonces.front();
340 auto header = mk_kid_header(account_url, nonce, resource_url);
342 header, nlohmann::json::object_t(), *account_key_pair, empty_payload);
343 http::URL url = with_default_port(resource_url);
351 const std::vector<uint8_t>& data) {
354 ok_callback(headers, nlohmann::json::parse(data));
357 catch (
const std::exception& ex)
359 LOG_FAIL_FMT(
"ACME: request callback failed: {}", ex.what());
377 std::optional<std::chrono::system_clock::time_point> last_request =
379 size_t num_failed_attempts = 0;
409 const std::string& url,
const std::string& default_port =
"443")
414 r.
port = default_port;
419 static std::vector<uint8_t>
s2v(
const std::string& s)
421 return std::vector<uint8_t>(s.data(), s.data() + s.size());
426 return s2v(j.dump());
430 const nlohmann::json& j,
bool with_padding =
true)
439 const unsigned char* pp = sig.data();
440 ECDSA_SIG* sig_r_s = d2i_ECDSA_SIG(NULL, &pp, sig.size());
441 const BIGNUM* r = ECDSA_SIG_get0_r(sig_r_s);
442 const BIGNUM* s = ECDSA_SIG_get0_s(sig_r_s);
444 sig = std::vector<uint8_t>(2 * sz, 0);
445 BN_bn2binpad(r, sig.data(), sz);
446 BN_bn2binpad(s, sig.data() + sz, sz);
447 ECDSA_SIG_free(sig_r_s);
450 class JWS :
public nlohmann::json::object_t
454 const nlohmann::json& header_,
455 const nlohmann::json& payload_,
457 bool empty_payload =
false)
461 auto header_b64 = json_to_b64url(header_,
false);
462 auto payload_b64 = empty_payload ?
"" : json_to_b64url(payload_,
false);
463 set(header_b64, payload_b64, signer_);
474 const std::string& header_b64,
475 const std::string& payload_b64,
478 auto msg = header_b64 +
"." + payload_b64;
479 auto sig = signer.
sign(s2v(msg));
480 convert_signature_to_ieee_p1363(sig, signer);
483 (*this)[
"protected"] = header_b64;
484 (*this)[
"payload"] = payload_b64;
485 (*this)[
"signature"] = sig_b64;
489 class JWK :
public nlohmann::json::object_t
493 const std::string& kty,
494 const std::string& crv,
495 const std::string& x,
496 const std::string& y,
497 const std::optional<std::string>& alg = std::nullopt,
498 const std::optional<std::string>& use = std::nullopt,
499 const std::optional<std::string>& kid = std::nullopt)
501 (*this)[
"kty"] = kty;
502 (*this)[
"crv"] = crv;
506 (*this)[
"alg"] = *alg;
508 (*this)[
"use"] = *use;
510 (*this)[
"kid"] = *kid;
518 for (
const auto& [k, v] : headers)
529 static void expect(
const nlohmann::json& j,
const std::string& key)
531 if (!j.contains(key))
533 throw std::runtime_error(fmt::format(
"Missing key '{}'", key));
538 const nlohmann::json& j,
const std::string& key,
const std::string& value)
542 const auto k = j[key].get<std::string>();
545 throw std::runtime_error(fmt::format(
546 "Unexpected value for '{}': '{}' while expecting '{}'",
554 const std::shared_ptr<ccf::crypto::KeyPair>& key_pair)
556 std::string crv, alg;
568 throw std::runtime_error(
"Unsupported curve");
570 return std::make_pair(crv, alg);
575 auto oit = std::find_if(
576 active_orders.begin(),
578 [&order_url](
const Order& other) {
579 return order_url == other.order_url;
582 if (oit != active_orders.end())
596 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
597 for (
auto it = active_orders.begin(); it != active_orders.end();)
599 if (it->order_url == order_url)
601 for (
const auto& [_, challenge] : it->challenges)
603 on_challenge_finished(challenge.token);
605 it = active_orders.erase(it);
616 const std::string& account_url,
617 const std::string& nonce,
618 const std::string& resource_url)
624 auto crv_alg = get_crv_alg(account_key_pair);
627 {
"alg", crv_alg.second},
628 {
"kid", account_url},
630 {
"url", resource_url}};
645 request_new_account();
651 http::URL url = with_default_port(directory.at(
"newNonce"));
656 HTTP_STATUS_NO_CONTENT,
666 std::string new_account_url =
667 directory.at(
"newAccount").get<std::string>();
671 request_new_nonce([
this]() { request_new_account(); });
675 auto nonce = nonces.front();
678 auto crv_alg = get_crv_alg(account_key_pair);
679 auto key_coords = account_key_pair->coordinates();
687 nlohmann::json header = {
688 {
"alg", crv_alg.second},
691 {
"url", new_account_url}};
693 nlohmann::json payload = {
697 JWS jws(header, payload, *account_key_pair);
699 http::URL url = with_default_port(new_account_url);
706 expect_string(j,
"status",
"valid");
708 auto loc_opt = get_header_value(headers,
"location");
709 request_new_order(loc_opt.value_or(
""));
716 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
717 auto order = get_order(order_url);
724 if (!order->authorizations.empty())
726 request_authorization(*order, *order->authorizations.begin());
735 [
this, account_url]() { request_new_order(account_url); });
739 auto nonce = nonces.front();
743 mk_kid_header(account_url, nonce, directory.at(
"newOrder"));
745 nlohmann::json payload = {
747 nlohmann::json::array(
751 payload[
"identifiers"] += {{
"type",
"dns"}, {
"value", n}};
762 JWS jws(header, payload, *account_key_pair);
764 http::URL url = with_default_port(directory.at(
"newOrder"));
773 expect(j,
"finalize");
775 auto order_url_opt = get_header_value(headers,
"location");
778 throw std::runtime_error(
"Missing order location");
781 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
782 active_orders.emplace_back(
Order{
783 ACTIVE, account_url, *order_url_opt, j[
"finalize"],
"", {}, {}});
785 Order& order = active_orders.back();
787 const auto status = j[
"status"].get<std::string>();
788 if (status ==
"pending" && j.contains(
"authorizations"))
790 expect(j,
"authorizations");
792 j[
"authorizations"].get<std::unordered_set<std::string>>();
794 authorize_next_challenge(*order_url_opt);
796 else if (status ==
"ready")
798 expect(j,
"finalize");
800 request_finalization(*order_url_opt);
802 else if (status ==
"valid")
804 expect(j,
"certificate");
807 request_certificate(*order_url_opt);
811 LOG_FAIL_FMT(
"ACME: unknown order status '{}', aborting", status);
813 remove_order(*order_url_opt);
824 [
this, order_url = order.
order_url, authz_url](
826 LOG_TRACE_FMT(
"ACME: authorization reply: {}", j.dump());
827 expect_string(j,
"status",
"pending");
828 expect(j,
"challenges");
831 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
832 auto order = get_order(order_url);
839 bool found_match = false;
840 for (const auto& challenge : j[
"challenges"])
843 challenge.contains(
"type") &&
844 challenge[
"type"] == config.challenge_type)
846 expect_string(challenge,
"status",
"pending");
847 expect(challenge,
"token");
848 expect(challenge,
"url");
850 std::string token = challenge[
"token"];
851 std::string challenge_url = challenge[
"url"];
853 add_challenge(*order, token, authz_url, challenge_url);
859 order->authorizations.erase(authz_url);
863 throw std::runtime_error(fmt::format(
864 "Challenge type '{}' not offered", config.challenge_type));
868 authorize_next_challenge(order_url);
877 auto crv_alg = get_crv_alg(account_key_pair);
878 auto key_coords = account_key_pair->coordinates();
892 const std::string& token,
893 const std::string& authorization_url,
894 const std::string& challenge_url)
896 auto response = make_challenge_response();
899 token,
Challenge{token, authorization_url, challenge_url});
901 on_challenge(token, response);
908 order_url(order_url),
909 challenge(challenge),
918 const std::string& order_url,
Challenge& challenge)
920 return std::make_unique<threading::Tmsg<ChallengeWaitMsg>>(
921 [](std::unique_ptr<threading::Tmsg<ChallengeWaitMsg>> msg) {
922 std::string& order_url = msg->data.order_url;
923 Challenge& challenge = msg->data.challenge;
926 if (
client->check_challenge(order_url, challenge))
930 std::move(msg), std::chrono::seconds(5));
939 const std::string& order_url,
const Challenge& challenge)
941 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
942 auto order = get_order(order_url);
946 order->challenges.find(challenge.
token) == order->challenges.end())
952 "ACME: requesting challenge status for token '{}' ...",
959 [
this, order_url, challenge_token = challenge.
token](
961 const std::vector<uint8_t>& body) {
962 auto j = nlohmann::json::parse(body);
963 LOG_TRACE_FMT(
"ACME: authorization status: {}", j.dump());
966 const auto status = j[
"status"].get<std::string>();
967 if (status ==
"valid")
969 finish_challenge(order_url, challenge_token);
971 else if (status ==
"pending" || status ==
"processing")
973 if (j.contains(
"error"))
976 "ACME: challenge for token '{}' failed with the following "
980 finish_challenge(order_url, challenge_token);
990 "ACME: challenge for token '{}' failed with status '{}' ",
993 finish_challenge(order_url, challenge_token);
1003 const std::string& order_url,
const std::string& challenge_token)
1005 bool order_done =
false;
1008 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
1009 auto order = get_order(order_url);
1016 auto cit = order->challenges.find(challenge_token);
1017 if (cit == order->challenges.end())
1019 throw std::runtime_error(
1020 fmt::format(
"No active challenge for token '{}'", challenge_token));
1023 on_challenge_finished(cit->first);
1024 order->challenges.erase(cit);
1025 order_done = order->challenges.empty();
1030 request_finalization(order_url);
1036 std::unique_lock<ccf::pal::Mutex> guard2(orders_lock);
1037 auto order = get_order(order_url);
1044 LOG_TRACE_FMT(
"ACME: checking finalization of {}", order_url);
1052 const std::vector<uint8_t>& body) {
1053 auto j = nlohmann::json::parse(body);
1054 LOG_TRACE_FMT(
"ACME: finalization status: {}", j.dump());
1055 expect(j,
"status");
1056 const auto status = j[
"status"].get<std::string>();
1057 if (status ==
"valid")
1059 expect(j,
"certificate");
1061 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
1062 auto order = get_order(order_url);
1065 order->certificate_url = j[
"certificate"];
1068 request_certificate(order_url);
1070 else if (status ==
"invalid")
1073 remove_order(order_url);
1075 else if (status !=
"pending" && status !=
"processing")
1078 "ACME: unknown order status '{}'; aborting order", status);
1079 remove_order(order_url);
1090 order_url(order_url),
1097 std::unique_ptr<threading::Tmsg<FinalizationWaitMsg>>
1100 return std::make_unique<threading::Tmsg<FinalizationWaitMsg>>(
1101 [](std::unique_ptr<threading::Tmsg<FinalizationWaitMsg>> msg) {
1103 const std::string& order_url = msg->data.order_url;
1105 if (
client->check_finalization(order_url))
1109 std::move(msg), std::chrono::seconds(5));
1118 std::vector<ccf::crypto::SubjectAltName> alt_names;
1119 alt_names.push_back({config.service_dns_name,
false});
1120 for (
const auto& an : config.alternative_names)
1121 alt_names.push_back({an,
false});
1122 return service_key->create_csr_der(
1123 "CN=" + config.service_dns_name, alt_names);
1131 [
this, &order_url]() { request_finalization(order_url); });
1135 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
1136 auto order = get_order(order_url);
1143 auto nonce = nonces.front();
1147 mk_kid_header(order->account_url, nonce, order->finalize_url);
1149 auto csr = get_service_csr();
1151 nlohmann::json payload = {
1154 JWS jws(header, payload, *account_key_pair);
1156 http::URL url = with_default_port(order->finalize_url);
1162 [
this, order_url = order->order_url](
1164 LOG_TRACE_FMT(
"ACME: finalization status: {}", j.dump());
1165 expect(j,
"status");
1166 const auto status = j[
"status"].get<std::string>();
1167 if (status ==
"valid")
1169 expect(j,
"certificate");
1172 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
1173 auto order = get_order(order_url);
1176 order->certificate_url = j[
"certificate"];
1179 request_certificate(order_url);
1183 LOG_TRACE_FMT(
"ACME: scheduling finalization check");
1184 threading::ThreadMessaging::instance().add_task_after(
1185 schedule_check_finalization(order_url),
1186 std::chrono::milliseconds(0));
1197 [
this, &order_url]() { request_certificate(order_url); });
1201 std::unique_lock<ccf::pal::Mutex> guard(orders_lock);
1202 auto order = get_order(order_url);
1209 http::URL url = with_default_port(order->certificate_url);
1212 order->certificate_url,
1215 const std::vector<uint8_t>& data) {
1216 std::string c(data.data(), data.data() + data.size());
1217 LOG_TRACE_FMT(
"ACME: obtained certificate (chain): {}", c);
1221 remove_order(order_url);
1223 last_request = std::chrono::system_clock::now();
1224 num_failed_attempts = 0;
Definition acme_client.h:490
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:492
Definition acme_client.h:451
virtual ~JWS()
Definition acme_client.h:470
JWS(const nlohmann::json &header_, ccf::crypto::KeyPair &signer_)
Definition acme_client.h:466
void set(const std::string &header_b64, const std::string &payload_b64, ccf::crypto::KeyPair &signer)
Definition acme_client.h:473
JWS(const nlohmann::json &header_, const nlohmann::json &payload_, ccf::crypto::KeyPair &signer_, bool empty_payload=false)
Definition acme_client.h:453
Definition acme_client.h:64
bool check_challenge(const std::string &order_url, const Challenge &challenge)
Definition acme_client.h:938
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:419
static void expect_string(const nlohmann::json &j, const std::string &key, const std::string &value)
Definition acme_client.h:537
void add_challenge(Order &order, const std::string &token, const std::string &authorization_url, const std::string &challenge_url)
Definition acme_client.h:890
std::list< std::string > nonces
Definition acme_client.h:372
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:321
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:1098
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
virtual void on_http_request(const http::URL &url, http::Request &&req, std::function< bool(ccf::http_status status, ccf::http::HeaderMap &&, std::vector< uint8_t > &&)> callback)=0
static std::string json_to_b64url(const nlohmann::json &j, bool with_padding=true)
Definition acme_client.h:429
ccf::pal::Mutex req_lock
Definition acme_client.h:374
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:714
static http::URL with_default_port(const std::string &url, const std::string &default_port="443")
Definition acme_client.h:408
void make_json_request(llhttp_method method, const http::URL &url, const std::vector< uint8_t > &body, ccf::http_status expected_status, std::function< void(const ccf::http::HeaderMap &headers, const nlohmann::json &)> ok_callback)
Definition acme_client.h:260
std::shared_ptr< ccf::crypto::KeyPair > service_key
Definition acme_client.h:367
nlohmann::json directory
Definition acme_client.h:370
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:298
std::optional< std::chrono::system_clock::time_point > last_request
Definition acme_client.h:377
void request_new_order(const std::string &account_url)
Definition acme_client.h:730
virtual std::vector< uint8_t > get_service_csr()
Definition acme_client.h:1116
size_t num_failed_attempts
Definition acme_client.h:379
static std::optional< std::string > get_header_value(const ccf::http::HeaderMap &headers, const std::string &name)
Definition acme_client.h:515
void request_directory()
Definition acme_client.h:635
virtual void on_certificate(const std::string &certificate)=0
bool check_finalization(const std::string &order_url)
Definition acme_client.h:1034
Order * get_order(const std::string &order_url)
Definition acme_client.h:573
static void expect(const nlohmann::json &j, const std::string &key)
Definition acme_client.h:529
void request_certificate(const std::string &order_url)
Definition acme_client.h:1192
nlohmann::json account
Definition acme_client.h:371
void request_authorization(Order &order, const std::string &authz_url)
Definition acme_client.h:819
std::shared_ptr< ccf::crypto::KeyPair > account_key_pair
Definition acme_client.h:368
void request_finalization(const std::string &order_url)
Definition acme_client.h:1126
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:435
void request_new_nonce(std::function< void()> ok_callback)
Definition acme_client.h:649
std::list< Order > active_orders
Definition acme_client.h:406
std::unique_ptr< threading::Tmsg< ChallengeWaitMsg > > schedule_check_challenge(const std::string &order_url, Challenge &challenge)
Definition acme_client.h:917
void finish_challenge(const std::string &order_url, const std::string &challenge_token)
Definition acme_client.h:1002
OrderStatus
Definition acme_client.h:389
@ ACTIVE
Definition acme_client.h:390
@ FINISHED
Definition acme_client.h:391
std::string make_challenge_response() const
Definition acme_client.h:875
static std::pair< std::string, std::string > get_crv_alg(const std::shared_ptr< ccf::crypto::KeyPair > &key_pair)
Definition acme_client.h:553
ccf::pal::Mutex orders_lock
Definition acme_client.h:375
ClientConfig config
Definition acme_client.h:366
void remove_order(const std::string &order_url)
Definition acme_client.h:592
nlohmann::json mk_kid_header(const std::string &account_url, const std::string &nonce, const std::string &resource_url)
Definition acme_client.h:615
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:664
void make_request(llhttp_method method, const http::URL &url, const std::vector< uint8_t > &body, ccf::http_status expected_status, std::function< bool(const ccf::http::HeaderMap &, const std::vector< uint8_t > &)> ok_callback)
Definition acme_client.h:180
static std::vector< uint8_t > json_to_bytes(const nlohmann::json &j)
Definition acme_client.h:424
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_header(std::string k, const std::string &v)
Definition http_builder.h:45
void set_body(const std::vector< uint8_t > *b, bool overwrite_content_length=true)
Definition http_builder.h:74
Definition http_builder.h:118
std::vector< uint8_t > build_request(bool header_only=false) const
Definition http_builder.h:177
static ThreadMessaging & instance()
Definition thread_messaging.h:283
TaskQueue::TimerEntry add_task_after(std::unique_ptr< Tmsg< Payload > > msg, std::chrono::milliseconds ms)
Definition thread_messaging.h:326
#define LOG_INFO_FMT
Definition logger.h:362
#define LOG_TRACE_FMT
Definition logger.h:356
#define LOG_DEBUG_FMT
Definition logger.h:357
#define LOG_FAIL_FMT
Definition logger.h:363
Definition acme_client.h:30
std::string b64url_from_raw(const uint8_t *data, size_t size, bool with_padding=true)
Definition base64.cpp:51
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:12
llhttp_status http_status
Definition http_status.h:9
Definition perf_client.h:12
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:905
Challenge challenge
Definition acme_client.h:913
ChallengeWaitMsg(const std::string &order_url, Challenge challenge, Client *client)
Definition acme_client.h:906
std::string order_url
Definition acme_client.h:912
Client * client
Definition acme_client.h:914
Definition acme_client.h:382
std::string token
Definition acme_client.h:383
std::string challenge_url
Definition acme_client.h:385
std::string authorization_url
Definition acme_client.h:384
Definition acme_client.h:1088
FinalizationWaitMsg(const std::string &order_url, Client *client)
Definition acme_client.h:1089
std::string order_url
Definition acme_client.h:1093
Client * client
Definition acme_client.h:1094
Definition acme_client.h:396
std::map< std::string, Challenge > challenges
Definition acme_client.h:403
std::string finalize_url
Definition acme_client.h:400
std::string certificate_url
Definition acme_client.h:401
std::string account_url
Definition acme_client.h:398
std::unordered_set< std::string > authorizations
Definition acme_client.h:402
std::string order_url
Definition acme_client.h:399
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