Skip to content

Commit 2d719a9

Browse files
authored
Hostname verification (djarek#67)
* Add failing Test * Fix Testnames in Cmake Config * Set Servername for OpenSSL in Tests Makes the wrong hostname test work for system that do not need the native verification * Set Verification Callback via SSL_CTX_set_verify Also remove some unnecessary functions in verification_utils.hpp This fixes hostname verification on systems that use the native implementations * Update Github Test Chain Test failed with "self signed certificate in certificate chain in function" * Silence Conversion Warning size_t->DWORD * Add missing openssl includes * Fix error in appveyor build X509_STORE_get0_param was only introduced in OpenSSL1.1.0 The Appveyor build uses OpenSSL 1.0.2 Use X509_STORE_CTX_get0_param from within store_ctx instead * Fix spki digest test I previously updated the old (expired) Github cert chain, inadvertently breaking the test. Re-add it to the fail_chains and adapt the test report_errors.
1 parent a1bd27f commit 2d719a9

File tree

9 files changed

+213
-145
lines changed

9 files changed

+213
-145
lines changed

include/boost/certify/detail/keystore_windows.ipp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ BOOST_CERTIFY_DECL std::unique_ptr<::CERT_CONTEXT const, cert_context_deleter>
9696
if (!CertAddEncodedCertificateToStore(store.get(),
9797
X509_ASN_ENCODING,
9898
buffer.data(),
99-
buffer.size(),
99+
static_cast<DWORD>(buffer.size()),
100100
CERT_STORE_ADD_ALWAYS,
101101
&leaf_cert))
102102
return nullptr;
@@ -110,7 +110,7 @@ BOOST_CERTIFY_DECL std::unique_ptr<::CERT_CONTEXT const, cert_context_deleter>
110110
if (!CertAddEncodedCertificateToStore(store.get(),
111111
X509_ASN_ENCODING,
112112
buffer.data(),
113-
buffer.size(),
113+
static_cast<DWORD>(buffer.size()),
114114
CERT_STORE_ADD_ALWAYS,
115115
nullptr))
116116
return nullptr;

include/boost/certify/https_verification.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ set_server_hostname(::SSL* handle,
2222
system::error_code& ec);
2323

2424
extern "C" inline int
25-
verify_server_certificates(::X509_STORE_CTX* ctx, void*) noexcept;
25+
verify_server_certificates(int preverified, X509_STORE_CTX* ctx) noexcept;
2626

2727
} // namespace detail
2828
} // namespace certify

include/boost/certify/impl/https_verification.ipp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
#ifndef BOOST_CERTIFY_IMPL_RFC2818_VERIFICATION_IPP
2-
#define BOOST_CERTIFY_IMPL_RFC2818_VERIFICATION_IPP
1+
#ifndef BOOST_CERTIFY_IMPL_HTTPS_VERIFICATION_IPP
2+
#define BOOST_CERTIFY_IMPL_HTTPS_VERIFICATION_IPP
33

44
#include <boost/certify/https_verification.hpp>
55

66
#include <boost/asio/ip/address.hpp>
7-
#include <openssl/x509v3.h>
7+
#include <openssl/ssl.h>
8+
#include <openssl/x509_vfy.h>
89

