Click here to Skip to main content
15,916,951 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, am trying to code the OPENSSL, but at the runtime execution gets hung state at SSL_CONNECT(ssl) function nothing is returning. please help me for this case am so stuck.

//Application Function 
int openssl_client_connection(char *p_IpAdd, ...)
{   
char l_hostname[50];
   snprintf(l_hostname, sizeof(l_hostname), "%s:%d", p_IpAdd, p_Port);

   g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> TLS Connection for HostName NAME : %s", __FUNCTION__, __LINE__, l_hostname);

   SSL_CTX *ctx;
   BIO *lbio;
   SSL *ssl;

   const SSL_METHOD *method;
   SSL_library_init();
   OpenSSL_add_all_algorithms();  /* Load cryptos, et.al. */
   SSL_load_error_strings();   /* Bring in and register error messages */

   method = SSLv3_client_method();  /* Create new client-method instance */
   ctx = SSL_CTX_new(method);   /* Create new context */

   g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> Certificate name : %s and Private key : %s ", __FUNCTION__, __LINE__, p_Certfile, p_KeyFile);

   if(ctx == NULL)
   {
      g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> Failed to Create a Context using SSL_METHOD", __FUNCTION__, __LINE__);
      return false;
   }
   ERR_print_errors_fp(stderr);

  cout<<__LINE__<<endl;
   if(SSL_CTX_use_certificate_file(ctx, p_Certfile, SSL_FILETYPE_PEM) != 1)
   {
      g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> Failed to load the cerficate file", __FUNCTION__, __LINE__);
      return false;
   }

   ERR_print_errors_fp(stderr);

   cout<<__LINE__<<endl;
   if(SSL_CTX_use_PrivateKey_file(ctx, p_KeyFile, SSL_FILETYPE_PEM) != 1)
   {
      g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> Failed at Loading private key in TLS Function", __FUNCTION__, __LINE__);
      return false;
   }

   ERR_print_errors_fp(stderr);

   cout<<__LINE__<<endl;
   if(SSL_CTX_check_private_key(ctx) != 1)
   {
      g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> Failed at Checking private key in TLS Function", __FUNCTION__, __LINE__);
      return false;
   }

   ERR_print_errors_fp(stderr);

   cout<<__LINE__<<endl;
   SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);      //setup a mode to CTX this mode will retry if send's or receive get failed.
   ERR_print_errors_fp(stderr);
   cout<<__LINE__<<endl;
   SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);  //server certificate also will verify , if fails terminate the handshake.
   ERR_print_errors_fp(stderr);
   cout<<__LINE__<<endl;
   SSL_CTX_set_verify_depth(ctx, 1);      
