/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/src/security/xyssl-0.9/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 program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, 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 443
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.1\r\n" \
00042     "Host: xyssl.org\r\n\r\n"
00043 
00044 #define DEBUG_LEVEL 0
00045 
00046 void my_debug( void *ctx, int level, char *str )
00047 {
00048     if( level < DEBUG_LEVEL )
00049     {
00050         fprintf( (FILE *) ctx, "%s", str );
00051         fflush(  (FILE *) ctx  );
00052     }
00053 }
00054 
00055 int main( void )
00056 {
00057     int ret, len, server_fd;
00058     unsigned char buf[1024];
00059     havege_state hs;
00060     ssl_context ssl;
00061     ssl_session ssn;
00062     x509_cert cacert;
00063     x509_cert clicert;
00064     rsa_context rsa;
00065 
00066     /*
00067      * 0. Initialize the RNG and the session data
00068      */
00069     havege_init( &hs );
00070     memset( &ssn, 0, sizeof( ssl_session ) );
00071 
00072     /*
00073      * 1.1. Load the trusted CA
00074      */
00075     printf( "\n  . Loading the CA root certificate ..." );
00076     fflush( stdout );
00077 
00078     memset( &cacert, 0, sizeof( x509_cert ) );
00079 
00080     /*
00081      * Alternatively, you may load the CA certificates from a .pem or
00082      * .crt file by calling x509parse_crtfile( &cacert, "myca.crt" ).
00083      */
00084     ret = x509parse_crt( &cacert, (unsigned char *) xyssl_ca_crt,
00085                          strlen( xyssl_ca_crt ) );
00086     if( ret != 0 )
00087     {
00088         printf( " failed\n  !  x509parse_crt returned %d\n\n", ret );
00089         goto exit;
00090     }
00091 
00092     printf( " ok\n" );
00093 
00094     /*
00095      * 1.2. Load own certificate and private key
00096      *
00097      * (can be skipped if client authentication is not required)
00098      */
00099     printf( "  . Loading the client cert. and key..." );
00100     fflush( stdout );
00101 
00102     memset( &clicert, 0, sizeof( x509_cert ) );
00103 
00104     ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
00105                          strlen( test_cli_crt ) );
00106     if( ret != 0 )
00107     {
00108         printf( " failed\n  !  x509parse_crt returned %d\n\n", ret );
00109         goto exit;
00110     }
00111 
00112     ret = x509parse_key( &rsa, (unsigned char *) test_cli_key,
00113                          strlen( test_cli_key ), NULL, 0 );
00114     if( ret != 0 )
00115     {
00116         printf( " failed\n  !  x509parse_key returned %d\n\n", ret );
00117         goto exit;
00118     }
00119 
00120     printf( " ok\n" );
00121 
00122     /*
00123      * 2. Start the connection
00124      */
00125     printf( "  . Connecting to tcp/%s/%-4d...", SERVER_NAME,
00126                                                 SERVER_PORT );
00127     fflush( stdout );
00128 
00129     if( ( ret = net_connect( &server_fd, SERVER_NAME,
00130                                          SERVER_PORT ) ) != 0 )
00131     {
00132         printf( " failed\n  ! net_connect returned %d\n\n", ret );
00133         goto exit;
00134     }
00135 
00136     printf( " ok\n" );
00137 
00138     /*
00139      * 3. Setup stuff
00140      */
00141     printf( "  . Setting up the SSL/TLS structure..." );
00142     fflush( stdout );
00143 
00144     havege_init( &hs );
00145 
00146     if( ( ret = ssl_init( &ssl ) ) != 0 )
00147     {
00148         printf( " failed\n  ! ssl_init returned %d\n\n", ret );
00149         goto exit;
00150     }
00151 
00152     printf( " ok\n" );
00153 
00154     ssl_set_endpoint( &ssl, SSL_IS_CLIENT );
00155     ssl_set_authmode( &ssl, SSL_VERIFY_OPTIONAL );
00156 
00157     ssl_set_rng( &ssl, havege_rand, &hs );
00158     ssl_set_bio( &ssl, net_recv, &server_fd,
00159                        net_send, &server_fd );
00160 
00161     ssl_set_ciphers( &ssl, ssl_default_ciphers );
00162     ssl_set_session( &ssl, 1, 600, &ssn );
00163 
00164     ssl_set_ca_chain( &ssl, &cacert, SERVER_NAME );
00165     ssl_set_own_cert( &ssl, &clicert, &rsa );
00166 
00167     ssl_set_hostname( &ssl, SERVER_NAME );
00168 
00169     /*
00170      * 4. Handshake
00171      */
00172     printf( "  . Performing the SSL/TLS handshake..." );
00173     fflush( stdout );
00174 
00175     while( ( ret = ssl_handshake( &ssl ) ) != 0 )
00176     {
00177         if( ret != XYSSL_ERR_NET_TRY_AGAIN )
00178         {
00179             printf( " failed\n  ! ssl_handshake returned %d\n\n", ret );
00180             goto exit;
00181         }
00182     }
00183 
00184     printf( " ok\n    [ Cipher is %s ]\n",
00185             ssl_get_cipher( &ssl ) );
00186 
00187     /*
00188      * 5. Verify the server certificate
00189      */
00190     printf( "  . Verifying peer X.509 certificate..." );
00191 
00192     if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 )
00193     {
00194         printf( " failed\n" );
00195 
00196         if( ( ret & BADCERT_EXPIRED ) != 0 )
00197             printf( "  ! server certificate has expired\n" );
00198 
00199         if( ( ret & BADCERT_REVOKED ) != 0 )
00200             printf( "  ! server certificate has been revoked\n" );
00201 
00202         if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
00203             printf( "  ! CN mismatch (expected CN=%s)\n", SERVER_NAME );
00204 
00205         if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
00206             printf( "  ! self-signed or not signed by a trusted CA\n" );
00207 
00208         printf( "\n" );
00209     }
00210     else
00211         printf( " ok\n" );
00212 
00213     printf( "  . Peer certificate information    ...\n" );
00214     printf( x509parse_cert_info( "      ", ssl.peer_cert ) );
00215 
00216     /*
00217      * 6. Write the GET request
00218      */
00219     printf( "  > Write to server:" );
00220     fflush( stdout );
00221 
00222     len = sprintf( (char *) buf, GET_REQUEST );
00223 
00224     while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 )
00225     {
00226         if( ret != XYSSL_ERR_NET_TRY_AGAIN )
00227         {
00228             printf( " failed\n  ! ssl_write returned %d\n\n", ret );
00229             goto exit;
00230         }
00231     }
00232 
00233     len = ret;
00234     printf( " %d bytes written\n\n%s", len, (char *) buf );
00235 
00236     /*
00237      * 7. Read the HTTP response
00238      */
00239     printf( "  < Read from server:" );
00240     fflush( stdout );
00241 
00242     do
00243     {
00244         len = sizeof( buf ) - 1;
00245         memset( buf, 0, sizeof( buf ) );
00246         ret = ssl_read( &ssl, buf, len );
00247 
00248         if( ret == XYSSL_ERR_NET_TRY_AGAIN )
00249             continue;
00250 
00251         if( ret == XYSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
00252             break;
00253 
00254         if( ret <= 0 )
00255         {
00256             printf( "failed\n  ! ssl_read returned %d\n\n", ret );
00257             break;
00258         }
00259 
00260         len = ret;
00261         printf( " %d bytes read\n\n%s", len, (char *) buf );
00262     }
00263     while( 0 );
00264 
00265     ssl_close_notify( &ssl );
00266 
00267 exit:
00268 
00269     net_close( server_fd );
00270     x509_free( &clicert );
00271     x509_free( &cacert );
00272     rsa_free( &rsa );
00273     ssl_free( &ssl );
00274 
00275     memset( &ssl, 0, sizeof( ssl ) );
00276 
00277 #ifdef WIN32
00278     printf( "  + Press Enter to exit this program.\n" );
00279     fflush( stdout ); getchar();
00280 #endif
00281 
00282     return( ret );
00283 }

Generated on Fri Jul 11 17:59:46 2008 for Mobile-C by  doxygen 1.5.4