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