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