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 <stdlib.h>
00030 #include <stdio.h>
00031 #include <time.h>
00032
00033 #include "xyssl/net.h"
00034 #include "xyssl/ssl.h"
00035
00036 static int ssl_get_session( ssl_context *ssl )
00037 {
00038 time_t t;
00039 int offset;
00040 unsigned char buf[128];
00041 unsigned char hash[20];
00042
00043 if( ssl->sidtable == NULL || ssl->sidlen != 32 )
00044 return( ERR_SSL_NO_SESSION_FOUND );
00045
00046 offset = ( (int) ssl->sessid[0] << 8 )
00047 | ( (int) ssl->sessid[1] );
00048 offset = ( offset % SSL_SESSION_TBL_LEN ) & ~127;
00049
00050 memcpy( buf, ssl->sidtable + offset, 128 );
00051
00052
00053
00054
00055
00056
00057
00058
00059 if( memcmp( buf, ssl->sessid, 32 ) != 0 )
00060 return( ERR_SSL_NO_SESSION_FOUND );
00061
00062 t = ( (time_t) buf[80] << 24 )
00063 | ( (time_t) buf[81] << 16 )
00064 | ( (time_t) buf[82] << 8 )
00065 | ( (time_t) buf[83] );
00066
00067 if( time( NULL ) - t > SSL_EXPIRATION_TIME )
00068 return( ERR_SSL_NO_SESSION_FOUND );
00069
00070 sha1( buf, 86, hash );
00071 if( memcmp( buf + 86, hash, 20 ) != 0 )
00072 return( ERR_SSL_NO_SESSION_FOUND );
00073
00074 memcpy( ssl->master, buf + 32, 48 );
00075 ssl->cipher = ( (int) buf[84] << 8 )
00076 | ( (int) buf[85] );
00077
00078 return( 0 );
00079 }
00080
00081 static void ssl_set_session( ssl_context *ssl )
00082 {
00083 time_t t;
00084 int offset;
00085 unsigned char buf[128];
00086
00087 if( ssl->sidtable == NULL || ssl->sidlen != 32 )
00088 return;
00089
00090
00091
00092
00093
00094
00095
00096
00097 t = time( NULL );
00098
00099 memcpy( buf , ssl->sessid, 32 );
00100 memcpy( buf + 32, ssl->master, 48 );
00101
00102 buf[80] = (unsigned char)( t >> 24 );
00103 buf[81] = (unsigned char)( t >> 16 );
00104 buf[82] = (unsigned char)( t >> 8 );
00105 buf[83] = (unsigned char)( t );
00106
00107 buf[84] = ( ssl->cipher >> 8 );
00108 buf[85] = ( ssl->cipher );
00109
00110 sha1( buf, 86, buf + 86 );
00111
00112 offset = ( (int) ssl->sessid[0] << 8 )
00113 | ( (int) ssl->sessid[1] );
00114 offset = ( offset % SSL_SESSION_TBL_LEN ) & ~127;
00115
00116 memcpy( ssl->sidtable + offset, buf, 128 );
00117 }
00118
00119 static int ssl_parse_client_hello( ssl_context *ssl )
00120 {
00121 int ret, i, j, n;
00122 int ciph_len, sess_len;
00123 int chal_len, comp_len;
00124 unsigned char *buf, *p;
00125
00126 buf = ssl->in_hdr;
00127
00128 if( ssl->in_left < 5 )
00129 {
00130
00131
00132
00133 n = 5 - ssl->in_left;
00134 ret = net_recv( ssl->read_fd, buf + ssl->in_left, &n );
00135 ssl->in_left += n;
00136
00137 if( ret != 0 )
00138 return( ret );
00139 }
00140
00141 if( ( buf[0] & 0x80 ) != 0 )
00142 {
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 if( buf[0] != 0x80 || buf[1] < 17 ||
00154 buf[2] != SSL_HS_CLIENT_HELLO ||
00155 buf[3] != SSLV3_MAJOR_VERSION )
00156 return( ERR_SSL_BAD_HS_CLIENT_HELLO );
00157
00158 memcpy( ssl->max_ver, buf + 3, 2 );
00159
00160 ssl->major_ver = SSLV3_MAJOR_VERSION;
00161 ssl->minor_ver = ( buf[4] <= TLS10_MINOR_VERSION )
00162 ? buf[4] : TLS10_MINOR_VERSION;
00163
00164 n = (int) buf[1] - 3;
00165
00166 if( ssl->in_left < 5 + n )
00167 {
00168 n -= ssl->in_left - 5;
00169 ret = net_recv( ssl->read_fd, buf + ssl->in_left, &n );
00170 ssl->in_left += n;
00171
00172 if( ret != 0 )
00173 return( ret );
00174 }
00175
00176 md5_starts( &ssl->hs_md5 );
00177 md5_update( &ssl->hs_md5, buf + 2, (int) buf[1] );
00178
00179 sha1_starts( &ssl->hs_sha1 );
00180 sha1_update( &ssl->hs_sha1, buf + 2, (int) buf[1] );
00181
00182 buf = ssl->in_msg;
00183 n = ssl->in_left - 5;
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 ciph_len = ( (int) buf[0] << 8 ) | (int) buf[1];
00194 sess_len = ( (int) buf[2] << 8 ) | (int) buf[3];
00195 chal_len = ( (int) buf[4] << 8 ) | (int) buf[5];
00196
00197 if( ciph_len < 3 || ciph_len > 192 ||
00198 ( ciph_len % 3 ) != 0 )
00199 return( ERR_SSL_BAD_HS_CLIENT_HELLO );
00200
00201 if( sess_len < 0 || sess_len > 32 )
00202 return( ERR_SSL_BAD_HS_CLIENT_HELLO );
00203
00204 if( chal_len < 8 || chal_len > 32 )
00205 return( ERR_SSL_BAD_HS_CLIENT_HELLO );
00206
00207 if( n != 6 + ciph_len + sess_len + chal_len )
00208 return( ERR_SSL_BAD_HS_CLIENT_HELLO );
00209
00210 p = buf + 6 + ciph_len;
00211 memset( ssl->randbytes, 0, 64 );
00212 memcpy( ssl->randbytes + 32 - chal_len, p, chal_len );
00213
00214 p += sess_len;
00215 ssl->sidlen = sess_len;
00216 memcpy( ssl->sessid, p, sess_len );
00217
00218 for( i = 0; ssl->cipherlist[i] != 0; i++ )
00219 {
00220 for( j = 0, p = buf + 6; j < ciph_len;
00221 j += 3, p += 3 )
00222 {
00223 if( p[0] == 0 && p[1] == 0 &&
00224 p[2] == ssl->cipherlist[i] )
00225 goto have_cipher;
00226 }
00227 }
00228 }
00229 else
00230 {
00231
00232
00233
00234
00235
00236
00237
00238
00239 if( buf[0] != SSL_MSG_HANDSHAKE ||
00240 buf[1] != SSLV3_MAJOR_VERSION ||
00241 buf[3] != 0 || buf[4] < 45 )
00242 return( ERR_SSL_BAD_HS_CLIENT_HELLO );
00243
00244 n = (int) buf[4];
00245
00246 if( ssl->in_left < 5 + n )
00247 {
00248 n -= ( ssl->in_left - 5 );
00249 ret = net_recv( ssl->read_fd, buf + ssl->in_left, &n );
00250 ssl->in_left += n;
00251
00252 if( ret != 0 )
00253 return( ret );
00254 }
00255
00256 buf = ssl->in_msg;
00257 n = ssl->in_left - 5;
00258
00259 md5_starts( &ssl->hs_md5 );
00260 md5_update( &ssl->hs_md5, buf, n );
00261
00262 sha1_starts( &ssl->hs_sha1 );
00263 sha1_update( &ssl->hs_sha1, buf, n );
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 if( buf[0] != SSL_HS_CLIENT_HELLO ||
00281 buf[4] != SSLV3_MAJOR_VERSION )
00282 return( ERR_SSL_BAD_HS_CLIENT_HELLO );
00283
00284 ssl->major_ver = SSLV3_MAJOR_VERSION;
00285 ssl->minor_ver = ( buf[5] <= TLS10_MINOR_VERSION )
00286 ? buf[5] : TLS10_MINOR_VERSION;
00287
00288 memcpy( ssl->max_ver , buf + 4, 2 );
00289 memcpy( ssl->randbytes, buf + 6, 32 );
00290
00291
00292 if( buf[1] != 0 || buf[2] != 0 || (int) buf[3] + 4 != n )
00293 return( ERR_SSL_BAD_HS_CLIENT_HELLO );
00294
00295
00296 sess_len = (int) buf[38];
00297
00298 if( sess_len < 0 || sess_len > 32 )
00299 return( ERR_SSL_BAD_HS_CLIENT_HELLO );
00300
00301 ssl->sidlen = sess_len;
00302 memcpy( ssl->sessid, buf + 39, ssl->sidlen );
00303
00304
00305 ciph_len = (int) buf[40 + sess_len];
00306
00307 if( ciph_len < 2 || ciph_len > 128 ||
00308 ( ciph_len % 2 ) != 0 )
00309 return( ERR_SSL_BAD_HS_CLIENT_HELLO );
00310
00311
00312 comp_len = (int) buf[41 + sess_len + ciph_len];
00313
00314 if( n != 42 + sess_len + ciph_len + comp_len )
00315 return( ERR_SSL_BAD_HS_CLIENT_HELLO );
00316
00317
00318 for( i = 0; ssl->cipherlist[i] != 0; i++ )
00319 {
00320 for( j = 0, p = buf + 41 + sess_len; j < ciph_len;
00321 j += 2, p += 2 )
00322 {
00323 if( p[0] == 0 && p[1] == ssl->cipherlist[i] )
00324 goto have_cipher;
00325 }
00326 }
00327 }
00328
00329 return( ERR_SSL_NO_CIPHER_CHOSEN );
00330
00331 have_cipher:
00332
00333 ssl->cipher = ssl->cipherlist[i];
00334 ssl->in_left = 0;
00335 ssl->state++;
00336 return( 0 );
00337 }
00338
00339 static int ssl_write_server_hello( ssl_context *ssl )
00340 {
00341 int i;
00342 time_t t;
00343 unsigned char *buf, *p;
00344
00345
00346
00347
00348
00349
00350
00351
00352 buf = ssl->out_msg;
00353 p = buf + 4;
00354
00355 *p++ = ssl->major_ver;
00356 *p++ = ssl->minor_ver;
00357
00358 t = time( NULL );
00359 *p++ = (unsigned char)( t >> 24 );
00360 *p++ = (unsigned char)( t >> 16 );
00361 *p++ = (unsigned char)( t >> 8 );
00362 *p++ = (unsigned char)( t );
00363
00364 for( i = 28; i > 0; i-- )
00365 *p++ = ssl->rng_f( ssl->rng_d );
00366
00367 memcpy( ssl->randbytes + 32, buf + 6, 32 );
00368
00369
00370
00371
00372
00373
00374
00375 *p++ = ssl->sidlen = 32;
00376
00377 if( ssl_get_session( ssl ) == 0 )
00378 {
00379
00380
00381
00382 ssl->resumed = 1;
00383 ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
00384 ssl_derive_keys( ssl );
00385 }
00386 else
00387 {
00388 ssl->resumed = 0;
00389 ssl->state++;
00390
00391 for( i = 0; i < ssl->sidlen; i++ )
00392 ssl->sessid[i] = ssl->rng_f( ssl->rng_d );
00393 }
00394
00395 memcpy( p, ssl->sessid, ssl->sidlen );
00396 p += ssl->sidlen;
00397
00398 *p++ = 0;
00399 *p++ = ssl->cipher;
00400 *p++ = SSL_COMPRESS_NULL;
00401
00402 ssl->out_msglen = p - buf;
00403 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
00404 ssl->out_msg[0] = SSL_HS_SERVER_HELLO;
00405
00406 return( ssl_write_record( ssl, 0 ) );
00407 }
00408
00409 static int ssl_write_certificate_request( ssl_context *ssl )
00410 {
00411 int n;
00412 unsigned char *buf, *p;
00413 x509_cert *crt;
00414
00415 ssl->state++;
00416
00417 if( ssl->authmode == SSL_VERIFY_NONE )
00418 return( 0 );
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 buf = ssl->out_msg;
00431 p = buf + 4;
00432
00433 *p++ = 1;
00434 *p++ = 1;
00435
00436 p += 2;
00437 crt = ssl->ca_chain;
00438
00439 while( crt != NULL && crt->next != NULL )
00440 {
00441 if( p - buf > 4096 )
00442 break;
00443
00444 n = crt->subject_raw.len;
00445 *p++ = ( n >> 8 );
00446 *p++ = ( n );
00447
00448 memcpy( p, crt->subject_raw.p, n );
00449 p += n;
00450
00451 crt = crt->next;
00452 }
00453
00454 ssl->out_msglen = n = p - buf;
00455 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
00456 ssl->out_msg[0] = SSL_HS_CERTIFICATE_REQUEST;
00457 ssl->out_msg[6] = ( (n - 8) >> 8 );
00458 ssl->out_msg[7] = ( (n - 8) );
00459
00460 return( ssl_write_record( ssl, 0 ) );
00461 }
00462
00463 static int ssl_write_server_key_exchange( ssl_context *ssl )
00464 {
00465 int ret, n;
00466 unsigned char hash[36];
00467 md5_context md5;
00468 sha1_context sha1;
00469
00470 if( ssl->cipher != SSL3_EDH_RSA_DES_168_SHA &&
00471 ssl->cipher != TLS1_EDH_RSA_AES_256_SHA )
00472 {
00473 ssl->state++;
00474 return( 0 );
00475 }
00476
00477 #if defined(NO_DHM)
00478 return( ERR_SSL_FEATURE_UNAVAILABLE );
00479 #else
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 if( ( ret = dhm_make_params( &ssl->dhm_ctx, ssl->rng_f,
00490 ssl->rng_d, ssl->out_msg + 4, &n ) ) != 0 )
00491 return( ret );
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 md5_starts( &md5 );
00507 md5_update( &md5, ssl->randbytes, 64 );
00508 md5_update( &md5, ssl->out_msg + 4, n );
00509 md5_finish( &md5, hash );
00510
00511 sha1_starts( &sha1 );
00512 sha1_update( &sha1, ssl->randbytes, 64 );
00513 sha1_update( &sha1, ssl->out_msg + 4, n );
00514 sha1_finish( &sha1, hash + 16 );
00515
00516 ssl->out_msg[4 + n] = ( ssl->own_key->len >> 8 );
00517 ssl->out_msg[5 + n] = ( ssl->own_key->len );
00518
00519 if( ( ret = rsa_pkcs1_sign( ssl->own_key, RSA_RAW,
00520 hash, 36, ssl->out_msg + 6 + n,
00521 ssl->own_key->len ) ) != 0 )
00522 return( ret );
00523
00524 ssl->out_msglen = 6 + n + ssl->own_key->len;
00525 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
00526 ssl->out_msg[0] = SSL_HS_SERVER_KEY_EXCHANGE;
00527
00528 ssl->state++;
00529 return( ssl_write_record( ssl, 0 ) );
00530 #endif
00531 }
00532
00533 static int ssl_write_server_hello_done( ssl_context *ssl )
00534 {
00535 ssl->out_msglen = 4;
00536 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
00537 ssl->out_msg[0] = SSL_HS_SERVER_HELLO_DONE;
00538
00539 ssl->state++;
00540 return( ssl_write_record( ssl, 0 ) );
00541 }
00542
00543 static int ssl_parse_client_key_exchange( ssl_context *ssl )
00544 {
00545 int ret, i, n;
00546
00547 if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
00548 return( ret );
00549
00550 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
00551 return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
00552
00553 if( ssl->in_msg[0] != SSL_HS_CLIENT_KEY_EXCHANGE )
00554 return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
00555
00556 if( ssl->cipher == SSL3_EDH_RSA_DES_168_SHA ||
00557 ssl->cipher == TLS1_EDH_RSA_AES_256_SHA )
00558 {
00559 #if defined(NO_DHM)
00560 return( ERR_SSL_FEATURE_UNAVAILABLE );
00561 #else
00562
00563
00564
00565 n = ( ssl->in_msg[4] << 8 )
00566 | ( ssl->in_msg[5] );
00567
00568 if( n < 1 || n > ssl->dhm_ctx.len ||
00569 n + 6 != ssl->in_hslen )
00570 return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
00571
00572 if( ( ret = dhm_read_public( &ssl->dhm_ctx,
00573 ssl->in_msg + 6, n ) ) != 0 )
00574 return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE | ret );
00575
00576 ssl->pmslen = ssl->dhm_ctx.len;
00577
00578 if( ( ret = dhm_calc_secret( &ssl->dhm_ctx,
00579 ssl->premaster,
00580 &ssl->pmslen ) ) != 0 )
00581 return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE | ret );
00582 #endif
00583 }
00584 else
00585 {
00586
00587
00588
00589 i = 4;
00590 n = ssl->own_key->len;
00591 ssl->pmslen = 48;
00592
00593 if( ssl->minor_ver != SSLV3_MINOR_VERSION )
00594 {
00595 i += 2;
00596 if( ssl->in_msg[4] != ( ( n >> 8 ) & 0xFF ) ||
00597 ssl->in_msg[5] != ( ( n ) & 0xFF ) )
00598 return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
00599 }
00600
00601 if( ssl->in_hslen != i + n )
00602 return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
00603
00604 ret = rsa_pkcs1_decrypt( ssl->own_key,
00605 ssl->in_msg + i, n,
00606 ssl->premaster,
00607 &ssl->pmslen );
00608
00609 if( ret != 0 )
00610 return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE | ret );
00611
00612 if( ssl->pmslen != 48 ||
00613 memcmp( ssl->premaster, ssl->max_ver, 2 ) != 0 )
00614 return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
00615 }
00616
00617 ssl_derive_keys( ssl );
00618 ssl_set_session( ssl );
00619
00620 ssl->state++;
00621 return( 0 );
00622 }
00623
00624 static int ssl_parse_certificate_verify( ssl_context *ssl )
00625 {
00626 int n1, n2, ret;
00627 unsigned char hash[36];
00628
00629 if( ssl->peer_cert == NULL )
00630 {
00631 ssl->state++;
00632 return( 0 );
00633 }
00634
00635 ssl_calc_verify( ssl, hash );
00636
00637 if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
00638 return( ret );
00639
00640 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
00641 return( ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
00642
00643 if( ssl->in_msg[0] != SSL_HS_CERTIFICATE_VERIFY )
00644 return( ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
00645
00646 n1 = ssl->peer_cert->rsa.len;
00647 n2 = ( (int) ssl->in_msg[4] << 8 )
00648 | ( (int) ssl->in_msg[5] );
00649
00650 if( n1 + 6 != ssl->in_hslen || n1 != n2 )
00651 return( ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
00652
00653 ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa,
00654 RSA_RAW, hash, 36,
00655 ssl->in_msg + 6, n1 );
00656
00657 ssl->state++;
00658 return( ( ssl->authmode == SSL_VERIFY_REQUIRED ) ? ret : 0 );
00659 }
00660
00661 static const char _ssl_srv_src[] = "_ssl_srv_src";
00662
00663
00664
00665
00666 int ssl_server_start( ssl_context *ssl )
00667 {
00668 int ret = ssl_flush_output( ssl );
00669
00670 while( ret == 0 )
00671 {
00672 switch( ssl->state )
00673 {
00674 case SSL_HELLO_REQUEST:
00675 ssl->state = SSL_CLIENT_HELLO;
00676 break;
00677
00678
00679
00680
00681 case SSL_CLIENT_HELLO:
00682 ret = ssl_parse_client_hello( ssl );
00683 break;
00684
00685
00686
00687
00688
00689
00690
00691
00692 case SSL_SERVER_HELLO:
00693 ret = ssl_write_server_hello( ssl );
00694 break;
00695
00696 case SSL_SERVER_CERTIFICATE:
00697 ret = ssl_write_certificate( ssl );
00698 break;
00699
00700 case SSL_SERVER_KEY_EXCHANGE:
00701 ret = ssl_write_server_key_exchange( ssl );
00702 break;
00703
00704 case SSL_CERTIFICATE_REQUEST:
00705 ret = ssl_write_certificate_request( ssl );
00706 break;
00707
00708 case SSL_SERVER_HELLO_DONE:
00709 ret = ssl_write_server_hello_done( ssl );
00710 break;
00711
00712
00713
00714
00715
00716
00717
00718
00719 case SSL_CLIENT_CERTIFICATE:
00720 ret = ssl_parse_certificate( ssl );
00721 break;
00722
00723 case SSL_CLIENT_KEY_EXCHANGE:
00724 ret = ssl_parse_client_key_exchange( ssl );
00725 break;
00726
00727 case SSL_CERTIFICATE_VERIFY:
00728 ret = ssl_parse_certificate_verify( ssl );
00729 break;
00730
00731 case SSL_CLIENT_CHANGE_CIPHER_SPEC:
00732 ret = ssl_parse_change_cipher_spec( ssl );
00733 break;
00734
00735 case SSL_CLIENT_FINISHED:
00736 ret = ssl_parse_finished( ssl );
00737 break;
00738
00739
00740
00741
00742
00743 case SSL_SERVER_CHANGE_CIPHER_SPEC:
00744 ret = ssl_write_change_cipher_spec( ssl );
00745 break;
00746
00747 case SSL_SERVER_FINISHED:
00748 ret = ssl_write_finished( ssl );
00749 break;
00750
00751 default:
00752 return( 0 );
00753 }
00754 }
00755
00756 return( ret );
00757 }