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>
54 #define sk_dup d->kossl->sk_dup
86 m_bAutoReconfig =
true;
108 rc = d->kossl->RAND_egd(m_cfg->
getEGDPath().latin1());
110 kdDebug(7029) <<
"KSSL: Error seeding PRNG with the EGD." << endl;
111 else kdDebug(7029) <<
"KSSL: PRNG was seeded with " << rc
112 <<
" bytes from the EGD." << endl;
114 rc = d->kossl->RAND_load_file(m_cfg->
getEGDPath().latin1(), -1);
116 kdDebug(7029) <<
"KSSL: Error seeding PRNG with the entropy file." << endl;
117 else kdDebug(7029) <<
"KSSL: PRNG was seeded with " << rc
118 <<
" bytes from the entropy file." << endl;
138 d->m_meth = d->kossl->TLSv1_client_method();
139 d->lastInitTLS =
true;
143 d->m_ctx = d->kossl->SSL_CTX_new(d->m_meth);
144 if (d->m_ctx == 0L) {
151 if (!clist.isEmpty())
152 d->kossl->SSL_CTX_set_cipher_list(d->m_ctx, const_cast<char *>(clist.ascii()));
164 kdDebug(7029) <<
"KSSL initialize" << endl;
173 d->lastInitTLS =
false;
178 d->m_meth = d->kossl->SSLv2_client_method();
180 d->m_meth = d->kossl->TLSv1_client_method();
182 d->m_meth = d->kossl->SSLv3_client_method();
183 else d->m_meth = d->kossl->SSLv23_client_method();
191 d->m_ctx = d->kossl->SSL_CTX_new(d->m_meth);
192 if (d->m_ctx == 0L) {
198 kdDebug(7029) <<
"Cipher list: " << clist << endl;
199 if (!clist.isEmpty())
200 d->kossl->SSL_CTX_set_cipher_list(d->m_ctx, const_cast<char *>(clist.ascii()));
219 static_cast<SSL_SESSION*
>(session->_session)->references++;
222 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 (static_cast<SSL_SESSION*>(d->session->_session)->sess_cert == 0)
289 kdDebug(7029) <<
"Can't reuse session, no certificate." << endl;
292 }
else if (1 == d->kossl->SSL_set_session(d->m_ssl,
293 static_cast<SSL_SESSION*>(d->session->_session))) {
294 kdDebug(7029) <<
"Session ID is being reused." << endl;
296 kdDebug(7029) <<
"Error attempting to reuse session." << endl;
311 int off = SSL_OP_ALL;
312 if (!d->lastInitTLS && !m_cfg->
tlsv1())
313 off |= SSL_OP_NO_TLSv1;
315 off |= SSL_OP_NO_SSLv3;
317 off |= SSL_OP_NO_SSLv2;
319 d->kossl->SSL_set_options(d->m_ssl, off);
321 rc = d->kossl->SSL_set_fd(d->m_ssl, sock);
323 d->kossl->SSL_shutdown(d->m_ssl);
324 d->kossl->SSL_free(d->m_ssl);
329 rc = d->kossl->SSL_accept(d->m_ssl);
333 kdDebug(7029) <<
"KSSL connected OK" << endl;
335 kdDebug(7029) <<
"KSSL accept failed - rc = " << rc << endl;
336 kdDebug(7029) <<
" ERROR = "
337 << d->kossl->SSL_get_error(d->m_ssl, rc) << endl;
338 d->kossl->SSL_shutdown(d->m_ssl);
339 d->kossl->SSL_free(d->m_ssl);
344 if (!d->kossl->SSL_session_reused(d->m_ssl)) {
346 kdDebug(7029) <<
"Session reuse failed. New session used instead." << endl;
353 SSL_SESSION *sess = d->kossl->SSL_get1_session(d->m_ssl);
356 d->session->_session = sess;
373 d->m_ssl = d->kossl->SSL_new(d->m_ctx);
378 if (static_cast<SSL_SESSION*>(d->session->_session)->sess_cert == 0)
380 kdDebug(7029) <<
"Can't reuse session, no certificate." << endl;
383 }
else if (1 == d->kossl->SSL_set_session(d->m_ssl,
384 static_cast<SSL_SESSION*>(d->session->_session))) {
385 kdDebug(7029) <<
"Session ID is being reused." << endl;
387 kdDebug(7029) <<
"Error attempting to reuse session." << endl;
402 int off = SSL_OP_ALL;
403 if (!d->lastInitTLS && !m_cfg->
tlsv1())
404 off |= SSL_OP_NO_TLSv1;
406 off |= SSL_OP_NO_SSLv3;
408 off |= SSL_OP_NO_SSLv2;
410 d->kossl->SSL_set_options(d->m_ssl, off);
412 rc = d->kossl->SSL_set_fd(d->m_ssl, sock);
414 d->kossl->SSL_shutdown(d->m_ssl);
415 d->kossl->SSL_free(d->m_ssl);
421 rc = d->kossl->SSL_connect(d->m_ssl);
425 kdDebug(7029) <<
"KSSL connected OK" << endl;
427 int err = d->kossl->SSL_get_error(d->m_ssl, rc);
428 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
432 kdDebug(7029) <<
"KSSL connect failed - rc = "
434 kdDebug(7029) <<
" ERROR = "
436 d->kossl->ERR_print_errors_fp(stderr);
437 d->kossl->SSL_shutdown(d->m_ssl);
438 d->kossl->SSL_free(d->m_ssl);
444 if (!d->kossl->SSL_session_reused(d->m_ssl)) {
446 kdDebug(7029) <<
"Session reuse failed. New session used instead." << endl;
453 SSL_SESSION *sess = d->kossl->SSL_get1_session(d->m_ssl);
456 d->session->_session = sess;
471 return d->kossl->SSL_pending(d->m_ssl);
483 return d->kossl->SSL_peek(d->m_ssl, buf, len);
499 rc = d->kossl->SSL_read(d->m_ssl, (
char *)buf, len);
501 int err = d->kossl->SSL_get_error(d->m_ssl, rc);
503 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
504 kdDebug(7029) <<
"SSL read() returning 0: " << err << endl;
505 if (maxIters-- > 0) {
512 kdDebug(7029) <<
"SSL READ ERROR: " << err << endl;
513 if (err != SSL_ERROR_NONE &&
514 err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_SYSCALL) {
516 d->kossl->ERR_print_errors_fp(stderr);
535 int rc = d->kossl->SSL_write(d->m_ssl, (
const char *)buf, len);
537 int err = d->kossl->SSL_get_error(d->m_ssl, rc);
539 if (err == SSL_ERROR_WANT_WRITE) {
544 kdDebug(7029) <<
"SSL WRITE ERROR: " << err << endl;
545 if (err != SSL_ERROR_NONE &&
546 err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_SYSCALL)
563 m_bAutoReconfig = ar;
575 bool KSSL::m_bSSLWorks =
true;
577 bool KSSL::m_bSSLWorks =
false;
585 void KSSL::setConnectionInfo() {
591 sc = d->kossl->SSL_get_current_cipher(d->m_ssl);
593 kdDebug(7029) <<
"KSSL get current cipher failed - we're probably gonna crash!" << endl;
598 m_ci.m_iCipherUsedBits = d->kossl->SSL_CIPHER_get_bits(sc, &(m_ci.m_iCipherBits));
600 m_ci.m_cipherVersion = d->kossl->SSL_CIPHER_get_version(sc);
602 m_ci.m_cipherName = d->kossl->SSL_CIPHER_get_name(sc);
604 m_ci.m_cipherDescription = d->kossl->SSL_CIPHER_description(sc, buf, 1023);
610 void KSSL::setPeerInfo() {
613 m_pi.m_cert.
setCert(d->kossl->SSL_get_peer_certificate(d->m_ssl));
614 STACK_OF(X509) *xs = d->kossl->SSL_get_peer_cert_chain(d->m_ssl);
616 xs = sk_X509_dup(xs);
617 m_pi.m_cert.setChain((
void *)xs);
629 d->proxyPeer = realHost;
651 if (!x || !k)
return false;
656 rc = d->kossl->SSL_CTX_use_certificate(d->m_ctx, x);
658 kdDebug(7029) <<
"KSSL - SSL_CTX_use_certificate failed. rc = " << rc << endl;
662 rc = d->kossl->SSL_CTX_use_PrivateKey(d->m_ctx, k);
664 kdDebug(7029) <<
"KSSL - SSL_CTX_use_PrivateKey failed. rc = " << rc << endl;
682 return (d->m_ssl && d->kossl->SSL_session_reused(d->m_ssl));