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 #ifdef WIN32
00026 #include <windows.h>
00027 #endif
00028
00029 #include <string.h>
00030 #include <stdlib.h>
00031 #include <stdio.h>
00032
00033 #include "xyssl/havege.h"
00034 #include "xyssl/certs.h"
00035 #include "xyssl/x509.h"
00036 #include "xyssl/ssl.h"
00037 #include "xyssl/net.h"
00038
00039 #define HTTP_RESPONSE \
00040 "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
00041 "<h2><p><center>Successful connection using: %s\r\n"
00042
00043
00044
00045
00046
00047
00048 char *my_dhm_P =
00049 "E4004C1F94182000103D883A448B3F80" \
00050 "2CE4B44A83301270002C20D0321CFD00" \
00051 "11CCEF784C26A400F43DFB901BCA7538" \
00052 "F2C6B176001CF5A0FD16D2C48B1D0C1C" \
00053 "F6AC8E1DA6BCC3B4E1F96B0564965300" \
00054 "FFA1D0B601EB2800F489AA512C4B248C" \
00055 "01F76949A60BB7F00A40B1EAB64BDD48" \
00056 "E8A700D60B7F1200FA8E77B0A979DABF";
00057
00058 char *my_dhm_G = "4";
00059
00060
00061
00062
00063 int my_ciphers[] =
00064 {
00065 SSL_EDH_RSA_AES_256_SHA,
00066 SSL_EDH_RSA_DES_168_SHA,
00067 SSL_RSA_AES_256_SHA,
00068 SSL_RSA_AES_128_SHA,
00069 SSL_RSA_DES_168_SHA,
00070 SSL_RSA_RC4_128_SHA,
00071 SSL_RSA_RC4_128_MD5,
00072 0
00073 };
00074
00075 #define DEBUG_LEVEL 0
00076
00077 void my_debug( void *ctx, int level, char *str )
00078 {
00079 if( level < DEBUG_LEVEL )
00080 {
00081 fprintf( (FILE *) ctx, "%s", str );
00082 fflush( (FILE *) ctx );
00083 }
00084 }
00085
00086
00087
00088
00089
00090 ssl_session *s_list_1st = NULL;
00091 ssl_session *cur, *prv;
00092
00093 static int my_get_session( ssl_context *ssl )
00094 {
00095 time_t t = time( NULL );
00096
00097 if( ssl->resume == 0 )
00098 return( 1 );
00099
00100 cur = s_list_1st;
00101 prv = NULL;
00102
00103 while( cur != NULL )
00104 {
00105 prv = cur;
00106 cur = cur->next;
00107
00108 if( ssl->timeout != 0 && t - prv->start > ssl->timeout )
00109 continue;
00110
00111 if( ssl->session->cipher != prv->cipher ||
00112 ssl->session->length != prv->length )
00113 continue;
00114
00115 if( memcmp( ssl->session->id, prv->id, prv->length ) != 0 )
00116 continue;
00117
00118 memcpy( ssl->session->master, prv->master, 48 );
00119 return( 0 );
00120 }
00121
00122 return( 1 );
00123 }
00124
00125 static int my_set_session( ssl_context *ssl )
00126 {
00127 time_t t = time( NULL );
00128
00129 cur = s_list_1st;
00130 prv = NULL;
00131
00132 while( cur != NULL )
00133 {
00134 if( ssl->timeout != 0 && t - cur->start > ssl->timeout )
00135 break;
00136
00137 if( memcmp( ssl->session->id, cur->id, cur->length ) == 0 )
00138 break;
00139
00140 prv = cur;
00141 cur = cur->next;
00142 }
00143
00144 if( cur == NULL )
00145 {
00146 cur = (ssl_session *) malloc( sizeof( ssl_session ) );
00147 if( cur == NULL )
00148 return( 1 );
00149
00150 if( prv == NULL )
00151 s_list_1st = cur;
00152 else prv->next = cur;
00153 }
00154
00155 memcpy( cur, ssl->session, sizeof( ssl_session ) );
00156
00157 return( 0 );
00158 }
00159
00160 int main( void )
00161 {
00162 int ret, len;
00163 int listen_fd;
00164 int client_fd;
00165 unsigned char buf[1024];
00166
00167 havege_state hs;
00168 ssl_context ssl;
00169 ssl_session ssn;
00170 x509_cert srvcert;
00171 rsa_context rsa;
00172
00173
00174
00175
00176 printf( "\n . Loading the server cert. and key..." );
00177 fflush( stdout );
00178
00179 memset( &srvcert, 0, sizeof( x509_cert ) );
00180
00181
00182
00183
00184
00185
00186 ret = x509parse_crt( &srvcert, (unsigned char *) test_srv_crt,
00187 strlen( test_srv_crt ) );
00188 if( ret != 0 )
00189 {
00190 printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
00191 goto exit;
00192 }
00193
00194 ret = x509parse_crt( &srvcert, (unsigned char *) test_ca_crt,
00195 strlen( test_ca_crt ) );
00196 if( ret != 0 )
00197 {
00198 printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
00199 goto exit;
00200 }
00201
00202 ret = x509parse_key( &rsa, (unsigned char *) test_srv_key,
00203 strlen( test_srv_key ), NULL, 0 );
00204 if( ret != 0 )
00205 {
00206 printf( " failed\n ! x509parse_key returned %d\n\n", ret );
00207 goto exit;
00208 }
00209
00210 printf( " ok\n" );
00211
00212
00213
00214
00215 printf( " . Bind on https://localhost:4433/ ..." );
00216 fflush( stdout );
00217
00218 if( ( ret = net_bind( &listen_fd, NULL, 4433 ) ) != 0 )
00219 {
00220 printf( " failed\n ! net_bind returned %d\n\n", ret );
00221 goto exit;
00222 }
00223
00224 printf( " ok\n" );
00225
00226
00227
00228
00229 #ifdef WIN32
00230 ShellExecute( NULL, "open", "https://localhost:4433/",
00231 NULL, NULL, SW_SHOWNORMAL );
00232 #endif
00233
00234 client_fd = -1;
00235 memset( &ssl, 0, sizeof( ssl ) );
00236
00237 accept:
00238
00239 net_close( client_fd );
00240 ssl_free( &ssl );
00241
00242 printf( " . Waiting for a remote connection ..." );
00243 fflush( stdout );
00244
00245 if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 )
00246 {
00247 printf( " failed\n ! net_accept returned %d\n\n", ret );
00248 goto exit;
00249 }
00250
00251 printf( " ok\n" );
00252
00253
00254
00255
00256 printf( " . Setting up the RNG and SSL data...." );
00257 fflush( stdout );
00258
00259 havege_init( &hs );
00260
00261 if( ( ret = ssl_init( &ssl ) ) != 0 )
00262 {
00263 printf( " failed\n ! ssl_init returned %d\n\n", ret );
00264 goto accept;
00265 }
00266
00267 printf( " ok\n" );
00268
00269 ssl_set_endpoint( &ssl, SSL_IS_SERVER );
00270 ssl_set_authmode( &ssl, SSL_VERIFY_NONE );
00271
00272 ssl_set_rng( &ssl, havege_rand, &hs );
00273 ssl_set_dbg( &ssl, my_debug, stdout );
00274 ssl_set_bio( &ssl, net_recv, &client_fd,
00275 net_send, &client_fd );
00276 ssl_set_scb( &ssl, my_get_session,
00277 my_set_session );
00278
00279 ssl_set_ciphers( &ssl, my_ciphers );
00280 ssl_set_session( &ssl, 1, 0, &ssn );
00281
00282 memset( &ssn, 0, sizeof( ssl_session ) );
00283
00284 ssl_set_ca_chain( &ssl, srvcert.next, NULL );
00285 ssl_set_own_cert( &ssl, &srvcert, &rsa );
00286 ssl_set_dh_param( &ssl, my_dhm_P, my_dhm_G );
00287
00288
00289
00290
00291 printf( " . Performing the SSL/TLS handshake..." );
00292 fflush( stdout );
00293
00294 while( ( ret = ssl_handshake( &ssl ) ) != 0 )
00295 {
00296 if( ret != XYSSL_ERR_NET_TRY_AGAIN )
00297 {
00298 printf( " failed\n ! ssl_handshake returned %d\n\n", ret );
00299 goto accept;
00300 }
00301 }
00302
00303 printf( " ok\n" );
00304
00305
00306
00307
00308 printf( " < Read from client:" );
00309 fflush( stdout );
00310
00311 do
00312 {
00313 len = sizeof( buf ) - 1;
00314 memset( buf, 0, sizeof( buf ) );
00315 ret = ssl_read( &ssl, buf, len );
00316
00317 if( ret == XYSSL_ERR_NET_TRY_AGAIN )
00318 continue;
00319
00320 if( ret <= 0 )
00321 {
00322 switch( ret )
00323 {
00324 case XYSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
00325 printf( " connection was closed gracefully\n" );
00326 break;
00327
00328 case XYSSL_ERR_NET_CONN_RESET:
00329 printf( " connection was reset by peer\n" );
00330 break;
00331
00332 default:
00333 printf( " ssl_read returned %d\n", ret );
00334 break;
00335 }
00336
00337 break;
00338 }
00339
00340 len = ret;
00341 printf( " %d bytes read\n\n%s", len, (char *) buf );
00342 }
00343 while( 0 );
00344
00345
00346
00347
00348 printf( " > Write to client:" );
00349 fflush( stdout );
00350
00351 len = sprintf( (char *) buf, HTTP_RESPONSE,
00352 ssl_get_cipher( &ssl ) );
00353
00354 while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 )
00355 {
00356 if( ret == XYSSL_ERR_NET_CONN_RESET )
00357 {
00358 printf( " failed\n ! peer closed the connection\n\n" );
00359 goto accept;
00360 }
00361
00362 if( ret != XYSSL_ERR_NET_TRY_AGAIN )
00363 {
00364 printf( " failed\n ! ssl_write returned %d\n\n", ret );
00365 goto exit;
00366 }
00367 }
00368
00369 len = ret;
00370 printf( " %d bytes written\n\n%s\n", len, (char *) buf );
00371
00372 ssl_close_notify( &ssl );
00373 goto accept;
00374
00375 exit:
00376
00377 net_close( client_fd );
00378 x509_free( &srvcert );
00379 rsa_free( &rsa );
00380 ssl_free( &ssl );
00381
00382 cur = s_list_1st;
00383 while( cur != NULL )
00384 {
00385 prv = cur;
00386 cur = cur->next;
00387 memset( prv, 0, sizeof( ssl_session ) );
00388 free( prv );
00389 }
00390
00391 memset( &ssl, 0, sizeof( ssl_context ) );
00392
00393 #ifdef WIN32
00394 printf( " Press Enter to exit this program.\n" );
00395 fflush( stdout ); getchar();
00396 #endif
00397
00398 return( ret );
00399 }