35 #include <openssl/ssl.h> 36 #include <openssl/err.h> 37 #include <sys/socket.h> 38 #include <netinet/in.h> 39 #include <arpa/inet.h> 56 const string &cert_file,
const string &cert_auth_file,
57 const string &key_file )
62 _cafile( cert_auth_file),
74 BESDEBUG(
"ppt",
"Loading SSL error strings ... " << endl ) ;
75 SSL_load_error_strings() ;
78 BESDEBUG(
"ppt",
"Initializing SSL library ... " << endl ) ;
82 #if OPENSSL_VERSION_NUMBER < 0x10000000L 83 SSL_METHOD *method = NULL ;
85 const SSL_METHOD *method = NULL ;
87 SSL_CTX *context = NULL ;
89 BESDEBUG(
"ppt",
"Creating method and context ... " << endl ) ;
90 method = SSLv3_client_method() ;
93 context = SSL_CTX_new( method ) ;
97 string msg =
"Failed to create SSL context\n" ;
98 msg += ERR_error_string( ERR_get_error(), NULL ) ;
106 bool ok_2_continue = false ;
108 BESDEBUG(
"ppt",
"Setting certificate and key ... " << endl ) ;
109 if( SSL_CTX_use_certificate_file( context, _cfile.c_str(), SSL_FILETYPE_PEM ) <= 0 )
111 err_msg =
"FAILED to use certificate file " + _cfile +
"\n" ;
112 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
114 else if( SSL_CTX_use_PrivateKey_file( context, _kfile.c_str(), SSL_FILETYPE_PEM ) <= 0 )
116 err_msg =
"FAILED to use private key file " + _kfile +
"\n" ;
117 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
119 else if( !SSL_CTX_check_private_key( context ) )
121 err_msg =
"FAILED to authenticate private key\n" ;
122 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
126 ok_2_continue = true ;
132 BESDEBUG(
"ppt",
"Certificate setup ... " << endl ) ;
133 SSL_CTX_set_verify( context, SSL_VERIFY_PEER, SSLClient::verify_server ) ;
134 SSL_CTX_set_client_CA_list( context, SSL_load_client_CA_file( _cafile.c_str() ));
135 if( ( !SSL_CTX_load_verify_locations( context, _cafile.c_str(), NULL )) ||
136 ( !SSL_CTX_set_default_verify_paths( context ) ) )
138 err_msg =
"Certificate setup failed\n" ;
139 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
140 ok_2_continue = false ;
149 BESDEBUG(
"ppt",
"Establishing TCP connection to " 150 << _host <<
":" << _port <<
" ... " << endl ) ;
151 sock_fd = connect_to_server() ;
154 err_msg =
"Failed to establish TCP connection" ;
155 ok_2_continue = false ;
163 BESDEBUG(
"ppt",
"Establishing secure connection ... " << endl ) ;
168 err_msg =
"FAILED to create new connection\n" ;
169 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
170 ok_2_continue = false ;
172 else if( ( ssl_ret = SSL_set_fd(
_connection, sock_fd ) ) < 0 )
174 err_msg =
"FAILED to set the socket descriptor\n" ;
175 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
176 ok_2_continue = false ;
178 else if( ( ssl_ret = SSL_connect(
_connection ) ) < 0 )
180 err_msg =
"FAILED to create SSL connection\n" ;
181 err_msg += ERR_error_string( SSL_get_error(
_connection, ssl_ret ), NULL ) ;
182 ok_2_continue = false ;
184 else if( verify_connection() < 0 )
186 err_msg =
"FAILED to verify SSL connection\n" ;
187 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
188 ok_2_continue = false ;
198 BESDEBUG(
"ppt",
"FAILED" << endl ) ;
207 SSLClient::connect_to_server( )
210 struct sockaddr_in addr ;
212 fd = socket( PF_INET, SOCK_STREAM, 0 ) ;
213 if( fd < 0 )
return -1 ;
215 memset( &addr, 0,
sizeof( addr ) ) ;
216 addr.sin_family = AF_INET ;
217 addr.sin_port = htons( _port ) ;
218 if( isdigit( (
int)*_host.c_str() ) )
220 addr.sin_addr.s_addr = inet_addr( _host.c_str() ) ;
224 struct hostent *hostEntry ;
225 if( ( hostEntry = gethostbyname( _host.c_str() ) ) != 0 )
227 if ( hostEntry->h_length >
sizeof(addr.sin_addr) )
229 memcpy( &addr.sin_addr, hostEntry->h_addr, hostEntry->h_length ) ;
237 if( connect( fd, (
struct sockaddr *)&addr,
sizeof( addr ) ) < 0 )
247 SSLClient::verify_connection( )
249 X509 *server_cert = NULL ;
264 SSLClient::verify_server(
int ok, X509_STORE_CTX *ctx )
268 BESDEBUG(
"ppt",
"VERIFIED " << endl ) ;
276 err_cert = X509_STORE_CTX_get_current_cert( ctx ) ;
277 err = X509_STORE_CTX_get_error( ctx ) ;
278 X509_NAME_oneline( X509_get_subject_name( err_cert ), mybuf, 256 ) ;
279 BESDEBUG(
"ppt",
"FAILED for " << mybuf << endl ) ;
280 BESDEBUG(
"ppt",
" " << X509_verify_cert_error_string( err )
284 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
286 X509_NAME_oneline( X509_get_issuer_name( err_cert ), mybuf, 256 ) ;
287 BESDEBUG(
"ppt",
" issuer = " << mybuf << endl ) ;
291 case X509_V_ERR_CERT_NOT_YET_VALID:
292 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
294 BESDEBUG(
"ppt",
" not yet valid!" << endl ) ;
298 case X509_V_ERR_CERT_HAS_EXPIRED:
299 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
301 BESDEBUG(
"ppt",
" expired!" << endl ) ;
320 << (
void *)
this <<
")" << endl ;
SSLClient(const string &hostStr, int portVal, const string &cert_file, const string &cert_auth_file, const string &key_file)
virtual void dump(ostream &strm) const
dumps information about this object
exception thrown if inernal error encountered
virtual void initConnection()
virtual void dump(ostream &strm) const
dumps information about this object
static ostream & LMarg(ostream &strm)
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream