Commit message: None
CVE: CVE-2008-1950
CWE: CWE-189
Vulnerability description: Integer signedness error in the _gnutls_ciphertext2compressed function in lib/gnutls_cipher.c in libgnutls in GnuTLS before 2.2.4 allows remote attackers to cause a denial of service (buffer over-read and crash) via a certain integer value in the Random field in an encrypted Client Hello message within a TLS record with an invalid Record Length, which leads to an invalid cipher padding length, aka GNUTLS-SA-2008-1-3.

Project: savannah
File: gnutls_cipher.c

_gnutls_compressed2ciphertext (gnutls_session_t session,
			       opaque * cipher_data, int cipher_size,
			       gnutls_datum_t compressed,
			       content_type_t _type, int random_pad)
{
  uint8_t MAC[MAX_HASH_SIZE];
  uint16_t c_length;
  uint8_t pad;
  int length, ret;
  digest_hd_st td;
  uint8_t type = _type;
  uint8_t major, minor;
  int hash_size =
    _gnutls_hash_get_algo_len (session->security_parameters.
			       write_mac_algorithm);
  gnutls_protocol_t ver;
  int blocksize =
    _gnutls_cipher_get_block_size (session->security_parameters.
				   write_bulk_cipher_algorithm);
  cipher_type_t block_algo =
    _gnutls_cipher_is_block (session->security_parameters.
			     write_bulk_cipher_algorithm);
  opaque *data_ptr;


  ver = gnutls_protocol_get_version (session);
  minor = _gnutls_version_get_minor (ver);
  major = _gnutls_version_get_major (ver);


  /* Initialize MAC */
  ret = mac_init (&td, session->security_parameters.write_mac_algorithm,
		 session->connection_state.write_mac_secret.data,
		 session->connection_state.write_mac_secret.size, ver);

  if (ret < 0 && session->security_parameters.write_mac_algorithm != GNUTLS_MAC_NULL)
    {
      gnutls_assert ();
      return ret;
    }

  c_length = _gnutls_conv_uint16 (compressed.size);

  if (session->security_parameters.write_mac_algorithm != GNUTLS_MAC_NULL)
    {				/* actually when the algorithm in not the NULL one */
      _gnutls_hmac (&td,
		    UINT64DATA (session->connection_state.
				write_sequence_number), 8);

      _gnutls_hmac (&td, &type, 1);
      if (ver >= GNUTLS_TLS1)
	{			/* TLS 1.0 or higher */
	  _gnutls_hmac (&td, &major, 1);
	  _gnutls_hmac (&td, &minor, 1);
	}
      _gnutls_hmac (&td, &c_length, 2);
      _gnutls_hmac (&td, compressed.data, compressed.size);
      mac_deinit (&td, MAC, ver);
    }


  /* Calculate the encrypted length (padding etc.)
   */
  length =
    calc_enc_length (session, compressed.size, hash_size, &pad,
		     random_pad, block_algo, blocksize);
  if (length < 0)
    {
      gnutls_assert ();
      return length;
    }

  /* copy the encrypted data to cipher_data.
   */
  if (cipher_size < length)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  data_ptr = cipher_data;
  if (block_algo == CIPHER_BLOCK &&
      session->security_parameters.version >= GNUTLS_TLS1_1)
    {
      /* copy the random IV.
       */
      ret = _gnutls_rnd (RND_NONCE, data_ptr, blocksize);
      if (ret < 0)
	{
	  gnutls_assert ();
	  return ret;
	}

      data_ptr += blocksize;
    }

  memcpy (data_ptr, compressed.data, compressed.size);
  data_ptr += compressed.size;

  if (hash_size > 0)
    {
      memcpy (data_ptr, MAC, hash_size);
      data_ptr += hash_size;
    }
  if (block_algo == CIPHER_BLOCK && pad > 0)
    {
      memset (data_ptr, pad - 1, pad);
    }


  /* Actual encryption (inplace).
   */
  ret = _gnutls_cipher_encrypt (&session->connection_state.
				write_cipher_state, cipher_data, length);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return length;
}

