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