/home/dko/projects/mobilec/trunk/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 Tue Oct 28 17:03:23 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /