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;
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 (1 == d->kossl->SSL_set_session(d->m_ssl,
288 static_cast<SSL_SESSION*
>(d->session->_session))) {
289 kdDebug(7029) <<
"Session ID is being reused." << endl;
291 kdDebug(7029) <<
"Error attempting to reuse session." << endl;
306 int off = SSL_OP_ALL;
307 if (!d->lastInitTLS && !m_cfg->
tlsv1())
308 off |= SSL_OP_NO_TLSv1;
310 off |= SSL_OP_NO_SSLv3;
312 off |= SSL_OP_NO_SSLv2;
314 d->kossl->_SSL_set_options(d->m_ssl, off);
316 rc = d->kossl->SSL_set_fd(d->m_ssl, sock);
318 d->kossl->SSL_shutdown(d->m_ssl);
319 d->kossl->SSL_free(d->m_ssl);
323 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
324 d->kossl->SSL_set_tlsext_host_name(d->m_ssl, d->proxyPeer.ascii());
327 rc = d->kossl->SSL_accept(d->m_ssl);
331 kdDebug(7029) <<
"KSSL connected OK" << endl;
333 kdDebug(7029) <<
"KSSL accept failed - rc = " << rc << endl;
334 kdDebug(7029) <<
" ERROR = "
335 << d->kossl->SSL_get_error(d->m_ssl, rc) << endl;
336 d->kossl->SSL_shutdown(d->m_ssl);
337 d->kossl->SSL_free(d->m_ssl);
342 if (!d->kossl->_SSL_session_reused(d->m_ssl)) {
344 kdDebug(7029) <<
"Session reuse failed. New session used instead." << endl;
351 SSL_SESSION *sess = d->kossl->SSL_get1_session(d->m_ssl);
354 d->session->_session = sess;
371 d->m_ssl = d->kossl->SSL_new(d->m_ctx);
376 if (1 == d->kossl->SSL_set_session(d->m_ssl,
377 static_cast<SSL_SESSION*
>(d->session->_session))) {
378 kdDebug(7029) <<
"Session ID is being reused." << endl;
380 kdDebug(7029) <<
"Error attempting to reuse session." << endl;
395 int off = SSL_OP_ALL;
396 if (!d->lastInitTLS && !m_cfg->
tlsv1())
397 off |= SSL_OP_NO_TLSv1;
399 off |= SSL_OP_NO_SSLv3;
401 off |= SSL_OP_NO_SSLv2;
403 d->kossl->_SSL_set_options(d->m_ssl, off);
405 rc = d->kossl->SSL_set_fd(d->m_ssl, sock);
407 d->kossl->SSL_shutdown(d->m_ssl);
408 d->kossl->SSL_free(d->m_ssl);
412 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
413 d->kossl->SSL_set_tlsext_host_name(d->m_ssl, d->proxyPeer.ascii());
417 rc = d->kossl->SSL_connect(d->m_ssl);
421 kdDebug(7029) <<
"KSSL connected OK" << endl;
423 int err = d->kossl->SSL_get_error(d->m_ssl, rc);
424 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
428 kdDebug(7029) <<
"KSSL connect failed - rc = "
430 kdDebug(7029) <<
" ERROR = "
432 d->kossl->ERR_print_errors_fp(stderr);
433 d->kossl->SSL_shutdown(d->m_ssl);
434 d->kossl->SSL_free(d->m_ssl);
440 if (!d->kossl->_SSL_session_reused(d->m_ssl)) {
442 kdDebug(7029) <<
"Session reuse failed. New session used instead." << endl;
449 SSL_SESSION *sess = d->kossl->SSL_get1_session(d->m_ssl);
452 d->session->_session = sess;
467 return d->kossl->SSL_pending(d->m_ssl);
479 return d->kossl->SSL_peek(d->m_ssl, buf, len);
495 rc = d->kossl->SSL_read(d->m_ssl, (
char *)buf, len);
497 int err = d->kossl->SSL_get_error(d->m_ssl, rc);
499 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
500 kdDebug(7029) <<
"SSL read() returning 0: " << err << endl;
501 if (maxIters-- > 0) {
508 kdDebug(7029) <<
"SSL READ ERROR: " << err << endl;
509 if (err != SSL_ERROR_NONE &&
510 err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_SYSCALL) {
512 d->kossl->ERR_print_errors_fp(stderr);
531 int rc = d->kossl->SSL_write(d->m_ssl, (
const char *)buf, len);
533 int err = d->kossl->SSL_get_error(d->m_ssl, rc);
535 if (err == SSL_ERROR_WANT_WRITE) {
540 kdDebug(7029) <<
"SSL WRITE ERROR: " << err << endl;
541 if (err != SSL_ERROR_NONE &&
542 err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_SYSCALL)
559 m_bAutoReconfig = ar;
571 bool KSSL::m_bSSLWorks =
true;
573 bool KSSL::m_bSSLWorks =
false;
581 void KSSL::setConnectionInfo() {
587 sc = d->kossl->SSL_get_current_cipher(d->m_ssl);
589 kdDebug(7029) <<
"KSSL get current cipher failed - we're probably gonna crash!" << endl;
594 m_ci.m_iCipherUsedBits = d->kossl->SSL_CIPHER_get_bits(sc, &(m_ci.m_iCipherBits));
596 m_ci.m_cipherVersion = d->kossl->SSL_CIPHER_get_version(sc);
598 m_ci.m_cipherName = d->kossl->SSL_CIPHER_get_name(sc);
600 m_ci.m_cipherDescription = d->kossl->SSL_CIPHER_description(sc, buf, 1023);
606 void KSSL::setPeerInfo() {
609 m_pi.m_cert.
setCert(d->kossl->SSL_get_peer_certificate(d->m_ssl));
610 STACK_OF(X509) *xs = d->kossl->SSL_get_peer_cert_chain(d->m_ssl);
612 xs =
reinterpret_cast<STACK_OF(X509)*
>(d->kossl->OPENSSL_sk_dup(xs));
613 m_pi.m_cert.setChain((
void *)xs);
625 d->proxyPeer = realHost;
647 if (!x || !k)
return false;
652 rc = d->kossl->SSL_CTX_use_certificate(d->m_ctx, x);
654 kdDebug(7029) <<
"KSSL - SSL_CTX_use_certificate failed. rc = " << rc << endl;
658 rc = d->kossl->SSL_CTX_use_PrivateKey(d->m_ctx, k);
660 kdDebug(7029) <<
"KSSL - SSL_CTX_use_PrivateKey failed. rc = " << rc << endl;
676 return (d->m_ssl && d->kossl->_SSL_session_reused(d->m_ssl));