Project: savannah
File: gnutls_cipher.c

_gnutls_decrypt (gnutls_session_t session, opaque * ciphertext,
		 size_t ciphertext_size, uint8_t * data,
		 size_t max_data_size, content_type_t type)
{
  gnutls_datum_t gtxt;
  gnutls_datum_t gcipher;
  int ret;

  if (ciphertext_size == 0)
    return 0;

  gcipher.size = ciphertext_size;
  gcipher.data = ciphertext;

  ret =
    _gnutls_ciphertext2compressed (session, data, max_data_size,
				   gcipher, type);
  if (ret < 0)
    {
      return ret;
    }

  if (ret == 0 || is_read_comp_null (session) == 0)
    {
      /* ret == ret */

    }
  else
    {
      gnutls_datum_t gcomp;

      /* compression has this malloc overhead.
       */

      gcomp.data = data;
      gcomp.size = ret;
      ret = _gnutls_m_compressed2plaintext (session, &gtxt, &gcomp);
      if (ret < 0)
	{
	  return ret;
	}

      if (gtxt.size > MAX_RECORD_RECV_SIZE)
	{
	  gnutls_assert ();
	  _gnutls_free_datum (&gtxt);
	  /* This shouldn't have happen and
	   * is a TLS fatal error.
	   */
	  return GNUTLS_E_DECOMPRESSION_FAILED;
	}

      /* This check is not really needed */
      if (max_data_size < MAX_RECORD_RECV_SIZE) 
        {
          gnutls_assert();
          _gnutls_free_datum (&gtxt);
          return GNUTLS_E_INTERNAL_ERROR;
        }

      memcpy (data, gtxt.data, gtxt.size);
      ret = gtxt.size;

      _gnutls_free_datum (&gtxt);
    }

  return ret;
}

Project: savannah
File: gnutls_cipher.c

_gnutls_encrypt (gnutls_session_t session, const opaque * headers,
		 size_t headers_size, const opaque * data,
		 size_t data_size, opaque * ciphertext,
		 size_t ciphertext_size, content_type_t type, int random_pad)
{
  gnutls_datum_t plain;
  gnutls_datum_t comp;
  int ret;
  int free_comp = 1;

  plain.data = (opaque *) data;
  plain.size = data_size;

  if (plain.size == 0 || is_write_comp_null (session) == 0)
    {
      comp = plain;
      free_comp = 0;
    }
  else
    {
      /* Here comp is allocated and must be 
       * freed.
       */
      ret = _gnutls_m_plaintext2compressed (session, &comp, &plain);
      if (ret < 0)
	{
	  gnutls_assert ();
	  return ret;
	}
    }

  ret = _gnutls_compressed2ciphertext (session, &ciphertext[headers_size],
				       ciphertext_size - headers_size,
				       comp, type, random_pad);

  if (free_comp)
    _gnutls_free_datum (&comp);

  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }


  /* copy the headers */
  memcpy (ciphertext, headers, headers_size);
  _gnutls_write_uint16 (ret, &ciphertext[3]);

  return ret + headers_size;
}

Project: savannah
File: gnutls_cipher.c

