Skip to content

Commit 29bb751

Browse files
authored
Fixed PAX filenames (open-eid#108)
* Fix tar filenames if only PAX size is used * Moved parseLabel to Lock, take minimum of expiry time
1 parent 4dfb83d commit 29bb751

File tree

11 files changed

+100
-97
lines changed

11 files changed

+100
-97
lines changed

cdoc/CDoc2.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,25 @@ std::string getSaltForExpand(const std::string& label);
4343
// Get salt bitstring for HKDF expand method
4444
std::string getSaltForExpand(const std::vector<uint8_t>& key_material, const std::vector<uint8_t>& rcpt_key);
4545

46+
/**
47+
* @brief Prefix with what starts machine generated Lock's label.
48+
*/
49+
constexpr std::string_view LABELPREFIX{"data:"};
50+
51+
/**
52+
* @brief String after label prefix indicating, the rest of the label is Base64 encoded.
53+
*/
54+
constexpr std::string_view LABELBASE64IND{";base64,"};
55+
56+
/**
57+
* @brief EID type values for machine-readable label
58+
*/
59+
static constexpr std::string_view eid_strs[] = {
60+
"Unknown",
61+
"ID-card",
62+
"Digi-ID",
63+
"Digi-ID E-RESIDENT"
64+
};
4665

4766
} // namespace CDoc2
4867
} // namespace libcdoc

cdoc/CDoc2Writer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ createRSAServerCapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc::R
119119
rsaKeyServer.Union(),
120120
builder.CreateString(rcpt.server_id),
121121
builder.CreateString(transaction_id));
122+
if (rcpt.expiry_ts) expiry_time = std::min(rcpt.expiry_ts, expiry_time);
122123
return cdoc20::header::CreateRecipientRecord(builder,
123124
cdoc20::header::Capsule::recipients_KeyServerCapsule,
124125
capsule.Union(),
@@ -153,6 +154,7 @@ createECCServerCapsule(flatbuffers::FlatBufferBuilder& builder, const libcdoc::R
153154
eccKeyServer.Union(),
154155
builder.CreateString(rcpt.server_id),
155156
builder.CreateString(transaction_id));
157+
if (rcpt.expiry_ts) expiry_time = std::min(rcpt.expiry_ts, expiry_time);
156158
return cdoc20::header::CreateRecipientRecord(builder,
157159
cdoc20::header::Capsule::recipients_KeyServerCapsule,
158160
capsule.Union(),

cdoc/CDocCipher.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ void CDocCipher::Locks(const char* file) const
673673

674674
int lock_id = 1;
675675
for (const Lock& lock : rdr->getLocks()) {
676-
map<string, string> parsed_label(Recipient::parseLabel(lock.label));
676+
map<string, string> parsed_label(Lock::parseLabel(lock.label));
677677
if (parsed_label.empty()) {
678678
// Human-readable label
679679
cout << lock_id << ": " << lock.label << endl;

cdoc/Lock.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "Lock.h"
2020

21+
#include "CDoc2.h"
2122
#include "Certificate.h"
2223
#include "Utils.h"
2324

@@ -52,5 +53,60 @@ Lock::setInt(Params key, int32_t val)
5253
params[key] = std::move(bytes);
5354
}
5455

56+
std::map<std::string, std::string>
57+
Lock::parseLabel(const std::string& label)
58+
{
59+
std::map<std::string, std::string> parsed_label;
60+
// Check if provided label starts with the machine generated label prefix.
61+
if (!label.starts_with(CDoc2::LABELPREFIX))
62+
{
63+
return parsed_label;
64+
}
65+
66+
std::string label_wo_prefix(label.substr(CDoc2::LABELPREFIX.size()));
67+
68+
// Label to be processed
69+
std::string label_to_prcss;
70+
71+
// We ignore mediatype part
72+
73+
// Check, if the label is Base64 encoded
74+
auto base64IndPos = label_wo_prefix.find(CDoc2::LABELBASE64IND);
75+
if (base64IndPos == std::string::npos)
76+
{
77+
if (label_wo_prefix.starts_with(",")) {
78+
label_to_prcss = label_wo_prefix.substr(1);
79+
} else {
80+
label_to_prcss = std::move(label_wo_prefix);
81+
}
82+
}
83+
else
84+
{
85+
std::string base64_label(label_wo_prefix.substr(base64IndPos + CDoc2::LABELBASE64IND.size()));
86+
std::vector<uint8_t> decodedLabel(fromBase64(base64_label));
87+
label_to_prcss.assign(decodedLabel.cbegin(), decodedLabel.cend());
88+
}
89+
90+
auto label_parts(split(label_to_prcss, '&'));
91+
for (auto& part : label_parts)
92+
{
93+
auto label_data_parts(split(part, '='));
94+
if (label_data_parts.size() != 2)
95+
{
96+
// Invalid label data. We just ignore them.
97+
LOG_ERROR("The label '{}' is invalid", label);
98+
}
99+
else
100+
{
101+
std::string key = urlDecode(label_data_parts[0]);
102+
std::string value = urlDecode(label_data_parts[1]);
103+
std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c){ return std::tolower(c); });
104+
parsed_label[key] = value;
105+
}
106+
}
107+
108+
return parsed_label;
109+
}
110+
55111
} // namespace libcdoc
56112

