Skip to content

Commit

Permalink
wip: sign cert
Browse files Browse the repository at this point in the history
  • Loading branch information
mereacre committed Jan 12, 2024
1 parent e8ca7a1 commit 744ce79
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 10 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
"cms.h": "c",
"*.inc": "cpp",
"array.h": "c",
"log.h": "c"
"log.h": "c",
"complex": "cpp",
"unordered_set": "cpp"
}
}
38 changes: 31 additions & 7 deletions src/brski/brski.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ static void show_help(const char *name) {
}
std::fprintf(stdout, "\nOptions:\n");
std::fprintf(stdout, "\t-c filename\t Path to the config file\n");
std::fprintf(stdout, "\t-i filename\t Path to the imported file\n");
std::fprintf(stdout, "\t-o filename\t Path to the exported file\n");
std::fprintf(
stdout,
Expand Down Expand Up @@ -123,7 +124,7 @@ static CommandId get_command_id(const std::string &command_label) {
}

static void process_options(int argc, char *const argv[], int &verbose,
std::string &config_filename,
std::string &config_filename, std::string &in_filename,
std::string &out_filename, CommandId &command_id) {
int opt;

Expand All @@ -138,6 +139,9 @@ static void process_options(int argc, char *const argv[], int &verbose,
case 'c':
config_filename.assign(optarg);
break;
case 'i':
in_filename.assign(optarg);
break;
case 'o':
out_filename.assign(optarg);
break;
Expand Down Expand Up @@ -182,13 +186,20 @@ struct BrskiConfig : public brski_config {
virtual ~BrskiConfig() { free_config_content(this); }
};

void print_cert(const char *cert)
{
std::fprintf(stdout, "-----BEGIN CERTIFICATE-----\n");
std::fprintf(stdout, "%s\n", cert);
std::fprintf(stdout, "-----END CERTIFICATE-----\n");
}

int main(int argc, char *argv[]) {
int verbose = 0;
std::string config_filename, out_filename;
std::string config_filename, in_filename, out_filename;
CommandId command_id;

process_options(argc, argv, verbose, config_filename, out_filename,
command_id);
process_options(argc, argv, verbose, config_filename,
in_filename, out_filename, command_id);

log_set_lock(log_lock_fun);

Expand Down Expand Up @@ -227,15 +238,28 @@ int main(int argc, char *argv[]) {
case CommandId::COMMAND_PLEDGE_REQUEST: {
log_info("Pledge voucher request to %s:%d",
config.rconf.bind_address, config.rconf.port);
std::string response;
std::string cert;
if (post_voucher_pledge_request(&config.pconf, &config.rconf,
&config.mconf, response) < 0) {
&config.mconf, cert) < 0) {
log_error("post_voucher_pledge_request fail");
return EXIT_FAILURE;
}
print_cert(cert.c_str());
break;
}

case CommandId::COMMAND_SIGN_CERT: {
log_info("Sign cert %s:%d", config.rconf.bind_address, config.rconf.port);
std::string cert;
if (post_sign_cert(&config.pconf, &config.rconf,
&config.mconf, in_filename.c_str(), cert) < 0) {
log_error("post_voucher_pledge_request fail");
return EXIT_FAILURE;
}
std::fprintf(stdout, "%s\n", response.c_str());
print_cert(cert.c_str());
break;
}

case CommandId::COMMAND_START_REGISTRAR:
if (registrar_start(&config.rconf, &config.mconf, &config.pconf,
&rcontext) < 0) {
Expand Down
26 changes: 26 additions & 0 deletions src/brski/http/httplib_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,29 @@ int httplib_post_request(const std::string &client_key_path,
return -1;
}
}

int httplib_post_request_ca(const std::string &client_key_path,
const std::string &client_cert_path,
const std::string &ca,
const std::string &host, int port,
const std::string &path,
const std::string &body,
const std::string &content_type,
std::string &response) {

httplib::SSLClient cli(host, port, client_cert_path, client_key_path);

cli.enable_server_certificate_verification(true);
cli.load_ca_cert_store(ca.c_str(), ca.length());

log_info("Post request to %s:%d%s", host.c_str(), port, path.c_str());
if (httplib::Result res = cli.Post(path, body, content_type)) {
response = res->body;
return res->status;
} else {
std::string err = to_string(res.error());
log_error("httplib::Client fail with \"%s\"", err.c_str());

return -1;
}
}
23 changes: 23 additions & 0 deletions src/brski/http/httplib_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,27 @@ int httplib_post_request(const std::string &client_key_path,
const std::string &body,
const std::string &content_type,
struct HttpResponse &http_res);

/**
* @brief Sends a POST request to an endpoint
*
* @param[in] client_key_path The https client key path
* @param[in] client_cert_path The https client cert path
* @param[in] ca The certificate authority string (PEM format)
* @param[in] host The https server host name
* @param[in] port The https server port name
* @param[in] path The endpoint route path string
* @param[in] body The request body string
* @param[in] content_type The content typ string
* @param[out] response The output response string
* @return int the status code on success, -1 on failure
*/
int httplib_post_request_ca(const std::string &client_key_path,
const std::string &client_cert_path,
const std::string &ca,
const std::string &host, int port,
const std::string &path,
const std::string &body,
const std::string &content_type,
std::string &response);
#endif
18 changes: 18 additions & 0 deletions src/brski/http/https_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@ int https_post_request(const std::string &client_key_path,
#endif
}

int https_post_request_ca(const std::string &client_key_path,
const std::string &client_cert_path,
const std::string &ca,
const std::string &host, int port,
const std::string &path,
const std::string &body,
const std::string &content_type,
std::string &response)
{
#ifdef WITH_CPPHTTPLIB_LIB
return httplib_post_request_ca(client_key_path, client_cert_path, ca,
host, port, path, body, content_type, response);
#else
log_error("No https client defined");
return -1;
#endif
}

std::string get_https_address(const char *bind_address, int port) {
return "https://" + std::string(bind_address) + ":" + std::to_string(port);
}
23 changes: 23 additions & 0 deletions src/brski/http/https_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,29 @@ int https_post_request(const std::string &client_key_path,
const std::string &body, const std::string &content_type,
struct HttpResponse &http_res);

/**
* @brief Sends a POST request to an endpoint
*
* @param[in] client_key_path The https client key path
* @param[in] client_cert_path The https client cert path
* @param[in] ca The certificate authority string (PEM format)
* @param[in] host The https server host name
* @param[in] port The https server port name
* @param[in] path The endpoint route path string
* @param[in] body The request body string
* @param[in] content_type The content typ string
* @param[out] response The output response string
* @return int the status code on success, -1 on failure
*/
int https_post_request_ca(const std::string &client_key_path,
const std::string &client_cert_path,
const std::string &ca,
const std::string &host, int port,
const std::string &path,
const std::string &body,
const std::string &content_type,
std::string &response);

/**
* @brief Returns the full address of a HTTPS server
*
Expand Down
42 changes: 42 additions & 0 deletions src/brski/pledge/pledge_request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,45 @@ int post_voucher_pledge_request(struct pledge_config *pconf,
free(pinned_domain_cert_base64);
return -1;
}

std::string create_cert_string(const std::string &cert)
{
std::string out = "-----BEGIN CERTIFICATE-----\n";
out += out + "\n";
out += "\n-----END CERTIFICATE-----\n";

return out;
}

int post_sign_cert(struct pledge_config *pconf,
struct registrar_config *rconf,
struct masa_config *mconf,
const char *cert_to_sign_path,
std::string &cert_out)
{
std::string pinned_cert, response, ca, body;

if (post_voucher_pledge_request(pconf, rconf, mconf, pinned_cert) < 0) {
log_error("post_voucher_pledge_request fail");
return -1;
}

ca = create_cert_string(pinned_cert);

std::string path = PATH_BRSKI_SIGNCERT;
std::string content_type = "application/voucher-cms+json";

struct BinaryArray *sign_cert = NULL;
sign_cert = file_to_x509buf(cert_to_sign_path);
if (sign_cert == NULL) {
log_error("file_to_x509buf fail");
return -1;
}

int status = https_post_request_ca(pconf->idevid_key_path, pconf->idevid_cert_path,
ca, rconf->bind_address, rconf->port, path, body, content_type, response);

free_binary_array(sign_cert);
cert_out = response;
return 0;
}
18 changes: 18 additions & 0 deletions src/brski/pledge/pledge_request.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,22 @@ int post_voucher_pledge_request(struct pledge_config *pconf,
struct registrar_config *rconf,
struct masa_config *mconf,
std::string &response);

/**
* @brief Signs a certificate after sending a pledge voucher POST request to the registrar
*
* @param[in] pconf The pledge configuration structure
* @param[in] rconf The registrar configuration structure
* @param[in] mconf The masa configuration structure
* @param[in] cert_to_sign_path The path of the certificate to sing
* @param[out] cert_out The signed certificate in DER format, encoded as
* base64.
* @return int 0 on success, -1 on failure
*/
int post_sign_cert(struct pledge_config *pconf,
struct registrar_config *rconf,
struct masa_config *mconf,
const char *cert_to_sign_path,
std::string &response);

#endif
5 changes: 3 additions & 2 deletions src/brski/registrar/registrar_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,10 @@ int registrar_signcert(const RequestHeader &request_header,
std::string &response, void *context)
{
log_trace("registrar_signcert:");
log_trace("%s", request_body.c_str());
const char *cert_str = request_body.c_str();
log_trace("%s", cert_str);

response.assign("registrar_enrollstatus");
response.assign("registrar_signcert");
response_header["Content-Type"] = "text/plain";
return 200;
}

0 comments on commit 744ce79

Please sign in to comment.