OpenVPN 3 Core Library
Loading...
Searching...
No Matches
awspc.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// Get AWS info such as instanceId, region, and privateIp.
13// Also optionally call AWSPC API with product code to get
14// number of licensed concurrent connections.
15
16#pragma once
17
18#include <string>
19#include <utility>
20
32
33namespace openvpn::AWS {
34
35class PCQuery : public RC<thread_unsafe_refcount>
36{
37 public:
39
40 OPENVPN_EXCEPTION(awspc_query_error);
41
42 struct Info
43 {
44 std::string instanceId;
45 std::string region;
46 std::string az;
47 std::string privateIp;
48
50
52 std::string error;
53
54 bool is_error() const
55 {
56 return !error.empty();
57 }
58
60 {
61 return !instanceId.empty() && !region.empty() && !privateIp.empty();
62 }
63
64 // example: [instanceId=i-ae91d23e region=us-east-1 privateIp=10.0.0.218 concurrentConnections=10]
65 std::string to_string() const
66 {
67 std::string ret = "[instanceId=" + instanceId + " region=" + region;
68 if (!privateIp.empty())
69 ret += " privateIp=" + privateIp;
70 if (concurrentConnections >= 0)
71 ret += " concurrentConnections=" + std::to_string(concurrentConnections);
72 if (!error.empty())
73 ret += " error='" + error + '\'';
74 ret += ']';
75 return ret;
76 }
77 };
78
80 const bool lookup_product_code_arg,
81 const int debug_level_arg)
82 : cs(std::move(cs_arg)),
83 rng(new DevURand()),
85 lookup_product_code(lookup_product_code_arg),
86 debug_level(debug_level_arg)
87 {
88 }
89
91 const std::string &role_for_credentials_arg,
92 const std::string &certs_dir_arg)
93 : cs(std::move(cs_arg)),
94 rng(new DevURand()),
97 debug_level(0),
98 role_for_credentials(role_for_credentials_arg),
99 certs_dir(certs_dir_arg)
100 {
101 }
102
104 {
105 // make HTTP context
107 http_config->frame = frame;
108 http_config->connect_timeout = 15;
109 http_config->general_timeout = 30;
110
111 // make transation set
113 ts->host.host = "169.254.169.254";
114 ts->host.port = "80";
115 ts->http_config = http_config;
116 ts->max_retries = 3;
117 ts->debug_level = debug_level;
118
119 return ts;
120 }
121
122 void start(std::function<void(Info info)> completion_arg)
123 {
124 // make sure we are not in a pending state
125 if (pending)
126 throw awspc_query_error("request pending");
127 pending = true;
128
129 // save completion method
130 completion = std::move(completion_arg);
131
132 // init return object
133 info = Info();
134
135 try
136 {
137 auto ts = prepare_transaction_set();
138
139 {
140 std::unique_ptr<WS::ClientSet::Transaction> t(new WS::ClientSet::Transaction);
141 t->req.method = "PUT";
142 t->req.uri = "/latest/api/token";
143 t->ci.extra_headers.emplace_back("X-aws-ec2-metadata-token-ttl-seconds: 60");
144 ts->transactions.push_back(std::move(t));
145 }
146
147 // completion handler
148 ts->completion = [self = Ptr(this)](WS::ClientSet::TransactionSet &ts)
149 {
150 self->token_query_complete(ts);
151 };
152
153 // do the request
154 cs->new_request(ts);
155 }
156 catch (const std::exception &e)
157 {
158 done(e.what());
159 }
160 }
161
162 void stop()
163 {
164 if (cs)
165 cs->stop();
166 }
167
168 private:
169 void done(std::string error)
170 {
171 pending = false;
172 info.error = std::move(error);
173 if (completion)
174 completion(std::move(info));
175 }
176
178 {
179 try
180 {
181 // get transactions and check that they succeeded
182 WS::ClientSet::Transaction &ident_trans = *lts.transactions.at(0);
183 if (!ident_trans.request_status_success())
184 {
185 done("could not fetch AWS identity document: " + ident_trans.format_status(lts));
186 return;
187 }
188
189 WS::ClientSet::Transaction &sig_trans = *lts.transactions.at(1);
190 if (!sig_trans.request_status_success())
191 {
192 done("could not fetch AWS identity document signature: " + sig_trans.format_status(lts));
193 return;
194 }
195
196 // get identity document and signature
197 const std::string ident = ident_trans.content_in.to_string();
198 const std::string sig = "-----BEGIN PKCS7-----\n"
199 + sig_trans.content_in.to_string()
200 + "\n-----END PKCS7-----\n";
201
202 if (debug_level >= 3)
203 {
204 OPENVPN_LOG("IDENT\n"
205 << ident);
206 OPENVPN_LOG("SIG\n"
207 << sig);
208 }
209
210 // verify signature on identity document
211 {
212 std::list<OpenSSLPKI::X509> certs;
213 if (certs_dir.empty())
214 certs.emplace_back(awscert(), "AWS Cert");
215 else
216 {
217 enum_dir(certs_dir, [&certs, certs_dir = certs_dir](const std::string &file)
218 { certs.emplace_back(read_text(certs_dir + "/" + file), "AWS Cert"); });
219 }
220 OpenSSLSign::verify_pkcs7(certs, sig, ident);
221 }
222
223 // parse the identity document (JSON)
224 {
225 const std::string title = "identity-document";
226 const Json::Value root = json::parse(ident, title);
227 info.region = json::get_string(root, "region", title);
228 info.az = json::get_string(root, "availabilityZone", title);
229 info.instanceId = json::get_string(root, "instanceId", title);
230 info.privateIp = json::get_string(root, "privateIp", title);
231 }
232
234 {
235 WS::ClientSet::Transaction &pc_trans = *lts.transactions.at(2);
236 if (pc_trans.request_status_success())
237 {
238 const std::string pc = pc_trans.content_in.to_string();
240 }
241 else
242 done("could not fetch AWS product code: " + pc_trans.format_status(lts));
243 }
244
245 if (!role_for_credentials.empty())
246 {
247 WS::ClientSet::Transaction &cred_trans = *lts.transactions.at(lookup_product_code ? 3 : 2);
248 if (cred_trans.request_status_success())
249 {
250 const std::string creds = cred_trans.content_in.to_string();
251 const Json::Value root = json::parse(creds);
252 info.creds.access_key = json::get_string(root, "AccessKeyId");
253 info.creds.secret_key = json::get_string(root, "SecretAccessKey");
254 info.creds.token = json::get_string(root, "Token");
255 done("");
256 }
257 else
258 done("could not fetch role credentials: " + cred_trans.format_status(lts));
259 }
260 else
261 done("");
262 }
263 catch (const std::exception &e)
264 {
265 done(e.what());
266 }
267 }
268
270 {
271 try
272 {
273 // get transaction and check that they succeeded
274 WS::ClientSet::Transaction &token_trans = *lts.transactions.at(0);
275 if (!token_trans.request_status_success())
276 {
277 done("could not fetch AWS session token: " + token_trans.format_status(lts));
278 return;
279 }
280 const std::string token = token_trans.content_in.to_string();
281
282 auto ts = prepare_transaction_set();
283
284 // transaction #1
285 {
286 std::unique_ptr<WS::ClientSet::Transaction> t(new WS::ClientSet::Transaction);
287 t->req.method = "GET";
288 t->req.uri = "/latest/dynamic/instance-identity/document";
289 t->ci.extra_headers.emplace_back("X-aws-ec2-metadata-token: " + token);
290 ts->transactions.push_back(std::move(t));
291 }
292
293 // transaction #2
294 {
295 std::unique_ptr<WS::ClientSet::Transaction> t(new WS::ClientSet::Transaction);
296 t->req.method = "GET";
297 t->req.uri = "/latest/dynamic/instance-identity/pkcs7";
298 t->ci.extra_headers.emplace_back("X-aws-ec2-metadata-token: " + token);
299 ts->transactions.push_back(std::move(t));
300 }
301
302 // transaction #3
304 {
305 std::unique_ptr<WS::ClientSet::Transaction> t(new WS::ClientSet::Transaction);
306 t->req.method = "GET";
307 t->req.uri = "/latest/meta-data/product-codes";
308 t->ci.extra_headers.emplace_back("X-aws-ec2-metadata-token: " + token);
309 ts->transactions.push_back(std::move(t));
310 }
311
312 // transaction #4
313 if (!role_for_credentials.empty())
314 {
315 std::unique_ptr<WS::ClientSet::Transaction> t(new WS::ClientSet::Transaction);
316 t->req.method = "GET";
317 t->req.uri = "/latest/meta-data/iam/security-credentials/" + role_for_credentials;
318 t->ci.extra_headers.emplace_back("X-aws-ec2-metadata-token: " + token);
319 ts->transactions.push_back(std::move(t));
320 }
321
322 // completion handler
323 ts->completion = [self = Ptr(this)](WS::ClientSet::TransactionSet &ts)
324 {
325 self->local_query_complete(ts);
326 };
327
328 // do the request
329 cs->new_request(ts);
330 }
331 catch (const std::exception &e)
332 {
333 done(e.what());
334 }
335 }
336
337 void queue_pc_validation(const std::string &pc)
338 {
339 if (debug_level >= 3)
340 OPENVPN_LOG("PRODUCT CODE: " << pc);
341
342 // SSL flags
343 unsigned int ssl_flags = SSLConst::ENABLE_CLIENT_SNI;
344 if (debug_level >= 1)
345 ssl_flags |= SSLConst::LOG_VERIFY_STATUS;
346
347 // make SSL context using awspc_web_cert() as our CA bundle
348 SSLLib::SSLAPI::Config::Ptr ssl(new SSLLib::SSLAPI::Config);
349 ssl->set_mode(Mode(Mode::CLIENT));
350 ssl->load_ca(awspc_web_cert(), false);
351 ssl->set_local_cert_enabled(false);
352 ssl->set_tls_version_min(TLSVersion::Type::V1_2);
353 ssl->set_remote_cert_tls(KUParse::TLS_WEB_SERVER);
354 ssl->set_flags(ssl_flags);
355 ssl->set_frame(frame);
356 ssl->set_rng(rng);
357
358 // make HTTP context
360 hc->frame = frame;
361 hc->ssl_factory = ssl->new_factory();
362 hc->user_agent = "PG";
363 hc->connect_timeout = 30;
364 hc->general_timeout = 60;
365
366 // make host list
368 "awspc1.openvpn.net",
369 "awspc2.openvpn.net"));
370
371 // make transaction set
373 ts->host.host = hr->next_host();
374 ts->host.port = "443";
375 ts->http_config = hc;
376 ts->error_recovery = hr;
377 ts->max_retries = 5;
378 ts->retry_duration = Time::Duration::seconds(5);
379 ts->debug_level = debug_level;
380
381 // transaction #1
382 {
383 std::unique_ptr<WS::ClientSet::Transaction> t(new WS::ClientSet::Transaction);
384 t->req.uri = "/prod/AwsPC";
385 t->req.method = "POST";
386 t->ci.type = "application/json";
387 t->randomize_resolver_results = true;
388
389 Json::Value root(Json::objectValue);
390 root["region"] = Json::Value(info.region);
391 root["identityIp"] = Json::Value(info.privateIp);
392 root["host"] = Json::Value(openvpn_io::ip::host_name());
393 root["instanceId"] = Json::Value(info.instanceId);
394 root["productCode"] = Json::Value(pc);
395 root["nonce"] = Json::Value(nonce());
396 const std::string jreq = root.toStyledString();
397 t->content_out.push_back(buf_from_string(jreq));
398 awspc_req = std::move(root);
399
400 ts->transactions.push_back(std::move(t));
401
402 if (debug_level >= 3)
403 OPENVPN_LOG("AWSPC REQ\n"
404 << jreq);
405 }
406
407 // completion handler
408 ts->completion = [self = Ptr(this)](WS::ClientSet::TransactionSet &ts)
409 {
410 self->awspc_query_complete(ts);
411 };
412
413 // do the request
414 cs->new_request(ts);
415 }
416
418 {
419 try
420 {
421 const std::string title = "awspc-reply";
422
423 // get transactions and check that they succeeded
424 WS::ClientSet::Transaction &trans = *ats.transactions.at(0);
425 if (!trans.request_status_success())
426 {
427 done("awspc server error: " + trans.format_status(ats));
428 return;
429 }
430
431 // check content-type
432 if (trans.reply.headers.get_value_trim("content-type") != "application/json")
433 {
434 done("expected application/json reply from awspc server");
435 return;
436 }
437
438 // parse JSON reply
439 const std::string jtxt = trans.content_in.to_string();
440 const Json::Value root = json::parse(jtxt, title);
441 if (debug_level >= 3)
442 OPENVPN_LOG("AWSPC REPLY\n"
443 << root.toStyledString());
444
445 // check for errors
446 if (json::exists(root, "errorMessage"))
447 {
448 const std::string em = json::get_string(root, "errorMessage", title);
449 const std::string et = json::get_string_optional(root, "errorType", "unspecified-error", title);
450 done(et + " : " + em);
451 return;
452 }
453
454 // verify consistency of region, instanceId, productCode, and nonce
456 {
457 done("awspc request/reply consistency");
458 return;
459 }
460
461 // verify reply signature
462 {
463 const std::string line_to_sign = to_string_sig(root);
464 if (debug_level >= 3)
465 OPENVPN_LOG("LINE TO SIGN: " << line_to_sign);
466 const std::string sig = json::get_string(root, "signature", title);
467 const OpenSSLPKI::X509 cert(awspc_signing_cert(), "awspc-cert");
468 OpenSSLSign::verify(cert, sig, line_to_sign, "sha256");
469 }
470
471 // get concurrent connections
472 info.concurrentConnections = json::get_int(root, "concurrentConnections", title);
473 done("");
474 }
475 catch (const std::exception &e)
476 {
477 done(e.what());
478 }
479 }
480
481 bool awspc_req_verify_consistency(const Json::Value &reply,
482 const std::string &key) const
483 {
484 return json::get_string(reply, key, "awspc-verify-reply") == json::get_string(awspc_req, key, "awspc-verify-request");
485 }
486
487 bool awspc_req_verify_consistency(const Json::Value &reply) const
488 {
489 return awspc_req_verify_consistency(reply, "region")
490 && awspc_req_verify_consistency(reply, "instanceId")
491 && awspc_req_verify_consistency(reply, "productCode")
492 && awspc_req_verify_consistency(reply, "nonce");
493 }
494
495 static std::string to_string_sig(const Json::Value &reply)
496 {
497 const std::string title = "to-string-sig";
498 return json::get_string(reply, "region", title)
499 + '/' + json::get_string(reply, "instanceId", title)
500 + '/' + json::get_string(reply, "productCode", title)
501 + '/' + json::get_string(reply, "nonce", title)
502 + '/' + std::to_string(json::get_int(reply, "concurrentConnections", title));
503 }
504
505 std::string nonce() const
506 {
507 unsigned char data[16];
508 rng->rand_fill(data);
509 return render_hex(data, sizeof(data));
510 }
511
512 // The AWS cert for PKCS#7 validation of AWS identity document
513 static std::string awscert()
514 {
515 return std::string(
516 "-----BEGIN CERTIFICATE-----\n"
517 "MIIC7TCCAq0CCQCWukjZ5V4aZzAJBgcqhkjOOAQDMFwxCzAJBgNVBAYTAlVTMRkw\n"
518 "FwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYD\n"
519 "VQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAeFw0xMjAxMDUxMjU2MTJaFw0z\n"
520 "ODAxMDUxMjU2MTJaMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9u\n"
521 "IFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNl\n"
522 "cnZpY2VzIExMQzCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQCjkvcS2bb1VQ4yt/5e\n"
523 "ih5OO6kK/n1Lzllr7D8ZwtQP8fOEpp5E2ng+D6Ud1Z1gYipr58Kj3nssSNpI6bX3\n"
524 "VyIQzK7wLclnd/YozqNNmgIyZecN7EglK9ITHJLP+x8FtUpt3QbyYXJdmVMegN6P\n"
525 "hviYt5JH/nYl4hh3Pa1HJdskgQIVALVJ3ER11+Ko4tP6nwvHwh6+ERYRAoGBAI1j\n"
526 "k+tkqMVHuAFcvAGKocTgsjJem6/5qomzJuKDmbJNu9Qxw3rAotXau8Qe+MBcJl/U\n"
527 "hhy1KHVpCGl9fueQ2s6IL0CaO/buycU1CiYQk40KNHCcHfNiZbdlx1E9rpUp7bnF\n"
528 "lRa2v1ntMX3caRVDdbtPEWmdxSCYsYFDk4mZrOLBA4GEAAKBgEbmeve5f8LIE/Gf\n"
529 "MNmP9CM5eovQOGx5ho8WqD+aTebs+k2tn92BBPqeZqpWRa5P/+jrdKml1qx4llHW\n"
530 "MXrs3IgIb6+hUIB+S8dz8/mmO0bpr76RoZVCXYab2CZedFut7qc3WUH9+EUAH5mw\n"
531 "vSeDCOUMYQR7R9LINYwouHIziqQYMAkGByqGSM44BAMDLwAwLAIUWXBlk40xTwSw\n"
532 "7HX32MxXYruse9ACFBNGmdX2ZBrVNGrN9N2f6ROk0k9K\n"
533 "-----END CERTIFICATE-----\n");
534 }
535
536 // The OpenVPN Tech. lambda web cert
537 static std::string awspc_web_cert()
538 {
539 // Go Daddy Root Certificate Authority - G2
540 return std::string(
541 "-----BEGIN CERTIFICATE-----\n"
542 "MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT\n"
543 "B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu\n"
544 "MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5\n"
545 "MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6\n"
546 "b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G\n"
547 "A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI\n"
548 "hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq\n"
549 "9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD\n"
550 "+qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd\n"
551 "fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl\n"
552 "NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC\n"
553 "MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9\n"
554 "BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac\n"
555 "vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r\n"
556 "5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV\n"
557 "N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO\n"
558 "LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1\n"
559 "-----END CERTIFICATE-----\n");
560 }
561
562 // The OpenVPN Tech. lambda response signing cert
563 static std::string awspc_signing_cert()
564 {
565 return std::string(
566 "-----BEGIN CERTIFICATE-----\n"
567 "MIIDSDCCAjCgAwIBAgIQYadxADonNbu3mPeXR0yYVTANBgkqhkiG9w0BAQsFADAW\n"
568 "MRQwEgYDVQQDEwtBV1MgUEMgUm9vdDAeFw0xNjAzMDExOTU2NTZaFw0yNjAyMjcx\n"
569 "OTU2NTZaMBAxDjAMBgNVBAMTBWF3c3BjMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n"
570 "MIIBCgKCAQEA0ggZoYroOMwDHKCngVOdUKiF6y65LDWmbAwZVqwVI7WYpvOELV34\n"
571 "04ZYtSqPq6IoGFuH6zl0P5rCi674T0oBPSUTmlLwLks+1zrGznboApkr67Mf2dCd\n"
572 "snlyaNPuwrjWHJBa6Pi9dv/YMoJgDxOxk9mslAlcl5xOFgXbfSj1pAA0KVzwwbzz\n"
573 "dnznJL67wCnuiAeqBxbkyarfOL414tepsI24kHoAddAVDdhWQ2WkhrT/vK2IRdGZ\n"
574 "kU5hAAz/qPKkJxebw5uc+cL2TBii2r0Hvg7tEXI9eIEWeoghftsE5YEuaQHP4EVL\n"
575 "JU+21OQzz0lT9L2rrvffTR7cF89Nbn2KMQIDAQABo4GXMIGUMAkGA1UdEwQCMAAw\n"
576 "HQYDVR0OBBYEFAMy6uiElCGZVP/wwJeqvXL7QHTSMEYGA1UdIwQ/MD2AFLDKS6Dk\n"
577 "NtTpQoOPxJi+DRS+GD2CoRqkGDAWMRQwEgYDVQQDEwtBV1MgUEMgUm9vdIIJAOu5\n"
578 "NqrIe040MBMGA1UdJQQMMAoGCCsGAQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG\n"
579 "9w0BAQsFAAOCAQEAsFhhC9wwybTS2yTYiStATbxHWqnHJRrbMBpqX8FJweS1MM/j\n"
580 "pwr1suTllwTHpqXpqgN6SDzdeG2ZKx8pvJr/dlmD9e+cHguIMTo6TcqPv1MPl3MZ\n"
581 "ugOmDPlgmFYwAWBwzujiGR9bgdGfzw+94KK06iO8MrFLtkz9EbeoJol68mi98CEz\n"
582 "kmOb2BM6tVzkvB9fIYyNkW66ZJs2gXwb6RZTyE9HMMGR67nWKYo9SxpB6f+6hlyU\n"
583 "q7ptxP2Rwmz0u1pRaZdfHmJFOJnPniB7UmMx/t3ftqYWYDXuobr3LVvg7+33WUk0\n"
584 "HfSdbAEkzzC82UTHj0xVH/uZZt8ORChRxuIWZQ==\n"
585 "-----END CERTIFICATE-----\n");
586 }
587
592 const int debug_level;
594 std::string certs_dir;
595
596 std::function<void(Info info)> completion;
598 Json::Value awspc_req;
599 bool pending = false;
600};
601} // namespace openvpn::AWS
PCQuery(WS::ClientSet::Ptr cs_arg, const std::string &role_for_credentials_arg, const std::string &certs_dir_arg)
Definition awspc.hpp:90
OPENVPN_EXCEPTION(awspc_query_error)
WS::ClientSet::Ptr cs
Definition awspc.hpp:588
void token_query_complete(WS::ClientSet::TransactionSet &lts)
Definition awspc.hpp:269
Json::Value awspc_req
Definition awspc.hpp:598
const bool lookup_product_code
Definition awspc.hpp:591
const int debug_level
Definition awspc.hpp:592
static std::string awspc_signing_cert()
Definition awspc.hpp:563
static std::string awscert()
Definition awspc.hpp:513
void done(std::string error)
Definition awspc.hpp:169
bool awspc_req_verify_consistency(const Json::Value &reply, const std::string &key) const
Definition awspc.hpp:481
PCQuery(WS::ClientSet::Ptr cs_arg, const bool lookup_product_code_arg, const int debug_level_arg)
Definition awspc.hpp:79
void queue_pc_validation(const std::string &pc)
Definition awspc.hpp:337
StrongRandomAPI::Ptr rng
Definition awspc.hpp:589
void local_query_complete(WS::ClientSet::TransactionSet &lts)
Definition awspc.hpp:177
RCPtr< PCQuery > Ptr
Definition awspc.hpp:38
std::string nonce() const
Definition awspc.hpp:505
std::function< void(Info info)> completion
Definition awspc.hpp:596
void awspc_query_complete(WS::ClientSet::TransactionSet &ats)
Definition awspc.hpp:417
static std::string to_string_sig(const Json::Value &reply)
Definition awspc.hpp:495
std::string certs_dir
Definition awspc.hpp:594
bool awspc_req_verify_consistency(const Json::Value &reply) const
Definition awspc.hpp:487
void start(std::function< void(Info info)> completion_arg)
Definition awspc.hpp:122
std::string role_for_credentials
Definition awspc.hpp:593
static std::string awspc_web_cert()
Definition awspc.hpp:537
WS::ClientSet::TransactionSet::Ptr prepare_transaction_set()
Definition awspc.hpp:103
The smart pointer class.
Definition rc.hpp:119
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Definition rc.hpp:912
void rand_fill(T &obj)
Fill a data object with random bytes.
Definition randapi.hpp:75
#define OPENVPN_LOG(args)
void verify(const OpenSSLPKI::X509 &cert, const std::string &sig, const std::string &data, const std::string &digest)
Definition verify.hpp:38
void verify_pkcs7(const std::list< OpenSSLPKI::X509 > &certs, const std::string &sig, const std::string &data)
int get_int(const Json::Value &root, const NAME &name, const TITLE &title)
bool exists(const Json::Value &root, const NAME &name)
std::string get_string_optional(const Json::Value &root, const NAME &name, const std::string &default_value, const TITLE &title)
Json::Value parse(const std::string &str, const TITLE &title)
std::string get_string(const Json::Value &root, const NAME &name, const TITLE &title)
Frame::Ptr frame_init_simple(const size_t payload)
std::string read_text(const std::string &filename, const std::uint64_t max_size=0)
Definition file.hpp:127
bool enum_dir(const std::string &dirname, F func)
Definition enumdir.hpp:33
std::string render_hex(const unsigned char *data, size_t size, const bool caps=false)
Definition hexstr.hpp:135
BufferPtr buf_from_string(const std::string &str)
Definition bufstr.hpp:46
std::string access_key
Definition awscreds.hpp:52
std::string token
Definition awscreds.hpp:54
std::string secret_key
Definition awscreds.hpp:53
std::string to_string() const
Definition awspc.hpp:65
bool instance_data_defined() const
Definition awspc.hpp:59
std::string to_string() const
Definition buflist.hpp:72
std::string get_value_trim(const std::string &key) const
Definition header.hpp:84
HeaderList headers
Definition reply.hpp:59
std::string format_status(const TransactionSet &ts) const
std::string ret