2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file gnutls_sample.cpp
18 * @author Kyungwook Tak (k.tak@samsung.com)
20 * @brief tpkp_gnutls unit test.
28 #include <sys/types.h>
29 #include <sys/socket.h>
32 #include <gnutls/gnutls.h>
33 #include <tpkp_gnutls.h>
34 #include <boost/test/unit_test.hpp>
39 gnutls_session_t session;
40 gnutls_certificate_credentials_t cred;
44 static std::vector<std::string> s_urlList = {
51 "www.hackerrank.com", /* no pinned data exist */
52 "www.algospot.com" /* no pinned data exist */
55 void connectWithUrl(const std::string &url, int &sockfd)
57 struct addrinfo *result;
58 struct addrinfo hints;
59 memset(&hints, 0x00, sizeof(struct addrinfo));
60 hints.ai_family = AF_UNSPEC;
61 hints.ai_socktype = SOCK_STREAM;
62 hints.ai_flags = AI_CANONNAME;
64 int s = getaddrinfo(url.c_str(), "https", &hints, &result);
65 BOOST_REQUIRE_MESSAGE(s == 0, "getaddrinfo err code: " << s << " desc: " << gai_strerror(s));
68 for (rp = result; rp != nullptr; rp = rp->ai_next) {
69 sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
73 if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) != -1)
79 BOOST_REQUIRE_MESSAGE(rp != nullptr, "Could not connect on url: " << url);
81 std::cout << "url[" << url << "] canonname[" << result->ai_canonname << "] connected!" << std::endl;
86 inline gnutls_certificate_credentials_t makeDefaultCred(gnutls_certificate_verify_function *verify_callback)
88 gnutls_certificate_credentials_t cred;
90 int ret = gnutls_certificate_allocate_credentials(&cred);
91 BOOST_REQUIRE_MESSAGE(
92 ret == GNUTLS_E_SUCCESS,
93 "Failed to gnutls_certificate_allocate_credentials: " << gnutls_strerror(ret));
95 ret = gnutls_certificate_set_x509_trust_file(cred, "/etc/ssl/ca-bundle.pem", GNUTLS_X509_FMT_PEM);
96 BOOST_REQUIRE_MESSAGE(
98 "Failed to gnutls_certificate_set_x509_trust_file ret: " << ret);
100 gnutls_certificate_set_verify_function(cred, verify_callback);
105 DataSet makeDefaultSession(const std::string &url)
109 data.cred = makeDefaultCred(&tpkp_gnutls_verify_callback);
111 int ret = gnutls_init(&data.session, GNUTLS_CLIENT);
112 BOOST_REQUIRE_MESSAGE(
113 ret == GNUTLS_E_SUCCESS,
114 "Failed to gnutls init session: " << gnutls_strerror(ret));
116 ret = gnutls_set_default_priority(data.session);
117 BOOST_REQUIRE_MESSAGE(
118 ret == GNUTLS_E_SUCCESS,
119 "Failed to set default priority on session: " << gnutls_strerror(ret));
121 ret = gnutls_credentials_set(data.session, GNUTLS_CRD_CERTIFICATE, data.cred);
122 BOOST_REQUIRE_MESSAGE(
123 ret == GNUTLS_E_SUCCESS,
124 "Failed to gnutls_credentials_set: " << gnutls_strerror(ret));
126 connectWithUrl(url, data.sockfd);
128 BOOST_REQUIRE_MESSAGE(
129 tpkp_gnutls_set_url_data(url.c_str()) == TPKP_E_NONE,
130 "Failed to tpkp_gnutls_set_url_data.");
132 gnutls_transport_set_int(data.session, data.sockfd);
133 gnutls_handshake_set_timeout(data.session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
138 DataSet makeSessionWithoutPinning(const std::string &url)
142 int ret = gnutls_certificate_allocate_credentials(&data.cred);
143 BOOST_REQUIRE_MESSAGE(
144 ret == GNUTLS_E_SUCCESS,
145 "Failed to gnutls_certificate_allocate_credentials: " << gnutls_strerror(ret));
147 ret = gnutls_init(&data.session, GNUTLS_CLIENT);
148 BOOST_REQUIRE_MESSAGE(
149 ret == GNUTLS_E_SUCCESS,
150 "Failed to gnutls init session: " << gnutls_strerror(ret));
152 ret = gnutls_set_default_priority(data.session);
153 BOOST_REQUIRE_MESSAGE(
154 ret == GNUTLS_E_SUCCESS,
155 "Failed to set default priority on session: " << gnutls_strerror(ret));
157 ret = gnutls_credentials_set(data.session, GNUTLS_CRD_CERTIFICATE, data.cred);
158 BOOST_REQUIRE_MESSAGE(
159 ret == GNUTLS_E_SUCCESS,
160 "Failed to gnutls_credentials_set: " << gnutls_strerror(ret));
162 connectWithUrl(url, data.sockfd);
164 gnutls_transport_set_int(data.session, data.sockfd);
165 gnutls_handshake_set_timeout(data.session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
170 DataSet makeDefaultSessionGlobal(const std::string &url)
172 int ret = gnutls_global_init();
173 BOOST_REQUIRE_MESSAGE(
174 ret == GNUTLS_E_SUCCESS,
175 "Failed to gnutls global init: " << gnutls_strerror(ret));
177 return makeDefaultSession(url);
180 void performHandshake(DataSet &data)
184 ret = gnutls_handshake(data.session);
185 } while (ret != GNUTLS_E_SUCCESS && gnutls_error_is_fatal(ret) == 0);
187 BOOST_REQUIRE_MESSAGE(
188 ret == GNUTLS_E_SUCCESS,
189 "Handshake failed! err code: " << ret << " desc: " << gnutls_strerror(ret));
192 void cleanup(DataSet &data)
194 gnutls_bye(data.session, GNUTLS_SHUT_RDWR);
197 gnutls_certificate_free_credentials(data.cred);
198 gnutls_deinit(data.session);
200 tpkp_gnutls_cleanup();
203 void cleanupGlobal(DataSet &data)
206 gnutls_global_deinit();
209 void perform(const std::string &url)
211 DataSet data = makeDefaultSession(url);
212 performHandshake(data);
216 void performWithoutPinning(const std::string &url)
218 DataSet data = makeSessionWithoutPinning(url);
219 performHandshake(data);
225 BOOST_AUTO_TEST_SUITE(TPKP_GNUTLS_TEST)
227 BOOST_AUTO_TEST_CASE(T00101_positive_1)
229 gnutls_global_init();
231 perform(s_urlList[0]);
233 gnutls_global_deinit();
236 BOOST_AUTO_TEST_CASE(T00102_positive_2)
238 gnutls_global_init();
240 perform(s_urlList[1]);
242 gnutls_global_deinit();
245 BOOST_AUTO_TEST_CASE(T00103_positive_3)
247 gnutls_global_init();
249 perform(s_urlList[2]);
251 gnutls_global_deinit();
254 BOOST_AUTO_TEST_CASE(T00104_positive_4)
256 gnutls_global_init();
258 perform(s_urlList[3]);
260 gnutls_global_deinit();
263 BOOST_AUTO_TEST_CASE(T00105_positive_5)
265 gnutls_global_init();
267 perform(s_urlList[4]);
269 gnutls_global_deinit();
272 BOOST_AUTO_TEST_CASE(T00106_positive_6)
274 gnutls_global_init();
276 perform(s_urlList[5]);
278 gnutls_global_deinit();
281 BOOST_AUTO_TEST_CASE(T00107_positive_7)
283 gnutls_global_init();
285 perform(s_urlList[6]);
287 gnutls_global_deinit();
290 BOOST_AUTO_TEST_CASE(T00108_positive_8)
292 gnutls_global_init();
294 perform(s_urlList[7]);
296 gnutls_global_deinit();
299 BOOST_AUTO_TEST_CASE(T00109_positive_all_single_thread)
301 gnutls_global_init();
303 for (const auto &url : s_urlList)
306 gnutls_global_deinit();
309 BOOST_AUTO_TEST_CASE(T00110_positive_all_single_thread_without_pinning)
311 gnutls_global_init();
313 for (const auto &url : s_urlList)
314 performWithoutPinning(url);
316 gnutls_global_deinit();
319 BOOST_AUTO_TEST_SUITE_END()