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