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

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

Generated on Fri May 16 14:49:55 2008 for Mobile-C by  doxygen 1.5.4