Skip to content

Commit d86c0d9

Browse files
committed
Add backwards compatibility with servers without x-expiry-time
MOPPAND-1717 Signed-off-by: Raul Metsma <[email protected]>
1 parent 19d61d9 commit d86c0d9

File tree

5 files changed

+81
-96
lines changed

5 files changed

+81
-96
lines changed

cdoc/Certificate.cpp

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,32 +89,51 @@ Certificate::getNotAfter() const
8989
#endif
9090
}
9191

92-
93-
94-
std::vector<std::string>
95-
Certificate::policies() const
92+
Certificate::EIDType
93+
Certificate::getEIDType() const
9694
{
97-
constexpr int PolicyBufferLen = 50;
98-
std::vector<std::string> list;
99-
10095
if(!cert)
101-
return list;
96+
return Unknown;
10297

10398
auto cp = make_unique_cast<CERTIFICATEPOLICIES_free>(X509_get_ext_d2i(
10499
cert.get(), NID_certificate_policies, nullptr, nullptr));
105100
if(!cp)
106-
return list;
101+
return Unknown;
107102

103+
constexpr int PolicyBufferLen = 50;
104+
char buf[PolicyBufferLen + 1]{};
108105
for(int i = 0; i < sk_POLICYINFO_num(cp.get()); i++) {
109106
POLICYINFO *pi = sk_POLICYINFO_value(cp.get(), i);
110-
char buf[PolicyBufferLen + 1]{};
111107
int len = OBJ_obj2txt(buf, PolicyBufferLen, pi->policyid, 1);
112-
if(len != NID_undef) {
113-
list.push_back(std::string(buf));
108+
if(len == NID_undef) {
109+
continue;
110+
}
111+
112+
std::string_view policy(buf, size_t(len));
113+
if (policy.starts_with("2.999.")) { // Zetes TEST OID prefix
114+
policy = policy.substr(6);
115+
}
116+
117+
if (policy.starts_with("1.3.6.1.4.1.51361.1.1.3") ||
118+
policy.starts_with("1.3.6.1.4.1.51361.1.2.3")) {
119+
return DigiID;
120+
}
121+
122+
if (policy.starts_with("1.3.6.1.4.1.51361.1.1.4") ||
123+
policy.starts_with("1.3.6.1.4.1.51361.1.2.4")) {
124+
return DigiID_EResident;
125+
}
126+
127+
if (policy.starts_with("1.3.6.1.4.1.51361.1.1") ||
128+
policy.starts_with("1.3.6.1.4.1.51455.1.1") ||
129+
policy.starts_with("1.3.6.1.4.1.51361.1.2") ||
130+
policy.starts_with("1.3.6.1.4.1.51455.1.2")) {
131+
return IDCard;
114132
}
115133
}
116134

117-
return list;
135+
// If the execution reaches so far then EID type determination failed.
136+
return Unknown;
118137
}
119138

120139
std::vector<uint8_t>

cdoc/Certificate.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,18 @@ namespace libcdoc {
3232

3333
class Certificate {
3434
public:
35-
enum Algorithm {
35+
enum Algorithm : unsigned char {
3636
RSA,
3737
ECC
3838
};
3939

40+
enum EIDType : unsigned char {
41+
Unknown,
42+
IDCard,
43+
DigiID,
44+
DigiID_EResident
45+
};
46+
4047
unique_free_t<X509> cert;
4148

4249
explicit Certificate(const std::vector<uint8_t>& cert);
@@ -46,7 +53,7 @@ class Certificate {
4653
std::string getSurname() const;
4754
std::string getSerialNumber() const;
4855

49-
std::vector<std::string> policies() const;
56+
EIDType getEIDType() const;
5057

5158
std::vector<uint8_t> getPublicKey() const;
5259
Algorithm getAlgorithm() const;

cdoc/NetworkBackend.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ libcdoc::NetworkBackend::sendKey (CapsuleInfo& dst, const std::string& url, cons
293293
if (expiry_ts) {
294294
std::string expiry_str = timeToISO(expiry_ts);
295295
LOG_DBG("Expiry time: {}", expiry_str);
296-
hdrs.emplace(std::make_pair("x-expiry-time", expiry_str));
296+
hdrs.emplace("x-expiry-time", expiry_str);
297297
}
298298
httplib::Response rsp;
299299
result = post(cli, full, hdrs, req_str, rsp);
@@ -306,12 +306,18 @@ libcdoc::NetworkBackend::sendKey (CapsuleInfo& dst, const std::string& url, cons
306306
}
307307
error = {};
308308
/* Remove /key-capsules/ */
309-
dst.transaction_id = location.substr(14);
309+
location.erase(14);
310+
dst.transaction_id = std::move(location);
310311

311312
std::string expiry_str = rsp.get_header_value("x-expiry-time");
312313
LOG_DBG("Server expiry: {}", expiry_str);
313-
dst.expiry_time = uint64_t(timeFromISO(expiry_str));
314-
LOG_DBG("Server expiry timestamp: {}", dst.expiry_time);
314+
if (!expiry_str.empty()) {
315+
dst.expiry_time = uint64_t(timeFromISO(expiry_str));
316+
LOG_DBG("Server expiry timestamp: {}", dst.expiry_time);
317+
} else {
318+
dst.expiry_time = expiry_ts;
319+
LOG_DBG("Given expiry timestamp: {}", dst.expiry_time);
320+
}
315321

316322
return OK;
317323
}

cdoc/Recipient.cpp

Lines changed: 26 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
#include "ILogger.h"
2525
#include "Utils.h"
2626

27+
#include <algorithm>
28+
#include <chrono>
29+
2730
using namespace std;
2831

2932
namespace libcdoc {
@@ -58,7 +61,7 @@ Recipient::makeSymmetric(std::string label, int32_t kdf_iter)
5861
}
5962

6063
Recipient
61-
Recipient::makePublicKey(std::string label, const std::vector<uint8_t>& public_key, PKType pk_type)
64+
Recipient::makePublicKey(std::string label, std::vector<uint8_t> public_key, PKType pk_type)
6265
{
6366
if (public_key.empty()) return Recipient(Type::NONE);
6467
Recipient rcpt(Type::PUBLIC_KEY);
@@ -69,18 +72,18 @@ Recipient::makePublicKey(std::string label, const std::vector<uint8_t>& public_k
6972
auto evp = Crypto::fromECPublicKeyDer(public_key);
7073
rcpt.rcpt_key = Crypto::toPublicKeyDer(evp.get());
7174
} else {
72-
rcpt.rcpt_key = public_key;
75+
rcpt.rcpt_key = std::move(public_key);
7376
}
7477
return rcpt;
7578
}
7679

7780
Recipient
7881
Recipient::makeCertificate(std::string label, std::vector<uint8_t> cert)
7982
{
83+
Certificate x509(cert);
8084
Recipient rcpt(Type::PUBLIC_KEY);
8185
rcpt.label = std::move(label);
8286
rcpt.cert = std::move(cert);
83-
Certificate x509(rcpt.cert);
8487
rcpt.rcpt_key = x509.getPublicKey();
8588
rcpt.pk_type = (x509.getAlgorithm() == libcdoc::Certificate::RSA) ? PKType::RSA : PKType::ECC;
8689
rcpt.expiry_ts = x509.getNotAfter();
@@ -90,36 +93,32 @@ Recipient::makeCertificate(std::string label, std::vector<uint8_t> cert)
9093
Recipient
9194
Recipient::makeServer(std::string label, std::vector<uint8_t> public_key, PKType pk_type, std::string server_id)
9295
{
93-
Recipient rcpt(Type::PUBLIC_KEY);
94-
rcpt.label = std::move(label);
95-
rcpt.pk_type = pk_type;
96-
if (pk_type == PKType::ECC && public_key[0] == 0x30) {
97-
// 0x30 identifies SEQUENCE tag in ASN.1 encoding
98-
auto evp = Crypto::fromECPublicKeyDer(public_key);
99-
rcpt.rcpt_key = Crypto::toPublicKeyDer(evp.get());
100-
} else {
101-
rcpt.rcpt_key = std::move(public_key);
102-
}
96+
Recipient rcpt = makePublicKey(std::move(label), std::move(public_key), pk_type);
10397
rcpt.server_id = std::move(server_id);
98+
const auto six_months_from_now = std::chrono::system_clock::now() + std::chrono::months(6);
99+
const auto expiry_ts = std::chrono::system_clock::to_time_t(six_months_from_now);
100+
rcpt.expiry_ts = uint64_t(expiry_ts);
104101
return rcpt;
105102
}
106103

107104
Recipient
108105
Recipient::makeServer(std::string label, std::vector<uint8_t> cert, std::string server_id)
109106
{
110-
Certificate x509(cert);
111-
Recipient rcpt = makeServer(std::move(label), x509.getPublicKey(), x509.getAlgorithm() == Certificate::Algorithm::RSA ? RSA : ECC, std::move(server_id));
112-
rcpt.cert = cert;
113-
return std::move(rcpt);
107+
Recipient rcpt = makeCertificate(std::move(label), std::move(cert));
108+
rcpt.server_id = std::move(server_id);
109+
const auto six_months_from_now = std::chrono::system_clock::now() + std::chrono::months(6);
110+
const auto expiry_ts = std::chrono::system_clock::to_time_t(six_months_from_now);
111+
rcpt.expiry_ts = std::min(rcpt.expiry_ts, uint64_t(expiry_ts));
112+
return rcpt;
114113
}
115114

116115
Recipient
117-
Recipient::makeShare(const std::string& label, const std::string& server_id, const std::string& recipient_id)
116+
Recipient::makeShare(std::string label, std::string server_id, std::string recipient_id)
118117
{
119118
Recipient rcpt(Type::KEYSHARE);
120-
rcpt.label = label;
121-
rcpt.server_id = server_id;
122-
rcpt.id = recipient_id;
119+
rcpt.label = std::move(label);
120+
rcpt.server_id = std::move(server_id);
121+
rcpt.id = std::move(recipient_id);
123122
return rcpt;
124123
}
125124

@@ -139,54 +138,20 @@ Recipient::isTheSameRecipient(const std::vector<uint8_t>& public_key) const
139138
return rcpt_key == public_key;
140139
}
141140

142-
static Recipient::EIDType
143-
getEIDType(const std::vector<std::string>& policies)
144-
{
145-
for (const auto& pol : policies)
146-
{
147-
std::string_view policy = pol;
148-
if (policy.starts_with("2.999.")) { // Zetes TEST OID prefix
149-
policy = policy.substr(6);
150-
}
151-
152-
if (policy.starts_with("1.3.6.1.4.1.51361.1.1.3") ||
153-
policy.starts_with("1.3.6.1.4.1.51361.1.2.3")) {
154-
return Recipient::EIDType::DigiID;
155-
}
156-
157-
if (policy.starts_with("1.3.6.1.4.1.51361.1.1.4") ||
158-
policy.starts_with("1.3.6.1.4.1.51361.1.2.4")) {
159-
return Recipient::EIDType::DigiID_EResident;
160-
}
161-
162-
if (policy.starts_with("1.3.6.1.4.1.51361.1.1") ||
163-
policy.starts_with("1.3.6.1.4.1.51455.1.1") ||
164-
policy.starts_with("1.3.6.1.4.1.51361.1.2") ||
165-
policy.starts_with("1.3.6.1.4.1.51455.1.2")) {
166-
return Recipient::EIDType::IDCard;
167-
}
168-
}
169-
170-
// If the execution reaches so far then EID type determination failed.
171-
return Recipient::EIDType::Unknown;
172-
}
173-
174141
static void
175142
buildLabel(std::ostream& ofs, std::string_view type, const std::initializer_list<std::pair<std::string_view, std::string_view>> &components)
176143
{
177144
ofs << LABELPREFIX;
178145
ofs << "v" << '=' << std::to_string(CDoc2::KEYLABELVERSION) << '&'
179146
<< "type" << '=' << type;
180147
for (auto& [key, value] : components) {
181-
if (value.empty())
182-
continue;
183-
ofs << '&';
184-
ofs << urlEncode(key) << '=' << urlEncode(value);
148+
if (!value.empty())
149+
ofs << '&' << urlEncode(key) << '=' << urlEncode(value);
185150
}
186151
}
187152

188153
static void
189-
BuildLabelEID(std::ostream& ofs, Recipient::EIDType type, const Certificate& x509)
154+
BuildLabelEID(std::ostream& ofs, Certificate::EIDType type, const Certificate& x509)
190155
{
191156
buildLabel(ofs, eid_strs[type], {
192157
{"cn", x509.getCommonName()},
@@ -251,7 +216,7 @@ Recipient::getLabel(const std::vector<std::pair<std::string_view, std::string_vi
251216
case PUBLIC_KEY:
252217
if (!cert.empty()) {
253218
Certificate x509(cert);
254-
if (auto type = getEIDType(x509.policies()); type != EIDType::Unknown) {
219+
if (auto type = x509.getEIDType(); type != Certificate::Unknown) {
255220
BuildLabelEID(ofs, type, x509);
256221
} else {
257222
BuildLabelCertificate(ofs, file_name, x509);
@@ -264,10 +229,8 @@ Recipient::getLabel(const std::vector<std::pair<std::string_view, std::string_vi
264229
break;
265230
}
266231
for (auto& [key, value] : extra) {
267-
if (value.empty())
268-
continue;
269-
ofs << '&';
270-
ofs << urlEncode(key) << '=' << urlEncode(value);
232+
if (!value.empty())
233+
ofs << '&' << urlEncode(key) << '=' << urlEncode(value);
271234
}
272235
LOG_DBG("Generated label: {}", ofs.str());
273236
return ofs.str();

cdoc/Recipient.h

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct CDOC_EXPORT Recipient {
3737
/**
3838
* @brief The recipient type
3939
*/
40-
enum Type : unsigned char {
40+
enum Type : uint8_t {
4141
/**
4242
* Uninitialized recipient
4343
*/
@@ -59,7 +59,7 @@ struct CDOC_EXPORT Recipient {
5959
/**
6060
* @brief The public key type
6161
*/
62-
enum PKType : unsigned char {
62+
enum PKType : uint8_t {
6363
/**
6464
* Elliptic curve
6565
*/
@@ -70,16 +70,6 @@ struct CDOC_EXPORT Recipient {
7070
RSA
7171
};
7272

73-
/**
74-
* @brief The EID type
75-
*/
76-
enum EIDType : unsigned char {
77-
Unknown,
78-
IDCard,
79-
DigiID,
80-
DigiID_EResident
81-
};
82-
8373
Recipient() = default;
8474

8575
/**
@@ -193,7 +183,7 @@ struct CDOC_EXPORT Recipient {
193183
* @param pk_type the algorithm type (either ECC or RSA)
194184
* @return a new Recipient structure
195185
*/
196-
static Recipient makePublicKey(std::string label, const std::vector<uint8_t>& public_key, PKType pk_type);
186+
static Recipient makePublicKey(std::string label, std::vector<uint8_t> public_key, PKType pk_type);
197187
/**
198188
* @brief Create a new certificate based Recipient
199189
* @param label the label text
@@ -233,7 +223,7 @@ struct CDOC_EXPORT Recipient {
233223
* @param recipient_id the recipient id (PNOEE-01234567890)
234224
* @return Recipient a new Recipient structure
235225
*/
236-
static Recipient makeShare(const std::string& label, const std::string& server_id, const std::string& recipient_id);
226+
static Recipient makeShare(std::string label, std::string server_id, std::string recipient_id);
237227

238228
/**
239229
* @brief Get the label for this recipient

0 commit comments

Comments
 (0)