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]