6 * DEBUG: section 83 SSL accelerator support
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * ----------------------------------------------------------
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.
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.
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.
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.
36 #include "squid-old.h"
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.
44 #include "acl/FilledChecklist.h"
45 #include "ssl/ErrorDetail.h"
46 #include "ssl/support.h"
47 #include "ssl/gadgets.h"
50 \defgroup ServerProtocolSSLInternal Server-Side SSL Internals
51 \ingroup ServerProtocolSSLAPI
54 /// \ingroup ServerProtocolSSLInternal
56 ssl_ask_password_cb(char *buf
, int size
, int rwflag
, void *userdata
)
62 snprintf(cmdline
, sizeof(cmdline
), "\"%s\" \"%s\"", Config
.Program
.ssl_password
, (const char *)userdata
);
63 in
= popen(cmdline
, "r");
65 if (fgets(buf
, size
, in
))
69 while (len
> 0 && (buf
[len
- 1] == '\n' || buf
[len
- 1] == '\r'))
80 /// \ingroup ServerProtocolSSLInternal
82 ssl_ask_password(SSL_CTX
* context
, const char * prompt
)
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
);
90 /// \ingroup ServerProtocolSSLInternal
92 ssl_temp_rsa_cb(SSL
* ssl
, int anInt
, int keylen
)
94 static RSA
*rsa_512
= NULL
;
95 static RSA
*rsa_1024
= NULL
;
104 rsa_512
= RSA_generate_key(512, RSA_F4
, NULL
, NULL
);
114 rsa_1024
= RSA_generate_key(1024, RSA_F4
, NULL
, NULL
);
122 debugs(83, 1, "ssl_temp_rsa_cb: Unexpected key length " << keylen
);
127 debugs(83, 1, "ssl_temp_rsa_cb: Failed to generate key " << keylen
);
133 PEM_write_RSAPrivateKey(debug_log
, rsa
, NULL
, NULL
, 0, NULL
, NULL
);
135 debugs(83, 1, "Generated ephemeral RSA key of length " << keylen
);
141 int Ssl::asn1timeToString(ASN1_TIME
*tm
, char *buf
, int len
)
145 bio
= BIO_new(BIO_s_mem());
147 if (ASN1_TIME_print(bio
, tm
))
148 write
= BIO_read(bio
, buf
, len
-1);
155 int Ssl::matchX509CommonNames(X509
*peer_cert
, void *check_data
, int (*check_func
)(void *check_data
, ASN1_STRING
*cn_data
))
159 X509_NAME
*name
= X509_get_subject_name(peer_cert
);
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
)) {
163 ASN1_STRING
*cn_data
= X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name
, i
));
165 if ( (*check_func
)(check_data
, cn_data
) == 0)
169 STACK_OF(GENERAL_NAME
) * altnames
;
170 altnames
= (STACK_OF(GENERAL_NAME
)*)X509_get_ext_d2i(peer_cert
, NID_subject_alt_name
, NULL
, NULL
);
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
) {
179 ASN1_STRING
*cn_data
= check
->d
.dNSName
;
181 if ( (*check_func
)(check_data
, cn_data
) == 0)
184 sk_GENERAL_NAME_pop_free(altnames
, GENERAL_NAME_free
);
189 static int check_domain( void *check_data
, ASN1_STRING
*cn_data
)
192 const char *server
= (const char *)check_data
;
194 if (cn_data
->length
> (int)sizeof(cn
) - 1) {
195 return 1; //if does not fit our buffer just ignore
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
);
203 bool Ssl::checkX509ServerValidity(X509
*cert
, const char *server
)
205 return matchX509CommonNames(cert
, (void *)server
, check_domain
);
208 /// \ingroup ServerProtocolSSLInternal
210 ssl_verify_cb(int ok
, X509_STORE_CTX
* ctx
)
212 // preserve original ctx->error before SSL_ calls can overwrite it
213 Ssl::ssl_error_t error_no
= ok
? SSL_ERROR_NONE
: ctx
->error
;
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
;
224 X509_NAME_oneline(X509_get_subject_name(peer_cert
), buffer
,
228 debugs(83, 5, "SSL Certificate signature OK: " << buffer
);
231 if (!Ssl::checkX509ServerValidity(peer_cert
, server
)) {
232 debugs(83, 2, "SQUID_X509_V_ERR_DOMAIN_MISMATCH: Certificate " << buffer
<< " does not match domainname " << server
);
234 error_no
= SQUID_X509_V_ERR_DOMAIN_MISMATCH
;
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");
244 error_no
= SQUID_X509_V_ERR_CERT_CHANGE
;
249 Ssl::Errors
*errNoList
= static_cast<Ssl::Errors
*>(SSL_get_ex_data(ssl
, ssl_ex_index_ssl_error_sslerrno
));
251 errNoList
= new Ssl::Errors(error_no
);
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
);
258 else // Append the err no to the SSL errors lists.
259 errNoList
->push_back_unique(error_no
);
261 if (const char *err_descr
= Ssl::GetErrorDescr(error_no
))
262 debugs(83, 5, err_descr
<< ": " << buffer
);
264 debugs(83, DBG_IMPORTANT
, "SSL unknown certificate error " << error_no
<< " in " << buffer
);
267 ACLFilledChecklist
*filledCheck
= Filled(check
);
268 assert(filledCheck
->sslErrorList
== NULL
);
269 filledCheck
->sslErrorList
= new Ssl::Errors(error_no
);
270 if (check
->fastCheck() == ACCESS_ALLOWED
) {
271 debugs(83, 3, "bypassing SSL error " << error_no
<< " in " << buffer
);
274 debugs(83, 5, "confirming SSL error " << error_no
);
276 // Delete the ssl error list
277 delete filledCheck
->sslErrorList
;
278 filledCheck
->sslErrorList
= NULL
;
282 if (!dont_verify_domain
&& server
) {}
284 if (!ok
&& !SSL_get_ex_data(ssl
, ssl_ex_index_ssl_error_detail
) ) {
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
;
294 Ssl::ErrorDetail
*errDetail
=
295 new Ssl::ErrorDetail(error_no
, peer_cert
, broken_cert
);
297 if (!SSL_set_ex_data(ssl
, ssl_ex_index_ssl_error_detail
, errDetail
)) {
298 debugs(83, 2, "Failed to set Ssl::ErrorDetail in ssl_verify_cb: Certificate " << buffer
);
306 /// \ingroup ServerProtocolSSLInternal
307 static struct ssl_option
{
314 #if SSL_OP_MICROSOFT_SESS_ID_BUG
316 "MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG
319 #if SSL_OP_NETSCAPE_CHALLENGE_BUG
321 "NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG
324 #if SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
326 "NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
329 #if SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
331 "SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
334 #if SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
336 "MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
339 #if SSL_OP_MSIE_SSLV2_RSA_PADDING
341 "MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING
344 #if SSL_OP_SSLEAY_080_CLIENT_DH_BUG
346 "SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG
349 #if SSL_OP_TLS_D5_BUG
351 "TLS_D5_BUG", SSL_OP_TLS_D5_BUG
354 #if SSL_OP_TLS_BLOCK_PADDING_BUG
356 "TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG
359 #if SSL_OP_TLS_ROLLBACK_BUG
361 "TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG
366 "ALL", (long)SSL_OP_ALL
369 #if SSL_OP_SINGLE_DH_USE
371 "SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE
374 #if SSL_OP_EPHEMERAL_RSA
376 "EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA
379 #if SSL_OP_PKCS1_CHECK_1
381 "PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1
384 #if SSL_OP_PKCS1_CHECK_2
386 "PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2
389 #if SSL_OP_NETSCAPE_CA_DN_BUG
391 "NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG
394 #if SSL_OP_NON_EXPORT_FIRST
396 "NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST
399 #if SSL_OP_CIPHER_SERVER_PREFERENCE
401 "CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE
404 #if SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
406 "NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
411 "NO_SSLv2", SSL_OP_NO_SSLv2
416 "NO_SSLv3", SSL_OP_NO_SSLv3
421 "NO_TLSv1", SSL_OP_NO_TLSv1
432 /// \ingroup ServerProtocolSSLInternal
434 ssl_parse_options(const char *options
)
443 tmp
= xstrdup(options
);
445 option
= strtok(tmp
, ":,");
449 struct ssl_option
*opt
= NULL
, *opttmp
;
452 MODE_ADD
, MODE_REMOVE
474 for (opttmp
= ssl_options
; opttmp
->name
; opttmp
++) {
475 if (strcmp(opttmp
->name
, option
) == 0) {
483 else if (strncmp(option
, "0x", 2) == 0) {
484 /* Special case.. hex specification */
485 value
= strtol(option
+ 2, NULL
, 16);
487 fatalf("Unknown SSL option '%s'", option
);
488 value
= 0; /* Keep GCC happy */
502 option
= strtok(NULL
, ":,");
511 /// \ingroup ServerProtocolSSLInternal
512 #define SSL_FLAG_NO_DEFAULT_CA (1<<0)
513 /// \ingroup ServerProtocolSSLInternal
514 #define SSL_FLAG_DELAYED_AUTH (1<<1)
515 /// \ingroup ServerProtocolSSLInternal
516 #define SSL_FLAG_DONT_VERIFY_PEER (1<<2)
517 /// \ingroup ServerProtocolSSLInternal
518 #define SSL_FLAG_DONT_VERIFY_DOMAIN (1<<3)
519 /// \ingroup ServerProtocolSSLInternal
520 #define SSL_FLAG_NO_SESSION_REUSE (1<<4)
521 /// \ingroup ServerProtocolSSLInternal
522 #define SSL_FLAG_VERIFY_CRL (1<<5)
523 /// \ingroup ServerProtocolSSLInternal
524 #define SSL_FLAG_VERIFY_CRL_ALL (1<<6)
526 /// \ingroup ServerProtocolSSLInternal
528 ssl_parse_flags(const char *flags
)
537 tmp
= xstrdup(flags
);
539 flag
= strtok(tmp
, ":,");
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
;
550 else if (strcmp(flag
, "NO_SESSION_REUSE") == 0)
551 fl
|= SSL_FLAG_NO_SESSION_REUSE
;
553 #if X509_V_FLAG_CRL_CHECK
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
;
563 fatalf("Unknown ssl flag '%s'", flag
);
565 flag
= strtok(NULL
, ":,");
572 // "dup" function for SSL_get_ex_new_index("cert_err_check")
574 ssl_dupAclChecklist(CRYPTO_EX_DATA
*, CRYPTO_EX_DATA
*, void *,
577 // We do not support duplication of ACLCheckLists.
578 // If duplication is needed, we can count copies with cbdata.
583 // "free" function for SSL_get_ex_new_index("cert_err_check")
585 ssl_freeAclChecklist(void *, void *ptr
, CRYPTO_EX_DATA
*,
588 delete static_cast<ACLChecklist
*>(ptr
); // may be NULL
591 // "free" function for SSL_get_ex_new_index("ssl_error_detail")
593 ssl_free_ErrorDetail(void *, void *ptr
, CRYPTO_EX_DATA
*,
596 Ssl::ErrorDetail
*errDetail
= static_cast <Ssl::ErrorDetail
*>(ptr
);
601 ssl_free_SslErrNoList(void *, void *ptr
, CRYPTO_EX_DATA
*,
604 Ssl::Errors
*errNo
= static_cast <Ssl::Errors
*>(ptr
);
608 // "free" function for X509 certificates
610 ssl_free_X509(void *, void *ptr
, CRYPTO_EX_DATA
*,
613 X509
*cert
= static_cast <X509
*>(ptr
);
617 /// \ingroup ServerProtocolSSLInternal
621 static int ssl_initialized
= 0;
623 if (!ssl_initialized
) {
625 SSL_load_error_strings();
626 SSLeay_add_ssl_algorithms();
627 #if HAVE_OPENSSL_ENGINE_H
629 if (Config
.SSL
.ssl_engine
) {
632 if (!(e
= ENGINE_by_id(Config
.SSL
.ssl_engine
))) {
633 fatalf("Unable to find SSL engine '%s'\n", Config
.SSL
.ssl_engine
);
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
));
644 if (Config
.SSL
.ssl_engine
) {
645 fatalf("Your OpenSSL has no SSL engine support\n");
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
);
654 ssl_ex_index_cert_error_check
= SSL_get_ex_new_index(0, (void *) "cert_error_check", NULL
, &ssl_dupAclChecklist
, &ssl_freeAclChecklist
);
655 ssl_ex_index_ssl_error_detail
= SSL_get_ex_new_index(0, (void *) "ssl_error_detail", NULL
, NULL
, &ssl_free_ErrorDetail
);
656 ssl_ex_index_ssl_peeked_cert
= SSL_get_ex_new_index(0, (void *) "ssl_peeked_cert", NULL
, NULL
, &ssl_free_X509
);
657 ssl_ex_index_ssl_error_sslerrno
= SSL_get_ex_new_index(0, (void *) "ssl_error_sslerrno", NULL
, NULL
, &ssl_free_SslErrNoList
);
660 /// \ingroup ServerProtocolSSLInternal
662 ssl_load_crl(SSL_CTX
*sslContext
, const char *CRLfile
)
664 X509_STORE
*st
= SSL_CTX_get_cert_store(sslContext
);
666 BIO
*in
= BIO_new_file(CRLfile
, "r");
670 debugs(83, 2, "WARNING: Failed to open CRL file '" << CRLfile
<< "'");
674 while ((crl
= PEM_read_bio_X509_CRL(in
,NULL
,NULL
,NULL
))) {
675 if (!X509_STORE_add_crl(st
, crl
))
676 debugs(83, 2, "WARNING: Failed to add CRL from file '" << CRLfile
<< "'");
688 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
)
691 #if OPENSSL_VERSION_NUMBER < 0x00909000L
694 const SSL_METHOD
*method
;
697 long fl
= ssl_parse_flags(flags
);
711 debugs(83, DBG_CRITICAL
, "ERROR: No certificate file");
718 #ifndef OPENSSL_NO_SSL2
719 debugs(83, 5, "Using SSLv2.");
720 method
= SSLv2_server_method();
722 debugs(83, DBG_IMPORTANT
, "SSLv2 is not available in this Proxy.");
728 debugs(83, 5, "Using SSLv3.");
729 method
= SSLv3_server_method();
733 debugs(83, 5, "Using TLSv1.");
734 method
= TLSv1_server_method();
740 debugs(83, 5, "Using SSLv2/SSLv3.");
741 method
= SSLv23_server_method();
745 sslContext
= SSL_CTX_new(method
);
747 if (sslContext
== NULL
) {
748 ssl_error
= ERR_get_error();
749 debugs(83, DBG_CRITICAL
, "ERROR: Failed to allocate SSL context: " << ERR_error_string(ssl_error
, NULL
));
753 SSL_CTX_set_options(sslContext
, ssl_parse_options(options
));
755 if (context
&& *context
) {
756 SSL_CTX_set_session_id_context(sslContext
, (const unsigned char *)context
, strlen(context
));
759 if (fl
& SSL_FLAG_NO_SESSION_REUSE
) {
760 SSL_CTX_set_session_cache_mode(sslContext
, SSL_SESS_CACHE_OFF
);
763 if (Config
.SSL
.unclean_shutdown
) {
764 debugs(83, 5, "Enabling quiet SSL shutdowns (RFC violation).");
766 SSL_CTX_set_quiet_shutdown(sslContext
, 1);
770 debugs(83, 5, "Using chiper suite " << cipher
<< ".");
772 if (!SSL_CTX_set_cipher_list(sslContext
, cipher
)) {
773 ssl_error
= ERR_get_error();
774 debugs(83, DBG_CRITICAL
, "ERROR: Failed to set SSL cipher suite '" << cipher
<< "': " << ERR_error_string(ssl_error
, NULL
));
775 SSL_CTX_free(sslContext
);
780 debugs(83, DBG_IMPORTANT
, "Using certificate in " << certfile
);
782 if (!SSL_CTX_use_certificate_chain_file(sslContext
, certfile
)) {
783 ssl_error
= ERR_get_error();
784 debugs(83, DBG_CRITICAL
, "ERROR: Failed to acquire SSL certificate '" << certfile
<< "': " << ERR_error_string(ssl_error
, NULL
));
785 SSL_CTX_free(sslContext
);
789 debugs(83, DBG_IMPORTANT
, "Using private key in " << keyfile
);
790 ssl_ask_password(sslContext
, keyfile
);
792 if (!SSL_CTX_use_PrivateKey_file(sslContext
, keyfile
, SSL_FILETYPE_PEM
)) {
793 ssl_error
= ERR_get_error();
794 debugs(83, DBG_CRITICAL
, "ERROR: Failed to acquire SSL private key '" << keyfile
<< "': " << ERR_error_string(ssl_error
, NULL
));
795 SSL_CTX_free(sslContext
);
799 debugs(83, 5, "Comparing private and public SSL keys.");
801 if (!SSL_CTX_check_private_key(sslContext
)) {
802 ssl_error
= ERR_get_error();
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
);
809 debugs(83, 9, "Setting RSA key generation callback.");
810 SSL_CTX_set_tmp_rsa_callback(sslContext
, ssl_temp_rsa_cb
);
812 debugs(83, 9, "Setting CA certificate locations.");
814 if ((CAfile
|| CApath
) && !SSL_CTX_load_verify_locations(sslContext
, CAfile
, CApath
)) {
815 ssl_error
= ERR_get_error();
816 debugs(83, DBG_IMPORTANT
, "WARNING: Ignoring error setting CA certificate locations: " << ERR_error_string(ssl_error
, NULL
));
819 if (!(fl
& SSL_FLAG_NO_DEFAULT_CA
) &&
820 !SSL_CTX_set_default_verify_paths(sslContext
)) {
821 ssl_error
= ERR_get_error();
822 debugs(83, DBG_IMPORTANT
, "WARNING: Ignoring error setting default CA certificate location: " << ERR_error_string(ssl_error
, NULL
));
826 STACK_OF(X509_NAME
) *cert_names
;
827 debugs(83, 9, "Set client certifying authority list.");
828 cert_names
= SSL_load_client_CA_file(clientCA
);
830 if (cert_names
== NULL
) {
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
);
837 SSL_CTX_set_client_CA_list(sslContext
, cert_names
);
839 if (fl
& SSL_FLAG_DELAYED_AUTH
) {
840 debugs(83, 9, "Not requesting client certificates until acl processing requires one");
841 SSL_CTX_set_verify(sslContext
, SSL_VERIFY_NONE
, NULL
);
843 debugs(83, 9, "Requiring client certificates.");
844 SSL_CTX_set_verify(sslContext
, SSL_VERIFY_PEER
| SSL_VERIFY_FAIL_IF_NO_PEER_CERT
, ssl_verify_cb
);
848 ssl_load_crl(sslContext
, CRLfile
);
849 fl
|= SSL_FLAG_VERIFY_CRL
;
852 #if X509_V_FLAG_CRL_CHECK
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
);
861 debugs(83, 9, "Not requiring any client certificates");
862 SSL_CTX_set_verify(sslContext
, SSL_VERIFY_NONE
, NULL
);
866 FILE *in
= fopen(dhfile
, "r");
871 dh
= PEM_read_DHparams(in
, NULL
, NULL
, NULL
);
876 debugs(83, DBG_IMPORTANT
, "WARNING: Failed to read DH parameters '" << dhfile
<< "'");
877 else if (dh
&& DH_check(dh
, &codes
) == 0) {
879 debugs(83, DBG_IMPORTANT
, "WARNING: Failed to verify DH parameters '" << dhfile
<< "' (" << std::hex
<< codes
<< ")");
886 SSL_CTX_set_tmp_dh(sslContext
, dh
);
889 if (fl
& SSL_FLAG_DONT_VERIFY_DOMAIN
)
890 SSL_CTX_set_ex_data(sslContext
, ssl_ctx_ex_index_dont_verify_domain
, (void *) -1);
896 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
)
899 #if OPENSSL_VERSION_NUMBER < 0x00909000L
902 const SSL_METHOD
*method
;
905 long fl
= ssl_parse_flags(flags
);
918 #ifndef OPENSSL_NO_SSL2
919 debugs(83, 5, "Using SSLv2.");
920 method
= SSLv2_client_method();
922 debugs(83, DBG_IMPORTANT
, "SSLv2 is not available in this Proxy.");
928 debugs(83, 5, "Using SSLv3.");
929 method
= SSLv3_client_method();
933 debugs(83, 5, "Using TLSv1.");
934 method
= TLSv1_client_method();
940 debugs(83, 5, "Using SSLv2/SSLv3.");
941 method
= SSLv23_client_method();
945 sslContext
= SSL_CTX_new(method
);
947 if (sslContext
== NULL
) {
948 ssl_error
= ERR_get_error();
949 fatalf("Failed to allocate SSL context: %s\n",
950 ERR_error_string(ssl_error
, NULL
));
953 SSL_CTX_set_options(sslContext
, ssl_parse_options(options
));
956 debugs(83, 5, "Using chiper suite " << cipher
<< ".");
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
));
966 debugs(83, 1, "Using certificate in " << certfile
);
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
));
974 debugs(83, 1, "Using private key in " << keyfile
);
975 ssl_ask_password(sslContext
, keyfile
);
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
));
983 debugs(83, 5, "Comparing private and public SSL keys.");
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
));
992 debugs(83, 9, "Setting RSA key generation callback.");
993 SSL_CTX_set_tmp_rsa_callback(sslContext
, ssl_temp_rsa_cb
);
995 if (fl
& SSL_FLAG_DONT_VERIFY_PEER
) {
996 debugs(83, 2, "NOTICE: Peer certificates are not verified for validity!");
997 SSL_CTX_set_verify(sslContext
, SSL_VERIFY_NONE
, NULL
);
999 debugs(83, 9, "Setting certificate verification callback.");
1000 SSL_CTX_set_verify(sslContext
, SSL_VERIFY_PEER
| SSL_VERIFY_FAIL_IF_NO_PEER_CERT
, ssl_verify_cb
);
1003 debugs(83, 9, "Setting CA certificate locations.");
1005 if ((CAfile
|| CApath
) && !SSL_CTX_load_verify_locations(sslContext
, CAfile
, CApath
)) {
1006 ssl_error
= ERR_get_error();
1007 debugs(83, DBG_IMPORTANT
, "WARNING: Ignoring error setting CA certificate locations: " << ERR_error_string(ssl_error
, NULL
));
1011 ssl_load_crl(sslContext
, CRLfile
);
1012 fl
|= SSL_FLAG_VERIFY_CRL
;
1015 #if X509_V_FLAG_CRL_CHECK
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
);
1023 if (!(fl
& SSL_FLAG_NO_DEFAULT_CA
) &&
1024 !SSL_CTX_set_default_verify_paths(sslContext
)) {
1025 ssl_error
= ERR_get_error();
1026 debugs(83, DBG_IMPORTANT
, "WARNING: Ignoring error setting default CA certificate location: " << ERR_error_string(ssl_error
, NULL
));
1032 /// \ingroup ServerProtocolSSLInternal
1034 ssl_read_method(int fd
, char *buf
, int len
)
1036 SSL
*ssl
= fd_table
[fd
].ssl
;
1041 if (!SSL_is_init_finished(ssl
)) {
1048 i
= SSL_read(ssl
, buf
, len
);
1050 if (i
> 0 && SSL_pending(ssl
) > 0) {
1051 debugs(83, 2, "SSL FD " << fd
<< " is pending");
1052 fd_table
[fd
].flags
.read_pending
= 1;
1054 fd_table
[fd
].flags
.read_pending
= 0;
1059 /// \ingroup ServerProtocolSSLInternal
1061 ssl_write_method(int fd
, const char *buf
, int len
)
1063 SSL
*ssl
= fd_table
[fd
].ssl
;
1066 if (!SSL_is_init_finished(ssl
)) {
1071 i
= SSL_write(ssl
, buf
, len
);
1077 ssl_shutdown_method(SSL
*ssl
)
1082 /// \ingroup ServerProtocolSSLInternal
1084 ssl_get_attribute(X509_NAME
* name
, const char *attribute_name
)
1086 static char buffer
[1024];
1091 if (strcmp(attribute_name
, "DN") == 0) {
1092 X509_NAME_oneline(name
, buffer
, sizeof(buffer
));
1096 nid
= OBJ_txt2nid((char *) attribute_name
);
1099 debugs(83, 1, "WARNING: Unknown SSL attribute name '" << attribute_name
<< "'");
1103 X509_NAME_get_text_by_NID(name
, nid
, buffer
, sizeof(buffer
));
1106 return *buffer
? buffer
: NULL
;
1109 /// \ingroup ServerProtocolSSLInternal
1111 sslGetUserAttribute(SSL
* ssl
, const char *attribute_name
)
1120 cert
= SSL_get_peer_certificate(ssl
);
1125 name
= X509_get_subject_name(cert
);
1127 ret
= ssl_get_attribute(name
, attribute_name
);
1134 /// \ingroup ServerProtocolSSLInternal
1136 sslGetCAAttribute(SSL
* ssl
, const char *attribute_name
)
1145 cert
= SSL_get_peer_certificate(ssl
);
1150 name
= X509_get_issuer_name(cert
);
1152 ret
= ssl_get_attribute(name
, attribute_name
);
1160 sslGetUserEmail(SSL
* ssl
)
1162 return sslGetUserAttribute(ssl
, "emailAddress");
1166 sslGetUserCertificatePEM(SSL
*ssl
)
1170 static char *str
= NULL
;
1179 cert
= SSL_get_peer_certificate(ssl
);
1184 mem
= BIO_new(BIO_s_mem());
1186 PEM_write_bio_X509(mem
, cert
);
1189 len
= BIO_get_mem_data(mem
, &ptr
);
1191 str
= (char *)xmalloc(len
+ 1);
1193 memcpy(str
, ptr
, len
);
1205 sslGetUserCertificateChainPEM(SSL
*ssl
)
1207 STACK_OF(X509
) *chain
;
1209 static char *str
= NULL
;
1219 chain
= SSL_get_peer_cert_chain(ssl
);
1222 return sslGetUserCertificatePEM(ssl
);
1224 mem
= BIO_new(BIO_s_mem());
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
);
1231 len
= BIO_get_mem_data(mem
, &ptr
);
1233 str
= (char *)xmalloc(len
+ 1);
1234 memcpy(str
, ptr
, len
);
1242 /// \ingroup ServerProtocolSSLInternal
1243 /// Create SSL context and apply ssl certificate and private key to it.
1244 static SSL_CTX
* createSSLContext(Ssl::X509_Pointer
& x509
, Ssl::EVP_PKEY_Pointer
& pkey
)
1246 Ssl::SSL_CTX_Pointer
sslContext(SSL_CTX_new(SSLv23_server_method()));
1248 if (!SSL_CTX_use_certificate(sslContext
.get(), x509
.get()))
1251 if (!SSL_CTX_use_PrivateKey(sslContext
.get(), pkey
.get()))
1253 return sslContext
.release();
1256 SSL_CTX
* Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data
)
1258 Ssl::X509_Pointer cert
;
1259 Ssl::EVP_PKEY_Pointer pkey
;
1260 if (!readCertAndPrivateKeyFromMemory(cert
, pkey
, data
))
1266 return createSSLContext(cert
, pkey
);
1269 SSL_CTX
* Ssl::generateSslContext(CertificateProperties
const &properties
)
1271 Ssl::X509_Pointer cert
;
1272 Ssl::EVP_PKEY_Pointer pkey
;
1273 if (!generateSslCertificate(cert
, pkey
, properties
))
1282 return createSSLContext(cert
, pkey
);
1285 bool Ssl::verifySslCertificate(SSL_CTX
* sslContext
, CertificateProperties
const &properties
)
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);
1296 return certificateMatchesProperties(cert
, properties
);
1300 Ssl::setClientSNI(SSL
*ssl
, const char *fqdn
)
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");
1313 debugs(83, 7, "no support for TLS servername extension (SNI)\n");
1318 void Ssl::addChainToSslContext(SSL_CTX
*sslContext
, STACK_OF(X509
) *chain
)
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
);
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
));
1336 \ingroup ServerProtocolSSLInternal
1337 * Read certificate from file.
1338 * See also: static readSslX509Certificate function, gadgets.cc file
1340 static X509
* readSslX509CertificatesChain(char const * certFilename
, STACK_OF(X509
)* chain
)
1344 Ssl::BIO_Pointer
bio(BIO_new(BIO_s_file_internal()));
1347 if (!BIO_read_filename(bio
.get(), certFilename
))
1349 X509
*certificate
= PEM_read_bio_X509(bio
.get(), NULL
, NULL
, NULL
);
1351 if (certificate
&& chain
) {
1353 if (X509_check_issued(certificate
, certificate
) == X509_V_OK
)
1354 debugs(83, 5, "Certificate is self-signed, will not be chained");
1356 if (sk_X509_push(chain
, certificate
))
1357 CRYPTO_add(&(certificate
->references
), 1, CRYPTO_LOCK_X509
);
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");
1371 void Ssl::readCertChainAndPrivateKeyFromFiles(X509_Pointer
& cert
, EVP_PKEY_Pointer
& pkey
, X509_STACK_Pointer
& chain
, char const * certFilename
, char const * keyFilename
)
1373 if (keyFilename
== NULL
)
1374 keyFilename
= certFilename
;
1376 chain
.reset(sk_X509_new_null());
1378 debugs(83, DBG_IMPORTANT
, "WARNING: unable to allocate memory for cert chain");
1379 pkey
.reset(readSslPrivateKey(keyFilename
, ssl_ask_password_cb
));
1380 cert
.reset(readSslX509CertificatesChain(certFilename
, chain
.get()));
1381 if (!pkey
|| !cert
|| !X509_check_private_key(cert
.get(), pkey
.get())) {
1387 static const char *getSubjectEntry(X509
*x509
, int nid
)
1389 static char name
[1024] = ""; // stores common name (CN)
1394 // TODO: What if the entry 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
, name
, sizeof(name
));
1405 const char *Ssl::CommonHostName(X509
*x509
)
1407 return getSubjectEntry(x509
, NID_commonName
);
1410 static const char *getOrganization(X509
*x509
)
1412 return getSubjectEntry(x509
, NID_organizationName
);
1415 bool Ssl::generateUntrustedCert(X509_Pointer
&untrustedCert
, EVP_PKEY_Pointer
&untrustedPkey
, X509_Pointer
const &cert
, EVP_PKEY_Pointer
const & pkey
)
1417 // Generate the self-signed certificate, using a hard-coded subject prefix
1418 Ssl::CertificateProperties certProperties
;
1419 if (const char *cn
= CommonHostName(cert
.get())) {
1420 certProperties
.commonName
= "Not trusted by \"";
1421 certProperties
.commonName
+= cn
;
1422 certProperties
.commonName
+= "\"";
1424 else if (const char *org
= getOrganization(cert
.get())) {
1425 certProperties
.commonName
= "Not trusted by \"";
1426 certProperties
.commonName
+= org
;
1427 certProperties
.commonName
+= "\"";
1430 certProperties
.commonName
= "Not trusted";
1431 certProperties
.setCommonName
= true;
1432 // O, OU, and other CA subject fields will be mimicked
1433 // Expiration date and other common properties will be mimicked
1434 certProperties
.signAlgorithm
= Ssl::algSignSelf
;
1435 certProperties
.signWithPkey
.resetAndLock(pkey
.get());
1436 certProperties
.mimicCert
.resetAndLock(cert
.get());
1437 return Ssl::generateSslCertificate(untrustedCert
, untrustedPkey
, certProperties
);
1440 #endif /* USE_SSL */