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/aes.h"
00030 #include "xyssl/dhm.h"
00031 #include "xyssl/rsa.h"
00032 #include "xyssl/sha1.h"
00033 #include "xyssl/havege.h"
00034
00035 #define SERVER_NAME "localhost"
00036 #define SERVER_PORT 11999
00037
00038 int main( void )
00039 {
00040 FILE *f;
00041
00042 int ret, n, buflen;
00043 int server_fd = -1;
00044
00045 unsigned char *p, *end;
00046 unsigned char buf[1024];
00047 unsigned char hash[20];
00048
00049 havege_state hs;
00050 rsa_context rsa;
00051 dhm_context dhm;
00052 aes_context aes;
00053
00054 memset( &rsa, 0, sizeof( rsa ) );
00055 memset( &dhm, 0, sizeof( dhm ) );
00056
00057
00058
00059
00060 printf( "\n . Seeding the random number generator" );
00061 fflush( stdout );
00062
00063 havege_init( &hs );
00064
00065
00066
00067
00068 printf( "\n . Reading public key from rsa_pub.txt" );
00069 fflush( stdout );
00070
00071 if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL )
00072 {
00073 ret = 1;
00074 printf( " failed\n ! Could not open rsa_pub.txt\n" \
00075 " ! Please run rsa_genkey first\n\n" );
00076 goto exit;
00077 }
00078
00079 if( ( ret = rsa_read_public( &rsa, f ) ) != 0 )
00080 {
00081 printf( " failed\n ! rsa_read_public returned %08x\n\n", ret );
00082 goto exit;
00083 }
00084
00085 fclose( f );
00086
00087
00088
00089
00090 printf( "\n . Connecting to tcp/%s/%d", SERVER_NAME,
00091 SERVER_PORT );
00092 fflush( stdout );
00093
00094 if( ( ret = net_connect( &server_fd, SERVER_NAME,
00095 SERVER_PORT ) ) != 0 )
00096 {
00097 printf( " failed\n ! net_connect returned %08x\n\n", ret );
00098 goto exit;
00099 }
00100
00101
00102
00103
00104 printf( "\n . Receiving the server's DH parameters" );
00105 fflush( stdout );
00106
00107 memset( buf, 0, sizeof( buf ) );
00108
00109 n = 2;
00110 if( ( ret = net_recv( server_fd, buf, &n ) ) != 0 )
00111 {
00112 printf( " failed\n ! net_recv returned %08x\n\n", ret );
00113 goto exit;
00114 }
00115
00116 n = buflen = ( buf[0] << 8 ) | buf[1];
00117 if( buflen < 1 || buflen > (int) sizeof( buf ) )
00118 {
00119 printf( " failed\n ! Got an invalid buffer length\n\n" );
00120 goto exit;
00121 }
00122
00123
00124
00125
00126 if( ( ret = net_recv( server_fd, buf, &n ) ) != 0 )
00127 {
00128 printf( " failed\n ! net_recv returned %08x\n\n", ret );
00129 goto exit;
00130 }
00131
00132 p = buf, end = buf + buflen;
00133
00134 if( ( ret = dhm_read_params( &dhm, &p, end ) ) != 0 )
00135 {
00136 printf( " failed\n ! dhm_read_params returned %08x\n\n", ret );
00137 goto exit;
00138 }
00139
00140 if( dhm.len < 64 || dhm.len > 256 )
00141 {
00142 ret = 1;
00143 printf( " failed\n ! Invalid DHM modulus size\n\n" );
00144 goto exit;
00145 }
00146
00147
00148
00149
00150
00151 printf( "\n . Verifying the server's RSA signature" );
00152 fflush( stdout );
00153
00154 if( ( n = (int)( end - p ) ) != rsa.len )
00155 {
00156 ret = 1;
00157 printf( " failed\n ! Invalid RSA signature size\n\n" );
00158 goto exit;
00159 }
00160
00161 sha1( buf, (int)( p - 2 - buf ), hash );
00162
00163 if( ( ret = rsa_pkcs1_verify( &rsa, RSA_SHA1,
00164 hash, 20, p, n ) ) != 0 )
00165 {
00166 printf( " failed\n ! rsa_pkcs1_verify returned "
00167 "%08x\n\n", ret );
00168 goto exit;
00169 }
00170
00171
00172
00173
00174 printf( "\n . Sending own public value to server" );
00175 fflush( stdout );
00176
00177 n = dhm.len;
00178 if( ( ret = dhm_make_public( &dhm, buf, n,
00179 havege_rand, &hs ) ) != 0 )
00180 {
00181 printf( " failed\n ! dhm_make_public returned %08x\n\n", ret );
00182 goto exit;
00183 }
00184
00185 if( ( ret = net_send( server_fd, buf, &n ) ) != 0 )
00186 {
00187 printf( " failed\n ! net_recv returned %08x\n\n", ret );
00188 goto exit;
00189 }
00190
00191
00192
00193
00194 printf( "\n . Shared secret: " );
00195 fflush( stdout );
00196
00197 n = dhm.len;
00198 if( ( ret = dhm_calc_secret( &dhm, buf, &n ) ) != 0 )
00199 {
00200 printf( " failed\n ! dhm_calc_secret returned %08x\n\n", ret );
00201 goto exit;
00202 }
00203
00204 for( n = 0; n < 16; n++ )
00205 printf( "%02x", buf[n] );
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 printf( "...\n . Receiving and decrypting the ciphertext" );
00216 fflush( stdout );
00217
00218 aes_set_key( &aes, buf, 256 );
00219
00220 n = 16;
00221 if( ( ret = net_recv( server_fd, buf, &n ) ) != 0 )
00222 {
00223 printf( " failed\n ! net_recv returned %08x\n\n", ret );
00224 goto exit;
00225 }
00226
00227 aes_decrypt( &aes, buf, buf ); buf[16] = '\0';
00228 printf( "\n . Plaintext is \"%s\"\n\n", buf );
00229
00230 exit:
00231
00232 net_close( server_fd );
00233 rsa_free( &rsa );
00234 dhm_free( &dhm );
00235
00236 #ifdef WIN32
00237 printf( " + Press Enter to exit this program.\n" );
00238 fflush( stdout ); getchar();
00239 #endif
00240
00241 return( ret );
00242 }