29 #include <netinet/in.h>
30 #include <sys/socket.h>
31 #define crypt _openssl_crypt
32 #include <openssl/ssl.h>
33 #include <openssl/x509.h>
34 #include <openssl/x509v3.h>
35 #include <openssl/pem.h>
36 #include <openssl/rand.h>
43 #include <kstandarddirs.h>
45 #include <ksockaddr.h>
48 #include <ksslx509v3.h>
49 #include <ksslpkcs12.h>
50 #include <ksslsession.h>
51 #include <tdelocale.h>
85 m_bAutoReconfig =
true;
107 rc = d->kossl->RAND_egd(m_cfg->
getEGDPath().latin1());
109 kdDebug(7029) <<
"KSSL: Error seeding PRNG with the EGD." << endl;
110 else kdDebug(7029) <<
"KSSL: PRNG was seeded with " << rc
111 <<
" bytes from the EGD." << endl;
113 rc = d->kossl->RAND_load_file(m_cfg->
getEGDPath().latin1(), -1);
115 kdDebug(7029) <<
"KSSL: Error seeding PRNG with the entropy file." << endl;
116 else kdDebug(7029) <<
"KSSL: PRNG was seeded with " << rc
117 <<
" bytes from the entropy file." << endl;
137 d->m_meth = d->kossl->TLS_client_method();
138 d->lastInitTLS =
true;
142 d->m_ctx = d->kossl->SSL_CTX_new(d->m_meth);
143 if (d->m_ctx == 0L) {
150 if (!clist.isEmpty())
151 d->kossl->SSL_CTX_set_cipher_list(d->m_ctx, const_cast<char *>(clist.ascii()));
163 kdDebug(7029) <<
"KSSL initialize" << endl;
172 d->lastInitTLS =
false;
177 d->m_meth = d->kossl->TLS_client_method();
179 else if (m_cfg->
sslv3()) {
180 d->m_meth = d->kossl->SSLv3_client_method();
182 else if (m_cfg->
sslv2()) {
183 d->m_meth = d->kossl->SSLv2_client_method();
192 d->m_ctx = d->kossl->SSL_CTX_new(d->m_meth);
193 if (d->m_ctx == 0L) {
199 kdDebug(7029) <<
"Cipher list: " << clist << endl;
200 if (!clist.isEmpty())
201 d->kossl->SSL_CTX_set_cipher_list(d->m_ctx, const_cast<char *>(clist.ascii()));
221 d->session->_session = session->_session;
222 session->_session = 0L;
241 d->kossl->SSL_shutdown(d->m_ssl);
242 d->kossl->SSL_free(d->m_ssl);
246 d->kossl->SSL_CTX_free(d->m_ctx);
248 d->kossl->RAND_write_file(m_cfg->
getEGDPath().latin1());
265 bool KSSL::setVerificationLogic() {
282 d->m_ssl = d->kossl->SSL_new(d->m_ctx);
287 #if OPENSSL_VERSION_NUMBER < 0x10100000L
288 if (static_cast<SSL_SESSION*>(d->session->_session)->sess_cert == 0)
290 kdDebug(7029) <<
"Can't reuse session, no certificate." << endl;
296 if (1 == d->kossl->SSL_set_session(d->m_ssl,
297 static_cast<SSL_SESSION*>(d->session->_session))) {
298 kdDebug(7029) <<
"Session ID is being reused." << endl;
300 kdDebug(7029) <<
"Error attempting to reuse session." << endl;
315 int off = SSL_OP_ALL;
316 if (!d->lastInitTLS && !m_cfg->
tlsv1())
317 off |= SSL_OP_NO_TLSv1;
319 off |= SSL_OP_NO_SSLv3;
321 off |= SSL_OP_NO_SSLv2;
323 d->kossl->_SSL_set_options(d->m_ssl, off);
325 rc = d->kossl->SSL_set_fd(d->m_ssl, sock);
327 d->kossl->SSL_shutdown(d->m_ssl);
328 d->kossl->SSL_free(d->m_ssl);
332 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
333 d->kossl->SSL_set_tlsext_host_name(d->m_ssl, d->proxyPeer.ascii());
336 rc = d->kossl->SSL_accept(d->m_ssl);
340 kdDebug(7029) <<
"KSSL connected OK" << endl;
342 kdDebug(7029) <<
"KSSL accept failed - rc = " << rc << endl;
343 kdDebug(7029) <<
" ERROR = "
344 << d->kossl->SSL_get_error(d->m_ssl, rc) << endl;
345 d->kossl->SSL_shutdown(d->m_ssl);
346 d->kossl->SSL_free(d->m_ssl);
351 if (!d->kossl->_SSL_session_reused(d->m_ssl)) {
353 kdDebug(7029) <<
"Session reuse failed. New session used instead." << endl;
360 SSL_SESSION *sess = d->kossl->SSL_get1_session(d->m_ssl);
363 d->session->_session = sess;
380 d->m_ssl = d->kossl->SSL_new(d->m_ctx);
385 #if OPENSSL_VERSION_NUMBER < 0x10100000L
386 if (static_cast<SSL_SESSION*>(d->session->_session)->sess_cert == 0)
388 kdDebug(7029) <<
"Can't reuse session, no certificate." << endl;
394 if (1 == d->kossl->SSL_set_session(d->m_ssl,
395 static_cast<SSL_SESSION*>(d->session->_session))) {
396 kdDebug(7029) <<
"Session ID is being reused." << endl;
398 kdDebug(7029) <<
"Error attempting to reuse session." << endl;
413 int off = SSL_OP_ALL;
414 if (!d->lastInitTLS && !m_cfg->
tlsv1())
415 off |= SSL_OP_NO_TLSv1;
417 off |= SSL_OP_NO_SSLv3;
419 off |= SSL_OP_NO_SSLv2;
421 d->kossl->_SSL_set_options(d->m_ssl, off);
423 rc = d->kossl->SSL_set_fd(d->m_ssl, sock);
425 d->kossl->SSL_shutdown(d->m_ssl);
426 d->kossl->SSL_free(d->m_ssl);
430 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
431 d->kossl->SSL_set_tlsext_host_name(d->m_ssl, d->proxyPeer.ascii());
435 rc = d->kossl->SSL_connect(d->m_ssl);
439 kdDebug(7029) <<
"KSSL connected OK" << endl;
441 int err = d->kossl->SSL_get_error(d->m_ssl, rc);
442 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
446 kdDebug(7029) <<
"KSSL connect failed - rc = "
448 kdDebug(7029) <<
" ERROR = "
450 d->kossl->ERR_print_errors_fp(stderr);
451 d->kossl->SSL_shutdown(d->m_ssl);
452 d->kossl->SSL_free(d->m_ssl);
458 if (!d->kossl->_SSL_session_reused(d->m_ssl)) {
460 kdDebug(7029) <<
"Session reuse failed. New session used instead." << endl;
467 SSL_SESSION *sess = d->kossl->SSL_get1_session(d->m_ssl);
470 d->session->_session = sess;
485 return d->kossl->SSL_pending(d->m_ssl);
497 return d->kossl->SSL_peek(d->m_ssl, buf, len);
513 rc = d->kossl->SSL_read(d->m_ssl, (
char *)buf, len);
515 int err = d->kossl->SSL_get_error(d->m_ssl, rc);
517 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
518 kdDebug(7029) <<
"SSL read() returning 0: " << err << endl;
519 if (maxIters-- > 0) {
526 kdDebug(7029) <<
"SSL READ ERROR: " << err << endl;
527 if (err != SSL_ERROR_NONE &&
528 err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_SYSCALL) {
530 d->kossl->ERR_print_errors_fp(stderr);
549 int rc = d->kossl->SSL_write(d->m_ssl, (
const char *)buf, len);
551 int err = d->kossl->SSL_get_error(d->m_ssl, rc);
553 if (err == SSL_ERROR_WANT_WRITE) {
558 kdDebug(7029) <<
"SSL WRITE ERROR: " << err << endl;
559 if (err != SSL_ERROR_NONE &&
560 err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_SYSCALL)
577 m_bAutoReconfig = ar;
589 bool KSSL::m_bSSLWorks =
true;
591 bool KSSL::m_bSSLWorks =
false;
599 void KSSL::setConnectionInfo() {
605 sc = d->kossl->SSL_get_current_cipher(d->m_ssl);
607 kdDebug(7029) <<
"KSSL get current cipher failed - we're probably gonna crash!" << endl;
612 m_ci.m_iCipherUsedBits = d->kossl->SSL_CIPHER_get_bits(sc, &(m_ci.m_iCipherBits));
614 m_ci.m_cipherVersion = d->kossl->SSL_CIPHER_get_version(sc);
616 m_ci.m_cipherName = d->kossl->SSL_CIPHER_get_name(sc);
618 m_ci.m_cipherDescription = d->kossl->SSL_CIPHER_description(sc, buf, 1023);
624 void KSSL::setPeerInfo() {
627 m_pi.m_cert.
setCert(d->kossl->SSL_get_peer_certificate(d->m_ssl));
628 STACK_OF(X509) *xs = d->kossl->SSL_get_peer_cert_chain(d->m_ssl);
630 xs =
reinterpret_cast<STACK_OF(X509)*
>(d->kossl->OPENSSL_sk_dup(xs));
631 m_pi.m_cert.setChain((
void *)xs);
643 d->proxyPeer = realHost;
665 if (!x || !k)
return false;
670 rc = d->kossl->SSL_CTX_use_certificate(d->m_ctx, x);
672 kdDebug(7029) <<
"KSSL - SSL_CTX_use_certificate failed. rc = " << rc << endl;
676 rc = d->kossl->SSL_CTX_use_PrivateKey(d->m_ctx, k);
678 kdDebug(7029) <<
"KSSL - SSL_CTX_use_PrivateKey failed. rc = " << rc << endl;
694 return (d->m_ssl && d->kossl->_SSL_session_reused(d->m_ssl));