Skip to content

Commit d4c5c5d

Browse files
authored
Allow only qualified OCSP-s (#645)
IB-8298 Signed-off-by: Raul Metsma <[email protected]>
1 parent f90a086 commit d4c5c5d

14 files changed

+11794
-91
lines changed

src/crypto/TSL.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
#include "Conf.h"
2323
#include "XMLDocument.h"
2424
#include "crypto/Connect.h"
25+
#include "util/algorithm.h"
2526
#include "util/DateTime.h"
2627
#include "util/File.h"
2728

28-
#include <algorithm>
2929
#include <array>
3030
#include <charconv>
3131
#include <fstream>
@@ -80,18 +80,10 @@ constexpr array SERVICESTATUS_END {
8080

8181
constexpr array SERVICES_SUPPORTED {
8282
"http://uri.etsi.org/TrstSvc/Svctype/CA/QC",
83-
"http://uri.etsi.org/TrstSvc/Svctype/Certstatus/OCSP",
8483
"http://uri.etsi.org/TrstSvc/Svctype/Certstatus/OCSP/QC",
8584
"http://uri.etsi.org/TrstSvc/Svctype/TSA/QTST",
8685
};
8786

88-
template<typename C, typename T>
89-
[[nodiscard]]
90-
constexpr bool contains(const C &list, const T &value)
91-
{
92-
return find(list.begin(), list.end(), value) != list.end();
93-
}
94-
9587
}
9688

9789

@@ -212,6 +204,7 @@ vector<TSL::Service> TSL::parse()
212204
vector<TSL::Service> TSL::parse(const string &url, const vector<X509Cert> &certs,
213205
const string &cache, const string &territory)
214206
{
207+
vector<Service> list;
215208
try {
216209
TSL tsl = parseTSL(url, certs, cache, territory);
217210
if(tsl.pointers().empty())
@@ -226,20 +219,19 @@ vector<TSL::Service> TSL::parse(const string &url, const vector<X509Cert> &certs
226219
return parse(p.location, p.certs, cache, p.territory + ".xml");
227220
}));
228221
}
229-
vector<Service> list;
230222
for(auto &f: futures)
231223
{
232224
vector<Service> services = f.get();
233225
list.insert(list.end(), make_move_iterator(services.begin()), make_move_iterator(services.end()));
234226
}
235-
return list;
236227
}
237228
catch(const Exception &e)
238229
{
239230
debugException(e);
240231
ERR("TSL %s Failed to validate list", territory.c_str());
241-
return {};
232+
list.clear();
242233
}
234+
return list;
243235
}
244236

