title: Client and Server communication using ssl c/c++ - SSL protocol don't works
body: <p>I'm trying use an SSL client/server example from:<a href="http://simplestcodings.blogspot.com.br/2010/08/secure-server-client-using-openssl-in-c.html">http://simplestcodings.blogspot.com.br/2010/08/secure-server-client-using-openssl-in-c.html</a> to create a secure connection using SSLv3. I made some changes for request the certificate on server-side, the comunication works fine and is understood in both sides. Thus, my problem is that when the client connects to server, the protocol communication SSLv3 is not working, I verified using the wirkeshark and in the protocol field just shows TCP, or IPA(RSL Malformed Packet) somebody can help me? Thanks!</p>
  
  <p>I've created my certificates following the tutorial <a href="https://help.ubuntu.com/community/OpenSSL">https://help.ubuntu.com/community/OpenSSL</a>.</p>
  
  <p>Here is my client code:</p>
  
  <pre><code>//SSL-Client.c
  #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
  
      //Added the LoadCertificates how in the server-side makes.    
  void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
  {
   /* 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();
      }
  }
  
  int OpenConnection(const char *hostname, int port)
  {   int sd;
      struct hostent *host;
      struct sockaddr_in addr;
  
      if ( (host = gethostbyname(hostname)) == NULL )
      {
          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 = SSLv3_client_method();  /* Create new client-method instance */
      ctx = SSL_CTX_new(method);   /* Create new context */
      if ( ctx == NULL )
      {
          ERR_print_errors_fp(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()
  {   SSL_CTX *ctx;
      int server;
      SSL *ssl;
      char buf[1024];
      int bytes;
      char hostname[]="127.0.0.1";
      char portnum[]="5000";
      char CertFile[] = "/home/myCA/cacert.pem";
      char KeyFile[] = "/home/myCA/private/cakey.pem";
  
      SSL_library_init();
  
      ctx = InitCTX();
      LoadCertificates(ctx, CertFile, KeyFile);
      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 */
          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>
  
  <p>And the server:</p>
  
  <pre><code>//SSL-Server.c
  #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
  
  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_METHOD *method;
      SSL_CTX *ctx;
  
      OpenSSL_add_all_algorithms();  /* load &amp; register all cryptos, etc. */
      SSL_load_error_strings();   /* load all error messages */
      method = SSLv3_server_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();
      }
  
      //New lines - Force the client-side have a certificate
      SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
      SSL_CTX_set_verify_depth(ctx, 4);
      //End new lines
  }
  
  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()
  {   SSL_CTX *ctx;
      int server;
      char portnum[]="5000";
  
          char CertFile[] = "/home/myCA/mycert.pem";
          char KeyFile[] = "/home/myCA/mycert.pem";
  
      SSL_library_init();
  
      ctx = InitServerCTX();        /* initialize SSL */
      LoadCertificates(ctx, CertFile, KeyFile); /* 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>