]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ssl/support.cc
Bug 4662 pt2: feature detect OpenSSL 1.1 API functions
[thirdparty/squid.git] / src / ssl / support.cc
CommitLineData
f484cdf5 1/*
4ac4a490 2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
f484cdf5 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
f484cdf5 7 */
8
bbc27441
AJ
9/* DEBUG: section 83 SSL accelerator support */
10
582c2af2 11#include "squid.h"
454e8283 12
13/* MS Visual Studio Projects are monolithic, so we need the following
14 * #if to exclude the SSL code from compile process when not needed.
15 */
cb4f4424 16#if USE_OPENSSL
454e8283 17
c0941a6a 18#include "acl/FilledChecklist.h"
86660d64 19#include "anyp/PortCfg.h"
ed6e9fb9 20#include "fatal.h"
b3a8ae1b 21#include "fd.h"
582c2af2
FC
22#include "fde.h"
23#include "globals.h"
86c63190 24#include "ipc/MemMap.h"
92e3827b 25#include "security/CertError.h"
8d15a0c1 26#include "security/Session.h"
4d5904f7 27#include "SquidConfig.h"
10a69fc0 28#include "SquidTime.h"
b3a8ae1b 29#include "ssl/bio.h"
2cef0ca6 30#include "ssl/Config.h"
4d16918e 31#include "ssl/ErrorDetail.h"
95d2589c 32#include "ssl/gadgets.h"
602d9612 33#include "ssl/support.h"
fc54b8d2 34#include "URL.h"
f484cdf5 35
1a30fdf5 36#include <cerrno>
21d845b1 37
55369ae6
AR
38// TODO: Move ssl_ex_index_* global variables from global.cc here.
39int ssl_ex_index_ssl_untrusted_chain = -1;
40
824d4656
AJ
41Ipc::MemMap *Ssl::SessionCache = NULL;
42const char *Ssl::SessionCacheName = "ssl_session_cache";
10a69fc0 43
55369ae6
AR
44static Ssl::CertsIndexedList SquidUntrustedCerts;
45
3c26b00a
CT
46const EVP_MD *Ssl::DefaultSignHash = NULL;
47
ba6fffba 48std::vector<const char *> Ssl::BumpModeStr = {
caf3666d
AR
49 "none",
50 "client-first",
51 "server-first",
5d65362c
CT
52 "peek",
53 "stare",
54 "bump",
7f4e9b73 55 "splice",
ba6fffba
EB
56 "terminate"
57 /*,"err"*/
caf3666d
AR
58};
59
63be0a78 60/**
61 \defgroup ServerProtocolSSLInternal Server-Side SSL Internals
62 \ingroup ServerProtocolSSLAPI
63 */
64
65/// \ingroup ServerProtocolSSLInternal
307b83b7 66static int
67ssl_ask_password_cb(char *buf, int size, int rwflag, void *userdata)
68{
69 FILE *in;
70 int len = 0;
71 char cmdline[1024];
72
73 snprintf(cmdline, sizeof(cmdline), "\"%s\" \"%s\"", Config.Program.ssl_password, (const char *)userdata);
74 in = popen(cmdline, "r");
75
76 if (fgets(buf, size, in))
77
78 len = strlen(buf);
79
80 while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r'))
5e263176 81 --len;
307b83b7 82
83 buf[len] = '\0';
84
85 pclose(in);
86
87 return len;
88}
89
63be0a78 90/// \ingroup ServerProtocolSSLInternal
307b83b7 91static void
92ssl_ask_password(SSL_CTX * context, const char * prompt)
93{
94 if (Config.Program.ssl_password) {
95 SSL_CTX_set_default_passwd_cb(context, ssl_ask_password_cb);
96 SSL_CTX_set_default_passwd_cb_userdata(context, (void *)prompt);
97 }
98}
99
17e98f24 100#if HAVE_LIBSSL_SSL_CTX_SET_TMP_RSA_CALLBACK
f484cdf5 101static RSA *
e6ccf245 102ssl_temp_rsa_cb(SSL * ssl, int anInt, int keylen)
f484cdf5 103{
e01f02ed 104 static RSA *rsa_512 = NULL;
105 static RSA *rsa_1024 = NULL;
106 RSA *rsa = NULL;
107 int newkey = 0;
f484cdf5 108
e01f02ed 109 switch (keylen) {
110
111 case 512:
112
113 if (!rsa_512) {
114 rsa_512 = RSA_generate_key(512, RSA_F4, NULL, NULL);
115 newkey = 1;
116 }
117
118 rsa = rsa_512;
119 break;
120
121 case 1024:
122
123 if (!rsa_1024) {
124 rsa_1024 = RSA_generate_key(1024, RSA_F4, NULL, NULL);
125 newkey = 1;
126 }
127
128 rsa = rsa_1024;
129 break;
130
131 default:
e0236918 132 debugs(83, DBG_IMPORTANT, "ssl_temp_rsa_cb: Unexpected key length " << keylen);
e01f02ed 133 return NULL;
134 }
135
136 if (rsa == NULL) {
e0236918 137 debugs(83, DBG_IMPORTANT, "ssl_temp_rsa_cb: Failed to generate key " << keylen);
e01f02ed 138 return NULL;
139 }
140
141 if (newkey) {
014adac1 142 if (Debug::Enabled(83, 5))
e01f02ed 143 PEM_write_RSAPrivateKey(debug_log, rsa, NULL, NULL, 0, NULL, NULL);
144
e0236918 145 debugs(83, DBG_IMPORTANT, "Generated ephemeral RSA key of length " << keylen);
e01f02ed 146 }
62e76326 147
f484cdf5 148 return rsa;
149}
b7afb10f
CT
150#endif
151
152static void
153maybeSetupRsaCallback(Security::ContextPointer &ctx)
154{
17e98f24 155#if HAVE_LIBSSL_SSL_CTX_SET_TMP_RSA_CALLBACK
b7afb10f
CT
156 debugs(83, 9, "Setting RSA key generation callback.");
157 SSL_CTX_set_tmp_rsa_callback(ctx.get(), ssl_temp_rsa_cb);
158#endif
159}
f484cdf5 160
4d16918e
CT
161int Ssl::asn1timeToString(ASN1_TIME *tm, char *buf, int len)
162{
163 BIO *bio;
164 int write = 0;
165 bio = BIO_new(BIO_s_mem());
166 if (bio) {
e34763f4
A
167 if (ASN1_TIME_print(bio, tm))
168 write = BIO_read(bio, buf, len-1);
169 BIO_free(bio);
4d16918e
CT
170 }
171 buf[write]='\0';
172 return write;
173}
174
175int Ssl::matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data, ASN1_STRING *cn_data))
176{
177 assert(peer_cert);
178
179 X509_NAME *name = X509_get_subject_name(peer_cert);
180
181 for (int i = X509_NAME_get_index_by_NID(name, NID_commonName, -1); i >= 0; i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) {
e34763f4 182
4d16918e
CT
183 ASN1_STRING *cn_data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
184
185 if ( (*check_func)(check_data, cn_data) == 0)
186 return 1;
187 }
188
189 STACK_OF(GENERAL_NAME) * altnames;
190 altnames = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(peer_cert, NID_subject_alt_name, NULL, NULL);
191
192 if (altnames) {
193 int numalts = sk_GENERAL_NAME_num(altnames);
d7ae3534 194 for (int i = 0; i < numalts; ++i) {
4d16918e
CT
195 const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
196 if (check->type != GEN_DNS) {
197 continue;
198 }
199 ASN1_STRING *cn_data = check->d.dNSName;
e34763f4 200
40dd2b59
CT
201 if ( (*check_func)(check_data, cn_data) == 0) {
202 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
4d16918e 203 return 1;
40dd2b59 204 }
4d16918e
CT
205 }
206 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
207 }
208 return 0;
209}
210
211static int check_domain( void *check_data, ASN1_STRING *cn_data)
212{
213 char cn[1024];
214 const char *server = (const char *)check_data;
215
abbd7825
CT
216 if (cn_data->length == 0)
217 return 1; // zero length cn, ignore
218
219 if (cn_data->length > (int)sizeof(cn) - 1)
4d16918e 220 return 1; //if does not fit our buffer just ignore
abbd7825 221
0f7f4cfc
AJ
222 char *s = reinterpret_cast<char*>(cn_data->data);
223 char *d = cn;
224 for (int i = 0; i < cn_data->length; ++i, ++d, ++s) {
225 if (*s == '\0')
226 return 1; // always a domain mismatch. contains 0x00
227 *d = *s;
228 }
4d16918e
CT
229 cn[cn_data->length] = '\0';
230 debugs(83, 4, "Verifying server domain " << server << " to certificate name/subjectAltName " << cn);
abbd7825 231 return matchDomainName(server, (cn[0] == '*' ? cn + 1 : cn), mdnRejectSubsubDomains);
4d16918e
CT
232}
233
8eb0a7ee
CT
234bool Ssl::checkX509ServerValidity(X509 *cert, const char *server)
235{
236 return matchX509CommonNames(cert, (void *)server, check_domain);
237}
238
17e98f24 239#if !HAVE_LIBCRYPTO_X509_STORE_CTX_GET0_CERT
2a268a06
CT
240static inline X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
241{
242 return ctx->cert;
243}
244#endif
245
63be0a78 246/// \ingroup ServerProtocolSSLInternal
f484cdf5 247static int
248ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
249{
7698a79c 250 // preserve original ctx->error before SSL_ calls can overwrite it
2a268a06 251 Security::ErrorCode error_no = ok ? SSL_ERROR_NONE : X509_STORE_CTX_get_error(ctx);
7698a79c
CT
252
253 char buffer[256] = "";
a7ad6e4e 254 SSL *ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
0476ec45 255 SSL_CTX *sslctx = SSL_get_SSL_CTX(ssl);
68920ad8 256 SBuf *server = (SBuf *)SSL_get_ex_data(ssl, ssl_ex_index_server);
a7ad6e4e 257 void *dont_verify_domain = SSL_CTX_get_ex_data(sslctx, ssl_ctx_ex_index_dont_verify_domain);
815eaa44 258 ACLChecklist *check = (ACLChecklist*)SSL_get_ex_data(ssl, ssl_ex_index_cert_error_check);
e7bcc25f 259 X509 *peeked_cert = (X509 *)SSL_get_ex_data(ssl, ssl_ex_index_ssl_peeked_cert);
92e3827b 260 Security::CertPointer peer_cert;
2a268a06 261 peer_cert.resetAndLock(X509_STORE_CTX_get0_cert(ctx));
f484cdf5 262
92e3827b 263 X509_NAME_oneline(X509_get_subject_name(peer_cert.get()), buffer, sizeof(buffer));
a7ad6e4e 264
0ad3ff51
CT
265 // detect infinite loops
266 uint32_t *validationCounter = static_cast<uint32_t *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_validation_counter));
267 if (!validationCounter) {
268 validationCounter = new uint32_t(1);
269 SSL_set_ex_data(ssl, ssl_ex_index_ssl_validation_counter, validationCounter);
270 } else {
271 // overflows allowed if SQUID_CERT_VALIDATION_ITERATION_MAX >= UINT32_MAX
272 (*validationCounter)++;
273 }
274
275 if ((*validationCounter) >= SQUID_CERT_VALIDATION_ITERATION_MAX) {
276 ok = 0; // or the validation loop will never stop
277 error_no = SQUID_X509_V_ERR_INFINITE_VALIDATION;
278 debugs(83, 2, "SQUID_X509_V_ERR_INFINITE_VALIDATION: " <<
279 *validationCounter << " iterations while checking " << buffer);
280 }
281
a7ad6e4e 282 if (ok) {
bf8fe701 283 debugs(83, 5, "SSL Certificate signature OK: " << buffer);
62e76326 284
4747ea4c 285 // Check for domain mismatch only if the current certificate is the peer certificate.
92e3827b
AJ
286 if (!dont_verify_domain && server && peer_cert.get() == X509_STORE_CTX_get_current_cert(ctx)) {
287 if (!Ssl::checkX509ServerValidity(peer_cert.get(), server->c_str())) {
815eaa44 288 debugs(83, 2, "SQUID_X509_V_ERR_DOMAIN_MISMATCH: Certificate " << buffer << " does not match domainname " << server);
62e76326 289 ok = 0;
4d16918e 290 error_no = SQUID_X509_V_ERR_DOMAIN_MISMATCH;
62e76326 291 }
292 }
7698a79c 293 }
0db46e4f 294
e7bcc25f 295 if (ok && peeked_cert) {
7a957a93 296 // Check whether the already peeked certificate matches the new one.
92e3827b 297 if (X509_cmp(peer_cert.get(), peeked_cert) != 0) {
e7bcc25f
CT
298 debugs(83, 2, "SQUID_X509_V_ERR_CERT_CHANGE: Certificate " << buffer << " does not match peeked certificate");
299 ok = 0;
300 error_no = SQUID_X509_V_ERR_CERT_CHANGE;
301 }
302 }
303
7698a79c 304 if (!ok) {
92e3827b
AJ
305 Security::CertPointer broken_cert;
306 broken_cert.resetAndLock(X509_STORE_CTX_get_current_cert(ctx));
62a7607e
CT
307 if (!broken_cert)
308 broken_cert = peer_cert;
309
92e3827b 310 Security::CertErrors *errs = static_cast<Security::CertErrors *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_errors));
e36bc333 311 const int depth = X509_STORE_CTX_get_error_depth(ctx);
7a957a93 312 if (!errs) {
92e3827b 313 errs = new Security::CertErrors(Security::CertError(error_no, broken_cert, depth));
7a957a93 314 if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_errors, (void *)errs)) {
fb2178bb 315 debugs(83, 2, "Failed to set ssl error_no in ssl_verify_cb: Certificate " << buffer);
7a957a93
AR
316 delete errs;
317 errs = NULL;
fb2178bb 318 }
87f237a9 319 } else // remember another error number
92e3827b 320 errs->push_back_unique(Security::CertError(error_no, broken_cert, depth));
fb2178bb 321
7698a79c 322 if (const char *err_descr = Ssl::GetErrorDescr(error_no))
cf09bec7
CT
323 debugs(83, 5, err_descr << ": " << buffer);
324 else
7698a79c
CT
325 debugs(83, DBG_IMPORTANT, "SSL unknown certificate error " << error_no << " in " << buffer);
326
0ad3ff51
CT
327 // Check if the certificate error can be bypassed.
328 // Infinity validation loop errors can not bypassed.
329 if (error_no != SQUID_X509_V_ERR_INFINITE_VALIDATION) {
330 if (check) {
331 ACLFilledChecklist *filledCheck = Filled(check);
332 assert(!filledCheck->sslErrors);
92e3827b
AJ
333 filledCheck->sslErrors = new Security::CertErrors(Security::CertError(error_no, broken_cert));
334 filledCheck->serverCert = peer_cert;
0ad3ff51
CT
335 if (check->fastCheck() == ACCESS_ALLOWED) {
336 debugs(83, 3, "bypassing SSL error " << error_no << " in " << buffer);
337 ok = 1;
338 } else {
339 debugs(83, 5, "confirming SSL error " << error_no);
340 }
341 delete filledCheck->sslErrors;
342 filledCheck->sslErrors = NULL;
58a5291c 343 filledCheck->serverCert.reset();
7698a79c 344 }
0ad3ff51
CT
345 // If the certificate validator is used then we need to allow all errors and
346 // pass them to certficate validator for more processing
347 else if (Ssl::TheConfig.ssl_crt_validator) {
7698a79c 348 ok = 1;
7698a79c 349 }
815eaa44 350 }
a7ad6e4e 351 }
62e76326 352
081be7eb
CT
353 if (Ssl::TheConfig.ssl_crt_validator) {
354 // Check if we have stored certificates chain. Store if not.
355 if (!SSL_get_ex_data(ssl, ssl_ex_index_ssl_cert_chain)) {
356 STACK_OF(X509) *certStack = X509_STORE_CTX_get1_chain(ctx);
357 if (certStack && !SSL_set_ex_data(ssl, ssl_ex_index_ssl_cert_chain, certStack))
358 sk_X509_pop_free(certStack, X509_free);
359 }
360 }
361
7698a79c 362 if (!ok && !SSL_get_ex_data(ssl, ssl_ex_index_ssl_error_detail) ) {
f622c461
MF
363
364 // Find the broken certificate. It may be intermediate.
92e3827b 365 Security::CertPointer broken_cert(peer_cert); // reasonable default if search fails
f622c461
MF
366 // Our SQUID_X509_V_ERR_DOMAIN_MISMATCH implies peer_cert is at fault.
367 if (error_no != SQUID_X509_V_ERR_DOMAIN_MISMATCH) {
92e3827b
AJ
368 if (auto *last_used_cert = X509_STORE_CTX_get_current_cert(ctx))
369 broken_cert.resetAndLock(last_used_cert);
f622c461
MF
370 }
371
92e3827b
AJ
372 auto *errDetail = new Ssl::ErrorDetail(error_no, peer_cert.get(), broken_cert.get());
373 if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_error_detail, errDetail)) {
4d16918e
CT
374 debugs(83, 2, "Failed to set Ssl::ErrorDetail in ssl_verify_cb: Certificate " << buffer);
375 delete errDetail;
376 }
377 }
378
f484cdf5 379 return ok;
380}
381
815eaa44 382// "dup" function for SSL_get_ex_new_index("cert_err_check")
2a268a06
CT
383#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
384static int
385ssl_dupAclChecklist(CRYPTO_EX_DATA *, const CRYPTO_EX_DATA *, void *,
386 int, long, void *)
387#else
815eaa44 388static int
389ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *,
26ac0430 390 int, long, void *)
2a268a06 391#endif
26ac0430 392{
815eaa44 393 // We do not support duplication of ACLCheckLists.
394 // If duplication is needed, we can count copies with cbdata.
395 assert(false);
396 return 0;
397}
398
399// "free" function for SSL_get_ex_new_index("cert_err_check")
400static void
401ssl_freeAclChecklist(void *, void *ptr, CRYPTO_EX_DATA *,
26ac0430
AJ
402 int, long, void *)
403{
815eaa44 404 delete static_cast<ACLChecklist *>(ptr); // may be NULL
405}
a7ad6e4e 406
4d16918e
CT
407// "free" function for SSL_get_ex_new_index("ssl_error_detail")
408static void
409ssl_free_ErrorDetail(void *, void *ptr, CRYPTO_EX_DATA *,
410 int, long, void *)
411{
412 Ssl::ErrorDetail *errDetail = static_cast <Ssl::ErrorDetail *>(ptr);
413 delete errDetail;
414}
415
fb2178bb 416static void
7a957a93 417ssl_free_SslErrors(void *, void *ptr, CRYPTO_EX_DATA *,
87f237a9 418 int, long, void *)
fb2178bb 419{
92e3827b 420 Security::CertErrors *errs = static_cast <Security::CertErrors*>(ptr);
7a957a93 421 delete errs;
fb2178bb
CT
422}
423
0ad3ff51
CT
424// "free" function for SSL_get_ex_new_index("ssl_ex_index_ssl_validation_counter")
425static void
426ssl_free_int(void *, void *ptr, CRYPTO_EX_DATA *,
3cc296c4 427 int, long, void *)
0ad3ff51
CT
428{
429 uint32_t *counter = static_cast <uint32_t *>(ptr);
430 delete counter;
431}
432
4747ea4c
CT
433/// \ingroup ServerProtocolSSLInternal
434/// Callback handler function to release STACK_OF(X509) "ex" data stored
435/// in an SSL object.
436static void
437ssl_free_CertChain(void *, void *ptr, CRYPTO_EX_DATA *,
438 int, long, void *)
439{
440 STACK_OF(X509) *certsChain = static_cast <STACK_OF(X509) *>(ptr);
441 sk_X509_pop_free(certsChain,X509_free);
442}
443
e7bcc25f
CT
444// "free" function for X509 certificates
445static void
446ssl_free_X509(void *, void *ptr, CRYPTO_EX_DATA *,
87f237a9 447 int, long, void *)
e7bcc25f
CT
448{
449 X509 *cert = static_cast <X509 *>(ptr);
450 X509_free(cert);
451}
452
c1d50c01 453// "free" function for SBuf
68920ad8
CT
454static void
455ssl_free_SBuf(void *, void *ptr, CRYPTO_EX_DATA *,
456 int, long, void *)
457{
458 SBuf *buf = static_cast <SBuf *>(ptr);
459 delete buf;
460}
461
0a28c16a
AJ
462void
463Ssl::Initialize(void)
f484cdf5 464{
56a35ad1
AR
465 static bool initialized = false;
466 if (initialized)
467 return;
468 initialized = true;
62e76326 469
56a35ad1
AR
470 SSL_load_error_strings();
471 SSLeay_add_ssl_algorithms();
62e76326 472
56a35ad1 473#if HAVE_OPENSSL_ENGINE_H
0a28c16a 474 if (::Config.SSL.ssl_engine) {
56a35ad1 475 ENGINE *e;
0a28c16a
AJ
476 if (!(e = ENGINE_by_id(::Config.SSL.ssl_engine)))
477 fatalf("Unable to find SSL engine '%s'\n", ::Config.SSL.ssl_engine);
56a35ad1
AR
478
479 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
f5518dca 480 const int ssl_error = ERR_get_error();
ea574635 481 fatalf("Failed to initialise SSL engine: %s\n", Security::ErrorString(ssl_error));
62e76326 482 }
56a35ad1 483 }
a7ad6e4e 484#else
0a28c16a 485 if (::Config.SSL.ssl_engine)
56a35ad1 486 fatalf("Your OpenSSL has no SSL engine support\n");
a7ad6e4e 487#endif
62e76326 488
0a28c16a 489 const char *defName = ::Config.SSL.certSignHash ? ::Config.SSL.certSignHash : SQUID_SSL_SIGN_HASH_IF_NONE;
3c26b00a
CT
490 Ssl::DefaultSignHash = EVP_get_digestbyname(defName);
491 if (!Ssl::DefaultSignHash)
492 fatalf("Sign hash '%s' is not supported\n", defName);
493
fa1cf51e 494 ssl_ex_index_server = SSL_get_ex_new_index(0, (void *) "server", NULL, NULL, ssl_free_SBuf);
a7ad6e4e 495 ssl_ctx_ex_index_dont_verify_domain = SSL_CTX_get_ex_new_index(0, (void *) "dont_verify_domain", NULL, NULL, NULL);
815eaa44 496 ssl_ex_index_cert_error_check = SSL_get_ex_new_index(0, (void *) "cert_error_check", NULL, &ssl_dupAclChecklist, &ssl_freeAclChecklist);
4d16918e 497 ssl_ex_index_ssl_error_detail = SSL_get_ex_new_index(0, (void *) "ssl_error_detail", NULL, NULL, &ssl_free_ErrorDetail);
e7bcc25f 498 ssl_ex_index_ssl_peeked_cert = SSL_get_ex_new_index(0, (void *) "ssl_peeked_cert", NULL, NULL, &ssl_free_X509);
7a957a93 499 ssl_ex_index_ssl_errors = SSL_get_ex_new_index(0, (void *) "ssl_errors", NULL, NULL, &ssl_free_SslErrors);
4747ea4c 500 ssl_ex_index_ssl_cert_chain = SSL_get_ex_new_index(0, (void *) "ssl_cert_chain", NULL, NULL, &ssl_free_CertChain);
0ad3ff51 501 ssl_ex_index_ssl_validation_counter = SSL_get_ex_new_index(0, (void *) "ssl_validation_counter", NULL, NULL, &ssl_free_int);
55369ae6
AR
502 ssl_ex_index_ssl_untrusted_chain = SSL_get_ex_new_index(0, (void *) "ssl_untrusted_chain", NULL, NULL, &ssl_free_CertChain);
503}
504
86660d64 505static bool
b23f5f9c 506configureSslContext(Security::ContextPointer &ctx, AnyP::PortCfg &port)
86660d64
CT
507{
508 int ssl_error;
b23f5f9c 509 SSL_CTX_set_options(ctx.get(), port.secure.parsedOptions);
f484cdf5 510
86660d64 511 if (port.sslContextSessionId)
b23f5f9c 512 SSL_CTX_set_session_id_context(ctx.get(), (const unsigned char *)port.sslContextSessionId, strlen(port.sslContextSessionId));
6b2936d5 513
9a622f3e 514 if (port.secure.parsedFlags & SSL_FLAG_NO_SESSION_REUSE) {
b23f5f9c 515 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_OFF);
b13877cc 516 }
517
a9d79803 518 if (Config.SSL.unclean_shutdown) {
bf8fe701 519 debugs(83, 5, "Enabling quiet SSL shutdowns (RFC violation).");
a9d79803 520
b23f5f9c 521 SSL_CTX_set_quiet_shutdown(ctx.get(), 1);
a9d79803 522 }
523
9a622f3e
AJ
524 if (!port.secure.sslCipher.isEmpty()) {
525 debugs(83, 5, "Using chiper suite " << port.secure.sslCipher << ".");
62e76326 526
b23f5f9c 527 if (!SSL_CTX_set_cipher_list(ctx.get(), port.secure.sslCipher.c_str())) {
62e76326 528 ssl_error = ERR_get_error();
ea574635 529 debugs(83, DBG_CRITICAL, "ERROR: Failed to set SSL cipher suite '" << port.secure.sslCipher << "': " << Security::ErrorString(ssl_error));
86660d64 530 return false;
62e76326 531 }
79d4ccdf 532 }
62e76326 533
b7afb10f 534 maybeSetupRsaCallback(ctx);
a7ad6e4e 535
b23f5f9c
AJ
536 port.secure.updateContextEecdh(ctx);
537 port.secure.updateContextCa(ctx);
62e76326 538
86660d64 539 if (port.clientCA.get()) {
8c1ff4ef 540 ERR_clear_error();
e0f4e4e0 541 if (STACK_OF(X509_NAME) *clientca = SSL_dup_CA_list(port.clientCA.get())) {
b23f5f9c 542 SSL_CTX_set_client_CA_list(ctx.get(), clientca);
e0f4e4e0
AR
543 } else {
544 ssl_error = ERR_get_error();
ea574635 545 debugs(83, DBG_CRITICAL, "ERROR: Failed to dupe the client CA list: " << Security::ErrorString(ssl_error));
e0f4e4e0
AR
546 return false;
547 }
62e76326 548
9a622f3e 549 if (port.secure.parsedFlags & SSL_FLAG_DELAYED_AUTH) {
bf8fe701 550 debugs(83, 9, "Not requesting client certificates until acl processing requires one");
b23f5f9c 551 SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, NULL);
62e76326 552 } else {
bf8fe701 553 debugs(83, 9, "Requiring client certificates.");
b23f5f9c 554 SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
62e76326 555 }
a82a4fe4 556
b23f5f9c 557 port.secure.updateContextCrl(ctx);
a82a4fe4 558
a7ad6e4e 559 } else {
bf8fe701 560 debugs(83, 9, "Not requiring any client certificates");
b23f5f9c 561 SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, NULL);
a7ad6e4e 562 }
f484cdf5 563
9a622f3e 564 if (port.secure.parsedFlags & SSL_FLAG_DONT_VERIFY_DOMAIN)
b23f5f9c 565 SSL_CTX_set_ex_data(ctx.get(), ssl_ctx_ex_index_dont_verify_domain, (void *) -1);
86660d64 566
b23f5f9c 567 Ssl::SetSessionCallbacks(ctx);
10a69fc0 568
86660d64
CT
569 return true;
570}
571
c75aba02 572bool
b23f5f9c 573Ssl::InitServerContext(Security::ContextPointer &ctx, AnyP::PortCfg &port)
86660d64 574{
9ad528b8 575 if (!ctx)
c75aba02 576 return false;
86660d64 577
9ad528b8 578 if (!SSL_CTX_use_certificate(ctx.get(), port.signingCert.get())) {
f5518dca 579 const int ssl_error = ERR_get_error();
d1d72d43 580 const auto &keys = port.secure.certs.front();
ea574635 581 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire TLS certificate '" << keys.certFile << "': " << Security::ErrorString(ssl_error));
c75aba02 582 return false;
86660d64
CT
583 }
584
9ad528b8 585 if (!SSL_CTX_use_PrivateKey(ctx.get(), port.signPkey.get())) {
f5518dca 586 const int ssl_error = ERR_get_error();
d1d72d43 587 const auto &keys = port.secure.certs.front();
ea574635 588 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire TLS private key '" << keys.privateKeyFile << "': " << Security::ErrorString(ssl_error));
c75aba02 589 return false;
86660d64
CT
590 }
591
b23f5f9c 592 Ssl::addChainToSslContext(ctx, port.certsToChain.get());
86660d64
CT
593
594 /* Alternate code;
595 debugs(83, DBG_IMPORTANT, "Using certificate in " << certfile);
596
9ad528b8 597 if (!SSL_CTX_use_certificate_chain_file(ctx.get(), certfile)) {
86660d64 598 ssl_error = ERR_get_error();
ea574635 599 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL certificate '" << certfile << "': " << Security::ErrorString(ssl_error));
c75aba02 600 return false;
35105e4b 601 }
602
86660d64 603 debugs(83, DBG_IMPORTANT, "Using private key in " << keyfile);
9ad528b8 604 ssl_ask_password(ctx.get(), keyfile);
86660d64 605
9ad528b8 606 if (!SSL_CTX_use_PrivateKey_file(ctx.get(), keyfile, SSL_FILETYPE_PEM)) {
86660d64 607 ssl_error = ERR_get_error();
ea574635 608 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL private key '" << keyfile << "': " << Security::ErrorString(ssl_error));
c75aba02 609 return false;
35105e4b 610 }
611
86660d64 612 debugs(83, 5, "Comparing private and public SSL keys.");
35105e4b 613
9ad528b8 614 if (!SSL_CTX_check_private_key(ctx.get())) {
86660d64
CT
615 ssl_error = ERR_get_error();
616 debugs(83, DBG_CRITICAL, "ERROR: SSL private key '" << certfile << "' does not match public key '" <<
ea574635 617 keyfile << "': " << Security::ErrorString(ssl_error));
c75aba02 618 return false;
86660d64
CT
619 }
620 */
621
b23f5f9c 622 if (!configureSslContext(ctx, port)) {
86660d64 623 debugs(83, DBG_CRITICAL, "ERROR: Configuring static SSL context");
c75aba02 624 return false;
86660d64 625 }
62e76326 626
c75aba02 627 return true;
a7ad6e4e 628}
629
c75aba02 630bool
cc488ec9 631Ssl::InitClientContext(Security::ContextPointer &ctx, Security::PeerOptions &peer, long fl)
d620ae0e 632{
64769c79 633 if (!ctx)
c75aba02 634 return false;
62e76326 635
d1d72d43
AJ
636 if (!peer.sslCipher.isEmpty()) {
637 debugs(83, 5, "Using chiper suite " << peer.sslCipher << ".");
62e76326 638
d1d72d43 639 const char *cipher = peer.sslCipher.c_str();
64769c79 640 if (!SSL_CTX_set_cipher_list(ctx.get(), cipher)) {
f5518dca 641 const int ssl_error = ERR_get_error();
62e76326 642 fatalf("Failed to set SSL cipher suite '%s': %s\n",
ea574635 643 cipher, Security::ErrorString(ssl_error));
62e76326 644 }
a7ad6e4e 645 }
62e76326 646
332c979d
AJ
647 if (!peer.certs.empty()) {
648 // TODO: support loading multiple cert/key pairs
649 auto &keys = peer.certs.front();
650 if (!keys.certFile.isEmpty()) {
651 debugs(83, DBG_IMPORTANT, "Using certificate in " << keys.certFile);
652
653 const char *certfile = keys.certFile.c_str();
64769c79 654 if (!SSL_CTX_use_certificate_chain_file(ctx.get(), certfile)) {
332c979d
AJ
655 const int ssl_error = ERR_get_error();
656 fatalf("Failed to acquire SSL certificate '%s': %s\n",
ea574635 657 certfile, Security::ErrorString(ssl_error));
332c979d 658 }
62e76326 659
332c979d
AJ
660 debugs(83, DBG_IMPORTANT, "Using private key in " << keys.privateKeyFile);
661 const char *keyfile = keys.privateKeyFile.c_str();
64769c79 662 ssl_ask_password(ctx.get(), keyfile);
62e76326 663
64769c79 664 if (!SSL_CTX_use_PrivateKey_file(ctx.get(), keyfile, SSL_FILETYPE_PEM)) {
332c979d
AJ
665 const int ssl_error = ERR_get_error();
666 fatalf("Failed to acquire SSL private key '%s': %s\n",
ea574635 667 keyfile, Security::ErrorString(ssl_error));
332c979d 668 }
62e76326 669
332c979d 670 debugs(83, 5, "Comparing private and public SSL keys.");
62e76326 671
64769c79 672 if (!SSL_CTX_check_private_key(ctx.get())) {
332c979d
AJ
673 const int ssl_error = ERR_get_error();
674 fatalf("SSL private key '%s' does not match public key '%s': %s\n",
ea574635 675 certfile, keyfile, Security::ErrorString(ssl_error));
332c979d 676 }
62e76326 677 }
a7ad6e4e 678 }
62e76326 679
b7afb10f 680 maybeSetupRsaCallback(ctx);
f484cdf5 681
a7ad6e4e 682 if (fl & SSL_FLAG_DONT_VERIFY_PEER) {
48e7baac 683 debugs(83, 2, "NOTICE: Peer certificates are not verified for validity!");
64769c79 684 SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, NULL);
a7ad6e4e 685 } else {
bf8fe701 686 debugs(83, 9, "Setting certificate verification callback.");
64769c79 687 SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
a7ad6e4e 688 }
f484cdf5 689
c75aba02 690 return true;
f484cdf5 691}
692
63be0a78 693/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 694static const char *
695ssl_get_attribute(X509_NAME * name, const char *attribute_name)
696{
697 static char buffer[1024];
a7ad6e4e 698 buffer[0] = '\0';
699
700 if (strcmp(attribute_name, "DN") == 0) {
62e76326 701 X509_NAME_oneline(name, buffer, sizeof(buffer));
627059a5
AJ
702 } else {
703 int nid = OBJ_txt2nid(const_cast<char *>(attribute_name));
704 if (nid == 0) {
705 debugs(83, DBG_IMPORTANT, "WARNING: Unknown SSL attribute name '" << attribute_name << "'");
706 return nullptr;
707 }
708 X509_NAME_get_text_by_NID(name, nid, buffer, sizeof(buffer));
a7ad6e4e 709 }
62e76326 710
627059a5 711 return *buffer ? buffer : nullptr;
a7ad6e4e 712}
713
63be0a78 714/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 715const char *
00352183 716Ssl::GetX509UserAttribute(X509 * cert, const char *attribute_name)
a7ad6e4e 717{
a7ad6e4e 718 X509_NAME *name;
23e6c4ae 719 const char *ret;
a7ad6e4e 720
a7ad6e4e 721 if (!cert)
62e76326 722 return NULL;
a7ad6e4e 723
5a4684b6 724 name = X509_get_subject_name(cert);
a7ad6e4e 725
23e6c4ae 726 ret = ssl_get_attribute(name, attribute_name);
727
23e6c4ae 728 return ret;
a7ad6e4e 729}
730
00352183
AR
731const char *
732Ssl::GetX509Fingerprint(X509 * cert, const char *)
733{
734 static char buf[1024];
735 if (!cert)
736 return NULL;
960e100b 737
00352183
AR
738 unsigned int n;
739 unsigned char md[EVP_MAX_MD_SIZE];
740 if (!X509_digest(cert, EVP_sha1(), md, &n))
741 return NULL;
742
743 assert(3 * n + 1 < sizeof(buf));
744
745 char *s = buf;
746 for (unsigned int i=0; i < n; ++i, s += 3) {
747 const char term = (i + 1 < n) ? ':' : '\0';
748 snprintf(s, 4, "%02X%c", md[i], term);
749 }
750
751 return buf;
752}
753
63be0a78 754/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 755const char *
00352183 756Ssl::GetX509CAAttribute(X509 * cert, const char *attribute_name)
a7ad6e4e 757{
00352183 758
a7ad6e4e 759 X509_NAME *name;
23e6c4ae 760 const char *ret;
a7ad6e4e 761
a7ad6e4e 762 if (!cert)
62e76326 763 return NULL;
a7ad6e4e 764
5a4684b6 765 name = X509_get_issuer_name(cert);
a7ad6e4e 766
23e6c4ae 767 ret = ssl_get_attribute(name, attribute_name);
768
00352183
AR
769 return ret;
770}
771
772const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name)
773{
774 if (!ssl)
775 return NULL;
776
777 X509 *cert = SSL_get_peer_certificate(ssl);
778
779 const char *attr = Ssl::GetX509UserAttribute(cert, attribute_name);
780
23e6c4ae 781 X509_free(cert);
00352183
AR
782 return attr;
783}
23e6c4ae 784
00352183
AR
785const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name)
786{
787 if (!ssl)
788 return NULL;
789
790 X509 *cert = SSL_get_peer_certificate(ssl);
791
792 const char *attr = Ssl::GetX509CAAttribute(cert, attribute_name);
793
794 X509_free(cert);
795 return attr;
a7ad6e4e 796}
797
a7ad6e4e 798const char *
799sslGetUserEmail(SSL * ssl)
800{
e6ceef10 801 return sslGetUserAttribute(ssl, "emailAddress");
a7ad6e4e 802}
4ac9968f 803
804const char *
805sslGetUserCertificatePEM(SSL *ssl)
806{
807 X509 *cert;
808 BIO *mem;
809 static char *str = NULL;
810 char *ptr;
811 long len;
812
813 safe_free(str);
814
815 if (!ssl)
816 return NULL;
817
818 cert = SSL_get_peer_certificate(ssl);
819
820 if (!cert)
821 return NULL;
822
823 mem = BIO_new(BIO_s_mem());
824
825 PEM_write_bio_X509(mem, cert);
826
4ac9968f 827 len = BIO_get_mem_data(mem, &ptr);
828
829 str = (char *)xmalloc(len + 1);
830
831 memcpy(str, ptr, len);
832
833 str[len] = '\0';
834
835 X509_free(cert);
836
837 BIO_free(mem);
838
839 return str;
840}
3d61c476 841
842const char *
843sslGetUserCertificateChainPEM(SSL *ssl)
844{
845 STACK_OF(X509) *chain;
846 BIO *mem;
847 static char *str = NULL;
848 char *ptr;
849 long len;
850 int i;
851
852 safe_free(str);
853
854 if (!ssl)
855 return NULL;
856
857 chain = SSL_get_peer_cert_chain(ssl);
858
859 if (!chain)
860 return sslGetUserCertificatePEM(ssl);
861
862 mem = BIO_new(BIO_s_mem());
863
d7ae3534 864 for (i = 0; i < sk_X509_num(chain); ++i) {
3d61c476 865 X509 *cert = sk_X509_value(chain, i);
866 PEM_write_bio_X509(mem, cert);
867 }
868
869 len = BIO_get_mem_data(mem, &ptr);
870
871 str = (char *)xmalloc(len + 1);
872 memcpy(str, ptr, len);
873 str[len] = '\0';
874
875 BIO_free(mem);
876
877 return str;
878}
454e8283 879
95d2589c 880/// Create SSL context and apply ssl certificate and private key to it.
0476ec45 881Security::ContextPointer
f97700a0 882Ssl::createSSLContext(Security::CertPointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port)
95d2589c 883{
0476ec45 884 Security::ContextPointer ctx(port.secure.createBlankContext());
95d2589c 885
0476ec45
AJ
886 if (!SSL_CTX_use_certificate(ctx.get(), x509.get()))
887 return Security::ContextPointer();
95d2589c 888
0476ec45
AJ
889 if (!SSL_CTX_use_PrivateKey(ctx.get(), pkey.get()))
890 return Security::ContextPointer();
86660d64 891
b23f5f9c 892 if (!configureSslContext(ctx, port))
0476ec45 893 return Security::ContextPointer();
86660d64 894
0476ec45 895 return ctx;
95d2589c
CT
896}
897
0476ec45 898Security::ContextPointer
86660d64 899Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortCfg &port)
95d2589c 900{
f97700a0 901 Security::CertPointer cert;
95d2589c 902 Ssl::EVP_PKEY_Pointer pkey;
96993ee0 903 if (!readCertAndPrivateKeyFromMemory(cert, pkey, data) || !cert || !pkey)
0476ec45 904 return Security::ContextPointer();
95d2589c 905
86660d64 906 return createSSLContext(cert, pkey, port);
95d2589c
CT
907}
908
0476ec45 909Security::ContextPointer
86660d64 910Ssl::generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &port)
95d2589c 911{
f97700a0 912 Security::CertPointer cert;
95d2589c 913 Ssl::EVP_PKEY_Pointer pkey;
96993ee0 914 if (!generateSslCertificate(cert, pkey, properties) || !cert || !pkey)
0476ec45 915 return Security::ContextPointer();
95d2589c 916
86660d64 917 return createSSLContext(cert, pkey, port);
95d2589c
CT
918}
919
d8f0ceab 920void
b23f5f9c 921Ssl::chainCertificatesToSSLContext(Security::ContextPointer &ctx, AnyP::PortCfg &port)
d8f0ceab 922{
b23f5f9c 923 assert(ctx);
d8f0ceab
CT
924 // Add signing certificate to the certificates chain
925 X509 *signingCert = port.signingCert.get();
b23f5f9c 926 if (SSL_CTX_add_extra_chain_cert(ctx.get(), signingCert)) {
d8f0ceab 927 // increase the certificate lock
6f2b8700 928 X509_up_ref(signingCert);
d8f0ceab
CT
929 } else {
930 const int ssl_error = ERR_get_error();
ea574635 931 debugs(33, DBG_IMPORTANT, "WARNING: can not add signing certificate to SSL context chain: " << Security::ErrorString(ssl_error));
d8f0ceab 932 }
b23f5f9c 933 Ssl::addChainToSslContext(ctx, port.certsToChain.get());
d8f0ceab
CT
934}
935
936void
b23f5f9c 937Ssl::configureUnconfiguredSslContext(Security::ContextPointer &ctx, Ssl::CertSignAlgorithm signAlgorithm,AnyP::PortCfg &port)
d8f0ceab 938{
b23f5f9c
AJ
939 if (ctx && signAlgorithm == Ssl::algSignTrusted)
940 Ssl::chainCertificatesToSSLContext(ctx, port);
d8f0ceab
CT
941}
942
d620ae0e
CT
943bool
944Ssl::configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port)
945{
f97700a0 946 Security::CertPointer cert;
d620ae0e
CT
947 Ssl::EVP_PKEY_Pointer pkey;
948 if (!generateSslCertificate(cert, pkey, properties))
949 return false;
950
951 if (!cert)
952 return false;
953
954 if (!pkey)
955 return false;
956
957 if (!SSL_use_certificate(ssl, cert.get()))
958 return false;
959
960 if (!SSL_use_PrivateKey(ssl, pkey.get()))
961 return false;
962
963 return true;
964}
965
966bool
967Ssl::configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port)
968{
f97700a0 969 Security::CertPointer cert;
d620ae0e
CT
970 Ssl::EVP_PKEY_Pointer pkey;
971 if (!readCertAndPrivateKeyFromMemory(cert, pkey, data))
972 return false;
973
974 if (!cert || !pkey)
975 return false;
976
977 if (!SSL_use_certificate(ssl, cert.get()))
978 return false;
979
980 if (!SSL_use_PrivateKey(ssl, pkey.get()))
981 return false;
982
983 return true;
984}
985
b23f5f9c
AJ
986bool
987Ssl::verifySslCertificate(Security::ContextPointer &ctx, CertificateProperties const &properties)
95d2589c 988{
b8649ee4
CT
989#if HAVE_SSL_CTX_GET0_CERTIFICATE
990 X509 * cert = SSL_CTX_get0_certificate(ctx.get());
991#elif SQUID_USE_SSLGETCERTIFICATE_HACK
b8658552 992 // SSL_get_certificate is buggy in openssl versions 1.0.1d and 1.0.1e
b23f5f9c 993 // Try to retrieve certificate directly from Security::ContextPointer object
b23f5f9c 994 X509 ***pCert = (X509 ***)ctx->cert;
b8658552 995 X509 * cert = pCert && *pCert ? **pCert : NULL;
fc321c30
CT
996#elif SQUID_SSLGETCERTIFICATE_BUGGY
997 X509 * cert = NULL;
998 assert(0);
b8658552 999#else
95d2589c 1000 // Temporary ssl for getting X509 certificate from SSL_CTX.
c96b5508 1001 Security::SessionPointer ssl(Security::NewSessionObject(ctx));
95d2589c 1002 X509 * cert = SSL_get_certificate(ssl.get());
b8658552
CT
1003#endif
1004 if (!cert)
1005 return false;
95d2589c
CT
1006 ASN1_TIME * time_notBefore = X509_get_notBefore(cert);
1007 ASN1_TIME * time_notAfter = X509_get_notAfter(cert);
1008 bool ret = (X509_cmp_current_time(time_notBefore) < 0 && X509_cmp_current_time(time_notAfter) > 0);
e7bcc25f
CT
1009 if (!ret)
1010 return false;
1011
4ece76b2 1012 return certificateMatchesProperties(cert, properties);
95d2589c
CT
1013}
1014
253749a8
CT
1015bool
1016Ssl::setClientSNI(SSL *ssl, const char *fqdn)
1017{
1018 //The SSL_CTRL_SET_TLSEXT_HOSTNAME is a openssl macro which indicates
1019 // if the TLS servername extension (SNI) is enabled in openssl library.
1020#if defined(SSL_CTRL_SET_TLSEXT_HOSTNAME)
1021 if (!SSL_set_tlsext_host_name(ssl, fqdn)) {
1022 const int ssl_error = ERR_get_error();
1023 debugs(83, 3, "WARNING: unable to set TLS servername extension (SNI): " <<
ea574635 1024 Security::ErrorString(ssl_error) << "\n");
253749a8
CT
1025 return false;
1026 }
1027 return true;
1028#else
1029 debugs(83, 7, "no support for TLS servername extension (SNI)\n");
1030 return false;
1031#endif
1032}
1033
b23f5f9c
AJ
1034void
1035Ssl::addChainToSslContext(Security::ContextPointer &ctx, STACK_OF(X509) *chain)
a594dbfa
CT
1036{
1037 if (!chain)
1038 return;
1039
d7ae3534 1040 for (int i = 0; i < sk_X509_num(chain); ++i) {
a594dbfa 1041 X509 *cert = sk_X509_value(chain, i);
b23f5f9c 1042 if (SSL_CTX_add_extra_chain_cert(ctx.get(), cert)) {
a594dbfa 1043 // increase the certificate lock
6f2b8700 1044 X509_up_ref(cert);
a594dbfa
CT
1045 } else {
1046 const int ssl_error = ERR_get_error();
ea574635 1047 debugs(83, DBG_IMPORTANT, "WARNING: can not add certificate to SSL context chain: " << Security::ErrorString(ssl_error));
a594dbfa
CT
1048 }
1049 }
1050}
1051
55369ae6
AR
1052static const char *
1053hasAuthorityInfoAccessCaIssuers(X509 *cert)
1054{
1055 AUTHORITY_INFO_ACCESS *info;
1056 if (!cert)
168d2b30 1057 return nullptr;
4b5ea8a6 1058 info = static_cast<AUTHORITY_INFO_ACCESS *>(X509_get_ext_d2i(cert, NID_info_access, NULL, NULL));
55369ae6 1059 if (!info)
168d2b30 1060 return nullptr;
55369ae6
AR
1061
1062 static char uri[MAX_URL];
1063 uri[0] = '\0';
1064
1065 for (int i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
1066 ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
1067 if (OBJ_obj2nid(ad->method) == NID_ad_ca_issuers) {
1068 if (ad->location->type == GEN_URI) {
2a268a06
CT
1069 xstrncpy(uri,
1070 reinterpret_cast<const char *>(
17e98f24 1071#if HAVE_LIBCRYPTO_ASN1_STRING_GET0_DATA
2a268a06 1072 ASN1_STRING_get0_data(ad->location->d.uniformResourceIdentifier)
17e98f24
AJ
1073#else
1074 ASN1_STRING_data(ad->location->d.uniformResourceIdentifier)
2a268a06 1075#endif
ac756c8c 1076 ),
2a268a06 1077 sizeof(uri));
55369ae6
AR
1078 }
1079 break;
1080 }
1081 }
1082 AUTHORITY_INFO_ACCESS_free(info);
168d2b30 1083 return uri[0] != '\0' ? uri : nullptr;
55369ae6
AR
1084}
1085
866be11c
CT
1086bool
1087Ssl::loadCerts(const char *certsFile, Ssl::CertsIndexedList &list)
1088{
1089 BIO *in = BIO_new_file(certsFile, "r");
1090 if (!in) {
1091 debugs(83, DBG_IMPORTANT, "Failed to open '" << certsFile << "' to load certificates");
1092 return false;
1093 }
1094
1095 X509 *aCert;
1096 while((aCert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1097 static char buffer[2048];
1098 X509_NAME_oneline(X509_get_subject_name(aCert), buffer, sizeof(buffer));
1099 list.insert(std::pair<SBuf, X509 *>(SBuf(buffer), aCert));
1100 }
1101 debugs(83, 4, "Loaded " << list.size() << " certificates from file: '" << certsFile << "'");
1102 BIO_free(in);
1103 return true;
1104}
1105
6c4905ef
CT
1106/// quickly find the issuer certificate of a certificate cert in the
1107/// Ssl::CertsIndexedList list
55369ae6 1108static X509 *
6c4905ef 1109findCertIssuerFast(Ssl::CertsIndexedList &list, X509 *cert)
55369ae6
AR
1110{
1111 static char buffer[2048];
1112
1113 if (X509_NAME *issuerName = X509_get_issuer_name(cert))
1114 X509_NAME_oneline(issuerName, buffer, sizeof(buffer));
1115 else
1116 return NULL;
1117
1118 const auto ret = list.equal_range(SBuf(buffer));
1119 for (Ssl::CertsIndexedList::iterator it = ret.first; it != ret.second; ++it) {
1120 X509 *issuer = it->second;
2f774469 1121 if (X509_check_issued(issuer, cert) == X509_V_OK) {
55369ae6
AR
1122 return issuer;
1123 }
1124 }
1125 return NULL;
1126}
1127
6c4905ef 1128/// slowly find the issuer certificate of a given cert using linear search
a34d1d2d
CT
1129static bool
1130findCertIssuer(Security::CertList const &list, X509 *cert)
55369ae6 1131{
a34d1d2d
CT
1132 for (Security::CertList::const_iterator it = list.begin(); it != list.end(); ++it) {
1133 if (X509_check_issued(it->get(), cert) == X509_V_OK)
1134 return true;
55369ae6 1135 }
a34d1d2d 1136 return false;
55369ae6
AR
1137}
1138
1139const char *
a34d1d2d 1140Ssl::uriOfIssuerIfMissing(X509 *cert, Security::CertList const &serverCertificates)
55369ae6 1141{
a34d1d2d 1142 if (!cert || !serverCertificates.size())
168d2b30 1143 return nullptr;
55369ae6 1144
a34d1d2d 1145 if (!findCertIssuer(serverCertificates, cert)) {
168d2b30 1146 //if issuer is missing
6c4905ef 1147 if (!findCertIssuerFast(SquidUntrustedCerts, cert)) {
3945c91d 1148 // and issuer not found in local untrusted certificates database
55369ae6
AR
1149 if (const char *issuerUri = hasAuthorityInfoAccessCaIssuers(cert)) {
1150 // There is a URI where we can download a certificate.
55369ae6
AR
1151 return issuerUri;
1152 }
1153 }
1154 }
168d2b30 1155 return nullptr;
55369ae6
AR
1156}
1157
1158void
a34d1d2d 1159Ssl::missingChainCertificatesUrls(std::queue<SBuf> &URIs, Security::CertList const &serverCertificates)
55369ae6 1160{
a34d1d2d 1161 if (!serverCertificates.size())
55369ae6
AR
1162 return;
1163
4b5ea8a6
CT
1164 for (const auto &i : serverCertificates) {
1165 if (const char *issuerUri = uriOfIssuerIfMissing(i.get(), serverCertificates))
55369ae6
AR
1166 URIs.push(SBuf(issuerUri));
1167 }
1168}
1169
1170void
1171Ssl::SSL_add_untrusted_cert(SSL *ssl, X509 *cert)
1172{
1173 STACK_OF(X509) *untrustedStack = static_cast <STACK_OF(X509) *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_untrusted_chain));
1174 if (!untrustedStack) {
1175 untrustedStack = sk_X509_new_null();
1176 if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_untrusted_chain, untrustedStack)) {
168d2b30
CT
1177 sk_X509_pop_free(untrustedStack, X509_free);
1178 throw TextException("Failed to attach untrusted certificates chain");
55369ae6
AR
1179 }
1180 }
1181 sk_X509_push(untrustedStack, cert);
1182}
1183
6c4905ef 1184/// Search for the issuer certificate of cert in sk list.
a34d1d2d 1185static X509 *
6c4905ef 1186sk_x509_findIssuer(STACK_OF(X509) *sk, X509 *cert)
a34d1d2d
CT
1187{
1188 if (!sk)
1189 return NULL;
1190
1191 const int skItemsNum = sk_X509_num(sk);
1192 for (int i = 0; i < skItemsNum; ++i) {
1193 X509 *issuer = sk_X509_value(sk, i);
1194 if (X509_check_issued(issuer, cert) == X509_V_OK)
1195 return issuer;
1196 }
1197 return NULL;
1198}
1199
55369ae6
AR
1200/// add missing issuer certificates to untrustedCerts
1201static void
1202completeIssuers(X509_STORE_CTX *ctx, STACK_OF(X509) *untrustedCerts)
1203{
1204 debugs(83, 2, "completing " << sk_X509_num(untrustedCerts) << " OpenSSL untrusted certs using " << SquidUntrustedCerts.size() << " configured untrusted certificates");
1205
17e98f24 1206#if HAVE_LIBCRYPTO_X509_VERIFY_PARAM_GET_DEPTH
2a268a06
CT
1207 const X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx);
1208 int depth = X509_VERIFY_PARAM_get_depth(param);
17e98f24
AJ
1209#else
1210 int depth = ctx->param->depth;
2a268a06
CT
1211#endif
1212 X509 *current = X509_STORE_CTX_get0_cert(ctx);
55369ae6
AR
1213 int i = 0;
1214 for (i = 0; current && (i < depth); ++i) {
2f774469 1215 if (X509_check_issued(current, current) == X509_V_OK) {
55369ae6
AR
1216 // either ctx->cert is itself self-signed or untrustedCerts
1217 // aready contain the self-signed current certificate
1218 break;
1219 }
1220
1221 // untrustedCerts is short, not worth indexing
6c4905ef 1222 X509 *issuer = sk_x509_findIssuer(untrustedCerts, current);
55369ae6 1223 if (!issuer) {
6c4905ef 1224 if ((issuer = findCertIssuerFast(SquidUntrustedCerts, current)))
55369ae6
AR
1225 sk_X509_push(untrustedCerts, issuer);
1226 }
1227 current = issuer;
1228 }
1229
1230 if (i >= depth)
1231 debugs(83, 2, "exceeded the maximum certificate chain length: " << depth);
1232}
1233
1234/// OpenSSL certificate validation callback.
1235static int
1236untrustedToStoreCtx_cb(X509_STORE_CTX *ctx,void *data)
1237{
1238 debugs(83, 4, "Try to use pre-downloaded intermediate certificates\n");
1239
4b5ea8a6 1240 SSL *ssl = static_cast<SSL *>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
55369ae6
AR
1241 STACK_OF(X509) *sslUntrustedStack = static_cast <STACK_OF(X509) *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_untrusted_chain));
1242
1243 // OpenSSL already maintains ctx->untrusted but we cannot modify
1244 // internal OpenSSL list directly. We have to give OpenSSL our own
1245 // list, but it must include certificates on the OpenSSL ctx->untrusted
17e98f24 1246#if HAVE_LIBCRYPTO_X509_STORE_CTX_GET0_UNTRUSTED
2a268a06 1247 STACK_OF(X509) *oldUntrusted = X509_STORE_CTX_get0_untrusted(ctx);
17e98f24
AJ
1248#else
1249 STACK_OF(X509) *oldUntrusted = ctx->untrusted;
2a268a06 1250#endif
55369ae6
AR
1251 STACK_OF(X509) *sk = sk_X509_dup(oldUntrusted); // oldUntrusted is always not NULL
1252
1253 for (int i = 0; i < sk_X509_num(sslUntrustedStack); ++i) {
1254 X509 *cert = sk_X509_value(sslUntrustedStack, i);
1255 sk_X509_push(sk, cert);
1256 }
1257
1258 // If the local untrusted certificates internal database is used
1259 // run completeIssuers to add missing certificates if possible.
1260 if (SquidUntrustedCerts.size() > 0)
1261 completeIssuers(ctx, sk);
1262
1263 X509_STORE_CTX_set_chain(ctx, sk); // No locking/unlocking, just sets ctx->untrusted
1264 int ret = X509_verify_cert(ctx);
17e98f24 1265#if HAVE_LIBCRYPTO_X509_STORE_CTX_SET0_UNTRUSTED
2a268a06 1266 X509_STORE_CTX_set0_untrusted(ctx, oldUntrusted);
17e98f24
AJ
1267#else
1268 X509_STORE_CTX_set_chain(ctx, oldUntrusted); // Set back the old untrusted list
2a268a06 1269#endif
55369ae6
AR
1270 sk_X509_free(sk); // Release sk list
1271 return ret;
1272}
1273
1274void
1275Ssl::useSquidUntrusted(SSL_CTX *sslContext)
1276{
1277 SSL_CTX_set_cert_verify_callback(sslContext, untrustedToStoreCtx_cb, NULL);
1278}
1279
1280bool
1281Ssl::loadSquidUntrusted(const char *path)
1282{
1283 return Ssl::loadCerts(path, SquidUntrustedCerts);
1284}
1285
1286void
1287Ssl::unloadSquidUntrusted()
1288{
1289 if (SquidUntrustedCerts.size()) {
1290 for (Ssl::CertsIndexedList::iterator it = SquidUntrustedCerts.begin(); it != SquidUntrustedCerts.end(); ++it) {
1291 X509_free(it->second);
1292 }
1293 SquidUntrustedCerts.clear();
1294 }
1295}
1296
a594dbfa
CT
1297/**
1298 \ingroup ServerProtocolSSLInternal
1299 * Read certificate from file.
1300 * See also: static readSslX509Certificate function, gadgets.cc file
1301 */
1302static X509 * readSslX509CertificatesChain(char const * certFilename, STACK_OF(X509)* chain)
1303{
1304 if (!certFilename)
1305 return NULL;
093deea9 1306 Ssl::BIO_Pointer bio(BIO_new(BIO_s_file()));
a594dbfa
CT
1307 if (!bio)
1308 return NULL;
1309 if (!BIO_read_filename(bio.get(), certFilename))
1310 return NULL;
1311 X509 *certificate = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL);
1312
1313 if (certificate && chain) {
1314
c11211d9 1315 if (X509_check_issued(certificate, certificate) == X509_V_OK)
a594dbfa
CT
1316 debugs(83, 5, "Certificate is self-signed, will not be chained");
1317 else {
a411d213 1318 // and add to the chain any other certificate exist in the file
a594dbfa
CT
1319 while (X509 *ca = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL)) {
1320 if (!sk_X509_push(chain, ca))
1321 debugs(83, DBG_IMPORTANT, "WARNING: unable to add CA certificate to cert chain");
1322 }
1323 }
1324 }
c11211d9 1325
a594dbfa
CT
1326 return certificate;
1327}
1328
f97700a0 1329void Ssl::readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename)
a594dbfa
CT
1330{
1331 if (keyFilename == NULL)
1332 keyFilename = certFilename;
86660d64
CT
1333
1334 if (certFilename == NULL)
1335 certFilename = keyFilename;
1336
1337 debugs(83, DBG_IMPORTANT, "Using certificate in " << certFilename);
1338
a594dbfa
CT
1339 if (!chain)
1340 chain.reset(sk_X509_new_null());
1341 if (!chain)
1342 debugs(83, DBG_IMPORTANT, "WARNING: unable to allocate memory for cert chain");
37144aca
AR
1343 // XXX: ssl_ask_password_cb needs SSL_CTX_set_default_passwd_cb_userdata()
1344 // so this may not fully work iff Config.Program.ssl_password is set.
1345 pem_password_cb *cb = ::Config.Program.ssl_password ? &ssl_ask_password_cb : NULL;
35b3559c
AJ
1346 pkey.resetWithoutLocking(readSslPrivateKey(keyFilename, cb));
1347 cert.resetWithoutLocking(readSslX509CertificatesChain(certFilename, chain.get()));
599111be
AJ
1348 if (!cert) {
1349 debugs(83, DBG_IMPORTANT, "WARNING: missing cert in '" << certFilename << "'");
1350 } else if (!pkey) {
1351 debugs(83, DBG_IMPORTANT, "WARNING: missing private key in '" << keyFilename << "'");
1352 } else if (!X509_check_private_key(cert.get(), pkey.get())) {
1353 debugs(83, DBG_IMPORTANT, "WARNING: X509_check_private_key() failed to verify signing cert");
1354 } else
1355 return; // everything is okay
1356
1357 pkey.reset();
1358 cert.reset();
a594dbfa
CT
1359}
1360
f97700a0 1361bool Ssl::generateUntrustedCert(Security::CertPointer &untrustedCert, EVP_PKEY_Pointer &untrustedPkey, Security::CertPointer const &cert, EVP_PKEY_Pointer const & pkey)
95588170
CT
1362{
1363 // Generate the self-signed certificate, using a hard-coded subject prefix
1364 Ssl::CertificateProperties certProperties;
1365 if (const char *cn = CommonHostName(cert.get())) {
1366 certProperties.commonName = "Not trusted by \"";
1367 certProperties.commonName += cn;
1368 certProperties.commonName += "\"";
87f237a9 1369 } else if (const char *org = getOrganization(cert.get())) {
95588170
CT
1370 certProperties.commonName = "Not trusted by \"";
1371 certProperties.commonName += org;
1372 certProperties.commonName += "\"";
87f237a9 1373 } else
95588170
CT
1374 certProperties.commonName = "Not trusted";
1375 certProperties.setCommonName = true;
1376 // O, OU, and other CA subject fields will be mimicked
1377 // Expiration date and other common properties will be mimicked
1378 certProperties.signAlgorithm = Ssl::algSignSelf;
1379 certProperties.signWithPkey.resetAndLock(pkey.get());
1380 certProperties.mimicCert.resetAndLock(cert.get());
1381 return Ssl::generateSslCertificate(untrustedCert, untrustedPkey, certProperties);
1382}
1383
10a69fc0
CT
1384static int
1385store_session_cb(SSL *ssl, SSL_SESSION *session)
1386{
824d4656 1387 if (!Ssl::SessionCache)
10a69fc0
CT
1388 return 0;
1389
1390 debugs(83, 5, "Request to store SSL Session ");
1391
1392 SSL_SESSION_set_timeout(session, Config.SSL.session_ttl);
1393
17e98f24 1394#if HAVE_LIBSSL_SSL_SESSION_GET_ID
2a268a06
CT
1395 unsigned int idlen;
1396 const unsigned char *id = SSL_SESSION_get_id(session, &idlen);
17e98f24
AJ
1397#else
1398 unsigned char *id = session->session_id;
1399 unsigned int idlen = session->session_id_length;
2a268a06 1400#endif
10a69fc0
CT
1401 unsigned char key[MEMMAP_SLOT_KEY_SIZE];
1402 // Session ids are of size 32bytes. They should always fit to a
86c63190 1403 // MemMap::Slot::key
10a69fc0
CT
1404 assert(idlen <= MEMMAP_SLOT_KEY_SIZE);
1405 memset(key, 0, sizeof(key));
1406 memcpy(key, id, idlen);
1407 int pos;
824d4656 1408 Ipc::MemMap::Slot *slotW = Ssl::SessionCache->openForWriting((const cache_key*)key, pos);
10a69fc0
CT
1409 if (slotW) {
1410 int lenRequired = i2d_SSL_SESSION(session, NULL);
1411 if (lenRequired < MEMMAP_SLOT_DATA_SIZE) {
1412 unsigned char *p = (unsigned char *)slotW->p;
1413 lenRequired = i2d_SSL_SESSION(session, &p);
1414 slotW->set(key, NULL, lenRequired, squid_curtime + Config.SSL.session_ttl);
1415 }
824d4656 1416 Ssl::SessionCache->closeForWriting(pos);
10a69fc0
CT
1417 debugs(83, 5, "wrote an ssl session entry of size " << lenRequired << " at pos " << pos);
1418 }
1419 return 0;
1420}
1421
1422static void
1423remove_session_cb(SSL_CTX *, SSL_SESSION *sessionID)
1424{
824d4656 1425 if (!Ssl::SessionCache)
10a69fc0
CT
1426 return ;
1427
1428 debugs(83, 5, "Request to remove corrupted or not valid SSL Session ");
1429 int pos;
824d4656 1430 Ipc::MemMap::Slot const *slot = Ssl::SessionCache->openForReading((const cache_key*)sessionID, pos);
10a69fc0
CT
1431 if (slot == NULL)
1432 return;
824d4656 1433 Ssl::SessionCache->closeForReading(pos);
10a69fc0
CT
1434 // TODO:
1435 // What if we are not able to remove the session?
1436 // Maybe schedule a job to remove it later?
1437 // For now we just have an invalid entry in cache until will be expired
1438 // The openSSL will reject it when we try to use it
824d4656 1439 Ssl::SessionCache->free(pos);
10a69fc0
CT
1440}
1441
1442static SSL_SESSION *
2a268a06 1443#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
10a69fc0 1444get_session_cb(SSL *, unsigned char *sessionID, int len, int *copy)
2a268a06
CT
1445#else
1446get_session_cb(SSL *, const unsigned char *sessionID, int len, int *copy)
1447#endif
10a69fc0 1448{
824d4656 1449 if (!Ssl::SessionCache)
10a69fc0
CT
1450 return NULL;
1451
1452 SSL_SESSION *session = NULL;
1453 const unsigned int *p;
1454 p = (unsigned int *)sessionID;
1455 debugs(83, 5, "Request to search for SSL Session of len:" <<
1456 len << p[0] << ":" << p[1]);
1457
1458 int pos;
824d4656 1459 Ipc::MemMap::Slot const *slot = Ssl::SessionCache->openForReading((const cache_key*)sessionID, pos);
10a69fc0
CT
1460 if (slot != NULL) {
1461 if (slot->expire > squid_curtime) {
1462 const unsigned char *ptr = slot->p;
1463 session = d2i_SSL_SESSION(NULL, &ptr, slot->pSize);
1464 debugs(83, 5, "Session retrieved from cache at pos " << pos);
1465 } else
1466 debugs(83, 5, "Session in cache expired");
824d4656 1467 Ssl::SessionCache->closeForReading(pos);
10a69fc0
CT
1468 }
1469
1470 if (!session)
1471 debugs(83, 5, "Failed to retrieved from cache\n");
1472
1473 // With the parameter copy the callback can require the SSL engine
1474 // to increment the reference count of the SSL_SESSION object, Normally
1475 // the reference count is not incremented and therefore the session must
1476 // not be explicitly freed with SSL_SESSION_free(3).
1477 *copy = 0;
1478 return session;
1479}
1480
824d4656 1481void
b23f5f9c 1482Ssl::SetSessionCallbacks(Security::ContextPointer &ctx)
10a69fc0 1483{
824d4656 1484 if (Ssl::SessionCache) {
b23f5f9c
AJ
1485 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL);
1486 SSL_CTX_sess_set_new_cb(ctx.get(), store_session_cb);
1487 SSL_CTX_sess_set_remove_cb(ctx.get(), remove_session_cb);
1488 SSL_CTX_sess_set_get_cb(ctx.get(), get_session_cb);
10a69fc0
CT
1489 }
1490}
1491
cb4f4424 1492#endif /* USE_OPENSSL */
f53969cc 1493