/home/dko/projects/mobilec/trunk/src/security/xyssl-0.7/programs/ssl/ssl_client2.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 174 $ : Last Committed Revision
00003  * $Date: 2008-06-24 10:50:29 -0700 (Tue, 24 Jun 2008) $ : Last Committed Date */
00004 /*
00005  *  SSL client with certificate authentication
00006  *
00007  *  Copyright (C) 2006-2007  Christophe Devine
00008  *
00009  *  This library is free software; you can redistribute it and/or
00010  *  modify it under the terms of the GNU Lesser General Public
00011  *  License, version 2.1 as published by the Free Software Foundation.
00012  *
00013  *  This library is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Lesser General Public
00019  *  License along with this library; if not, write to the Free Software
00020  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00021  *  MA  02110-1301  USA
00022  */
00023 
00024 #ifndef _CRT_SECURE_NO_DEPRECATE
00025 #define _CRT_SECURE_NO_DEPRECATE 1
00026 #endif
00027 
00028 #include <string.h>
00029 #include <stdio.h>
00030 
00031 #include "xyssl/net.h"
00032 #include "xyssl/ssl.h"
00033 #include "xyssl/havege.h"
00034 #include "xyssl/certs.h"
00035 #include "xyssl/x509.h"
00036 
00037 #define SERVER_PORT 4433
00038 /*
00039 #define SERVER_NAME "localhost"
00040 #define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"
00041 */
00042 #define SERVER_NAME "xyssl.org"
00043 #define GET_REQUEST \
00044     "GET /hello/ HTTP/1.0\r\n" \
00045     "Host: xyssl.org\r\n\r\n"
00046 
00047 int main( void )
00048 {
00049     int ret, len;
00050     int server_fd;
00051     unsigned char buf[1024];
00052     havege_state hs;
00053     ssl_context ssl;
00054     x509_cert cacert;
00055     x509_cert clicert;
00056     rsa_context rsa;
00057 
00058     /*
00059      * 1.1. Load the trusted CA
00060      */
00061     printf( "\n  . Loading the CA root certificate ..." );
00062     fflush( stdout );
00063 
00064     memset( &cacert, 0, sizeof( x509_cert ) );
00065 
00066     /*
00067      * Alternatively, you may load the CA certificate from a pem or
00068      * crt file by calling x509_read_crtfile( &cacert, "myca.crt" ).
00069      */
00070     ret = x509_add_certs( &cacert, (unsigned char *) xyssl_ca_crt,
00071                           strlen( xyssl_ca_crt ) );
00072     if( ret != 0 )
00073     {
00074         printf( " failed\n  ! x509_add_certs returned %08x\n\n", ret );
00075         goto exit;
00076     }
00077 
00078     printf( " ok\n" );
00079 
00080     /*
00081      * 1.2. Load own certificate and private key
00082      *
00083      * (can be skipped if client authentication is not required)
00084      */
00085     printf( "  . Loading the client cert. and key..." );
00086     fflush( stdout );
00087 
00088     memset( &clicert, 0, sizeof( x509_cert ) );
00089 
00090     ret = x509_add_certs( &clicert, (unsigned char *) test_cli_crt,
00091                           strlen( test_cli_crt ) );
00092     if( ret != 0 )
00093     {
00094         printf( " failed\n  ! x509_add_certs returned %08x\n\n", ret );
00095         goto exit;
00096     }
00097 
00098     ret = x509_parse_key( &rsa, (unsigned char *) test_cli_key,
00099                           strlen( test_cli_key ), NULL, 0 );
00100     if( ret != 0 )
00101     {
00102         printf( " failed\n  ! x509_parse_key returned %08x\n\n", ret );
00103         goto exit;
00104     }
00105 
00106     printf( " ok\n" );
00107 
00108     /*
00109      * 2. Initiate the connection
00110      */
00111     printf( "  . Connecting to tcp/%s/%-4d...", SERVER_NAME,
00112                                                 SERVER_PORT );
00113     fflush( stdout );
00114 
00115     if( ( ret = net_connect( &server_fd, SERVER_NAME,
00116                                          SERVER_PORT ) ) != 0 )
00117     {
00118         printf( " failed\n  ! net_connect returned %08x\n\n", ret );
00119         goto exit;
00120     }
00121 
00122     printf( " ok\n" );
00123 
00124     /*
00125      * 3. Setup stuff
00126      */
00127     printf( "  . Setting up the RNG and SSL state..." );
00128     fflush( stdout );
00129 
00130     havege_init( &hs );
00131 
00132     if( ( ret = ssl_init( &ssl, 1 ) ) != 0 )
00133     {
00134         printf( " failed\n  ! ssl_init returned %08x\n\n", ret );
00135         goto exit;
00136     }
00137 
00138     printf( " ok\n" );
00139 
00140     ssl_set_endpoint( &ssl, SSL_IS_CLIENT );
00141     ssl_set_authmode( &ssl, SSL_VERIFY_OPTIONAL );
00142 
00143     ssl_set_rng_func( &ssl, havege_rand, &hs );
00144     ssl_set_ciphlist( &ssl, ssl_default_ciphers );
00145     ssl_set_io_files( &ssl, server_fd, server_fd );
00146 
00147     ssl_set_ca_chain( &ssl, &cacert, SERVER_NAME );
00148     ssl_set_rsa_cert( &ssl, &clicert, &rsa );
00149 
00150     /*
00151      * 4. Handshake
00152      */
00153     printf( "  . Performing the SSL/TLS handshake..." );
00154     fflush( stdout );
00155 
00156     ret = ssl_handshake( &ssl );
00157     if( ret != 0 )
00158     {
00159         printf( " failed\n  ! ssl_handshake returned %08x\n\n", ret );
00160         goto exit;
00161     }
00162 
00163     printf( " ok\n    [ Cipher is %s ]\n",
00164             ssl_get_cipher_name( &ssl ) );
00165 
00166     /*
00167      * 5. Verify the server certificate
00168      */
00169     printf( "  . Verifying peer X.509 certificate..." );
00170 
00171     if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 )
00172     {
00173         printf( " failed\n" );
00174 
00175         if( ( ret & BADCERT_HAS_EXPIRED ) != 0 )
00176             printf( "  ! server certificate has expired\n" );
00177 
00178         if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
00179             printf( "  ! CN mismatch (expected CN=%s)\n", SERVER_NAME );
00180 
00181         if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
00182             printf( "  ! self-signed or not signed by a trusted CA\n" );
00183 
00184         printf( "\n" );
00185     }
00186     else
00187         printf( " ok\n" );
00188 
00189     /*
00190      * 6. Write the GET request
00191      */
00192     printf( "  > Write to server:" );
00193 
00194     len = sprintf( (char *) buf, GET_REQUEST );
00195 
00196     if( ( ret = ssl_write( &ssl, buf, len ) ) != 0 )
00197     {
00198         printf( " failed\n  ! ssl_write returned %08x\n\n", ret );
00199         goto exit;
00200     }
00201 
00202     printf( "\n\n%s", buf );
00203 
00204     /*
00205      * 7. Read the HTTP response
00206      */
00207     printf( "  < Read from server:\n\n" );
00208 
00209     do
00210     {
00211         len = sizeof( buf ) - 1;
00212         ret = ssl_read( &ssl, buf, &len );
00213 
00214         if( ret == ERR_SSL_PEER_CLOSE_NOTIFY )
00215             /* peer terminated the session */
00216             break;
00217 
00218         if( ret != 0 )
00219         {
00220             printf( "  ! ssl_read returned %08x\n\n", ret );
00221             break;
00222         }
00223 
00224         buf[len] = '\0';
00225         printf( "%s", buf );
00226     }
00227     while( 1 );
00228 
00229     ssl_close_notify( &ssl );
00230 
00231 exit:
00232 
00233     net_close( server_fd );
00234     ssl_free( &ssl );
00235     rsa_free( &rsa );
00236     x509_free_cert( &clicert );
00237     x509_free_cert( &cacert );
00238 
00239     memset( &ssl, 0, sizeof( ssl ) );
00240 
00241 #ifdef WIN32
00242     printf( "  + Press Enter to exit this program.\n" );
00243     fflush( stdout ); getchar();
00244 #endif
00245 
00246     return( ret );
00247 }

Generated on Tue Jul 1 15:29:59 2008 for Mobile-C by  doxygen 1.5.4