910
namespace boost
1011
{
@@ -14,9 +15,9 @@ namespace detail
1415
{
1516

1617
extern "C" BOOST_CERTIFY_DECL int
17-
verify_server_certificates(::X509_STORE_CTX* ctx, void*) noexcept
18+
verify_server_certificates(int preverified, X509_STORE_CTX* ctx) noexcept
1819
{
19-
if (::X509_verify_cert(ctx) == 1)
20+
if (preverified == 1)
2021
return true;
2122

2223
auto const err = ::X509_STORE_CTX_get_error(ctx);
@@ -33,9 +34,8 @@ verify_server_certificates(::X509_STORE_CTX* ctx, void*) noexcept
3334
}
3435

3536
void
36-
set_server_hostname(::SSL* handle, string_view hostname, system::error_code& ec)
37+
set_server_hostname(::X509_VERIFY_PARAM* param, string_view hostname, system::error_code& ec)
3738
{
38-
auto* param = ::SSL_get0_param(handle);
3939
::X509_VERIFY_PARAM_set_hostflags(param,
4040
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
4141
// TODO(djarek): OpenSSL doesn't report an error here?
@@ -46,16 +46,25 @@ set_server_hostname(::SSL* handle, string_view hostname, system::error_code& ec)
4646
ec = {};
4747
}
4848

49+
void
50+
set_server_hostname(::SSL* handle, string_view hostname, system::error_code& ec)
51+
{
52+
auto* param = ::SSL_get0_param(handle);
53+
set_server_hostname(param, hostname, ec);
54+
}
55+
56+
4957
} // namespace detail
5058

5159
BOOST_CERTIFY_DECL void
5260
enable_native_https_server_verification(asio::ssl::context& context)
5361
{
54-
::SSL_CTX_set_cert_verify_callback(
55-
context.native_handle(), &detail::verify_server_certificates, nullptr);
62+
::SSL_CTX_set_verify(context.native_handle(),
63+
::SSL_CTX_get_verify_mode(context.native_handle()),
64+
&detail::verify_server_certificates);
5665
}
5766

5867
} // namespace certify
5968
} // namespace boost
6069

61-
#endif // BOOST_CERTIFY_IMPL_RFC2818_VERIFICATION_IPP
70+
#endif // BOOST_CERTIFY_IMPL_HTTPS_VERIFICATION_IPP

tests/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ function (certify_verify_add_test test_file)
1111
COMMAND ${target_name})
1212
endfunction(certify_verify_add_test)
1313

14-
certify_verify_add_test(rfc2818_verification_success.cpp)
15-
certify_verify_add_test(rfc2818_verification_fail.cpp)
14+
certify_verify_add_test(https_verification_success.cpp)
15+
certify_verify_add_test(https_verification_fail.cpp)

tests/detail_spki_digest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ main()
99
::SSL_library_init();
1010

1111
auto chain = boost::certify::certificate_chain::from_file(
12-
"libs/certify/tests/res/success_chains/github.com.crt");
12+
"libs/certify/tests/res/fail_chains/github.com.crt");
1313

