00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "MHD_config.h"
00029 #include "gnutls_int.h"
00030 #include "gnutls_errors.h"
00031 #include "gnutls_dh.h"
00032 #include "debug.h"
00033 #include "gnutls_algorithms.h"
00034 #include "gnutls_cipher.h"
00035 #include "gnutls_buffers.h"
00036 #include "gnutls_kx.h"
00037 #include "gnutls_handshake.h"
00038 #include "gnutls_num.h"
00039 #include "gnutls_hash_int.h"
00040 #include "gnutls_extensions.h"
00041 #include "gnutls_supplemental.h"
00042 #include "gnutls_auth_int.h"
00043 #include "auth_cert.h"
00044 #include "gnutls_cert.h"
00045 #include "gnutls_constate.h"
00046 #include "gnutls_record.h"
00047 #include "gnutls_state.h"
00048 #include "gnutls_rsa_export.h"
00049 #include "gc.h"
00050
00051 #ifdef HANDSHAKE_DEBUG
00052 #define ERR(x, y) MHD__gnutls_handshake_log( "HSK[%x]: %s (%d)\n", session, x,y)
00053 #else
00054 #define ERR(x, y)
00055 #endif
00056
00057 #define TRUE 1
00058 #define FALSE 0
00059
00060
00061
00062
00063
00064 #define MAX_EXT_DATA_LENGTH 1024
00065
00066
00067 static int MHD_gtls_remove_unwanted_ciphersuites (MHD_gtls_session_t session,
00068 cipher_suite_st **
00069 cipherSuites,
00070 int numCipherSuites,
00071 enum
00072 MHD_GNUTLS_PublicKeyAlgorithm);
00073 static int MHD_gtls_server_select_suite (MHD_gtls_session_t session,
00074 opaque * data, int datalen);
00075
00076 static int MHD_gtls_generate_session_id (opaque * session_id, uint8_t * len);
00077
00078 static int MHD_gtls_handshake_common (MHD_gtls_session_t session);
00079
00080 static int MHD_gtls_handshake_server (MHD_gtls_session_t session);
00081
00082 #if MHD_DEBUG_TLS
00083 static int MHD_gtls_handshake_client (MHD_gtls_session_t session);
00084 #endif
00085
00086
00087 static int MHD__gnutls_server_select_comp_method (MHD_gtls_session_t session,
00088 opaque * data, int datalen);
00089
00090
00091
00092
00093 static void
00094 MHD__gnutls_handshake_hash_buffers_clear (MHD_gtls_session_t session)
00095 {
00096 MHD_gnutls_hash_deinit (session->internals.handshake_mac_handle_md5, NULL);
00097 MHD_gnutls_hash_deinit (session->internals.handshake_mac_handle_sha, NULL);
00098 session->internals.handshake_mac_handle_md5 = NULL;
00099 session->internals.handshake_mac_handle_sha = NULL;
00100 MHD_gtls_handshake_buffer_clear (session);
00101 }
00102
00114 void
00115 MHD__gnutls_handshake_set_max_packet_length (MHD_gtls_session_t session,
00116 size_t max)
00117 {
00118 session->internals.max_handshake_data_buffer_size = max;
00119 }
00120
00121
00122 static void
00123 MHD_gtls_set_server_random (MHD_gtls_session_t session, uint8_t * rnd)
00124 {
00125 memcpy (session->security_parameters.server_random, rnd, TLS_RANDOM_SIZE);
00126 }
00127
00128 static void
00129 MHD_gtls_set_client_random (MHD_gtls_session_t session, uint8_t * rnd)
00130 {
00131 memcpy (session->security_parameters.client_random, rnd, TLS_RANDOM_SIZE);
00132 }
00133
00134
00135 #define SSL3_CLIENT_MSG "CLNT"
00136 #define SSL3_SERVER_MSG "SRVR"
00137 #define SSL_MSG_LEN 4
00138 static int
00139 MHD__gnutls_ssl3_finished (MHD_gtls_session_t session, int type, opaque * ret)
00140 {
00141 const int siz = SSL_MSG_LEN;
00142 mac_hd_t td_md5;
00143 mac_hd_t td_sha;
00144 const char *mesg;
00145
00146 td_md5 = MHD_gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
00147 if (td_md5 == NULL)
00148 {
00149 MHD_gnutls_assert ();
00150 return GNUTLS_E_HASH_FAILED;
00151 }
00152
00153 td_sha = MHD_gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
00154 if (td_sha == NULL)
00155 {
00156 MHD_gnutls_assert ();
00157 MHD_gnutls_hash_deinit (td_md5, NULL);
00158 return GNUTLS_E_HASH_FAILED;
00159 }
00160
00161 if (type == GNUTLS_SERVER)
00162 {
00163 mesg = SSL3_SERVER_MSG;
00164 }
00165 else
00166 {
00167 mesg = SSL3_CLIENT_MSG;
00168 }
00169
00170 MHD_gnutls_hash (td_md5, mesg, siz);
00171 MHD_gnutls_hash (td_sha, mesg, siz);
00172
00173 MHD_gnutls_mac_deinit_ssl3_handshake (td_md5, ret,
00174 session->security_parameters.
00175 master_secret, TLS_MASTER_SIZE);
00176 MHD_gnutls_mac_deinit_ssl3_handshake (td_sha, &ret[16],
00177 session->security_parameters.
00178 master_secret, TLS_MASTER_SIZE);
00179
00180 return 0;
00181 }
00182
00183
00184 #define SERVER_MSG "server finished"
00185 #define CLIENT_MSG "client finished"
00186 #define TLS_MSG_LEN 15
00187 static int
00188 MHD__gnutls_finished (MHD_gtls_session_t session, int type, void *ret)
00189 {
00190 const int siz = TLS_MSG_LEN;
00191 opaque concat[36];
00192 size_t len;
00193 const char *mesg;
00194 mac_hd_t td_md5 = NULL;
00195 mac_hd_t td_sha;
00196 enum MHD_GNUTLS_Protocol ver = MHD__gnutls_protocol_get_version (session);
00197
00198 if (ver < MHD_GNUTLS_PROTOCOL_TLS1_2)
00199 {
00200 td_md5 =
00201 MHD_gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
00202 if (td_md5 == NULL)
00203 {
00204 MHD_gnutls_assert ();
00205 return GNUTLS_E_HASH_FAILED;
00206 }
00207 }
00208
00209 td_sha = MHD_gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
00210 if (td_sha == NULL)
00211 {
00212 MHD_gnutls_assert ();
00213 if (td_md5 != NULL)
00214 MHD_gnutls_hash_deinit (td_md5, NULL);
00215 return GNUTLS_E_HASH_FAILED;
00216 }
00217
00218 if (ver < MHD_GNUTLS_PROTOCOL_TLS1_2)
00219 {
00220 MHD_gnutls_hash_deinit (td_md5, concat);
00221 MHD_gnutls_hash_deinit (td_sha, &concat[16]);
00222 len = 20 + 16;
00223 }
00224 else
00225 {
00226 MHD_gnutls_hash_deinit (td_sha, concat);
00227 len = 20;
00228 }
00229
00230 if (type == GNUTLS_SERVER)
00231 {
00232 mesg = SERVER_MSG;
00233 }
00234 else
00235 {
00236 mesg = CLIENT_MSG;
00237 }
00238
00239 return MHD_gtls_PRF (session, session->security_parameters.master_secret,
00240 TLS_MASTER_SIZE, mesg, siz, concat, len, 12, ret);
00241 }
00242
00243
00244
00245
00246 static int
00247 MHD_gtls_tls_create_random (opaque * dst)
00248 {
00249 uint32_t tim;
00250
00251
00252
00253
00254
00255
00256 tim = time (NULL);
00257
00258 MHD_gtls_write_uint32 (tim, dst);
00259
00260 if (MHD_gc_nonce ((char *) &dst[4], TLS_RANDOM_SIZE - 4) != GC_OK)
00261 {
00262 MHD_gnutls_assert ();
00263 return GNUTLS_E_RANDOM_FAILED;
00264 }
00265
00266 return 0;
00267 }
00268
00269
00270
00271 static int
00272 MHD_gtls_negotiate_version (MHD_gtls_session_t session,
00273 enum MHD_GNUTLS_Protocol adv_version)
00274 {
00275 int ret;
00276
00277
00278 if (MHD_gtls_version_is_supported (session, adv_version) == 0)
00279 {
00280
00281
00282
00283 ret = MHD_gtls_version_max (session);
00284 }
00285 else
00286 {
00287 ret = adv_version;
00288 }
00289 MHD_gtls_set_current_version (session, ret);
00290
00291 return ret;
00292 }
00293
00294
00295
00296
00297
00298
00299 static int
00300 MHD__gnutls_read_client_hello (MHD_gtls_session_t session, opaque * data,
00301 int datalen)
00302 {
00303 uint8_t session_id_len;
00304 int pos = 0, ret = 0;
00305 uint16_t suite_size, comp_size;
00306 enum MHD_GNUTLS_Protocol adv_version;
00307 int neg_version;
00308 int len = datalen;
00309 opaque rnd[TLS_RANDOM_SIZE], *suite_ptr, *comp_ptr;
00310
00311 DECR_LEN (len, 2);
00312
00313 MHD__gnutls_handshake_log ("HSK[%x]: Client's version: %d.%d\n", session,
00314 data[pos], data[pos + 1]);
00315
00316 adv_version = MHD_gtls_version_get (data[pos], data[pos + 1]);
00317 set_adv_version (session, data[pos], data[pos + 1]);
00318 pos += 2;
00319
00320 neg_version = MHD_gtls_negotiate_version (session, adv_version);
00321 if (neg_version < 0)
00322 {
00323 MHD_gnutls_assert ();
00324 return ret;
00325 }
00326
00327
00328
00329 DECR_LEN (len, TLS_RANDOM_SIZE);
00330 MHD_gtls_set_client_random (session, &data[pos]);
00331 pos += TLS_RANDOM_SIZE;
00332
00333 MHD_gtls_tls_create_random (rnd);
00334 MHD_gtls_set_server_random (session, rnd);
00335
00336 session->security_parameters.timestamp = time (NULL);
00337
00338 DECR_LEN (len, 1);
00339 session_id_len = data[pos++];
00340
00341
00342 if (session_id_len > TLS_MAX_SESSION_ID_SIZE)
00343 {
00344 MHD_gnutls_assert ();
00345 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
00346 }
00347 DECR_LEN (len, session_id_len);
00348
00349 pos += session_id_len;
00350
00351 MHD_gtls_generate_session_id (session->security_parameters.session_id,
00352 &session->security_parameters.
00353 session_id_size);
00354
00355 session->internals.resumed = RESUME_FALSE;
00356
00357
00358 DECR_LEN (len, 2);
00359 suite_size = MHD_gtls_read_uint16 (&data[pos]);
00360 pos += 2;
00361
00362 DECR_LEN (len, suite_size);
00363 suite_ptr = &data[pos];
00364 pos += suite_size;
00365
00366
00367
00368 DECR_LEN (len, 1);
00369 comp_size = data[pos++];
00370
00371 DECR_LEN (len, comp_size);
00372 comp_ptr = &data[pos];
00373 pos += comp_size;
00374
00375
00376
00377 if (neg_version >= MHD_GNUTLS_PROTOCOL_TLS1_0)
00378 {
00379 ret = MHD_gtls_parse_extensions (session, EXTENSION_APPLICATION, &data[pos], len);
00380 if (ret < 0)
00381 {
00382 MHD_gnutls_assert ();
00383 return ret;
00384 }
00385 }
00386
00387 if (neg_version >= MHD_GNUTLS_PROTOCOL_TLS1_0)
00388 {
00389 ret = MHD_gtls_parse_extensions (session, EXTENSION_TLS, &data[pos], len);
00390 if (ret < 0)
00391 {
00392 MHD_gnutls_assert ();
00393 return ret;
00394 }
00395 }
00396
00397
00398
00399 ret = MHD_gtls_server_select_suite (session, suite_ptr, suite_size);
00400 if (ret < 0)
00401 {
00402 MHD_gnutls_assert ();
00403 return ret;
00404 }
00405
00406
00407 ret = MHD__gnutls_server_select_comp_method (session, comp_ptr, comp_size);
00408 if (ret < 0)
00409 {
00410 MHD_gnutls_assert ();
00411 return ret;
00412 }
00413
00414 return 0;
00415 }
00416
00417
00418
00419 static int
00420 MHD__gnutls_handshake_hash_pending (MHD_gtls_session_t session)
00421 {
00422 size_t siz;
00423 int ret;
00424 opaque *data;
00425
00426 if (session->internals.handshake_mac_handle_sha == NULL ||
00427 session->internals.handshake_mac_handle_md5 == NULL)
00428 {
00429 MHD_gnutls_assert ();
00430 return GNUTLS_E_INTERNAL_ERROR;
00431 }
00432
00433
00434
00435 if ((ret = MHD_gtls_handshake_buffer_get_ptr (session, &data, &siz)) < 0)
00436 {
00437 MHD_gnutls_assert ();
00438 return ret;
00439 }
00440
00441 if (siz > 0)
00442 {
00443 MHD_gnutls_hash (session->internals.handshake_mac_handle_sha, data,
00444 siz);
00445 MHD_gnutls_hash (session->internals.handshake_mac_handle_md5, data,
00446 siz);
00447 }
00448
00449 MHD_gtls_handshake_buffer_empty (session);
00450
00451 return 0;
00452 }
00453
00454
00455
00456
00457
00458
00459 static int
00460 MHD__gnutls_send_finished (MHD_gtls_session_t session, int again)
00461 {
00462 uint8_t data[36];
00463 int ret;
00464 int data_size = 0;
00465
00466
00467 if (again == 0)
00468 {
00469
00470
00471
00472
00473 if ((ret = MHD__gnutls_handshake_hash_pending (session)) < 0)
00474 {
00475 MHD_gnutls_assert ();
00476 return ret;
00477 }
00478
00479 if (MHD__gnutls_protocol_get_version (session) ==
00480 MHD_GNUTLS_PROTOCOL_SSL3)
00481 {
00482 ret =
00483 MHD__gnutls_ssl3_finished (session,
00484 session->security_parameters.entity,
00485 data);
00486 data_size = 36;
00487 }
00488 else
00489 {
00490 ret =
00491 MHD__gnutls_finished (session,
00492 session->security_parameters.entity, data);
00493 data_size = 12;
00494 }
00495
00496 if (ret < 0)
00497 {
00498 MHD_gnutls_assert ();
00499 return ret;
00500 }
00501
00502 }
00503
00504 ret =
00505 MHD_gtls_send_handshake (session, data, data_size,
00506 GNUTLS_HANDSHAKE_FINISHED);
00507
00508 return ret;
00509 }
00510
00511
00512
00513
00514 static int
00515 MHD__gnutls_recv_finished (MHD_gtls_session_t session)
00516 {
00517 uint8_t data[36], *vrfy;
00518 int data_size;
00519 int ret;
00520 int vrfysize;
00521
00522 ret =
00523 MHD_gtls_recv_handshake (session, &vrfy, &vrfysize,
00524 GNUTLS_HANDSHAKE_FINISHED, MANDATORY_PACKET);
00525 if (ret < 0)
00526 {
00527 ERR ("recv finished int", ret);
00528 MHD_gnutls_assert ();
00529 return ret;
00530 }
00531
00532
00533 if (MHD__gnutls_protocol_get_version (session) == MHD_GNUTLS_PROTOCOL_SSL3)
00534 {
00535 data_size = 36;
00536 }
00537 else
00538 {
00539 data_size = 12;
00540 }
00541
00542 if (vrfysize != data_size)
00543 {
00544 MHD_gnutls_assert ();
00545 MHD_gnutls_free (vrfy);
00546 return GNUTLS_E_ERROR_IN_FINISHED_PACKET;
00547 }
00548
00549 if (MHD__gnutls_protocol_get_version (session) == MHD_GNUTLS_PROTOCOL_SSL3)
00550 {
00551 ret =
00552 MHD__gnutls_ssl3_finished (session,
00553 (session->security_parameters.entity +
00554 1) % 2, data);
00555 }
00556 else
00557 {
00558 ret =
00559 MHD__gnutls_finished (session,
00560 (session->security_parameters.entity +
00561 1) % 2, data);
00562 }
00563
00564 if (ret < 0)
00565 {
00566 MHD_gnutls_assert ();
00567 MHD_gnutls_free (vrfy);
00568 return ret;
00569 }
00570
00571 if (memcmp (vrfy, data, data_size) != 0)
00572 {
00573 MHD_gnutls_assert ();
00574 ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
00575 }
00576 MHD_gnutls_free (vrfy);
00577
00578 return ret;
00579 }
00580
00581
00582
00583
00584 static int
00585 MHD__gnutls_server_find_pk_algos_in_ciphersuites (const opaque *
00586 data, int datalen)
00587 {
00588 int j;
00589 enum MHD_GNUTLS_PublicKeyAlgorithm algo = GNUTLS_PK_NONE, prev_algo = 0;
00590 enum MHD_GNUTLS_KeyExchangeAlgorithm kx;
00591 cipher_suite_st cs;
00592
00593 if (datalen % 2 != 0)
00594 {
00595 MHD_gnutls_assert ();
00596 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
00597 }
00598
00599 for (j = 0; j < datalen; j += 2)
00600 {
00601 memcpy (&cs.suite, &data[j], 2);
00602 kx = MHD_gtls_cipher_suite_get_kx_algo (&cs);
00603
00604 if (MHD_gtls_map_kx_get_cred (kx, 1) == MHD_GNUTLS_CRD_CERTIFICATE)
00605 {
00606 algo = MHD_gtls_map_pk_get_pk (kx);
00607
00608 if (algo != prev_algo && prev_algo != 0)
00609 return GNUTLS_PK_ANY;
00610 prev_algo = algo;
00611 }
00612 }
00613
00614 return algo;
00615 }
00616
00617
00618
00619
00620
00621 static int
00622 MHD_gtls_server_select_suite (MHD_gtls_session_t session, opaque * data,
00623 int datalen)
00624 {
00625 int x, i, j;
00626 cipher_suite_st *ciphers, cs;
00627 int retval, err;
00628 enum MHD_GNUTLS_PublicKeyAlgorithm pk_algo;
00629
00630
00631
00632 pk_algo = MHD__gnutls_server_find_pk_algos_in_ciphersuites (data, datalen);
00633
00634 x = MHD_gtls_supported_ciphersuites (session, &ciphers);
00635 if (x < 0)
00636 {
00637 MHD_gnutls_assert ();
00638 return x;
00639 }
00640
00641
00642
00643
00644
00645 x = MHD_gtls_remove_unwanted_ciphersuites (session, &ciphers, x, pk_algo);
00646 if (x <= 0)
00647 {
00648 MHD_gnutls_assert ();
00649 MHD_gnutls_free (ciphers);
00650 if (x < 0)
00651 return x;
00652 else
00653 return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
00654 }
00655
00656
00657
00658
00659
00660 if (datalen % 2 != 0)
00661 {
00662 MHD_gnutls_assert ();
00663 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
00664 }
00665 memset (session->security_parameters.current_cipher_suite.suite, '\0', 2);
00666
00667 retval = GNUTLS_E_UNKNOWN_CIPHER_SUITE;
00668
00669 for (j = 0; j < datalen; j += 2)
00670 {
00671 for (i = 0; i < x; i++)
00672 {
00673 if (memcmp (ciphers[i].suite, &data[j], 2) == 0)
00674 {
00675 memcpy (&cs.suite, &data[j], 2);
00676
00677 MHD__gnutls_handshake_log
00678 ("HSK[%x]: Selected cipher suite: %s\n", session,
00679 MHD_gtls_cipher_suite_get_name (&cs));
00680 memcpy (session->security_parameters.current_cipher_suite.suite,
00681 ciphers[i].suite, 2);
00682 retval = 0;
00683 goto finish;
00684 }
00685 }
00686 }
00687
00688 finish:
00689 MHD_gnutls_free (ciphers);
00690
00691 if (retval != 0)
00692 {
00693 MHD_gnutls_assert ();
00694 return retval;
00695 }
00696
00697
00698
00699 if (MHD_gtls_get_kx_cred
00700 (session,
00701 MHD_gtls_cipher_suite_get_kx_algo (&session->security_parameters.
00702 current_cipher_suite), &err) == NULL
00703 && err != 0)
00704 {
00705 MHD_gnutls_assert ();
00706 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
00707 }
00708
00709
00710
00711
00712
00713
00714 session->internals.auth_struct =
00715 MHD_gtls_kx_auth_struct (MHD_gtls_cipher_suite_get_kx_algo
00716 (&session->security_parameters.
00717 current_cipher_suite));
00718 if (session->internals.auth_struct == NULL)
00719 {
00720
00721 MHD__gnutls_handshake_log
00722 ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n",
00723 session);
00724 MHD_gnutls_assert ();
00725 return GNUTLS_E_INTERNAL_ERROR;
00726 }
00727
00728 return 0;
00729
00730 }
00731
00732
00733
00734
00735 static int
00736 MHD__gnutls_server_select_comp_method (MHD_gtls_session_t session,
00737 opaque * data, int datalen)
00738 {
00739 int x, i, j;
00740 uint8_t *comps;
00741
00742 x = MHD_gtls_supported_compression_methods (session, &comps);
00743 if (x < 0)
00744 {
00745 MHD_gnutls_assert ();
00746 return x;
00747 }
00748
00749 memset (&session->internals.compression_method, 0,
00750 sizeof (enum MHD_GNUTLS_CompressionMethod));
00751
00752 for (j = 0; j < datalen; j++)
00753 {
00754 for (i = 0; i < x; i++)
00755 {
00756 if (comps[i] == data[j])
00757 {
00758 enum MHD_GNUTLS_CompressionMethod method =
00759 MHD_gtls_compression_get_id_from_int (comps[i]);
00760
00761 session->internals.compression_method = method;
00762 MHD_gnutls_free (comps);
00763 return 0;
00764 }
00765 }
00766 }
00767
00768
00769
00770
00771 MHD_gnutls_free (comps);
00772 MHD_gnutls_assert ();
00773 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
00774
00775 }
00776
00777
00778
00779
00780
00781
00782 static int
00783 MHD__gnutls_send_empty_handshake (MHD_gtls_session_t session,
00784 MHD_gnutls_handshake_description_t type,
00785 int again)
00786 {
00787 opaque data = 0;
00788 opaque *ptr;
00789
00790 if (again == 0)
00791 ptr = &data;
00792 else
00793 ptr = NULL;
00794
00795 return MHD_gtls_send_handshake (session, ptr, 0, type);
00796 }
00797
00798
00799
00800 static int
00801 MHD__gnutls_handshake_hash_add_sent (MHD_gtls_session_t session,
00802 MHD_gnutls_handshake_description_t type,
00803 opaque * dataptr, uint32_t datalen)
00804 {
00805 int ret;
00806
00807 if ((ret = MHD__gnutls_handshake_hash_pending (session)) < 0)
00808 {
00809 MHD_gnutls_assert ();
00810 return ret;
00811 }
00812
00813 if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
00814 {
00815 MHD_gnutls_hash (session->internals.handshake_mac_handle_sha, dataptr,
00816 datalen);
00817 MHD_gnutls_hash (session->internals.handshake_mac_handle_md5, dataptr,
00818 datalen);
00819 }
00820
00821 return 0;
00822 }
00823
00824
00825
00826
00827
00828
00829
00830 int
00831 MHD_gtls_send_handshake (MHD_gtls_session_t session, void *i_data,
00832 uint32_t i_datasize,
00833 MHD_gnutls_handshake_description_t type)
00834 {
00835 int ret;
00836 uint8_t *data;
00837 uint32_t datasize;
00838 int pos = 0;
00839
00840 if (i_data == NULL && i_datasize == 0)
00841 {
00842
00843
00844
00845 ret = MHD_gtls_handshake_io_write_flush (session);
00846 return ret;
00847
00848 }
00849
00850 if (i_data == NULL && i_datasize > 0)
00851 {
00852 MHD_gnutls_assert ();
00853 return GNUTLS_E_INVALID_REQUEST;
00854 }
00855
00856
00857 datasize = i_datasize + HANDSHAKE_HEADER_SIZE;
00858 data = MHD_gnutls_alloca (datasize);
00859 if (data == NULL)
00860 {
00861 MHD_gnutls_assert ();
00862 return GNUTLS_E_MEMORY_ERROR;
00863 }
00864
00865 data[pos++] = (uint8_t) type;
00866 MHD_gtls_write_uint24 (i_datasize, &data[pos]);
00867 pos += 3;
00868
00869 if (i_datasize > 0)
00870 memcpy (&data[pos], i_data, i_datasize);
00871
00872
00873
00874 if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
00875 if ((ret =
00876 MHD__gnutls_handshake_hash_add_sent (session, type, data,
00877 datasize)) < 0)
00878 {
00879 MHD_gnutls_assert ();
00880 MHD_gnutls_afree (data);
00881 return ret;
00882 }
00883
00884 session->internals.last_handshake_out = type;
00885
00886 ret =
00887 MHD_gtls_handshake_io_send_int (session, GNUTLS_HANDSHAKE, type,
00888 data, datasize);
00889
00890 MHD__gnutls_handshake_log ("HSK[%x]: %s was sent [%ld bytes]\n",
00891 session, MHD__gnutls_handshake2str (type),
00892 (long) datasize);
00893
00894 MHD_gnutls_afree (data);
00895
00896 return ret;
00897 }
00898
00899
00900
00901
00902
00903
00904
00905 #define SSL2_HEADERS 1
00906 static int
00907 MHD__gnutls_recv_handshake_header (MHD_gtls_session_t session,
00908 MHD_gnutls_handshake_description_t type,
00909 MHD_gnutls_handshake_description_t *
00910 recv_type)
00911 {
00912 int ret;
00913 uint32_t length32 = 0;
00914 uint8_t *dataptr = NULL;
00915 size_t handshake_header_size = HANDSHAKE_HEADER_SIZE;
00916
00917
00918
00919
00920
00921 if (session->internals.handshake_header_buffer.header_size ==
00922 handshake_header_size || (session->internals.v2_hello != 0
00923 && type == GNUTLS_HANDSHAKE_CLIENT_HELLO
00924 && session->internals.
00925 handshake_header_buffer.packet_length > 0))
00926 {
00927
00928 *recv_type = session->internals.handshake_header_buffer.recv_type;
00929
00930 return session->internals.handshake_header_buffer.packet_length;
00931 }
00932
00933
00934
00935 dataptr = session->internals.handshake_header_buffer.header;
00936
00937
00938
00939 if (session->internals.handshake_header_buffer.header_size < SSL2_HEADERS)
00940 {
00941 ret =
00942 MHD_gtls_handshake_io_recv_int (session, GNUTLS_HANDSHAKE,
00943 type, dataptr, SSL2_HEADERS);
00944
00945 if (ret < 0)
00946 {
00947 MHD_gnutls_assert ();
00948 return ret;
00949 }
00950
00951
00952
00953 if (ret != SSL2_HEADERS)
00954 {
00955 MHD_gnutls_assert ();
00956 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
00957 }
00958 session->internals.handshake_header_buffer.header_size = SSL2_HEADERS;
00959 }
00960
00961 if (session->internals.v2_hello == 0
00962 || type != GNUTLS_HANDSHAKE_CLIENT_HELLO)
00963 {
00964 ret =
00965 MHD_gtls_handshake_io_recv_int (session, GNUTLS_HANDSHAKE,
00966 type,
00967 &dataptr
00968 [session->internals.
00969 handshake_header_buffer.header_size],
00970 HANDSHAKE_HEADER_SIZE -
00971 session->internals.
00972 handshake_header_buffer.header_size);
00973 if (ret <= 0)
00974 {
00975 MHD_gnutls_assert ();
00976 return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
00977 }
00978 if ((size_t) ret !=
00979 HANDSHAKE_HEADER_SIZE -
00980 session->internals.handshake_header_buffer.header_size)
00981 {
00982 MHD_gnutls_assert ();
00983 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
00984 }
00985 *recv_type = dataptr[0];
00986
00987
00988
00989
00990 length32 = MHD_gtls_read_uint24 (&dataptr[1]);
00991 handshake_header_size = HANDSHAKE_HEADER_SIZE;
00992
00993 MHD__gnutls_handshake_log ("HSK[%x]: %s was received [%ld bytes]\n",
00994 session,
00995 MHD__gnutls_handshake2str (dataptr[0]),
00996 length32 + HANDSHAKE_HEADER_SIZE);
00997
00998 }
00999 else
01000 {
01001 length32 = session->internals.v2_hello - SSL2_HEADERS;
01002
01003 handshake_header_size = SSL2_HEADERS;
01004
01005 *recv_type = dataptr[0];
01006
01007 MHD__gnutls_handshake_log ("HSK[%x]: %s(v2) was received [%ld bytes]\n",
01008 session,
01009 MHD__gnutls_handshake2str (*recv_type),
01010 length32 + handshake_header_size);
01011
01012 if (*recv_type != GNUTLS_HANDSHAKE_CLIENT_HELLO)
01013 {
01014 MHD_gnutls_assert ();
01015 return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
01016 }
01017 }
01018
01019
01020 session->internals.handshake_header_buffer.header_size =
01021 handshake_header_size;
01022 session->internals.handshake_header_buffer.packet_length = length32;
01023 session->internals.handshake_header_buffer.recv_type = *recv_type;
01024
01025 if (*recv_type != type)
01026 {
01027 MHD_gnutls_assert ();
01028 return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
01029 }
01030
01031 return length32;
01032 }
01033
01034 #define MHD__gnutls_handshake_header_buffer_clear( session) session->internals.handshake_header_buffer.header_size = 0
01035
01036
01037
01038
01039 static int
01040 MHD__gnutls_handshake_hash_add_recvd (MHD_gtls_session_t session,
01041 MHD_gnutls_handshake_description_t
01042 recv_type, opaque * header,
01043 uint16_t header_size, opaque * dataptr,
01044 uint32_t datalen)
01045 {
01046 int ret;
01047
01048
01049
01050
01051
01052 if ((ret = MHD__gnutls_handshake_hash_pending (session)) < 0)
01053 {
01054 MHD_gnutls_assert ();
01055 return ret;
01056 }
01057
01058
01059 if (recv_type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
01060 {
01061
01062 if ((ret =
01063 MHD_gtls_handshake_buffer_put (session, header, header_size)) < 0)
01064 {
01065 MHD_gnutls_assert ();
01066 return ret;
01067 }
01068
01069 if (datalen > 0)
01070 {
01071 if ((ret =
01072 MHD_gtls_handshake_buffer_put (session, dataptr, datalen)) < 0)
01073 {
01074 MHD_gnutls_assert ();
01075 return ret;
01076 }
01077 }
01078 }
01079
01080 return 0;
01081 }
01082
01083
01084
01085
01086
01087
01088 int
01089 MHD_gtls_recv_handshake (MHD_gtls_session_t session, uint8_t ** data,
01090 int *datalen,
01091 MHD_gnutls_handshake_description_t type,
01092 Optional optional)
01093 {
01094 int ret;
01095 uint32_t length32 = 0;
01096 opaque *dataptr = NULL;
01097 MHD_gnutls_handshake_description_t recv_type;
01098
01099 ret = MHD__gnutls_recv_handshake_header (session, type, &recv_type);
01100 if (ret < 0)
01101 {
01102
01103 if (ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET
01104 && optional == OPTIONAL_PACKET)
01105 {
01106 if (datalen != NULL)
01107 *datalen = 0;
01108 if (data != NULL)
01109 *data = NULL;
01110 return 0;
01111 }
01112
01113 return ret;
01114 }
01115
01116 session->internals.last_handshake_in = recv_type;
01117
01118 length32 = ret;
01119
01120 if (length32 > 0)
01121 dataptr = MHD_gnutls_malloc (length32);
01122 else if (recv_type != GNUTLS_HANDSHAKE_SERVER_HELLO_DONE)
01123 {
01124 MHD_gnutls_assert ();
01125 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
01126 }
01127
01128 if (dataptr == NULL && length32 > 0)
01129 {
01130 MHD_gnutls_assert ();
01131 return GNUTLS_E_MEMORY_ERROR;
01132 }
01133
01134 if (datalen != NULL)
01135 *datalen = length32;
01136
01137 if (length32 > 0)
01138 {
01139 ret =
01140 MHD_gtls_handshake_io_recv_int (session, GNUTLS_HANDSHAKE,
01141 type, dataptr, length32);
01142 if (ret <= 0)
01143 {
01144 MHD_gnutls_assert ();
01145 MHD_gnutls_free (dataptr);
01146 return (ret == 0) ? GNUTLS_E_UNEXPECTED_PACKET_LENGTH : ret;
01147 }
01148 }
01149
01150 if (data != NULL && length32 > 0)
01151 *data = dataptr;
01152
01153
01154 ret = MHD__gnutls_handshake_hash_add_recvd (session, recv_type,
01155 session->internals.
01156 handshake_header_buffer.header,
01157 session->internals.
01158 handshake_header_buffer.header_size,
01159 dataptr, length32);
01160 if (ret < 0)
01161 {
01162 MHD_gnutls_assert ();
01163 MHD__gnutls_handshake_header_buffer_clear (session);
01164 return ret;
01165 }
01166
01167
01168
01169
01170
01171 MHD__gnutls_handshake_header_buffer_clear (session);
01172
01173 switch (recv_type)
01174 {
01175 case GNUTLS_HANDSHAKE_CLIENT_HELLO:
01176 case GNUTLS_HANDSHAKE_SERVER_HELLO:
01177 ret = MHD_gtls_recv_hello (session, dataptr, length32);
01178
01179
01180 MHD_gnutls_free (dataptr);
01181 if (data != NULL)
01182 *data = NULL;
01183 break;
01184 case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
01185 if (length32 == 0)
01186 ret = 0;
01187 else
01188 ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
01189 break;
01190 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
01191 case GNUTLS_HANDSHAKE_FINISHED:
01192 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
01193 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
01194 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
01195 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
01196 case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
01197 ret = length32;
01198 break;
01199 default:
01200 MHD_gnutls_assert ();
01201 MHD_gnutls_free (dataptr);
01202 if (data != NULL)
01203 *data = NULL;
01204 ret = GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
01205 }
01206
01207 return ret;
01208 }
01209
01210 #if MHD_DEBUG_TLS
01211
01212
01213
01214 static int
01215 MHD__gnutls_client_set_ciphersuite (MHD_gtls_session_t session,
01216 opaque suite[2])
01217 {
01218 uint8_t z;
01219 cipher_suite_st *cipher_suites;
01220 int cipher_suite_num;
01221 int i, err;
01222
01223 z = 1;
01224 cipher_suite_num =
01225 MHD_gtls_supported_ciphersuites (session, &cipher_suites);
01226 if (cipher_suite_num < 0)
01227 {
01228 MHD_gnutls_assert ();
01229 return cipher_suite_num;
01230 }
01231
01232 for (i = 0; i < cipher_suite_num; i++)
01233 {
01234 if (memcmp (&cipher_suites[i], suite, 2) == 0)
01235 {
01236 z = 0;
01237 break;
01238 }
01239 }
01240
01241 MHD_gnutls_free (cipher_suites);
01242
01243 if (z != 0)
01244 {
01245 MHD_gnutls_assert ();
01246 return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
01247 }
01248
01249 memcpy (session->security_parameters.current_cipher_suite.suite, suite, 2);
01250
01251 MHD__gnutls_handshake_log ("HSK[%x]: Selected cipher suite: %s\n", session,
01252 MHD_gtls_cipher_suite_get_name
01253 (&session->security_parameters.
01254 current_cipher_suite));
01255
01256
01257
01258
01259
01260 if (MHD_gtls_get_kx_cred
01261 (session,
01262 MHD_gtls_cipher_suite_get_kx_algo
01263 (&session->security_parameters.current_cipher_suite), &err) == NULL
01264 && err != 0)
01265 {
01266 MHD_gnutls_assert ();
01267 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
01268 }
01269
01270
01271
01272
01273
01274
01275 session->internals.auth_struct =
01276 MHD_gtls_kx_auth_struct (MHD_gtls_cipher_suite_get_kx_algo
01277 (&session->security_parameters.
01278 current_cipher_suite));
01279
01280 if (session->internals.auth_struct == NULL)
01281 {
01282
01283 MHD__gnutls_handshake_log
01284 ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n",
01285 session);
01286 MHD_gnutls_assert ();
01287 return GNUTLS_E_INTERNAL_ERROR;
01288 }
01289
01290
01291 return 0;
01292 }
01293
01294
01295
01296
01297 static int
01298 MHD__gnutls_client_set_comp_method (MHD_gtls_session_t session,
01299 opaque comp_method)
01300 {
01301 int comp_methods_num;
01302 uint8_t *compression_methods;
01303 int i;
01304
01305 comp_methods_num = MHD_gtls_supported_compression_methods (session,
01306 &compression_methods);
01307 if (comp_methods_num < 0)
01308 {
01309 MHD_gnutls_assert ();
01310 return comp_methods_num;
01311 }
01312
01313 for (i = 0; i < comp_methods_num; i++)
01314 {
01315 if (compression_methods[i] == comp_method)
01316 {
01317 comp_methods_num = 0;
01318 break;
01319 }
01320 }
01321
01322 MHD_gnutls_free (compression_methods);
01323
01324 if (comp_methods_num != 0)
01325 {
01326 MHD_gnutls_assert ();
01327 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
01328 }
01329
01330 session->internals.compression_method =
01331 MHD_gtls_compression_get_id_from_int (comp_method);
01332
01333
01334 return 0;
01335 }
01336
01337
01338
01339
01340
01341 static int
01342 MHD__gnutls_client_check_if_resuming (MHD_gtls_session_t session,
01343 opaque * session_id, int session_id_len)
01344 {
01345 opaque buf[2 * TLS_MAX_SESSION_ID_SIZE + 1];
01346
01347 MHD__gnutls_handshake_log ("HSK[%x]: SessionID length: %d\n", session,
01348 session_id_len);
01349 MHD__gnutls_handshake_log ("HSK[%x]: SessionID: %s\n", session,
01350 MHD_gtls_bin2hex (session_id, session_id_len,
01351 (char *) buf, sizeof (buf)));
01352
01353 if (session_id_len > 0 &&
01354 session->internals.resumed_security_parameters.session_id_size ==
01355 session_id_len
01356 && memcmp (session_id,
01357 session->internals.resumed_security_parameters.session_id,
01358 session_id_len) == 0)
01359 {
01360
01361 memcpy (session->internals.resumed_security_parameters.server_random,
01362 session->security_parameters.server_random, TLS_RANDOM_SIZE);
01363 memcpy (session->internals.resumed_security_parameters.client_random,
01364 session->security_parameters.client_random, TLS_RANDOM_SIZE);
01365 session->internals.resumed = RESUME_TRUE;
01366
01367 return 0;
01368 }
01369 else
01370 {
01371
01372 session->internals.resumed = RESUME_FALSE;
01373 session->security_parameters.session_id_size = session_id_len;
01374 memcpy (session->security_parameters.session_id,
01375 session_id, session_id_len);
01376
01377 return -1;
01378 }
01379 }
01380
01381
01382
01383
01384
01385 static int
01386 MHD__gnutls_read_server_hello (MHD_gtls_session_t session,
01387 opaque * data, int datalen)
01388 {
01389 uint8_t session_id_len = 0;
01390 int pos = 0;
01391 int ret = 0;
01392 enum MHD_GNUTLS_Protocol version;
01393 int len = datalen;
01394
01395 if (datalen < 38)
01396 {
01397 MHD_gnutls_assert ();
01398 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
01399 }
01400
01401 MHD__gnutls_handshake_log ("HSK[%x]: Server's version: %d.%d\n",
01402 session, data[pos], data[pos + 1]);
01403
01404 DECR_LEN (len, 2);
01405 version = MHD_gtls_version_get (data[pos], data[pos + 1]);
01406 if (MHD_gtls_version_is_supported (session, version) == 0)
01407 {
01408 MHD_gnutls_assert ();
01409 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
01410 }
01411 else
01412 {
01413 MHD_gtls_set_current_version (session, version);
01414 }
01415
01416 pos += 2;
01417
01418 DECR_LEN (len, TLS_RANDOM_SIZE);
01419 MHD_gtls_set_server_random (session, &data[pos]);
01420 pos += TLS_RANDOM_SIZE;
01421
01422
01423
01424
01425 DECR_LEN (len, 1);
01426 session_id_len = data[pos++];
01427
01428 if (len < session_id_len)
01429 {
01430 MHD_gnutls_assert ();
01431 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
01432 }
01433 DECR_LEN (len, session_id_len);
01434
01435
01436
01437
01438
01439 if (MHD__gnutls_client_check_if_resuming
01440 (session, &data[pos], session_id_len) == 0)
01441 return 0;
01442 pos += session_id_len;
01443
01444
01445
01446
01447
01448
01449 DECR_LEN (len, 2);
01450 ret = MHD__gnutls_client_set_ciphersuite (session, &data[pos]);
01451 if (ret < 0)
01452 {
01453 MHD_gnutls_assert ();
01454 return ret;
01455 }
01456 pos += 2;
01457
01458
01459
01460
01461 DECR_LEN (len, 1);
01462
01463 ret = MHD__gnutls_client_set_comp_method (session, data[pos++]);
01464 if (ret < 0)
01465 {
01466 MHD_gnutls_assert ();
01467 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
01468 }
01469
01470
01471
01472 if (version >= MHD_GNUTLS_PROTOCOL_TLS1_0)
01473 {
01474 ret = MHD_gtls_parse_extensions (session, EXTENSION_ANY, &data[pos], len);
01475 if (ret < 0)
01476 {
01477 MHD_gnutls_assert ();
01478 return ret;
01479 }
01480 }
01481 return ret;
01482 }
01483
01484
01485
01486
01487
01488 int
01489 MHD__gnutls_copy_ciphersuites (MHD_gtls_session_t session,
01490 opaque * ret_data, size_t ret_data_size)
01491 {
01492 int ret, i;
01493 cipher_suite_st *cipher_suites;
01494 uint16_t cipher_num;
01495 int datalen, pos;
01496
01497 ret = MHD_gtls_supported_ciphersuites_sorted (session, &cipher_suites);
01498 if (ret < 0)
01499 {
01500 MHD_gnutls_assert ();
01501 return ret;
01502 }
01503
01504
01505
01506
01507
01508 ret =
01509 MHD_gtls_remove_unwanted_ciphersuites (session, &cipher_suites, ret, -1);
01510 if (ret < 0)
01511 {
01512 MHD_gnutls_assert ();
01513 MHD_gnutls_free (cipher_suites);
01514 return ret;
01515 }
01516
01517
01518
01519 if (ret == 0)
01520 {
01521 MHD_gnutls_assert ();
01522 MHD_gnutls_free (cipher_suites);
01523 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
01524 }
01525
01526 cipher_num = ret;
01527
01528 cipher_num *= sizeof (uint16_t);
01529
01530 datalen = pos = 0;
01531
01532 datalen += sizeof (uint16_t) + cipher_num;
01533
01534 if ((size_t) datalen > ret_data_size)
01535 {
01536 MHD_gnutls_assert ();
01537 return GNUTLS_E_INTERNAL_ERROR;
01538 }
01539
01540 MHD_gtls_write_uint16 (cipher_num, ret_data);
01541 pos += 2;
01542
01543 for (i = 0; i < (cipher_num / 2); i++)
01544 {
01545 memcpy (&ret_data[pos], cipher_suites[i].suite, 2);
01546 pos += 2;
01547 }
01548 MHD_gnutls_free (cipher_suites);
01549
01550 return datalen;
01551 }
01552
01553
01554
01555
01556 static int
01557 MHD__gnutls_copy_comp_methods (MHD_gtls_session_t session,
01558 opaque * ret_data, size_t ret_data_size)
01559 {
01560 int ret, i;
01561 uint8_t *compression_methods, comp_num;
01562 int datalen, pos;
01563
01564 ret =
01565 MHD_gtls_supported_compression_methods (session, &compression_methods);
01566 if (ret < 0)
01567 {
01568 MHD_gnutls_assert ();
01569 return ret;
01570 }
01571
01572 comp_num = ret;
01573
01574 datalen = pos = 0;
01575 datalen += comp_num + 1;
01576
01577 if ((size_t) datalen > ret_data_size)
01578 {
01579 MHD_gnutls_assert ();
01580 return GNUTLS_E_INTERNAL_ERROR;
01581 }
01582
01583 ret_data[pos++] = comp_num;
01584
01585 for (i = 0; i < comp_num; i++)
01586 {
01587 ret_data[pos++] = compression_methods[i];
01588 }
01589
01590 MHD_gnutls_free (compression_methods);
01591
01592 return datalen;
01593 }
01594
01595 static void
01596 MHD_gtls_set_adv_version (MHD_gtls_session_t session,
01597 enum MHD_GNUTLS_Protocol ver)
01598 {
01599 set_adv_version (session, MHD_gtls_version_get_major (ver),
01600 MHD_gtls_version_get_minor (ver));
01601 }
01602
01603
01604
01605 static int
01606 MHD__gnutls_send_client_hello (MHD_gtls_session_t session, int again)
01607 {
01608 opaque *data = NULL;
01609 int extdatalen;
01610 int pos = 0;
01611 int datalen = 0, ret = 0;
01612 opaque rnd[TLS_RANDOM_SIZE];
01613 enum MHD_GNUTLS_Protocol hver;
01614 opaque extdata[MAX_EXT_DATA_LENGTH];
01615
01616 opaque *SessionID =
01617 session->internals.resumed_security_parameters.session_id;
01618 uint8_t session_id_len =
01619 session->internals.resumed_security_parameters.session_id_size;
01620
01621 if (SessionID == NULL)
01622 session_id_len = 0;
01623 else if (session_id_len == 0)
01624 SessionID = NULL;
01625
01626 if (again == 0)
01627 {
01628
01629 datalen = 2 + (session_id_len + 1) + TLS_RANDOM_SIZE;
01630
01631
01632
01633 data = MHD_gnutls_malloc (datalen);
01634 if (data == NULL)
01635 {
01636 MHD_gnutls_assert ();
01637 return GNUTLS_E_MEMORY_ERROR;
01638 }
01639
01640
01641
01642
01643 if (SessionID == NULL)
01644 hver = MHD_gtls_version_max (session);
01645 else
01646 {
01647 hver = session->internals.resumed_security_parameters.version;
01648 }
01649
01650 if (hver == MHD_GNUTLS_PROTOCOL_VERSION_UNKNOWN || hver == 0)
01651 {
01652 MHD_gnutls_assert ();
01653 MHD_gnutls_free (data);
01654 return GNUTLS_E_INTERNAL_ERROR;
01655 }
01656
01657 data[pos++] = MHD_gtls_version_get_major (hver);
01658 data[pos++] = MHD_gtls_version_get_minor (hver);
01659
01660
01661
01662
01663 MHD_gtls_set_adv_version (session, hver);
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673 MHD_gtls_set_current_version (session, hver);
01674
01675
01676
01677 session->security_parameters.timestamp = time (NULL);
01678
01679
01680
01681 MHD_gtls_tls_create_random (rnd);
01682 MHD_gtls_set_client_random (session, rnd);
01683
01684 memcpy (&data[pos], rnd, TLS_RANDOM_SIZE);
01685 pos += TLS_RANDOM_SIZE;
01686
01687
01688 data[pos++] = session_id_len;
01689
01690 if (session_id_len > 0)
01691 {
01692 memcpy (&data[pos], SessionID, session_id_len);
01693 pos += session_id_len;
01694 }
01695
01696
01697
01698
01699 extdatalen =
01700 MHD__gnutls_copy_ciphersuites (session, extdata, sizeof (extdata));
01701 if (extdatalen > 0)
01702 {
01703 datalen += extdatalen;
01704 data = MHD_gtls_realloc_fast (data, datalen);
01705 if (data == NULL)
01706 {
01707 MHD_gnutls_assert ();
01708 return GNUTLS_E_MEMORY_ERROR;
01709 }
01710
01711 memcpy (&data[pos], extdata, extdatalen);
01712 pos += extdatalen;
01713
01714 }
01715 else
01716 {
01717 if (extdatalen == 0)
01718 extdatalen = GNUTLS_E_INTERNAL_ERROR;
01719 MHD_gnutls_free (data);
01720 MHD_gnutls_assert ();
01721 return extdatalen;
01722 }
01723
01724
01725
01726
01727 extdatalen =
01728 MHD__gnutls_copy_comp_methods (session, extdata, sizeof (extdata));
01729 if (extdatalen > 0)
01730 {
01731 datalen += extdatalen;
01732 data = MHD_gtls_realloc_fast (data, datalen);
01733 if (data == NULL)
01734 {
01735 MHD_gnutls_assert ();
01736 return GNUTLS_E_MEMORY_ERROR;
01737 }
01738
01739 memcpy (&data[pos], extdata, extdatalen);
01740 pos += extdatalen;
01741
01742 }
01743 else
01744 {
01745 if (extdatalen == 0)
01746 extdatalen = GNUTLS_E_INTERNAL_ERROR;
01747 MHD_gnutls_free (data);
01748 MHD_gnutls_assert ();
01749 return extdatalen;
01750 }
01751
01752
01753
01754 if (hver >= MHD_GNUTLS_PROTOCOL_TLS1_0)
01755 {
01756 extdatalen =
01757 MHD_gtls_gen_extensions (session, extdata, sizeof (extdata));
01758
01759 if (extdatalen > 0)
01760 {
01761 datalen += extdatalen;
01762 data = MHD_gtls_realloc_fast (data, datalen);
01763 if (data == NULL)
01764 {
01765 MHD_gnutls_assert ();
01766 return GNUTLS_E_MEMORY_ERROR;
01767 }
01768
01769 memcpy (&data[pos], extdata, extdatalen);
01770 }
01771 else if (extdatalen < 0)
01772 {
01773 MHD_gnutls_assert ();
01774 MHD_gnutls_free (data);
01775 return extdatalen;
01776 }
01777 }
01778 }
01779
01780 ret =
01781 MHD_gtls_send_handshake (session, data, datalen,
01782 GNUTLS_HANDSHAKE_CLIENT_HELLO);
01783 MHD_gnutls_free (data);
01784
01785 return ret;
01786 }
01787 #endif
01788
01789 static int
01790 MHD__gnutls_send_server_hello (MHD_gtls_session_t session, int again)
01791 {
01792 opaque *data = NULL;
01793 opaque extdata[MAX_EXT_DATA_LENGTH];
01794 int extdatalen;
01795 int pos = 0;
01796 int datalen, ret = 0;
01797 uint8_t comp;
01798 opaque *SessionID = session->security_parameters.session_id;
01799 uint8_t session_id_len = session->security_parameters.session_id_size;
01800 opaque buf[2 * TLS_MAX_SESSION_ID_SIZE + 1];
01801
01802 if (SessionID == NULL)
01803 session_id_len = 0;
01804
01805 datalen = 0;
01806
01807 if (again == 0)
01808 {
01809 datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE + 3;
01810 extdatalen =
01811 MHD_gtls_gen_extensions (session, extdata, sizeof (extdata));
01812
01813 if (extdatalen < 0)
01814 {
01815 MHD_gnutls_assert ();
01816 return extdatalen;
01817 }
01818
01819 data = MHD_gnutls_alloca (datalen + extdatalen);
01820 if (data == NULL)
01821 {
01822 MHD_gnutls_assert ();
01823 return GNUTLS_E_MEMORY_ERROR;
01824 }
01825
01826 data[pos++] =
01827 MHD_gtls_version_get_major (session->security_parameters.version);
01828 data[pos++] =
01829 MHD_gtls_version_get_minor (session->security_parameters.version);
01830
01831 memcpy (&data[pos],
01832 session->security_parameters.server_random, TLS_RANDOM_SIZE);
01833 pos += TLS_RANDOM_SIZE;
01834
01835 data[pos++] = session_id_len;
01836 if (session_id_len > 0)
01837 {
01838 memcpy (&data[pos], SessionID, session_id_len);
01839 }
01840 pos += session_id_len;
01841
01842 MHD__gnutls_handshake_log ("HSK[%x]: SessionID: %s\n", session,
01843 MHD_gtls_bin2hex (SessionID, session_id_len,
01844 (char *) buf,
01845 sizeof (buf)));
01846
01847 memcpy (&data[pos],
01848 session->security_parameters.current_cipher_suite.suite, 2);
01849 pos += 2;
01850
01851 comp =
01852 (uint8_t) MHD_gtls_compression_get_num (session->
01853 internals.compression_method);
01854 data[pos++] = comp;
01855
01856
01857 if (extdatalen > 0)
01858 {
01859 datalen += extdatalen;
01860
01861 memcpy (&data[pos], extdata, extdatalen);
01862 }
01863 }
01864
01865 ret =
01866 MHD_gtls_send_handshake (session, data, datalen,
01867 GNUTLS_HANDSHAKE_SERVER_HELLO);
01868 MHD_gnutls_afree (data);
01869
01870 return ret;
01871 }
01872
01873 int
01874 MHD_gtls_send_hello (MHD_gtls_session_t session, int again)
01875 {
01876 int ret;
01877 #if MHD_DEBUG_TLS
01878 if (session->security_parameters.entity == GNUTLS_CLIENT)
01879 {
01880 ret = MHD__gnutls_send_client_hello (session, again);
01881
01882 }
01883 else
01884 #endif
01885 {
01886 ret = MHD__gnutls_send_server_hello (session, again);
01887 }
01888
01889 return ret;
01890 }
01891
01892
01893
01894
01895
01896 int
01897 MHD_gtls_recv_hello (MHD_gtls_session_t session, opaque * data, int datalen)
01898 {
01899 int ret;
01900 #if MHD_DEBUG_TLS
01901 if (session->security_parameters.entity == GNUTLS_CLIENT)
01902 {
01903 ret = MHD__gnutls_read_server_hello (session, data, datalen);
01904 if (ret < 0)
01905 {
01906 MHD_gnutls_assert ();
01907 return ret;
01908 }
01909 }
01910 else
01911 #endif
01912 {
01913
01914 ret = MHD__gnutls_read_client_hello (session, data, datalen);
01915 if (ret < 0)
01916 {
01917 MHD_gnutls_assert ();
01918 return ret;
01919 }
01920 }
01921
01922 return ret;
01923 }
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01971 int
01972 MHD__gnutls_rehandshake (MHD_gtls_session_t session)
01973 {
01974 int ret;
01975
01976 ret =
01977 MHD__gnutls_send_empty_handshake (session, GNUTLS_HANDSHAKE_HELLO_REQUEST,
01978 AGAIN (STATE50));
01979 STATE = STATE50;
01980
01981 if (ret < 0)
01982 {
01983 MHD_gnutls_assert ();
01984 return ret;
01985 }
01986 STATE = STATE0;
01987
01988 return 0;
01989 }
01990
01991 inline static int
01992 MHD__gnutls_abort_handshake (MHD_gtls_session_t session, int ret)
01993 {
01994 if (((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) &&
01995 (MHD_gnutls_alert_get (session) == GNUTLS_A_NO_RENEGOTIATION))
01996 || ret == GNUTLS_E_GOT_APPLICATION_DATA)
01997 return 0;
01998
01999
02000 return GNUTLS_E_INTERNAL_ERROR;
02001 }
02002
02003
02004
02005
02006 inline static int
02007 MHD__gnutls_handshake_hash_init (MHD_gtls_session_t session)
02008 {
02009
02010 if (session->internals.handshake_mac_handle_md5 == NULL)
02011 {
02012 session->internals.handshake_mac_handle_md5 =
02013 MHD_gtls_hash_init (MHD_GNUTLS_MAC_MD5);
02014
02015 if (session->internals.handshake_mac_handle_md5 == GNUTLS_HASH_FAILED)
02016 {
02017 MHD_gnutls_assert ();
02018 return GNUTLS_E_MEMORY_ERROR;
02019 }
02020 }
02021
02022 if (session->internals.handshake_mac_handle_sha == NULL)
02023 {
02024 session->internals.handshake_mac_handle_sha =
02025 MHD_gtls_hash_init (MHD_GNUTLS_MAC_SHA1);
02026 if (session->internals.handshake_mac_handle_sha == GNUTLS_HASH_FAILED)
02027 {
02028 MHD_gnutls_assert ();
02029 return GNUTLS_E_MEMORY_ERROR;
02030 }
02031 }
02032
02033 return 0;
02034 }
02035
02036 static int
02037 MHD__gnutls_send_supplemental (MHD_gtls_session_t session, int again)
02038 {
02039 int ret = 0;
02040
02041 MHD__gnutls_debug_log ("EXT[%x]: Sending supplemental data\n", session);
02042
02043 if (again)
02044 ret = MHD_gtls_send_handshake (session, NULL, 0,
02045 GNUTLS_HANDSHAKE_SUPPLEMENTAL);
02046 else
02047 {
02048 MHD_gtls_buffer buf;
02049 MHD_gtls_buffer_init (&buf);
02050
02051 ret = MHD__gnutls_gen_supplemental (session, &buf);
02052 if (ret < 0)
02053 {
02054 MHD_gnutls_assert ();
02055 return ret;
02056 }
02057
02058 ret = MHD_gtls_send_handshake (session, buf.data, buf.length,
02059 GNUTLS_HANDSHAKE_SUPPLEMENTAL);
02060 MHD_gtls_buffer_clear (&buf);
02061 }
02062
02063 return ret;
02064 }
02065
02066 static int
02067 MHD__gnutls_recv_supplemental (MHD_gtls_session_t session)
02068 {
02069 uint8_t *data = NULL;
02070 int datalen = 0;
02071 int ret;
02072
02073 MHD__gnutls_debug_log ("EXT[%x]: Expecting supplemental data\n", session);
02074
02075 ret = MHD_gtls_recv_handshake (session, &data, &datalen,
02076 GNUTLS_HANDSHAKE_SUPPLEMENTAL,
02077 OPTIONAL_PACKET);
02078 if (ret < 0)
02079 {
02080 MHD_gnutls_assert ();
02081 return ret;
02082 }
02083
02084 ret = MHD__gnutls_parse_supplemental (session, data, datalen);
02085 if (ret < 0)
02086 {
02087 MHD_gnutls_assert ();
02088 return ret;
02089 }
02090
02091 MHD_gnutls_free (data);
02092
02093 return ret;
02094 }
02095
02123 int
02124 MHD__gnutls_handshake (MHD_gtls_session_t session)
02125 {
02126 int ret;
02127
02128 if ((ret = MHD__gnutls_handshake_hash_init (session)) < 0)
02129 {
02130 MHD_gnutls_assert ();
02131 return ret;
02132 }
02133 #if MHD_DEBUG_TLS
02134 if (session->security_parameters.entity == GNUTLS_CLIENT)
02135 {
02136 ret = MHD_gtls_handshake_client (session);
02137 }
02138 else
02139 #endif
02140 {
02141 ret = MHD_gtls_handshake_server (session);
02142 }
02143
02144 if (ret < 0)
02145 {
02146
02147
02148
02149 if (MHD__gnutls_abort_handshake (session, ret) == 0)
02150 STATE = STATE0;
02151
02152 return ret;
02153 }
02154
02155 ret = MHD_gtls_handshake_common (session);
02156
02157 if (ret < 0)
02158 {
02159 if (MHD__gnutls_abort_handshake (session, ret) == 0)
02160 STATE = STATE0;
02161
02162 return ret;
02163 }
02164
02165 STATE = STATE0;
02166
02167 MHD__gnutls_handshake_io_buffer_clear (session);
02168 MHD_gtls_handshake_internal_state_clear (session);
02169
02170 return 0;
02171 }
02172
02173 #define IMED_RET( str, ret) do { \
02174 if (ret < 0) { \
02175 if (MHD_gtls_error_is_fatal(ret)==0) return ret; \
02176 MHD_gnutls_assert(); \
02177 ERR( str, ret); \
02178 MHD__gnutls_handshake_hash_buffers_clear(session); \
02179 return ret; \
02180 } } while (0)
02181
02182
02183 #if MHD_DEBUG_TLS
02184
02185
02186
02187
02188 static int
02189 MHD_gtls_handshake_client (MHD_gtls_session_t session)
02190 {
02191 int ret = 0;
02192
02193 switch (STATE)
02194 {
02195 case STATE0:
02196 case STATE1:
02197 ret = MHD_gtls_send_hello (session, AGAIN (STATE1));
02198 STATE = STATE1;
02199 IMED_RET ("send hello", ret);
02200
02201 case STATE2:
02202
02203 ret =
02204 MHD_gtls_recv_handshake (session, NULL, NULL,
02205 GNUTLS_HANDSHAKE_SERVER_HELLO,
02206 MANDATORY_PACKET);
02207 STATE = STATE2;
02208 IMED_RET ("recv hello", ret);
02209
02210 case STATE70:
02211 if (session->security_parameters.extensions.do_recv_supplemental)
02212 {
02213 ret = MHD__gnutls_recv_supplemental (session);
02214 STATE = STATE70;
02215 IMED_RET ("recv supplemental", ret);
02216 }
02217
02218 case STATE3:
02219
02220 if (session->internals.resumed == RESUME_FALSE)
02221 ret = MHD_gtls_recv_server_certificate (session);
02222 STATE = STATE3;
02223 IMED_RET ("recv server certificate", ret);
02224
02225 case STATE4:
02226
02227 if (session->internals.resumed == RESUME_FALSE)
02228 ret = MHD_gtls_recv_server_kx_message (session);
02229 STATE = STATE4;
02230 IMED_RET ("recv server kx message", ret);
02231
02232 case STATE5:
02233
02234
02235
02236 if (session->internals.resumed == RESUME_FALSE)
02237 ret = MHD_gtls_recv_server_certificate_request (session);
02238 STATE = STATE5;
02239 IMED_RET ("recv server certificate request message", ret);
02240
02241 case STATE6:
02242
02243 if (session->internals.resumed == RESUME_FALSE)
02244 ret =
02245 MHD_gtls_recv_handshake (session, NULL, NULL,
02246 GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
02247 MANDATORY_PACKET);
02248 STATE = STATE6;
02249 IMED_RET ("recv server hello done", ret);
02250
02251 case STATE71:
02252 if (session->security_parameters.extensions.do_send_supplemental)
02253 {
02254 ret = MHD__gnutls_send_supplemental (session, AGAIN (STATE71));
02255 STATE = STATE71;
02256 IMED_RET ("send supplemental", ret);
02257 }
02258
02259 case STATE7:
02260
02261
02262 if (session->internals.resumed == RESUME_FALSE)
02263 ret = MHD_gtls_send_client_certificate (session, AGAIN (STATE7));
02264 STATE = STATE7;
02265 IMED_RET ("send client certificate", ret);
02266
02267 case STATE8:
02268 if (session->internals.resumed == RESUME_FALSE)
02269 ret = MHD_gtls_send_client_kx_message (session, AGAIN (STATE8));
02270 STATE = STATE8;
02271 IMED_RET ("send client kx", ret);
02272
02273 case STATE9:
02274
02275 if (session->internals.resumed == RESUME_FALSE)
02276 ret =
02277 MHD_gtls_send_client_certificate_verify (session, AGAIN (STATE9));
02278 STATE = STATE9;
02279 IMED_RET ("send client certificate verify", ret);
02280
02281 STATE = STATE0;
02282 default:
02283 break;
02284 }
02285
02286
02287 return 0;
02288 }
02289 #endif
02290
02291
02292
02293 static int
02294 MHD__gnutls_send_handshake_final (MHD_gtls_session_t session, int init)
02295 {
02296 int ret = 0;
02297
02298
02299
02300 switch (STATE)
02301 {
02302 case STATE0:
02303 case STATE20:
02304 ret = MHD_gtls_send_change_cipher_spec (session, AGAIN (STATE20));
02305 STATE = STATE20;
02306 if (ret < 0)
02307 {
02308 ERR ("send ChangeCipherSpec", ret);
02309 MHD_gnutls_assert ();
02310 return ret;
02311 }
02312
02313
02314
02315 if (init == TRUE)
02316 {
02317 ret = MHD_gtls_connection_state_init (session);
02318 if (ret < 0)
02319 {
02320 MHD_gnutls_assert ();
02321 return ret;
02322 }
02323 }
02324
02325 ret = MHD_gtls_write_connection_state_init (session);
02326 if (ret < 0)
02327 {
02328 MHD_gnutls_assert ();
02329 return ret;
02330 }
02331
02332 case STATE21:
02333
02334 ret = MHD__gnutls_send_finished (session, AGAIN (STATE21));
02335 STATE = STATE21;
02336 if (ret < 0)
02337 {
02338 ERR ("send Finished", ret);
02339 MHD_gnutls_assert ();
02340 return ret;
02341 }
02342
02343 STATE = STATE0;
02344 default:
02345 break;
02346 }
02347
02348 return 0;
02349 }
02350
02351
02352
02353
02354
02355 static int
02356 MHD__gnutls_recv_handshake_final (MHD_gtls_session_t session, int init)
02357 {
02358 int ret = 0;
02359 uint8_t ch;
02360
02361 switch (STATE)
02362 {
02363 case STATE0:
02364 case STATE30:
02365 ret =
02366 MHD_gtls_recv_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, &ch, 1);
02367 STATE = STATE30;
02368 if (ret <= 0)
02369 {
02370 ERR ("recv ChangeCipherSpec", ret);
02371 MHD_gnutls_assert ();
02372 return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
02373 }
02374
02375
02376 if (init == TRUE)
02377 {
02378 ret = MHD_gtls_connection_state_init (session);
02379 if (ret < 0)
02380 {
02381 MHD_gnutls_assert ();
02382 return ret;
02383 }
02384 }
02385
02386 ret = MHD_gtls_read_connection_state_init (session);
02387 if (ret < 0)
02388 {
02389 MHD_gnutls_assert ();
02390 return ret;
02391 }
02392
02393 case STATE31:
02394 ret = MHD__gnutls_recv_finished (session);
02395 STATE = STATE31;
02396 if (ret < 0)
02397 {
02398 ERR ("recv finished", ret);
02399 MHD_gnutls_assert ();
02400 return ret;
02401 }
02402 STATE = STATE0;
02403 default:
02404 break;
02405 }
02406
02407
02408 return 0;
02409 }
02410
02411
02412
02413
02414
02415
02416 static int
02417 MHD_gtls_handshake_server (MHD_gtls_session_t session)
02418 {
02419 int ret = 0;
02420
02421 switch (STATE)
02422 {
02423 case STATE0:
02424 case STATE1:
02425 ret =
02426 MHD_gtls_recv_handshake (session, NULL, NULL,
02427 GNUTLS_HANDSHAKE_CLIENT_HELLO,
02428 MANDATORY_PACKET);
02429 STATE = STATE1;
02430 IMED_RET ("recv hello", ret);
02431
02432 case STATE2:
02433 ret = MHD_gtls_send_hello (session, AGAIN (STATE2));
02434 STATE = STATE2;
02435 IMED_RET ("send hello", ret);
02436
02437 case STATE70:
02438 if (session->security_parameters.extensions.do_send_supplemental)
02439 {
02440 ret = MHD__gnutls_send_supplemental (session, AGAIN (STATE70));
02441 STATE = STATE70;
02442 IMED_RET ("send supplemental data", ret);
02443 }
02444
02445
02446 case STATE3:
02447
02448
02449 if (session->internals.resumed == RESUME_FALSE)
02450 ret = MHD_gtls_send_server_certificate (session, AGAIN (STATE3));
02451 STATE = STATE3;
02452 IMED_RET ("send server certificate", ret);
02453
02454 case STATE4:
02455
02456 if (session->internals.resumed == RESUME_FALSE)
02457 ret = MHD_gtls_send_server_kx_message (session, AGAIN (STATE4));
02458 STATE = STATE4;
02459 IMED_RET ("send server kx", ret);
02460
02461 case STATE5:
02462
02463 if (session->internals.resumed == RESUME_FALSE)
02464 ret =
02465 MHD_gtls_send_server_certificate_request (session, AGAIN (STATE5));
02466 STATE = STATE5;
02467 IMED_RET ("send server cert request", ret);
02468
02469 case STATE6:
02470
02471 if (session->internals.resumed == RESUME_FALSE)
02472 ret =
02473 MHD__gnutls_send_empty_handshake (session,
02474 GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
02475 AGAIN (STATE6));
02476 STATE = STATE6;
02477 IMED_RET ("send server hello done", ret);
02478
02479 case STATE71:
02480 if (session->security_parameters.extensions.do_recv_supplemental)
02481 {
02482 ret = MHD__gnutls_recv_supplemental (session);
02483 STATE = STATE71;
02484 IMED_RET ("recv client supplemental", ret);
02485 }
02486
02487
02488 case STATE7:
02489
02490 if (session->internals.resumed == RESUME_FALSE)
02491 ret = MHD_gtls_recv_client_certificate (session);
02492 STATE = STATE7;
02493 IMED_RET ("recv client certificate", ret);
02494
02495 case STATE8:
02496
02497 if (session->internals.resumed == RESUME_FALSE)
02498 ret = MHD_gtls_recv_client_kx_message (session);
02499 STATE = STATE8;
02500 IMED_RET ("recv client kx", ret);
02501
02502 case STATE9:
02503
02504 if (session->internals.resumed == RESUME_FALSE)
02505 ret = MHD_gtls_recv_client_certificate_verify_message (session);
02506 STATE = STATE9;
02507 IMED_RET ("recv client certificate verify", ret);
02508
02509 STATE = STATE0;
02510 default:
02511 break;
02512 }
02513
02514 return 0;
02515 }
02516
02517 static int
02518 MHD_gtls_handshake_common (MHD_gtls_session_t session)
02519 {
02520 int ret = 0;
02521
02522
02523 if ((session->internals.resumed == RESUME_TRUE
02524 && session->security_parameters.entity == GNUTLS_CLIENT)
02525 || (session->internals.resumed == RESUME_FALSE
02526 && session->security_parameters.entity == GNUTLS_SERVER))
02527 {
02528
02529
02530 ret = MHD__gnutls_recv_handshake_final (session, TRUE);
02531 IMED_RET ("recv handshake final", ret);
02532
02533 ret = MHD__gnutls_send_handshake_final (session, FALSE);
02534 IMED_RET ("send handshake final", ret);
02535 }
02536 else
02537 {
02538
02539 ret = MHD__gnutls_send_handshake_final (session, TRUE);
02540 IMED_RET ("send handshake final 2", ret);
02541
02542 ret = MHD__gnutls_recv_handshake_final (session, FALSE);
02543 IMED_RET ("recv handshake final 2", ret);
02544 }
02545
02546
02547 MHD__gnutls_handshake_hash_buffers_clear (session);
02548 return ret;
02549
02550 }
02551
02552 static int
02553 MHD_gtls_generate_session_id (opaque * session_id, uint8_t * len)
02554 {
02555 *len = TLS_MAX_SESSION_ID_SIZE;
02556
02557 if (MHD_gc_nonce ((char *) session_id, *len) != GC_OK)
02558 {
02559 MHD_gnutls_assert ();
02560 return GNUTLS_E_RANDOM_FAILED;
02561 }
02562
02563 return 0;
02564 }
02565
02566 int
02567 MHD_gtls_recv_hello_request (MHD_gtls_session_t session, void *data,
02568 uint32_t data_size)
02569 {
02570 uint8_t type;
02571
02572 if (session->security_parameters.entity == GNUTLS_SERVER)
02573 {
02574 MHD_gnutls_assert ();
02575 return GNUTLS_E_UNEXPECTED_PACKET;
02576 }
02577 if (data_size < 1)
02578 {
02579 MHD_gnutls_assert ();
02580 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
02581 }
02582 type = ((uint8_t *) data)[0];
02583 if (type == GNUTLS_HANDSHAKE_HELLO_REQUEST)
02584 return GNUTLS_E_REHANDSHAKE;
02585 else
02586 {
02587 MHD_gnutls_assert ();
02588 return GNUTLS_E_UNEXPECTED_PACKET;
02589 }
02590 }
02591
02592
02593
02594
02595 inline static int
02596 check_server_params (MHD_gtls_session_t session,
02597 enum MHD_GNUTLS_KeyExchangeAlgorithm kx,
02598 enum MHD_GNUTLS_KeyExchangeAlgorithm *alg, int alg_size)
02599 {
02600 int cred_type;
02601 MHD_gtls_dh_params_t dh_params = NULL;
02602 MHD_gtls_rsa_params_t rsa_params = NULL;
02603 int j;
02604
02605 cred_type = MHD_gtls_map_kx_get_cred (kx, 1);
02606
02607
02608
02609 if (cred_type == MHD_GNUTLS_CRD_CERTIFICATE)
02610 {
02611 int delete;
02612 MHD_gtls_cert_credentials_t x509_cred =
02613 (MHD_gtls_cert_credentials_t) MHD_gtls_get_cred (session->key,
02614 cred_type, NULL);
02615
02616 if (x509_cred != NULL)
02617 {
02618 dh_params =
02619 MHD_gtls_get_dh_params (x509_cred->dh_params,
02620 x509_cred->params_func, session);
02621 rsa_params =
02622 MHD_gtls_certificate_get_rsa_params (x509_cred->rsa_params,
02623 x509_cred->params_func,
02624 session);
02625 }
02626
02627
02628
02629
02630 delete = 1;
02631 for (j = 0; j < alg_size; j++)
02632 {
02633 if (alg[j] == kx)
02634 {
02635 delete = 0;
02636 break;
02637 }
02638 }
02639
02640 if (delete == 1)
02641 return 1;
02642
02643 }
02644 else
02645 return 0;
02646
02647
02648
02649
02650
02651 if (MHD_gtls_kx_needs_rsa_params (kx) != 0)
02652 {
02653
02654 if (MHD__gnutls_rsa_params_to_mpi (rsa_params) == NULL)
02655 {
02656 MHD_gnutls_assert ();
02657 return 1;
02658 }
02659 }
02660
02661 if (MHD_gtls_kx_needs_dh_params (kx) != 0)
02662 {
02663
02664 if (MHD_gtls_dh_params_to_mpi (dh_params) == NULL)
02665 {
02666 MHD_gnutls_assert ();
02667 return 1;
02668 }
02669 }
02670
02671 return 0;
02672 }
02673
02674
02675
02676
02677
02678
02679
02680
02681 static int
02682 MHD_gtls_remove_unwanted_ciphersuites (MHD_gtls_session_t session,
02683 cipher_suite_st ** cipherSuites,
02684 int numCipherSuites,
02685 enum MHD_GNUTLS_PublicKeyAlgorithm
02686 requested_pk_algo)
02687 {
02688
02689 int ret = 0;
02690 cipher_suite_st *newSuite, cs;
02691 int newSuiteSize = 0, i;
02692 MHD_gtls_cert_credentials_t cert_cred;
02693 enum MHD_GNUTLS_KeyExchangeAlgorithm kx;
02694 int server = session->security_parameters.entity == GNUTLS_SERVER ? 1 : 0;
02695 enum MHD_GNUTLS_KeyExchangeAlgorithm *alg = NULL;
02696 int alg_size = 0;
02697
02698
02699
02700
02701
02702
02703
02704 cert_cred =
02705 (MHD_gtls_cert_credentials_t) MHD_gtls_get_cred (session->key,
02706 MHD_GNUTLS_CRD_CERTIFICATE,
02707 NULL);
02708
02709
02710
02711
02712 if (session->security_parameters.entity == GNUTLS_SERVER
02713 && cert_cred != NULL)
02714 {
02715 ret = MHD_gtls_server_select_cert (session, requested_pk_algo);
02716 if (ret < 0)
02717 {
02718 MHD_gnutls_assert ();
02719 MHD__gnutls_x509_log
02720 ("Could not find an appropriate certificate: %s\n",
02721 MHD_gtls_strerror (ret));
02722 cert_cred = NULL;
02723 }
02724 }
02725
02726
02727
02728
02729 if ((ret =
02730 MHD_gtls_selected_cert_supported_kx (session, &alg, &alg_size)) < 0)
02731 {
02732 MHD_gnutls_assert ();
02733 return ret;
02734 }
02735
02736 newSuite = MHD_gnutls_malloc (numCipherSuites * sizeof (cipher_suite_st));
02737 if (newSuite == NULL)
02738 {
02739 MHD_gnutls_assert ();
02740 MHD_gnutls_free (alg);
02741 return GNUTLS_E_MEMORY_ERROR;
02742 }
02743
02744
02745
02746 for (i = 0; i < numCipherSuites; i++)
02747 {
02748 int delete = 0;
02749
02750
02751
02752
02753 kx = MHD_gtls_cipher_suite_get_kx_algo (&(*cipherSuites)[i]);
02754
02755
02756
02757 if (MHD_gtls_get_kx_cred (session, kx, NULL) == NULL)
02758 {
02759 delete = 1;
02760 }
02761 else
02762 {
02763 delete = 0;
02764
02765 if (server)
02766 delete = check_server_params (session, kx, alg, alg_size);
02767 }
02768 memcpy (&cs.suite, &(*cipherSuites)[i].suite, 2);
02769
02770 if (delete == 0)
02771 {
02772
02773 MHD__gnutls_handshake_log ("HSK[%x]: Keeping ciphersuite: %s\n",
02774 session,
02775 MHD_gtls_cipher_suite_get_name (&cs));
02776
02777 memcpy (newSuite[newSuiteSize].suite, (*cipherSuites)[i].suite, 2);
02778 newSuiteSize++;
02779 }
02780 else
02781 {
02782 MHD__gnutls_handshake_log ("HSK[%x]: Removing ciphersuite: %s\n",
02783 session,
02784 MHD_gtls_cipher_suite_get_name (&cs));
02785
02786 }
02787 }
02788
02789 MHD_gnutls_free (alg);
02790 MHD_gnutls_free (*cipherSuites);
02791 *cipherSuites = newSuite;
02792
02793 ret = newSuiteSize;
02794
02795 return ret;
02796
02797 }
02798
02799 enum MHD_GNUTLS_Protocol
02800 MHD_gtls_get_adv_version (MHD_gtls_session_t session)
02801 {
02802 return MHD_gtls_version_get (MHD__gnutls_get_adv_version_major (session),
02803 MHD__gnutls_get_adv_version_minor (session));
02804 }