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
26 changes: 13 additions & 13 deletions cdoc/CDoc2Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ createRSACapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc::Recipie
return cdoc20::header::CreateRecipientRecord(builder,
cdoc20::header::Capsule::recipients_RSAPublicKeyCapsule,
capsule.Union(),
builder.CreateString(rcpt.label),
builder.CreateString(rcpt.getLabel({})),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
}

static flatbuffers::Offset<cdoc20::header::RecipientRecord>
createRSAServerCapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc::Recipient& rcpt, const std::string& transaction_id, const std::vector<uint8_t>& xor_key)
createRSAServerCapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc::Recipient& rcpt, const std::string& transaction_id, uint64_t expiry_time, const std::vector<uint8_t>& xor_key)
{
auto rsaKeyServer = cdoc20::recipients::CreateRsaKeyDetails(builder,
builder.CreateVector(rcpt.rcpt_key));
Expand All @@ -123,7 +123,7 @@ createRSAServerCapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc::R
return cdoc20::header::CreateRecipientRecord(builder,
cdoc20::header::Capsule::recipients_KeyServerCapsule,
capsule.Union(),
builder.CreateString(rcpt.label),
builder.CreateString(rcpt.getLabel({{"x-expiry-time", std::to_string(expiry_time)}})),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
}
Expand All @@ -138,13 +138,13 @@ createECCCapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc::Recipie
return cdoc20::header::CreateRecipientRecord(builder,
cdoc20::header::Capsule::recipients_ECCPublicKeyCapsule,
capsule.Union(),
builder.CreateString(rcpt.label),
builder.CreateString(rcpt.getLabel({})),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
}

static flatbuffers::Offset<cdoc20::header::RecipientRecord>
createECCServerCapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc::Recipient& rcpt, const std::string& transaction_id, const std::vector<uint8_t>& xor_key)
createECCServerCapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc::Recipient& rcpt, const std::string& transaction_id, uint64_t expiry_time, const std::vector<uint8_t>& xor_key)
{
auto eccKeyServer = cdoc20::recipients::CreateEccKeyDetails(builder,
cdoc20::recipients::EllipticCurve::secp384r1,
Expand All @@ -157,7 +157,7 @@ createECCServerCapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc::R
return cdoc20::header::CreateRecipientRecord(builder,
cdoc20::header::Capsule::recipients_KeyServerCapsule,
capsule.Union(),
builder.CreateString(rcpt.label),
builder.CreateString(rcpt.getLabel({{"x-expiry-time", std::to_string(expiry_time)}})),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
}
Expand All @@ -170,7 +170,7 @@ createSymmetricKeyCapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc
return cdoc20::header::CreateRecipientRecord(builder,
cdoc20::header::Capsule::recipients_SymmetricKeyCapsule,
capsule.Union(),
builder.CreateString(rcpt.label),
builder.CreateString(rcpt.getLabel({})),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
}
Expand All @@ -186,7 +186,7 @@ createPasswordCapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc::Re
return cdoc20::header::CreateRecipientRecord(builder,
cdoc20::header::Capsule::recipients_PBKDF2Capsule,
capsule.Union(),
builder.CreateString(rcpt.label),
builder.CreateString(rcpt.getLabel({})),
builder.CreateVector(xor_key),
cdoc20::header::FMKEncryptionMethod::XOR);
}
Expand Down Expand Up @@ -272,7 +272,7 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
return libcdoc::CONFIGURATION_ERROR;
}
libcdoc::NetworkBackend::CapsuleInfo cinfo;
int result = network->sendKey(cinfo, send_url, rcpt.rcpt_key, key_material, "RSA");
int result = network->sendKey(cinfo, send_url, rcpt.rcpt_key, key_material, "RSA", rcpt.expiry_ts);
if (result < 0) {
setLastError(network->getLastErrorStr(result));
LOG_ERROR("{}", last_error);
Expand All @@ -282,7 +282,7 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
LOG_DBG("Keyserver Id: {}", rcpt.server_id);
LOG_DBG("Transaction Id: {}", cinfo.transaction_id);

auto record = createRSAServerCapsule(builder, rcpt, cinfo.transaction_id, xor_key);
auto record = createRSAServerCapsule(builder, rcpt, cinfo.transaction_id, cinfo.expiry_time, xor_key);
fb_rcpts.push_back(std::move(record));
} else {
auto record = createRSACapsule(builder, rcpt, key_material, xor_key);
Expand All @@ -307,7 +307,7 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
return libcdoc::CONFIGURATION_ERROR;
}
libcdoc::NetworkBackend::CapsuleInfo cinfo;
int result = network->sendKey(cinfo, send_url, rcpt.rcpt_key, key_material, "ecc_secp384r1");
int result = network->sendKey(cinfo, send_url, rcpt.rcpt_key, key_material, "ecc_secp384r1", rcpt.expiry_ts);
if (result < 0) {
setLastError(network->getLastErrorStr(result));
LOG_ERROR("{}", last_error);
Expand All @@ -317,15 +317,15 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
LOG_DBG("Keyserver Id: {}", rcpt.server_id);
LOG_DBG("Transaction Id: {}", cinfo.transaction_id);

auto record = createECCServerCapsule(builder, rcpt, cinfo.transaction_id, xor_key);
auto record = createECCServerCapsule(builder, rcpt, cinfo.transaction_id, cinfo.expiry_time, xor_key);
fb_rcpts.push_back(std::move(record));
} else {
auto record = createECCCapsule(builder, rcpt, key_material, xor_key);
fb_rcpts.push_back(std::move(record));
}
}
} else if (rcpt.isSymmetric()) {
std::string info_str = libcdoc::CDoc2::getSaltForExpand(rcpt.label);
std::string info_str = libcdoc::CDoc2::getSaltForExpand(rcpt.getLabel({}));
std::vector<uint8_t> kek_pm(libcdoc::CDoc2::KEY_LEN);
std::vector<uint8_t> salt;
int64_t result = crypto->random(salt, libcdoc::CDoc2::KEY_LEN);
Expand Down
61 changes: 7 additions & 54 deletions cdoc/CDocCipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,64 +268,17 @@ fill_recipients_from_rcpt_info(ToolConf& conf, ToolCrypto& crypto, std::vector<l
for (const auto& rcpt : recipients) {
// Generate the labels if needed
string label;
if (conf.gen_label) {
switch (rcpt.type) {
case RcptInfo::Type::PASSWORD:
label = Recipient::BuildLabelPassword(CDoc2::KEYLABELVERSION, rcpt.label.empty() ? GenerateRandomSequence() : rcpt.label);
break;

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

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

case RcptInfo::Type::P11_PKI: {
bool isRsa;
vector<uint8_t> cert_bytes;
ToolPKCS11* p11 = dynamic_cast<ToolPKCS11*>(crypto.p11.get());
int result = p11->getCertificate(cert_bytes, isRsa, rcpt.slot, rcpt.secret, rcpt.key_id, rcpt.key_label);
if (result != libcdoc::OK)
{
LOG_ERROR("Certificate reading from SC card failed. Key label: {}", rcpt.key_label);
return 1;
}
LOG_DBG("Got certificate from P11 module");
label = Recipient::BuildLabelEID(cert_bytes);
break;
}

case RcptInfo::Type::CERT:
{
label = Recipient::BuildLabelCertificate(rcpt.key_file_name, rcpt.cert);
break;
} case RcptInfo::Type::P11_SYMMETRIC:
// TODO: what label should be generated in this case?
break;

default:
LOG_ERROR("Unhandled recipient type {} for generating the lock's label", static_cast<int>(rcpt.type));
break;
}
#ifndef NDEBUG
LOG_DBG("Generated label: {}", label);
#endif
} else {
label = rcpt.label;
}

if (label.empty()) {
LOG_ERROR("No lock label");
return 1;
}
if (!conf.gen_label) label = rcpt.label;

crypto_rcpts[idx++] = rcpt;

Recipient key;
if (rcpt.type == RcptInfo::Type::CERT) {
key = libcdoc::Recipient::makeCertificate(label, rcpt.cert);
if (!conf.servers.empty()) {
key = libcdoc::Recipient::makeServer(label, rcpt.cert, conf.servers[0].ID);
} else {
key = libcdoc::Recipient::makeCertificate(label, rcpt.cert);
}
} else if (rcpt.type == RcptInfo::Type::SKEY) {
key = libcdoc::Recipient::makeSymmetric(label, 0);
LOG_DBG("Creating symmetric key:");
Expand Down Expand Up @@ -766,7 +719,7 @@ void CDocCipher::Locks(const char* file) const
}

// Output the fields with their values
cout << lock_id << ":" << endl;
cout << lock_id << ":" << lock.label << endl;
for (map<string, string>::const_reference pair : parsed_label) {
cout << " " << setw(maxFieldLength + 1) << left << pair.first << ": " << pair.second << endl;
}
Expand Down
2 changes: 2 additions & 0 deletions cdoc/ILogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ class CDOC_EXPORT ILogger
*/
static ILogger* getLogger();

static void setLogger(ILogger *logger);

protected:
/**
* @brief Minimum level of log messages to log.
Expand Down
16 changes: 16 additions & 0 deletions cdoc/LogEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ struct LogEngine final : public ILogger
return tmp;
}

void setLogger(ILogger *logger) {
lock_guard<mutex> guard(loggers_protector);
while (!loggers.empty()) {
delete loggers.begin()->second;
loggers.erase(loggers.begin()->first);
}
loggers[0] = logger;
}

private:
// Current Cookie value
int currentLoggerCookie = 0;
Expand Down Expand Up @@ -91,4 +100,11 @@ ILogger::getLogger()
return &defaultLogEngine;
}

void
ILogger::setLogger(ILogger *logger)
{
defaultLogEngine.setLogger(logger);
}


}
52 changes: 24 additions & 28 deletions cdoc/NetworkBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,11 @@ setProxy(httplib::SSLClient& cli, libcdoc::NetworkBackend *network)
// Post request and fetch response
//
static libcdoc::result_t
post(httplib::SSLClient& cli, const std::string& path, const std::string& req, httplib::Response& rsp)
post(httplib::SSLClient& cli, const std::string& path, httplib::Headers& hdrs, const std::string& req, httplib::Response& rsp)
{
// Capture TLS and HTTP errors
libcdoc::LOG_DBG("POST: {} {}", path, req);
httplib::Result res = cli.Post(path, req, "application/json");
httplib::Result res = cli.Post(path, hdrs, req, "application/json");
if (!res) {
error = FORMAT("Cannot connect to https://{}:{}{}", cli.host(), cli.port(), path);
return libcdoc::NetworkBackend::NETWORK_ERROR;
Expand Down Expand Up @@ -267,8 +267,9 @@ get(httplib::SSLClient& cli, httplib::Headers& hdrs, const std::string& path, pi
}

libcdoc::result_t
libcdoc::NetworkBackend::sendKey (CapsuleInfo& dst, const std::string& url, const std::vector<uint8_t>& rcpt_key, const std::vector<uint8_t> &key_material, const std::string& type)
libcdoc::NetworkBackend::sendKey (CapsuleInfo& dst, const std::string& url, const std::vector<uint8_t>& rcpt_key, const std::vector<uint8_t> &key_material, const std::string& type, uint64_t expiry_ts)
{
LOG_DBG("Sendkey");
picojson::object obj = {
{"recipient_id", picojson::value(libcdoc::toBase64(rcpt_key))},
{"ephemeral_key_material", picojson::value(libcdoc::toBase64(key_material))},
Expand All @@ -288,8 +289,14 @@ libcdoc::NetworkBackend::sendKey (CapsuleInfo& dst, const std::string& url, cons
if (result = setProxy(cli, this); result != OK) return result;

std::string full = path + "/key-capsules";
httplib::Headers hdrs;
if (expiry_ts) {
std::string expiry_str = timeToISO(expiry_ts);
LOG_DBG("Expiry time: {}", expiry_str);
hdrs.emplace(std::make_pair("x-expiry-time", expiry_str));
}
httplib::Response rsp;
result = post(cli, full, req_str, rsp);
result = post(cli, full, hdrs, req_str, rsp);
if (result != libcdoc::OK) return result;

std::string location = rsp.get_header_value("Location");
Expand All @@ -298,28 +305,13 @@ libcdoc::NetworkBackend::sendKey (CapsuleInfo& dst, const std::string& url, cons
return NETWORK_ERROR;
}
error = {};

/* Remove /key-capsules/ */
dst.transaction_id = location.substr(14);

// Calculate expiry time
auto now = std::chrono::system_clock::now();
// Get a days-precision chrono::time_point
auto sd = floor<std::chrono::days>(now);
// Record the time of day
auto time_of_day = now - sd;
// Convert to a y/m/d calendar data structure
std::chrono::year_month_day ymd = sd;
// Add the months
ymd += std::chrono::months{6};
// Add some policy for overflowing the day-of-month if desired
if (!ymd.ok())
ymd = ymd.year()/ymd.month()/std::chrono::last;
// Convert back to system_clock::time_point
std::chrono::system_clock::time_point later = std::chrono::sys_days{ymd} + time_of_day;
auto ttt = std::chrono::system_clock::to_time_t(later);

dst.expiry_time = ttt;
std::string expiry_str = rsp.get_header_value("x-expiry-time");
LOG_DBG("Server expiry: {}", expiry_str);
dst.expiry_time = uint64_t(timeFromISO(expiry_str));
LOG_DBG("Server expiry timestamp: {}", dst.expiry_time);

return OK;
}
Expand Down Expand Up @@ -348,8 +340,9 @@ libcdoc::NetworkBackend::sendShare(std::vector<uint8_t>& dst, const std::string&
if (result = setProxy(cli, this); result != OK) return result;

std::string full = path + "/key-shares";
httplib::Headers hdrs;
httplib::Response rsp;
result = post(cli, full, req_str, rsp);
result = post(cli, full, hdrs, req_str, rsp);
if (result != libcdoc::OK) return result;

std::string location = rsp.get_header_value("Location");
Expand Down Expand Up @@ -421,8 +414,9 @@ libcdoc::NetworkBackend::fetchNonce(std::vector<uint8_t>& dst, const std::string
if (result = setProxy(cli, this); result != OK) return result;

std::string full = path + "/key-shares/" + share_id + "/nonce";
httplib::Headers hdrs;
httplib::Response rsp;
result = post(cli, full, "", rsp);
result = post(cli, full, hdrs, "", rsp);
if (result != libcdoc::OK) return result;

LOG_DBG("Response: {}", rsp.body);
Expand Down Expand Up @@ -710,8 +704,9 @@ libcdoc::NetworkBackend::signSID(std::vector<uint8_t>& dst, std::vector<uint8_t>
//
std::string full = path + "/certificatechoice/" + rcpt_id;
LOG_DBG("SmartID path: {}", full);
httplib::Headers hdrs;
httplib::Response rsp;
result = post(cli, full, query.serialize(), rsp);
result = post(cli, full, hdrs, query.serialize(), rsp);
if (result != libcdoc::OK) return result;


Expand Down Expand Up @@ -773,7 +768,7 @@ libcdoc::NetworkBackend::signSID(std::vector<uint8_t>& dst, std::vector<uint8_t>
//
full = path + "/authentication/" + rcpt_id;
LOG_DBG("SmartID path: {}", full);
result = post(cli, full, query.serialize(), rsp);
result = post(cli, full, hdrs, query.serialize(), rsp);
if (result != libcdoc::OK) return result;
LOG_DBG("Response: {}", rsp.body);
picojson::parse(v, rsp.body);
Expand Down Expand Up @@ -857,8 +852,9 @@ libcdoc::NetworkBackend::signMID(std::vector<uint8_t>& dst, std::vector<uint8_t>
//
std::string full = path + "/authentication";
LOG_DBG("Mobile ID path: {}", full);
httplib::Headers hdrs;
httplib::Response rsp;
result = post(cli, full, query.serialize(), rsp);
result = post(cli, full, hdrs, query.serialize(), rsp);
if (result != libcdoc::OK) return result;
LOG_DBG("Response: {}", rsp.body);

Expand Down
3 changes: 2 additions & 1 deletion cdoc/NetworkBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,10 @@ struct CDOC_EXPORT NetworkBackend {
* @param rcpt_key recipient's public key
* @param key_material encrypted KEK or ECDH public Key used to derive shared secret
* @param type algorithm type, currently either "rsa" or "ecc_secp384r1"
* @param expiry_ts the requested capsule expiry timestamp, 0 - use server default
* @return error code or OK
*/
virtual result_t sendKey (CapsuleInfo& dst, const std::string& url, const std::vector<uint8_t>& rcpt_key, const std::vector<uint8_t> &key_material, const std::string& type);
virtual result_t sendKey (CapsuleInfo& dst, const std::string& url, const std::vector<uint8_t>& rcpt_key, const std::vector<uint8_t> &key_material, const std::string& type, uint64_t expiry_ts);
/**
* @brief send key share to server
*
Expand Down
Loading
Loading