Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace crypto {
using asn1_string_t = util::safe_ptr<ASN1_STRING, ASN1_STRING_free>;
using x509_name_t = util::safe_ptr<X509_NAME, &X509_NAME_free>;

cert_chain_t::cert_chain_t():
_certs {},
Expand Down Expand Up @@ -391,7 +392,10 @@ namespace crypto {
const ASN1_BIT_STRING *asn1 = nullptr;
X509_get0_signature(&asn1, nullptr, x.get());

return {(const char *) asn1->data, (std::size_t) asn1->length};
return {
reinterpret_cast<const char *>(ASN1_STRING_get0_data(asn1)),
static_cast<std::size_t>(ASN1_STRING_length(asn1))
};
}

std::string rand(std::size_t bytes) {
Expand Down Expand Up @@ -461,10 +465,11 @@ namespace crypto {

X509_set_pubkey(x509.get(), pkey.get());

auto name = X509_get_subject_name(x509.get());
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const std::uint8_t *) cn.data(), (int) cn.size(), -1, 0);
x509_name_t name {X509_NAME_new()};
X509_NAME_add_entry_by_txt(name.get(), "CN", MBSTRING_ASC, reinterpret_cast<const std::uint8_t *>(cn.data()), (int) cn.size(), -1, 0);

X509_set_issuer_name(x509.get(), name);
X509_set_subject_name(x509.get(), name.get());
X509_set_issuer_name(x509.get(), name.get());
X509_sign(x509.get(), pkey.get(), EVP_sha256());

return {pem(x509), pem(pkey)};
Expand Down
50 changes: 50 additions & 0 deletions tests/unit/test_crypto.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* @file tests/unit/test_crypto.cpp
* @brief Test src/crypto.*.
*/
// test imports
#include "../tests_common.h"

// lib imports
#include <openssl/x509.h>

// local imports
#include <src/crypto.h>

TEST(CryptoTest, GeneratedCredentialsExposeSubjectAndVerifySignatures) {
constexpr std::string_view common_name = "Sunshine Test Host";
constexpr std::string_view payload = "payload";

auto creds = crypto::gen_creds(common_name, 2048);
ASSERT_FALSE(creds.x509.empty());
ASSERT_FALSE(creds.pkey.empty());

auto cert = crypto::x509(creds.x509);
auto pkey = crypto::pkey(creds.pkey);
ASSERT_NE(cert.get(), nullptr);
ASSERT_NE(pkey.get(), nullptr);

const auto subject = X509_get_subject_name(cert.get());
ASSERT_NE(subject, nullptr);

const auto common_name_index = X509_NAME_get_index_by_NID(subject, NID_commonName, -1);
ASSERT_GE(common_name_index, 0);

const auto common_name_entry = X509_NAME_get_entry(subject, common_name_index);
ASSERT_NE(common_name_entry, nullptr);

const auto common_name_data = X509_NAME_ENTRY_get_data(common_name_entry);
ASSERT_NE(common_name_data, nullptr);

const std::string_view parsed_common_name {
reinterpret_cast<const char *>(ASN1_STRING_get0_data(common_name_data)),
static_cast<std::size_t>(ASN1_STRING_length(common_name_data))
};
ASSERT_EQ(parsed_common_name, common_name);

ASSERT_FALSE(crypto::signature(cert).empty());

const auto signature = crypto::sign256(pkey, payload);
ASSERT_FALSE(signature.empty());
ASSERT_TRUE(crypto::verify256(cert, payload, {reinterpret_cast<const char *>(signature.data()), signature.size()}));
}
Loading