forked from libcpr/cpr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathssl_tests.cpp
196 lines (168 loc) · 9.3 KB
/
ssl_tests.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#include <gtest/gtest.h>
#include <chrono>
#include <string>
#include <thread>
#include <vector>
#include "cpr/cprtypes.h"
#include "cpr/filesystem.h"
#include "cpr/ssl_options.h"
#include "httpsServer.hpp"
using namespace cpr;
static HttpsServer* server;
static std::string caCertPath;
static std::string serverPubKeyPath;
static std::string clientKeyPath;
static std::string clientCertPath;
std::string loadFileContent(const std::string filePath) {
std::ifstream file(filePath);
std::stringstream buffer;
buffer << file.rdbuf();
return buffer.str();
}
TEST(SslTests, HelloWorldTestSimpel) {
std::this_thread::sleep_for(std::chrono::seconds(1));
Url url{server->GetBaseUrl() + "/hello.html"};
std::string baseDirPath{server->getBaseDirPath()};
std::string crtPath{baseDirPath + "certificates/"};
std::string keyPath{baseDirPath + "keys/"};
SslOptions sslOpts = Ssl(ssl::CaInfo{crtPath + "ca-bundle.crt"}, ssl::CertFile{crtPath + "client.crt"}, ssl::KeyFile{keyPath + "client.key"}, ssl::VerifyPeer{true}, ssl::PinnedPublicKey{keyPath + "server.pub"}, ssl::VerifyHost{true}, ssl::VerifyStatus{false});
Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
std::string expected_text = "Hello world!";
EXPECT_EQ(expected_text, response.text);
EXPECT_EQ(url, response.url);
EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
EXPECT_EQ(200, response.status_code);
EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;
}
TEST(SslTests, HelloWorldTestFull) {
std::this_thread::sleep_for(std::chrono::seconds(1));
Url url{server->GetBaseUrl() + "/hello.html"};
std::string baseDirPath{server->getBaseDirPath()};
std::string crtPath{baseDirPath + "certificates/"};
std::string keyPath{baseDirPath + "keys/"};
SslOptions sslOpts = Ssl(ssl::TLSv1{}, ssl::ALPN{false},
#if SUPPORT_NPN
ssl::NPN{false},
#endif // DEBUG
ssl::CaInfo{crtPath + "ca-bundle.crt"}, ssl::CertFile{crtPath + "client.crt"}, ssl::KeyFile{keyPath + "client.key"}, ssl::PinnedPublicKey{keyPath + "server.pub"}, ssl::VerifyPeer{true}, ssl::VerifyHost{true}, ssl::VerifyStatus{false});
Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
std::string expected_text = "Hello world!";
EXPECT_EQ(expected_text, response.text);
EXPECT_EQ(url, response.url);
EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
EXPECT_EQ(200, response.status_code);
EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;
}
TEST(SslTests, GetCertInfos) {
std::this_thread::sleep_for(std::chrono::seconds(1));
Url url{server->GetBaseUrl() + "/hello.html"};
std::string baseDirPath{server->getBaseDirPath()};
std::string crtPath{baseDirPath + "certificates/"};
std::string keyPath{baseDirPath + "keys/"};
SslOptions sslOpts = Ssl(ssl::CaInfo{crtPath + "ca-bundle.crt"}, ssl::CertFile{crtPath + "client.crt"}, ssl::KeyFile{keyPath + "client.key"}, ssl::VerifyPeer{true}, ssl::VerifyHost{true}, ssl::VerifyStatus{false});
Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
std::vector<CertInfo> certInfos = response.GetCertInfos();
std::string expected_text = "Hello world!";
std::vector<CertInfo> expectedCertInfos{
CertInfo{
"Subject:CN = test-server",
"Issuer:C = GB, O = Example, CN = Sub CA",
"Version:2",
"Serial Number:acbefc2cde5b900b55548396556765d4",
"Signature Algorithm:ED25519",
"Public Key Algorithm:ED25519",
"X509v3 Authority Key Identifier:9B:B1:9B:21:61:DC:66:2B:3A:AD:ED:84:F1:05:B6:CE:99:82:C1:FC",
"X509v3 Basic Constraints:CA:FALSE",
"X509v3 Extended Key Usage:TLS Web Client Authentication, TLS Web Server Authentication",
"X509v3 Key Usage:Digital Signature, Key Encipherment",
"X509v3 Subject Key Identifier:66:47:54:F8:25:97:56:9A:52:56:35:B4:A7:52:60:0C:E7:4F:33:09",
"X509v3 Subject Alternative Name:DNS:localhost, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1",
"Start date:May 7 10:18:22 2024 GMT",
"Expire date:May 6 10:18:22 2029 GMT",
"Signature:6d:63:d9:11:a3:9b:c7:9f:b6:23:12:27:e9:34:e0:a1:a3:20:be:fb:df:80:fe:53:08:9d:8c:e4:82:42:76:c2:55:13:e8:7c:86:83:33:0b:9a:9f:92:2a:3f:de:e9:32:78:c0:b1:bc:3f:42:e9:17:f9:9f:6c:15:35:a3:01:09:",
R"(Cert:-----BEGIN CERTIFICATE-----
MIIBtDCCAWagAwIBAgIRAKy+/CzeW5ALVVSDllVnZdQwBQYDK2VwMDAxCzAJBgNV
BAYTAkdCMRAwDgYDVQQKDAdFeGFtcGxlMQ8wDQYDVQQDDAZTdWIgQ0EwHhcNMjQw
NTA3MTAxODIyWhcNMjkwNTA2MTAxODIyWjAWMRQwEgYDVQQDDAt0ZXN0LXNlcnZl
cjAqMAUGAytlcAMhACdLUqJFSyspgGKJiXNlnOLU2dO/TLV+b8aIZNAX7EuVo4Gu
MIGrMB8GA1UdIwQYMBaAFJuxmyFh3GYrOq3thPEFts6ZgsH8MAwGA1UdEwEB/wQC
MAAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMA4GA1UdDwEB/wQEAwIF
oDAdBgNVHQ4EFgQUZkdU+CWXVppSVjW0p1JgDOdPMwkwLAYDVR0RBCUwI4IJbG9j
YWxob3N0hwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMAUGAytlcANBAG1j2RGjm8ef
tiMSJ+k04KGjIL7734D+UwidjOSCQnbCVRPofIaDMwuan5IqP97pMnjAsbw/QukX
+Z9sFTWjAQk=
-----END CERTIFICATE-----
)",
},
};
EXPECT_EQ(expected_text, response.text);
EXPECT_EQ(url, response.url);
EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
EXPECT_EQ(200, response.status_code);
EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;
EXPECT_EQ(1, certInfos.size());
for (auto certInfo_it = certInfos.begin(), expectedCertInfo_it = expectedCertInfos.begin(); certInfo_it != certInfos.end() && expectedCertInfo_it != expectedCertInfos.end(); certInfo_it++, expectedCertInfo_it++) {
for (auto entry_it = (*certInfo_it).begin(), expectedEntry_it = (*expectedCertInfo_it).begin(); entry_it != (*certInfo_it).end() && expectedEntry_it != (*expectedCertInfo_it).end(); entry_it++, expectedEntry_it++) {
std::string search_string = "Identifier:keyid:";
std::size_t search_index = (*entry_it).find(search_string);
if (search_index != std::string::npos) {
(*entry_it).replace(search_index, search_string.length(), "Identifier:");
search_string = "\n";
search_index = (*entry_it).find(search_string);
if (search_index != std::string::npos) {
(*entry_it).replace(search_index, search_string.length(), "");
}
}
EXPECT_EQ(*expectedEntry_it, *entry_it);
}
std::cout << '\n';
}
}
#if SUPPORT_CURLOPT_SSL_CTX_FUNCTION
TEST(SslTests, LoadCertFromBufferTestSimpel) {
std::this_thread::sleep_for(std::chrono::seconds(1));
Url url{server->GetBaseUrl() + "/hello.html"};
std::string baseDirPath{server->getBaseDirPath()};
std::string crtPath{baseDirPath + "certificates/"};
std::string keyPath{baseDirPath + "keys/"};
std::string certBuffer = loadFileContent(crtPath + "ca-bundle.crt");
SslOptions sslOpts = Ssl(ssl::CaBuffer{std::move(certBuffer)}, ssl::CertFile{crtPath + "client.crt"}, ssl::KeyFile{keyPath + "client.key"}, ssl::VerifyPeer{true}, ssl::VerifyHost{true}, ssl::VerifyStatus{false});
Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
std::string expected_text = "Hello world!";
EXPECT_EQ(expected_text, response.text);
EXPECT_EQ(url, response.url);
EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
EXPECT_EQ(200, response.status_code);
EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;
}
#endif
#if SUPPORT_CURLOPT_SSLKEY_BLOB
TEST(SslTests, LoadKeyFromBlobTestSimpel) {
std::this_thread::sleep_for(std::chrono::seconds(1));
Url url{server->GetBaseUrl() + "/hello.html"};
std::string baseDirPath{server->getBaseDirPath()};
std::string crtPath{baseDirPath + "certificates/"};
std::string keyPath{baseDirPath + "keys/"};
std::string keyBuffer = loadFileContent(keyPath + "client.key");
SslOptions sslOpts = Ssl(ssl::CaInfo{crtPath + "ca-bundle.crt"}, ssl::CertFile{crtPath + "client.crt"}, ssl::KeyBlob{std::move(keyBuffer)}, ssl::VerifyPeer{true}, ssl::VerifyHost{true}, ssl::VerifyStatus{false});
Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
std::string expected_text = "Hello world!";
EXPECT_EQ(expected_text, response.text);
EXPECT_EQ(url, response.url);
EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
EXPECT_EQ(200, response.status_code);
EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;
}
#endif
fs::path GetBasePath(const std::string& execPath) {
return fs::path(fs::path{execPath}.parent_path().string() + "/").make_preferred();
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
fs::path baseDirPath = fs::path{GetBasePath(argv[0]).string() + "data/"};
fs::path serverCertPath = fs::path{baseDirPath}.append("certificates/server.crt");
fs::path serverKeyPath = fs::path{baseDirPath}.append("keys/server.key");
server = new HttpsServer(std::move(baseDirPath), std::move(serverCertPath), std::move(serverKeyPath));
::testing::AddGlobalTestEnvironment(server);
return RUN_ALL_TESTS();
}