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
55 changes: 19 additions & 36 deletions cdoc/CDoc1Reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ constexpr std::array SUPPORTED_KWAES {
* @brief CDoc1Reader is used for decrypt data.
*/

class CDoc1Reader::Private
struct CDoc1Reader::Private
{
public:
libcdoc::DataSource *dsrc = nullptr;
bool src_owned = false;
std::string mime, method;
Expand Down Expand Up @@ -138,7 +137,6 @@ CDoc1Reader::getFMK(std::vector<uint8_t>& fmk, unsigned int lock_idx)
LOG_ERROR("{}", last_error);
return libcdoc::CRYPTO_ERROR;
}
setLastError({});
return libcdoc::OK;
}

Expand Down Expand Up @@ -187,7 +185,6 @@ CDoc1Reader::decrypt(const std::vector<uint8_t>& fmk, libcdoc::MultiDataConsumer
libcdoc::result_t
CDoc1Reader::beginDecryption(const std::vector<uint8_t>& fmk)
{
setLastError({});
return CDoc1Reader::decryptData(fmk, [&](DataSource &src, const std::string &mime) -> result_t {
if(mime == MIME_DDOC || mime == MIME_DDOC_OLD) {
LOG_DBG("Contains DDoc content {}", mime);
Expand Down Expand Up @@ -257,70 +254,57 @@ CDoc1Reader::readData(uint8_t *dst, size_t size)
* @param src A DataSource of container
*/
CDoc1Reader::CDoc1Reader(libcdoc::DataSource *src, bool delete_on_close)
: CDocReader(1), d(new Private)
: CDocReader(1), d(new Private{.dsrc = src, .src_owned = delete_on_close})
{
d->dsrc = src;
d->src_owned = delete_on_close;
auto hex2bin = [](const std::string &in) {
std::vector<uint8_t> out;
out.reserve(in.size() / 2);
char data[] = "00";
for(std::string::const_iterator i = in.cbegin(); distance(i, in.cend()) >= 2;)
{
data[0] = *(i++);
data[1] = *(i++);
out.push_back(static_cast<uint8_t>(strtoul(data, 0, 16)));
}
if(out[0] == 0x00)
out.erase(out.cbegin());
return out;
auto hex2bin = [](std::string_view in) {
return fromHex(in.starts_with("00") ? in.substr(2) : in);
};

XMLReader reader(*d->dsrc);
while (reader.read()) {
if(reader.isEndElement())
while (reader.read()) {
if(reader.isEndElement())
continue;
// EncryptedData
if(reader.isElement("EncryptedData"))
d->mime = reader.attribute("MimeType");
d->mime = reader.attribute("MimeType");
// EncryptedData/EncryptionMethod
else if(reader.isElement("EncryptionMethod"))
d->method = reader.attribute("Algorithm");
else if(reader.isElement("EncryptionMethod"))
d->method = reader.attribute("Algorithm");
// EncryptedData/EncryptionProperties/EncryptionProperty
else if(reader.isElement("EncryptionProperty"))
{
auto name = reader.attribute("Name");
d->properties[std::move(name)] = reader.readText();
}
// EncryptedData/KeyInfo/EncryptedKey
else if(reader.isElement("EncryptedKey"))
else if(reader.isElement("EncryptedKey"))
{
Lock &key = d->locks.emplace_back(Lock::Type::CDOC1);
key.label = reader.attribute("Recipient");
while(reader.read())
while(reader.read())
{
if(reader.isElement("EncryptedKey") && reader.isEndElement())
if(reader.isElement("EncryptedKey") && reader.isEndElement())
break;
if(reader.isEndElement())
continue;
// EncryptedData/KeyInfo/EncryptedKey/EncryptionMethod
if(reader.isElement("EncryptionMethod"))
key.setString(Lock::Params::METHOD, reader.attribute("Algorithm"));
// EncryptedData/KeyInfo/EncryptedKey/KeyInfo/AgreementMethod/KeyDerivationMethod/ConcatKDFParams
else if(reader.isElement("ConcatKDFParams"))
else if(reader.isElement("ConcatKDFParams"))
{
key.setBytes(Lock::Params::ALGORITHM_ID, hex2bin(reader.attribute("AlgorithmID")));
key.setBytes(Lock::Params::PARTY_UINFO, hex2bin(reader.attribute("PartyUInfo")));
key.setBytes(Lock::Params::PARTY_VINFO, hex2bin(reader.attribute("PartyVInfo")));
}
// EncryptedData/KeyInfo/EncryptedKey/KeyInfo/AgreementMethod/KeyDerivationMethod/ConcatKDFParams/DigestMethod
else if(reader.isElement("DigestMethod"))
else if(reader.isElement("DigestMethod"))
key.setString(Lock::Params::CONCAT_DIGEST, reader.attribute("Algorithm"));
// EncryptedData/KeyInfo/EncryptedKey/KeyInfo/AgreementMethod/OriginatorKeyInfo/KeyValue/ECKeyValue/PublicKey
else if(reader.isElement("PublicKey"))
else if(reader.isElement("PublicKey"))
key.setBytes(Lock::Params::KEY_MATERIAL, reader.readBase64());
// EncryptedData/KeyInfo/EncryptedKey/KeyInfo/X509Data/X509Certificate
else if(reader.isElement("X509Certificate"))
else if(reader.isElement("X509Certificate"))
{
auto cert = reader.readBase64();
Certificate ssl(cert);
Expand All @@ -329,14 +313,14 @@ CDoc1Reader::CDoc1Reader(libcdoc::DataSource *src, bool delete_on_close)
key.pk_type = (ssl.getAlgorithm() == libcdoc::Certificate::RSA) ? Lock::RSA : Lock::ECC;
}
// EncryptedData/KeyInfo/EncryptedKey/KeyInfo/CipherData/CipherValue
else if(reader.isElement("CipherValue"))
else if(reader.isElement("CipherValue"))
key.encrypted_fmk = reader.readBase64();
}
}
}
}

CDoc1Reader::~CDoc1Reader()
CDoc1Reader::~CDoc1Reader() noexcept
{
delete d;
}
Expand Down Expand Up @@ -367,6 +351,7 @@ CDoc1Reader::isCDoc1File(libcdoc::DataSource *src)
result_t CDoc1Reader::decryptData(const std::vector<uint8_t>& fmk,
const std::function<libcdoc::result_t(libcdoc::DataSource &src, const std::string &mime)>& f)
{
setLastError({});
if (fmk.empty()) {
setLastError("FMK is missing");
return libcdoc::WRONG_ARGUMENTS;
Expand Down Expand Up @@ -414,8 +399,6 @@ result_t CDoc1Reader::decryptData(const std::vector<uint8_t>& fmk,
setLastError("Failed to decrypt data, verify if FMK is correct");
return CRYPTO_ERROR;
}
setLastError({});

if (d->mime == MIME_ZLIB) {
libcdoc::ZSource zsrc(&dec);
if(auto rv = f(zsrc, d->properties["OriginalMimeType"]); rv < OK)
Expand Down
25 changes: 12 additions & 13 deletions cdoc/CDoc1Reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,28 @@

class Token;

class CDoc1Reader : public libcdoc::CDocReader
class CDoc1Reader final : public libcdoc::CDocReader
{
public:
CDoc1Reader(libcdoc::DataSource *src, bool take_ownership = false);
~CDoc1Reader();
~CDoc1Reader() noexcept final;

const std::vector<libcdoc::Lock>& getLocks() override final;
libcdoc::result_t getLockForCert(const std::vector<uint8_t>& cert) override final;
libcdoc::result_t getFMK(std::vector<uint8_t>& fmk, unsigned int lock_idx) override final;
libcdoc::result_t decrypt(const std::vector<uint8_t>& fmk, libcdoc::MultiDataConsumer *dst) override final;
const std::vector<libcdoc::Lock>& getLocks() final;
libcdoc::result_t getLockForCert(const std::vector<uint8_t>& cert) final;
libcdoc::result_t getFMK(std::vector<uint8_t>& fmk, unsigned int lock_idx) final;
libcdoc::result_t decrypt(const std::vector<uint8_t>& fmk, libcdoc::MultiDataConsumer *dst) final;

// Pull interface
libcdoc::result_t beginDecryption(const std::vector<uint8_t>& fmk) override final;
libcdoc::result_t nextFile(std::string& name, int64_t& size) override final;
libcdoc::result_t readData(uint8_t *dst, size_t size) override final;
libcdoc::result_t finishDecryption() override final;
libcdoc::result_t beginDecryption(const std::vector<uint8_t>& fmk) final;
libcdoc::result_t nextFile(std::string& name, int64_t& size) final;
libcdoc::result_t readData(uint8_t *dst, size_t size) final;
libcdoc::result_t finishDecryption() final;

static bool isCDoc1File(libcdoc::DataSource *src);
private:
CDoc1Reader(const CDoc1Reader &) = delete;
CDoc1Reader &operator=(const CDoc1Reader &) = delete;
CDOC_DISABLE_MOVE_COPY(CDoc1Reader);
libcdoc::result_t decryptData(const std::vector<uint8_t>& fmk,
const std::function<libcdoc::result_t(libcdoc::DataSource &src, const std::string &mime)>& f);
class Private;
struct Private;
Private *d;
};
2 changes: 1 addition & 1 deletion cdoc/CDocCipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

#include "CDocCipher.h"
#include "CDocReader.h"
#include "CDoc2.h"
#include "Io.h"
#include "Lock.h"
#include "NetworkBackend.h"
#include "PKCS11Backend.h"
Expand Down
6 changes: 3 additions & 3 deletions cdoc/Lock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
#include "Lock.h"

#include "CDoc2.h"
#include "Certificate.h"
#include "Utils.h"

#include "json/base.h"

namespace libcdoc {

std::string
Expand Down Expand Up @@ -83,8 +84,7 @@ Lock::parseLabel(const std::string& label)
else
{
std::string base64_label(label_wo_prefix.substr(base64IndPos + CDoc2::LABELBASE64IND.size()));
std::vector<uint8_t> decodedLabel(fromBase64(base64_label));
label_to_prcss.assign(decodedLabel.cbegin(), decodedLabel.cend());
label_to_prcss = jwt::base::decode<jwt::alphabet::base64>(base64_label);
}

auto label_parts(split(label_to_prcss, '&'));
Expand Down
1 change: 0 additions & 1 deletion cdoc/Recipient.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

#include <cdoc/Exports.h>

#include <map>
#include <string>
#include <vector>
#include <cstdint>
Expand Down
36 changes: 6 additions & 30 deletions cdoc/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

#include "Utils.h"

#include "json/jwt.h"
#include "json/base.h"
#include "json/picojson/picojson.h"

#include <openssl/evp.h>
Expand Down Expand Up @@ -65,16 +65,15 @@ timeFromISO(const std::string& iso)
}

std::string
timeToISO(double time)
timeToISO(time_t time)
{
#ifdef __cpp_lib_format
auto expiry_tp = std::chrono::system_clock::time_point{std::chrono::seconds{time_t(time)}};
auto expiry_tp = std::chrono::system_clock::from_time_t(time);
return std::format("{:%FT%TZ}", expiry_tp);
#else
char buf[sizeof "2011-10-08T07:07:09Z"];
time_t tstamp = (time_t) time;
strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%SZ", gmtime(&tstamp));
return std::string(buf);
std::string buf = "0000-00-00T00:00:00Z";
strftime(buf.data(), buf.size() + 1, "%FT%TZ", gmtime(&time));
return buf;
#endif
}

Expand Down Expand Up @@ -156,29 +155,6 @@ operator<<(std::ostream& escaped, urlEncode src)
return escaped;
}

std::string
urlDecode(const std::string &src)
{
std::string ret;
ret.reserve(src.size());
uint8_t value = 0;

for (auto it = src.begin(), end = src.end(); it != end; ++it) {
if (*it == '%' && std::distance(it, end) >= 3 &&
std::isxdigit(*(it + 1)) && std::isxdigit(*(it + 2))) {
auto result = std::from_chars(&*(it + 1), &*(it + 3), value, 16);
if (result.ec == std::errc()) {
ret += char(value);
std::advance(it, 2);
continue;
}
}
ret += *it;
}

return ret;
}

std::vector<std::string>
JsonToStringArray(std::string_view json)
{
Expand Down
Loading
Loading