Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
1b76e52
Added CDocV1 tests
Jan 9, 2026
7a2b181
Added CDoc1 tests and cleaned up testing
Jan 9, 2026
2629756
More CDocCipher cleanups
Jan 13, 2026
4febb5c
Fix windows build
Jan 13, 2026
dd2cf68
Fix initializer order for gcc
Jan 13, 2026
5e4e80f
Use again absolute paths for tests
Jan 13, 2026
bb66be5
Create test tmp path if not exist
Jan 13, 2026
a4efe25
Change SID/MID callback signature to handle QR codes
Jan 14, 2026
0cab1cb
Apply suggestions from code review
lauris71 Jan 14, 2026
0da1fd8
Update cdoc/cdoc-tool.cpp
lauris71 Jan 14, 2026
75d1101
Update cdoc/cdoc-tool.cpp
lauris71 Jan 14, 2026
5b32d9f
Merge branch 'open-eid:master' into master
lauris71 Jan 14, 2026
87e5493
Merge branch 'master' into sid2
Jan 14, 2026
53a6898
Some fixes from ai security audit
May 20, 2026
47715fe
Fixed cdoc-tool index usage
May 22, 2026
fef2389
Update cdoc/cdoc-tool.cpp
lauris71 May 25, 2026
8848542
Update cdoc/cdoc-tool.cpp
lauris71 May 25, 2026
bf5ca62
Some more AI issue fixes
May 26, 2026
0a6b12b
Hardcode SSL timeout
May 27, 2026
a4dafb9
Fixed xstream uint overflow and tool logging
May 27, 2026
8c9b789
Some more fixes
May 27, 2026
e9a8a6e
Secure tool key handling, use explicid compile time definitions for k…
May 27, 2026
fa288ee
Fixed potential tar size overflow and secured proxy password
May 27, 2026
b89e4f1
Windows build fix
May 27, 2026
d0e0c90
Revert proxy password for now
May 27, 2026
87d1547
Make proxy password string_view
May 29, 2026
3631991
Disable potential Bleichenbacher attack for CDoc1 RSA encryption
Jun 1, 2026
7e6cdaa
Moved fix to main decryptRSA method
Jun 1, 2026
f01510a
Added ct.h
Jun 1, 2026
0aec4a1
Bleichenbacher fix for NCrypt backend
Jun 1, 2026
6f37761
Some cleanups
Jun 1, 2026
cc19133
All C,H & M fixes from Caludo Opus review
Jun 5, 2026
6bd12a8
Merge branch 'open-eid:master' into master
lauris71 Jun 5, 2026
8102224
Update cdoc-tool
Jun 5, 2026
c3d8dd2
Merge branch 'open-eid:master' into master
lauris71 Jun 11, 2026
bb9945c
Merge branch 'master' into ai-security
Jun 11, 2026
08ca9e5
Make default KDF iter 600000
Jun 11, 2026
004ce57
Added std_string_view.i
Jun 16, 2026
212825a
Fixed label parsing on Ubuntu 22
Jun 16, 2026
6db3372
Include <string.h>
Jun 17, 2026
8a2f494
Use explicit_bzero on glibc
Jun 17, 2026
573f147
Use SecureZeroMemory on windows
Jun 17, 2026
2d552cb
Use OPENSSL_cleanse for secure cleanup
Jun 17, 2026
f63ed77
Fixed inverted constant-time comparison
Jun 17, 2026
a6fc79a
Merge branch 'open-eid:master' into master
lauris71 Jun 17, 2026
88f1fa7
Merge commit 'a6fc79ad2e3c4d9d34157742f84db1c0c25faca3' into ai-security
Jun 17, 2026
578ff3a
Merge branch 'ai-security' into sid2
Jul 2, 2026
c0626a0
Update cdoc/CDocCipher.cpp
metsma Jul 2, 2026
eb091c3
Fix build for SIDMID
Jul 2, 2026
0e544fc
Fixed PKCS11 and NCrypt RSA handling and check all random() calls for…
Jul 2, 2026
3641679
Fix share encryption
Jul 3, 2026
3e62abe
Fixed PKCS11 public key loading
Jul 3, 2026
68cc522
Merge branch 'open-eid:master' into master
lauris71 Jul 3, 2026
32995f7
Merge branch 'master' into sid2
Jul 3, 2026
ed72221
fixes
Jul 15, 2026
5769447
Fixed label UTF-8 escaping if locale is not C
Jul 15, 2026
a7b7c6b
Merge branch 'open-eid:master' into master
lauris71 Jul 15, 2026
1225355
Fixed label generation for non-C locales
Jul 15, 2026
4ba85f1
Merge branch 'master' of github.com:lauris71/libcdoc
Jul 15, 2026
e5ac2a3
Merge branch 'open-eid:master' into master
lauris71 Jul 24, 2026
1df498c
Working authentication
Jul 24, 2026
463bfd5
Merge branch 'master' into ai-security
Jul 24, 2026
dc23ffa
Added SecureTarget class
Jul 24, 2026
139d1a7
Fixed N1 (out-of-bounds read) from 2026-07 report
Jul 27, 2026
e37902c
Added Utils.cpp to test build
Jul 27, 2026
e7ad099
Delete reader and writer in TestPasswordWithlabel
Jul 27, 2026
5743645
Clean up z_stream on zlib errors
Jul 27, 2026
6ae5ab9
Fixed N3 (base64 decode throws on errors) from 202607 report
Jul 27, 2026
90c72e6
Initial working SID decryption
Aug 4, 2026
31fb917
Preliminary configuration settings for MID
Aug 4, 2026
eaf6bff
Check that we have session disclosures for all share servers before c…
Aug 5, 2026
a63652e
Added CDoc2Reader.cpp changes
Aug 5, 2026
976cab5
Merge branch 'ai-security' into sid2
Aug 5, 2026
9b65423
More fixes to SID
Aug 5, 2026
adc94f4
Validate auth and rp server signatures
Aug 6, 2026
df0a4ed
Preliminary working MobileId authentication
Aug 7, 2026
b638e6d
Added MID signature and certificate validation
Aug 7, 2026
36545e6
Fixed keyshare KEK creatin, urlencode untrusted path components, log …
Aug 12, 2026
8492680
Verify shares recipient and vc code
Aug 12, 2026
9b01b40
Made SessionData public
Aug 14, 2026
08b5d44
Added tests for MID/SID (not automatic)
Aug 14, 2026
2481367
Reworking CDocTool.java
Aug 17, 2026
e2d7828
Minor fixes: removed AES-CBC, N4, N5
Aug 17, 2026
b47770c
fixed N7 (zstream max size), N8 (PBKDF limits), N9 (logging), N10 (th…
Aug 17, 2026
662da29
Added comment about N12 (OpenSSL fast-path timing), fixed N13 (decode…
Aug 17, 2026
311be5b
Fixed N17 (time parsing errors) and N18 (clean FMK in CDocCipher)
Aug 17, 2026
fb37985
Fixed N20 (handle exactly 100 byte tar filenames), N21 (treat PKCS11 …
Aug 18, 2026
0892d09
Minor logging cleanups
Aug 18, 2026
9743447
fixed libcoc::LOG...
Aug 18, 2026
11bfdad
Remove apostrofes from numberl literals
Aug 18, 2026
dce0136
Use swig workaround for new configuration keys
Aug 18, 2026
75bb399
Merge branch 'ai-security' into sid2
Aug 18, 2026
b4d4bd1
Added get() and post() virtual methods to NetworkBackend, plus SID/MI…
Aug 19, 2026
f7d15a9
Cleaned up (both C and Java) api
Aug 24, 2026
b30321a
Made SID/MID display text configurable
Aug 24, 2026
6193802
use core names for old openSSL
Aug 25, 2026
9cb19fe
Small fixes
Aug 25, 2026
fd03e1e
unittests now has SID/MID test with RIA dev servers (not run by default)
Aug 28, 2026
922254c
Merge branch 'open-eid:master' into master
lauris71 Sep 30, 2026
28ac376
Merge branch 'master' into sid2
Oct 12, 2026
77bb98e
Allow specifying certificate files per server in cdoc-tool
Oct 13, 2026
87c9d83
Merge branch 'master' into sid2
metsma Oct 29, 2026
794effe
Apply suggestion from @metsma
metsma Oct 29, 2026
fa18414
Apply suggestion from @metsma
metsma Oct 29, 2026
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
214 changes: 167 additions & 47 deletions cdoc/CDoc2Reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,85 +243,205 @@ CDoc2Reader::getFMK(std::vector<uint8_t>& fmk, unsigned int lock_idx)
/* SHARE_URLS */
/* url,share_id;url,share_id... */
std::string all = lock.getString(Lock::SHARE_URLS);
std::vector<std::string> strs = split(all, ';');
if (strs.empty()){
std::vector<std::string> servers = split(all, ';');
if (servers.empty()){
setLastError("Lock does not contain server info");
LOG_ERROR("{}", last_error);
return libcdoc::DATA_FORMAT_ERROR;
}
std::vector<ShareData> shares;
for (auto& str : strs) {
std::vector<std::string> parts = split(str, ',');
for (auto& server : servers) {
std::vector<std::string> parts = split(server, ',');
if (parts.size() != 2) {
setLastError("Invalid server info in lock");
LOG_ERROR("{}", last_error);
return libcdoc::DATA_FORMAT_ERROR;
}
std::string url = parts[0];
std::string id = parts[1];
LOG_TRACE("Share {} url {}", id, url);
LOG_DBG("Share {} url {}", parts[1], parts[0]);
shares.emplace_back(parts[0], parts[1]);
}

// Get authentication token
std::string auth_url = conf->getValue({}, Configuration::AUTH_SERVER);
if (auth_url.empty()) {
setLastError(FORMAT("No AUTH_SERVER found"));
LOG_ERROR("{}", last_error);
return libcdoc::CONFIGURATION_ERROR;
}
// auth_url = "https://cdoc2-auth.dev.riaint.ee";
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
// fixme:
std::string signer_type = conf->getValue(Configuration::SHARE_SIGNER);
LOG_DBG("Signer: {}", signer_type);
bool mid = false;
if (signer_type == Configuration::SHARE_SIGNER_MID) {
mid = true;
} else if (signer_type != Configuration::SHARE_SIGNER_SID) {
setLastError(t_("Unknown or missing signer type"));
LOG_ERROR("Unknown or missing signer type");
return libcdoc::CONFIGURATION_ERROR;
}
std::string phone;
if (mid) {
phone = conf->getValue({}, Configuration::PHONE_NUMBER);
if (phone.empty()) {
setLastError(t_("Missing phone number"));
LOG_ERROR("Missing phone number");
return libcdoc::CONFIGURATION_ERROR;
}
}

NetworkBackend::SessionData session;
if (auto rv = network->authenticateForShares(auth_url, rcpt_id, phone, session); rv != OK) {
setLastError(network->getLastErrorStr(rv));
LOG_ERROR("{}", last_error);
return rv;
}

// S1: only contact share servers that the authentication server has
// authorized for this session. The session token carries one
// disclosure per authorized server; a container pointing to any other
// server would otherwise receive the session token and the user's
// credentials (SSRF / credential exfiltration). N-of-N reconstruction
// needs every share, so an unauthorized server rejects the container.
{
SessionToken stoken(session.token);
for (const auto& share : shares) {
if (!stoken.hasDisclosureForUrl(share.base_url)) {
setLastError(FORMAT("Share server {} is not authorized by the authentication session", share.base_url));
LOG_ERROR("{}", last_error);
return libcdoc::DATA_FORMAT_ERROR;
}
}
}

// S8: validate the authentication session client-side - the session
// certificate must belong to the lock recipient and the session token
// must not be expired. Also learns the schemeName/rpName claims needed
// to verify the signed ticket later.
std::string scheme_name, rp_name, v_err;
if (auto rv = validateSessionData(crypto, rcpt_id, mid, session.token, session.cert, scheme_name, rp_name, v_err); rv != OK) {
setLastError(v_err);
LOG_ERROR("{}", last_error);
return rv;
}

// Get nonces
for (auto& share : shares) {
std::vector<uint8_t> nonce;
result_t result = network->fetchNonce(nonce, url, id);
result_t result = network->fetchNonce(nonce, share.base_url, share.share_id, session);
if (result != libcdoc::OK) {
setLastError(network->getLastErrorStr(result));
LOG_ERROR("Cannot fetch nonce from server {}", url);
LOG_ERROR("Cannot fetch nonce {} from server {}", share.share_id, share.base_url);
return result;
}
LOG_TRACE("Nonce: {}", std::string(nonce.cbegin(), nonce.cend()));
ShareData acc(url, id, std::string(nonce.cbegin(), nonce.cend()));
shares.push_back(std::move(acc));
LOG_DBG("Nonce: {}", std::string(nonce.cbegin(), nonce.cend()));
share.nonce = std::string(nonce.cbegin(), nonce.cend());
}

std::string rp_url = conf->getValue({}, Configuration::RP_SERVER);
if (rp_url.empty()) {
setLastError(FORMAT("No RP_SERVER found"));
LOG_ERROR("{}", last_error);
return libcdoc::CONFIGURATION_ERROR;
}
// rp_url = "https://cdoc2-rp.dev.riaint.ee/"
/* Create tickets from shares */
std::vector<std::string> tickets;
std::vector<uint8_t> cert;
std::vector<std::string> auth_tokens;
AuthenticationData auth;
result_t result = NOT_IMPLEMENTED;
std::string signer = conf->getValue(Configuration::SHARE_SIGNER);
LOG_TRACE("Signer: {}", signer);
if (signer == "SMART_ID") {
// "https://sid.demo.sk.ee/smart-id-rp/v2"
std::string url = conf->getValue(Configuration::SID_DOMAIN, Configuration::BASE_URL);
// "00000000-0000-0000-0000-000000000000"
std::string relyingPartyUUID = conf->getValue(Configuration::SID_DOMAIN, Configuration::RP_UUID);
// "DEMO"
std::string relyingPartyName = conf->getValue(Configuration::SID_DOMAIN, Configuration::RP_NAME);
SIDSigner signer(url, relyingPartyUUID, relyingPartyName, rcpt_id, network);
result = signer.generateTickets(tickets, shares);

// The text shown on the user's device in the SID/MID confirmation
// dialog (Smart-ID displayText200 / Mobile-ID displayText).
std::string display_text = conf ? conf->getValue(libcdoc::Configuration::DISPLAY_TEXT) : std::string{};

if (!mid) {
SIDSigner signer(rp_url, session, rcpt_id, network, display_text);
result = signer.generateTickets(auth_tokens, shares);
if (result != OK) {
setLastError(signer.error);
} else {
cert = std::move(signer.cert);
auth.cert = std::move(signer.cert);
auth.params = std::move(signer.params);
}
} else if (signer == "MOBILE_ID") {
// "https://sid.demo.sk.ee/smart-id-rp/v2"
std::string url = conf->getValue(Configuration::MID_DOMAIN, Configuration::BASE_URL);
// "00000000-0000-0000-0000-000000000000"
std::string relyingPartyUUID = conf->getValue(Configuration::MID_DOMAIN, Configuration::RP_UUID);
// "DEMO"
std::string relyingPartyName = conf->getValue(Configuration::MID_DOMAIN, Configuration::RP_NAME);
// "37200000566"
std::string phone = conf->getValue(Configuration::MID_DOMAIN, Configuration::PHONE_NUMBER);
MIDSigner signer(url, relyingPartyUUID, relyingPartyName, phone, rcpt_id, network);
result = signer.generateTickets(tickets, shares);
} else {
MIDSigner signer(rp_url, phone, session, rcpt_id, network, display_text);
result = signer.generateTickets(auth_tokens, shares);
if (result != OK) {
setLastError(signer.error);
} else {
cert = std::move(signer.cert);
auth.cert = std::move(signer.cert);
auth.params = std::move(signer.params);
}
} else {
setLastError(t_("Unknown or missing signer type"));
LOG_ERROR("Unknown or missing signer type");
return result;
}
if (result != libcdoc::OK) {
LOG_ERROR("Cannot generate share tickets");
return result;
}
kek.resize(32);
std::fill(kek.begin(), kek.end(), 0);
for (unsigned int i = 0; i < tickets.size(); i++) {
// S8: verify the signed auth ticket client-side before spending it -
// the signing certificate must belong to rcpt_id and the ticket
// signature must verify (binds identity, the consent text shown to
// the user, and freshness). All tickets share the same signed JWT,
// so validating the first one covers them all.
if (!auth_tokens.empty()) {
if (!mid) {
// Smart-ID: RSASSA-PSS over the ACSP_V2 payload
std::vector params = fromBase64URL(auth.params[network->X_CDOC2_SID_RPV3_SIGNATURE_PARAMETERS]);
if (auto rv = validateAuthTicket(crypto, rcpt_id, auth_tokens[0], auth.cert, std::string(params.cbegin(), params.cend()), scheme_name, rp_name, v_err); rv != OK) {
setLastError(v_err);
LOG_ERROR("{}", last_error);
return rv;
}
} else {
// Mobile-ID: ECDSA (ES256) ticket signature plus the RP
// server RFC9421 HTTP countersignature. The RP signing keys
// are fetched from its well-known endpoint.
std::string jwks;
{
std::string jwks_url = joinUrl(rp_url, "/.well-known/jwks.jws");
std::map<std::string, std::string> headers;
std::vector<uint8_t> body;
if (auto rv = network->get(jwks_url, body, headers, false); rv != OK) {
setLastError(network->getLastErrorStr(rv));
LOG_ERROR("{}", last_error);
return rv;
}
jwks.assign(body.begin(), body.end());

// The endpoint name says .jws: accept both a plain JWK
// Set (what the servers currently return) and a JWS
// compact serialization (header64.payload64.signature64)
// whose payload is the JWK Set.
if (jwks.find("\"keys\"") == std::string::npos) {
std::vector<std::string> parts = split(jwks, '.');
if (parts.size() == 3) {
std::vector<uint8_t> payload = fromBase64URL(parts[1]);
jwks.assign(payload.begin(), payload.end());
}
}
if (jwks.find("\"keys\"") == std::string::npos) {
setLastError("Well-known keys response is not a JWK Set");
LOG_ERROR("{}", last_error);
return libcdoc::DATA_FORMAT_ERROR;
}
}
if (auto rv = validateAuthTicketMID(crypto, rcpt_id, auth_tokens[0], auth.cert, auth.params, jwks, v_err); rv != OK) {
setLastError(v_err);
LOG_ERROR("{}", last_error);
return rv;
}
}
}
std::vector<uint8_t>& kek_build = kek.getTarget(32);
std::fill(kek_build.begin(), kek_build.end(), 0);
// Build the auth SessionData once (cert and params are shared);
// only the per-share ticket token changes between requests.
NetworkBackend::SessionData auth_session;
auth_session.cert = toBase64URL(auth.cert);
auth_session.params = auth.params;
for (unsigned int i = 0; i < auth_tokens.size(); i++) {
NetworkBackend::ShareInfo share;
result = network->fetchShare(share, shares[i].base_url, shares[i].share_id, tickets[i], cert);
auth_session.token = auth_tokens[i];
result = network->fetchShare(share, shares[i].base_url, shares[i].share_id, session, auth_session);
if (result != libcdoc::OK) {
setLastError(network->getLastErrorStr(result));
LOG_ERROR("Cannot fetch share {}", i);
Expand All @@ -331,7 +451,7 @@ CDoc2Reader::getFMK(std::vector<uint8_t>& fmk, unsigned int lock_idx)
// remaining shares it reconstructs the KEK. Wipe it after
// XOR-ing it into kek so it does not linger on the heap.
libcdoc::Cleanser share_guard(share.share);
if (auto err = libcdoc::Crypto::xor_data(kek, kek, share.share); err != libcdoc::OK) {
if (auto err = libcdoc::Crypto::xor_data(kek_build, kek_build, share.share); err != libcdoc::OK) {
setLastError("Failed to derive kek");
LOG_ERROR("Failed to derive kek");
return err;
Expand Down
25 changes: 20 additions & 5 deletions cdoc/CDoc2Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,11 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
FAIL("Missing server list for ID " + rcpt.server_id, libcdoc::CONFIGURATION_ERROR);
LOG_DBG("Share servers: {}", url_list);
std::vector<std::string> urls = libcdoc::JsonToStringArray(url_list);
if (urls.size() < 1)
FAIL("No server URLs in " + rcpt.server_id, libcdoc::CONFIGURATION_ERROR);
// S5: with fewer than 2 servers the XOR "split" would hand the
// complete KEK to a single server, defeating the threshold
// protection - refuse to produce such a container.
if (urls.size() < 2)
FAIL("At least 2 share server URLs are required for ID " + rcpt.server_id, libcdoc::CONFIGURATION_ERROR);
int N_SHARES = urls.size();
LOG_DBG("Number of shares: {}", N_SHARES);

Expand All @@ -372,8 +375,11 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
// key_material is split-share-input material; wipe on exit.
libcdoc::Cleanser key_material_guard(key_material);

//KEK_i_pm = HKDF_Extract(KeyMaterialSalt_i, KeyMaterial_i)
std::vector<uint8_t> kek_pm = libcdoc::Crypto::extract(key_material_salt, key_material);
// KEK_i_pm = HKDF_Extract(KeyMaterialSalt_i, KeyMaterial_i)
// RFC 5869: HKDF-Extract(salt, IKM); Crypto::extract takes (IKM, salt).
// (S11: the arguments were swapped, deviating from the spec and
// the reference implementation.)
std::vector<uint8_t> kek_pm = libcdoc::Crypto::extract(key_material, key_material_salt);
libcdoc::Cleanser kek_pm_guard(kek_pm);

// KEK_i = HKDF_Expand(KEK_i_pm, "CDOC2kek" + FMKEncryptionMethod + RecipientInfo_i, L)
Expand Down Expand Up @@ -419,7 +425,8 @@ CDoc2Writer::buildHeader(std::vector<uint8_t>& header, const std::vector<libcdoc
std::vector<std::vector<uint8_t>> transaction_ids(N_SHARES);
for (int i = 0; i < N_SHARES; i++) {
std::string send_url = urls[i];
LOG_TRACE_KEY("Sending share: {} {} {}", i, send_url, libcdoc::toHex(kek_shares[i]));
LOG_TRACE("Sending share {} to {}", i, send_url);
LOG_TRACE_KEY("Share: {}", kek_shares[i]);
int result = network->sendShare(transaction_ids[i], send_url, RecipientInfo_i, kek_shares[i]);
if (result < 0)
FAIL(network->getLastErrorStr(result), result);
Expand Down Expand Up @@ -479,6 +486,14 @@ CDoc2Writer::addRecipient(const libcdoc::Recipient& rcpt)
if(!rcpt.validate())
FAIL("Invalid recipient parameters", libcdoc::WRONG_ARGUMENTS);
break;
#ifdef HAS_KEYSHARES
case Recipient::KEYSHARE:
if (!network)
FAIL("KeyShares require NetworkBackend", libcdoc::WORKFLOW_ERROR);
if (!rcpt.validate())
FAIL("Invalid recipient parameters", libcdoc::WRONG_ARGUMENTS);
break;
#endif
default:
FAIL("Invalid recipient type", WRONG_ARGUMENTS);
}
Expand Down
14 changes: 11 additions & 3 deletions cdoc/CDocCipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ struct ToolNetwork : public libcdoc::NetworkBackend {

int rcpt_idx = -1;

std::vector<std::vector<uint8_t>> certs;
std::map<std::string, std::vector<std::vector<uint8_t>>> certs;

explicit ToolNetwork(ToolCrypto *_crypto) : crypto(_crypto) {
}
Expand All @@ -298,8 +298,10 @@ struct ToolNetwork : public libcdoc::NetworkBackend {
return crypto->p11->getCertificate(dst, long(rcpt->p11.slot), rcpt->secret, rcpt->p11.key_id, rcpt->p11.key_label);
}

libcdoc::result_t getPeerTLSCertificates(std::vector<std::vector<uint8_t>> &dst) override final {
dst = certs;
libcdoc::result_t getPeerTLSCertificates(std::vector<std::vector<uint8_t>> &dst, const std::string& url) override final {
if (certs.contains(url)) {
dst = certs.at(url);
}
return libcdoc::OK;
}

Expand Down Expand Up @@ -399,6 +401,12 @@ fill_recipients_from_rcpt_info(ToolConf& conf, ToolCrypto& crypto, std::vector<l
key.setLabelValue(CDoc2::Label::LABEL, rcpt.label);
#ifdef HAS_KEYSHARES
} else if (rcpt.type == RcptInfo::Type::SHARE) {
if (conf.servers.empty()) {
// S4: a share recipient without --server indexed servers[0]
// out of bounds.
LOG_ERROR("Keyshare recipient '{}' requires a share server (--server ID URL)", rcpt.label);
continue;
}
LOG_DBG("Creating keyshare recipient:");
key = libcdoc::Recipient::makeShare(std::move(label), conf.servers[0].ID, "PNOEE-" + rcpt.id);
#endif
Expand Down
11 changes: 10 additions & 1 deletion cdoc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ add_library(cdoc
CDoc2Writer.cpp CDoc2Writer.h
DDocReader.cpp DDocReader.h
DDocWriter.cpp DDocWriter.h
KeyShares.cpp KeyShares.h
# KeyShares.cpp KeyShares.h
XmlReader.cpp XmlReader.h
XmlWriter.cpp XmlWriter.h
Expand Down Expand Up @@ -79,6 +80,9 @@ target_include_directories(cdoc PUBLIC
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
)

# Enable SID/MID
target_compile_definitions(cdoc PRIVATE HAS_KEYSHARES)

if(NOT BUILD_SHARED_LIBS)
target_compile_definitions(cdoc PUBLIC cdoc_STATIC)
endif()
Expand All @@ -102,6 +106,10 @@ target_link_libraries(cdoc PRIVATE
if(BUILD_TOOLS)
add_executable(cdoc-tool cdoc-tool.cpp)
target_include_directories(cdoc-tool PRIVATE ${OPENSSL_INCLUDE_DIR})

# Enable SID/MID
target_compile_definitions(cdoc-tool PRIVATE HAS_KEYSHARES)

target_link_libraries(cdoc-tool cdoc_ver cdoc OpenSSL::SSL)
target_link_options(cdoc-tool PRIVATE
$<$<PLATFORM_ID:Windows>: /MANIFEST:NO /MANIFEST:EMBED /MANIFESTINPUT:${CMAKE_CURRENT_SOURCE_DIR}/cdoc-tool.manifest>
Expand Down Expand Up @@ -152,8 +160,9 @@ if(SWIG_FOUND)
set_target_properties(cdoc_java PROPERTIES
INSTALL_RPATH $<$<PLATFORM_ID:Darwin>:/Library/Frameworks>
SWIG_COMPILE_DEFINITIONS $<$<PLATFORM_ID:Windows>:SWIGWIN>
SWIG_COMPILE_DEFINITIONS HAS_KEYSHARES
)
#install(TARGETS cdoc_java DESTINATION $<IF:$<PLATFORM_ID:Darwin>,/Library/Java/Extensions,${CMAKE_INSTALL_LIBDIR}>) # FIXME: build mac packages
target_compile_definitions(cdoc_java PRIVATE HAS_KEYSHARES)
install(TARGETS cdoc_java DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/java/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ee/ria/cdoc FILES_MATCHING PATTERN "*.java")
if(WIN32)
Expand Down
Loading
Loading