00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
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 
00037 
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 
00068 
00069     havege_init( &hs );
00070     memset( &ssn, 0, sizeof( ssl_session ) );
00071 
00072     
00073 
00074 
00075     printf( "\n  . Loading the CA root certificate ..." );
00076     fflush( stdout );
00077 
00078     memset( &cacert, 0, sizeof( x509_cert ) );
00079 
00080     
00081 
00082 
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 
00096 
00097 
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 
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 
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 
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 
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 
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 
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 }