00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "C_TransIPTLS.hpp"
00021 #include "C_SecureSocket.hpp"
00022 #include "Utils.hpp"
00023
00024 #define CALL_BACK_USER_DATA "ksgr"
00025
00026 #ifdef DEBUG_MODE
00027 #define GEN_DEBUG(l,a) iostream_error << a << iostream_endl << iostream_flush ;
00028 #else
00029 #define GEN_DEBUG(l,a)
00030 #endif
00031
00032 #define GEN_ERROR(l,a) iostream_error << a << iostream_endl << iostream_flush ;
00033
00034 static C_TransIPTLS::T_supported_methods m_methods [] = {
00035 { "SSLv23", SSLv23_method }
00036 } ;
00037 static int m_nb_methods = 1 ;
00038
00039 static char *password ;
00040 static int passwd_call_back(char *buf,int num,
00041 int rwflag,void *userdata) {
00042 if(num<(int)strlen(password)+1)
00043 return(0);
00044
00045 strcpy(buf,password);
00046 return(strlen(password));
00047 }
00048
00049 static int verify_callback(int P_ok , X509_STORE_CTX *P_store)
00050 {
00051 char L_data[512];
00052
00053 if (!P_ok) {
00054
00055 X509 *L_cert = X509_STORE_CTX_get_current_cert(P_store);
00056
00057
00058
00059 X509_NAME_oneline(X509_get_issuer_name(L_cert),
00060 L_data,512);
00061 GEN_ERROR(1, "TLS verification error for issuer [" << L_data << "]");
00062 X509_NAME_oneline(X509_get_subject_name(L_cert),
00063 L_data,512);
00064 GEN_ERROR(1, "TLS verification error for subject [" << L_data << "]");
00065 }
00066 return P_ok;
00067 }
00068
00069
00070 int C_TransIPTLS::load_crls(char *P_crlfile)
00071 {
00072 X509_STORE *L_store;
00073 X509_LOOKUP *L_lookup;
00074
00075
00076 if (!(L_store = SSL_CTX_get_cert_store(m_ssl_ctx))) {
00077 return (-1);
00078 }
00079
00080
00081 if (!(L_lookup = X509_STORE_add_lookup(L_store,X509_LOOKUP_file()))) {
00082 return (-1);
00083 }
00084
00085
00086 if (X509_load_crl_file(L_lookup,m_crl_file,X509_FILETYPE_PEM) != 1) {
00087 return (-1);
00088 }
00089
00090
00091 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
00092 X509_STORE_set_flags( L_store,X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
00093 #else
00094 GEN_ERROR(1, "version OpenSSL (<0.9.7) cannot handle CRL files in capath");
00095 #endif
00096
00097 return (1);
00098 }
00099
00100
00101
00102 C_TransIPTLS::T_SSLMethodType C_TransIPTLS::find_method(char *P_name) {
00103
00104 int L_i ;
00105 T_SSLMethodType L_ret = NULL ;
00106
00107 for (L_i = 0 ; L_i < m_nb_methods ; L_i++) {
00108 if (strcmp(P_name, m_methods[L_i].m_name) == 0){
00109 L_ret = m_methods[L_i].m_method ;
00110 break ;
00111 }
00112 }
00113 return (L_ret);
00114 }
00115
00116 int C_TransIPTLS::config (T_pConfigValueList P_config_param_list) {
00117 GEN_DEBUG(1, "C_TransIP::config ()");
00118 m_logInfo = NULL ;
00119 m_logError = NULL ;
00120
00121 int L_ret = 0 ;
00122 T_ConfigValueList::iterator L_config_it ;
00123
00124 if (!P_config_param_list->empty()) {
00125 for (L_config_it = P_config_param_list->begin() ;
00126 L_config_it != P_config_param_list->end();
00127 L_config_it++) {
00128 L_ret = analyze_config(*L_config_it) ;
00129 if (L_ret != 0) break ;
00130 }
00131 }
00132
00133 return (L_ret);
00134 }
00135
00136 bool C_TransIPTLS::analyze_init_string (char *P_buf) {
00137
00138 bool L_ret = false ;
00139 char L_tmp [255] ;
00140
00141 analyze_optional_init_string(P_buf);
00142
00143 L_tmp[0] = '\0' ;
00144 if (analyze_string_value (P_buf,
00145 (char*)"cert_chain_file=",
00146 L_tmp)) {
00147 ALLOC_TABLE(m_cert_chain_file,
00148 char*,
00149 sizeof(char),
00150 strlen(L_tmp)+1);
00151 sprintf(m_cert_chain_file, "%s", L_tmp);
00152 L_ret = true ;
00153 } else {
00154
00155 GEN_ERROR(1, "[cert_chain_file] value madatory for TLS transport");
00156 L_ret = false ;
00157 }
00158
00159 L_tmp[0] = '\0' ;
00160 if (L_ret && analyze_string_value (P_buf,
00161 (char*)"private_key_file=",
00162 L_tmp)) {
00163 ALLOC_TABLE(m_private_key_file,
00164 char*,
00165 sizeof(char),
00166 strlen(L_tmp)+1);
00167 sprintf(m_private_key_file, "%s", L_tmp);
00168 L_ret = true ;
00169 } else {
00170
00171 GEN_ERROR(1, "[private_key_file] value madatory for secure transport");
00172 L_ret = false ;
00173 }
00174
00175 L_tmp[0] = '\0' ;
00176 if (L_ret && analyze_string_value (P_buf,
00177 (char*)"passwd=",
00178 L_tmp)) {
00179 ALLOC_TABLE(m_passwd,
00180 char*,
00181 sizeof(char),
00182 strlen(L_tmp)+1);
00183 sprintf(m_passwd, "%s", L_tmp);
00184 password = m_passwd ;
00185 L_ret = true ;
00186 } else {
00187
00188 GEN_ERROR(1, "[passwd] value madatory for secure transport");
00189 L_ret = false ;
00190 }
00191
00192 L_tmp[0] = '\0' ;
00193 if (L_ret && analyze_string_value (P_buf,
00194 (char*)"method=",
00195 L_tmp)) {
00196
00197 m_method = find_method(L_tmp) ;
00198 if (m_method == NULL) {
00199 GEN_ERROR(1, "unknown [method] value for secure transport");
00200 L_ret = false ;
00201 } else {
00202 L_ret = true ;
00203 }
00204 } else {
00205
00206 GEN_ERROR(1, "[method] value madatory for secure transport");
00207 L_ret = false ;
00208 }
00209
00210 L_tmp[0] = '\0' ;
00211 if (L_ret && analyze_string_value (P_buf,
00212 (char*)"crl_file=",
00213 L_tmp)) {
00214 ALLOC_TABLE(m_crl_file,
00215 char*,
00216 sizeof(char),
00217 strlen(L_tmp)+1);
00218 sprintf(m_crl_file, "%s", L_tmp);
00219 L_ret = true ;
00220 }
00221
00222 L_tmp[0] = '\0' ;
00223 if (L_ret && analyze_string_value (P_buf,
00224 (char*)"secure=",
00225 L_tmp)) {
00226
00227 if (strcmp(L_tmp, (char*)"no") == 0){
00228 m_start_secure_mode = false ;
00229 }
00230 L_ret = true ;
00231 }
00232
00233 return (L_ret);
00234 }
00235
00236
00237 int C_TransIPTLS::analyze_config(T_ConfigValue& P_config) {
00238 int L_ret = 0 ;
00239 return (L_ret);
00240 }
00241
00242 C_TransIPTLS::C_TransIPTLS() : C_TransIP() {
00243 m_ssl_ctx = NULL ;
00244 m_passwd = NULL ;
00245 m_cert_chain_file = NULL ;
00246 m_private_key_file = NULL ;
00247 m_crl_file = NULL ;
00248 m_method = NULL ;
00249 m_start_secure_mode = true ;
00250 }
00251
00252 C_TransIPTLS::~C_TransIPTLS() {
00253 if (m_ssl_ctx) {
00254 SSL_CTX_free(m_ssl_ctx);
00255 }
00256 FREE_TABLE(m_passwd);
00257 FREE_TABLE(m_cert_chain_file);
00258 FREE_TABLE(m_private_key_file);
00259 FREE_TABLE(m_crl_file);
00260 }
00261
00262
00263
00264 int C_TransIPTLS::init (char *P_buf,
00265 T_logFunction P_logError,
00266 T_logFunction P_logInfo) {
00267
00268 int L_ret = 0 ;
00269
00270 L_ret = C_TransIP::init(P_buf, P_logError, P_logInfo) ;
00271 if (L_ret != -1 ) {
00272
00273 SSL_library_init();
00274 SSL_load_error_strings() ;
00275
00276 if ((m_ssl_ctx = SSL_CTX_new(((*m_method)()))) == NULL ) {
00277 GEN_ERROR(1, "SSL_CTX_new failed");
00278 L_ret = -1 ;
00279 } else {
00280 m_trans_type = E_SOCKET_TCP_MODE ;
00281 SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx,
00282 (void *)m_passwd);
00283 SSL_CTX_set_default_passwd_cb(m_ssl_ctx,
00284 passwd_call_back);
00285
00286 if (SSL_CTX_use_certificate_chain_file(m_ssl_ctx,
00287 m_cert_chain_file) != 1) {
00288 GEN_ERROR(1, "SSL_CTX_use_certificate_file failed");
00289 L_ret = -1 ;
00290 }
00291
00292 if (L_ret != -1) {
00293 if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx,
00294 m_private_key_file,
00295 SSL_FILETYPE_PEM))) {
00296 GEN_ERROR(1, "SSL_CTX_use_PrivateKey_file failed");
00297 L_ret = -1 ;
00298 }
00299
00300 if (L_ret != -1) {
00301
00302 if (!(SSL_CTX_load_verify_locations(m_ssl_ctx, m_cert_chain_file, 0))) {
00303 GEN_ERROR(1, "Cannot load CA");
00304 L_ret = -1 ;
00305 }
00306
00307 if (L_ret != -1) {
00308
00309 if (m_crl_file != NULL) {
00310 if(load_crls(m_crl_file) == -1) {
00311 GEN_ERROR(1, "Unable to load CRL file [" << m_crl_file << "]" );
00312 L_ret = -1 ;
00313 }
00314
00315
00316
00317 SSL_CTX_set_verify(m_ssl_ctx,
00318 SSL_VERIFY_PEER |
00319 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
00320 verify_callback);
00321 }
00322 }
00323 }
00324 }
00325 }
00326 }
00327
00328 return (L_ret);
00329
00330 }
00331
00332
00333 C_Socket* C_TransIPTLS::open (int P_channel_id,
00334 T_pIpAddr P_Addr,
00335 T_pOpenStatus P_status,
00336 C_ProtocolBinaryFrame *P_protocol) {
00337
00338 C_Socket *L_socket_created = NULL ;
00339
00340 if (m_start_secure_mode == true) {
00341
00342 int L_rc ;
00343
00344 GEN_DEBUG(1, "C_TransIPTLS::open ()");
00345
00346 switch (P_Addr->m_umode) {
00347 case E_IP_USAGE_MODE_SERVER: {
00348
00349 C_SecureSocketListen *L_Socket ;
00350
00351 NEW_VAR(L_Socket, C_SecureSocketListen(m_ssl_ctx,
00352 m_trans_type,
00353 P_Addr,
00354 P_channel_id,
00355 m_read_buffer_size,
00356 m_decode_buffer_size));
00357
00358 L_rc = L_Socket->_open(m_buffer_size, P_protocol) ;
00359 if (L_rc == 0) {
00360 L_socket_created = L_Socket ;
00361 *P_status = E_OPEN_OK ;
00362 } else {
00363 DELETE_VAR(L_Socket) ;
00364 *P_status = E_OPEN_FAILED ;
00365 }
00366 }
00367 break ;
00368
00369 case E_IP_USAGE_MODE_CLIENT: {
00370 C_SecureSocketClient *L_Socket ;
00371
00372 NEW_VAR(L_Socket, C_SecureSocketClient(m_ssl_ctx,
00373 m_trans_type,
00374 P_Addr,
00375 P_channel_id,
00376 m_read_buffer_size,
00377 m_decode_buffer_size));
00378
00379
00380 L_rc = L_Socket->_open(P_status, m_buffer_size, P_protocol) ;
00381 if (L_rc == 0) {
00382 L_socket_created = L_Socket ;
00383 } else {
00384 DELETE_VAR(L_Socket) ;
00385 *P_status = E_OPEN_FAILED ;
00386 }
00387 }
00388
00389 break ;
00390
00391 case E_IP_USAGE_MODE_UNKNOWN:
00392
00393 GEN_ERROR(1, "OPEN failed: Unsupported mode");
00394 *P_status = E_OPEN_FAILED ;
00395 break ;
00396 }
00397
00398 } else {
00399 L_socket_created = C_TransIP::open(P_channel_id,
00400 P_Addr,
00401 P_status,
00402 P_protocol) ;
00403 }
00404
00405 return (L_socket_created);
00406 }
00407
00408 C_Socket* C_TransIPTLS::make_secure (C_Socket *P_Socket) {
00409
00410 C_Socket *L_new = NULL ;
00411
00412 {
00413 C_SocketClient *L_socket = NULL ;
00414
00415 L_socket = dynamic_cast<C_SocketClient*>(P_Socket) ;
00416 if (L_socket != NULL) {
00417 NEW_VAR(L_new,
00418 C_SecureSocketClient(m_ssl_ctx,*L_socket));
00419 }
00420 }
00421
00422 if (L_new == NULL) {
00423 C_SocketServer *L_socket = NULL ;
00424
00425 L_socket = dynamic_cast<C_SocketServer*>(P_Socket) ;
00426 if (L_socket != NULL) {
00427 NEW_VAR(L_new,
00428 C_SecureSocketServer(m_ssl_ctx,*L_socket));
00429 }
00430 }
00431
00432
00433
00434 return (L_new);
00435 }
00436
00437 int C_TransIPTLS::set_option (int P_Channel_Id, char *P_buf) {
00438
00439 C_Socket *L_socket = NULL;
00440 T_SocketMap::iterator L_it ;
00441 int L_ret = 0 ;
00442
00443 L_it = m_socket_map.find(T_SocketMap::key_type(P_Channel_Id));
00444 if (L_it != m_socket_map.end()) {
00445 L_socket = make_secure (L_it->second);
00446 if (L_socket != NULL) {
00447 m_socket_map.erase(L_it);
00448 m_socket_map.insert(T_SocketMap::value_type(L_socket->get_id(),
00449 L_socket));
00450 } else {
00451
00452 L_ret = -1 ;
00453 }
00454
00455 } else {
00456 L_ret = -1 ;
00457 }
00458
00459 return (L_ret);
00460 }
00461
00462
00463
00464
00465 T_pTransport create_ciptlsio_instance () {
00466 C_TransIPTLS* L_inst ;
00467 NEW_VAR(L_inst, C_TransIPTLS());
00468 return (L_inst);
00469 }
00470
00471 void delete_ciptlsio_instance (T_ppTransport P_inst) {
00472 if (P_inst != NULL) {
00473 C_TransIPTLS* L_inst = (C_TransIPTLS*) *P_inst ;
00474 DELETE_VAR(L_inst);
00475 *P_inst = NULL ;
00476 }
00477 }