ERR_print_errors_fp(stderr);
   cout<<__LINE__<<endl;

   ssl = SSL_new(ctx);
   if(ssl == NULL)
   {
      ERR_print_errors_fp(stderr);
      g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> initializing the ssl get failed\n", __FUNCTION__, __LINE__);
      return NULL;
   }

   ERR_print_errors_fp(stderr);
   cout<<__LINE__<<endl;
   if ((lbio = BIO_new_connect(l_hostname)) == NULL)
   {
      g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> Unable to connect the given hostname, please the hostname", __FUNCTION__, __LINE__);
      SSL_free(ssl);
      return NULL;
   }

   ERR_print_errors_fp(stderr);
   cout<<__LINE__<<endl;
   if (BIO_do_connect(lbio) != 1)
   {
      ERR_print_errors_fp(stderr);
      g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> Unable to connect the given hostname, please the hostname", __FUNCTION__, __LINE__);
      SSL_free(ssl);
      BIO_free(lbio);
      return NULL;
   }

   ERR_print_errors_fp(stderr);
   SSL_set_bio(ssl, lbio, lbio);
   ERR_print_errors_fp(stderr);

   cout<<__LINE__<<endl;
   if (1 != SSL_connect(ssl))   /* Here My code gets Hung state */
   {
      ERR_print_errors_fp(stderr);
      g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> SSL Connection establishment is failed", __FUNCTION__, __LINE__);
      SSL_CTX_free(ctx);        /* release context */
      SSL_free(ssl);
      BIO_free(lbio);
      return false;
   }
   else
   {
      g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> Connected with %s encryption\n", SSL_get_cipher(ssl));
      ShowCerts(ssl);        /* get any certs */
      g_Logger.log(LOG_LEVEL_NORMAL, "%s <Ln:%d> Connected to %s succefully..", __FUNCTION__, __LINE__, p_name.c_str());

    
      int l_Errno = -1;
      pthread_t l_ThreadId;
      pthread_attr_t attr;
      pthread_attr_init(&attr);
      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

      g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> Creating Separate Thread For [%s] Receiver", __FUNCTION__, __LINE__, p_name.c_str());
      if (0 != (l_Errno = pthread_create(&l_ThreadId, &attr, SslReader, (char*)P_name.c_str())))
      {
         g_Logger.log(LOG_LEVEL_WARNING, "%s <Ln:%d> Failed to create SslReader Thread [Ret:%d, Errno:%d, Err:%s]",
               __FUNCTION__, __LINE__, l_Errno, errno, strerror(errno));
         SSL_CTX_free(ctx);        /* release context */
         SSL_free(ssl);
         BIO_free(lbio);
         return false;
      }
      pthread_attr_destroy (&attr);
   }
   ERR_print_errors_fp(stderr);
   return true;
}

//Simulator server side
#include <stdio.h>
#include<iostream>
#include<string>
#include<stdlib.h>
#include<unistd.h>
#include <iostream>
#include <stddef.h>
#include <netdb.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fstream>
#include<sys/time.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <bits/stdc++.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <error.h>
using namespace std;

SSL *g_ssl;
int mmtfd;
string file_1, file_2, file_3, MMTPort, MMTIP, ESMEIP, ESMEPort;
list<string> g_recMap, g_mmtMap;
void *SSLServer(void*);
void *sendmmt(void*);
int startServer(SSL_CTX* ctx);
int main(int argc, char **argv)
{

   string xml = argv[1];
   file_1 = getValue(xml, "FILE_1");
   file_2 = getValue(xml, "FILE_2");
   file_3 = getValue(xml, "FILE_PATH");
   MMTIP = getValue(xml, "MMTIP");
   MMTPort = getValue(xml, "MMTPORT");
   ESMEIP = getValue(xml, "ESMEIP");
   ESMEPort = getValue(xml, "ESMEPORT");

   pthread_t   l_ThreadId;
   pthread_attr_t attr;
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

   if (0 != (pthread_create(&l_ThreadId, &attr, SSLServer ,NULL)))
   {
      cout<<__LINE__<<" Failed to create thread"<<endl;
      return -1;
   }

   pthread_attr_destroy (&attr);

   cout<<"OPENSSL Server Thread Created Successful\n";

   int SockFd = socket(AF_INET, SOCK_STREAM, 0);

   if (SockFd < 0)
   {
      cout<<__LINE__<<" Error Opening Socket Connection Exiting.."<<endl;
      exit(1);
   }
  cout<<__LINE__<<" Socket created successfully"<<endl;
   struct sockaddr_in serv_addr;
   int PortNum = atoi(MMTPort.c_str());
   memset((char *) &serv_addr, 0, sizeof(serv_addr));
   serv_addr.sin_family = AF_INET;

   serv_addr.sin_addr.s_addr = inet_addr(MMTIP.c_str());
   serv_addr.sin_port = htons(PortNum);

   if (0 > connect(SockFd,(struct sockaddr *)&serv_addr, sizeof(serv_addr)))
   {
      cout<<__LINE__<<" Failed to Connect .check it IP : "<<MMTIP.c_str()<<" PORT : "<<PortNum<<endl;
      return -1;
   }

   cout<<"MMT Tool Connected Successful for SockFD : "<<SockFd<<endl;

   mmtfd = SockFd;

   pthread_t   l_ThreadId1;
   pthread_attr_t attr1;
   pthread_attr_init(&attr1);
   pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);

   if (0 != (pthread_create(&l_ThreadId1, &attr1, sendmmt ,NULL)))
   {
      cout<<__LINE__<<" Failed to create thread"<<endl;
      return -1;
   }
   pthread_attr_destroy (&attr1);

   cout<<"Send to MMT Tool Thread Created\n";

   fd_set l_FdSet;
   char rec[200];
 while(1)
   {
      FD_ZERO(&l_FdSet);
      FD_SET(SockFd, &l_FdSet);
      if(-1 == select(SockFd + 1, &l_FdSet, 0, 0, NULL))
      {
         cout<<"Error Description : "<<strerror(errno)<<endl;
         close(SockFd);
      }

      if(FD_ISSET(SockFd, &l_FdSet))
      {
         memset(rec, 0, sizeof(rec));
         int val;
         val = recv(SockFd, rec, sizeof(rec), 0);

         if(val <= 0)
            cout<<__LINE__<<" Failed at recv and error msg : "<<strerror(errno)<<endl;
         cout<<"Received msg : "<<rec<<"\t"<<"size of msg : "<<val<<" and Error no : "<<errno<<endl;

         g_recMap.push_back(string(rec));
      }
   }

   return 1;
}

