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