You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/tdeio/kssl/kssl.cpp

700 lines
15 KiB

/* This file is part of the KDE project
*
* Copyright (C) 2000-2003 George Staikos <staikos@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
// this hack provided by Malte Starostik to avoid glibc/openssl bug
// on some systems
#ifdef KSSL_HAVE_SSL
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define crypt _openssl_crypt
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#undef crypt
#endif
#include "kssl.h"
#include <kdebug.h>
#include <kstandarddirs.h>
#include <ksock.h>
#include <ksockaddr.h>
#include <kopenssl.h>
#include <ksslx509v3.h>
#include <ksslpkcs12.h>
#include <ksslsession.h>
#include <tdelocale.h>
#include <ksocks.h>
class KSSLPrivate {
public:
KSSLPrivate() {
lastInitTLS = false;
kossl = KOpenSSLProxy::self();
session = 0L;
}
~KSSLPrivate() {
delete session;
session = 0L;
}
bool lastInitTLS;
KSSLCertificate::KSSLValidation m_cert_vfy_res;
TQString proxyPeer;
#ifdef KSSL_HAVE_SSL
SSL *m_ssl;
SSL_CTX *m_ctx;
SSL_METHOD *m_meth;
#endif
KSSLSession *session;
KOSSL *kossl;
};
KSSL::KSSL(bool init) {
d = new KSSLPrivate;
m_bInit = false;
m_bAutoReconfig = true;
m_cfg = new KSSLSettings();
#ifdef KSSL_HAVE_SSL
d->m_ssl = 0L;
#endif
if (init)
initialize();
}
KSSL::~KSSL() {
close();
delete m_cfg;
delete d;
}
int KSSL::seedWithEGD() {
int rc = 0;
#ifdef KSSL_HAVE_SSL
if (m_cfg->useEGD() && !m_cfg->getEGDPath().isEmpty()) {
rc = d->kossl->RAND_egd(m_cfg->getEGDPath().latin1());
if (rc < 0)
kdDebug(7029) << "KSSL: Error seeding PRNG with the EGD." << endl;
else kdDebug(7029) << "KSSL: PRNG was seeded with " << rc
<< " bytes from the EGD." << endl;
} else if (m_cfg->useEFile() && !m_cfg->getEGDPath().isEmpty()) {
rc = d->kossl->RAND_load_file(m_cfg->getEGDPath().latin1(), -1);
if (rc < 0)
kdDebug(7029) << "KSSL: Error seeding PRNG with the entropy file." << endl;
else kdDebug(7029) << "KSSL: PRNG was seeded with " << rc
<< " bytes from the entropy file." << endl;
}
#endif
return rc;
}
bool KSSL::TLSInit() {
#ifdef KSSL_HAVE_SSL
// kdDebug(7029) << "KSSL TLS initialize" << endl;
if (m_bInit)
return false;
if (m_bAutoReconfig)
m_cfg->load();
if (!m_cfg->tlsv1())
return false;
seedWithEGD();
d->m_meth = d->kossl->TLS_client_method();
d->lastInitTLS = true;
m_pi.reset();
d->m_ctx = d->kossl->SSL_CTX_new(d->m_meth);
if (d->m_ctx == 0L) {
return false;
}
// set cipher list
TQString clist = m_cfg->getCipherList();
//kdDebug(7029) << "Cipher list: " << clist << endl;
if (!clist.isEmpty())
d->kossl->SSL_CTX_set_cipher_list(d->m_ctx, const_cast<char *>(clist.ascii()));
m_bInit = true;
return true;
#else
return false;
#endif
}
bool KSSL::initialize() {
#ifdef KSSL_HAVE_SSL
kdDebug(7029) << "KSSL initialize" << endl;
if (m_bInit)
return false;
if (m_bAutoReconfig)
m_cfg->load();
seedWithEGD();
// FIXME: we should be able to force SSL off entirely.
d->lastInitTLS = false;
m_pi.reset();
if (m_cfg->tlsv1() || (m_cfg->sslv3() && m_cfg->sslv2())) {
d->m_meth = d->kossl->TLS_client_method();
}
else if (m_cfg->sslv3()) {
d->m_meth = d->kossl->SSLv3_client_method();
}
else if (m_cfg->sslv2()) {
d->m_meth = d->kossl->SSLv2_client_method();
}
/*
if (m_cfg->sslv2() && m_cfg->sslv3()) kdDebug(7029) << "Double method" << endl;
else if (m_cfg->sslv2()) kdDebug(7029) << "SSL2 method" << endl;
else if (m_cfg->sslv3()) kdDebug(7029) << "SSL3 method" << endl;
*/
d->m_ctx = d->kossl->SSL_CTX_new(d->m_meth);
if (d->m_ctx == 0L) {
return false;
}
// set cipher list
TQString clist = m_cfg->getCipherList();
kdDebug(7029) << "Cipher list: " << clist << endl;
if (!clist.isEmpty())
d->kossl->SSL_CTX_set_cipher_list(d->m_ctx, const_cast<char *>(clist.ascii()));
m_bInit = true;
return true;
#else
return false;
#endif
}
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
bool KSSL::takeSession(KSSLSession *session) {
#ifdef KSSL_HAVE_SSL
if (!session) {
delete d->session;
d->session = 0L;
return true;
}
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
// Take session reference
d->session = new KSSLSession;
d->session->_session = session->_session;
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
session->_session = 0L;
return true;
#else
return false;
#endif
}
void KSSL::close() {
#ifdef KSSL_HAVE_SSL
//kdDebug(7029) << "KSSL close" << endl;
if (!m_bInit)
return;
delete d->session;
d->session = 0L;
if (d->m_ssl) {
d->kossl->SSL_shutdown(d->m_ssl);
d->kossl->SSL_free(d->m_ssl);
d->m_ssl = 0L;
}
d->kossl->SSL_CTX_free(d->m_ctx);
if (m_cfg->useEFile() && !m_cfg->getEGDPath().isEmpty()) {
d->kossl->RAND_write_file(m_cfg->getEGDPath().latin1());
}
m_bInit = false;
#endif
}
bool KSSL::reInitialize() {
close();
return initialize();
}
// get the callback file - it's hidden away in here
//#include "ksslcallback.c"
bool KSSL::setVerificationLogic() {
#if 0
#ifdef KSSL_HAVE_SSL
// SSL_set_verify_result(d->m_ssl, X509_V_OK);
// SSL_CTX_set_verify(d->m_ctx, SSL_VERIFY_PEER, X509Callback);
#endif
#endif
return true;
}
int KSSL::accept(int sock) {
#ifdef KSSL_HAVE_SSL
// kdDebug(7029) << "KSSL accept" << endl;
int rc;
if (!m_bInit)
return -1;
d->m_ssl = d->kossl->SSL_new(d->m_ctx);
if (!d->m_ssl)
return -1;
if (d->session) {
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
#if OPENSSL_VERSION_NUMBER < 0x10100000L
if (static_cast<SSL_SESSION*>(d->session->_session)->sess_cert == 0)
{
kdDebug(7029) << "Can't reuse session, no certificate." << endl;
delete d->session;
d->session = 0;
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
}
else
#endif
if (1 == d->kossl->SSL_set_session(d->m_ssl,
static_cast<SSL_SESSION*>(d->session->_session))) {
kdDebug(7029) << "Session ID is being reused." << endl;
} else {
kdDebug(7029) << "Error attempting to reuse session." << endl;
delete d->session;
d->session = 0;
}
}
/*
if (!setVerificationLogic()) {
d->kossl->SSL_shutdown(d->m_ssl);
d->kossl->SSL_free(d->m_ssl);
d->m_ssl = 0;
return -1;
}
*/
int off = SSL_OP_ALL;
if (!d->lastInitTLS && !m_cfg->tlsv1())
off |= SSL_OP_NO_TLSv1;
if (!m_cfg->sslv3())
off |= SSL_OP_NO_SSLv3;
if (!m_cfg->sslv2())
off |= SSL_OP_NO_SSLv2;
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
d->kossl->_SSL_set_options(d->m_ssl, off);
rc = d->kossl->SSL_set_fd(d->m_ssl, sock);
if (rc == 0) {
d->kossl->SSL_shutdown(d->m_ssl);
d->kossl->SSL_free(d->m_ssl);
d->m_ssl = 0;
return rc;
}
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
d->kossl->SSL_set_tlsext_host_name(d->m_ssl, d->proxyPeer.ascii());
#endif
rc = d->kossl->SSL_accept(d->m_ssl);
if (rc == 1) {
setConnectionInfo();
setPeerInfo();
kdDebug(7029) << "KSSL connected OK" << endl;
} else {
kdDebug(7029) << "KSSL accept failed - rc = " << rc << endl;
kdDebug(7029) << " ERROR = "
<< d->kossl->SSL_get_error(d->m_ssl, rc) << endl;
d->kossl->SSL_shutdown(d->m_ssl);
d->kossl->SSL_free(d->m_ssl);
d->m_ssl = 0;
return -1;
}
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
if (!d->kossl->_SSL_session_reused(d->m_ssl)) {
if (d->session) {
kdDebug(7029) << "Session reuse failed. New session used instead." << endl;
delete d->session;
d->session = 0L;
}
}
if (!d->session) {
SSL_SESSION *sess = d->kossl->SSL_get1_session(d->m_ssl);
if (sess) {
d->session = new KSSLSession;
d->session->_session = sess;
}
}
return rc;
#else
return -1;
#endif
}
int KSSL::connect(int sock) {
#ifdef KSSL_HAVE_SSL
// kdDebug(7029) << "KSSL connect" << endl;
int rc;
if (!m_bInit)
return -1;
d->m_ssl = d->kossl->SSL_new(d->m_ctx);
if (!d->m_ssl)
return -1;
if (d->session) {
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
#if OPENSSL_VERSION_NUMBER < 0x10100000L
if (static_cast<SSL_SESSION*>(d->session->_session)->sess_cert == 0)
{
kdDebug(7029) << "Can't reuse session, no certificate." << endl;
delete d->session;
d->session = 0;
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
}
else
#endif
if (1 == d->kossl->SSL_set_session(d->m_ssl,
static_cast<SSL_SESSION*>(d->session->_session))) {
kdDebug(7029) << "Session ID is being reused." << endl;
} else {
kdDebug(7029) << "Error attempting to reuse session." << endl;
delete d->session;
d->session = 0;
}
}
/*
if (!setVerificationLogic()) {
d->kossl->SSL_shutdown(d->m_ssl);
d->kossl->SSL_free(d->m_ssl);
d->m_ssl = 0;
return -1;
}
*/
int off = SSL_OP_ALL;
if (!d->lastInitTLS && !m_cfg->tlsv1())
off |= SSL_OP_NO_TLSv1;
if (!m_cfg->sslv3())
off |= SSL_OP_NO_SSLv3;
if (!m_cfg->sslv2())
off |= SSL_OP_NO_SSLv2;
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
d->kossl->_SSL_set_options(d->m_ssl, off);
rc = d->kossl->SSL_set_fd(d->m_ssl, sock);
if (rc == 0) {
d->kossl->SSL_shutdown(d->m_ssl);
d->kossl->SSL_free(d->m_ssl);
d->m_ssl = 0;
return rc;
}
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
d->kossl->SSL_set_tlsext_host_name(d->m_ssl, d->proxyPeer.ascii());
#endif
connect_again:
rc = d->kossl->SSL_connect(d->m_ssl);
if (rc == 1) {
setConnectionInfo();
setPeerInfo();
kdDebug(7029) << "KSSL connected OK" << endl;
} else {
int err = d->kossl->SSL_get_error(d->m_ssl, rc);
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
// nonblocking - but we block anyways in connect() :)
goto connect_again;
} else {
kdDebug(7029) << "KSSL connect failed - rc = "
<< rc << endl;
kdDebug(7029) << " ERROR = "
<< err << endl;
d->kossl->ERR_print_errors_fp(stderr);
d->kossl->SSL_shutdown(d->m_ssl);
d->kossl->SSL_free(d->m_ssl);
d->m_ssl = 0;
return -1;
}
}
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
if (!d->kossl->_SSL_session_reused(d->m_ssl)) {
if (d->session) {
kdDebug(7029) << "Session reuse failed. New session used instead." << endl;
delete d->session;
d->session = 0L;
}
}
if (!d->session) {
SSL_SESSION *sess = d->kossl->SSL_get1_session(d->m_ssl);
if (sess) {
d->session = new KSSLSession;
d->session->_session = sess;
}
}
return rc;
#else
return -1;
#endif
}
int KSSL::pending() {
#ifdef KSSL_HAVE_SSL
if (!m_bInit)
return -1;
return d->kossl->SSL_pending(d->m_ssl);
#else
return -1;
#endif
}
int KSSL::peek(void *buf, int len) {
#ifdef KSSL_HAVE_SSL
if (!m_bInit)
return -1;
// FIXME: enhance to work the way read() does below, handling errors
return d->kossl->SSL_peek(d->m_ssl, buf, len);
#else
return -1;
#endif
}
int KSSL::read(void *buf, int len) {
#ifdef KSSL_HAVE_SSL
int rc = 0;
int maxIters = 10;
if (!m_bInit)
return -1;
read_again:
rc = d->kossl->SSL_read(d->m_ssl, (char *)buf, len);
if (rc <= 0) {
int err = d->kossl->SSL_get_error(d->m_ssl, rc);
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
kdDebug(7029) << "SSL read() returning 0: " << err << endl;
if (maxIters-- > 0) {
::usleep(20000); // 20ms sleep
goto read_again;
}
return 0;
}
kdDebug(7029) << "SSL READ ERROR: " << err << endl;
if (err != SSL_ERROR_NONE &&
err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_SYSCALL) {
rc = -1; // OpenSSL returns 0 on error too
d->kossl->ERR_print_errors_fp(stderr);
}
// else if (err == SSL_ERROR_ZERO_RETURN)
// rc = 0;
}
return rc;
#else
return -1;
#endif
}
int KSSL::write(const void *buf, int len) {
#ifdef KSSL_HAVE_SSL
if (!m_bInit)
return -1;
write_again:
int rc = d->kossl->SSL_write(d->m_ssl, (const char *)buf, len);
if (rc <= 0) { // OpenSSL returns 0 on error too
int err = d->kossl->SSL_get_error(d->m_ssl, rc);
if (err == SSL_ERROR_WANT_WRITE) {
::usleep(20000); // 20ms sleep
goto write_again;
}
kdDebug(7029) << "SSL WRITE ERROR: " << err << endl;
if (err != SSL_ERROR_NONE &&
err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_SYSCALL)
rc = -1;
}
return rc;
#else
return -1;
#endif
}
bool KSSL::reconfig() {
return reInitialize();
}
void KSSL::setAutoReconfig(bool ar) {
m_bAutoReconfig = ar;
}
bool KSSL::setSettings(KSSLSettings *settings) {
delete m_cfg;
m_cfg = settings;
return reconfig();
}
#ifdef KSSL_HAVE_SSL
bool KSSL::m_bSSLWorks = true;
#else
bool KSSL::m_bSSLWorks = false;
#endif
bool KSSL::doesSSLWork() {
return m_bSSLWorks;
}
void KSSL::setConnectionInfo() {
#ifdef KSSL_HAVE_SSL
SSL_CIPHER *sc;
char buf[1024];
buf[0] = 0; // for safety.
sc = d->kossl->SSL_get_current_cipher(d->m_ssl);
if (!sc) {
kdDebug(7029) << "KSSL get current cipher failed - we're probably gonna crash!" << endl;
return;
}
// set the number of bits, bits used
m_ci.m_iCipherUsedBits = d->kossl->SSL_CIPHER_get_bits(sc, &(m_ci.m_iCipherBits));
// set the cipher version
m_ci.m_cipherVersion = d->kossl->SSL_CIPHER_get_version(sc);
// set the cipher name
m_ci.m_cipherName = d->kossl->SSL_CIPHER_get_name(sc);
// set the cipher description
m_ci.m_cipherDescription = d->kossl->SSL_CIPHER_description(sc, buf, 1023);
#endif
}
void KSSL::setPeerInfo() {
#ifdef KSSL_HAVE_SSL
m_pi.setPeerHost(d->proxyPeer);
m_pi.m_cert.setCert(d->kossl->SSL_get_peer_certificate(d->m_ssl));
STACK_OF(X509) *xs = d->kossl->SSL_get_peer_cert_chain(d->m_ssl);
if (xs)
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
xs = reinterpret_cast<STACK_OF(X509)*>(d->kossl->OPENSSL_sk_dup(xs)); // Leak?
m_pi.m_cert.setChain((void *)xs);
#endif
}
KSSLConnectionInfo& KSSL::connectionInfo() {
return m_ci;
}
// KDE 4: Make it const TQString &
void KSSL::setPeerHost(TQString realHost) {
d->proxyPeer = realHost;
}
// deprecated
void KSSL::setProxyUse(bool, TQString, int, TQString) {
}
KSSLPeerInfo& KSSL::peerInfo() {
return m_pi;
}
bool KSSL::setClientCertificate(KSSLPKCS12 *pkcs) {
#ifdef KSSL_HAVE_SSL
if (!pkcs || !pkcs->getCertificate())
return false;
int rc;
X509 *x = pkcs->getCertificate()->getCert();
EVP_PKEY *k = pkcs->getPrivateKey();
if (!x || !k) return false;
if (!pkcs->getCertificate()->x509V3Extensions().certTypeSSLClient())
return false;
rc = d->kossl->SSL_CTX_use_certificate(d->m_ctx, x);
if (rc <= 0) {
kdDebug(7029) << "KSSL - SSL_CTX_use_certificate failed. rc = " << rc << endl;
return false;
}
rc = d->kossl->SSL_CTX_use_PrivateKey(d->m_ctx, k);
if (rc <= 0) {
kdDebug(7029) << "KSSL - SSL_CTX_use_PrivateKey failed. rc = " << rc << endl;
return false;
}
return true;
#else
return false;
#endif
}
const KSSLSession* KSSL::session() const {
return d->session;
}
bool KSSL::reusingSession() const {
#ifdef KSSL_HAVE_SSL
Added support for OpenSSL 1.1 Some KOpenSSLProxy methods have been renamed to be consistent with OpenSSL 1.1 API names and to prevent hidden API changes. To ensure API / ABI compatibility, the original methods are still included but have been marked as deprecated. + SSLv23_client_method => TLS_client_method + X509_STORE_CTX_set_chain => X509_STORE_CTX_set0_untrusted + sk_dup => OPENSSL_sk_dup + sk_free => OPENSSL_sk_free + sk_new => OPENSSL_sk_new + sk_num => OPENSSL_sk_num + sk_pop => OPENSSL_sk_pop + sk_push => OPENSSL_sk_push + sk_value => OPENSSL_sk_value Additional methods have been added to KOpenSSLProxy to support the new OpenSSL 1.1 API functions that provide access to the (now) opaque SSL structures. Compatibility with OpenSSL < 1.1 is handled internally in KOpenSSLProxy. + BIO_get_data + DSA_get0_key + DSA_get0_pqg + EVP_PKEY_base_id + EVP_PKEY_get0_DSA + EVP_PKEY_get0_RSA + RSA_get0_key + X509_CRL_get0_lastUpdate + X509_CRL_get0_nextUpdate + X509_OBJECT_get0_X509 + X509_OBJECT_get_type + X509_STORE_CTX_get_current_cert + X509_STORE_CTX_get_error + X509_STORE_CTX_get_error_depth + X509_STORE_CTX_set_error + X509_STORE_get0_objects + X509_STORE_set_verify_cb + X509_get0_signature + X509_getm_notAfter + X509_getm_notBefore + X509_subject_name_cmp + _SSL_session_reused + _SSL_set_options Method "KSSL::setSession" has been renamed to "KSSL::takeSession" and its functionality has changed: the session is now transferred from the argument object to the invoked object. Since it is only used internally in TDE and the functionality is different, the method with the previous name has not been preserved. Signed-off-by: Slávek Banko <slavek.banko@axis.cz> Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
7 years ago
return (d->m_ssl && d->kossl->_SSL_session_reused(d->m_ssl));
#else
return false;
#endif
}