Aktualizr
C++ SOTA Client
bootstrap.cc
1 #include "bootstrap.h"
2 
3 #include <cstdio>
4 #include <fstream>
5 #include <sstream>
6 
7 #include "crypto/crypto.h"
8 #include "logging/logging.h"
9 #include "utilities/utils.h"
10 
11 Bootstrap::Bootstrap(const boost::filesystem::path& provision_path, const std::string& provision_password)
12  : ca_(""), cert_(""), pkey_("") {
13  if (provision_path.empty()) {
14  LOG_ERROR << "Provision path is empty!";
15  throw std::runtime_error("Unable to parse bootstrap (shared) credentials");
16  }
17 
18  std::ifstream as(provision_path.c_str(), std::ios::in | std::ios::binary);
19  if (as.fail()) {
20  LOG_ERROR << "Unable to open provided provisioning archive " << provision_path << ": " << std::strerror(errno);
21  throw std::runtime_error("Unable to parse bootstrap (shared) credentials");
22  }
23 
24  std::string p12_str = Utils::readFileFromArchive(as, "autoprov_credentials.p12");
25  if (p12_str.empty()) {
26  throw std::runtime_error("Unable to parse bootstrap (shared) credentials");
27  }
28 
29  readTlsP12(p12_str, provision_password, pkey_, cert_, ca_);
30 }
31 
32 void Bootstrap::readTlsP12(const std::string& p12_str, const std::string& provision_password, std::string& pkey,
33  std::string& cert, std::string& ca) {
34  StructGuard<BIO> reg_p12(BIO_new_mem_buf(p12_str.c_str(), static_cast<int>(p12_str.size())), BIO_vfree);
35  if (reg_p12 == nullptr) {
36  LOG_ERROR << "Unable to open P12 archive: " << std::strerror(errno);
37  throw std::runtime_error("Unable to parse bootstrap credentials");
38  }
39 
40  if (!Crypto::parseP12(reg_p12.get(), provision_password, &pkey, &cert, &ca)) {
41  LOG_ERROR << "Unable to parse P12 archive";
42  throw std::runtime_error("Unable to parse bootstrap credentials");
43  }
44 }
45 
46 std::string Bootstrap::readServerUrl(const boost::filesystem::path& provision_path) {
47  std::string url;
48  try {
49  std::ifstream as(provision_path.c_str(), std::ios::in | std::ios::binary);
50  if (as.fail()) {
51  LOG_ERROR << "Unable to open provided provisioning archive " << provision_path << ": " << std::strerror(errno);
52  throw std::runtime_error("Unable to parse bootstrap credentials");
53  }
54  url = Utils::readFileFromArchive(as, "autoprov.url", true);
55  } catch (std::runtime_error& exc) {
56  LOG_ERROR << "Unable to read server URL from archive: " << exc.what();
57  url = "";
58  }
59 
60  return url;
61 }
62 
63 std::string Bootstrap::readServerCa(const boost::filesystem::path& provision_path) {
64  std::string server_ca;
65  try {
66  std::ifstream as(provision_path.c_str(), std::ios::in | std::ios::binary);
67  if (as.fail()) {
68  LOG_ERROR << "Unable to open provided provisioning archive " << provision_path << ": " << std::strerror(errno);
69  throw std::runtime_error("Unable to parse bootstrap credentials");
70  }
71  server_ca = Utils::readFileFromArchive(as, "server_ca.pem");
72  } catch (std::runtime_error& exc) {
73  LOG_ERROR << "Unable to read server CA certificate from archive: " << exc.what();
74  return "";
75  }
76 
77  return server_ca;
78 }