void* sendmmt(void*)
{
   while(1)
   {
      int l_size = g_mmtMap.size();
      if(l_size > 1)
      {
         for(list<string>::iterator itr = g_mmtMap.begin(); itr != g_mmtMap.end(); itr++)
         {
            string str = *itr;
            if ( 0 < send(mmtfd, str.c_str(), str.length(), 0))
            {
               cout<<__LINE__<<" send failed\n";
               return NULL;
            }
            else
               g_mmtMap.erase(itr);
         }
      }

      list<string> ::iterator itr1 = g_recMap.begin();
      for(itr1 = g_recMap.begin(); itr1 != g_recMap.end() ; itr1++)
      {
         cout<<"At g_Recmap sector\n";
         int n = -1;
         string str = *itr1;
         n = SSL_write(g_ssl, str.c_str(), str.length());
         if(n<=0)
         {
            cout<<__LINE__<<" ERROR in SSL_WRITE : ";
            perror("");
         }

         g_recMap.erase(itr1);
      }
	}
}

void* SSLServer(void*)
{
   SSL_library_init();
   SSL_load_error_strings();
   SSL_CTX* ctx;
   const SSL_METHOD * method;
   BIO *server_bio = NULL;
   BIO *client_bio = NULL;

   method = SSLv3_server_method();
   ctx = SSL_CTX_new(method);

   SSL *ssl = SSL_new (ctx);
   if (!ssl)
       cout<<__LINE__<<" Failed allocating SSL structure\n";

   if( 1 != SSL_CTX_use_certificate_file(ctx, file_2.c_str(), SSL_FILETYPE_PEM))
   {
      cout<<__LINE__<<" : "<<"SSL_CTX_use_certificate_file"<<" Gets Failed for Reason : "<<strerror(errno)<<endl;
      ERR_print_errors_fp(stderr);
      return NULL;
   }
   if(1 != SSL_CTX_use_PrivateKey_file(ctx, file_1.c_str(), SSL_FILETYPE_PEM))
   {
      cout<<__LINE__<<" : "<<"SSL_CTX_use_PrivateKey_file"<<" Gets Failed for Reason : "<<strerror(errno)<<endl;
      ERR_print_errors_fp(stderr);
      return NULL;
   }

   if (1 != SSL_CTX_check_private_key(ctx))
   {
      cout<<__LINE__<<" : "<<"SSL_CTX_check_private_key"<<" Gets Failed for Reason : "<<strerror(errno)<<endl;
      ERR_print_errors_fp(stderr);
      return NULL;
   }
#if 0
   if ((server_bio = BIO_new_accept(port)) == NULL)
       cout<<"Bio Accept getting failed\n"<<"Error Describtion : "<<strerror(errno)<<endl;

   if (BIO_do_accept(server_bio) <= 0)
      cout<<"Bio Do accept getting failed\n"<<"Error Describtion : "<<strerror(errno)<<endl;

   SSL_set_bio(my_ssl, client_bio, client_bio);

   if (SSL_accept(my_ssl) <= 0)
      cout<<"Bio accept getting failed\n"<<"Error Describtion : "<<strerror(errno)<<endl;

#endif



#if 0
   // load certificate and password
   if( 1 != SSL_CTX_load_verify_locations(ctx, file_1.c_str(), file_3.c_str()))
   {
      cout<<__LINE__<<" : "<<"SSL_CTX_load_verify_locations"<<" Gets Failed for Reason : "<<strerror(errno)<<endl;
      ERR_print_errors_fp(stderr);
      return NULL;
   }
#endif

   if( 1 != SSL_CTX_set_cipher_list(ctx, "SSLv2:SSLv3:TLSv1"))
   {
      cout<<__LINE__<<" : "<<"SSL_CTX_set_cipher_list"<<" Gets Failed for Reason : "<<strerror(errno)<<endl;
      ERR_print_errors_fp(stderr);
      return NULL;
   }
   SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);

   startServer(ctx);
   return NULL;
}

