]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ssl/support.cc
Removed squid-old.h
[thirdparty/squid.git] / src / ssl / support.cc
CommitLineData
f484cdf5 1
2/*
262a0e14 3 * $Id$
f484cdf5 4 *
5 * AUTHOR: Benno Rice
27d8545c 6 * DEBUG: section 83 SSL accelerator support
f484cdf5 7 *
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * ----------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * the CREDITS file for full details.
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
26ac0430 24 *
f484cdf5 25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
26ac0430 29 *
f484cdf5 30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
33 *
34 */
35
582c2af2 36#include "squid.h"
454e8283 37
38/* MS Visual Studio Projects are monolithic, so we need the following
39 * #if to exclude the SSL code from compile process when not needed.
40 */
41#if USE_SSL
42
c0941a6a 43#include "acl/FilledChecklist.h"
582c2af2
FC
44#include "fde.h"
45#include "globals.h"
46#include "protos.h"
4d16918e 47#include "ssl/ErrorDetail.h"
4db984be 48#include "ssl/support.h"
95d2589c 49#include "ssl/gadgets.h"
f484cdf5 50
caf3666d
AR
51const char *Ssl::BumpModeStr[] = {
52 "none",
53 "client-first",
54 "server-first",
55 NULL
56};
57
63be0a78 58/**
59 \defgroup ServerProtocolSSLInternal Server-Side SSL Internals
60 \ingroup ServerProtocolSSLAPI
61 */
62
63/// \ingroup ServerProtocolSSLInternal
307b83b7 64static int
65ssl_ask_password_cb(char *buf, int size, int rwflag, void *userdata)
66{
67 FILE *in;
68 int len = 0;
69 char cmdline[1024];
70
71 snprintf(cmdline, sizeof(cmdline), "\"%s\" \"%s\"", Config.Program.ssl_password, (const char *)userdata);
72 in = popen(cmdline, "r");
73
74 if (fgets(buf, size, in))
75
76 len = strlen(buf);
77
78 while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r'))
5e263176 79 --len;
307b83b7 80
81 buf[len] = '\0';
82
83 pclose(in);
84
85 return len;
86}
87
63be0a78 88/// \ingroup ServerProtocolSSLInternal
307b83b7 89static void
90ssl_ask_password(SSL_CTX * context, const char * prompt)
91{
92 if (Config.Program.ssl_password) {
93 SSL_CTX_set_default_passwd_cb(context, ssl_ask_password_cb);
94 SSL_CTX_set_default_passwd_cb_userdata(context, (void *)prompt);
95 }
96}
97
63be0a78 98/// \ingroup ServerProtocolSSLInternal
f484cdf5 99static RSA *
e6ccf245 100ssl_temp_rsa_cb(SSL * ssl, int anInt, int keylen)
f484cdf5 101{
e01f02ed 102 static RSA *rsa_512 = NULL;
103 static RSA *rsa_1024 = NULL;
104 RSA *rsa = NULL;
105 int newkey = 0;
f484cdf5 106
e01f02ed 107 switch (keylen) {
108
109 case 512:
110
111 if (!rsa_512) {
112 rsa_512 = RSA_generate_key(512, RSA_F4, NULL, NULL);
113 newkey = 1;
114 }
115
116 rsa = rsa_512;
117 break;
118
119 case 1024:
120
121 if (!rsa_1024) {
122 rsa_1024 = RSA_generate_key(1024, RSA_F4, NULL, NULL);
123 newkey = 1;
124 }
125
126 rsa = rsa_1024;
127 break;
128
129 default:
e0236918 130 debugs(83, DBG_IMPORTANT, "ssl_temp_rsa_cb: Unexpected key length " << keylen);
e01f02ed 131 return NULL;
132 }
133
134 if (rsa == NULL) {
e0236918 135 debugs(83, DBG_IMPORTANT, "ssl_temp_rsa_cb: Failed to generate key " << keylen);
e01f02ed 136 return NULL;
137 }
138
139 if (newkey) {
140 if (do_debug(83, 5))
141 PEM_write_RSAPrivateKey(debug_log, rsa, NULL, NULL, 0, NULL, NULL);
142
e0236918 143 debugs(83, DBG_IMPORTANT, "Generated ephemeral RSA key of length " << keylen);
e01f02ed 144 }
62e76326 145
f484cdf5 146 return rsa;
147}
148
4d16918e
CT
149int Ssl::asn1timeToString(ASN1_TIME *tm, char *buf, int len)
150{
151 BIO *bio;
152 int write = 0;
153 bio = BIO_new(BIO_s_mem());
154 if (bio) {
e34763f4
A
155 if (ASN1_TIME_print(bio, tm))
156 write = BIO_read(bio, buf, len-1);
157 BIO_free(bio);
4d16918e
CT
158 }
159 buf[write]='\0';
160 return write;
161}
162
163int Ssl::matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data, ASN1_STRING *cn_data))
164{
165 assert(peer_cert);
166
167 X509_NAME *name = X509_get_subject_name(peer_cert);
168
169 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 170
4d16918e
CT
171 ASN1_STRING *cn_data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
172
173 if ( (*check_func)(check_data, cn_data) == 0)
174 return 1;
175 }
176
177 STACK_OF(GENERAL_NAME) * altnames;
178 altnames = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(peer_cert, NID_subject_alt_name, NULL, NULL);
179
180 if (altnames) {
181 int numalts = sk_GENERAL_NAME_num(altnames);
d7ae3534 182 for (int i = 0; i < numalts; ++i) {
4d16918e
CT
183 const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
184 if (check->type != GEN_DNS) {
185 continue;
186 }
187 ASN1_STRING *cn_data = check->d.dNSName;
e34763f4 188
4d16918e
CT
189 if ( (*check_func)(check_data, cn_data) == 0)
190 return 1;
191 }
192 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
193 }
194 return 0;
195}
196
197static int check_domain( void *check_data, ASN1_STRING *cn_data)
198{
199 char cn[1024];
200 const char *server = (const char *)check_data;
201
e34763f4 202 if (cn_data->length > (int)sizeof(cn) - 1) {
4d16918e
CT
203 return 1; //if does not fit our buffer just ignore
204 }
205 memcpy(cn, cn_data->data, cn_data->length);
206 cn[cn_data->length] = '\0';
207 debugs(83, 4, "Verifying server domain " << server << " to certificate name/subjectAltName " << cn);
208 return matchDomainName(server, cn[0] == '*' ? cn + 1 : cn);
209}
210
8eb0a7ee
CT
211bool Ssl::checkX509ServerValidity(X509 *cert, const char *server)
212{
213 return matchX509CommonNames(cert, (void *)server, check_domain);
214}
215
63be0a78 216/// \ingroup ServerProtocolSSLInternal
f484cdf5 217static int
218ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
219{
7698a79c
CT
220 // preserve original ctx->error before SSL_ calls can overwrite it
221 Ssl::ssl_error_t error_no = ok ? SSL_ERROR_NONE : ctx->error;
222
223 char buffer[256] = "";
a7ad6e4e 224 SSL *ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
225 SSL_CTX *sslctx = SSL_get_SSL_CTX(ssl);
226 const char *server = (const char *)SSL_get_ex_data(ssl, ssl_ex_index_server);
227 void *dont_verify_domain = SSL_CTX_get_ex_data(sslctx, ssl_ctx_ex_index_dont_verify_domain);
815eaa44 228 ACLChecklist *check = (ACLChecklist*)SSL_get_ex_data(ssl, ssl_ex_index_cert_error_check);
e7bcc25f 229 X509 *peeked_cert = (X509 *)SSL_get_ex_data(ssl, ssl_ex_index_ssl_peeked_cert);
a7ad6e4e 230 X509 *peer_cert = ctx->cert;
f484cdf5 231
a7ad6e4e 232 X509_NAME_oneline(X509_get_subject_name(peer_cert), buffer,
62e76326 233 sizeof(buffer));
a7ad6e4e 234
235 if (ok) {
bf8fe701 236 debugs(83, 5, "SSL Certificate signature OK: " << buffer);
62e76326 237
e34763f4 238 if (server) {
8eb0a7ee 239 if (!Ssl::checkX509ServerValidity(peer_cert, server)) {
815eaa44 240 debugs(83, 2, "SQUID_X509_V_ERR_DOMAIN_MISMATCH: Certificate " << buffer << " does not match domainname " << server);
62e76326 241 ok = 0;
4d16918e 242 error_no = SQUID_X509_V_ERR_DOMAIN_MISMATCH;
62e76326 243 }
244 }
7698a79c 245 }
0db46e4f 246
e7bcc25f 247 if (ok && peeked_cert) {
7a957a93 248 // Check whether the already peeked certificate matches the new one.
e7bcc25f
CT
249 if (X509_cmp(peer_cert, peeked_cert) != 0) {
250 debugs(83, 2, "SQUID_X509_V_ERR_CERT_CHANGE: Certificate " << buffer << " does not match peeked certificate");
251 ok = 0;
252 error_no = SQUID_X509_V_ERR_CERT_CHANGE;
253 }
254 }
255
7698a79c 256 if (!ok) {
7a957a93
AR
257 Ssl::Errors *errs = static_cast<Ssl::Errors *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_errors));
258 if (!errs) {
259 errs = new Ssl::Errors(error_no);
260 if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_errors, (void *)errs)) {
fb2178bb 261 debugs(83, 2, "Failed to set ssl error_no in ssl_verify_cb: Certificate " << buffer);
7a957a93
AR
262 delete errs;
263 errs = NULL;
fb2178bb 264 }
87f237a9 265 } else // remember another error number
7a957a93 266 errs->push_back_unique(error_no);
fb2178bb 267
7698a79c 268 if (const char *err_descr = Ssl::GetErrorDescr(error_no))
cf09bec7
CT
269 debugs(83, 5, err_descr << ": " << buffer);
270 else
7698a79c
CT
271 debugs(83, DBG_IMPORTANT, "SSL unknown certificate error " << error_no << " in " << buffer);
272
273 if (check) {
fb2178bb 274 ACLFilledChecklist *filledCheck = Filled(check);
7a957a93
AR
275 assert(!filledCheck->sslErrors);
276 filledCheck->sslErrors = new Ssl::Errors(error_no);
2efeb0b7 277 if (check->fastCheck() == ACCESS_ALLOWED) {
7698a79c
CT
278 debugs(83, 3, "bypassing SSL error " << error_no << " in " << buffer);
279 ok = 1;
280 } else {
281 debugs(83, 5, "confirming SSL error " << error_no);
282 }
7a957a93
AR
283 delete filledCheck->sslErrors;
284 filledCheck->sslErrors = NULL;
815eaa44 285 }
a7ad6e4e 286 }
62e76326 287
26ac0430 288 if (!dont_verify_domain && server) {}
62e76326 289
7698a79c 290 if (!ok && !SSL_get_ex_data(ssl, ssl_ex_index_ssl_error_detail) ) {
f622c461
MF
291
292 // Find the broken certificate. It may be intermediate.
293 X509 *broken_cert = peer_cert; // reasonable default if search fails
294 // Our SQUID_X509_V_ERR_DOMAIN_MISMATCH implies peer_cert is at fault.
295 if (error_no != SQUID_X509_V_ERR_DOMAIN_MISMATCH) {
296 if (X509 *last_used_cert = X509_STORE_CTX_get_current_cert(ctx))
297 broken_cert = last_used_cert;
298 }
299
300 Ssl::ErrorDetail *errDetail =
de878a55 301 new Ssl::ErrorDetail(error_no, peer_cert, broken_cert);
f622c461 302
e34763f4 303 if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_error_detail, errDetail)) {
4d16918e
CT
304 debugs(83, 2, "Failed to set Ssl::ErrorDetail in ssl_verify_cb: Certificate " << buffer);
305 delete errDetail;
306 }
307 }
308
f484cdf5 309 return ok;
310}
311
63be0a78 312/// \ingroup ServerProtocolSSLInternal
26ac0430 313static struct ssl_option {
79d4ccdf 314 const char *name;
315 long value;
62e76326 316}
317
318ssl_options[] = {
79d4ccdf 319
32d002cb 320#if SSL_OP_MICROSOFT_SESS_ID_BUG
26ac0430
AJ
321 {
322 "MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG
323 },
673cd7db 324#endif
32d002cb 325#if SSL_OP_NETSCAPE_CHALLENGE_BUG
26ac0430
AJ
326 {
327 "NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG
328 },
673cd7db 329#endif
32d002cb 330#if SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
26ac0430
AJ
331 {
332 "NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
333 },
673cd7db 334#endif
32d002cb 335#if SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
26ac0430
AJ
336 {
337 "SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
338 },
673cd7db 339#endif
32d002cb 340#if SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
26ac0430
AJ
341 {
342 "MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
343 },
673cd7db 344#endif
32d002cb 345#if SSL_OP_MSIE_SSLV2_RSA_PADDING
26ac0430
AJ
346 {
347 "MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING
348 },
673cd7db 349#endif
32d002cb 350#if SSL_OP_SSLEAY_080_CLIENT_DH_BUG
26ac0430
AJ
351 {
352 "SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG
353 },
673cd7db 354#endif
32d002cb 355#if SSL_OP_TLS_D5_BUG
26ac0430
AJ
356 {
357 "TLS_D5_BUG", SSL_OP_TLS_D5_BUG
358 },
673cd7db 359#endif
32d002cb 360#if SSL_OP_TLS_BLOCK_PADDING_BUG
26ac0430
AJ
361 {
362 "TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG
363 },
673cd7db 364#endif
32d002cb 365#if SSL_OP_TLS_ROLLBACK_BUG
26ac0430
AJ
366 {
367 "TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG
368 },
673cd7db 369#endif
32d002cb 370#if SSL_OP_ALL
26ac0430 371 {
866eafc6 372 "ALL", (long)SSL_OP_ALL
26ac0430 373 },
673cd7db 374#endif
32d002cb 375#if SSL_OP_SINGLE_DH_USE
26ac0430
AJ
376 {
377 "SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE
378 },
673cd7db 379#endif
32d002cb 380#if SSL_OP_EPHEMERAL_RSA
26ac0430
AJ
381 {
382 "EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA
383 },
673cd7db 384#endif
32d002cb 385#if SSL_OP_PKCS1_CHECK_1
26ac0430
AJ
386 {
387 "PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1
388 },
673cd7db 389#endif
32d002cb 390#if SSL_OP_PKCS1_CHECK_2
26ac0430
AJ
391 {
392 "PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2
393 },
673cd7db 394#endif
32d002cb 395#if SSL_OP_NETSCAPE_CA_DN_BUG
26ac0430
AJ
396 {
397 "NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG
398 },
673cd7db 399#endif
32d002cb 400#if SSL_OP_NON_EXPORT_FIRST
26ac0430
AJ
401 {
402 "NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST
403 },
673cd7db 404#endif
32d002cb 405#if SSL_OP_CIPHER_SERVER_PREFERENCE
26ac0430
AJ
406 {
407 "CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE
408 },
673cd7db 409#endif
32d002cb 410#if SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
26ac0430
AJ
411 {
412 "NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
413 },
673cd7db 414#endif
32d002cb 415#if SSL_OP_NO_SSLv2
26ac0430
AJ
416 {
417 "NO_SSLv2", SSL_OP_NO_SSLv2
418 },
673cd7db 419#endif
32d002cb 420#if SSL_OP_NO_SSLv3
26ac0430
AJ
421 {
422 "NO_SSLv3", SSL_OP_NO_SSLv3
423 },
673cd7db 424#endif
32d002cb 425#if SSL_OP_NO_TLSv1
26ac0430
AJ
426 {
427 "NO_TLSv1", SSL_OP_NO_TLSv1
428 },
3d96b0e8
AJ
429#endif
430#if SSL_OP_NO_TLSv1_1
431 {
432 "NO_TLSv1_1", SSL_OP_NO_TLSv1_1
433 },
434#endif
435#if SSL_OP_NO_TLSv1_2
436 {
437 "NO_TLSv1_2", SSL_OP_NO_TLSv1_2
438 },
673cd7db 439#endif
26ac0430
AJ
440 {
441 "", 0
442 },
443 {
444 NULL, 0
445 }
446};
79d4ccdf 447
63be0a78 448/// \ingroup ServerProtocolSSLInternal
84f2d773 449static long
79d4ccdf 450ssl_parse_options(const char *options)
451{
943c5f16 452 long op = 0;
79d4ccdf 453 char *tmp;
454 char *option;
455
456 if (!options)
62e76326 457 goto no_options;
79d4ccdf 458
459 tmp = xstrdup(options);
62e76326 460
79d4ccdf 461 option = strtok(tmp, ":,");
62e76326 462
79d4ccdf 463 while (option) {
62e76326 464
465 struct ssl_option *opt = NULL, *opttmp;
466 long value = 0;
467 enum {
468 MODE_ADD, MODE_REMOVE
469 } mode;
470
471 switch (*option) {
472
473 case '!':
474
475 case '-':
476 mode = MODE_REMOVE;
d7ae3534 477 ++option;
62e76326 478 break;
479
480 case '+':
481 mode = MODE_ADD;
d7ae3534 482 ++option;
62e76326 483 break;
484
485 default:
486 mode = MODE_ADD;
487 break;
488 }
489
d7ae3534 490 for (opttmp = ssl_options; opttmp->name; ++opttmp) {
62e76326 491 if (strcmp(opttmp->name, option) == 0) {
492 opt = opttmp;
493 break;
494 }
495 }
496
497 if (opt)
498 value = opt->value;
499 else if (strncmp(option, "0x", 2) == 0) {
500 /* Special case.. hex specification */
501 value = strtol(option + 2, NULL, 16);
502 } else {
503 fatalf("Unknown SSL option '%s'", option);
504 value = 0; /* Keep GCC happy */
505 }
506
507 switch (mode) {
508
509 case MODE_ADD:
510 op |= value;
511 break;
512
513 case MODE_REMOVE:
514 op &= ~value;
515 break;
516 }
517
518 option = strtok(NULL, ":,");
79d4ccdf 519 }
520
521 safe_free(tmp);
62e76326 522
523no_options:
79d4ccdf 524 return op;
525}
526
63be0a78 527/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 528#define SSL_FLAG_NO_DEFAULT_CA (1<<0)
63be0a78 529/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 530#define SSL_FLAG_DELAYED_AUTH (1<<1)
63be0a78 531/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 532#define SSL_FLAG_DONT_VERIFY_PEER (1<<2)
63be0a78 533/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 534#define SSL_FLAG_DONT_VERIFY_DOMAIN (1<<3)
63be0a78 535/// \ingroup ServerProtocolSSLInternal
b13877cc 536#define SSL_FLAG_NO_SESSION_REUSE (1<<4)
63be0a78 537/// \ingroup ServerProtocolSSLInternal
a82a4fe4 538#define SSL_FLAG_VERIFY_CRL (1<<5)
63be0a78 539/// \ingroup ServerProtocolSSLInternal
a82a4fe4 540#define SSL_FLAG_VERIFY_CRL_ALL (1<<6)
a7ad6e4e 541
63be0a78 542/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 543static long
544ssl_parse_flags(const char *flags)
545{
546 long fl = 0;
547 char *tmp;
548 char *flag;
549
550 if (!flags)
62e76326 551 return 0;
a7ad6e4e 552
553 tmp = xstrdup(flags);
62e76326 554
a7ad6e4e 555 flag = strtok(tmp, ":,");
62e76326 556
a7ad6e4e 557 while (flag) {
62e76326 558 if (strcmp(flag, "NO_DEFAULT_CA") == 0)
559 fl |= SSL_FLAG_NO_DEFAULT_CA;
560 else if (strcmp(flag, "DELAYED_AUTH") == 0)
561 fl |= SSL_FLAG_DELAYED_AUTH;
562 else if (strcmp(flag, "DONT_VERIFY_PEER") == 0)
563 fl |= SSL_FLAG_DONT_VERIFY_PEER;
564 else if (strcmp(flag, "DONT_VERIFY_DOMAIN") == 0)
565 fl |= SSL_FLAG_DONT_VERIFY_DOMAIN;
b13877cc 566 else if (strcmp(flag, "NO_SESSION_REUSE") == 0)
567 fl |= SSL_FLAG_NO_SESSION_REUSE;
a82a4fe4 568
32d002cb 569#if X509_V_FLAG_CRL_CHECK
a82a4fe4 570
571 else if (strcmp(flag, "VERIFY_CRL") == 0)
572 fl |= SSL_FLAG_VERIFY_CRL;
573 else if (strcmp(flag, "VERIFY_CRL_ALL") == 0)
574 fl |= SSL_FLAG_VERIFY_CRL_ALL;
575
576#endif
577
62e76326 578 else
579 fatalf("Unknown ssl flag '%s'", flag);
580
581 flag = strtok(NULL, ":,");
a7ad6e4e 582 }
62e76326 583
a7ad6e4e 584 safe_free(tmp);
585 return fl;
586}
587
815eaa44 588// "dup" function for SSL_get_ex_new_index("cert_err_check")
589static int
590ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *,
26ac0430
AJ
591 int, long, void *)
592{
815eaa44 593 // We do not support duplication of ACLCheckLists.
594 // If duplication is needed, we can count copies with cbdata.
595 assert(false);
596 return 0;
597}
598
599// "free" function for SSL_get_ex_new_index("cert_err_check")
600static void
601ssl_freeAclChecklist(void *, void *ptr, CRYPTO_EX_DATA *,
26ac0430
AJ
602 int, long, void *)
603{
815eaa44 604 delete static_cast<ACLChecklist *>(ptr); // may be NULL
605}
a7ad6e4e 606
4d16918e
CT
607// "free" function for SSL_get_ex_new_index("ssl_error_detail")
608static void
609ssl_free_ErrorDetail(void *, void *ptr, CRYPTO_EX_DATA *,
610 int, long, void *)
611{
612 Ssl::ErrorDetail *errDetail = static_cast <Ssl::ErrorDetail *>(ptr);
613 delete errDetail;
614}
615
fb2178bb 616static void
7a957a93 617ssl_free_SslErrors(void *, void *ptr, CRYPTO_EX_DATA *,
87f237a9 618 int, long, void *)
fb2178bb 619{
7a957a93
AR
620 Ssl::Errors *errs = static_cast <Ssl::Errors*>(ptr);
621 delete errs;
fb2178bb
CT
622}
623
e7bcc25f
CT
624// "free" function for X509 certificates
625static void
626ssl_free_X509(void *, void *ptr, CRYPTO_EX_DATA *,
87f237a9 627 int, long, void *)
e7bcc25f
CT
628{
629 X509 *cert = static_cast <X509 *>(ptr);
630 X509_free(cert);
631}
632
63be0a78 633/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 634static void
635ssl_initialize(void)
f484cdf5 636{
d193a436 637 static int ssl_initialized = 0;
62e76326 638
d193a436 639 if (!ssl_initialized) {
62e76326 640 ssl_initialized = 1;
641 SSL_load_error_strings();
642 SSLeay_add_ssl_algorithms();
32d002cb 643#if HAVE_OPENSSL_ENGINE_H
62e76326 644
645 if (Config.SSL.ssl_engine) {
646 ENGINE *e;
647
648 if (!(e = ENGINE_by_id(Config.SSL.ssl_engine))) {
649 fatalf("Unable to find SSL engine '%s'\n", Config.SSL.ssl_engine);
650 }
651
652 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
653 int ssl_error = ERR_get_error();
654 fatalf("Failed to initialise SSL engine: %s\n",
655 ERR_error_string(ssl_error, NULL));
656 }
657 }
658
a7ad6e4e 659#else
62e76326 660 if (Config.SSL.ssl_engine) {
661 fatalf("Your OpenSSL has no SSL engine support\n");
662 }
663
a7ad6e4e 664#endif
62e76326 665
d193a436 666 }
62e76326 667
a7ad6e4e 668 ssl_ex_index_server = SSL_get_ex_new_index(0, (void *) "server", NULL, NULL, NULL);
669 ssl_ctx_ex_index_dont_verify_domain = SSL_CTX_get_ex_new_index(0, (void *) "dont_verify_domain", NULL, NULL, NULL);
815eaa44 670 ssl_ex_index_cert_error_check = SSL_get_ex_new_index(0, (void *) "cert_error_check", NULL, &ssl_dupAclChecklist, &ssl_freeAclChecklist);
4d16918e 671 ssl_ex_index_ssl_error_detail = SSL_get_ex_new_index(0, (void *) "ssl_error_detail", NULL, NULL, &ssl_free_ErrorDetail);
e7bcc25f 672 ssl_ex_index_ssl_peeked_cert = SSL_get_ex_new_index(0, (void *) "ssl_peeked_cert", NULL, NULL, &ssl_free_X509);
7a957a93 673 ssl_ex_index_ssl_errors = SSL_get_ex_new_index(0, (void *) "ssl_errors", NULL, NULL, &ssl_free_SslErrors);
a7ad6e4e 674}
675
63be0a78 676/// \ingroup ServerProtocolSSLInternal
a82a4fe4 677static int
678ssl_load_crl(SSL_CTX *sslContext, const char *CRLfile)
679{
680 X509_STORE *st = SSL_CTX_get_cert_store(sslContext);
681 X509_CRL *crl;
682 BIO *in = BIO_new_file(CRLfile, "r");
683 int count = 0;
684
685 if (!in) {
bf8fe701 686 debugs(83, 2, "WARNING: Failed to open CRL file '" << CRLfile << "'");
a82a4fe4 687 return 0;
688 }
689
690 while ((crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL))) {
691 if (!X509_STORE_add_crl(st, crl))
bf8fe701 692 debugs(83, 2, "WARNING: Failed to add CRL from file '" << CRLfile << "'");
a82a4fe4 693 else
d7ae3534 694 ++count;
a82a4fe4 695
696 X509_CRL_free(crl);
697 }
698
699 BIO_free(in);
700 return count;
701}
702
a7ad6e4e 703SSL_CTX *
a82a4fe4 704sslCreateServerContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *clientCA, const char *CAfile, const char *CApath, const char *CRLfile, const char *dhfile, const char *context)
a7ad6e4e 705{
706 int ssl_error;
f1c9c850 707#if OPENSSL_VERSION_NUMBER < 0x00909000L
a7ad6e4e 708 SSL_METHOD *method;
f1c9c850
AJ
709#else
710 const SSL_METHOD *method;
711#endif
a7ad6e4e 712 SSL_CTX *sslContext;
713 long fl = ssl_parse_flags(flags);
714
715 ssl_initialize();
716
f484cdf5 717 if (!keyfile)
62e76326 718 keyfile = certfile;
719
f484cdf5 720 if (!certfile)
62e76326 721 certfile = keyfile;
722
a7ad6e4e 723 if (!CAfile)
62e76326 724 CAfile = clientCA;
f484cdf5 725
f4e4d4d6
CT
726 if (!certfile) {
727 debugs(83, DBG_CRITICAL, "ERROR: No certificate file");
728 return NULL;
729 }
730
79d4ccdf 731 switch (version) {
62e76326 732
f484cdf5 733 case 2:
50b4c080 734#ifndef OPENSSL_NO_SSL2
bf8fe701 735 debugs(83, 5, "Using SSLv2.");
62e76326 736 method = SSLv2_server_method();
50b4c080 737#else
48e7baac 738 debugs(83, DBG_IMPORTANT, "SSLv2 is not available in this Proxy.");
50b4c080
AJ
739 return NULL;
740#endif
62e76326 741 break;
742
f484cdf5 743 case 3:
bf8fe701 744 debugs(83, 5, "Using SSLv3.");
62e76326 745 method = SSLv3_server_method();
746 break;
747
f484cdf5 748 case 4:
bf8fe701 749 debugs(83, 5, "Using TLSv1.");
62e76326 750 method = TLSv1_server_method();
751 break;
752
3d96b0e8
AJ
753 case 5:
754#if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
755 debugs(83, 5, "Using TLSv1.1.");
756 method = TLSv1_1_server_method();
757#else
758 debugs(83, DBG_IMPORTANT, "TLSv1.1 is not available in this Proxy.");
759 return NULL;
760#endif
761 break;
762
763 case 6:
764#if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
765 debugs(83, 5, "Using TLSv1.2");
766 method = TLSv1_2_server_method();
767#else
768 debugs(83, DBG_IMPORTANT, "TLSv1.2 is not available in this Proxy.");
769 return NULL;
770#endif
771 break;
772
f484cdf5 773 case 1:
62e76326 774
f484cdf5 775 default:
bf8fe701 776 debugs(83, 5, "Using SSLv2/SSLv3.");
62e76326 777 method = SSLv23_server_method();
778 break;
f484cdf5 779 }
780
781 sslContext = SSL_CTX_new(method);
62e76326 782
f484cdf5 783 if (sslContext == NULL) {
62e76326 784 ssl_error = ERR_get_error();
f4e4d4d6
CT
785 debugs(83, DBG_CRITICAL, "ERROR: Failed to allocate SSL context: " << ERR_error_string(ssl_error, NULL));
786 return NULL;
f484cdf5 787 }
62e76326 788
79d4ccdf 789 SSL_CTX_set_options(sslContext, ssl_parse_options(options));
f484cdf5 790
6b2936d5 791 if (context && *context) {
3de409f0 792 SSL_CTX_set_session_id_context(sslContext, (const unsigned char *)context, strlen(context));
6b2936d5 793 }
794
b13877cc 795 if (fl & SSL_FLAG_NO_SESSION_REUSE) {
796 SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF);
797 }
798
a9d79803 799 if (Config.SSL.unclean_shutdown) {
bf8fe701 800 debugs(83, 5, "Enabling quiet SSL shutdowns (RFC violation).");
a9d79803 801
802 SSL_CTX_set_quiet_shutdown(sslContext, 1);
803 }
804
79d4ccdf 805 if (cipher) {
bf8fe701 806 debugs(83, 5, "Using chiper suite " << cipher << ".");
62e76326 807
808 if (!SSL_CTX_set_cipher_list(sslContext, cipher)) {
809 ssl_error = ERR_get_error();
f4e4d4d6
CT
810 debugs(83, DBG_CRITICAL, "ERROR: Failed to set SSL cipher suite '" << cipher << "': " << ERR_error_string(ssl_error, NULL));
811 SSL_CTX_free(sslContext);
812 return NULL;
62e76326 813 }
79d4ccdf 814 }
62e76326 815
48e7baac 816 debugs(83, DBG_IMPORTANT, "Using certificate in " << certfile);
62e76326 817
a7ad6e4e 818 if (!SSL_CTX_use_certificate_chain_file(sslContext, certfile)) {
62e76326 819 ssl_error = ERR_get_error();
48e7baac
AJ
820 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL certificate '" << certfile << "': " << ERR_error_string(ssl_error, NULL));
821 SSL_CTX_free(sslContext);
822 return NULL;
f484cdf5 823 }
62e76326 824
48e7baac 825 debugs(83, DBG_IMPORTANT, "Using private key in " << keyfile);
307b83b7 826 ssl_ask_password(sslContext, keyfile);
62e76326 827
f484cdf5 828 if (!SSL_CTX_use_PrivateKey_file(sslContext, keyfile, SSL_FILETYPE_PEM)) {
62e76326 829 ssl_error = ERR_get_error();
48e7baac
AJ
830 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL private key '" << keyfile << "': " << ERR_error_string(ssl_error, NULL));
831 SSL_CTX_free(sslContext);
832 return NULL;
f484cdf5 833 }
62e76326 834
bf8fe701 835 debugs(83, 5, "Comparing private and public SSL keys.");
62e76326 836
a7ad6e4e 837 if (!SSL_CTX_check_private_key(sslContext)) {
62e76326 838 ssl_error = ERR_get_error();
48e7baac
AJ
839 debugs(83, DBG_CRITICAL, "ERROR: SSL private key '" << certfile << "' does not match public key '" <<
840 keyfile << "': " << ERR_error_string(ssl_error, NULL));
841 SSL_CTX_free(sslContext);
842 return NULL;
a7ad6e4e 843 }
62e76326 844
bf8fe701 845 debugs(83, 9, "Setting RSA key generation callback.");
a7ad6e4e 846 SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb);
847
bf8fe701 848 debugs(83, 9, "Setting CA certificate locations.");
62e76326 849
a82a4fe4 850 if ((CAfile || CApath) && !SSL_CTX_load_verify_locations(sslContext, CAfile, CApath)) {
62e76326 851 ssl_error = ERR_get_error();
48e7baac 852 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate locations: " << ERR_error_string(ssl_error, NULL));
a7ad6e4e 853 }
62e76326 854
a7ad6e4e 855 if (!(fl & SSL_FLAG_NO_DEFAULT_CA) &&
62e76326 856 !SSL_CTX_set_default_verify_paths(sslContext)) {
857 ssl_error = ERR_get_error();
48e7baac 858 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default CA certificate location: " << ERR_error_string(ssl_error, NULL));
a7ad6e4e 859 }
62e76326 860
a7ad6e4e 861 if (clientCA) {
8c1ff4ef 862 STACK_OF(X509_NAME) *cert_names;
bf8fe701 863 debugs(83, 9, "Set client certifying authority list.");
8c1ff4ef 864 cert_names = SSL_load_client_CA_file(clientCA);
865
866 if (cert_names == NULL) {
48e7baac
AJ
867 debugs(83, DBG_IMPORTANT, "ERROR: loading the client CA certificates from '" << clientCA << "\': " << ERR_error_string(ERR_get_error(),NULL));
868 SSL_CTX_free(sslContext);
869 return NULL;
8c1ff4ef 870 }
871
872 ERR_clear_error();
873 SSL_CTX_set_client_CA_list(sslContext, cert_names);
62e76326 874
875 if (fl & SSL_FLAG_DELAYED_AUTH) {
bf8fe701 876 debugs(83, 9, "Not requesting client certificates until acl processing requires one");
62e76326 877 SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
878 } else {
bf8fe701 879 debugs(83, 9, "Requiring client certificates.");
62e76326 880 SSL_CTX_set_verify(sslContext, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
881 }
a82a4fe4 882
883 if (CRLfile) {
884 ssl_load_crl(sslContext, CRLfile);
885 fl |= SSL_FLAG_VERIFY_CRL;
886 }
887
32d002cb 888#if X509_V_FLAG_CRL_CHECK
a82a4fe4 889 if (fl & SSL_FLAG_VERIFY_CRL_ALL)
890 X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
891 else if (fl & SSL_FLAG_VERIFY_CRL)
892 X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK);
893
894#endif
895
a7ad6e4e 896 } else {
bf8fe701 897 debugs(83, 9, "Not requiring any client certificates");
62e76326 898 SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
a7ad6e4e 899 }
f484cdf5 900
35105e4b 901 if (dhfile) {
902 FILE *in = fopen(dhfile, "r");
903 DH *dh = NULL;
904 int codes;
905
906 if (in) {
907 dh = PEM_read_DHparams(in, NULL, NULL, NULL);
908 fclose(in);
909 }
910
911 if (!dh)
48e7baac 912 debugs(83, DBG_IMPORTANT, "WARNING: Failed to read DH parameters '" << dhfile << "'");
35105e4b 913 else if (dh && DH_check(dh, &codes) == 0) {
914 if (codes) {
48e7baac 915 debugs(83, DBG_IMPORTANT, "WARNING: Failed to verify DH parameters '" << dhfile << "' (" << std::hex << codes << ")");
35105e4b 916 DH_free(dh);
917 dh = NULL;
918 }
919 }
920
921 if (dh)
922 SSL_CTX_set_tmp_dh(sslContext, dh);
923 }
924
a7ad6e4e 925 if (fl & SSL_FLAG_DONT_VERIFY_DOMAIN)
62e76326 926 SSL_CTX_set_ex_data(sslContext, ssl_ctx_ex_index_dont_verify_domain, (void *) -1);
927
a7ad6e4e 928 return sslContext;
a7ad6e4e 929}
930
931SSL_CTX *
a82a4fe4 932sslCreateClientContext(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)
a7ad6e4e 933{
934 int ssl_error;
f1c9c850 935#if OPENSSL_VERSION_NUMBER < 0x00909000L
a7ad6e4e 936 SSL_METHOD *method;
f1c9c850
AJ
937#else
938 const SSL_METHOD *method;
939#endif
a7ad6e4e 940 SSL_CTX *sslContext;
941 long fl = ssl_parse_flags(flags);
942
943 ssl_initialize();
944
945 if (!keyfile)
62e76326 946 keyfile = certfile;
947
a7ad6e4e 948 if (!certfile)
62e76326 949 certfile = keyfile;
a7ad6e4e 950
a7ad6e4e 951 switch (version) {
62e76326 952
a7ad6e4e 953 case 2:
50b4c080 954#ifndef OPENSSL_NO_SSL2
bf8fe701 955 debugs(83, 5, "Using SSLv2.");
62e76326 956 method = SSLv2_client_method();
50b4c080 957#else
48e7baac 958 debugs(83, DBG_IMPORTANT, "SSLv2 is not available in this Proxy.");
50b4c080
AJ
959 return NULL;
960#endif
62e76326 961 break;
962
a7ad6e4e 963 case 3:
bf8fe701 964 debugs(83, 5, "Using SSLv3.");
62e76326 965 method = SSLv3_client_method();
966 break;
967
a7ad6e4e 968 case 4:
bf8fe701 969 debugs(83, 5, "Using TLSv1.");
62e76326 970 method = TLSv1_client_method();
971 break;
972
3d96b0e8
AJ
973 case 5:
974#if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
975 debugs(83, 5, "Using TLSv1.1.");
976 method = TLSv1_1_client_method();
977#else
978 debugs(83, DBG_IMPORTANT, "TLSv1.1 is not available in this Proxy.");
979 return NULL;
980#endif
981 break;
982
983 case 6:
984#if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
985 debugs(83, 5, "Using TLSv1.2");
986 method = TLSv1_2_client_method();
987#else
988 debugs(83, DBG_IMPORTANT, "TLSv1.2 is not available in this Proxy.");
989 return NULL;
990#endif
991 break;
992
a7ad6e4e 993 case 1:
62e76326 994
a7ad6e4e 995 default:
bf8fe701 996 debugs(83, 5, "Using SSLv2/SSLv3.");
62e76326 997 method = SSLv23_client_method();
998 break;
a7ad6e4e 999 }
1000
1001 sslContext = SSL_CTX_new(method);
62e76326 1002
a7ad6e4e 1003 if (sslContext == NULL) {
62e76326 1004 ssl_error = ERR_get_error();
1005 fatalf("Failed to allocate SSL context: %s\n",
1006 ERR_error_string(ssl_error, NULL));
a7ad6e4e 1007 }
62e76326 1008
a7ad6e4e 1009 SSL_CTX_set_options(sslContext, ssl_parse_options(options));
1010
1011 if (cipher) {
bf8fe701 1012 debugs(83, 5, "Using chiper suite " << cipher << ".");
62e76326 1013
1014 if (!SSL_CTX_set_cipher_list(sslContext, cipher)) {
1015 ssl_error = ERR_get_error();
1016 fatalf("Failed to set SSL cipher suite '%s': %s\n",
1017 cipher, ERR_error_string(ssl_error, NULL));
1018 }
a7ad6e4e 1019 }
62e76326 1020
a7ad6e4e 1021 if (certfile) {
e0236918 1022 debugs(83, DBG_IMPORTANT, "Using certificate in " << certfile);
62e76326 1023
1024 if (!SSL_CTX_use_certificate_chain_file(sslContext, certfile)) {
1025 ssl_error = ERR_get_error();
1026 fatalf("Failed to acquire SSL certificate '%s': %s\n",
1027 certfile, ERR_error_string(ssl_error, NULL));
1028 }
1029
e0236918 1030 debugs(83, DBG_IMPORTANT, "Using private key in " << keyfile);
307b83b7 1031 ssl_ask_password(sslContext, keyfile);
62e76326 1032
1033 if (!SSL_CTX_use_PrivateKey_file(sslContext, keyfile, SSL_FILETYPE_PEM)) {
1034 ssl_error = ERR_get_error();
1035 fatalf("Failed to acquire SSL private key '%s': %s\n",
1036 keyfile, ERR_error_string(ssl_error, NULL));
1037 }
1038
bf8fe701 1039 debugs(83, 5, "Comparing private and public SSL keys.");
62e76326 1040
1041 if (!SSL_CTX_check_private_key(sslContext)) {
1042 ssl_error = ERR_get_error();
1043 fatalf("SSL private key '%s' does not match public key '%s': %s\n",
1044 certfile, keyfile, ERR_error_string(ssl_error, NULL));
1045 }
a7ad6e4e 1046 }
62e76326 1047
bf8fe701 1048 debugs(83, 9, "Setting RSA key generation callback.");
f484cdf5 1049 SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb);
1050
a7ad6e4e 1051 if (fl & SSL_FLAG_DONT_VERIFY_PEER) {
48e7baac 1052 debugs(83, 2, "NOTICE: Peer certificates are not verified for validity!");
62e76326 1053 SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
a7ad6e4e 1054 } else {
bf8fe701 1055 debugs(83, 9, "Setting certificate verification callback.");
62e76326 1056 SSL_CTX_set_verify(sslContext, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
a7ad6e4e 1057 }
f484cdf5 1058
bf8fe701 1059 debugs(83, 9, "Setting CA certificate locations.");
62e76326 1060
a82a4fe4 1061 if ((CAfile || CApath) && !SSL_CTX_load_verify_locations(sslContext, CAfile, CApath)) {
1062 ssl_error = ERR_get_error();
48e7baac 1063 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate locations: " << ERR_error_string(ssl_error, NULL));
a82a4fe4 1064 }
1065
1066 if (CRLfile) {
1067 ssl_load_crl(sslContext, CRLfile);
1068 fl |= SSL_FLAG_VERIFY_CRL;
1069 }
1070
32d002cb 1071#if X509_V_FLAG_CRL_CHECK
a82a4fe4 1072 if (fl & SSL_FLAG_VERIFY_CRL_ALL)
1073 X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1074 else if (fl & SSL_FLAG_VERIFY_CRL)
1075 X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK);
1076
1077#endif
62e76326 1078
a7ad6e4e 1079 if (!(fl & SSL_FLAG_NO_DEFAULT_CA) &&
62e76326 1080 !SSL_CTX_set_default_verify_paths(sslContext)) {
1081 ssl_error = ERR_get_error();
48e7baac 1082 debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default CA certificate location: " << ERR_error_string(ssl_error, NULL));
f484cdf5 1083 }
62e76326 1084
d193a436 1085 return sslContext;
f484cdf5 1086}
1087
63be0a78 1088/// \ingroup ServerProtocolSSLInternal
d193a436 1089int
e6ccf245 1090ssl_read_method(int fd, char *buf, int len)
f484cdf5 1091{
6de9e64b 1092 SSL *ssl = fd_table[fd].ssl;
79d4ccdf 1093 int i;
1094
6de9e64b 1095#if DONT_DO_THIS
1096
1097 if (!SSL_is_init_finished(ssl)) {
1098 errno = ENOTCONN;
1099 return -1;
1100 }
79d4ccdf 1101
6de9e64b 1102#endif
1103
1104 i = SSL_read(ssl, buf, len);
1105
1106 if (i > 0 && SSL_pending(ssl) > 0) {
bf8fe701 1107 debugs(83, 2, "SSL FD " << fd << " is pending");
62e76326 1108 fd_table[fd].flags.read_pending = 1;
79d4ccdf 1109 } else
62e76326 1110 fd_table[fd].flags.read_pending = 0;
79d4ccdf 1111
1112 return i;
f484cdf5 1113}
1114
63be0a78 1115/// \ingroup ServerProtocolSSLInternal
d193a436 1116int
e6ccf245 1117ssl_write_method(int fd, const char *buf, int len)
f484cdf5 1118{
6de9e64b 1119 SSL *ssl = fd_table[fd].ssl;
1120 int i;
1121
1122 if (!SSL_is_init_finished(ssl)) {
1123 errno = ENOTCONN;
1124 return -1;
1125 }
1126
1127 i = SSL_write(ssl, buf, len);
1128
1129 return i;
f484cdf5 1130}
79d4ccdf 1131
1132void
575d05c4 1133ssl_shutdown_method(SSL *ssl)
79d4ccdf 1134{
79d4ccdf 1135 SSL_shutdown(ssl);
1136}
a7ad6e4e 1137
63be0a78 1138/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 1139static const char *
1140ssl_get_attribute(X509_NAME * name, const char *attribute_name)
1141{
1142 static char buffer[1024];
1143 int nid;
1144
1145 buffer[0] = '\0';
1146
1147 if (strcmp(attribute_name, "DN") == 0) {
62e76326 1148 X509_NAME_oneline(name, buffer, sizeof(buffer));
1149 goto done;
a7ad6e4e 1150 }
62e76326 1151
a7ad6e4e 1152 nid = OBJ_txt2nid((char *) attribute_name);
62e76326 1153
a7ad6e4e 1154 if (nid == 0) {
e0236918 1155 debugs(83, DBG_IMPORTANT, "WARNING: Unknown SSL attribute name '" << attribute_name << "'");
62e76326 1156 return NULL;
a7ad6e4e 1157 }
62e76326 1158
a7ad6e4e 1159 X509_NAME_get_text_by_NID(name, nid, buffer, sizeof(buffer));
62e76326 1160
1161done:
a7ad6e4e 1162 return *buffer ? buffer : NULL;
1163}
1164
63be0a78 1165/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 1166const char *
1167sslGetUserAttribute(SSL * ssl, const char *attribute_name)
1168{
1169 X509 *cert;
1170 X509_NAME *name;
23e6c4ae 1171 const char *ret;
a7ad6e4e 1172
1173 if (!ssl)
62e76326 1174 return NULL;
a7ad6e4e 1175
1176 cert = SSL_get_peer_certificate(ssl);
62e76326 1177
a7ad6e4e 1178 if (!cert)
62e76326 1179 return NULL;
a7ad6e4e 1180
5a4684b6 1181 name = X509_get_subject_name(cert);
a7ad6e4e 1182
23e6c4ae 1183 ret = ssl_get_attribute(name, attribute_name);
1184
1185 X509_free(cert);
1186
23e6c4ae 1187 return ret;
a7ad6e4e 1188}
1189
63be0a78 1190/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 1191const char *
1192sslGetCAAttribute(SSL * ssl, const char *attribute_name)
1193{
1194 X509 *cert;
1195 X509_NAME *name;
23e6c4ae 1196 const char *ret;
a7ad6e4e 1197
1198 if (!ssl)
62e76326 1199 return NULL;
a7ad6e4e 1200
1201 cert = SSL_get_peer_certificate(ssl);
62e76326 1202
a7ad6e4e 1203 if (!cert)
62e76326 1204 return NULL;
a7ad6e4e 1205
5a4684b6 1206 name = X509_get_issuer_name(cert);
a7ad6e4e 1207
23e6c4ae 1208 ret = ssl_get_attribute(name, attribute_name);
1209
1210 X509_free(cert);
1211
23e6c4ae 1212 return ret;
a7ad6e4e 1213}
1214
a7ad6e4e 1215const char *
1216sslGetUserEmail(SSL * ssl)
1217{
e6ceef10 1218 return sslGetUserAttribute(ssl, "emailAddress");
a7ad6e4e 1219}
4ac9968f 1220
1221const char *
1222sslGetUserCertificatePEM(SSL *ssl)
1223{
1224 X509 *cert;
1225 BIO *mem;
1226 static char *str = NULL;
1227 char *ptr;
1228 long len;
1229
1230 safe_free(str);
1231
1232 if (!ssl)
1233 return NULL;
1234
1235 cert = SSL_get_peer_certificate(ssl);
1236
1237 if (!cert)
1238 return NULL;
1239
1240 mem = BIO_new(BIO_s_mem());
1241
1242 PEM_write_bio_X509(mem, cert);
1243
1244
1245 len = BIO_get_mem_data(mem, &ptr);
1246
1247 str = (char *)xmalloc(len + 1);
1248
1249 memcpy(str, ptr, len);
1250
1251 str[len] = '\0';
1252
1253 X509_free(cert);
1254
1255 BIO_free(mem);
1256
1257 return str;
1258}
3d61c476 1259
1260const char *
1261sslGetUserCertificateChainPEM(SSL *ssl)
1262{
1263 STACK_OF(X509) *chain;
1264 BIO *mem;
1265 static char *str = NULL;
1266 char *ptr;
1267 long len;
1268 int i;
1269
1270 safe_free(str);
1271
1272 if (!ssl)
1273 return NULL;
1274
1275 chain = SSL_get_peer_cert_chain(ssl);
1276
1277 if (!chain)
1278 return sslGetUserCertificatePEM(ssl);
1279
1280 mem = BIO_new(BIO_s_mem());
1281
d7ae3534 1282 for (i = 0; i < sk_X509_num(chain); ++i) {
3d61c476 1283 X509 *cert = sk_X509_value(chain, i);
1284 PEM_write_bio_X509(mem, cert);
1285 }
1286
1287 len = BIO_get_mem_data(mem, &ptr);
1288
1289 str = (char *)xmalloc(len + 1);
1290 memcpy(str, ptr, len);
1291 str[len] = '\0';
1292
1293 BIO_free(mem);
1294
1295 return str;
1296}
454e8283 1297
95d2589c
CT
1298/// \ingroup ServerProtocolSSLInternal
1299/// Create SSL context and apply ssl certificate and private key to it.
1300static SSL_CTX * createSSLContext(Ssl::X509_Pointer & x509, Ssl::EVP_PKEY_Pointer & pkey)
1301{
1302 Ssl::SSL_CTX_Pointer sslContext(SSL_CTX_new(SSLv23_server_method()));
1303
1304 if (!SSL_CTX_use_certificate(sslContext.get(), x509.get()))
1305 return NULL;
1306
1307 if (!SSL_CTX_use_PrivateKey(sslContext.get(), pkey.get()))
1308 return NULL;
1309 return sslContext.release();
1310}
1311
1312SSL_CTX * Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data)
1313{
1314 Ssl::X509_Pointer cert;
1315 Ssl::EVP_PKEY_Pointer pkey;
1316 if (!readCertAndPrivateKeyFromMemory(cert, pkey, data))
1317 return NULL;
1318
1319 if (!cert || !pkey)
1320 return NULL;
1321
1322 return createSSLContext(cert, pkey);
1323}
1324
aebe6888 1325SSL_CTX * Ssl::generateSslContext(CertificateProperties const &properties)
95d2589c
CT
1326{
1327 Ssl::X509_Pointer cert;
1328 Ssl::EVP_PKEY_Pointer pkey;
aebe6888 1329 if (!generateSslCertificate(cert, pkey, properties))
95d2589c 1330 return NULL;
9a90aace 1331
95d2589c
CT
1332 if (!cert)
1333 return NULL;
1334
1335 if (!pkey)
1336 return NULL;
1337
1338 return createSSLContext(cert, pkey);
1339}
1340
4ece76b2 1341bool Ssl::verifySslCertificate(SSL_CTX * sslContext, CertificateProperties const &properties)
95d2589c
CT
1342{
1343 // Temporary ssl for getting X509 certificate from SSL_CTX.
1344 Ssl::SSL_Pointer ssl(SSL_new(sslContext));
1345 X509 * cert = SSL_get_certificate(ssl.get());
1346 ASN1_TIME * time_notBefore = X509_get_notBefore(cert);
1347 ASN1_TIME * time_notAfter = X509_get_notAfter(cert);
1348 bool ret = (X509_cmp_current_time(time_notBefore) < 0 && X509_cmp_current_time(time_notAfter) > 0);
e7bcc25f
CT
1349 if (!ret)
1350 return false;
1351
4ece76b2 1352 return certificateMatchesProperties(cert, properties);
95d2589c
CT
1353}
1354
253749a8
CT
1355bool
1356Ssl::setClientSNI(SSL *ssl, const char *fqdn)
1357{
1358 //The SSL_CTRL_SET_TLSEXT_HOSTNAME is a openssl macro which indicates
1359 // if the TLS servername extension (SNI) is enabled in openssl library.
1360#if defined(SSL_CTRL_SET_TLSEXT_HOSTNAME)
1361 if (!SSL_set_tlsext_host_name(ssl, fqdn)) {
1362 const int ssl_error = ERR_get_error();
1363 debugs(83, 3, "WARNING: unable to set TLS servername extension (SNI): " <<
1364 ERR_error_string(ssl_error, NULL) << "\n");
1365 return false;
1366 }
1367 return true;
1368#else
1369 debugs(83, 7, "no support for TLS servername extension (SNI)\n");
1370 return false;
1371#endif
1372}
1373
a594dbfa
CT
1374void Ssl::addChainToSslContext(SSL_CTX *sslContext, STACK_OF(X509) *chain)
1375{
1376 if (!chain)
1377 return;
1378
d7ae3534 1379 for (int i = 0; i < sk_X509_num(chain); ++i) {
a594dbfa
CT
1380 X509 *cert = sk_X509_value(chain, i);
1381 if (SSL_CTX_add_extra_chain_cert(sslContext, cert)) {
1382 // increase the certificate lock
1383 CRYPTO_add(&(cert->references),1,CRYPTO_LOCK_X509);
1384 } else {
1385 const int ssl_error = ERR_get_error();
1386 debugs(83, DBG_IMPORTANT, "WARNING: can not add certificate to SSL context chain: " << ERR_error_string(ssl_error, NULL));
1387 }
1388 }
1389}
1390
1391/**
1392 \ingroup ServerProtocolSSLInternal
1393 * Read certificate from file.
1394 * See also: static readSslX509Certificate function, gadgets.cc file
1395 */
1396static X509 * readSslX509CertificatesChain(char const * certFilename, STACK_OF(X509)* chain)
1397{
1398 if (!certFilename)
1399 return NULL;
1400 Ssl::BIO_Pointer bio(BIO_new(BIO_s_file_internal()));
1401 if (!bio)
1402 return NULL;
1403 if (!BIO_read_filename(bio.get(), certFilename))
1404 return NULL;
1405 X509 *certificate = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL);
1406
1407 if (certificate && chain) {
1408
c11211d9 1409 if (X509_check_issued(certificate, certificate) == X509_V_OK)
a594dbfa
CT
1410 debugs(83, 5, "Certificate is self-signed, will not be chained");
1411 else {
c11211d9 1412 if (sk_X509_push(chain, certificate))
a594dbfa
CT
1413 CRYPTO_add(&(certificate->references), 1, CRYPTO_LOCK_X509);
1414 else
1415 debugs(83, DBG_IMPORTANT, "WARNING: unable to add signing certificate to cert chain");
1416 // and add to the chain any certificate loaded from the file
1417 while (X509 *ca = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL)) {
1418 if (!sk_X509_push(chain, ca))
1419 debugs(83, DBG_IMPORTANT, "WARNING: unable to add CA certificate to cert chain");
1420 }
1421 }
1422 }
c11211d9 1423
a594dbfa
CT
1424 return certificate;
1425}
1426
1427void Ssl::readCertChainAndPrivateKeyFromFiles(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename)
1428{
1429 if (keyFilename == NULL)
1430 keyFilename = certFilename;
1431 if (!chain)
1432 chain.reset(sk_X509_new_null());
1433 if (!chain)
1434 debugs(83, DBG_IMPORTANT, "WARNING: unable to allocate memory for cert chain");
3227b302 1435 pkey.reset(readSslPrivateKey(keyFilename, ssl_ask_password_cb));
a594dbfa
CT
1436 cert.reset(readSslX509CertificatesChain(certFilename, chain.get()));
1437 if (!pkey || !cert || !X509_check_private_key(cert.get(), pkey.get())) {
1438 pkey.reset(NULL);
1439 cert.reset(NULL);
1440 }
1441}
1442
95588170
CT
1443bool Ssl::generateUntrustedCert(X509_Pointer &untrustedCert, EVP_PKEY_Pointer &untrustedPkey, X509_Pointer const &cert, EVP_PKEY_Pointer const & pkey)
1444{
1445 // Generate the self-signed certificate, using a hard-coded subject prefix
1446 Ssl::CertificateProperties certProperties;
1447 if (const char *cn = CommonHostName(cert.get())) {
1448 certProperties.commonName = "Not trusted by \"";
1449 certProperties.commonName += cn;
1450 certProperties.commonName += "\"";
87f237a9 1451 } else if (const char *org = getOrganization(cert.get())) {
95588170
CT
1452 certProperties.commonName = "Not trusted by \"";
1453 certProperties.commonName += org;
1454 certProperties.commonName += "\"";
87f237a9 1455 } else
95588170
CT
1456 certProperties.commonName = "Not trusted";
1457 certProperties.setCommonName = true;
1458 // O, OU, and other CA subject fields will be mimicked
1459 // Expiration date and other common properties will be mimicked
1460 certProperties.signAlgorithm = Ssl::algSignSelf;
1461 certProperties.signWithPkey.resetAndLock(pkey.get());
1462 certProperties.mimicCert.resetAndLock(cert.get());
1463 return Ssl::generateSslCertificate(untrustedCert, untrustedPkey, certProperties);
1464}
1465
454e8283 1466#endif /* USE_SSL */