Skip to content

Commit

Permalink
Add helper methods
Browse files Browse the repository at this point in the history
Signed-off-by: Raul Metsma <raul@metsma.ee>
  • Loading branch information
metsma committed Feb 26, 2025
1 parent d676c3d commit a7169a3
Show file tree
Hide file tree
Showing 17 changed files with 154 additions and 91 deletions.
6 changes: 3 additions & 3 deletions cdoc/CDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ static constexpr int n_results = sizeof(results) / sizeof(Result);

std::string
getErrorStr(int64_t code) {
for (auto& r : results) {
for (const auto& r : results) {
if (r.code == code) return std::string(r.message);
}
return FORMAT("Unknown result code {}", code);
Expand All @@ -72,15 +72,15 @@ getVersion()
}

bool
libcdoc::Configuration::getBoolean(const std::string_view& param, bool def_val)
libcdoc::Configuration::getBoolean(std::string_view param, bool def_val) const
{
std::string val = getValue(param);
if (val.empty()) return def_val;
return val == "true";
}

int
libcdoc::Configuration::getInt(const std::string_view& param, int def_val)
libcdoc::Configuration::getInt(std::string_view param, int def_val) const
{
std::string val = getValue(param);
if (val.empty()) return def_val;
Expand Down
23 changes: 13 additions & 10 deletions cdoc/CDoc1Reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,20 @@ CDoc1Reader::getLockForCert(const std::vector<uint8_t>& cert)
const libcdoc::Lock *ll = d->locks.at(i);
if (!ll->isCDoc1()) continue;
std::vector<uint8_t> l_cert = ll->getBytes(libcdoc::Lock::Params::CERT);
if(l_cert != cc.cert || ll->encrypted_fmk.empty()) continue;
if(cc.getAlgorithm() == libcdoc::Certificate::RSA) {
if (ll->getString(libcdoc::Lock::Params::METHOD) == libcdoc::Crypto::RSA_MTH) {
if(l_cert != cert || ll->encrypted_fmk.empty()) continue;
switch(cc.getAlgorithm()) {
case libcdoc::Certificate::RSA:
if (ll->getString(libcdoc::Lock::Params::METHOD) == libcdoc::Crypto::RSA_MTH) {
return i;
}
} else if(cc.getAlgorithm() == libcdoc::Certificate::ECC) {
std::vector<uint8_t> eph_key = ll->getBytes(libcdoc::Lock::Params::KEY_MATERIAL);
if(!eph_key.empty() && SUPPORTED_KWAES.contains(ll->getString(libcdoc::Lock::Params::METHOD))) {
}
break;
case libcdoc::Certificate::ECC:
if(std::vector<uint8_t> eph_key = ll->getBytes(libcdoc::Lock::Params::KEY_MATERIAL);
!eph_key.empty() && SUPPORTED_KWAES.contains(ll->getString(libcdoc::Lock::Params::METHOD))) {
return i;
}
} else {
}
break;
default:
return libcdoc::NOT_SUPPORTED;
}
}
Expand Down Expand Up @@ -131,7 +134,7 @@ CDoc1Reader::getFMK(std::vector<uint8_t>& fmk, unsigned int lock_idx)
}
} else {
std::vector<uint8_t> eph_key = lock->getBytes(libcdoc::Lock::Params::KEY_MATERIAL);
int result = crypto->deriveConcatKDF(decrypted_key, eph_key, lock->getString(libcdoc::Lock::Params::CONCAT_DIGEST),
int result = crypto->deriveConcatKDF(decrypted_key, eph_key, std::string(lock->getString(libcdoc::Lock::Params::CONCAT_DIGEST)),
lock->getBytes(libcdoc::Lock::Params::ALGORITHM_ID),
lock->getBytes(libcdoc::Lock::Params::PARTY_UINFO),
lock->getBytes(libcdoc::Lock::Params::PARTY_VINFO),
Expand Down
12 changes: 6 additions & 6 deletions cdoc/CDoc2Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
builder.CreateString(rcpt.label),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
fb_rcpts.push_back(record);
fb_rcpts.push_back(std::move(record));
} else {
auto capsule = cdoc20::recipients::CreateRSAPublicKeyCapsule(builder,
builder.CreateVector(rcpt.rcpt_key),
Expand All @@ -233,7 +233,7 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
builder.CreateString(rcpt.label),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
fb_rcpts.push_back(record);
fb_rcpts.push_back(std::move(record));
}
} else {
auto publicKey = libcdoc::Crypto::fromECPublicKeyDer(rcpt.rcpt_key, NID_secp384r1);
Expand Down Expand Up @@ -308,7 +308,7 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
builder.CreateString(rcpt.label),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
fb_rcpts.push_back(record);
fb_rcpts.push_back(std::move(record));
} else {
auto capsule = cdoc20::recipients::CreateECCPublicKeyCapsule(builder,
cdoc20::recipients::EllipticCurve::secp384r1,
Expand All @@ -320,7 +320,7 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
builder.CreateString(rcpt.label),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
fb_rcpts.push_back(record);
fb_rcpts.push_back(std::move(record));
}
}
} else if (rcpt.isSymmetric()) {
Expand Down Expand Up @@ -371,7 +371,7 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
builder.CreateString(rcpt.label),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
fb_rcpts.push_back(offs);
fb_rcpts.push_back(std::move(offs));
} else {
auto capsule = cdoc20::recipients::CreateSymmetricKeyCapsule(builder,
builder.CreateVector(salt));
Expand All @@ -381,7 +381,7 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
builder.CreateString(rcpt.label),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
fb_rcpts.push_back(offs);
fb_rcpts.push_back(std::move(offs));
}
} else {
setLastError("Invalid recipient type");
Expand Down
14 changes: 5 additions & 9 deletions cdoc/CDocCipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "CDocCipher.h"
#include "CDocReader.h"
#include "CDoc2.h"
#include "Certificate.h"
#include "ILogger.h"
#include "Lock.h"
#include "NetworkBackend.h"
Expand Down Expand Up @@ -214,15 +213,15 @@ int CDocCipher::Encrypt(ToolConf& conf, RecipientInfoVector& recipients, const v
switch (rcpt.type)
{
case RcptInfo::Type::PASSWORD:
label = std::move(Recipient::BuildLabelPassword(CDoc2::KEYLABELVERSION, rcpt.label.empty() ? GenerateRandomSequence() : rcpt.label));
label = Recipient::BuildLabelPassword(CDoc2::KEYLABELVERSION, rcpt.label.empty() ? GenerateRandomSequence() : rcpt.label);
break;

case RcptInfo::Type::SKEY:
label = std::move(Recipient::BuildLabelSymmetricKey(CDoc2::KEYLABELVERSION, rcpt.label.empty() ? GenerateRandomSequence() : rcpt.label, rcpt.key_file_name));
label = Recipient::BuildLabelSymmetricKey(CDoc2::KEYLABELVERSION, rcpt.label.empty() ? GenerateRandomSequence() : rcpt.label, rcpt.key_file_name);
break;

case RcptInfo::Type::PKEY:
label = std::move(Recipient::BuildLabelPublicKey(CDoc2::KEYLABELVERSION, rcpt.key_file_name));
label = Recipient::BuildLabelPublicKey(CDoc2::KEYLABELVERSION, rcpt.key_file_name);
break;

case RcptInfo::Type::P11_PKI:
Expand All @@ -236,16 +235,13 @@ int CDocCipher::Encrypt(ToolConf& conf, RecipientInfoVector& recipients, const v
LOG_ERROR("Certificate reading from SC card failed. Key label: {}", rcpt.key_label);
return 1;
}
Certificate cert(cert_bytes);
label = std::move(Recipient::BuildLabelEID(CDoc2::KEYLABELVERSION, Recipient::getEIDType(cert.policies()), cert.getCommonName(), cert.getSerialNumber(), cert.getSurname(), cert.getGivenName()));
label = Recipient::BuildLabelEID(cert_bytes);
break;
}

case RcptInfo::Type::CERT:
{
Certificate cert(rcpt.cert);
vector<uint8_t> digest = cert.getDigest();
label = std::move(Recipient::BuildLabelCertificate(CDoc2::KEYLABELVERSION, rcpt.key_file_name, cert.getCommonName(), digest));
label = Recipient::BuildLabelCertificate(rcpt.key_file_name, rcpt.cert);
break;
}
case RcptInfo::Type::P11_SYMMETRIC:
Expand Down
33 changes: 17 additions & 16 deletions cdoc/Certificate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@

namespace libcdoc {

Certificate::Certificate(const std::vector<uint8_t>& cert) noexcept
: cert(Crypto::toX509(cert))
{
}

static std::string
getName(const std::vector<uint8_t>& cert, int NID)
getName(const unique_free_t<X509>& cert, int NID)
{
std::string cn;
auto peerCert = Crypto::toX509(cert);
if(!peerCert)
if(!cert)
return cn;
X509_NAME *name = X509_get_subject_name(peerCert.get());
X509_NAME *name = X509_get_subject_name(cert.get());
if(!name)
return cn;
int pos = X509_NAME_get_index_by_NID(name, NID, -1);
Expand Down Expand Up @@ -59,7 +63,7 @@ Certificate::getGivenName() const
}

std::string
Certificate::getSurname() const
Certificate::getSurName() const
{
return getName(cert, NID_surname);
}
Expand All @@ -78,12 +82,11 @@ Certificate::policies() const
constexpr int PolicyBufferLen = 50;
std::vector<std::string> list;

auto peerCert = Crypto::toX509(cert);
if(!peerCert)
if(!cert)
return list;

auto cp = make_unique_cast<CERTIFICATEPOLICIES_free>(X509_get_ext_d2i(
peerCert.get(), NID_certificate_policies, nullptr, nullptr));
cert.get(), NID_certificate_policies, nullptr, nullptr));
if(!cp)
return list;

Expand All @@ -102,36 +105,34 @@ Certificate::policies() const
std::vector<uint8_t>
Certificate::getPublicKey() const
{
if(auto x509 = Crypto::toX509(cert))
return Crypto::toPublicKeyDer(X509_get0_pubkey(x509.get()));
if(cert)
return Crypto::toPublicKeyDer(X509_get0_pubkey(cert.get()));
return {};
}

Certificate::Algorithm
Certificate::getAlgorithm() const
{
auto x509 = Crypto::toX509(cert);
if(!x509)
if(!cert)
return {};

EVP_PKEY *pkey = X509_get0_pubkey(x509.get());
EVP_PKEY *pkey = X509_get0_pubkey(cert.get());
int alg = EVP_PKEY_get_base_id(pkey);

return (alg == EVP_PKEY_RSA) ? Algorithm::RSA : Algorithm::ECC;
}

std::vector<uint8_t> Certificate::getDigest()
{
auto x509 = Crypto::toX509(cert);
if(!x509)
if(!cert)
return {};

const EVP_MD* digest_type = EVP_get_digestbyname("sha1");

std::vector<uint8_t> digest(EVP_MAX_MD_SIZE);
unsigned int digest_len = 0;

if (X509_digest(x509.get(), digest_type, digest.data(), &digest_len))
if (X509_digest(cert.get(), digest_type, digest.data(), &digest_len))
{
digest.resize(digest_len);
}
Expand Down
12 changes: 8 additions & 4 deletions cdoc/Certificate.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,29 @@

#include "Exports.h"

#include "utils/memory.h"

#include <string>
#include <vector>

using X509 = struct x509_st;

namespace libcdoc {

class CDOC_EXPORT Certificate {
class Certificate {
public:
enum Algorithm {
RSA,
ECC
};

std::vector<uint8_t> cert;
unique_free_t<X509> cert;

Certificate(const std::vector<uint8_t>& cert) : cert(cert) {}
explicit Certificate(const std::vector<uint8_t>& cert) noexcept;

std::string getCommonName() const;
std::string getGivenName() const;
std::string getSurname() const;
std::string getSurName() const;
std::string getSerialNumber() const;

std::vector<std::string> policies() const;
Expand Down
10 changes: 5 additions & 5 deletions cdoc/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct CDOC_EXPORT Configuration {
virtual ~Configuration() noexcept = default;
Configuration(const Configuration&) = delete;
Configuration& operator=(const Configuration&) = delete;
CDOC_ENABLE_MOVE(Configuration);
CDOC_DISABLE_MOVE(Configuration);

/**
* @brief get a value of configuration parameter
Expand All @@ -57,28 +57,28 @@ struct CDOC_EXPORT Configuration {
* @param param the parameter name.
* @return a string value or empty string if parameter is not defined.
*/
virtual std::string getValue(const std::string_view& domain, const std::string_view& param) {return {};}
virtual std::string getValue(std::string_view domain, std::string_view param) const {return {};}

/**
* @brief get a value of configuration parameter from default domain
* @param param the parameter name.
* @return a string value or empty string if parameter is not defined.
*/
std::string getValue(const std::string_view& param) {return getValue({}, param);}
std::string getValue(std::string_view param) const {return getValue({}, param);}
/**
* @brief get boolean value of configuration parameter from default domain
* @param param the parameter name
* @param def_val the default value to return if parameter is not set
* @return the parameter value
*/
bool getBoolean(const std::string_view& param, bool def_val = false);
bool getBoolean(std::string_view param, bool def_val = false) const;
/**
* @brief get integer value of configuration parameter from default domain
* @param param the parameter name
* @param def_val the default value to return if parameter is not set
* @return the key value
*/
int getInt(const std::string_view& param, int def_val = 0);
int getInt(std::string_view param, int def_val = 0) const;

#if LIBCDOC_TESTING
virtual int64_t test(std::vector<uint8_t>& dst);
Expand Down
2 changes: 1 addition & 1 deletion cdoc/CryptoBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct CDOC_EXPORT CryptoBackend {
virtual ~CryptoBackend() noexcept = default;
CryptoBackend(const CryptoBackend&) = delete;
CryptoBackend& operator=(const CryptoBackend&) = delete;
CDOC_ENABLE_MOVE(CryptoBackend);
CDOC_DISABLE_MOVE(CryptoBackend);

virtual std::string getLastErrorStr(int code) const;

Expand Down
6 changes: 3 additions & 3 deletions cdoc/Exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
#define STDCALL
#endif

#define CDOC_ENABLE_MOVE(Class) \
Class(Class&&) noexcept = default; \
Class& operator=(Class&&) noexcept = default;
#define CDOC_DISABLE_MOVE(Class) \
Class(Class&&) noexcept = delete; \
Class& operator=(Class&&) noexcept = delete;

#endif // EXPOORTS_H
Loading

0 comments on commit a7169a3

Please sign in to comment.