Hi, all.
Thanks for all the advices you all gave me on my previous question
regarding client certficate question.
I've attached simple client/server code I've been using to establish SSL
connection between TCP/IP client/server application program.
Client side verified server certificate without any problem, however the
server's error message indicates that the client doesn't have
certificate.
Coult you please take a moment to read my simple client/server code and
give me help to find what the problem is?
I've been struggling with this for a long time, but unfortunately I
don't even have a clue why this short,simple code is not working both
way.
I'd very,very much appreciate it if you could give me any hint to solve
the problem. :)
Thanks and have a great weekend!

/Best Regards,
 Sejin.


======================================================================
Client code
=======================================================================

/*
 * TLS Client example
 */
#include <string>
#include <stdio.h>
#include <memory.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>

#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

/* define HOME to be dir for key and cert files... */
#define HOME "./CA_Client/private/"
#define MYHOME "./CA_Client/newcerts/"

/* CA file to verify client certificate */
#define CERTF  HOME "CAcert.pem"

/* Certificate and Key used to identify itself to the server. */
#define MYCERTF MYHOME "newcert.pem"
#define MYKEYF  MYHOME "newkey.pem"

#define CHK_NULL(x) if ((x)==NULL) exit (1)
#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr);
exit(2); }

void main ()
{
  int err;
  int sd;
  struct sockaddr_in sa;
  SSL_CTX* ctx;
  SSL*     ssl;
  X509*    server_cert;
  char*    str;
  char     tmpbuf[4];
  char     buf [4096];
  SSL_METHOD *meth;

  SSL_library_init();
  SSLeay_add_ssl_algorithms();
  meth = TLSv1_client_method();
  SSL_load_error_strings();

  CHK_SSL(err);

  ctx = SSL_CTX_new (meth);                        CHK_NULL(ctx);

  int i = 0;


  if (SSL_CTX_set_options(ctx,SSL_VERIFY_PEER) <= 0 ) {
    printf(" VERIFICATION ERROR\n");
    exit(7);
  }


  //Set trusted CA certs for incomming server certificate
 if (SSL_CTX_load_verify_locations(ctx,CERTF,HOME) <= 0 ) {
   ERR_print_errors_fp(stderr);
   exit(3);
 }

 if (SSL_CTX_use_certificate_file(ctx, MYCERTF, SSL_FILETYPE_PEM) <= 0)
{
    ERR_print_errors_fp(stderr);
    exit(3);
  }


  if (SSL_CTX_use_PrivateKey_file(ctx, MYKEYF, SSL_FILETYPE_PEM) <= 0) {

    ERR_print_errors_fp(stderr);
    exit(4);
  }

  if (!SSL_CTX_check_private_key(ctx)) {
    fprintf(stderr,"Private key does not match the certificate public
key\n");
    exit(5);
  }



  /* ----------------------------------------------- */
  /* Create a socket and connect to server using normal socket calls. */


  sd = socket (AF_INET, SOCK_STREAM, 0);       CHK_ERR(sd, "socket");

  memset (&sa, '\0', sizeof(sa));
  sa.sin_family      = AF_INET;
  string address("192.168.174.233");

  sa.sin_addr.s_addr = inet_addr (address.c_str());
//"192.168.174.233");   /* Server IP */
  int port = 9540;
  sa.sin_port        = htons     (port);          /* Server Port number
*/

  err = connect(sd, (struct sockaddr*) &sa,
  sizeof(sa));                   CHK_ERR(err, "connect");

  /* ----------------------------------------------- */
  /* Now we have TCP conncetion. Start SSL negotiation. */

  ssl = SSL_new (ctx);                         CHK_NULL(ssl);
  SSL_set_fd (ssl, sd);

  printf("Connecting....\n");
  err = SSL_connect (ssl);                     CHK_SSL(err);
  printf("Connected to server.\n");

  /* Get the cipher - opt */

  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));

  /* Get server's certificate */

  server_cert = SSL_get_peer_certificate (ssl);
CHK_NULL(server_cert);
  if (SSL_get_verify_result(ssl) != X509_V_OK) {
    printf("Server certification verification error.\n");
    exit(5);
  }

  printf ("Server certificate:\n");


  str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0);
  CHK_NULL(str);
  printf ("\t subject: %s\n", str);

  free (str);

  str = X509_NAME_oneline (X509_get_issuer_name  (server_cert),0,0);
  CHK_NULL(str);
  printf ("\t issuer: %s\n", str);
  free (str);

  X509_free (server_cert);

  /* --------------------------------------------------- */
  /* DATA EXCHANGE - Send a message and receive a reply. */

  err = SSL_write (ssl, "Hello World!", strlen("Hello World!"));
CHK_SSL(err);

  err=SSL_peek(ssl,tmpbuf,3);
  tmpbuf[err] = '\0';

  printf("First 3 letters =%s \n",tmpbuf);
  err = SSL_read (ssl, buf, sizeof(buf) - 1);
CHK_SSL(err);
  buf[err] = '\0';
  printf ("Got %d chars:'%s'\n", err, buf);
  SSL_shutdown (ssl);  /* send SSL/TLS close_notify */

  /* Clean up. */

  close (sd);
  SSL_free (ssl);
  SSL_CTX_free (ctx);
}
/* EOF - cli.cpp */


==============================================================================

  Server code
================================================================================

/*
 * TLS Server example
 */


