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 <stdlib.h>
00027 #include <time.h>
00028
00029 #include "xyssl/ssl.h"
00030
00031 static int ssl_write_client_hello( ssl_context *ssl )
00032 {
00033 int i, n;
00034 time_t t;
00035 unsigned char *buf, *p;
00036
00037 md5_starts( &ssl->hs_md5 );
00038 sha1_starts( &ssl->hs_sha1 );
00039
00040 ssl->major_ver = SSLV3_MAJOR_VERSION;
00041 ssl->minor_ver = SSLV3_MINOR_VERSION;
00042
00043
00044
00045
00046
00047
00048
00049
00050 buf = ssl->out_msg;
00051 p = buf + 4;
00052
00053 *p++ = ssl->max_ver[0] = SSLV3_MAJOR_VERSION;
00054 *p++ = ssl->max_ver[1] = TLS10_MINOR_VERSION;
00055
00056 t = time( NULL );
00057 *p++ = (unsigned char)( t >> 24 );
00058 *p++ = (unsigned char)( t >> 16 );
00059 *p++ = (unsigned char)( t >> 8 );
00060 *p++ = (unsigned char)( t );
00061
00062 for( i = 28; i > 0; i-- )
00063 *p++ = ssl->rng_f( ssl->rng_d );
00064
00065 memcpy( ssl->randbytes, buf + 6, 32 );
00066
00067
00068
00069
00070
00071
00072
00073
00074 n = ( ssl->sidlen > 0 && ssl->sidlen <= 32 )
00075 ? ssl->sidlen : 0;
00076
00077 *p++ = n;
00078 for( i = 0; i < n; i++ )
00079 *p++ = ssl->sessid[i];
00080
00081 for( n = 0; ssl->cipherlist[n] != 0; n++ );
00082 *p++ = ( n >> 7 );
00083 *p++ = ( n << 1 );
00084
00085 for( i = 0; i < n; i++ )
00086 {
00087 *p++ = ( ssl->cipherlist[i] >> 8 );
00088 *p++ = ( ssl->cipherlist[i] );
00089 }
00090
00091 *p++ = 1;
00092 *p++ = SSL_COMPRESS_NULL;
00093
00094 ssl->out_msglen = p - buf;
00095 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
00096 ssl->out_msg[0] = SSL_HS_CLIENT_HELLO;
00097
00098 ssl->state++;
00099 return( ssl_write_record( ssl, 0 ) );
00100 }
00101
00102 static int ssl_parse_server_hello( ssl_context *ssl )
00103 {
00104 int ret, i, n;
00105 unsigned char *buf;
00106
00107
00108
00109
00110
00111
00112
00113
00114 buf = ssl->in_msg;
00115
00116 if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
00117 return( ret );
00118
00119 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
00120 return( ERR_SSL_UNEXPECTED_MESSAGE );
00121
00122 if( ssl->in_hslen < 42 ||
00123 buf[0] != SSL_HS_SERVER_HELLO ||
00124 buf[4] != SSLV3_MAJOR_VERSION )
00125 return( ERR_SSL_BAD_HS_SERVER_HELLO );
00126
00127 if( buf[5] != SSLV3_MINOR_VERSION &&
00128 buf[5] != TLS10_MINOR_VERSION )
00129 return( ERR_SSL_BAD_HS_SERVER_HELLO );
00130
00131 ssl->minor_ver = buf[5];
00132
00133 memcpy( ssl->randbytes + 32, buf + 6, 32 );
00134
00135
00136
00137
00138
00139
00140
00141 n = buf[38];
00142 if( n < 0 || n > 32 || ssl->in_hslen != 42 + n )
00143 return( ERR_SSL_BAD_HS_SERVER_HELLO );
00144
00145 ssl->cipher = ( (int) buf[39 + n] << 8 )
00146 | ( (int) buf[40 + n] );
00147
00148 if( n > 0 && memcmp( ssl->sessid, buf + 39, n ) == 0 )
00149 {
00150
00151
00152
00153 ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
00154 ssl->resumed = 1;
00155 ssl_derive_keys( ssl );
00156 }
00157 else
00158 {
00159 ssl->state++;
00160 ssl->resumed = 0;
00161 ssl->sidlen = n;
00162 memcpy( ssl->sessid, buf + 39, n );
00163 }
00164
00165 i = 0;
00166 while( 1 )
00167 {
00168 if( ssl->cipherlist[i] == 0 )
00169 return( ERR_SSL_NO_CIPHER_CHOSEN );
00170
00171 if( ssl->cipherlist[i++] == ssl->cipher )
00172 break;
00173 }
00174
00175 if( buf[41 + n] != SSL_COMPRESS_NULL )
00176 return( ERR_SSL_BAD_HS_SERVER_HELLO );
00177
00178 return( 0 );
00179 }
00180
00181 static int ssl_parse_server_key_exchange( ssl_context *ssl )
00182 {
00183 int ret, n;
00184 unsigned char *p, *end;
00185 unsigned char hash[36];
00186 md5_context md5;
00187 sha1_context sha1;
00188
00189 if( ssl->cipher != SSL3_EDH_RSA_DES_168_SHA &&
00190 ssl->cipher != TLS1_EDH_RSA_AES_256_SHA )
00191 {
00192 ssl->state++;
00193 return( 0 );
00194 }
00195
00196 #if defined(NO_DHM)
00197 return( ERR_SSL_FEATURE_UNAVAILABLE );
00198 #else
00199 if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
00200 return( ret );
00201
00202 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
00203 return( ERR_SSL_UNEXPECTED_MESSAGE );
00204
00205 if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE )
00206 return( ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 p = ssl->in_msg + 4;
00218 end = ssl->in_msg + ssl->in_hslen;
00219
00220 if( ( ret = dhm_read_params( &ssl->dhm_ctx, &p, end ) ) != 0 )
00221 return( ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE | ret );
00222
00223 if( (int)( end - p ) != ssl->peer_cert->rsa.len )
00224 return( ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
00225
00226 if( ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 256 )
00227 return( ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 n = ssl->in_hslen - ( end - p ) - 6;
00243
00244 md5_starts( &md5 );
00245 md5_update( &md5, ssl->randbytes, 64 );
00246 md5_update( &md5, ssl->in_msg + 4, n );
00247 md5_finish( &md5, hash );
00248
00249 sha1_starts( &sha1 );
00250 sha1_update( &sha1, ssl->randbytes, 64 );
00251 sha1_update( &sha1, ssl->in_msg + 4, n );
00252 sha1_finish( &sha1, hash + 16 );
00253
00254 n = ssl->peer_cert->rsa.len;
00255 if( ( ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa,
00256 RSA_RAW, hash, 36, p, n ) ) != 0 )
00257 return( ret );
00258
00259 ssl->state++;
00260 return( 0 );
00261 #endif
00262 }
00263
00264 static int ssl_parse_certificate_request( ssl_context *ssl )
00265 {
00266 int ret;
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
00280 return( ret );
00281
00282 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
00283 return( ERR_SSL_UNEXPECTED_MESSAGE );
00284
00285 ssl->state++;
00286 ssl->client_auth = 0;
00287
00288 if( ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST )
00289 {
00290 ssl->client_auth++;
00291
00292
00293
00294
00295 #if 0
00296 if( ssl->own_cert == NULL )
00297 return( ERR_SSL_CERTIFICATE_REQUIRED );
00298
00299 if( ssl->own_key == NULL )
00300 return( ERR_SSL_PRIVATE_KEY_REQUIRED );
00301 #endif
00302 }
00303
00304 return( 0 );
00305 }
00306
00307 static int ssl_parse_server_hello_done( ssl_context *ssl )
00308 {
00309 int ret;
00310
00311 if( ssl->client_auth != 0 )
00312 {
00313 if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
00314 return( ret );
00315
00316 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
00317 return( ERR_SSL_UNEXPECTED_MESSAGE );
00318 }
00319
00320 if( ssl->in_hslen != 4 ||
00321 ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE )
00322 return( ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
00323
00324 ssl->state++;
00325 return( 0 );
00326 }
00327
00328 static int ssl_write_client_key_exchange( ssl_context *ssl )
00329 {
00330 int ret, i, n;
00331
00332 if( ssl->cipher == SSL3_EDH_RSA_DES_168_SHA ||
00333 ssl->cipher == TLS1_EDH_RSA_AES_256_SHA )
00334 {
00335 #if defined(NO_DHM)
00336 return( ERR_SSL_FEATURE_UNAVAILABLE );
00337 #else
00338
00339
00340
00341 n = ssl->dhm_ctx.len;
00342
00343 ssl->out_msg[4] = ( n >> 8 );
00344 ssl->out_msg[5] = ( n );
00345 i = 6;
00346
00347 if( ( ret = dhm_make_public( &ssl->dhm_ctx,
00348 &ssl->out_msg[i], n,
00349 ssl->rng_f,
00350 ssl->rng_d ) ) != 0 )
00351 return( ret );
00352
00353 ssl->pmslen = ssl->dhm_ctx.len;
00354
00355 if( ( ret = dhm_calc_secret( &ssl->dhm_ctx,
00356 ssl->premaster,
00357 &ssl->pmslen ) ) != 0 )
00358 return( ret );
00359 #endif
00360 }
00361 else
00362 {
00363
00364
00365
00366 memcpy( ssl->premaster, ssl->max_ver, 2 );
00367
00368 ssl->pmslen = 48;
00369
00370 for( i = 2; i < ssl->pmslen; i++ )
00371 ssl->premaster[i] = ssl->rng_f( ssl->rng_d );
00372
00373 i = 4;
00374 n = ssl->peer_cert->rsa.len;
00375
00376 if( ssl->minor_ver != SSLV3_MINOR_VERSION )
00377 {
00378 i += 2;
00379 ssl->out_msg[4] = ( n >> 8 );
00380 ssl->out_msg[5] = ( n );
00381 }
00382
00383 ret = rsa_pkcs1_encrypt( &ssl->peer_cert->rsa,
00384 ssl->premaster,
00385 ssl->pmslen,
00386 ssl->out_msg + i, n );
00387 if( ret != 0 )
00388 return( ret );
00389 }
00390
00391 ssl_derive_keys( ssl );
00392
00393 ssl->out_msglen = i + n;
00394 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
00395 ssl->out_msg[0] = SSL_HS_CLIENT_KEY_EXCHANGE;
00396
00397 ssl->state++;
00398 return( ssl_write_record( ssl, 0 ) );
00399 }
00400
00401 static int ssl_write_certificate_verify( ssl_context *ssl )
00402 {
00403 int ret, n;
00404 unsigned char hash[36];
00405
00406 if( ssl->client_auth == 0 || ssl->own_key == NULL )
00407 {
00408 ssl->state++;
00409 return( 0 );
00410 }
00411
00412
00413
00414
00415 ssl_calc_verify( ssl, hash );
00416
00417 n = ssl->own_key->len;
00418 ssl->out_msg[4] = ( n >> 8 );
00419 ssl->out_msg[5] = ( n );
00420
00421 if( ( ret = rsa_pkcs1_sign( ssl->own_key, RSA_RAW, hash, 36,
00422 ssl->out_msg + 6, n ) ) != 0 )
00423 return( ret );
00424
00425 ssl->out_msglen = 6 + n;
00426 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
00427 ssl->out_msg[0] = SSL_HS_CERTIFICATE_VERIFY;
00428
00429 ssl->state++;
00430 return( ssl_write_record( ssl, 0 ) );
00431 }
00432
00433 static const char _ssl_cli_src[] = "_ssl_cli_src";
00434
00435
00436
00437
00438 int ssl_client_start( ssl_context *ssl )
00439 {
00440 int ret = ssl_flush_output( ssl );
00441
00442 while( ret == 0 )
00443 {
00444 switch( ssl->state )
00445 {
00446 case SSL_HELLO_REQUEST:
00447 ssl->state = SSL_CLIENT_HELLO;
00448 break;
00449
00450
00451
00452
00453 case SSL_CLIENT_HELLO:
00454 ret = ssl_write_client_hello( ssl );
00455 break;
00456
00457
00458
00459
00460
00461
00462
00463
00464 case SSL_SERVER_HELLO:
00465 ret = ssl_parse_server_hello( ssl );
00466 break;
00467
00468 case SSL_SERVER_CERTIFICATE:
00469 ret = ssl_parse_certificate( ssl );
00470 break;
00471
00472 case SSL_SERVER_KEY_EXCHANGE:
00473 ret = ssl_parse_server_key_exchange( ssl );
00474 break;
00475
00476 case SSL_CERTIFICATE_REQUEST:
00477 ret = ssl_parse_certificate_request( ssl );
00478 break;
00479
00480 case SSL_SERVER_HELLO_DONE:
00481 ret = ssl_parse_server_hello_done( ssl );
00482 break;
00483
00484
00485
00486
00487
00488
00489
00490
00491 case SSL_CLIENT_CERTIFICATE:
00492 ret = ssl_write_certificate( ssl );
00493 break;
00494
00495 case SSL_CLIENT_KEY_EXCHANGE:
00496 ret = ssl_write_client_key_exchange( ssl );
00497 break;
00498
00499 case SSL_CERTIFICATE_VERIFY:
00500 ret = ssl_write_certificate_verify( ssl );
00501 break;
00502
00503 case SSL_CLIENT_CHANGE_CIPHER_SPEC:
00504 ret = ssl_write_change_cipher_spec( ssl );
00505 break;
00506
00507 case SSL_CLIENT_FINISHED:
00508 ret = ssl_write_finished( ssl );
00509 break;
00510
00511
00512
00513
00514
00515 case SSL_SERVER_CHANGE_CIPHER_SPEC:
00516 ret = ssl_parse_change_cipher_spec( ssl );
00517 break;
00518
00519 case SSL_SERVER_FINISHED:
00520 ret = ssl_parse_finished( ssl );
00521 break;
00522
00523 default:
00524 return( 0 );
00525 }
00526 }
00527
00528 return( ret );
00529 }