15 #include "tlsopensslbase.h"
24 #include <openssl/err.h>
25 #include <openssl/comp.h>
31 :
TLSBase( th, server ), m_ssl( 0 ), m_ctx( 0 ), m_buf( 0 ), m_bufsize( 17000 )
33 m_buf = (
char*)calloc( m_bufsize + 1,
sizeof(
char ) );
40 SSL_CTX_free( m_ctx );
41 SSL_shutdown( m_ssl );
48 const std::string& clientCerts,
54 SSL_COMP_add_compression_method( 193, COMP_zlib() );
56 OpenSSL_add_all_algorithms();
64 if( !SSL_CTX_set_cipher_list( m_ctx,
"HIGH:MEDIUM:AES:@STRENGTH" ) )
67 m_ssl = SSL_new( m_ctx );
71 if( !BIO_new_bio_pair( &m_ibio, 0, &m_nbio, 0 ) )
74 SSL_set_bio( m_ssl, m_ibio, m_ibio );
75 SSL_set_mode( m_ssl, SSL_MODE_AUTO_RETRY | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE );
77 ERR_load_crypto_strings();
78 SSL_load_error_strings();
97 doTLSOperation( TLSWrite );
103 m_recvBuffer += data;
111 doTLSOperation( TLSRead );
119 StringList::const_iterator it = m_cacerts.begin();
120 for( ; it != m_cacerts.end(); ++it )
121 SSL_CTX_load_verify_locations( m_ctx, (*it).c_str(), 0 );
126 m_clientKey = clientKey;
127 m_clientCerts = clientCerts;
129 if( !m_clientKey.empty() && !m_clientCerts.empty() )
131 if( SSL_CTX_use_certificate_chain_file( m_ctx, m_clientCerts.c_str() ) != 1 )
135 if( SSL_CTX_use_RSAPrivateKey_file( m_ctx, m_clientKey.c_str(), SSL_FILETYPE_PEM ) != 1 )
141 if ( SSL_CTX_check_private_key( m_ctx ) != 1 )
158 void OpenSSLBase::doTLSOperation( TLSOperation op )
164 bool onceAgain =
false;
171 ret = handshakeFunction();
174 ret = SSL_write( m_ssl, m_sendBuffer.c_str(), m_sendBuffer.length() );
177 ret = SSL_read( m_ssl, m_buf, m_bufsize );
181 switch( SSL_get_error( m_ssl, ret ) )
183 case SSL_ERROR_WANT_READ:
184 case SSL_ERROR_WANT_WRITE:
188 if( op == TLSHandshake )
190 else if( op == TLSWrite )
191 m_sendBuffer.erase( 0, ret );
192 else if( op == TLSRead )
202 if( !onceAgain && !m_recvBuffer.length() )
207 while( ( ( onceAgain || m_recvBuffer.length() ) && ( !m_secure || op == TLSRead ) )
208 || ( ( op == TLSWrite ) && ( ret > 0 ) ));
211 int OpenSSLBase::openSSLTime2UnixTime(
const char* time_string )
217 for(
int n = 0; n < 12; n += 2 )
219 tstring[m] = time_string[n];
220 tstring[m + 1] = time_string[n + 1];
227 time_st.tm_year = ( atoi( &tstring[3 * 0] ) >= 70 ) ? atoi( &tstring[3 * 0] )
228 : atoi( &tstring[3 * 0] ) + 100;
229 time_st.tm_mon = atoi( &tstring[3 * 1] ) - 1;
230 time_st.tm_mday = atoi( &tstring[3 * 2] );
231 time_st.tm_hour = atoi( &tstring[3 * 3] );
232 time_st.tm_min = atoi( &tstring[3 * 4] );
233 time_st.tm_sec = atoi( &tstring[3 * 5] );
235 time_t unixt = mktime( &time_st );
242 doTLSOperation( TLSHandshake );
247 int res = SSL_get_verify_result( m_ssl );
248 if( res != X509_V_OK )
253 X509* peer = SSL_get_peer_certificate( m_ssl );
257 X509_NAME_get_text_by_NID( X509_get_issuer_name( peer ), NID_commonName, peer_CN,
sizeof( peer_CN ) );
258 m_certInfo.
issuer = peer_CN;
259 X509_NAME_get_text_by_NID( X509_get_subject_name( peer ), NID_commonName, peer_CN,
sizeof( peer_CN ) );
260 m_certInfo.
server = peer_CN;
261 m_certInfo.
date_from = openSSLTime2UnixTime( (
char*) (peer->cert_info->validity->notBefore->data) );
262 m_certInfo.
date_to = openSSLTime2UnixTime( (
char*) (peer->cert_info->validity->notAfter->data) );
263 std::string p( peer_CN );
264 std::transform( p.begin(), p.end(), p.begin(), tolower );
268 if( ASN1_UTCTIME_cmp_time_t( X509_get_notBefore( peer ), time( 0 ) ) != -1 )
271 if( ASN1_UTCTIME_cmp_time_t( X509_get_notAfter( peer ), time( 0 ) ) != 1 )
282 tmp = SSL_get_cipher_name( m_ssl );
286 tmp = SSL_get_cipher_version( m_ssl );
290 tmp = SSL_COMP_get_name( SSL_get_current_compression( m_ssl ) );
300 void OpenSSLBase::pushFunc()
307 while( ( wantwrite = BIO_ctrl_pending( m_nbio ) ) > 0 )
309 if( wantwrite > m_bufsize )
310 wantwrite = m_bufsize;
315 frombio = BIO_read( m_nbio, m_buf, wantwrite );
321 while( ( wantread = BIO_ctrl_get_read_request( m_nbio ) ) > 0 )
323 if( wantread > m_recvBuffer.length() )
324 wantread = m_recvBuffer.length();
329 tobio = BIO_write( m_nbio, m_recvBuffer.c_str(), wantread );
330 m_recvBuffer.erase( 0, tobio );
336 #endif // HAVE_OPENSSL
virtual void setClientCert(const std::string &clientKey, const std::string &clientCerts)
std::list< std::string > StringList
virtual void handleEncryptedData(const TLSBase *base, const std::string &data)=0
virtual int decrypt(const std::string &data)
virtual void setCACerts(const StringList &cacerts)
The namespace for the gloox library.
virtual bool encrypt(const std::string &data)
OpenSSLBase(TLSHandler *th, const std::string &server=EmptyString)
An abstract base class for TLS implementations.
virtual bool init(const std::string &clientKey=EmptyString, const std::string &clientCerts=EmptyString, const StringList &cacerts=StringList())
virtual void handleDecryptedData(const TLSBase *base, const std::string &data)=0
An interface that allows for interacting with TLS implementations derived from TLSBase.
virtual void handleHandshakeResult(const TLSBase *base, bool success, CertInfo &certinfo)=0