#include <string>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <iostream.h>

#include <openssl/rsa.h>       /* SSLeay stuff */
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>


/* define HOME to be dir for key and cert files... */
#define HOME "./CA_Server/newcerts/"
#define CLIENT_HOME "./CA_Server/private/"

/* Certificate and key file to identify itself to the client */
#define CERTF  HOME "newcert.pem"
#define KEYF  HOME  "newkey.pem"

/* CA file used to verify client certificate */
#define CLIENT_CERTF CLIENT_HOME "CAcert.pem"

#define CHK_NULL(x) if ((x)==NULL) exit (1)
#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr);
exit(2); }

static int verify_callback(int ok, X509_STORE_CTX *ctx) {

  char *s,buf[256];

  s =
X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf,256);
  if (s!=NULL) {
   cout << "Depth = " << ctx->error_depth << " " << buf << endl;
  }
  else
 cout << "X509_NAME_oneline returned NULL. " << endl;
  exit(0);
}

void main ()
{
  int err;
  int listen_sd;
  int sd;
  struct sockaddr_in sa_serv;
  struct sockaddr_in sa_cli;
  size_t client_len;
  SSL_CTX* ctx;
  SSL*     ssl;
  X509*    client_cert;
  char*    str;
  char     buf [4096];
  SSL_METHOD *meth;

  // A method to initialize global data

  SSL_library_init();
  SSL_load_error_strings();
  SSLeay_add_ssl_algorithms();
  meth = TLSv1_server_method();
  ctx = SSL_CTX_new (meth);
  if (!ctx) {
    ERR_print_errors_fp(stderr);
    exit(2);
  }

  if (SSL_CTX_set_options(ctx,SSL_VERIFY_PEER) <= 0) {
    printf(" VERIFICATION ERROR\n");
    exit(6);
  }

  if (SSL_CTX_load_verify_locations(ctx, CLIENT_CERTF,CLIENT_HOME) <= 0)
{
    ERR_print_errors_fp(stderr);
    exit(3);
  }

  if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) {

    ERR_print_errors_fp(stderr);
    exit(3);
  }

  if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(4);
  }


  if (!SSL_CTX_check_private_key(ctx)) {
    fprintf(stderr,"Private key does not match the certificate public
key\n");
    exit(5);
  }

  /*
  SSL_CTX_set_verify(ctx,
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
             verify_callback);
  printf("Callback function for verification error is set.\n");

  */

  /* ----------------------------------------------- */
  /* Prepare TCP socket for receiving connections */

  listen_sd = socket (AF_INET, SOCK_STREAM, 0);   CHK_ERR(listen_sd,
"socket");
  printf("Socket created....\n");

  memset (&sa_serv, '\0', sizeof(sa_serv));
  sa_serv.sin_family      = AF_INET;
  int port = 9540;

  string address("192.168.174.233");
  sa_serv.sin_addr.s_addr = inet_addr(address.c_str()); //INADDR_ANY;
  sa_serv.sin_port        = htons (port);          /* Server Port number
*/

  err = bind(listen_sd, (struct sockaddr*) &sa_serv,
      sizeof (sa_serv));                   CHK_ERR(err, "bind");
  printf("Socket bound to service...\n");

  /* Receive a TCP connection. */

  err = listen (listen_sd, 5);                    CHK_ERR(err,
"listen");

  client_len = sizeof(sa_cli);

  printf("Listening....\n");

  sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
  printf("Connection accepted.\n");


  CHK_ERR(sd, "accept");
  close (listen_sd);

  cout << "Remote IP address = " << inet_ntoa(sa_cli.sin_addr) << endl;
  cout << "Remote port number = " << ntohs(sa_cli.sin_port) << endl;

  /* ----------------------------------------------- */
  /* TCP connection is ready. Do server side SSL. */

  printf("Initiating ssl server process..\n");
  ssl = SSL_new (ctx);                           CHK_NULL(ssl);
  SSL_set_fd (ssl, sd);

  printf("Calling SSL_accept..\n");
  err = SSL_accept (ssl);                        CHK_SSL(err);

  /* Get the cipher - opt */

  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));

  /* Get client's certificate - opt */

  client_cert = SSL_get_peer_certificate (ssl);
  if (SSL_get_verify_result(ssl) != X509_V_OK) {
    printf("Client certification verification error.\n");
    exit(6);
  }

  if (client_cert != NULL) {
    printf ("Client certificate:\n");

    str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);

    CHK_NULL(str);
    printf ("\t subject: %s\n", str);
    free (str);

    str = X509_NAME_oneline (X509_get_issuer_name  (client_cert), 0, 0);

    CHK_NULL(str);
    printf ("\t issuer: %s\n", str);
    free (str);

    /* We could do all sorts of certificate verification stuff here
before
       deallocating the certificate. */

    X509_free (client_cert);
  } else
    printf ("Client does not have certificate.\n");

  /* DATA EXCHANGE - Receive message and send reply. */

  err = SSL_read (ssl, buf, sizeof(buf) - 1);
CHK_SSL(err);
  buf[err] = '\0';
  printf ("Got %d chars:'%s'\n", err, buf);

  err = SSL_write (ssl, "I hear you.", strlen("I hear you."));
CHK_SSL(err);

  /* Clean up. */

  close (sd);
  SSL_free (ssl);
  SSL_CTX_free (ctx);
}
/* EOF - serv.cpp */


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to