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