int startServer(SSL_CTX* ctx)
{
   int fd = socket(AF_INET, SOCK_STREAM, 0);
   if(fd < 1)
   {
      cout<<__LINE__<<" Opening New Socket Getting Failed\n";
      return -1;
   }

   int port = atoi(ESMEPort.c_str());
   struct sockaddr_in s1;
   s1.sin_family = AF_INET;
   s1.sin_addr.s_addr = INADDR_ANY;
   s1.sin_port = htons(port);

   if(bind(fd, (struct sockaddr*) &s1, sizeof(s1)))
   {
      cout<<__LINE__<<" Binding is failed, retry the binary_up\n";
      return -1;
   }

   listen(fd, 2);

   int sock;
   SSL * ssl = SSL_new(ctx);
   BIO * bio = BIO_new_socket(sock, BIO_NOCLOSE);
   SSL_set_bio(ssl, bio, bio);

   g_ssl = ssl;
   cout<<"INitiating a While Loop for continues connection\n";
   while (1)
   {
		
      int ret;
      if ((sock = accept(fd, NULL, 0)) < 0)
      {
         cout<<__LINE__<<" Error at accept \n";
         perror("accept");
         close(fd);
         return -1;
      }

      cout<<__LINE__<<" : "<<"Accept get successful\n";

      ret = SSL_accept(ssl);
      if (ret <= 0)
      {
         ERR_print_errors_fp(stderr);
         cout<<__LINE__<<" getting failure in SSL_accept\n";
      }
      else
      {
         char buf[20000];
         memset(buf, 0, sizeof(buf));
         int ret = SSL_read(ssl, buf, sizeof(buf));
         if (ret <= 0)
         {
            cout<<__LINE__<<" SSL_READ gets failed"<<" "<<__LINE__<<endl;
            break;
         }
         else
            g_mmtMap.push_back(string(buf));

         cout<<__LINE__<<" : SSL_READING successful No .of Bytes : "<<ret<<endl;
      }


#if 0
      if (!SSL_shutdown(ssl))
      {
         close(sock);
         SSL_shutdown(ssl);
      }
      SSL_free(ssl);

      stopServer(connection);
      close(sock);
#endif
      return 1;
   }
}


What I have tried:

have tried that code i have paste it, please check it.
Posted
Updated 29-Jul-22 3:00am

1 solution

I'm not going to wade through ~500 lines of code to try to figure out where things have gone wrong.

Start by using the openssl command line openssl s_connect host:port and confirm that your server is behaving correctly.

You're using SSLv3_client_method(), which limits the connection to only SSL_v3. You should probably prefer SSLv23_client_medthod() which will negotiate the highest SSL version that the server supports, from SSLv2 through TLSv1.2.

In order to figure out what's going wrong, I'd recommend writing the simplest program you can that will connect to the server. If/when that's working, take what you've learned and apply it to your project.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900