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