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