1414
std::array<std::array<unsigned char, 32>, 3> const expected = {
1515
{{{0xa3, 0x9a, 0x1a, 0xe4, 0x5e, 0x0b, 0x6d, 0x91, 0x1f, 0x79, 0x9d,

tests/extras/include/boost/certify/verification_utils.hpp

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1+
#ifndef BOOST_CERTIFY_VERIFICATION_UTILS_HPP
2+
#define BOOST_CERTIFY_VERIFICATION_UTILS_HPP
3+
14
#include <boost/certify/https_verification.hpp>
25

36
#include <boost/asio/ssl/error.hpp>
47
#include <boost/filesystem/operations.hpp>
58
#include <boost/filesystem/path.hpp>
69
#include <boost/system/error_code.hpp>
10+
#include <boost/utility/string_view.hpp>
11+
#include <openssl/pem.h>
12+
#include <openssl/x509.h>
713

814
namespace boost
915
{
@@ -125,9 +131,6 @@ get_store_ctx_category()
125131
return instance;
126132
}
127133

128-
extern "C" inline int
129-
verify_callback(int preverified, X509_STORE_CTX* ctx);
130-
131134
class store_ctx
132135
{
133136
public:
@@ -154,6 +157,8 @@ class store_ctx
154157
boost::asio::error::get_ssl_category()};
155158
boost::throw_exception(system::system_error{ec});
156159
}
160+
::X509_STORE_CTX_set_verify_cb(handle_.get(),
161+
&detail::verify_server_certificates);
157162
}
158163

159164
store_ctx(store_ctx const&) = delete;
@@ -164,25 +169,23 @@ class store_ctx
164169

165170
~store_ctx() = default;
166171

167-
template<typename T>
168-
void set_verify_callback(T&& t)
172+
native_handle_type native_handle() const
169173
{
170-
callback_ = std::forward<T>(t);
171-
::X509_STORE_CTX_set_verify_cb(handle_.get(), &verify_callback);
172-
auto const ret =
173-
::X509_STORE_CTX_set_ex_data(handle_.get(), get_ex_index(), this);
174-
assert(ret == 1);
174+
return handle_.get();
175175
}
176176

177-
native_handle_type native_handle() const
177+
void set_server_hostname(string_view hostname)
178178
{
179-
return handle_.get();
179+
auto* param = ::X509_STORE_CTX_get0_param(handle_.get());
180+
system::error_code ec;
181+
detail::set_server_hostname(param, hostname, ec);
182+
if (ec)
183+
boost::throw_exception(system::system_error{ec});
180184
}
181185

182186
void verify(system::error_code& ec)
183187
{
184-
auto ret =
185-
certify::detail::verify_server_certificates(handle_.get(), nullptr);
188+
auto ret = ::X509_verify_cert(handle_.get());
186189
if (ret != 1)
187190
{
188191
auto const err = ::X509_STORE_CTX_get_error(handle_.get());
@@ -201,18 +204,6 @@ class store_ctx
201204
}
202205

203206
private:
204-
friend int verify_callback(int preverified, X509_STORE_CTX* ctx);
205-
206-
static int get_ex_index()
207-
{
208-
static int const index = []() {
209-
return ::X509_STORE_CTX_get_ex_new_index(
210-
0, nullptr, nullptr, nullptr, nullptr);
211-
}();
212-
213-
return index;
214-
}
215-
216207
struct free
217208
{
218209
void operator()(native_handle_type h)
@@ -222,19 +213,8 @@ class store_ctx
222213
};
223214

224215
std::unique_ptr<::X509_STORE_CTX, free> handle_;
225-
std::function<int(bool, boost::asio::ssl::verify_context&)> callback_;
226216
};
227217

228-
extern "C" inline int
229-
verify_callback(int preverified, X509_STORE_CTX* ctx)
230-
{
231-
boost::asio::ssl::verify_context verify_ctx{ctx};
232-
void* const p = X509_STORE_CTX_get_ex_data(ctx, store_ctx::get_ex_index());
233-
BOOST_ASSERT(p != nullptr);
234-
auto& sctx = *static_cast<store_ctx*>(p);
235-
return sctx.callback_(preverified == 1, verify_ctx);
236-
}
237-
238218
void
239219
verify_chain(boost::filesystem::path const& chain_path,
240220
boost::certify::certificate_store& store,
@@ -245,8 +225,12 @@ verify_chain(boost::filesystem::path const& chain_path,
245225

246226
auto cert_chain = boost::certify::certificate_chain::from_file(chain_path);
247227
boost::certify::store_ctx ctx{cert_chain, store};
228+
ctx.set_server_hostname(chain_path.stem().string());
248229
ctx.verify(ec);
249230
}
250231

251232
} // namespace certify
252233
} // namespace boost
234+
235+
#endif // BOOST_CERTIFY_VERIFICATION_UTILS_HPP
236+
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
Old certificate chain, expired Jun 03, 2020.
2+
-----BEGIN CERTIFICATE-----
3+
MIIHQjCCBiqgAwIBAgIQCgYwQn9bvO1pVzllk7ZFHzANBgkqhkiG9w0BAQsFADB1
4+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
5+
d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk
6+
IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE4MDUwODAwMDAwMFoXDTIwMDYwMzEy
7+
MDAwMFowgccxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB
8+
BAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQF
9+
Ewc1MTU3NTUwMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQG
10+
A1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRMwEQYD
11+
VQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
12+
xjyq8jyXDDrBTyitcnB90865tWBzpHSbindG/XqYQkzFMBlXmqkzC+FdTRBYyneZ
13+
w5Pz+XWQvL+74JW6LsWNc2EF0xCEqLOJuC9zjPAqbr7uroNLghGxYf13YdqbG5oj
14+
/4x+ogEG3dF/U5YIwVr658DKyESMV6eoYV9mDVfTuJastkqcwero+5ZAKfYVMLUE
15+
sMwFtoTDJFmVf6JlkOWwsxp1WcQ/MRQK1cyqOoUFUgYylgdh3yeCDPeF22Ax8AlQ
16+
xbcaI+GwfQL1FB7Jy+h+KjME9lE/UpgV6Qt2R1xNSmvFCBWu+NFX6epwFP/JRbkM
17+
fLz0beYFUvmMgLtwVpEPSwIDAQABo4IDeTCCA3UwHwYDVR0jBBgwFoAUPdNQpdag
18+
re7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFMnCU2FmnV+rJfQmzQ84mqhJ6kipMCUG
19+
A1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1UdDwEB/wQE
20+
AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0
21+
oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcy
22+
LmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2Vy
23+
dmVyLWcyLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG/WwCATAqMCgGCCsGAQUFBwIB
24+
FhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGIBggrBgEF
25+
BQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBS
26+
BggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
27+
U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAA
28+
MIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWY
29+
BPkb37jjd80OyA3cEAAAAWNBYm0KAAAEAwBHMEUCIQDRZp38cTWsWH2GdBpe/uPT
30+
Wnsu/m4BEC2+dIcvSykZYgIgCP5gGv6yzaazxBK2NwGdmmyuEFNSg2pARbMJlUFg
31+
U5UAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAWNBYm0tAAAE
32+
AwBHMEUCIQCi7omUvYLm0b2LobtEeRAYnlIo7n6JxbYdrtYdmPUWJQIgVgw1AZ51
33+
vK9ENinBg22FPxb82TvNDO05T17hxXRC2IYAdgC72d+8H4pxtZOUI5eqkntHOFeV
34+
CqtS6BqQlmQ2jh7RhQAAAWNBYm3fAAAEAwBHMEUCIQChzdTKUU2N+XcqcK0OJYrN
35+
8EYynloVxho4yPk6Dq3EPgIgdNH5u8rC3UcslQV4B9o0a0w204omDREGKTVuEpxG
36+
eOQwDQYJKoZIhvcNAQELBQADggEBAHAPWpanWOW/ip2oJ5grAH8mqQfaunuCVE+v
37+
ac+88lkDK/LVdFgl2B6kIHZiYClzKtfczG93hWvKbST4NRNHP9LiaQqdNC17e5vN
38+
HnXVUGw+yxyjMLGqkgepOnZ2Rb14kcTOGp4i5AuJuuaMwXmCo7jUwPwfLe1NUlVB
39+
Kqg6LK0Hcq4K0sZnxE8HFxiZ92WpV2AVWjRMEc/2z2shNoDvxvFUYyY1Oe67xINk
40+
myQKc+ygSBZzyLnXSFVWmHr3u5dcaaQGGAR42v6Ydr4iL38Hd4dOiBma+FXsXBIq
41+
WUjbST4VXmdaol7uzFMojA4zkxQDZAvF5XgJlAFadfySna/teik=
42+
-----END CERTIFICATE-----
43+
-----BEGIN CERTIFICATE-----
44+
MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs
45+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
46+
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
47+
ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL
48+
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
49+
LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW
50+
YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
51+
ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY
52+
uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/
53+
LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy
54+
/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh
55+
cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k
56+
8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB
57+
Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
58+
BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
59+
Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy
60+
dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2
61+
MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j
62+
b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW
63+
gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh
64+
hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg
65+
4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa
66+
2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs
67+
1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1
68+
oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn
69+
8TUoE6smftX3eg==
70+
-----END CERTIFICATE-----
71+
-----BEGIN CERTIFICATE-----
72+
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
73+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
74+
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
75+
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
76+
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
77+
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
78+
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
79+
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
80+
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
81+
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
82+
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
83+
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
84+
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
85+
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
86+
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
87+
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
88+
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
89+
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
90+
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
91+
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
92+
+OkuE6N36B9K
93+
-----END CERTIFICATE-----
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIGqDCCBZCgAwIBAgIQCvBs2jemC2QTQvCh6x1Z/TANBgkqhkiG9w0BAQsFADBN
3+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
4+
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMjAwMzIzMDAwMDAwWhcN
5+
MjIwNTE3MTIwMDAwWjBuMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p
6+
YTEVMBMGA1UEBxMMV2FsbnV0IENyZWVrMRwwGgYDVQQKExNMdWNhcyBHYXJyb24g
7+
VG9ycmVzMRUwEwYDVQQDDAwqLmJhZHNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUA
8+
A4IBDwAwggEKAoIBAQDCBOz4jO4EwrPYUNVwWMyTGOtcqGhJsCK1+ZWesSssdj5s
9+
wEtgTEzqsrTAD4C2sPlyyYYC+VxBXRMrf3HES7zplC5QN6ZnHGGM9kFCxUbTFocn
10+
n3TrCp0RUiYhc2yETHlV5NFr6AY9SBVSrbMo26r/bv9glUp3aznxJNExtt1NwMT8
11+
U7ltQq21fP6u9RXSM0jnInHHwhR6bCjqN0rf6my1crR+WqIW3GmxV0TbChKr3sMP
12+
R3RcQSLhmvkbk+atIgYpLrG6SRwMJ56j+4v3QHIArJII2YxXhFOBBcvm/mtUmEAn
13+
hccQu3Nw72kYQQdFVXz5ZD89LMOpfOuTGkyG0cqFAgMBAAGjggNhMIIDXTAfBgNV
14+
HSMEGDAWgBQPgGEcgjFh1S8o541GOLQs4cbZ4jAdBgNVHQ4EFgQUne7Be4ELOkdp
15+
cRh9ETeTvKUbP/swIwYDVR0RBBwwGoIMKi5iYWRzc2wuY29tggpiYWRzc2wuY29t
16+
MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
17+
awYDVR0fBGQwYjAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NzY2Et
18+
c2hhMi1nNi5jcmwwL6AtoCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2Nh
19+
LXNoYTItZzYuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUH
20+
AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQIDMHwGCCsG
21+
AQUFBwEBBHAwbjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t
22+
MEYGCCsGAQUFBzAChjpodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl
23+
cnRTSEEyU2VjdXJlU2VydmVyQ0EuY3J0MAwGA1UdEwEB/wQCMAAwggF+BgorBgEE
24+
AdZ5AgQCBIIBbgSCAWoBaAB2ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaO
25+
HtGFAAABcQhGXioAAAQDAEcwRQIgDfWVBXEuUZC2YP4Si3AQDidHC4U9e5XTGyG7
26+
SFNDlRkCIQCzikrA1nf7boAdhvaGu2Vkct3VaI+0y8p3gmonU5d9DwB2ACJFRQdZ
27+
VSRWlj+hL/H3bYbgIyZjrcBLf13Gg1xu4g8CAAABcQhGXlsAAAQDAEcwRQIhAMWi
28+
Vsi2vYdxRCRsu/DMmCyhY0iJPKHE2c6ejPycIbgqAiAs3kSSS0NiUFiHBw7QaQ/s
29+
GO+/lNYvjExlzVUWJbgNLwB2AFGjsPX9AXmcVm24N3iPDKR6zBsny/eeiEKaDf7U
30+
iwXlAAABcQhGXnoAAAQDAEcwRQIgKsntiBqt8Au8DAABFkxISELhP3U/wb5lb76p
31+
vfenWL0CIQDr2kLhCWP/QUNxXqGmvr1GaG9EuokTOLEnGPhGv1cMkDANBgkqhkiG
32+
9w0BAQsFAAOCAQEA0RGxlwy3Tl0lhrUAn2mIi8LcZ9nBUyfAcCXCtYyCdEbjIP64
33+
xgX6pzTt0WJoxzlT+MiK6fc0hECZXqpkTNVTARYtGkJoljlTK2vAdHZ0SOpm9OT4
34+
RLfjGnImY0hiFbZ/LtsvS2Zg7cVJecqnrZe/za/nbDdljnnrll7C8O5naQuKr4te
35+
uice3e8a4TtviFwS/wdDnJ3RrE83b1IljILbU5SV0X1NajyYkUWS7AnOmrFUUByz
36+
MwdGrM6kt0lfJy/gvGVsgIKZocHdedPeECqAtq7FAJYanOsjNN9RbBOGhbwq0/FP
37+
CC01zojqS10nGowxzOiqyB4m6wytmzf0QwjpMw==
38+
-----END CERTIFICATE-----
39+
-----BEGIN CERTIFICATE-----
40+
MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh
41+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
42+
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
43+
QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT
44+
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg
45+
U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
46+
ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83
47+
nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd
48+
KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f
49+
/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX
50+
kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0
51+
/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C
52+
AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY
53+
aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6
54+
Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1
55+
oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD
56+
QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
57+
d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh
58+
xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB
59+
CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl
60+
5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA
61+
8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC
62+
2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit
63+
c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0
64+
j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz
65+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)