title: OpenSSl Error: peer did not return a certificate
body: <p>I am using OpenSSL integration on my existing code to achieve SSL security. My Client side code is in c++ and is on Windows OS and the back-end code, server, code is on AIX.</p>
  
  <p><strong>The certificates are created by following the below commands on AIX and the client certificate and key created are being used at clent end i.e Windows:</strong></p>
  
  <p>/<em>/Commands to create the CA authority</em></p>
  
  <ol>
  <li><p>openssl genrsa -des3 -out Keys/RootCA_test.key 2048</p></li>
  <li><p>openssl req -new -x509 -days 360 -key Keys/RootCA_test.key -out Certificates/RootCA_test.crt</p></li>
  </ol>
  
  <p><em>//Commands to create the server certificate</em></p>
  
  <ol start="3">
  <li>openssl genrsa -out Keys/server_test.key 2048</li>
  <li>openssl req -new -key Keys/server_test.key -out CSR/server_test.csr</li>
  <li>openssl ca -days 360 -in CSR/server_test.csr -out Certificates/server_test.crt -keyfile Keys/RootCA_test.key -cert Certificates/RootCA_test.crt</li>
  </ol>
  
  <p><em>//Commands to create the client certificate</em></p>
  
  <ol start="6">
  <li><p>openssl genrsa -out Keys/client_test.key 2048</p></li>
  <li><p>openssl req -new -key Keys/client_test.key -out CSR/client_test.csr</p></li>
  <li><p>openssl ca -days 360 -in CSR/client_test.csr -out Certificates/client_test.crt -keyfile Keys/RootCA_test.key -cert Certificates/RootCA_test.crt  </p></li>
  </ol>
  
  <p><strong>After integrating the code looks like:</strong></p>
  
  <p><strong>Client Code - On Windows</strong>    </p>
  
  <pre><code> #include "stdafx.h"
      #include &lt;string&gt;
      #include &lt;stdio.h&gt;
      #include &lt;openssl/ssl.h&gt; // SSL and SSL_CTX for SSL connections
      #include &lt;openssl/err.h&gt; // Error reporting
  
  
      SOCKET s;
      SSL_CTX *ctx;
      SSL *ssl;
      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(AF_INET, SOCK_STREAM,IPPROTO_TCP);    
          memset(&amp;addr,0, 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;
      }
  
      BOOL InitOpenSSL()//OPENSSL
      {
          //set default locations for trusted CA certificates
          CString sslCrtFilePath  = "C:\\Program Files\\cv\\certificates\\client_test.crt";
          CString sslKeyFilePath  = "C:\\Program Files\\cv\\certificates\\client_test.key";
          CString sslRootFilePath = "C:\\Program Files\\cv\\certificates\\RootCA_test.crt";
          int server;
          char buf[1024];
          int bytes;
          char hostname[]="20.17.127.235";   
          int portnum = 4005;
          SSL_library_init();
          SSL_METHOD *method;    
  
          OpenSSL_add_all_algorithms();  /* Load cryptos, et.al. */
          SSL_load_error_strings();   /* Bring in and register error messages */
          method = SSLv23_client_method();//SSLv23_method();  /* Create new client-method instance */
          ctx = SSL_CTX_new(method);   /* Create new context */
          if ( ctx == NULL )
          {        
              abort();
          }
          if (!(LoadCertificates(sslRootFilePath.GetBuffer(sslRootFilePath.GetLength()),sslCrtFilePath.GetBuffer(sslCrtFilePath.GetLength()), sslKeyFilePath.GetBuffer(sslKeyFilePath.GetLength()))))
          {
              s = INVALID_SOCKET;     
              cout &lt;&lt; "Failed to load certificate file and key file.";
              return false;
          }   
          ctx  = SSL_CTX_new(method);   /* Create new context */  
          ssl = SSL_new(ctx);      /* create new SSL connection state */
          if ( ctx == NULL )
          {
              ERR_print_errors_fp(stderr);
              s = INVALID_SOCKET;
              cout &lt;&lt; "Error in creating SSL_CTX object.";
              return FALSE;
          }
          server = OpenConnection(hostname, portnum);
          SSL_set_fd(ssl, server);    /* attach the socket descriptor */   
          int n = SSL_connect(ssl);
          if ( n != 1 )   /* perform the connection */
          {
              int rc = SSL_get_error(ssl,n);  
              cout &lt;&lt; "Error in SSL_connect";      
              exit(1);
          }
          else
          {   char *msg = "Hello! I am Client.Who are you ?\n";
              cout &lt;&lt; "Connected with " &lt;&lt; SSL_get_cipher(ssl) &lt;&lt; " encryption" ;        
              SSL_write(ssl, msg, strlen(msg));   /* encrypt &amp; send message */
              bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply &amp; decrypt */
              buf[bytes] = 0;
              cout &lt;&lt; buf;
              SSL_free(ssl);        /* release connection state */
          }
          close(server);         /* close socket */
          SSL_CTX_free(ctx);        /* release context */
          return 0;   
  
      }
      bool LoadCertificates(char* sslRootFilePath,char* CertFile, char* KeyFile)//OPENSSL
      {
           if(!SSL_CTX_load_verify_locations(ctx,sslRootFilePath , NULL))
              {
                  /* Handle error here */ 
                  s = INVALID_SOCKET;
                  cout &lt;&lt; "Failed to load root CA certificate.";
                  return FALSE;
              }       
              /*Set cipher list*/
              if (SSL_CTX_set_cipher_list(ctx,CIPHER_LIST) &lt;= 0) 
              {
                  cout &lt;&lt; "Error setting the cipher list.";
              }
  
              if ( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM ) &lt;= 0 )
              {
                  cout &lt;&lt; "Failed in setting the local certificate from CertFile.";
                  return false;
              }
              /* set the private key from KeyFile (may be the same as CertFile) */
               if ( SSL_CTX_use_PrivateKey_file (ctx, KeyFile , SSL_FILETYPE_PEM) != 1 ) //SSL_FILETYPE_PEM
              {
                  cout &lt;&lt; "Failed in setting the private key from KeyFile.";
                  return false;        
              }
              /* verify private key */
              if ( !SSL_CTX_check_private_key(ctx) )
              {
                  cout &lt;&lt; ("Failed in verifying private key.", MB_TOPMOST | MB_SETFOREGROUND|MB_OK);
                  return false;        
              }
      }
      int main()
      {   
          BOOL st = InitOpenSSL();
          return 0;
      }
  </code></pre>
  
  <p><strong>Server Code On AIX</strong> </p>
  
  <p>SSL_CTX *ctx;
          SSL *ssl;</p>
  
  <pre><code>    string root,key,cert;
      int OpenListener(int port)
      {
           cout &lt;&lt;  "OpenListener() Start" &lt;&lt; endl ;
           int sd;
          struct sockaddr_in addr;   
          int portno = 4005;
          sd = socket(AF_INET, SOCK_STREAM, 0); 
           memset(&amp;addr,0, sizeof(addr));
  
           addr.sin_family = AF_INET;
           addr.sin_port = htons(portno);
           addr.sin_addr.s_addr = INADDR_ANY;
  
  
          if ( bind(sd, (struct sockaddr*)&amp;addr, sizeof(addr)) != 0 )
          {
              cout &lt;&lt; "can't bind port" &lt;&lt; endl;
              abort();
          }
          if ( listen(sd, 10) != 0 )
          {
           cout &lt;&lt; "Can't configure listening port" &lt;&lt; endl;
           abort();
          }
          cout &lt;&lt; "Port : " &lt;&lt;  addr.sin_port  &lt;&lt; " Address : " &lt;&lt; addr.sin_addr.s_addr &lt;&lt; endl;
          cout &lt;&lt;  "OpenListener() End" &lt;&lt; endl ;
          return sd;
      }
      void Servlet(SSL* ssl) 
      {
       cout &lt;&lt;  "Servlet() Start" &lt;&lt; endl;
       char buf[1024];
       char reply[1024];
       int sd, bytes;
  
       if ( SSL_accept(ssl) != 1 )     /* do SSL-protocol accept */
       ERR_print_errors_fp(stderr);
       else
        {
              cout &lt;&lt;  "SSL_accept() executed" &lt;&lt; endl;
              ShowCerts();        /* get any certificates */
              bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */
              if ( bytes &gt; 0 )
              {
                  buf[bytes] = 0;
                  cout &lt;&lt; "Client msg: " &lt;&lt;  buf &lt;&lt; endl;            
                  SSL_write(ssl, reply, strlen(reply)); /* send reply */
              }
              else
                {
                  cout &lt;&lt; " Bytes returned by SSL_read() is 0" &lt;&lt; endl;
                  ERR_print_errors_fp(stderr);
                 }
          }
          sd = SSL_get_fd(ssl);       /* get socket connection */
          SSL_free(ssl);         /* release SSL state */
          close(sd);          /* close connection */
          cout &lt;&lt;  "Servlet() End" &lt;&lt; endl;
      }
      void ShowCerts()
      {
          cout &lt;&lt;  "ShowCerts() Start " &lt;&lt; endl;
          X509 *cert;
          char *line;
          cout &lt;&lt; "SSL_get_peer_certificate Initiated " &lt;&lt; endl;
          cert = SSL_get_peer_certificate(ssl);       /* Get certificates (if available) */
          if ( cert != NULL )
          {
              cout &lt;&lt; "Server certificates: " &lt;&lt; endl;
              line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
              cout &lt;&lt; "Subject: " &lt;&lt; line  &lt;&lt; endl;
              free(line);
              line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
              cout &lt;&lt; "Issuer: " &lt;&lt; line  &lt;&lt; endl;
              free(line);
              X509_free(cert);
          }
          else
            cout &lt;&lt; "SSL_get_peer_certificate() returns NULL  " &lt;&lt; endl;
  
          cout &lt;&lt;  "ShowCerts() End " &lt;&lt; endl;
  
      }
  
      bool InitOpenSSL()
      {
          cout &lt;&lt;  "InitOpenSSL() Starts" &lt;&lt; endl;
          SSL_library_init();
          SSL_METHOD *method;
  
          OpenSSL_add_all_algorithms();  /* Load cryptos, et.al. */
          SSL_load_error_strings();   /* Bring in and register error messages */
          method = const_cast &lt;SSL_METHOD *&gt; (SSLv23_server_method());  /* Create new server-method instance */
          ctx  = SSL_CTX_new(method);   /* Create new context */
  
              if ( ctx == NULL )
              {
                      ERR_print_errors_fp(stderr);
                      cout &lt;&lt; "Error in creating SSL_CTX object."  &lt;&lt; endl;
                      return false;
              }
              //set default locations for trusted CA certificates
              cout &lt;&lt; "Server Certificate Used : " &lt;&lt; cert &lt;&lt; endl;
              cout &lt;&lt; "Server Key Used         : " &lt;&lt; key  &lt;&lt; endl;
              if (!(LoadCertificates(const_cast&lt;char *&gt; (cert.c_str()), const_cast &lt;char*&gt; (key.c_str()))) )
              {
                      cout &lt;&lt; "Failed to load certificate file and key file." &lt;&lt; endl;
                      return false;
              }
             SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
             SSL_CTX_set_verify_depth(ctx, 4); 
             if(!SSL_CTX_load_verify_locations(ctx,root.c_str() , NULL) )
                cout &lt;&lt; "SSL_CTX_load_verify_locations failed." &lt;&lt; endl;
             else
                cout &lt;&lt; "SSL_CTX_load_verify_locations passed." &lt;&lt; endl;
  
             int  server = OpenListener(4005);                                /* create server socket */
             cout &lt;&lt; "OpenListener() returns : " &lt;&lt; server &lt;&lt; endl;
             while (1)
             {
               cout &lt;&lt; "In While(1) Loop " &lt;&lt; endl;
               struct sockaddr_in addr;
               socklen_t len = sizeof(addr);
               cout &lt;&lt; "::accept() called, get ready!" &lt;&lt; endl ;
               int client = ::accept(server, (struct sockaddr*)&amp;addr, &amp;len);          /* accept connection as usual */
               cout &lt;&lt; "::accept() returns " &lt;&lt; client &lt;&lt; endl;
               //printf("Connection: %s:%d\n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
               cout &lt;&lt; "Connection " &lt;&lt; inet_ntoa(addr.sin_addr) &lt;&lt; ntohs(addr.sin_port) &lt;&lt; endl;
               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 */
          cout &lt;&lt;  "InitOpenSSL() Ends" &lt;&lt; endl;
      }
      bool LoadCertificates(char* CertFile, char* KeyFile)
      {
          cout &lt;&lt;  "LoadCertificates() Start" &lt;&lt; endl;
          bool rc = true;
           /* set the local certificate from CertFile */
          if ( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) &lt;= 0 )
              {
                 cout &lt;&lt; "Failed to get the certificate file" &lt;&lt; endl;
                 rc = false;
              }
              /* 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 )
          {
                 cout &lt;&lt; "Failed to get the private key file" &lt;&lt; endl;
                 rc = false;
              }
              /* verify private key */
          if ( !SSL_CTX_check_private_key(ctx) )
          {
                cout &lt;&lt; "Private key does not match the public certificate" &lt;&lt; endl;
                rc = false;
              }
          cout &lt;&lt;  "LoadCertificates() End" &lt;&lt; endl;
              return rc;
      }
  
  
  
      int main()
      {
              cout &lt;&lt; "Root path:" &lt;&lt; endl;
              cin &gt;&gt; root;
              cout &lt;&lt; "Key path:" &lt;&lt; endl;
              cin &gt;&gt; key;
              cout &lt;&lt; "Cert path:" &lt;&lt; endl;
              cin &gt;&gt; cert;
  
              InitOpenSSL();
              return 0;
      }
  </code></pre>
  
  <p>On Running the server on AIX and then the client on Windows , Output is something like:</p>
  
  <pre><code>Root path:
  /tmp/Certificates/RootCA_test.crt
  Key path:
  /tmp/Keys/server_test.key 
  Cert path:
  /tmp/Certificates/server_test.crt
  
  InitOpenSSL() Starts
  Server Certificate Used : /tmp/Certificates/server_test.crt
  Server Key Used         : /tmp/Keys/server_test.key
  LoadCertificates() Start
  LoadCertificates() End
  SSL_CTX_load_verify_locations passed for /tmp/Certificates/RootCA_test.crt
  OpenListener() Start
  Port : 4005 Address : 0
  OpenListener() End
  OpenListener() returns : 3
  In While(1) Loop
  ::accept() called, get ready!
  ::accept() returns 4
  Connection xx.xx.xx.xxxxx
  Servlet() Start    
  **1152921504606846944:error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate:s3_srvr.c:3281:**
  Servlet() End
  In While(1) Loop
  ::accept() called, get ready!
  </code></pre>
  
  <p>Please can you help me with this error :  <strong>1152921504606846944:error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate:s3_srvr.c:3281:</strong></p>
  
  <p>I tried various links and googled out too but no answer seems to work for this!</p>
  
  <p>Is the way by which I am creating the certificates and key is OK?</p>
  
  <p>Is there any piece of code needs to be added or removed in client/server code snippet given above? As there are many different approaches for doing the same!</p>
  
  <p>An interesting conclusion is that when I run openssl commmand on the <strong>AIX server, it seems to make a connectivity</strong>: </p>
  
  <pre><code>my_server_07:  openssl s_server -cert /tmp/Certificates/server_test.crt -key /tmp/Keys/server_test.key -port 4005
  Using default temp DH parameters
  Using default temp ECDH parameters
  ACCEPT
  
  -----BEGIN SSL SESSION PARAMETERS-----
  MFUCAQECAgMDBALAMAQABDDNSf27vf0Jg6GLr+Z7DP/DasT0+dCDRprYoQ4kMMIk
  bwtptVYQUgIpkLk/SRDhdhqhBgIEVkB9J6IEAgIBLKQGBAQAAAAB
  -----END SSL SESSION PARAMETERS-----
  Shared ciphers:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA
  CIPHER is ECDHE-RSA-AES256-GCM-SHA384
  Secure Renegotiation IS supported
  Hello! I am Client.Who are you ?
  I am Server AIX :)
  </code></pre>
  
  <p><em>This works fine which gives me an impression that my client side code and certificates are OK and are working fine as I am able to receive the client message on server and the server message on client. Isn't it ?</em></p>
  
  <p>But when I run the the server side code of mine on AIX and the client side openssl command as follows:
  <strong>C:\Windows\system32>openssl s_client -connect xx.xx.xxx.xxx:4005</strong></p>
  
  <p>The output is as follows <strong>on Client Side</strong> (server shows the same error: <strong>1152921504606846944:error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate:s3_srvr.c:3281:</strong>)</p>
  
  <pre><code>Loading 'screen' into random state - done
  CONNECTED(000000D0)
  depth=1 /C=IN/ST=XX/L=AAA/O=BBB/OU=CCC/CN=root_crt/emailAddress=ans@gmail.com
  verify error:num=19:self signed certificate in certificate chain
  verify return:0
  1520:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:.\ssl\s3_pkt.c:1146:SSL alert number 40
  1520:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:.\ssl\s23_lib.c:178:**
  </code></pre>
  
  <p><em>The error : verify error:num=19:self signed certificate in certificate chain seems to point to some type of certificate signing process. I looked on the various forums and the opessl.org but nowhere seems to give a proper working resolution of this.</em></p>
  
  <p><strong><em>Please help me in whatever way you think that can lead to fix these issues.
  Thanks in advance....!!</em></strong></p>