cdoc/Lock.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,13 @@ struct CDOC_EXPORT Lock
239239
*/
240240
void setInt(Params param, int32_t val);
241241

242+
/**
243+
* @brief parse machine-readable CDoc2 label
244+
* @param label the label
245+
* @return a map of key-value pairs
246+
*/
247+
static std::map<std::string, std::string> parseLabel(const std::string& label);
248+
242249
bool operator== (const Lock& other) const noexcept = default;
243250

244251
private:

cdoc/Recipient.cpp

Lines changed: 2 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,6 @@ using namespace std;
3030

3131
namespace libcdoc {
3232

33-
/**
34-
* @brief Prefix with what starts machine generated Lock's label.
35-
*/
36-
constexpr string_view LABELPREFIX{"data:"};
37-
38-
/**
39-
* @brief String after label prefix indicating, the rest of the label is Base64 encoded.
40-
*/
41-
constexpr string_view LABELBASE64IND{";base64,"};
42-
43-
/**
44-
* @brief EID type values for machine-readable label
45-
*/
46-
static constexpr std::string_view eid_strs[] = {
47-
"Unknown",
48-
"ID-card",
49-
"Digi-ID",
50-
"Digi-ID E-RESIDENT"
51-
};
52-
5333
Recipient
5434
Recipient::makeSymmetric(std::string label, int32_t kdf_iter)
5535
{
@@ -143,7 +123,7 @@ Recipient::isTheSameRecipient(const std::vector<uint8_t>& public_key) const
143123
static void
144124
buildLabel(std::ostream& ofs, std::string_view type, std::initializer_list<std::pair<std::string_view, std::string_view>> components)
145125
{
146-
ofs << LABELPREFIX;
126+
ofs << CDoc2::LABELPREFIX;
147127
ofs << "v" << '=' << std::to_string(CDoc2::KEYLABELVERSION) << '&'
148128
<< "type" << '=' << type;
149129
for (const auto& [key, value] : components) {
@@ -155,7 +135,7 @@ buildLabel(std::ostream& ofs, std::string_view type, std::initializer_list<std::
155135
static void
156136
BuildLabelEID(std::ostream& ofs, Certificate::EIDType type, const Certificate& x509)
157137
{
158-
buildLabel(ofs, eid_strs[type], {
138+
buildLabel(ofs, CDoc2::eid_strs[type], {
159139
{"cn", x509.getCommonName()},
160140
{"serial_number", x509.getSerialNumber()},
161141
{"last_name", x509.getSurname()},
@@ -238,59 +218,5 @@ Recipient::getLabel(const std::vector<std::pair<std::string_view, std::string_vi
238218
return ofs.str();
239219
}
240220

241-
map<string, string> Recipient::parseLabel(const string& label)
242-
{
243-
map<string, string> parsed_label;
244-
// Check if provided label starts with the machine generated label prefix.
245-
if (!label.starts_with(LABELPREFIX))
246-
{
247-
return parsed_label;
248-
}
249-
250-
string label_wo_prefix(label.substr(LABELPREFIX.size()));
251-
252-
// Label to be processed
253-
string label_to_prcss;
254-
255-
// We ignore mediatype part
256-
257-
// Check, if the label is Base64 encoded
258-
string::size_type base64IndPos = label_wo_prefix.find(LABELBASE64IND);
259-
if (base64IndPos == string::npos)
260-
{
261-
if (label_wo_prefix.starts_with(",")) {
262-
label_to_prcss = label_wo_prefix.substr(1);
263-
} else {
264-
label_to_prcss = std::move(label_wo_prefix);
265-
}
266-
}
267-
else
268-
{
269-
string base64_label(label_wo_prefix.substr(base64IndPos + LABELBASE64IND.size()));
270-
vector<uint8_t> decodedLabel(fromBase64(base64_label));
271-
label_to_prcss.assign(decodedLabel.cbegin(), decodedLabel.cend());
272-
}
273-
274-
vector<string> label_parts(split(label_to_prcss, '&'));
275-
for (vector<string>::const_reference part : label_parts)
276-
{
277-
vector<string> label_data_parts(split(part, '='));
278-
if (label_data_parts.size() != 2)
279-
{
280-
// Invalid label data. We just ignore them.
281-
LOG_ERROR("The label '{}' is invalid", label);
282-
}
283-
else
284-
{
285-
std::string key = urlDecode(label_data_parts[0]);
286-
std::string value = urlDecode(label_data_parts[1]);
287-
std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c){ return std::tolower(c); });
288-
parsed_label[key] = value;
289-
}
290-
}
291-
292-
return parsed_label;
293-
}
294-
295221
} // namespace libcdoc
296222

cdoc/Recipient.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,6 @@ struct CDOC_EXPORT Recipient {
235235
*/
236236
std::string getLabel(const std::vector<std::pair<std::string_view, std::string_view>> &extra) const;
237237

238-
/**
239-
* @brief parse machine-readable CDoc2 label
240-
* @param label the label
241-
* @return a map of key-value pairs
242-
*/
243-
static std::map<std::string, std::string> parseLabel(const std::string& label);
244-
245238
bool operator== (const Recipient& other) const = default;
246239
protected:
247240
Recipient(Type _type) : type(_type) {};

cdoc/Tar.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,9 @@ libcdoc::TarConsumer::writeHeader(const Header &h) noexcept {
153153
}
154154

155155
libcdoc::result_t
156-
libcdoc::TarConsumer::writeHeader(Header &h, const std::string& name, int64_t size) noexcept {
156+
libcdoc::TarConsumer::writeHeader(const std::string& name, int64_t size, char typeflag) noexcept {
157+
Header h {};
158+
h.typeflag = typeflag;
157159
h.chksum.fill(' ');
158160
size_t len = std::min(name.size(), h.name.size());
159161
std::copy_n(name.cbegin(), len, h.name.begin());
@@ -214,7 +216,6 @@ libcdoc::TarConsumer::open(const std::string& name, int64_t size)
214216

215217
_current_size = size;
216218
_current_written = 0;
217-
Header h {};
218219

219220
bool need_pax_name = (name.size() >= 100);
220221
for (auto c : name) {
@@ -225,7 +226,6 @@ libcdoc::TarConsumer::open(const std::string& name, int64_t size)
225226
}
226227
if(need_pax_name || size > 07777777) {
227228
LOG_DBG("Writing Pax header: name {} size {}", name, size);
228-
h.typeflag = 'x';
229229
std::string paxData;
230230
if(need_pax_name)
231231
paxData += toPaxRecord("path", name);
@@ -238,15 +238,14 @@ libcdoc::TarConsumer::open(const std::string& name, int64_t size)
238238
path = std::filesystem::path("./PaxHeaders.X") / path.filename();
239239
}
240240
LOG_DBG("Pax path: {}", path.string());
241-
if (auto rv = writeHeader(h, path.string(), paxData.size()); rv != OK)
241+
if (auto rv = writeHeader(path.string(), paxData.size(), 'x'); rv != OK)
242242
return rv;
243243
if (auto rv = _dst->write((const uint8_t *) paxData.data(), paxData.size()); rv != paxData.size())
244244
return rv < OK ? rv : OUTPUT_ERROR;
245245
if (auto rv = writePadding(paxData.size()); rv != OK)
246246
return rv;
247247
}
248-
h.typeflag = '0';
249-
return writeHeader(h, name, size);
248+
return writeHeader(name, size, '0');
250249
}
251250

252251
libcdoc::TarSource::TarSource(DataSource *src, bool take_ownership)
@@ -297,8 +296,8 @@ libcdoc::result_t
297296
libcdoc::TarSource::readPaxHeader(const Header& hdr, std::string& name, int64_t& size)
298297
{
299298
int64_t h_size = hdr.getSize();
300-
std::string paxData(h_size, 0);
301-
result_t result = _src->read((uint8_t *) paxData.data(), paxData.size());
299+
std::string paxData(h_size, 0);
300+
result_t result = _src->read((uint8_t *) paxData.data(), paxData.size());
302301
if (result != h_size) {
303302
_error = INPUT_STREAM_ERROR;
304303
return _error;

cdoc/Tar.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct TarConsumer final : public MultiDataConsumer
3737
libcdoc::result_t open(const std::string& name, int64_t size) final;
3838
private:
3939
result_t writeHeader(const Header &h) noexcept;
40-
result_t writeHeader(Header &h, const std::string& name, int64_t size) noexcept;
40+
result_t writeHeader(const std::string& name, int64_t size, char typeflag = '0') noexcept;
4141
result_t writePadding(int64_t size) noexcept;
4242

4343
DataConsumer *_dst;

examples/java/src/main/java/ee/ria/cdoc/CDocTool.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ static void locks(String path) {
369369
static void test() {
370370
System.err.println("Testing label generation");
371371
String label = "data:v=1&type=ID-card&serial_number=PNOEE-38001085718&cn=J%C3%95EORG%2CJAAK-KRISTJAN%2C38001085718";
372-
java.util.Map<String,String> map = Recipient.parseLabel(label);
372+
java.util.Map<String,String> map = ee.ria.cdoc.Lock.parseLabel(label);
373373
for (String key : map.keySet()) {
374374
System.err.format(" %s:%s\n", key, map.get(key));
375375
}

0 commit comments

Comments
 (0)