gnutls_state.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
00003  *
00004  * Author: Nikos Mavrogiannopoulos
00005  *
00006  * This file is part of GNUTLS.
00007  *
00008  * The GNUTLS library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation; either version 2.1 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00021  * USA
00022  *
00023  */
00024 
00025 /* Functions to manipulate the session (MHD_gnutls_int.h), and some other stuff
00026  * are included here. The file's name is traditionally MHD_gnutls_state even if the
00027  * state has been renamed to session.
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 /* Check if the given certificate type is supported.
00092  * This means that it is enabled by the priority functions,
00093  * and a matching certificate exists.
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             /* no certificate is of that type.
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;             /* ok */
00141         }
00142     }
00143 
00144   return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
00145 }
00146 
00147 /* this function deinitializes all the internal parameters stored
00148  * in a session struct.
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 /* This function will clear all the variables in internals
00163  * structure within the session, which depend on the current handshake.
00164  * This is used to allow further handshakes.
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   /* by default no selected certificate */
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   /* use out of band data for the last
00183    * handshake messages received.
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 /* TODO rm redundent pointer ref */
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   /* the default certificate type for TLS */
00223   (*session)->security_parameters.cert_type = DEFAULT_CERT_TYPE;
00224 
00225   /* Set the defaults for initial handshake */
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   /* Initialize buffers */
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;      /* one hour default */
00254 
00255   MHD__gnutls_dh_set_prime_bits ((*session), MIN_DH_BITS);
00256 
00257   MHD__gnutls_transport_set_lowat ((*session), DEFAULT_LOWAT);  /* the default for tcp */
00258 
00259   MHD__gnutls_handshake_set_max_packet_length ((*session),
00260                                                MAX_HANDSHAKE_PACKET_SIZE);
00261 
00262   /* Allocate a minimum size for recv_data
00263    * This is allocated in order to avoid small messages, making
00264    * the receive procedure slow.
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   /* set the socket pointers to -1; */
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   /* set the default maximum record size for TLS
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   /* everything else not initialized here is initialized
00286    * as NULL or 0. This is why calloc is used.
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   /* remove auth info firstly */
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       /* RSA */
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 /* Returns the minimum prime bits that are acceptable.
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 /* This function will set in the auth info structure the
00436  * RSA exponent and the modulus.
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 /* Sets the prime and the generator in the auth info structure.
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   /* prime
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   /* generator
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  * MHD__gnutls_record_set_default_version - Used to set the default version for the first record packet
00538  * @session: is a #MHD_gtls_session_t structure.
00539  * @major: is a tls major version
00540  * @minor: is a tls minor version
00541  *
00542  * This function sets the default version that we will use in the first
00543  * record packet (client hello). This function is only useful to people
00544  * that know TLS internals and want to debug other implementations.
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 /* Produces "total_bytes" bytes using the hash algorithm specified.
00580  * (used in the PRF function)
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   /* calculate A(0) */
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       /* here we calculate A(i+1) */
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 /* Xor's two buffers and puts the output in the first one.
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 /* The PRF function expands a given secret
00675  * needed by the TLS specification. ret must have a least total_bytes
00676  * available.
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   /* label+seed = s_seed */
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;                     /* ok */
00757 
00758 }
00759 
00760 
00761 /*-
00762  * MHD_gtls_session_is_export - Used to check whether this session is of export grade
00763  * @session: is a #MHD_gtls_session_t structure.
00764  *
00765  * This function will return non zero if this session is of export grade.
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 }

Generated on Sun Jul 26 17:20:56 2009 for GNU libmicrohttpd by  doxygen 1.5.9