76 SSL* ssl =
static_cast<SSL*>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
78 std::string connectionName = *
static_cast<std::string*>(SSL_get_ex_data(ssl, 0));
80 X509* curr_cert = X509_STORE_CTX_get_current_cert(ctx);
81 const int depth = X509_STORE_CTX_get_error_depth(ctx);
83 char subjectName[256];
84 X509_NAME_oneline(X509_get_subject_name(curr_cert), subjectName, 256);
87 X509_NAME_oneline(X509_get_issuer_name(curr_cert), issuerName, 256);
89 if (preverify_ok != 0) {
90 LOG(DEBUG) << connectionName <<
": SSL/TLS verify success at depth=" << depth;
91 LOG(DEBUG) <<
" Issuer: " << issuerName;
92 LOG(DEBUG) <<
" Subject: " << subjectName;
94 const int err = X509_STORE_CTX_get_error(ctx);
97
98
99
101 LOG(DEBUG) << connectionName <<
": SSL/TLS verify error at depth=" << depth <<
": " << X509_verify_cert_error_string(err);
102 LOG(DEBUG) <<
" Issuer: " << issuerName;
103 LOG(DEBUG) <<
" Subject: " << subjectName;
114 static int sslSessionCtxId = 1;
116 SSL_CTX* ctx = SSL_CTX_new(sslConfig.server ? TLS_server_method() : TLS_client_method());
118 if (ctx !=
nullptr) {
119 SSL_CTX_set_read_ahead(ctx, 1);
121 SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
122 SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
126 if (sslConfig.server) {
127 SSL_CTX_set_session_id_context(ctx,
reinterpret_cast<
const unsigned char*>(&sslSessionCtxId),
sizeof(sslSessionCtxId));
130 if (!sslConfig.caCert.empty() || !sslConfig.caCertDir.empty()) {
131 if (SSL_CTX_load_verify_locations(ctx,
132 !sslConfig.caCert.empty() ? sslConfig.caCert.c_str() :
nullptr,
133 !sslConfig.caCertDir.empty() ? sslConfig.caCertDir.c_str() :
nullptr) == 0) {
134 ssl_log_error(sslConfig.instanceName +
" SSL/TLS: CA certificate error loading file '" + sslConfig.caCert +
"', dir '" +
135 sslConfig.caCertDir +
"'");
138 if (!sslConfig.caCert.empty()) {
139 LOG(TRACE) << sslConfig.instanceName <<
" SSL/TLS: CA certificate loaded";
140 LOG(TRACE) <<
" " << sslConfig.caCert;
142 LOG(TRACE) << sslConfig.instanceName <<
" SSL/TLS: CA certificate not loaded from a file";
144 if (!sslConfig.caCertDir.empty()) {
145 LOG(TRACE) << sslConfig.instanceName <<
" SSL/TLS: CA certificates load from";
146 LOG(TRACE) <<
" " << sslConfig.caCertDir;
148 LOG(TRACE) << sslConfig.instanceName <<
" SSL/TLS: CA certificates not loaded from a directory";
152 LOG(TRACE) << sslConfig.instanceName <<
" SSL/TLS: CA certificate not loaded from a file";
153 LOG(TRACE) << sslConfig.instanceName <<
" SSL/TLS: CA certificates not loaded from a directory";
155 if (!sslErr && sslConfig.caCertUseDefaultDir) {
156 if (SSL_CTX_set_default_verify_paths(ctx) == 0) {
157 ssl_log_error(sslConfig.instanceName +
" SSL/TLS: CA certificates error load from default openssl CA directory");
160 LOG(TRACE) << sslConfig.instanceName <<
" SSL/TLS: CA certificates enabled load from default openssl CA directory";
163 LOG(TRACE) << sslConfig.instanceName <<
" SSL/TLS: CA certificates not loaded from default openssl CA directory";
166 SSL_CTX_set_verify_depth(ctx, 5);
167 SSL_CTX_set_verify(ctx,
168 (sslConfig.caCertAcceptUnknown ? SSL_VERIFY_NONE
169 : (!sslConfig.caCert.empty() || !sslConfig.caCertDir.empty() || sslConfig.caCertUseDefaultDir)
170 ? SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
173 if ((SSL_CTX_get_verify_mode(ctx) & SSL_VERIFY_PEER) != 0) {
174 LOG(TRACE) << sslConfig.instanceName <<
" SSL/TLS: CA requested verify";
176 if (!sslConfig.cert.empty()) {
177 if (SSL_CTX_use_certificate_chain_file(ctx, sslConfig.cert.c_str()) == 0) {
178 ssl_log_error(sslConfig.instanceName +
" SSL/TLS: Cert chain error loading from file '" + sslConfig.cert +
"'");
180 }
else if (!sslConfig.certKey.empty()) {
181 if (!sslConfig.password.empty()) {
183 SSL_CTX_set_default_passwd_cb_userdata(ctx, ::strdup(sslConfig.password.c_str()));
185 if (SSL_CTX_use_PrivateKey_file(ctx, sslConfig.certKey.c_str(), SSL_FILETYPE_PEM) == 0) {
186 ssl_log_error(sslConfig.instanceName +
" SSL/TLS: Cert chain key error loading file '" + sslConfig.certKey +
189 }
else if (SSL_CTX_check_private_key(ctx) != 1) {
190 ssl_log_error(sslConfig.instanceName +
" SSL/TLS: Cert chain key error");
192 LOG(TRACE) <<
" " << sslConfig.certKey;
195 LOG(TRACE) << sslConfig.instanceName <<
" SSL/TLS: Cert chain key loaded";
196 LOG(TRACE) <<
" " << sslConfig.certKey;
198 LOG(TRACE) << sslConfig.instanceName <<
" SSL/TLS: Cert chain loaded";
199 LOG(TRACE) <<
" " << sslConfig.cert;
205 if (sslConfig.sslOptions != 0) {
206 SSL_CTX_set_options(ctx, sslConfig.sslOptions);
208 if (!sslConfig.cipherList.empty()) {
209 SSL_CTX_set_cipher_list(ctx, sslConfig.cipherList.c_str());
221 std::map<std::string, SSL_CTX*> sans;
223 if (sslCtx !=
nullptr) {
224 X509* x509 = SSL_CTX_get0_certificate(sslCtx);
225 if (x509 !=
nullptr) {
226 GENERAL_NAMES* subjectAltNames =
227 static_cast<GENERAL_NAMES*>(X509_get_ext_d2i(x509, NID_subject_alt_name,
nullptr,
nullptr));
229#pragma GCC diagnostic push
231#if __has_warning
("-Wused-but-marked-unused")
232#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
236 const int32_t altNameCount = sk_GENERAL_NAME_num(subjectAltNames);
238#pragma GCC diagnostic pop
240 for (int32_t i = 0; i < altNameCount; ++i) {
242#pragma GCC diagnostic push
244#if __has_warning
("-Wused-but-marked-unused")
245#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
249 GENERAL_NAME* generalName = sk_GENERAL_NAME_value(subjectAltNames, i);
251#pragma GCC diagnostic pop
253 if (generalName->type == GEN_DNS || generalName->type == GEN_URI || generalName->type == GEN_EMAIL) {
254 const std::string subjectAltName =
255 std::string(
reinterpret_cast<
const char*>(ASN1_STRING_get0_data(generalName->d.dNSName)),
256 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.dNSName)));
257 sans.insert({subjectAltName, sslCtx});
261#pragma GCC diagnostic push
263#if __has_warning
("-Wused-but-marked-unused")
264#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
268 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
270#pragma GCC diagnostic pop
285 SSL_CTX* newSslCtx = SSL_set_SSL_CTX(ssl, sslCtx);
286 SSL_clear_options(ssl, 0xFFFFFFFFL);
287 SSL_set_options(ssl, SSL_CTX_get_options(sslCtx));
288 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(sslCtx), SSL_CTX_get_verify_callback(sslCtx));
289 SSL_set_verify_depth(ssl, SSL_CTX_get_verify_depth(sslCtx));
290 SSL_set_mode(ssl, SSL_CTX_get_mode(sslCtx));
303 const unsigned char* ext =
nullptr;
306 size_t server_name_list_len = 0;
307 size_t server_name_len = 0;
309 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &ext, &ext_len) == 0) {
319 server_name_list_len =
static_cast<size_t>((ext[p] << 8) + ext[p + 1]);
321 if (p + server_name_list_len != ext_len) {
326 if (ext[p] != TLSEXT_NAMETYPE_host_name) {
332 server_name_len =
static_cast<size_t>((ext[p] << 8) + ext[p + 1]);
334 if (p + server_name_len != ext_len) {
342 return std::string(
reinterpret_cast<
const char*>(ext + p), ext_len - p);