]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ssl/support.cc
MemBuf implements Packable interface
[thirdparty/squid.git] / src / ssl / support.cc
1 /*
2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9 /* DEBUG: section 83 SSL accelerator support */
10
11 #include "squid.h"
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 */
16 #if USE_OPENSSL
17
18 #include "acl/FilledChecklist.h"
19 #include "anyp/PortCfg.h"
20 #include "fatal.h"
21 #include "fd.h"
22 #include "fde.h"
23 #include "globals.h"
24 #include "ipc/MemMap.h"
25 #include "SquidConfig.h"
26 #include "SquidTime.h"
27 #include "ssl/bio.h"
28 #include "ssl/Config.h"
29 #include "ssl/ErrorDetail.h"
30 #include "ssl/gadgets.h"
31 #include "ssl/support.h"
32 #include "URL.h"
33
34 #include <cerrno>
35
36 static void setSessionCallbacks(SSL_CTX *ctx);
37 Ipc::MemMap *SslSessionCache = NULL;
38 const char *SslSessionCacheName = "ssl_session_cache";
39
40 const EVP_MD *Ssl::DefaultSignHash = NULL;
41
42 const char *Ssl::BumpModeStr[] = {
43 "none",
44 "client-first",
45 "server-first",
46 "peek",
47 "stare",
48 "bump",
49 "splice",
50 "terminate",
51 /*"err",*/
52 NULL
53 };
54
55 /**
56 \defgroup ServerProtocolSSLInternal Server-Side SSL Internals
57 \ingroup ServerProtocolSSLAPI
58 */
59
60 /// \ingroup ServerProtocolSSLInternal
61 static int
62 ssl_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'))
76 --len;
77
78 buf[len] = '\0';
79
80 pclose(in);
81
82 return len;
83 }
84
85 /// \ingroup ServerProtocolSSLInternal
86 static void
87 ssl_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
95 /// \ingroup ServerProtocolSSLInternal
96 static RSA *
97 ssl_temp_rsa_cb(SSL * ssl, int anInt, int keylen)
98 {
99 static RSA *rsa_512 = NULL;
100 static RSA *rsa_1024 = NULL;
101 RSA *rsa = NULL;
102 int newkey = 0;
103
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:
127 debugs(83, DBG_IMPORTANT, "ssl_temp_rsa_cb: Unexpected key length " << keylen);
128 return NULL;
129 }
130
131 if (rsa == NULL) {
132 debugs(83, DBG_IMPORTANT, "ssl_temp_rsa_cb: Failed to generate key " << keylen);
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
140 debugs(83, DBG_IMPORTANT, "Generated ephemeral RSA key of length " << keylen);
141 }
142
143 return rsa;
144 }
145
146 int 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) {
152 if (ASN1_TIME_print(bio, tm))
153 write = BIO_read(bio, buf, len-1);
154 BIO_free(bio);
155 }
156 buf[write]='\0';
157 return write;
158 }
159
160 int 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)) {
167
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);
179 for (int i = 0; i < numalts; ++i) {
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;
185
186 if ( (*check_func)(check_data, cn_data) == 0) {
187 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
188 return 1;
189 }
190 }
191 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
192 }
193 return 0;
194 }
195
196 static int check_domain( void *check_data, ASN1_STRING *cn_data)
197 {
198 char cn[1024];
199 const char *server = (const char *)check_data;
200
201 if (cn_data->length > (int)sizeof(cn) - 1) {
202 return 1; //if does not fit our buffer just ignore
203 }
204 memcpy(cn, cn_data->data, cn_data->length);
205 cn[cn_data->length] = '\0';
206 debugs(83, 4, "Verifying server domain " << server << " to certificate name/subjectAltName " << cn);
207 return matchDomainName(server, cn[0] == '*' ? cn + 1 : cn);
208 }
209
210 bool Ssl::checkX509ServerValidity(X509 *cert, const char *server)
211 {
212 return matchX509CommonNames(cert, (void *)server, check_domain);
213 }
214
215 /// \ingroup ServerProtocolSSLInternal
216 static int
217 ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
218 {
219 // preserve original ctx->error before SSL_ calls can overwrite it
220 Ssl::ssl_error_t error_no = ok ? SSL_ERROR_NONE : ctx->error;
221
222 char buffer[256] = "";
223 SSL *ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
224 SSL_CTX *sslctx = SSL_get_SSL_CTX(ssl);
225 const char *server = (const char *)SSL_get_ex_data(ssl, ssl_ex_index_server);
226 void *dont_verify_domain = SSL_CTX_get_ex_data(sslctx, ssl_ctx_ex_index_dont_verify_domain);
227 ACLChecklist *check = (ACLChecklist*)SSL_get_ex_data(ssl, ssl_ex_index_cert_error_check);
228 X509 *peeked_cert = (X509 *)SSL_get_ex_data(ssl, ssl_ex_index_ssl_peeked_cert);
229 X509 *peer_cert = ctx->cert;
230
231 X509_NAME_oneline(X509_get_subject_name(peer_cert), buffer,
232 sizeof(buffer));
233
234 // detect infinite loops
235 uint32_t *validationCounter = static_cast<uint32_t *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_validation_counter));
236 if (!validationCounter) {
237 validationCounter = new uint32_t(1);
238 SSL_set_ex_data(ssl, ssl_ex_index_ssl_validation_counter, validationCounter);
239 } else {
240 // overflows allowed if SQUID_CERT_VALIDATION_ITERATION_MAX >= UINT32_MAX
241 (*validationCounter)++;
242 }
243
244 if ((*validationCounter) >= SQUID_CERT_VALIDATION_ITERATION_MAX) {
245 ok = 0; // or the validation loop will never stop
246 error_no = SQUID_X509_V_ERR_INFINITE_VALIDATION;
247 debugs(83, 2, "SQUID_X509_V_ERR_INFINITE_VALIDATION: " <<
248 *validationCounter << " iterations while checking " << buffer);
249 }
250
251 if (ok) {
252 debugs(83, 5, "SSL Certificate signature OK: " << buffer);
253
254 // Check for domain mismatch only if the current certificate is the peer certificate.
255 if (!dont_verify_domain && server && peer_cert == X509_STORE_CTX_get_current_cert(ctx)) {
256 if (!Ssl::checkX509ServerValidity(peer_cert, server)) {
257 debugs(83, 2, "SQUID_X509_V_ERR_DOMAIN_MISMATCH: Certificate " << buffer << " does not match domainname " << server);
258 ok = 0;
259 error_no = SQUID_X509_V_ERR_DOMAIN_MISMATCH;
260 }
261 }
262 }
263
264 if (ok && peeked_cert) {
265 // Check whether the already peeked certificate matches the new one.
266 if (X509_cmp(peer_cert, peeked_cert) != 0) {
267 debugs(83, 2, "SQUID_X509_V_ERR_CERT_CHANGE: Certificate " << buffer << " does not match peeked certificate");
268 ok = 0;
269 error_no = SQUID_X509_V_ERR_CERT_CHANGE;
270 }
271 }
272
273 if (!ok) {
274 X509 *broken_cert = X509_STORE_CTX_get_current_cert(ctx);
275 if (!broken_cert)
276 broken_cert = peer_cert;
277
278 Ssl::CertErrors *errs = static_cast<Ssl::CertErrors *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_errors));
279 if (!errs) {
280 errs = new Ssl::CertErrors(Ssl::CertError(error_no, broken_cert));
281 if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_errors, (void *)errs)) {
282 debugs(83, 2, "Failed to set ssl error_no in ssl_verify_cb: Certificate " << buffer);
283 delete errs;
284 errs = NULL;
285 }
286 } else // remember another error number
287 errs->push_back_unique(Ssl::CertError(error_no, broken_cert));
288
289 if (const char *err_descr = Ssl::GetErrorDescr(error_no))
290 debugs(83, 5, err_descr << ": " << buffer);
291 else
292 debugs(83, DBG_IMPORTANT, "SSL unknown certificate error " << error_no << " in " << buffer);
293
294 // Check if the certificate error can be bypassed.
295 // Infinity validation loop errors can not bypassed.
296 if (error_no != SQUID_X509_V_ERR_INFINITE_VALIDATION) {
297 if (check) {
298 ACLFilledChecklist *filledCheck = Filled(check);
299 assert(!filledCheck->sslErrors);
300 filledCheck->sslErrors = new Ssl::CertErrors(Ssl::CertError(error_no, broken_cert));
301 filledCheck->serverCert.resetAndLock(peer_cert);
302 if (check->fastCheck() == ACCESS_ALLOWED) {
303 debugs(83, 3, "bypassing SSL error " << error_no << " in " << buffer);
304 ok = 1;
305 } else {
306 debugs(83, 5, "confirming SSL error " << error_no);
307 }
308 delete filledCheck->sslErrors;
309 filledCheck->sslErrors = NULL;
310 filledCheck->serverCert.reset(NULL);
311 }
312 // If the certificate validator is used then we need to allow all errors and
313 // pass them to certficate validator for more processing
314 else if (Ssl::TheConfig.ssl_crt_validator) {
315 ok = 1;
316 }
317 }
318 }
319
320 if (Ssl::TheConfig.ssl_crt_validator) {
321 // Check if we have stored certificates chain. Store if not.
322 if (!SSL_get_ex_data(ssl, ssl_ex_index_ssl_cert_chain)) {
323 STACK_OF(X509) *certStack = X509_STORE_CTX_get1_chain(ctx);
324 if (certStack && !SSL_set_ex_data(ssl, ssl_ex_index_ssl_cert_chain, certStack))
325 sk_X509_pop_free(certStack, X509_free);
326 }
327 }
328
329 if (!ok && !SSL_get_ex_data(ssl, ssl_ex_index_ssl_error_detail) ) {
330
331 // Find the broken certificate. It may be intermediate.
332 X509 *broken_cert = peer_cert; // reasonable default if search fails
333 // Our SQUID_X509_V_ERR_DOMAIN_MISMATCH implies peer_cert is at fault.
334 if (error_no != SQUID_X509_V_ERR_DOMAIN_MISMATCH) {
335 if (X509 *last_used_cert = X509_STORE_CTX_get_current_cert(ctx))
336 broken_cert = last_used_cert;
337 }
338
339 Ssl::ErrorDetail *errDetail =
340 new Ssl::ErrorDetail(error_no, peer_cert, broken_cert);
341
342 if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_error_detail, errDetail)) {
343 debugs(83, 2, "Failed to set Ssl::ErrorDetail in ssl_verify_cb: Certificate " << buffer);
344 delete errDetail;
345 }
346 }
347
348 return ok;
349 }
350
351 /// \ingroup ServerProtocolSSLInternal
352 static struct ssl_option {
353 const char *name;
354 long value;
355 }
356
357 ssl_options[] = {
358
359 #if SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
360 {
361 "NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
362 },
363 #endif
364 #if SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
365 {
366 "SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
367 },
368 #endif
369 #if SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
370 {
371 "MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
372 },
373 #endif
374 #if SSL_OP_SSLEAY_080_CLIENT_DH_BUG
375 {
376 "SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG
377 },
378 #endif
379 #if SSL_OP_TLS_D5_BUG
380 {
381 "TLS_D5_BUG", SSL_OP_TLS_D5_BUG
382 },
383 #endif
384 #if SSL_OP_TLS_BLOCK_PADDING_BUG
385 {
386 "TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG
387 },
388 #endif
389 #if SSL_OP_TLS_ROLLBACK_BUG
390 {
391 "TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG
392 },
393 #endif
394 #if SSL_OP_ALL
395 {
396 "ALL", (long)SSL_OP_ALL
397 },
398 #endif
399 #if SSL_OP_SINGLE_DH_USE
400 {
401 "SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE
402 },
403 #endif
404 #if SSL_OP_EPHEMERAL_RSA
405 {
406 "EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA
407 },
408 #endif
409 #if SSL_OP_PKCS1_CHECK_1
410 {
411 "PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1
412 },
413 #endif
414 #if SSL_OP_PKCS1_CHECK_2
415 {
416 "PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2
417 },
418 #endif
419 #if SSL_OP_NETSCAPE_CA_DN_BUG
420 {
421 "NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG
422 },
423 #endif
424 #if SSL_OP_NON_EXPORT_FIRST
425 {
426 "NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST
427 },
428 #endif
429 #if SSL_OP_CIPHER_SERVER_PREFERENCE
430 {
431 "CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE
432 },
433 #endif
434 #if SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
435 {
436 "NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
437 },
438 #endif
439 #if SSL_OP_NO_SSLv3
440 {
441 "NO_SSLv3", SSL_OP_NO_SSLv3
442 },
443 #endif
444 #if SSL_OP_NO_TLSv1
445 {
446 "NO_TLSv1", SSL_OP_NO_TLSv1
447 },
448 #endif
449 #if SSL_OP_NO_TLSv1_1
450 {
451 "NO_TLSv1_1", SSL_OP_NO_TLSv1_1
452 },
453 #endif
454 #if SSL_OP_NO_TLSv1_2
455 {
456 "NO_TLSv1_2", SSL_OP_NO_TLSv1_2
457 },
458 #endif
459 #if SSL_OP_NO_COMPRESSION
460 {
461 "No_Compression", SSL_OP_NO_COMPRESSION
462 },
463 #endif
464 #if SSL_OP_NO_TICKET
465 {
466 "NO_TICKET", SSL_OP_NO_TICKET
467 },
468 #endif
469 {
470 "", 0
471 },
472 {
473 NULL, 0
474 }
475 };
476
477 /// \ingroup ServerProtocolSSLInternal
478 long
479 Ssl::parse_options(const char *options)
480 {
481 long op = 0;
482 char *tmp;
483 char *option;
484
485 if (!options)
486 goto no_options;
487
488 tmp = xstrdup(options);
489
490 option = strtok(tmp, ":,");
491
492 while (option) {
493
494 struct ssl_option *opt = NULL, *opttmp;
495 long value = 0;
496 enum {
497 MODE_ADD, MODE_REMOVE
498 } mode;
499
500 switch (*option) {
501
502 case '!':
503
504 case '-':
505 mode = MODE_REMOVE;
506 ++option;
507 break;
508
509 case '+':
510 mode = MODE_ADD;
511 ++option;
512 break;
513
514 default:
515 mode = MODE_ADD;
516 break;
517 }
518
519 for (opttmp = ssl_options; opttmp->name; ++opttmp) {
520 if (strcmp(opttmp->name, option) == 0) {
521 opt = opttmp;
522 break;
523 }
524 }
525
526 if (opt)
527 value = opt->value;
528 else if (strncmp(option, "0x", 2) == 0) {
529 /* Special case.. hex specification */
530 value = strtol(option + 2, NULL, 16);
531 } else {
532 fatalf("Unknown SSL option '%s'", option);
533 value = 0; /* Keep GCC happy */
534 }
535
536 switch (mode) {
537
538 case MODE_ADD:
539 op |= value;
540 break;
541
542 case MODE_REMOVE:
543 op &= ~value;
544 break;
545 }
546
547 option = strtok(NULL, ":,");
548 }
549
550 safe_free(tmp);
551
552 no_options:
553 #if SSL_OP_NO_SSLv2
554 // compliance with RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0
555 op = op | SSL_OP_NO_SSLv2;
556 #endif
557 return op;
558 }
559
560 /// \ingroup ServerProtocolSSLInternal
561 #define SSL_FLAG_NO_DEFAULT_CA (1<<0)
562 /// \ingroup ServerProtocolSSLInternal
563 #define SSL_FLAG_DELAYED_AUTH (1<<1)
564 /// \ingroup ServerProtocolSSLInternal
565 #define SSL_FLAG_DONT_VERIFY_PEER (1<<2)
566 /// \ingroup ServerProtocolSSLInternal
567 #define SSL_FLAG_DONT_VERIFY_DOMAIN (1<<3)
568 /// \ingroup ServerProtocolSSLInternal
569 #define SSL_FLAG_NO_SESSION_REUSE (1<<4)
570 /// \ingroup ServerProtocolSSLInternal
571 #define SSL_FLAG_VERIFY_CRL (1<<5)
572 /// \ingroup ServerProtocolSSLInternal
573 #define SSL_FLAG_VERIFY_CRL_ALL (1<<6)
574
575 /// \ingroup ServerProtocolSSLInternal
576 long
577 Ssl::parse_flags(const char *flags)
578 {
579 long fl = 0;
580 char *tmp;
581 char *flag;
582
583 if (!flags)
584 return 0;
585
586 tmp = xstrdup(flags);
587
588 flag = strtok(tmp, ":,");
589
590 while (flag) {
591 if (strcmp(flag, "NO_DEFAULT_CA") == 0)
592 fl |= SSL_FLAG_NO_DEFAULT_CA;
593 else if (strcmp(flag, "DELAYED_AUTH") == 0)
594 fl |= SSL_FLAG_DELAYED_AUTH;
595 else if (strcmp(flag, "DONT_VERIFY_PEER") == 0)
596 fl |= SSL_FLAG_DONT_VERIFY_PEER;
597 else if (strcmp(flag, "DONT_VERIFY_DOMAIN") == 0)
598 fl |= SSL_FLAG_DONT_VERIFY_DOMAIN;
599 else if (strcmp(flag, "NO_SESSION_REUSE") == 0)
600 fl |= SSL_FLAG_NO_SESSION_REUSE;
601
602 #if X509_V_FLAG_CRL_CHECK
603
604 else if (strcmp(flag, "VERIFY_CRL") == 0)
605 fl |= SSL_FLAG_VERIFY_CRL;
606 else if (strcmp(flag, "VERIFY_CRL_ALL") == 0)
607 fl |= SSL_FLAG_VERIFY_CRL_ALL;
608
609 #endif
610
611 else
612 fatalf("Unknown ssl flag '%s'", flag);
613
614 flag = strtok(NULL, ":,");
615 }
616
617 safe_free(tmp);
618 return fl;
619 }
620
621 // "dup" function for SSL_get_ex_new_index("cert_err_check")
622 static int
623 ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *,
624 int, long, void *)
625 {
626 // We do not support duplication of ACLCheckLists.
627 // If duplication is needed, we can count copies with cbdata.
628 assert(false);
629 return 0;
630 }
631
632 // "free" function for SSL_get_ex_new_index("cert_err_check")
633 static void
634 ssl_freeAclChecklist(void *, void *ptr, CRYPTO_EX_DATA *,
635 int, long, void *)
636 {
637 delete static_cast<ACLChecklist *>(ptr); // may be NULL
638 }
639
640 // "free" function for SSL_get_ex_new_index("ssl_error_detail")
641 static void
642 ssl_free_ErrorDetail(void *, void *ptr, CRYPTO_EX_DATA *,
643 int, long, void *)
644 {
645 Ssl::ErrorDetail *errDetail = static_cast <Ssl::ErrorDetail *>(ptr);
646 delete errDetail;
647 }
648
649 static void
650 ssl_free_SslErrors(void *, void *ptr, CRYPTO_EX_DATA *,
651 int, long, void *)
652 {
653 Ssl::CertErrors *errs = static_cast <Ssl::CertErrors*>(ptr);
654 delete errs;
655 }
656
657 // "free" function for SSL_get_ex_new_index("ssl_ex_index_ssl_validation_counter")
658 static void
659 ssl_free_int(void *, void *ptr, CRYPTO_EX_DATA *,
660 int, long, void *)
661 {
662 uint32_t *counter = static_cast <uint32_t *>(ptr);
663 delete counter;
664 }
665
666 /// \ingroup ServerProtocolSSLInternal
667 /// Callback handler function to release STACK_OF(X509) "ex" data stored
668 /// in an SSL object.
669 static void
670 ssl_free_CertChain(void *, void *ptr, CRYPTO_EX_DATA *,
671 int, long, void *)
672 {
673 STACK_OF(X509) *certsChain = static_cast <STACK_OF(X509) *>(ptr);
674 sk_X509_pop_free(certsChain,X509_free);
675 }
676
677 // "free" function for X509 certificates
678 static void
679 ssl_free_X509(void *, void *ptr, CRYPTO_EX_DATA *,
680 int, long, void *)
681 {
682 X509 *cert = static_cast <X509 *>(ptr);
683 X509_free(cert);
684 }
685
686 /// \ingroup ServerProtocolSSLInternal
687 static void
688 ssl_initialize(void)
689 {
690 static bool initialized = false;
691 if (initialized)
692 return;
693 initialized = true;
694
695 SSL_load_error_strings();
696 SSLeay_add_ssl_algorithms();
697
698 #if HAVE_OPENSSL_ENGINE_H
699 if (Config.SSL.ssl_engine) {
700 ENGINE *e;
701 if (!(e = ENGINE_by_id(Config.SSL.ssl_engine)))
702 fatalf("Unable to find SSL engine '%s'\n", Config.SSL.ssl_engine);
703
704 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
705 int ssl_error = ERR_get_error();
706 fatalf("Failed to initialise SSL engine: %s\n", ERR_error_string(ssl_error, NULL));
707 }
708 }
709 #else
710 if (Config.SSL.ssl_engine)
711 fatalf("Your OpenSSL has no SSL engine support\n");
712 #endif
713
714 const char *defName = Config.SSL.certSignHash ? Config.SSL.certSignHash : SQUID_SSL_SIGN_HASH_IF_NONE;
715 Ssl::DefaultSignHash = EVP_get_digestbyname(defName);
716 if (!Ssl::DefaultSignHash)
717 fatalf("Sign hash '%s' is not supported\n", defName);
718
719 ssl_ex_index_server = SSL_get_ex_new_index(0, (void *) "server", NULL, NULL, NULL);
720 ssl_ctx_ex_index_dont_verify_domain = SSL_CTX_get_ex_new_index(0, (void *) "dont_verify_domain", NULL, NULL, NULL);
721 ssl_ex_index_cert_error_check = SSL_get_ex_new_index(0, (void *) "cert_error_check", NULL, &ssl_dupAclChecklist, &ssl_freeAclChecklist);
722 ssl_ex_index_ssl_error_detail = SSL_get_ex_new_index(0, (void *) "ssl_error_detail", NULL, NULL, &ssl_free_ErrorDetail);
723 ssl_ex_index_ssl_peeked_cert = SSL_get_ex_new_index(0, (void *) "ssl_peeked_cert", NULL, NULL, &ssl_free_X509);
724 ssl_ex_index_ssl_errors = SSL_get_ex_new_index(0, (void *) "ssl_errors", NULL, NULL, &ssl_free_SslErrors);
725 ssl_ex_index_ssl_cert_chain = SSL_get_ex_new_index(0, (void *) "ssl_cert_chain", NULL, NULL, &ssl_free_CertChain);
726 ssl_ex_index_ssl_validation_counter = SSL_get_ex_new_index(0, (void *) "ssl_validation_counter", NULL, NULL, &ssl_free_int);
727 }
728
729 /// \ingroup ServerProtocolSSLInternal
730 static int
731 ssl_load_crl(SSL_CTX *sslContext, const char *CRLfile)
732 {
733 X509_STORE *st = SSL_CTX_get_cert_store(sslContext);
734 X509_CRL *crl;
735 BIO *in = BIO_new_file(CRLfile, "r");
736 int count = 0;
737
738 if (!in) {
739 debugs(83, 2, "WARNING: Failed to open CRL file '" << CRLfile << "'");
740 return 0;
741 }
742
743 while ((crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL))) {
744 if (!X509_STORE_add_crl(st, crl))
745 debugs(83, 2, "WARNING: Failed to add CRL from file '" << CRLfile << "'");
746 else
747 ++count;
748
749 X509_CRL_free(crl);
750 }
751
752 BIO_free(in);
753 return count;
754 }
755
756 STACK_OF(X509_CRL) *
757 Ssl::loadCrl(const char *CRLFile, long &flags)
758 {
759 X509_CRL *crl;
760 BIO *in = BIO_new_file(CRLFile, "r");
761 if (!in) {
762 debugs(83, 2, "WARNING: Failed to open CRL file '" << CRLFile << "'");
763 return NULL;
764 }
765
766 STACK_OF(X509_CRL) *CRLs = sk_X509_CRL_new_null();
767 if (!CRLs) {
768 debugs(83, 2, "WARNING: Failed to allocate X509_CRL stack to load file '" << CRLFile << "'");
769 return NULL;
770 }
771
772 int count = 0;
773 while ((crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL))) {
774 if (!sk_X509_CRL_push(CRLs, crl))
775 debugs(83, 2, "WARNING: Failed to add CRL from file '" << CRLFile << "'");
776 else
777 ++count;
778 }
779 BIO_free(in);
780
781 if (count)
782 flags |= SSL_FLAG_VERIFY_CRL;
783
784 return CRLs;
785 }
786
787 DH *
788 Ssl::readDHParams(const char *dhfile)
789 {
790 FILE *in = fopen(dhfile, "r");
791 DH *dh = NULL;
792 int codes;
793
794 if (in) {
795 dh = PEM_read_DHparams(in, NULL, NULL, NULL);
796 fclose(in);
797 }
798
799 if (!dh)
800 debugs(83, DBG_IMPORTANT, "WARNING: Failed to read DH parameters '" << dhfile << "'");
801 else if (dh && DH_check(dh, &codes) == 0) {
802 if (codes) {
803 debugs(83, DBG_IMPORTANT, "WARNING: Failed to verify DH parameters '" << dhfile << "' (" << std::hex << codes << ")");
804 DH_free(dh);
805 dh = NULL;
806 }
807 }
808 return dh;
809 }
810
811 static bool
812 configureSslContext(SSL_CTX *sslContext, AnyP::PortCfg &port)
813 {
814 int ssl_error;
815 SSL_CTX_set_options(sslContext, port.sslOptions);
816
817 if (port.sslContextSessionId)
818 SSL_CTX_set_session_id_context(sslContext, (const unsigned char *)port.sslContextSessionId, strlen(port.sslContextSessionId));
819
820 if (port.sslContextFlags & SSL_FLAG_NO_SESSION_REUSE) {
821 SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF);
822 }
823
824 if (Config.SSL.unclean_shutdown) {
825 debugs(83, 5, "Enabling quiet SSL shutdowns (RFC violation).");
826
827 SSL_CTX_set_quiet_shutdown(sslContext, 1);
828 }
829
830 if (port.cipher) {
831 debugs(83, 5, "Using chiper suite " << port.cipher << ".");
832
833 if (!SSL_CTX_set_cipher_list(sslContext, port.cipher)) {
834 ssl_error = ERR_get_error();
835 debugs(83, DBG_CRITICAL, "ERROR: Failed to set SSL cipher suite '" << port.cipher << "': " << ERR_error_string(ssl_error, NULL));
836 return false;
837 }
838 }
839
840 debugs(83, 9, "Setting RSA key generation callback.");
841 SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb);
842
843 debugs(83, 9, "Setting CA certificate locations.");
844
845 const char *cafile = port.cafile ? port.cafile : port.clientca;
846 if ((cafile || port.capath) && !SSL_CTX_load_verify_locations(sslContext, cafile, port.capath)) {
847 ssl_error = ERR_get_error();
848 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate locations: " << ERR_error_string(ssl_error, NULL));
849 }
850
851 if (!(port.sslContextFlags & SSL_FLAG_NO_DEFAULT_CA) &&
852 !SSL_CTX_set_default_verify_paths(sslContext)) {
853 ssl_error = ERR_get_error();
854 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default CA certificate location: " << ERR_error_string(ssl_error, NULL));
855 }
856
857 if (port.clientCA.get()) {
858 ERR_clear_error();
859 SSL_CTX_set_client_CA_list(sslContext, port.clientCA.get());
860
861 if (port.sslContextFlags & SSL_FLAG_DELAYED_AUTH) {
862 debugs(83, 9, "Not requesting client certificates until acl processing requires one");
863 SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
864 } else {
865 debugs(83, 9, "Requiring client certificates.");
866 SSL_CTX_set_verify(sslContext, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
867 }
868
869 if (port.clientVerifyCrls.get()) {
870 X509_STORE *st = SSL_CTX_get_cert_store(sslContext);
871 for (int i = 0; i < sk_X509_CRL_num(port.clientVerifyCrls.get()); ++i) {
872 X509_CRL *crl = sk_X509_CRL_value(port.clientVerifyCrls.get(), i);
873 if (!X509_STORE_add_crl(st, crl))
874 debugs(83, 2, "WARNING: Failed to add CRL");
875 }
876 }
877
878 #if X509_V_FLAG_CRL_CHECK
879 if (port.sslContextFlags & SSL_FLAG_VERIFY_CRL_ALL)
880 X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
881 else if (port.sslContextFlags & SSL_FLAG_VERIFY_CRL)
882 X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK);
883 #endif
884
885 } else {
886 debugs(83, 9, "Not requiring any client certificates");
887 SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
888 }
889
890 if (port.dhParams.get()) {
891 SSL_CTX_set_tmp_dh(sslContext, port.dhParams.get());
892 }
893
894 if (port.sslContextFlags & SSL_FLAG_DONT_VERIFY_DOMAIN)
895 SSL_CTX_set_ex_data(sslContext, ssl_ctx_ex_index_dont_verify_domain, (void *) -1);
896
897 setSessionCallbacks(sslContext);
898
899 return true;
900 }
901
902 SSL_CTX *
903 sslCreateServerContext(AnyP::PortCfg &port)
904 {
905 int ssl_error;
906 SSL_CTX *sslContext;
907 const char *keyfile, *certfile;
908 certfile = port.cert;
909 keyfile = port.key;
910
911 ssl_initialize();
912
913 if (!keyfile)
914 keyfile = certfile;
915
916 if (!certfile)
917 certfile = keyfile;
918
919 sslContext = SSL_CTX_new(port.contextMethod);
920
921 if (sslContext == NULL) {
922 ssl_error = ERR_get_error();
923 debugs(83, DBG_CRITICAL, "ERROR: Failed to allocate SSL context: " << ERR_error_string(ssl_error, NULL));
924 return NULL;
925 }
926
927 if (!SSL_CTX_use_certificate(sslContext, port.signingCert.get())) {
928 ssl_error = ERR_get_error();
929 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL certificate '" << certfile << "': " << ERR_error_string(ssl_error, NULL));
930 SSL_CTX_free(sslContext);
931 return NULL;
932 }
933
934 if (!SSL_CTX_use_PrivateKey(sslContext, port.signPkey.get())) {
935 ssl_error = ERR_get_error();
936 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL private key '" << keyfile << "': " << ERR_error_string(ssl_error, NULL));
937 SSL_CTX_free(sslContext);
938 return NULL;
939 }
940
941 Ssl::addChainToSslContext(sslContext, port.certsToChain.get());
942
943 /* Alternate code;
944 debugs(83, DBG_IMPORTANT, "Using certificate in " << certfile);
945
946 if (!SSL_CTX_use_certificate_chain_file(sslContext, certfile)) {
947 ssl_error = ERR_get_error();
948 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL certificate '" << certfile << "': " << ERR_error_string(ssl_error, NULL));
949 SSL_CTX_free(sslContext);
950 return NULL;
951 }
952
953 debugs(83, DBG_IMPORTANT, "Using private key in " << keyfile);
954 ssl_ask_password(sslContext, keyfile);
955
956 if (!SSL_CTX_use_PrivateKey_file(sslContext, keyfile, SSL_FILETYPE_PEM)) {
957 ssl_error = ERR_get_error();
958 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL private key '" << keyfile << "': " << ERR_error_string(ssl_error, NULL));
959 SSL_CTX_free(sslContext);
960 return NULL;
961 }
962
963 debugs(83, 5, "Comparing private and public SSL keys.");
964
965 if (!SSL_CTX_check_private_key(sslContext)) {
966 ssl_error = ERR_get_error();
967 debugs(83, DBG_CRITICAL, "ERROR: SSL private key '" << certfile << "' does not match public key '" <<
968 keyfile << "': " << ERR_error_string(ssl_error, NULL));
969 SSL_CTX_free(sslContext);
970 return NULL;
971 }
972 */
973
974 if (!configureSslContext(sslContext, port)) {
975 debugs(83, DBG_CRITICAL, "ERROR: Configuring static SSL context");
976 SSL_CTX_free(sslContext);
977 return NULL;
978 }
979
980 return sslContext;
981 }
982
983 int Ssl::OpenSSLtoSquidSSLVersion(int sslVersion)
984 {
985 if (sslVersion == SSL2_VERSION)
986 return 2;
987 else if (sslVersion == SSL3_VERSION)
988 return 3;
989 else if (sslVersion == TLS1_VERSION)
990 return 4;
991 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
992 else if (sslVersion == TLS1_1_VERSION)
993 return 5;
994 else if (sslVersion == TLS1_2_VERSION)
995 return 6;
996 #endif
997 else
998 return 1;
999 }
1000
1001 #if OPENSSL_VERSION_NUMBER < 0x00909000L
1002 SSL_METHOD *
1003 #else
1004 const SSL_METHOD *
1005 #endif
1006 Ssl::method(int version)
1007 {
1008 switch (version) {
1009
1010 case 2:
1011 debugs(83, DBG_IMPORTANT, "SSLv2 is not available in this Proxy.");
1012 return NULL;
1013 break;
1014
1015 case 3:
1016 debugs(83, 5, "Using SSLv3.");
1017 return SSLv3_client_method();
1018 break;
1019
1020 case 4:
1021 debugs(83, 5, "Using TLSv1.");
1022 return TLSv1_client_method();
1023 break;
1024
1025 case 5:
1026 #if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
1027 debugs(83, 5, "Using TLSv1.1.");
1028 return TLSv1_1_client_method();
1029 #else
1030 debugs(83, DBG_IMPORTANT, "TLSv1.1 is not available in this Proxy.");
1031 return NULL;
1032 #endif
1033 break;
1034
1035 case 6:
1036 #if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
1037 debugs(83, 5, "Using TLSv1.2");
1038 return TLSv1_2_client_method();
1039 #else
1040 debugs(83, DBG_IMPORTANT, "TLSv1.2 is not available in this Proxy.");
1041 return NULL;
1042 #endif
1043 break;
1044
1045 case 1:
1046
1047 default:
1048 debugs(83, 5, "Using SSLv2/SSLv3.");
1049 return SSLv23_client_method();
1050 break;
1051 }
1052
1053 //Not reached
1054 return NULL;
1055 }
1056
1057 const SSL_METHOD *
1058 Ssl::serverMethod(int version)
1059 {
1060 switch (version) {
1061
1062 case 2:
1063 debugs(83, DBG_IMPORTANT, "SSLv2 is not available in this Proxy.");
1064 return NULL;
1065 break;
1066
1067 case 3:
1068 debugs(83, 5, "Using SSLv3.");
1069 return SSLv3_server_method();
1070 break;
1071
1072 case 4:
1073 debugs(83, 5, "Using TLSv1.");
1074 return TLSv1_server_method();
1075 break;
1076
1077 case 5:
1078 #if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
1079 debugs(83, 5, "Using TLSv1.1.");
1080 return TLSv1_1_server_method();
1081 #else
1082 debugs(83, DBG_IMPORTANT, "TLSv1.1 is not available in this Proxy.");
1083 return NULL;
1084 #endif
1085 break;
1086
1087 case 6:
1088 #if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
1089 debugs(83, 5, "Using TLSv1.2");
1090 return TLSv1_2_server_method();
1091 #else
1092 debugs(83, DBG_IMPORTANT, "TLSv1.2 is not available in this Proxy.");
1093 return NULL;
1094 #endif
1095 break;
1096
1097 case 1:
1098
1099 default:
1100 debugs(83, 5, "Using SSLv2/SSLv3.");
1101 return SSLv23_server_method();
1102 break;
1103 }
1104
1105 //Not reached
1106 return NULL;
1107 }
1108
1109 SSL_CTX *
1110 sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile)
1111 {
1112 int ssl_error;
1113 Ssl::ContextMethod method;
1114 SSL_CTX * sslContext;
1115 long fl = Ssl::parse_flags(flags);
1116
1117 ssl_initialize();
1118
1119 if (!(method = Ssl::method(version)))
1120 return NULL;
1121
1122 sslContext = SSL_CTX_new(method);
1123
1124 if (sslContext == NULL) {
1125 ssl_error = ERR_get_error();
1126 fatalf("Failed to allocate SSL context: %s\n",
1127 ERR_error_string(ssl_error, NULL));
1128 }
1129
1130 SSL_CTX_set_options(sslContext, Ssl::parse_options(options));
1131
1132 if (*cipher) {
1133 debugs(83, 5, "Using chiper suite " << cipher << ".");
1134
1135 if (!SSL_CTX_set_cipher_list(sslContext, cipher)) {
1136 ssl_error = ERR_get_error();
1137 fatalf("Failed to set SSL cipher suite '%s': %s\n",
1138 cipher, ERR_error_string(ssl_error, NULL));
1139 }
1140 }
1141
1142 if (*certfile) {
1143 debugs(83, DBG_IMPORTANT, "Using certificate in " << certfile);
1144
1145 if (!SSL_CTX_use_certificate_chain_file(sslContext, certfile)) {
1146 ssl_error = ERR_get_error();
1147 fatalf("Failed to acquire SSL certificate '%s': %s\n",
1148 certfile, ERR_error_string(ssl_error, NULL));
1149 }
1150
1151 debugs(83, DBG_IMPORTANT, "Using private key in " << keyfile);
1152 ssl_ask_password(sslContext, keyfile);
1153
1154 if (!SSL_CTX_use_PrivateKey_file(sslContext, keyfile, SSL_FILETYPE_PEM)) {
1155 ssl_error = ERR_get_error();
1156 fatalf("Failed to acquire SSL private key '%s': %s\n",
1157 keyfile, ERR_error_string(ssl_error, NULL));
1158 }
1159
1160 debugs(83, 5, "Comparing private and public SSL keys.");
1161
1162 if (!SSL_CTX_check_private_key(sslContext)) {
1163 ssl_error = ERR_get_error();
1164 fatalf("SSL private key '%s' does not match public key '%s': %s\n",
1165 certfile, keyfile, ERR_error_string(ssl_error, NULL));
1166 }
1167 }
1168
1169 debugs(83, 9, "Setting RSA key generation callback.");
1170 SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb);
1171
1172 if (fl & SSL_FLAG_DONT_VERIFY_PEER) {
1173 debugs(83, 2, "NOTICE: Peer certificates are not verified for validity!");
1174 SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
1175 } else {
1176 debugs(83, 9, "Setting certificate verification callback.");
1177 SSL_CTX_set_verify(sslContext, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
1178 }
1179
1180 debugs(83, 9, "Setting CA certificate locations.");
1181
1182 if ((*CAfile || *CApath) && !SSL_CTX_load_verify_locations(sslContext, CAfile, CApath)) {
1183 ssl_error = ERR_get_error();
1184 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate locations: " << ERR_error_string(ssl_error, NULL));
1185 }
1186
1187 if (*CRLfile) {
1188 ssl_load_crl(sslContext, CRLfile);
1189 fl |= SSL_FLAG_VERIFY_CRL;
1190 }
1191
1192 #if X509_V_FLAG_CRL_CHECK
1193 if (fl & SSL_FLAG_VERIFY_CRL_ALL)
1194 X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1195 else if (fl & SSL_FLAG_VERIFY_CRL)
1196 X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK);
1197
1198 #endif
1199
1200 if (!(fl & SSL_FLAG_NO_DEFAULT_CA) &&
1201 !SSL_CTX_set_default_verify_paths(sslContext)) {
1202 ssl_error = ERR_get_error();
1203 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default CA certificate location: " << ERR_error_string(ssl_error, NULL));
1204 }
1205
1206 return sslContext;
1207 }
1208
1209 /// \ingroup ServerProtocolSSLInternal
1210 int
1211 ssl_read_method(int fd, char *buf, int len)
1212 {
1213 SSL *ssl = fd_table[fd].ssl;
1214 int i;
1215
1216 #if DONT_DO_THIS
1217
1218 if (!SSL_is_init_finished(ssl)) {
1219 errno = ENOTCONN;
1220 return -1;
1221 }
1222
1223 #endif
1224
1225 i = SSL_read(ssl, buf, len);
1226
1227 if (i > 0 && SSL_pending(ssl) > 0) {
1228 debugs(83, 2, "SSL FD " << fd << " is pending");
1229 fd_table[fd].flags.read_pending = true;
1230 } else
1231 fd_table[fd].flags.read_pending = false;
1232
1233 return i;
1234 }
1235
1236 /// \ingroup ServerProtocolSSLInternal
1237 int
1238 ssl_write_method(int fd, const char *buf, int len)
1239 {
1240 SSL *ssl = fd_table[fd].ssl;
1241 int i;
1242
1243 if (!SSL_is_init_finished(ssl)) {
1244 errno = ENOTCONN;
1245 return -1;
1246 }
1247
1248 i = SSL_write(ssl, buf, len);
1249
1250 return i;
1251 }
1252
1253 void
1254 ssl_shutdown_method(SSL *ssl)
1255 {
1256 SSL_shutdown(ssl);
1257 }
1258
1259 /// \ingroup ServerProtocolSSLInternal
1260 static const char *
1261 ssl_get_attribute(X509_NAME * name, const char *attribute_name)
1262 {
1263 static char buffer[1024];
1264 int nid;
1265
1266 buffer[0] = '\0';
1267
1268 if (strcmp(attribute_name, "DN") == 0) {
1269 X509_NAME_oneline(name, buffer, sizeof(buffer));
1270 goto done;
1271 }
1272
1273 nid = OBJ_txt2nid((char *) attribute_name);
1274
1275 if (nid == 0) {
1276 debugs(83, DBG_IMPORTANT, "WARNING: Unknown SSL attribute name '" << attribute_name << "'");
1277 return NULL;
1278 }
1279
1280 X509_NAME_get_text_by_NID(name, nid, buffer, sizeof(buffer));
1281
1282 done:
1283 return *buffer ? buffer : NULL;
1284 }
1285
1286 /// \ingroup ServerProtocolSSLInternal
1287 const char *
1288 Ssl::GetX509UserAttribute(X509 * cert, const char *attribute_name)
1289 {
1290 X509_NAME *name;
1291 const char *ret;
1292
1293 if (!cert)
1294 return NULL;
1295
1296 name = X509_get_subject_name(cert);
1297
1298 ret = ssl_get_attribute(name, attribute_name);
1299
1300 return ret;
1301 }
1302
1303 const char *
1304 Ssl::GetX509Fingerprint(X509 * cert, const char *)
1305 {
1306 static char buf[1024];
1307 if (!cert)
1308 return NULL;
1309
1310 unsigned int n;
1311 unsigned char md[EVP_MAX_MD_SIZE];
1312 if (!X509_digest(cert, EVP_sha1(), md, &n))
1313 return NULL;
1314
1315 assert(3 * n + 1 < sizeof(buf));
1316
1317 char *s = buf;
1318 for (unsigned int i=0; i < n; ++i, s += 3) {
1319 const char term = (i + 1 < n) ? ':' : '\0';
1320 snprintf(s, 4, "%02X%c", md[i], term);
1321 }
1322
1323 return buf;
1324 }
1325
1326 /// \ingroup ServerProtocolSSLInternal
1327 const char *
1328 Ssl::GetX509CAAttribute(X509 * cert, const char *attribute_name)
1329 {
1330
1331 X509_NAME *name;
1332 const char *ret;
1333
1334 if (!cert)
1335 return NULL;
1336
1337 name = X509_get_issuer_name(cert);
1338
1339 ret = ssl_get_attribute(name, attribute_name);
1340
1341 return ret;
1342 }
1343
1344 const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name)
1345 {
1346 if (!ssl)
1347 return NULL;
1348
1349 X509 *cert = SSL_get_peer_certificate(ssl);
1350
1351 const char *attr = Ssl::GetX509UserAttribute(cert, attribute_name);
1352
1353 X509_free(cert);
1354 return attr;
1355 }
1356
1357 const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name)
1358 {
1359 if (!ssl)
1360 return NULL;
1361
1362 X509 *cert = SSL_get_peer_certificate(ssl);
1363
1364 const char *attr = Ssl::GetX509CAAttribute(cert, attribute_name);
1365
1366 X509_free(cert);
1367 return attr;
1368 }
1369
1370 const char *
1371 sslGetUserEmail(SSL * ssl)
1372 {
1373 return sslGetUserAttribute(ssl, "emailAddress");
1374 }
1375
1376 const char *
1377 sslGetUserCertificatePEM(SSL *ssl)
1378 {
1379 X509 *cert;
1380 BIO *mem;
1381 static char *str = NULL;
1382 char *ptr;
1383 long len;
1384
1385 safe_free(str);
1386
1387 if (!ssl)
1388 return NULL;
1389
1390 cert = SSL_get_peer_certificate(ssl);
1391
1392 if (!cert)
1393 return NULL;
1394
1395 mem = BIO_new(BIO_s_mem());
1396
1397 PEM_write_bio_X509(mem, cert);
1398
1399 len = BIO_get_mem_data(mem, &ptr);
1400
1401 str = (char *)xmalloc(len + 1);
1402
1403 memcpy(str, ptr, len);
1404
1405 str[len] = '\0';
1406
1407 X509_free(cert);
1408
1409 BIO_free(mem);
1410
1411 return str;
1412 }
1413
1414 const char *
1415 sslGetUserCertificateChainPEM(SSL *ssl)
1416 {
1417 STACK_OF(X509) *chain;
1418 BIO *mem;
1419 static char *str = NULL;
1420 char *ptr;
1421 long len;
1422 int i;
1423
1424 safe_free(str);
1425
1426 if (!ssl)
1427 return NULL;
1428
1429 chain = SSL_get_peer_cert_chain(ssl);
1430
1431 if (!chain)
1432 return sslGetUserCertificatePEM(ssl);
1433
1434 mem = BIO_new(BIO_s_mem());
1435
1436 for (i = 0; i < sk_X509_num(chain); ++i) {
1437 X509 *cert = sk_X509_value(chain, i);
1438 PEM_write_bio_X509(mem, cert);
1439 }
1440
1441 len = BIO_get_mem_data(mem, &ptr);
1442
1443 str = (char *)xmalloc(len + 1);
1444 memcpy(str, ptr, len);
1445 str[len] = '\0';
1446
1447 BIO_free(mem);
1448
1449 return str;
1450 }
1451
1452 Ssl::ContextMethod
1453 Ssl::contextMethod(int version)
1454 {
1455 Ssl::ContextMethod method;
1456
1457 switch (version) {
1458
1459 case 2:
1460 debugs(83, DBG_IMPORTANT, "SSLv2 is not available in this Proxy.");
1461 return NULL;
1462 break;
1463
1464 case 3:
1465 debugs(83, 5, "Using SSLv3.");
1466 method = SSLv3_server_method();
1467 break;
1468
1469 case 4:
1470 debugs(83, 5, "Using TLSv1.");
1471 method = TLSv1_server_method();
1472 break;
1473
1474 case 5:
1475 #if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
1476 debugs(83, 5, "Using TLSv1.1.");
1477 method = TLSv1_1_server_method();
1478 #else
1479 debugs(83, DBG_IMPORTANT, "TLSv1.1 is not available in this Proxy.");
1480 return NULL;
1481 #endif
1482 break;
1483
1484 case 6:
1485 #if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
1486 debugs(83, 5, "Using TLSv1.2");
1487 method = TLSv1_2_server_method();
1488 #else
1489 debugs(83, DBG_IMPORTANT, "TLSv1.2 is not available in this Proxy.");
1490 return NULL;
1491 #endif
1492 break;
1493
1494 case 1:
1495
1496 default:
1497 debugs(83, 5, "Using SSLv2/SSLv3.");
1498 method = SSLv23_server_method();
1499 break;
1500 }
1501 return method;
1502 }
1503
1504 /// \ingroup ServerProtocolSSLInternal
1505 /// Create SSL context and apply ssl certificate and private key to it.
1506 SSL_CTX *
1507 Ssl::createSSLContext(Ssl::X509_Pointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port)
1508 {
1509 Ssl::SSL_CTX_Pointer sslContext(SSL_CTX_new(port.contextMethod));
1510
1511 if (!SSL_CTX_use_certificate(sslContext.get(), x509.get()))
1512 return NULL;
1513
1514 if (!SSL_CTX_use_PrivateKey(sslContext.get(), pkey.get()))
1515 return NULL;
1516
1517 if (!configureSslContext(sslContext.get(), port))
1518 return NULL;
1519
1520 return sslContext.release();
1521 }
1522
1523 SSL_CTX *
1524 Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortCfg &port)
1525 {
1526 Ssl::X509_Pointer cert;
1527 Ssl::EVP_PKEY_Pointer pkey;
1528 if (!readCertAndPrivateKeyFromMemory(cert, pkey, data))
1529 return NULL;
1530
1531 if (!cert || !pkey)
1532 return NULL;
1533
1534 return createSSLContext(cert, pkey, port);
1535 }
1536
1537 SSL_CTX *
1538 Ssl::generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &port)
1539 {
1540 Ssl::X509_Pointer cert;
1541 Ssl::EVP_PKEY_Pointer pkey;
1542 if (!generateSslCertificate(cert, pkey, properties))
1543 return NULL;
1544
1545 if (!cert)
1546 return NULL;
1547
1548 if (!pkey)
1549 return NULL;
1550
1551 return createSSLContext(cert, pkey, port);
1552 }
1553
1554 bool
1555 Ssl::configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port)
1556 {
1557 Ssl::X509_Pointer cert;
1558 Ssl::EVP_PKEY_Pointer pkey;
1559 if (!generateSslCertificate(cert, pkey, properties))
1560 return false;
1561
1562 if (!cert)
1563 return false;
1564
1565 if (!pkey)
1566 return false;
1567
1568 if (!SSL_use_certificate(ssl, cert.get()))
1569 return false;
1570
1571 if (!SSL_use_PrivateKey(ssl, pkey.get()))
1572 return false;
1573
1574 return true;
1575 }
1576
1577 bool
1578 Ssl::configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port)
1579 {
1580 Ssl::X509_Pointer cert;
1581 Ssl::EVP_PKEY_Pointer pkey;
1582 if (!readCertAndPrivateKeyFromMemory(cert, pkey, data))
1583 return false;
1584
1585 if (!cert || !pkey)
1586 return false;
1587
1588 if (!SSL_use_certificate(ssl, cert.get()))
1589 return false;
1590
1591 if (!SSL_use_PrivateKey(ssl, pkey.get()))
1592 return false;
1593
1594 return true;
1595 }
1596
1597 bool Ssl::verifySslCertificate(SSL_CTX * sslContext, CertificateProperties const &properties)
1598 {
1599 // SSL_get_certificate is buggy in openssl versions 1.0.1d and 1.0.1e
1600 // Try to retrieve certificate directly from SSL_CTX object
1601 #if SQUID_USE_SSLGETCERTIFICATE_HACK
1602 X509 ***pCert = (X509 ***)sslContext->cert;
1603 X509 * cert = pCert && *pCert ? **pCert : NULL;
1604 #elif SQUID_SSLGETCERTIFICATE_BUGGY
1605 X509 * cert = NULL;
1606 assert(0);
1607 #else
1608 // Temporary ssl for getting X509 certificate from SSL_CTX.
1609 Ssl::SSL_Pointer ssl(SSL_new(sslContext));
1610 X509 * cert = SSL_get_certificate(ssl.get());
1611 #endif
1612 if (!cert)
1613 return false;
1614 ASN1_TIME * time_notBefore = X509_get_notBefore(cert);
1615 ASN1_TIME * time_notAfter = X509_get_notAfter(cert);
1616 bool ret = (X509_cmp_current_time(time_notBefore) < 0 && X509_cmp_current_time(time_notAfter) > 0);
1617 if (!ret)
1618 return false;
1619
1620 return certificateMatchesProperties(cert, properties);
1621 }
1622
1623 bool
1624 Ssl::setClientSNI(SSL *ssl, const char *fqdn)
1625 {
1626 //The SSL_CTRL_SET_TLSEXT_HOSTNAME is a openssl macro which indicates
1627 // if the TLS servername extension (SNI) is enabled in openssl library.
1628 #if defined(SSL_CTRL_SET_TLSEXT_HOSTNAME)
1629 if (!SSL_set_tlsext_host_name(ssl, fqdn)) {
1630 const int ssl_error = ERR_get_error();
1631 debugs(83, 3, "WARNING: unable to set TLS servername extension (SNI): " <<
1632 ERR_error_string(ssl_error, NULL) << "\n");
1633 return false;
1634 }
1635 return true;
1636 #else
1637 debugs(83, 7, "no support for TLS servername extension (SNI)\n");
1638 return false;
1639 #endif
1640 }
1641
1642 void Ssl::addChainToSslContext(SSL_CTX *sslContext, STACK_OF(X509) *chain)
1643 {
1644 if (!chain)
1645 return;
1646
1647 for (int i = 0; i < sk_X509_num(chain); ++i) {
1648 X509 *cert = sk_X509_value(chain, i);
1649 if (SSL_CTX_add_extra_chain_cert(sslContext, cert)) {
1650 // increase the certificate lock
1651 CRYPTO_add(&(cert->references),1,CRYPTO_LOCK_X509);
1652 } else {
1653 const int ssl_error = ERR_get_error();
1654 debugs(83, DBG_IMPORTANT, "WARNING: can not add certificate to SSL context chain: " << ERR_error_string(ssl_error, NULL));
1655 }
1656 }
1657 }
1658
1659 /**
1660 \ingroup ServerProtocolSSLInternal
1661 * Read certificate from file.
1662 * See also: static readSslX509Certificate function, gadgets.cc file
1663 */
1664 static X509 * readSslX509CertificatesChain(char const * certFilename, STACK_OF(X509)* chain)
1665 {
1666 if (!certFilename)
1667 return NULL;
1668 Ssl::BIO_Pointer bio(BIO_new(BIO_s_file_internal()));
1669 if (!bio)
1670 return NULL;
1671 if (!BIO_read_filename(bio.get(), certFilename))
1672 return NULL;
1673 X509 *certificate = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL);
1674
1675 if (certificate && chain) {
1676
1677 if (X509_check_issued(certificate, certificate) == X509_V_OK)
1678 debugs(83, 5, "Certificate is self-signed, will not be chained");
1679 else {
1680 // and add to the chain any other certificate exist in the file
1681 while (X509 *ca = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL)) {
1682 if (!sk_X509_push(chain, ca))
1683 debugs(83, DBG_IMPORTANT, "WARNING: unable to add CA certificate to cert chain");
1684 }
1685 }
1686 }
1687
1688 return certificate;
1689 }
1690
1691 void Ssl::readCertChainAndPrivateKeyFromFiles(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename)
1692 {
1693 if (keyFilename == NULL)
1694 keyFilename = certFilename;
1695
1696 if (certFilename == NULL)
1697 certFilename = keyFilename;
1698
1699 debugs(83, DBG_IMPORTANT, "Using certificate in " << certFilename);
1700
1701 if (!chain)
1702 chain.reset(sk_X509_new_null());
1703 if (!chain)
1704 debugs(83, DBG_IMPORTANT, "WARNING: unable to allocate memory for cert chain");
1705 // XXX: ssl_ask_password_cb needs SSL_CTX_set_default_passwd_cb_userdata()
1706 // so this may not fully work iff Config.Program.ssl_password is set.
1707 pem_password_cb *cb = ::Config.Program.ssl_password ? &ssl_ask_password_cb : NULL;
1708 pkey.reset(readSslPrivateKey(keyFilename, cb));
1709 cert.reset(readSslX509CertificatesChain(certFilename, chain.get()));
1710 if (!pkey || !cert || !X509_check_private_key(cert.get(), pkey.get())) {
1711 pkey.reset(NULL);
1712 cert.reset(NULL);
1713 }
1714 }
1715
1716 bool Ssl::generateUntrustedCert(X509_Pointer &untrustedCert, EVP_PKEY_Pointer &untrustedPkey, X509_Pointer const &cert, EVP_PKEY_Pointer const & pkey)
1717 {
1718 // Generate the self-signed certificate, using a hard-coded subject prefix
1719 Ssl::CertificateProperties certProperties;
1720 if (const char *cn = CommonHostName(cert.get())) {
1721 certProperties.commonName = "Not trusted by \"";
1722 certProperties.commonName += cn;
1723 certProperties.commonName += "\"";
1724 } else if (const char *org = getOrganization(cert.get())) {
1725 certProperties.commonName = "Not trusted by \"";
1726 certProperties.commonName += org;
1727 certProperties.commonName += "\"";
1728 } else
1729 certProperties.commonName = "Not trusted";
1730 certProperties.setCommonName = true;
1731 // O, OU, and other CA subject fields will be mimicked
1732 // Expiration date and other common properties will be mimicked
1733 certProperties.signAlgorithm = Ssl::algSignSelf;
1734 certProperties.signWithPkey.resetAndLock(pkey.get());
1735 certProperties.mimicCert.resetAndLock(cert.get());
1736 return Ssl::generateSslCertificate(untrustedCert, untrustedPkey, certProperties);
1737 }
1738
1739 SSL *
1740 SslCreate(SSL_CTX *sslContext, const int fd, Ssl::Bio::Type type, const char *squidCtx)
1741 {
1742 const char *errAction = NULL;
1743 int errCode = 0;
1744 if (SSL *ssl = SSL_new(sslContext)) {
1745 // without BIO, we would call SSL_set_fd(ssl, fd) instead
1746 if (BIO *bio = Ssl::Bio::Create(fd, type)) {
1747 Ssl::Bio::Link(ssl, bio); // cannot fail
1748
1749 fd_table[fd].ssl = ssl;
1750 fd_table[fd].read_method = &ssl_read_method;
1751 fd_table[fd].write_method = &ssl_write_method;
1752 fd_note(fd, squidCtx);
1753
1754 return ssl;
1755 }
1756 errCode = ERR_get_error();
1757 errAction = "failed to initialize I/O";
1758 SSL_free(ssl);
1759 } else {
1760 errCode = ERR_get_error();
1761 errAction = "failed to allocate handle";
1762 }
1763
1764 debugs(83, DBG_IMPORTANT, "ERROR: " << squidCtx << ' ' << errAction <<
1765 ": " << ERR_error_string(errCode, NULL));
1766 return NULL;
1767 }
1768
1769 SSL *
1770 Ssl::CreateClient(SSL_CTX *sslContext, const int fd, const char *squidCtx)
1771 {
1772 return SslCreate(sslContext, fd, Ssl::Bio::BIO_TO_SERVER, squidCtx);
1773 }
1774
1775 SSL *
1776 Ssl::CreateServer(SSL_CTX *sslContext, const int fd, const char *squidCtx)
1777 {
1778 return SslCreate(sslContext, fd, Ssl::Bio::BIO_TO_CLIENT, squidCtx);
1779 }
1780
1781 Ssl::CertError::CertError(ssl_error_t anErr, X509 *aCert): code(anErr)
1782 {
1783 cert.resetAndLock(aCert);
1784 }
1785
1786 Ssl::CertError::CertError(CertError const &err): code(err.code)
1787 {
1788 cert.resetAndLock(err.cert.get());
1789 }
1790
1791 Ssl::CertError &
1792 Ssl::CertError::operator = (const CertError &old)
1793 {
1794 code = old.code;
1795 cert.resetAndLock(old.cert.get());
1796 return *this;
1797 }
1798
1799 bool
1800 Ssl::CertError::operator == (const CertError &ce) const
1801 {
1802 return code == ce.code && cert.get() == ce.cert.get();
1803 }
1804
1805 bool
1806 Ssl::CertError::operator != (const CertError &ce) const
1807 {
1808 return code != ce.code || cert.get() != ce.cert.get();
1809 }
1810
1811 static int
1812 store_session_cb(SSL *ssl, SSL_SESSION *session)
1813 {
1814 if (!SslSessionCache)
1815 return 0;
1816
1817 debugs(83, 5, "Request to store SSL Session ");
1818
1819 SSL_SESSION_set_timeout(session, Config.SSL.session_ttl);
1820
1821 unsigned char *id = session->session_id;
1822 unsigned int idlen = session->session_id_length;
1823 unsigned char key[MEMMAP_SLOT_KEY_SIZE];
1824 // Session ids are of size 32bytes. They should always fit to a
1825 // MemMap::Slot::key
1826 assert(idlen <= MEMMAP_SLOT_KEY_SIZE);
1827 memset(key, 0, sizeof(key));
1828 memcpy(key, id, idlen);
1829 int pos;
1830 Ipc::MemMap::Slot *slotW = SslSessionCache->openForWriting((const cache_key*)key, pos);
1831 if (slotW) {
1832 int lenRequired = i2d_SSL_SESSION(session, NULL);
1833 if (lenRequired < MEMMAP_SLOT_DATA_SIZE) {
1834 unsigned char *p = (unsigned char *)slotW->p;
1835 lenRequired = i2d_SSL_SESSION(session, &p);
1836 slotW->set(key, NULL, lenRequired, squid_curtime + Config.SSL.session_ttl);
1837 }
1838 SslSessionCache->closeForWriting(pos);
1839 debugs(83, 5, "wrote an ssl session entry of size " << lenRequired << " at pos " << pos);
1840 }
1841 return 0;
1842 }
1843
1844 static void
1845 remove_session_cb(SSL_CTX *, SSL_SESSION *sessionID)
1846 {
1847 if (!SslSessionCache)
1848 return ;
1849
1850 debugs(83, 5, "Request to remove corrupted or not valid SSL Session ");
1851 int pos;
1852 Ipc::MemMap::Slot const *slot = SslSessionCache->openForReading((const cache_key*)sessionID, pos);
1853 if (slot == NULL)
1854 return;
1855 SslSessionCache->closeForReading(pos);
1856 // TODO:
1857 // What if we are not able to remove the session?
1858 // Maybe schedule a job to remove it later?
1859 // For now we just have an invalid entry in cache until will be expired
1860 // The openSSL will reject it when we try to use it
1861 SslSessionCache->free(pos);
1862 }
1863
1864 static SSL_SESSION *
1865 get_session_cb(SSL *, unsigned char *sessionID, int len, int *copy)
1866 {
1867 if (!SslSessionCache)
1868 return NULL;
1869
1870 SSL_SESSION *session = NULL;
1871 const unsigned int *p;
1872 p = (unsigned int *)sessionID;
1873 debugs(83, 5, "Request to search for SSL Session of len:" <<
1874 len << p[0] << ":" << p[1]);
1875
1876 int pos;
1877 Ipc::MemMap::Slot const *slot = SslSessionCache->openForReading((const cache_key*)sessionID, pos);
1878 if (slot != NULL) {
1879 if (slot->expire > squid_curtime) {
1880 const unsigned char *ptr = slot->p;
1881 session = d2i_SSL_SESSION(NULL, &ptr, slot->pSize);
1882 debugs(83, 5, "Session retrieved from cache at pos " << pos);
1883 } else
1884 debugs(83, 5, "Session in cache expired");
1885 SslSessionCache->closeForReading(pos);
1886 }
1887
1888 if (!session)
1889 debugs(83, 5, "Failed to retrieved from cache\n");
1890
1891 // With the parameter copy the callback can require the SSL engine
1892 // to increment the reference count of the SSL_SESSION object, Normally
1893 // the reference count is not incremented and therefore the session must
1894 // not be explicitly freed with SSL_SESSION_free(3).
1895 *copy = 0;
1896 return session;
1897 }
1898
1899 static void
1900 setSessionCallbacks(SSL_CTX *ctx)
1901 {
1902 if (SslSessionCache) {
1903 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL);
1904 SSL_CTX_sess_set_new_cb(ctx, store_session_cb);
1905 SSL_CTX_sess_set_remove_cb(ctx, remove_session_cb);
1906 SSL_CTX_sess_set_get_cb(ctx, get_session_cb);
1907 }
1908 }
1909
1910 static bool
1911 isSslServer()
1912 {
1913 if (HttpsPortList != NULL)
1914 return true;
1915
1916 for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) {
1917 if (s->flags.tunnelSslBumping)
1918 return true;
1919 }
1920
1921 return false;
1922 }
1923
1924 #define SSL_SESSION_ID_SIZE 32
1925 #define SSL_SESSION_MAX_SIZE 10*1024
1926
1927 void
1928 Ssl::initialize_session_cache()
1929 {
1930
1931 if (!isSslServer()) //no need to configure ssl session cache.
1932 return;
1933
1934 // Check if the MemMap keys and data are enough big to hold
1935 // session ids and session data
1936 assert(SSL_SESSION_ID_SIZE >= MEMMAP_SLOT_KEY_SIZE);
1937 assert(SSL_SESSION_MAX_SIZE >= MEMMAP_SLOT_DATA_SIZE);
1938
1939 int configuredItems = ::Config.SSL.sessionCacheSize / sizeof(Ipc::MemMap::Slot);
1940 if (IamWorkerProcess() && configuredItems)
1941 SslSessionCache = new Ipc::MemMap(SslSessionCacheName);
1942 else {
1943 SslSessionCache = NULL;
1944 return;
1945 }
1946
1947 for (AnyP::PortCfgPointer s = HttpsPortList; s != NULL; s = s->next) {
1948 if (s->staticSslContext.get() != NULL)
1949 setSessionCallbacks(s->staticSslContext.get());
1950 }
1951
1952 for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) {
1953 if (s->staticSslContext.get() != NULL)
1954 setSessionCallbacks(s->staticSslContext.get());
1955 }
1956 }
1957
1958 void
1959 destruct_session_cache()
1960 {
1961 delete SslSessionCache;
1962 }
1963
1964 /// initializes shared memory segments used by MemStore
1965 class SharedSessionCacheRr: public Ipc::Mem::RegisteredRunner
1966 {
1967 public:
1968 /* RegisteredRunner API */
1969 SharedSessionCacheRr(): owner(NULL) {}
1970 virtual void useConfig();
1971 virtual ~SharedSessionCacheRr();
1972
1973 protected:
1974 virtual void create();
1975
1976 private:
1977 Ipc::MemMap::Owner *owner;
1978 };
1979
1980 RunnerRegistrationEntry(SharedSessionCacheRr);
1981
1982 void
1983 SharedSessionCacheRr::useConfig()
1984 {
1985 Ipc::Mem::RegisteredRunner::useConfig();
1986 }
1987
1988 void
1989 SharedSessionCacheRr::create()
1990 {
1991 if (!isSslServer()) //no need to configure ssl session cache.
1992 return;
1993
1994 int items;
1995 items = Config.SSL.sessionCacheSize / sizeof(Ipc::MemMap::Slot);
1996 if (items)
1997 owner = Ipc::MemMap::Init(SslSessionCacheName, items);
1998 }
1999
2000 SharedSessionCacheRr::~SharedSessionCacheRr()
2001 {
2002 delete owner;
2003 }
2004
2005 #endif /* USE_OPENSSL */
2006