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