245237
TSL TSL::parseTSL(const string &url, const vector<X509Cert> &certs,

src/crypto/X509CertStore.cpp

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,17 @@
2323
#include "crypto/Connect.h"
2424
#include "crypto/OpenSSLHelpers.h"
2525
#include "crypto/TSL.h"
26+
#include "util/algorithm.h"
2627
#include "util/DateTime.h"
2728
#include "util/log.h"
2829

2930
#include <openssl/conf.h>
3031
#include <openssl/ssl.h>
3132
#include <openssl/x509v3.h>
3233

33-
#include <algorithm>
34-
3534
using namespace digidoc;
3635
using namespace std;
3736

38-
template<typename C, typename T>
39-
[[nodiscard]]
40-
constexpr bool contains(const C &list, const T &value)
41-
{
42-
return find(list.begin(), list.end(), std::forward<decltype(value)>(value)) != list.end();
43-
};
44-
4537
const X509CertStore::Type X509CertStore::CA {
4638
"http://uri.etsi.org/TrstSvc/Svctype/CA/QC",
4739
};
@@ -52,7 +44,6 @@ const X509CertStore::Type X509CertStore::TSA {
5244

5345
const X509CertStore::Type X509CertStore::OCSP {
5446
"http://uri.etsi.org/TrstSvc/Svctype/CA/QC",
55-
"http://uri.etsi.org/TrstSvc/Svctype/Certstatus/OCSP",
5647
"http://uri.etsi.org/TrstSvc/Svctype/Certstatus/OCSP/QC",
5748
};
5849

@@ -181,7 +172,7 @@ int X509CertStore::validate(int ok, X509_STORE_CTX *ctx, const Type &type)
181172
{
182173
if(type.find(s.type) == type.cend())
183174
continue;
184-
if(none_of(s.certs.cbegin(), s.certs.cend(), [&](const X509Cert &issuer){
175+
if(none_of(s.certs, [&](const X509Cert &issuer) {
185176
if(issuer == x509)
186177
return true;
187178
if(X509_check_issued(issuer.handle(), x509) != X509_V_OK)
@@ -254,13 +245,13 @@ bool X509CertStore::verify(const X509Cert &cert, bool noqscd) const
254245
bool isESeal = // Special treamtent for E-Seals
255246
contains(policies, X509Cert::QCP_LEGAL) ||
256247
contains(qcstatement, X509Cert::QCT_ESEAL);
257-
auto matchPolicySet = [&policies](const vector<string> &policySet){
258-
return all_of(policySet.cbegin(), policySet.cend(), [&policies](const string &policy) {
248+
auto matchPolicySet = [&policies](const vector<string> &policySet) {
249+
return all_of(policySet, [&policies](const string &policy) {
259250
return contains(policies, policy);
260251
});
261252
};
262-
auto matchKeyUsageSet = [&keyUsage](const map<X509Cert::KeyUsage,bool> &keyUsageSet){
263-
return all_of(keyUsageSet.cbegin(), keyUsageSet.cend(), [&keyUsage](pair<X509Cert::KeyUsage, bool> keyUsageBit){
253+
auto matchKeyUsageSet = [&keyUsage](const map<X509Cert::KeyUsage,bool> &keyUsageSet) {
254+
return all_of(keyUsageSet, [&keyUsage](pair<X509Cert::KeyUsage, bool> keyUsageBit) {
264255
return contains(keyUsage, keyUsageBit.first) == keyUsageBit.second;
265256
});
266257
};
@@ -269,14 +260,14 @@ bool X509CertStore::verify(const X509Cert &cert, bool noqscd) const
269260
{
270261
if(q.assert_ == "all")
271262
{
272-
if(!(all_of(q.policySet.cbegin(), q.policySet.cend(), matchPolicySet) &&
273-
all_of(q.keyUsage.cbegin(), q.keyUsage.cend(), matchKeyUsageSet)))
263+
if(!(all_of(q.policySet, matchPolicySet) &&
264+
all_of(q.keyUsage, matchKeyUsageSet)))
274265
continue;
275266
}
276267
else if(q.assert_ == "atLeastOne")
277268
{
278-
if(!(any_of(q.policySet.cbegin(), q.policySet.cend(), matchPolicySet) ||
279-
any_of(q.keyUsage.cbegin(), q.keyUsage.cend(), matchKeyUsageSet)))
269+
if(!(any_of(q.policySet, matchPolicySet) ||
270+
any_of(q.keyUsage, matchKeyUsageSet)))
280271
continue;
281272
}
282273
else

src/util/algorithm.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* libdigidocpp
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17+
*
18+
*/
19+
20+
#pragma once
21+
22+
#include <algorithm>
23+
24+
namespace digidoc
25+
{
26+
27+
template<typename C, typename P>
28+
[[nodiscard]]
29+
constexpr bool all_of(const C &list, P pred)
30+
{
31+
return std::all_of(list.begin(), list.end(), std::forward<P>(pred));
32+
}
33+
34+
template<typename C, typename P>
35+
[[nodiscard]]
36+
constexpr bool any_of(const C &list, P pred)
37+
{
38+
return std::any_of(list.begin(), list.end(), std::forward<P>(pred));
39+
}
40+
41+
template<typename C, typename T>
42+
[[nodiscard]]
43+
constexpr bool contains(const C &list, T value)
44+
{
45+
return std::find(list.begin(), list.end(), std::forward<T>(value)) != list.end();
46+
}
47+
48+
template<typename C, typename P>
49+
[[nodiscard]]
50+
constexpr bool none_of(const C &list, P pred)
51+
{
52+
return std::none_of(list.begin(), list.end(), std::forward<P>(pred));
53+
}
54+
55+
template<typename T>
56+
[[nodiscard]]
57+
constexpr bool starts_with(T str, T needle) {
58+
return str.size() >= needle.size() && str.compare(0, needle.size(), needle) == 0;
59+
}
60+
61+
}

test/CMakeLists.txt

Lines changed: 24 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -17,64 +17,28 @@ add_test(NAME runtest
1717
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/unittests --build_info=YES --report_level=no --logger=${TEST_FORMAT},all,${CMAKE_CURRENT_BINARY_DIR}/libdigidocpp.xml -- ${CMAKE_CURRENT_SOURCE_DIR}/data
1818
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
1919
)
20-
add_test(NAME TSLTest_CA-invalid-type
21-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-CA-invalid-type.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
22-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
23-
)
24-
add_test(NAME TSLTest_CA-non-qa
25-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-CA-non-qa.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
26-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
27-
)
28-
add_test(NAME TSLTest_CA-withdrawn
29-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-CA-withdrawn.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
30-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
31-
)
32-
add_test(NAME TSLTest_CA-withdrawn-granted-before
33-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-CA-withdrawn-granted-before.xml good ${CMAKE_CURRENT_SOURCE_DIR}/data
34-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
35-
)
36-
add_test(NAME TSLTest_CA-withdrawn-granted-later
37-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-CA-withdrawn-granted-later.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
38-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
39-
)
40-
add_test(NAME TSLTest_OCSP-invalid-type
41-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-OCSP-invalid-type.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
42-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
43-
)
44-
add_test(NAME TSLTest_OCSP-withdrawn
45-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-OCSP-withdrawn.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
46-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
47-
)
48-
add_test(NAME TSLTest_OCSP-withdrawn-granted-before
49-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-OCSP-withdrawn-granted-before.xml good ${CMAKE_CURRENT_SOURCE_DIR}/data
50-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
51-
)
52-
add_test(NAME TSLTest_OCSP-withdrawn-granted-later
53-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-OCSP-withdrawn-granted-later.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
54-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
55-
)
56-
add_test(NAME TSLTest_TSA-invalid-type
57-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-TSA-invalid-type.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
58-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
59-
)
60-
add_test(NAME TSLTest_TSA-withdrawn
61-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-TSA-withdrawn.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
62-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
63-
)
64-
add_test(NAME TSLTest_TSA-withdrawn-granted-before
65-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-TSA-withdrawn-granted-before.xml good ${CMAKE_CURRENT_SOURCE_DIR}/data
66-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
67-
)
68-
add_test(NAME TSLTest_TSA-withdrawn-granted-later
69-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-TSA-withdrawn-granted-later.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
70-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
71-
)
72-
add_test(NAME TSLTest_EE_T-no_QCStatement
73-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-no_QCStatement.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
74-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
75-
)
76-
add_test(NAME TSLTest_EE_T-no_QCSD
77-
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-no_QCSD.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
78-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
79-
)
20+
21+
# Bad status tests
22+
foreach(TEST CA-non-qa no_QCStatement no_QCSD
23+
CA-invalid-type CA-withdrawn CA-granted-later CA-withdrawn-granted-later CA-noqscd-granted-later
24+
OCSP-invalid-type OCSP-withdrawn OCSP-granted-later OCSP-withdrawn-granted-later OCSP-noqscd-granted-later
25+
TSA-invalid-type TSA-withdrawn TSA-granted-later TSA-withdrawn-granted-later TSA-noqscd-granted-later
26+
)
27+
add_test(NAME TSLTest_${TEST}
28+
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-${TEST}.xml bad ${CMAKE_CURRENT_SOURCE_DIR}/data
29+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
30+
)
31+
endforeach()
32+
33+
# Good status tests
34+
foreach(TEST CA-withdrawn-granted-before CA-noqscd-granted-before
35+
OCSP-withdrawn-granted-before OCSP-noqscd-granted-before
36+
TSA-withdrawn-granted-before TSA-noqscd-granted-before
37+
)
38+
add_test(NAME TSLTest_${TEST}
39+
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/TSLTests -- EE_T-${TEST}.xml good ${CMAKE_CURRENT_SOURCE_DIR}/data
40+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
41+
)
42+
endforeach()
43+
8044
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS unittests TSLTests)

0 commit comments

Comments
 (0)