calc_enc_length (gnutls_session_t session, int data_size,
		 int hash_size, uint8_t * pad, int random_pad,
		 cipher_type_t block_algo, uint16_t blocksize)
{
  uint8_t rnd;
  int length, ret;

  *pad = 0;

  switch (block_algo)
    {
    case CIPHER_STREAM:
      length = data_size + hash_size;

      break;
    case CIPHER_BLOCK:
      ret =_gnutls_rnd (RND_NONCE, &rnd, 1);
      if ( ret < 0)
	{
	  gnutls_assert ();
	  return ret;
	}

      /* make rnd a multiple of blocksize */
      if (session->security_parameters.version == GNUTLS_SSL3 ||
	  random_pad == 0)
	{
	  rnd = 0;
	}
      else
	{
	  rnd = (rnd / blocksize) * blocksize;
	  /* added to avoid the case of pad calculated 0
	   * seen below for pad calculation.
	   */
	  if (rnd > blocksize)
	    rnd -= blocksize;
	}

      length = data_size + hash_size;

      *pad = (uint8_t) (blocksize - (length % blocksize)) + rnd;

      length += *pad;
      if (session->security_parameters.version >= GNUTLS_TLS1_1)
	length += blocksize;	/* for the IV */

      break;
    default:
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  return length;
}

Project: savannah
File: gnutls_cipher.c

is_read_comp_null (gnutls_session_t session)
{
  if (session->security_parameters.read_compression_algorithm ==
      GNUTLS_COMP_NULL)
    return 0;

  return 1;
}

Project: savannah
File: gnutls_cipher.c

is_write_comp_null (gnutls_session_t session)
{
  if (session->security_parameters.write_compression_algorithm ==
      GNUTLS_COMP_NULL)
    return 0;

  return 1;
}

Project: savannah
File: gnutls_cipher.c

mac_deinit (digest_hd_st *td, opaque * res, int ver)
{
  if (ver == GNUTLS_SSL3)
    {				/* SSL 3.0 */
      _gnutls_mac_deinit_ssl3 (td, res);
    }
  else
    {
      _gnutls_hmac_deinit (td, res);
    }
}

Project: savannah
File: gnutls_cipher.c

mac_init (digest_hd_st* td, gnutls_mac_algorithm_t mac, opaque * secret, int secret_size,
	  int ver)
{
int ret =  0;

  if (mac == GNUTLS_MAC_NULL)
    {
      gnutls_assert();
      return GNUTLS_E_HASH_FAILED;
    }

  if (ver == GNUTLS_SSL3)
    {				/* SSL 3.0 */
      ret = _gnutls_mac_init_ssl3 (td, mac, secret, secret_size);
    }
  else
    {				/* TLS 1.x */
      ret = _gnutls_hmac_init (td, mac, secret, secret_size);
    }

  return ret;
}

Project: savannah
File: gnutls_handshake.c

_gnutls_finished (gnutls_session_t session, int type, void *ret)
{
  const int siz = TLS_MSG_LEN;
  opaque concat[36];
  size_t len;
  const char *mesg;
  digest_hd_st td_md5;
  digest_hd_st td_sha;
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
  int rc;

  if (ver < GNUTLS_TLS1_2)
    {
      rc = _gnutls_hash_copy (&td_md5, &session->internals.handshake_mac_handle_md5);
      if (rc < 0)
	{
	  gnutls_assert ();
	  return rc;
	}
    }

  rc = _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha);
  if (rc < 0)
    {
      gnutls_assert ();
      _gnutls_hash_deinit (&td_md5, NULL);
      return rc;
    }

  if (ver < GNUTLS_TLS1_2)
    {
      _gnutls_hash_deinit (&td_md5, concat);
      _gnutls_hash_deinit (&td_sha, &concat[16]);
      len = 20 + 16;
    }
  else
    {
      _gnutls_hash_deinit (&td_sha, concat);
      len = 20;
    }

  if (type == GNUTLS_SERVER)
    {
      mesg = SERVER_MSG;
    }
  else
    {
      mesg = CLIENT_MSG;
    }

  return _gnutls_PRF (session, session->security_parameters.master_secret,
		      TLS_MASTER_SIZE, mesg, siz, concat, len, 12, ret);
}

Project: savannah
File: gnutls_handshake.c

_gnutls_handshake_hash_add_sent (gnutls_session_t session,
				 gnutls_handshake_description_t type,
				 opaque * dataptr, uint32_t datalen)
{
  int ret;

  if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
    {
      _gnutls_hash (&session->internals.handshake_mac_handle_sha, dataptr,
		    datalen);
      _gnutls_hash (&session->internals.handshake_mac_handle_md5, dataptr,
		    datalen);
    }

  return 0;
}

Project: savannah
File: gnutls_handshake.c

