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
00029
00030 #include <gnutls_int.h>
00031 #include <gnutls_errors.h>
00032 #include <gnutls_auth_int.h>
00033 #include <gnutls_num.h>
00034 #include <gnutls_datum.h>
00035 #include <gnutls_record.h>
00036 #include <gnutls_handshake.h>
00037 #include <gnutls_dh.h>
00038 #include <gnutls_buffers.h>
00039 #include <gnutls_state.h>
00040 #include <auth_cert.h>
00041 #include <gnutls_algorithms.h>
00042 #include <gnutls_rsa_export.h>
00043
00044 void
00045 MHD__gnutls_session_cert_type_set (MHD_gtls_session_t session,
00046 enum MHD_GNUTLS_CertificateType ct)
00047 {
00048 session->security_parameters.cert_type = ct;
00049 }
00050
00057 enum MHD_GNUTLS_CipherAlgorithm
00058 MHD_gnutls_cipher_get (MHD_gtls_session_t session)
00059 {
00060 return session->security_parameters.read_bulk_cipher_algorithm;
00061 }
00062
00073 enum MHD_GNUTLS_CertificateType
00074 MHD_gnutls_certificate_type_get (MHD_gtls_session_t session)
00075 {
00076 return session->security_parameters.cert_type;
00077 }
00078
00085 enum MHD_GNUTLS_KeyExchangeAlgorithm
00086 MHD_gnutls_kx_get (MHD_gtls_session_t session)
00087 {
00088 return session->security_parameters.kx_algorithm;
00089 }
00090
00091
00092
00093
00094
00095 int
00096 MHD_gtls_session_cert_type_supported (MHD_gtls_session_t session,
00097 enum MHD_GNUTLS_CertificateType
00098 cert_type)
00099 {
00100 unsigned i;
00101 unsigned cert_found = 0;
00102 MHD_gtls_cert_credentials_t cred;
00103
00104 if (session->security_parameters.entity == GNUTLS_SERVER)
00105 {
00106 cred
00107 = (MHD_gtls_cert_credentials_t) MHD_gtls_get_cred (session->key,
00108 MHD_GNUTLS_CRD_CERTIFICATE,
00109 NULL);
00110
00111 if (cred == NULL)
00112 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
00113
00114 if (cred->server_get_cert_callback == NULL)
00115 {
00116 for (i = 0; i < cred->ncerts; i++)
00117 {
00118 if (cred->cert_list[i][0].cert_type == cert_type)
00119 {
00120 cert_found = 1;
00121 break;
00122 }
00123 }
00124
00125 if (cert_found == 0)
00126
00127
00128 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
00129 }
00130 }
00131
00132 if (session->internals.priorities.cert_type.num_algorithms == 0 && cert_type
00133 == DEFAULT_CERT_TYPE)
00134 return 0;
00135
00136 for (i = 0; i < session->internals.priorities.cert_type.num_algorithms; i++)
00137 {
00138 if (session->internals.priorities.cert_type.priority[i] == cert_type)
00139 {
00140 return 0;
00141 }
00142 }
00143
00144 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
00145 }
00146
00147
00148
00149
00150 inline static void
00151 deinit_internal_params (MHD_gtls_session_t session)
00152 {
00153 if (session->internals.params.free_dh_params)
00154 MHD__gnutls_dh_params_deinit (session->internals.params.dh_params);
00155
00156 if (session->internals.params.free_rsa_params)
00157 MHD__gnutls_rsa_params_deinit (session->internals.params.rsa_params);
00158
00159 memset (&session->internals.params, 0, sizeof (session->internals.params));
00160 }
00161
00162
00163
00164
00165
00166 void
00167 MHD_gtls_handshake_internal_state_clear (MHD_gtls_session_t session)
00168 {
00169 session->internals.extensions_sent_size = 0;
00170
00171
00172 session->internals.proposed_record_size = DEFAULT_MAX_RECORD_SIZE;
00173 session->internals.adv_version_major = 0;
00174 session->internals.adv_version_minor = 0;
00175 session->internals.v2_hello = 0;
00176 memset (&session->internals.handshake_header_buffer, 0,
00177 sizeof (MHD_gtls_handshake_header_buffer_st));
00178 session->internals.adv_version_minor = 0;
00179 session->internals.adv_version_minor = 0;
00180 session->internals.direction = 0;
00181
00182
00183
00184
00185 session->internals.last_handshake_in = -1;
00186 session->internals.last_handshake_out = -1;
00187
00188 session->internals.resumable = RESUME_TRUE;
00189 MHD__gnutls_free_datum (&session->internals.recv_buffer);
00190
00191 deinit_internal_params (session);
00192
00193 }
00194
00195 #define MIN_DH_BITS 727
00196
00211
00212 int
00213 MHD__gnutls_init (MHD_gtls_session_t * session,
00214 MHD_gnutls_connection_end_t con_end)
00215 {
00216 *session = MHD_gnutls_calloc (1, sizeof (struct MHD_gtls_session_int));
00217 if (*session == NULL)
00218 return GNUTLS_E_MEMORY_ERROR;
00219
00220 (*session)->security_parameters.entity = con_end;
00221
00222
00223 (*session)->security_parameters.cert_type = DEFAULT_CERT_TYPE;
00224
00225
00226 (*session)->security_parameters.read_bulk_cipher_algorithm =
00227 (*session)->security_parameters.write_bulk_cipher_algorithm =
00228 MHD_GNUTLS_CIPHER_NULL;
00229
00230 (*session)->security_parameters.read_mac_algorithm =
00231 (*session)->security_parameters.write_mac_algorithm = MHD_GNUTLS_MAC_NULL;
00232
00233
00234 MHD_gtls_buffer_init (&(*session)->internals.application_data_buffer);
00235 MHD_gtls_buffer_init (&(*session)->internals.handshake_data_buffer);
00236 MHD_gtls_buffer_init (&(*session)->internals.handshake_hash_buffer);
00237 MHD_gtls_buffer_init (&(*session)->internals.ia_data_buffer);
00238
00239 MHD_gtls_buffer_init (&(*session)->internals.record_send_buffer);
00240 MHD_gtls_buffer_init (&(*session)->internals.record_recv_buffer);
00241
00242 MHD_gtls_buffer_init (&(*session)->internals.handshake_send_buffer);
00243 MHD_gtls_buffer_init (&(*session)->internals.handshake_recv_buffer);
00244
00245 (*session)->key = MHD_gnutls_calloc (1, sizeof (struct MHD_gtls_key));
00246 if ((*session)->key == NULL)
00247 {
00248 cleanup_session:MHD_gnutls_free (*session);
00249 *session = NULL;
00250 return GNUTLS_E_MEMORY_ERROR;
00251 }
00252
00253 (*session)->internals.expire_time = DEFAULT_EXPIRE_TIME;
00254
00255 MHD__gnutls_dh_set_prime_bits ((*session), MIN_DH_BITS);
00256
00257 MHD__gnutls_transport_set_lowat ((*session), DEFAULT_LOWAT);
00258
00259 MHD__gnutls_handshake_set_max_packet_length ((*session),
00260 MAX_HANDSHAKE_PACKET_SIZE);
00261
00262
00263
00264
00265
00266 (*session)->internals.record_recv_buffer.data
00267 = MHD_gnutls_malloc (INITIAL_RECV_BUFFER_SIZE);
00268 if ((*session)->internals.record_recv_buffer.data == NULL)
00269 {
00270 MHD_gnutls_free ((*session)->key);
00271 goto cleanup_session;
00272 }
00273
00274
00275 (*session)->internals.transport_recv_ptr = (MHD_gnutls_transport_ptr_t) - 1;
00276 (*session)->internals.transport_send_ptr = (MHD_gnutls_transport_ptr_t) - 1;
00277
00278
00279
00280 (*session)->security_parameters.max_record_recv_size
00281 = DEFAULT_MAX_RECORD_SIZE;
00282 (*session)->security_parameters.max_record_send_size
00283 = DEFAULT_MAX_RECORD_SIZE;
00284
00285
00286
00287
00288
00289 MHD_gtls_handshake_internal_state_clear (*session);
00290
00291 return 0;
00292 }
00293
00294
00303 void
00304 MHD__gnutls_deinit (MHD_gtls_session_t session)
00305 {
00306
00307 if (session == NULL)
00308 return;
00309
00310
00311 MHD_gtls_free_auth_info (session);
00312
00313 MHD_gtls_handshake_internal_state_clear (session);
00314 MHD__gnutls_handshake_io_buffer_clear (session);
00315
00316 MHD__gnutls_free_datum (&session->connection_state.read_mac_secret);
00317 MHD__gnutls_free_datum (&session->connection_state.write_mac_secret);
00318
00319 MHD_gtls_buffer_clear (&session->internals.ia_data_buffer);
00320 MHD_gtls_buffer_clear (&session->internals.handshake_hash_buffer);
00321 MHD_gtls_buffer_clear (&session->internals.handshake_data_buffer);
00322 MHD_gtls_buffer_clear (&session->internals.application_data_buffer);
00323 MHD_gtls_buffer_clear (&session->internals.record_recv_buffer);
00324 MHD_gtls_buffer_clear (&session->internals.record_send_buffer);
00325
00326 MHD__gnutls_credentials_clear (session);
00327 MHD_gtls_selected_certs_deinit (session);
00328
00329 if (session->connection_state.read_cipher_state != NULL)
00330 MHD_gnutls_cipher_deinit (session->connection_state.read_cipher_state);
00331 if (session->connection_state.write_cipher_state != NULL)
00332 MHD_gnutls_cipher_deinit (session->connection_state.write_cipher_state);
00333
00334 MHD__gnutls_free_datum (&session->cipher_specs.server_write_mac_secret);
00335 MHD__gnutls_free_datum (&session->cipher_specs.client_write_mac_secret);
00336 MHD__gnutls_free_datum (&session->cipher_specs.server_write_IV);
00337 MHD__gnutls_free_datum (&session->cipher_specs.client_write_IV);
00338 MHD__gnutls_free_datum (&session->cipher_specs.server_write_key);
00339 MHD__gnutls_free_datum (&session->cipher_specs.client_write_key);
00340
00341 if (session->key != NULL)
00342 {
00343 MHD_gtls_mpi_release (&session->key->KEY);
00344 MHD_gtls_mpi_release (&session->key->client_Y);
00345 MHD_gtls_mpi_release (&session->key->client_p);
00346 MHD_gtls_mpi_release (&session->key->client_g);
00347
00348 MHD_gtls_mpi_release (&session->key->u);
00349 MHD_gtls_mpi_release (&session->key->a);
00350 MHD_gtls_mpi_release (&session->key->x);
00351 MHD_gtls_mpi_release (&session->key->A);
00352 MHD_gtls_mpi_release (&session->key->B);
00353 MHD_gtls_mpi_release (&session->key->b);
00354
00355
00356 MHD_gtls_mpi_release (&session->key->rsa[0]);
00357 MHD_gtls_mpi_release (&session->key->rsa[1]);
00358
00359 MHD_gtls_mpi_release (&session->key->dh_secret);
00360 MHD_gnutls_free (session->key);
00361
00362 session->key = NULL;
00363 }
00364
00365 memset (session, 0, sizeof (struct MHD_gtls_session_int));
00366 MHD_gnutls_free (session);
00367 }
00368
00369
00370
00371 int
00372 MHD_gtls_dh_get_allowed_prime_bits (MHD_gtls_session_t session)
00373 {
00374 return session->internals.dh_prime_bits;
00375 }
00376
00377 int
00378 MHD_gtls_dh_set_peer_public (MHD_gtls_session_t session, mpi_t public)
00379 {
00380 MHD_gtls_dh_info_st *dh;
00381 int ret;
00382
00383 switch (MHD_gtls_auth_get_type (session))
00384 {
00385 case MHD_GNUTLS_CRD_CERTIFICATE:
00386 {
00387 cert_auth_info_t info;
00388
00389 info = MHD_gtls_get_auth_info (session);
00390 if (info == NULL)
00391 return GNUTLS_E_INTERNAL_ERROR;
00392
00393 dh = &info->dh;
00394 break;
00395 }
00396 default:
00397 MHD_gnutls_assert ();
00398 return GNUTLS_E_INTERNAL_ERROR;
00399 }
00400
00401 ret = MHD_gtls_mpi_dprint_lz (&dh->public_key, public);
00402 if (ret < 0)
00403 {
00404 MHD_gnutls_assert ();
00405 return ret;
00406 }
00407
00408 return 0;
00409 }
00410
00411 int
00412 MHD_gtls_dh_set_secret_bits (MHD_gtls_session_t session, unsigned bits)
00413 {
00414 switch (MHD_gtls_auth_get_type (session))
00415 {
00416 case MHD_GNUTLS_CRD_CERTIFICATE:
00417 {
00418 cert_auth_info_t info;
00419
00420 info = MHD_gtls_get_auth_info (session);
00421 if (info == NULL)
00422 return GNUTLS_E_INTERNAL_ERROR;
00423
00424 info->dh.secret_bits = bits;
00425 break;
00426 default:
00427 MHD_gnutls_assert ();
00428 return GNUTLS_E_INTERNAL_ERROR;
00429 }
00430 }
00431
00432 return 0;
00433 }
00434
00435
00436
00437
00438 int
00439 MHD_gtls_rsa_export_set_pubkey (MHD_gtls_session_t session,
00440 mpi_t exponent, mpi_t modulus)
00441 {
00442 cert_auth_info_t info;
00443 int ret;
00444
00445 info = MHD_gtls_get_auth_info (session);
00446 if (info == NULL)
00447 return GNUTLS_E_INTERNAL_ERROR;
00448
00449 ret = MHD_gtls_mpi_dprint_lz (&info->rsa_export.modulus, modulus);
00450 if (ret < 0)
00451 {
00452 MHD_gnutls_assert ();
00453 return ret;
00454 }
00455
00456 ret = MHD_gtls_mpi_dprint_lz (&info->rsa_export.exponent, exponent);
00457 if (ret < 0)
00458 {
00459 MHD_gnutls_assert ();
00460 MHD__gnutls_free_datum (&info->rsa_export.modulus);
00461 return ret;
00462 }
00463
00464 return 0;
00465 }
00466
00467
00468
00469 int
00470 MHD_gtls_dh_set_group (MHD_gtls_session_t session, mpi_t gen, mpi_t prime)
00471 {
00472 MHD_gtls_dh_info_st *dh;
00473 int ret;
00474
00475 switch (MHD_gtls_auth_get_type (session))
00476 {
00477 case MHD_GNUTLS_CRD_CERTIFICATE:
00478 {
00479 cert_auth_info_t info;
00480
00481 info = MHD_gtls_get_auth_info (session);
00482 if (info == NULL)
00483 return GNUTLS_E_INTERNAL_ERROR;
00484
00485 dh = &info->dh;
00486 break;
00487 }
00488 default:
00489 MHD_gnutls_assert ();
00490 return GNUTLS_E_INTERNAL_ERROR;
00491 }
00492
00493
00494
00495 ret = MHD_gtls_mpi_dprint_lz (&dh->prime, prime);
00496 if (ret < 0)
00497 {
00498 MHD_gnutls_assert ();
00499 return ret;
00500 }
00501
00502
00503
00504 ret = MHD_gtls_mpi_dprint_lz (&dh->generator, gen);
00505 if (ret < 0)
00506 {
00507 MHD_gnutls_assert ();
00508 MHD__gnutls_free_datum (&dh->prime);
00509 return ret;
00510 }
00511
00512 return 0;
00513 }
00514
00529 void
00530 MHD__gnutls_certificate_send_x509_rdn_sequence (MHD_gtls_session_t session,
00531 int status)
00532 {
00533 session->internals.ignore_rdn_sequence = status;
00534 }
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 void
00548 MHD__gnutls_record_set_default_version (MHD_gtls_session_t session,
00549 unsigned char major,
00550 unsigned char minor)
00551 {
00552 session->internals.default_record_version[0] = major;
00553 session->internals.default_record_version[1] = minor;
00554 }
00555
00556 inline static int
00557 MHD__gnutls_cal_PRF_A (enum MHD_GNUTLS_HashAlgorithm algorithm,
00558 const void *secret,
00559 int secret_size,
00560 const void *seed, int seed_size, void *result)
00561 {
00562 mac_hd_t td1;
00563
00564 td1 = MHD_gtls_MHD_hmac_init (algorithm, secret, secret_size);
00565 if (td1 == GNUTLS_MAC_FAILED)
00566 {
00567 MHD_gnutls_assert ();
00568 return GNUTLS_E_INTERNAL_ERROR;
00569 }
00570
00571 MHD_gnutls_hash (td1, seed, seed_size);
00572 MHD_gnutls_MHD_hmac_deinit (td1, result);
00573
00574 return 0;
00575 }
00576
00577 #define MAX_SEED_SIZE 200
00578
00579
00580
00581
00582 static int
00583 MHD__gnutls_P_hash (enum MHD_GNUTLS_HashAlgorithm algorithm,
00584 const opaque * secret,
00585 int secret_size,
00586 const opaque * seed,
00587 int seed_size, int total_bytes, opaque * ret)
00588 {
00589
00590 mac_hd_t td2;
00591 int i, times, how, blocksize, A_size;
00592 opaque final[20], Atmp[MAX_SEED_SIZE];
00593 int output_bytes, result;
00594
00595 if (seed_size > MAX_SEED_SIZE || total_bytes <= 0)
00596 {
00597 MHD_gnutls_assert ();
00598 return GNUTLS_E_INTERNAL_ERROR;
00599 }
00600
00601 blocksize = MHD_gnutls_hash_get_algo_len (algorithm);
00602
00603 output_bytes = 0;
00604 do
00605 {
00606 output_bytes += blocksize;
00607 }
00608 while (output_bytes < total_bytes);
00609
00610
00611
00612 memcpy (Atmp, seed, seed_size);
00613 A_size = seed_size;
00614
00615 times = output_bytes / blocksize;
00616
00617 for (i = 0; i < times; i++)
00618 {
00619 td2 = MHD_gtls_MHD_hmac_init (algorithm, secret, secret_size);
00620 if (td2 == GNUTLS_MAC_FAILED)
00621 {
00622 MHD_gnutls_assert ();
00623 return GNUTLS_E_INTERNAL_ERROR;
00624 }
00625
00626
00627 if ((result =
00628 MHD__gnutls_cal_PRF_A (algorithm, secret, secret_size, Atmp,
00629 A_size, Atmp)) < 0)
00630 {
00631 MHD_gnutls_assert ();
00632 MHD_gnutls_MHD_hmac_deinit (td2, final);
00633 return result;
00634 }
00635
00636 A_size = blocksize;
00637
00638 MHD_gnutls_hash (td2, Atmp, A_size);
00639 MHD_gnutls_hash (td2, seed, seed_size);
00640 MHD_gnutls_MHD_hmac_deinit (td2, final);
00641
00642 if ((1 + i) * blocksize < total_bytes)
00643 {
00644 how = blocksize;
00645 }
00646 else
00647 {
00648 how = total_bytes - (i) * blocksize;
00649 }
00650
00651 if (how > 0)
00652 {
00653 memcpy (&ret[i * blocksize], final, how);
00654 }
00655 }
00656
00657 return 0;
00658 }
00659
00660
00661
00662 inline static void
00663 MHD__gnutls_xor (opaque * o1, opaque * o2, int length)
00664 {
00665 int i;
00666 for (i = 0; i < length; i++)
00667 {
00668 o1[i] ^= o2[i];
00669 }
00670 }
00671
00672 #define MAX_PRF_BYTES 200
00673
00674
00675
00676
00677
00678 int
00679 MHD_gtls_PRF (MHD_gtls_session_t session,
00680 const opaque * secret,
00681 int secret_size,
00682 const char *label,
00683 int label_size,
00684 const opaque * seed, int seed_size, int total_bytes, void *ret)
00685 {
00686 int l_s, s_seed_size;
00687 const opaque *s1, *s2;
00688 opaque s_seed[MAX_SEED_SIZE];
00689 opaque o1[MAX_PRF_BYTES], o2[MAX_PRF_BYTES];
00690 int result;
00691 enum MHD_GNUTLS_Protocol ver = MHD__gnutls_protocol_get_version (session);
00692
00693 if (total_bytes > MAX_PRF_BYTES)
00694 {
00695 MHD_gnutls_assert ();
00696 return GNUTLS_E_INTERNAL_ERROR;
00697 }
00698
00699 s_seed_size = seed_size + label_size;
00700
00701 if (s_seed_size > MAX_SEED_SIZE)
00702 {
00703 MHD_gnutls_assert ();
00704 return GNUTLS_E_INTERNAL_ERROR;
00705 }
00706
00707 memcpy (s_seed, label, label_size);
00708 memcpy (&s_seed[label_size], seed, seed_size);
00709
00710 if (ver >= MHD_GNUTLS_PROTOCOL_TLS1_2)
00711 {
00712 result =
00713 MHD__gnutls_P_hash (MHD_GNUTLS_MAC_SHA1, secret, secret_size, s_seed,
00714 s_seed_size, total_bytes, ret);
00715 if (result < 0)
00716 {
00717 MHD_gnutls_assert ();
00718 return result;
00719 }
00720 }
00721 else
00722 {
00723 l_s = secret_size / 2;
00724
00725 s1 = &secret[0];
00726 s2 = &secret[l_s];
00727
00728 if (secret_size % 2 != 0)
00729 {
00730 l_s++;
00731 }
00732
00733 result =
00734 MHD__gnutls_P_hash (MHD_GNUTLS_MAC_MD5, s1, l_s, s_seed, s_seed_size,
00735 total_bytes, o1);
00736 if (result < 0)
00737 {
00738 MHD_gnutls_assert ();
00739 return result;
00740 }
00741
00742 result =
00743 MHD__gnutls_P_hash (MHD_GNUTLS_MAC_SHA1, s2, l_s, s_seed, s_seed_size,
00744 total_bytes, o2);
00745 if (result < 0)
00746 {
00747 MHD_gnutls_assert ();
00748 return result;
00749 }
00750
00751 MHD__gnutls_xor (o1, o2, total_bytes);
00752
00753 memcpy (ret, o1, total_bytes);
00754 }
00755
00756 return 0;
00757
00758 }
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 int
00769 MHD_gtls_session_is_export (MHD_gtls_session_t session)
00770 {
00771 enum MHD_GNUTLS_CipherAlgorithm cipher;
00772
00773 cipher =
00774 MHD_gtls_cipher_suite_get_cipher_algo (&session->security_parameters.
00775 current_cipher_suite);
00776
00777 if (MHD_gtls_cipher_get_export_flag (cipher) != 0)
00778 return 1;
00779
00780 return 0;
00781 }
00782
00800 int
00801 MHD__gnutls_record_get_direction (MHD_gtls_session_t session)
00802 {
00803 return session->internals.direction;
00804 }