title: Client-Server communication using OPENSSL (using Certificate)
body: <p>I'm using <a href="http://simplestcodings.blogspot.com.br/2010/08/secure-server-client-using-openssl-in-c.html" rel="nofollow">http://simplestcodings.blogspot.com.br/2010/08/secure-server-client-using-openssl-in-c.html</a> to generate client-server that communicate with each other using OPENSSL.</p>
  
  <p>I generate the certificate using same way as mention in the site and then I did run server part successfully.</p>
  
  <p>I did the client part too.But when i run,i got several error mention below(From Server side).</p>
  
  <p><strong>Usage: 5000 
  LoadCertificates Compleate Successfully.....
  139761812350824:error:140C5042:SSL routines:SSL_UNDEFINED_FUNCTION:called a function you should not call:ssl_lib.c:2421:
  Connection: 127.0.0.1:57320
  139761812350824:error:140C5042:SSL routines:SSL_UNDEFINED_FUNCTION:called a function you should not call:ssl_lib.c:2421:
  139761812350824:error:140C5042:SSL routines:SSL_UNDEFINED_FUNCTION:called a function you should not call:ssl_lib.c:2421:
  139761812350824:error:140780E5:SSL routines:SSL23_READ:ssl handshake failure:s23_lib.c:138:
  Connection: 127.0.0.1:57402
  No certificates.</strong></p>
  
  <p>My code is slightly modified................</p>
  
  <p><strong>//client</strong></p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;malloc.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;resolv.h&gt;
  #include &lt;netdb.h&gt;
  #include &lt;openssl/ssl.h&gt;
  #include &lt;openssl/err.h&gt;
  
  #define FAIL    -1
  
  int OpenConnection(const char *hostname, int port)
  {   int sd;
  struct hostent *host;
  struct sockaddr_in addr;
  
  if ( (host = gethostbyname(hostname)) == NULL )
  {
      printf('Eroor: %s\n',hostname);
      perror(hostname);
      abort();
  }
  sd = socket(PF_INET, SOCK_STREAM, 0);
  bzero(&amp;addr, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
  addr.sin_addr.s_addr = *(long*)(host-&gt;h_addr);
  if ( connect(sd, (struct sockaddr*)&amp;addr, sizeof(addr)) != 0 )
  {
      close(sd);
      perror(hostname);
      abort();
  }
  return sd;
  }
  
  SSL_CTX* InitCTX(void)
  {   SSL_METHOD *method;
  SSL_CTX *ctx;
  
  OpenSSL_add_all_algorithms();  /* Load cryptos, et.al. */
  SSL_load_error_strings();   /* Bring in and register error messages */
  method = SSLv2_client_method();  /* Create new client-method instance */
  ctx = SSL_CTX_new(method);   /* Create new context */
  if ( ctx == NULL )
  {
      ERR_print_errors_fp(stderr);
      printf('Eroor: %s\n',stderr);
      abort();
  }
  return ctx;
  }
  
  void ShowCerts(SSL* ssl)
  {   X509 *cert;
      char *line;
  
      cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
      if ( cert != NULL )
      {
      printf("Server certificates:\n");
      line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
      printf("Subject: %s\n", line);
      free(line);       /* free the malloc'ed string */
      line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
      printf("Issuer: %s\n", line);
      free(line);       /* free the malloc'ed string */
      X509_free(cert);     /* free the malloc'ed certificate copy */
  }
  else
      printf("No certificates.\n");
  }
  
  int main(int count, char *strings[])
  {   SSL_CTX *ctx;
  int server;
  SSL *ssl;
  char buf[1024];
  int bytes;
  char *hostname, *portnum;
  
  if ( count != 3 )
  {
      printf("usage: %s &lt;hostname&gt; &lt;portnum&gt;\n", strings[0]);
      exit(0);
  }
  
  
  SSL_library_init();
  hostname=strings[1];
  portnum=strings[2];
  
  ctx = InitCTX();
  server = OpenConnection(hostname, atoi(portnum));
  ssl = SSL_new(ctx);      /* create new SSL connection state */
  SSL_set_fd(ssl, server);    /* attach the socket descriptor */
  if ( SSL_connect(ssl) == FAIL )   /* perform the connection */
  {
      printf('Eroor: %s\n',stderr);
      ERR_print_errors_fp(stderr);
  }
  else
  {   char *msg = "Hello???";
  
      printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
      ShowCerts(ssl);        /* get any certs */
      SSL_write(ssl, msg, strlen(msg));   /* encrypt &amp; send message */
      bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply &amp; decrypt */
      buf[bytes] = 0;
      printf("Received: \"%s\"\n", buf);
      SSL_free(ssl);        /* release connection state */
  }
  close(server);         /* close socket */
  SSL_CTX_free(ctx);        /* release context */
  return 0;
  }
  </code></pre>
  
  <hr>
  
  <pre><code>#include &lt;errno.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;malloc.h&gt;
  #include &lt;string.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;resolv.h&gt;
  #include "openssl/ssl.h"
  #include "openssl/err.h"
  
  #define FAIL    -1
  using namespace std;
  
  int OpenListener(int port)
  {   int sd;
  struct sockaddr_in addr;
  
  sd = socket(PF_INET, SOCK_STREAM, 0);
  bzero(&amp;addr, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
  addr.sin_addr.s_addr = INADDR_ANY;
  if ( bind(sd, (struct sockaddr*)&amp;addr, sizeof(addr)) != 0 )
  {
      perror("can't bind port");
      abort();
  }
  if ( listen(sd, 10) != 0 )
  {
      perror("Can't configure listening port");
      abort();
  }
  return sd;
  }
  
  SSL_CTX* InitServerCTX(void)
  {
  SSL_CTX *ctx = NULL;
  
      #if OPENSSL_VERSION_NUMBER &gt;= 0x10000000L
             const SSL_METHOD *method;
      #else
              SSL_METHOD *method;
      #endif
  
      SSL_library_init();
      OpenSSL_add_all_algorithms();  /* load &amp; register all cryptos, etc. */
      SSL_load_error_strings();   /* load all error messages */
  
  
  
      method = SSLv23_client_method(); /* create new server-method instance */
      ctx = SSL_CTX_new(method);   /* create new context from method */
      if ( ctx == NULL )
      {
          ERR_print_errors_fp(stderr);
          abort();
      }
      return ctx;
  }
  
  void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
  {
  //New lines
      if (SSL_CTX_load_verify_locations(ctx, CertFile, KeyFile) != 1)
          ERR_print_errors_fp(stderr);
  
      if (SSL_CTX_set_default_verify_paths(ctx) != 1)
          ERR_print_errors_fp(stderr);
      //End new lines
  /* set the local certificate from CertFile */
  if ( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) &lt;= 0 )
  {
      ERR_print_errors_fp(stderr);
      abort();
  }
  /* set the private key from KeyFile (may be the same as CertFile) */
  if ( SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) &lt;= 0 )
  {
      ERR_print_errors_fp(stderr);
      abort();
  }
  /* verify private key */
  if ( !SSL_CTX_check_private_key(ctx) )
  {
      fprintf(stderr, "Private key does not match the public certificate\n");
      abort();
  }
  printf("LoadCertificates Compleate Successfully.....\n");
  }
  
  void ShowCerts(SSL* ssl)
  {   X509 *cert;
  char *line;
  
  cert = SSL_get_peer_certificate(ssl); /* Get certificates (if available) */
  if ( cert != NULL )
  {
      printf("Server certificates:\n");
      line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
      printf("Subject: %s\n", line);
      free(line);
      line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
      printf("Issuer: %s\n", line);
      free(line);
      X509_free(cert);
  }
  else
      printf("No certificates.\n");
  }
  
  void Servlet(SSL* ssl) /* Serve the connection -- threadable */
  {   char buf[1024];
  char reply[1024];
  int sd, bytes;
  const char* HTMLecho="&lt;html&gt;&lt;body&gt;&lt;pre&gt;%s&lt;/pre&gt;&lt;/body&gt;&lt;/html&gt;\n\n";
  
  if ( SSL_accept(ssl) == FAIL )     /* do SSL-protocol accept */
      ERR_print_errors_fp(stderr);
  else
  {
      ShowCerts(ssl);        /* get any certificates */
      bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */
      if ( bytes &gt; 0 )
      {
          buf[bytes] = 0;
          printf("Client msg: \"%s\"\n", buf);
          sprintf(reply, HTMLecho, buf);   /* construct reply */
          SSL_write(ssl, reply, strlen(reply)); /* send reply */
      }
      else
          ERR_print_errors_fp(stderr);
  }
  sd = SSL_get_fd(ssl);       /* get socket connection */
  SSL_free(ssl);         /* release SSL state */
  close(sd);          /* close connection */
  }
  
  int main(int count, char *strings[])
  {   SSL_CTX *ctx;
  int server;
  char *portnum;
  
  if ( count != 2 )
  {
      printf("Usage: %s &lt;portnum&gt;\n", strings[0]);
      exit(0);
  }
  else
  {
      printf("Usage: %s &lt;portnum&gt;\n", strings[1]);
  }
  SSL_library_init();
  
  portnum = strings[1];
  ctx = InitServerCTX();        /* initialize SSL */
  LoadCertificates(ctx, "/home/stud/kawsar/mycert.pem", "/home/stud/kawsar/mycert.pem");  /* load certs */
  server = OpenListener(atoi(portnum));    /* create server socket */
  while (1)
  {   struct sockaddr_in addr;
      socklen_t len = sizeof(addr);
      SSL *ssl;
  
      int client = accept(server, (struct sockaddr*)&amp;addr, &amp;len);  /* accept connection   as usual */
      printf("Connection: %s:%d\n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
      ssl = SSL_new(ctx);              /* get new SSL state with context */
      SSL_set_fd(ssl, client);      /* set connection socket to SSL state */
      Servlet(ssl);         /* service connection */
  }
  close(server);          /* close server socket */
  SSL_CTX_free(ctx);         /* release context */
  }
  </code></pre>