_gnutls_handshake_hash_buffers_clear (gnutls_session_t session)
{
  _gnutls_hash_deinit (&session->internals.handshake_mac_handle_md5, NULL);
  _gnutls_hash_deinit (&session->internals.handshake_mac_handle_sha, NULL);
  _gnutls_handshake_buffer_clear (session);
}

Project: savannah
File: gnutls_handshake.c

_gnutls_handshake_hash_pending (gnutls_session_t session)
{
  size_t siz;
  int ret;
  opaque *data;

  if (session->internals.handshake_mac_handle_init == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  /* We check if there are pending data to hash.
   */
  if ((ret = _gnutls_handshake_buffer_get_ptr (session, &data, &siz)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  if (siz > 0)
    {
      _gnutls_hash (&session->internals.handshake_mac_handle_sha, data, siz);
      _gnutls_hash (&session->internals.handshake_mac_handle_md5, data, siz);
    }

  _gnutls_handshake_buffer_empty (session);

  return 0;
}

Project: savannah
File: gnutls_handshake.c

int _gnutls_negotiate_version( gnutls_session_t session, gnutls_protocol_t adv_version)
{
int ret;

  /* if we do not support that version  */
  if (_gnutls_version_is_supported (session, adv_version) == 0)
    {
      /* If he requested something we do not support
       * then we send him the highest we support.
       */
      ret = _gnutls_version_max (session);
      if (ret == GNUTLS_VERSION_UNKNOWN)
	{
	  /* this check is not really needed.
	   */
	  gnutls_assert ();
	  return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
	}
    }
  else
    {
      ret = adv_version;
    }

  _gnutls_set_current_version (session, ret);
    
  return ret;
}

Project: savannah
File: gnutls_handshake.c

_gnutls_read_client_hello (gnutls_session_t session, opaque * data,
			   int datalen)
{
  uint8_t session_id_len;
  int pos = 0, ret;
  uint16_t suite_size, comp_size;
  gnutls_protocol_t adv_version;
  int neg_version;
  int len = datalen;
  opaque rnd[TLS_RANDOM_SIZE], *suite_ptr, *comp_ptr;

  if (session->internals.v2_hello != 0)
    {				/* version 2.0 */
      return _gnutls_read_client_hello_v2 (session, data, datalen);
    }
  DECR_LEN (len, 2);

  _gnutls_handshake_log ("HSK[%x]: Client's version: %d.%d\n", session,
			 data[pos], data[pos + 1]);

  adv_version = _gnutls_version_get (data[pos], data[pos + 1]);
  set_adv_version (session, data[pos], data[pos + 1]);
  pos += 2;

  neg_version = _gnutls_negotiate_version( session, adv_version);
  if (neg_version < 0)
    {
      gnutls_assert();
      return neg_version;
    }

  /* Read client random value.
   */
  DECR_LEN (len, TLS_RANDOM_SIZE);
  _gnutls_set_client_random (session, &data[pos]);
  pos += TLS_RANDOM_SIZE;

  _gnutls_tls_create_random (rnd);
  _gnutls_set_server_random (session, rnd);

  session->security_parameters.timestamp = time (NULL);

  DECR_LEN (len, 1);
  session_id_len = data[pos++];

  /* RESUME SESSION 
   */
  if (session_id_len > TLS_MAX_SESSION_ID_SIZE)
    {
      gnutls_assert ();
      return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
    }
  DECR_LEN (len, session_id_len);
  
  ret = _gnutls_server_restore_session (session, &data[pos], session_id_len);
  pos += session_id_len;

  if (ret == 0)
    {				/* resumed! */
      resume_copy_required_values (session);
      session->internals.resumed = RESUME_TRUE;
      return _gnutls_user_hello_func( session, adv_version);
    }
  else
    {
      _gnutls_generate_session_id (session->security_parameters.
				   session_id,
				   &session->security_parameters.
				   session_id_size);

      session->internals.resumed = RESUME_FALSE;
    }

  /* Remember ciphersuites for later
   */
  DECR_LEN (len, 2);
  suite_size = _gnutls_read_uint16 (&data[pos]);
  pos += 2;

  DECR_LEN (len, suite_size);
  suite_ptr = &data[pos];
  pos += suite_size;

  /* Point to the compression methods
   */
  DECR_LEN (len, 1);
  comp_size = data[pos++];		/* z is the number of compression methods */

  DECR_LEN (len, comp_size);
  comp_ptr = &data[pos];
  pos += comp_size;

  /* Parse the extensions (if any)
   */
  if (neg_version >= GNUTLS_TLS1)
    {
      ret = _gnutls_parse_extensions (session, EXTENSION_APPLICATION, &data[pos], len);	/* len is the rest of the parsed length */
      if (ret < 0)
	{
	  gnutls_assert ();
	  return ret;
	}
    }

  ret = _gnutls_user_hello_func( session, adv_version);
  if (ret < 0) 
    {
      gnutls_assert();
      return ret;
    }
  
  if (neg_version >= GNUTLS_TLS1)
    {
      ret = _gnutls_parse_extensions (session, EXTENSION_TLS, &data[pos], len);	/* len is the rest of the parsed length */
      if (ret < 0)
	{
	  gnutls_assert ();
	  return ret;
	}
    }

  /* select an appropriate cipher suite
   */
  ret = _gnutls_server_select_suite (session, suite_ptr, suite_size);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  /* select appropriate compression method */
  ret = _gnutls_server_select_comp_method (session, comp_ptr, comp_size);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return 0;
}

Project: savannah
File: gnutls_handshake.c

_gnutls_recv_finished (gnutls_session_t session)
{
  uint8_t data[36], *vrfy;
  int data_size;
  int ret;
  int vrfysize;

  ret =
    _gnutls_recv_handshake (session, &vrfy, &vrfysize,
			    GNUTLS_HANDSHAKE_FINISHED, MANDATORY_PACKET);
  if (ret < 0)
    {
      ERR ("recv finished int", ret);
      gnutls_assert ();
      return ret;
    }


  if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
    {
      data_size = 36;
    }
  else
    {
      data_size = 12;
    }

  if (vrfysize != data_size)
    {
      gnutls_assert ();
      gnutls_free (vrfy);
      return GNUTLS_E_ERROR_IN_FINISHED_PACKET;
    }

  if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
    {
      ret =
	_gnutls_ssl3_finished (session,
			       (session->security_parameters.
				entity + 1) % 2, data);
    }
  else
    {				/* TLS 1.0 */
      ret =
	_gnutls_finished (session,
			  (session->security_parameters.entity +
			   1) % 2, data);
    }

  if (ret < 0)
    {
      gnutls_assert ();
      gnutls_free (vrfy);
      return ret;
    }

  if (memcmp (vrfy, data, data_size) != 0)
    {
      gnutls_assert ();
      ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
    }
  gnutls_free (vrfy);

  return ret;
}

Project: savannah
File: gnutls_handshake.c

_gnutls_send_empty_handshake (gnutls_session_t session,
			      gnutls_handshake_description_t type, int again)
{
  opaque data = 0;
  opaque *ptr;

  if (again == 0)
    ptr = &data;
  else
    ptr = NULL;

  return _gnutls_send_handshake (session, ptr, 0, type);
}

Project: savannah
File: gnutls_handshake.c

_gnutls_send_finished (gnutls_session_t session, int again)
{
  uint8_t data[36];
  int ret;
  int data_size = 0;


  if (again == 0)
    {

      /* This is needed in order to hash all the required
       * messages.
       */
      if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
	{
	  gnutls_assert ();
	  return ret;
	}

      if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
	{
	  ret =
	    _gnutls_ssl3_finished (session,
				   session->security_parameters.entity, data);
	  data_size = 36;
	}
      else
	{			/* TLS 1.0 */
	  ret =
	    _gnutls_finished (session,
			      session->security_parameters.entity, data);
	  data_size = 12;
	}

      if (ret < 0)
	{
	  gnutls_assert ();
	  return ret;
	}

    }

  ret =
    _gnutls_send_handshake (session, data, data_size,
			    GNUTLS_HANDSHAKE_FINISHED);

  return ret;
}

Project: savannah
File: gnutls_handshake.c

_gnutls_send_handshake (gnutls_session_t session, void *i_data,
			uint32_t i_datasize,
			gnutls_handshake_description_t type)
{
  int ret;
  uint8_t *data;
  uint32_t datasize;
  int pos = 0;

  if (i_data == NULL && i_datasize == 0)
    {
      /* we are resuming a previously interrupted
       * send.
       */
      ret = _gnutls_handshake_io_write_flush (session);
      return ret;

    }

  if (i_data == NULL && i_datasize > 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  /* first run */
  datasize = i_datasize + HANDSHAKE_HEADER_SIZE;
  data = gnutls_malloc (datasize);
  if (data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  data[pos++] = (uint8_t) type;
  _gnutls_write_uint24 (i_datasize, &data[pos]);
  pos += 3;

  if (i_datasize > 0)
    memcpy (&data[pos], i_data, i_datasize);

  _gnutls_handshake_log ("HSK[%x]: %s was send [%ld bytes]\n",
			 session, _gnutls_handshake2str (type), datasize);


  /* Here we keep the handshake messages in order to hash them...
   */
  if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
    if ((ret =
	 _gnutls_handshake_hash_add_sent (session, type, data, datasize)) < 0)
      {
	gnutls_assert ();
	gnutls_free (data);
	return ret;
      }

  session->internals.last_handshake_out = type;

  ret =
    _gnutls_handshake_io_send_int (session, GNUTLS_HANDSHAKE, type,
				   data, datasize);

  gnutls_free (data);

  return ret;
}

Project: savannah
File: gnutls_handshake.c

_gnutls_server_find_pk_algos_in_ciphersuites (const opaque *
					      data, int datalen)
{
  int j;
  gnutls_pk_algorithm_t algo = GNUTLS_PK_NONE, prev_algo = 0;
  gnutls_kx_algorithm_t kx;
  cipher_suite_st cs;

  if (datalen % 2 != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
    }

  for (j = 0; j < datalen; j += 2)
    {
      memcpy (&cs.suite, &data[j], 2);
      kx = _gnutls_cipher_suite_get_kx_algo (&cs);

      if (_gnutls_map_kx_get_cred (kx, 1) == GNUTLS_CRD_CERTIFICATE)
	{
	  algo = _gnutls_map_pk_get_pk (kx);

	  if (algo != prev_algo && prev_algo != 0)
	    return GNUTLS_PK_ANY;
	  prev_algo = algo;
	}
    }

  return algo;
}

Project: savannah
File: gnutls_handshake.c

_gnutls_server_select_comp_method (gnutls_session_t session,
				   opaque * data, int datalen)
{
  int x, i, j;
  uint8_t *comps;

  x = _gnutls_supported_compression_methods (session, &comps);
  if (x < 0)
    {
      gnutls_assert ();
      return x;
    }

  memset (&session->internals.compression_method, 0,
	  sizeof (gnutls_compression_method_t));

  for (j = 0; j < datalen; j++)
    {
      for (i = 0; i < x; i++)
	{
	  if (comps[i] == data[j])
	    {
	      gnutls_compression_method_t method =
		_gnutls_compression_get_id (comps[i]);

	      session->internals.compression_method = method;
	      gnutls_free (comps);

	      _gnutls_handshake_log
		("HSK[%x]: Selected Compression Method: %s\n", session,
		 gnutls_compression_get_name (session->internals.
					      compression_method));


	      return 0;
	    }
	}
    }

  /* we were not able to find a compatible compression
   * algorithm
   */
  gnutls_free (comps);
  gnutls_assert ();
  return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;

}

Project: savannah
File: gnutls_handshake.c

_gnutls_set_server_random (gnutls_session_t session, uint8_t * rnd)
{
  memcpy (session->security_parameters.server_random, rnd, TLS_RANDOM_SIZE);
}

Project: savannah
File: gnutls_handshake.c

_gnutls_ssl3_finished (gnutls_session_t session, int type, opaque * ret)
{
  const int siz = SSL_MSG_LEN;
  digest_hd_st td_md5;
  digest_hd_st td_sha;
  const char *mesg;
  int rc;

  rc = _gnutls_hash_copy (&td_md5, &session->internals.handshake_mac_handle_md5);
  if (rc < 0)
    {
      gnutls_assert ();
      return rc;
    }

  rc = _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha);
  if (rc < 0)
    {
      gnutls_assert ();
      _gnutls_hash_deinit (&td_md5, NULL);
      return rc;
    }

  if (type == GNUTLS_SERVER)
    {
      mesg = SSL3_SERVER_MSG;
    }
  else
    {
      mesg = SSL3_CLIENT_MSG;
    }

  _gnutls_hash (&td_md5, mesg, siz);
  _gnutls_hash (&td_sha, mesg, siz);

  _gnutls_mac_deinit_ssl3_handshake (&td_md5, ret,
				     session->security_parameters.
				     master_secret, TLS_MASTER_SIZE);
  _gnutls_mac_deinit_ssl3_handshake (&td_sha, &ret[16],
				     session->security_parameters.
				     master_secret, TLS_MASTER_SIZE);

  return 0;
}

Project: savannah
File: gnutls_handshake.c

_gnutls_tls_create_random (opaque * dst)
{
  uint32_t tim;
  int ret;

  /* Use weak random numbers for the most of the
   * buffer except for the first 4 that are the
   * system's time.
   */

  tim = time (NULL);
  /* generate server random value */
  _gnutls_write_uint32 (tim, dst);

  ret = _gnutls_rnd (RND_NONCE, &dst[4], TLS_RANDOM_SIZE - 4);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return 0;
}

Project: savannah
File: gnutls_handshake.c

int _gnutls_user_hello_func( gnutls_session session, gnutls_protocol_t adv_version)
{
int ret;

  if (session->internals.user_hello_func != NULL) 
    {
      ret = session->internals.user_hello_func( session);
      if (ret < 0) 
        {
          gnutls_assert();
          return ret;
        }
      /* Here we need to renegotiate the version since the callee might
       * have disabled some TLS versions.
       */
      ret = _gnutls_negotiate_version( session, adv_version);
      if (ret < 0) {
        gnutls_assert();
        return ret;
      }
    }
  return 0;
}

Project: savannah
File: gnutls_handshake.c

resume_copy_required_values (gnutls_session_t session)
{
  /* get the new random values */
  memcpy (session->internals.resumed_security_parameters.
	  server_random,
	  session->security_parameters.server_random, TLS_RANDOM_SIZE);
  memcpy (session->internals.resumed_security_parameters.
	  client_random,
	  session->security_parameters.client_random, TLS_RANDOM_SIZE);

  /* keep the ciphersuite and compression 
   * That is because the client must see these in our
   * hello message.
   */
  memcpy (session->security_parameters.current_cipher_suite.
	  suite,
	  session->internals.resumed_security_parameters.
	  current_cipher_suite.suite, 2);

  session->internals.compression_method =
    session->internals.resumed_security_parameters.read_compression_algorithm;
  /* or write_compression_algorithm
   * they are the same
   */

  session->security_parameters.entity =
    session->internals.resumed_security_parameters.entity;

  _gnutls_set_current_version (session,
			       session->internals.
			       resumed_security_parameters.version);

  session->security_parameters.cert_type =
    session->internals.resumed_security_parameters.cert_type;

  memcpy (session->security_parameters.session_id,
	  session->internals.resumed_security_parameters.
	  session_id, sizeof (session->security_parameters.session_id));
  session->security_parameters.session_id_size =
    session->internals.resumed_security_parameters.session_id_size;
}