Ejemplo n.º 1
0
/* Generates a signature of all the previous sent packets in the 
 * handshake procedure. (20040227: now it works for SSL 3.0 as well)
 */
int
_gnutls_tls_sign_hdata (gnutls_session_t session,
			gnutls_cert * cert, gnutls_privkey * pkey,
			gnutls_datum_t * signature)
{
  gnutls_datum_t dconcat;
  int ret;
  opaque concat[36];
  digest_hd_st td_md5;
  digest_hd_st td_sha;
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);

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

  if (ver == GNUTLS_SSL3)
    {
      ret = _gnutls_generate_master (session, 1);
      if (ret < 0)
	{
	  gnutls_assert ();
	  return ret;
	}

      _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
					 session->security_parameters.
					 master_secret, GNUTLS_MASTER_SIZE);
    }
  else
    _gnutls_hash_deinit (&td_sha, &concat[16]);

  switch (cert->subject_pk_algorithm)
    {
    case GNUTLS_PK_RSA:
      ret =
	_gnutls_hash_copy (&td_md5,
			   &session->internals.handshake_mac_handle_md5);
      if (ret < 0)
	{
	  gnutls_assert ();
	  return ret;
	}

      if (ver == GNUTLS_SSL3)
	_gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
					   session->security_parameters.
					   master_secret, GNUTLS_MASTER_SIZE);
      else
	_gnutls_hash_deinit (&td_md5, concat);

      dconcat.data = concat;
      dconcat.size = 36;
      break;
    case GNUTLS_PK_DSA:
      dconcat.data = &concat[16];
      dconcat.size = 20;
      break;

    default:
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }
  ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
    }

  return ret;
}
Ejemplo n.º 2
0
/* the same as _gnutls_handshake_sign_cert_vrfy except that it is made for TLS 1.2
 */
static int
_gnutls_handshake_sign_cert_vrfy12 (gnutls_session_t session,
				    gnutls_cert * cert, gnutls_privkey * pkey,
				    gnutls_datum_t * signature)
{
  gnutls_datum_t dconcat;
  int ret;
  opaque concat[MAX_SIG_SIZE];
  digest_hd_st td;
  gnutls_sign_algorithm_t sign_algo;
  gnutls_digest_algorithm_t hash_algo;
  digest_hd_st *handshake_td;

  handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
  hash_algo = handshake_td->algorithm;
  sign_algo = _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);

  /* The idea here is to try signing with the one of the algorithms
   * that have been initiated at handshake (SHA1, SHA256). If they
   * are not requested by peer... tough luck
   */
  ret = _gnutls_session_sign_algo_requested (session, sign_algo);
  if (sign_algo == GNUTLS_SIGN_UNKNOWN || ret < 0)
    {
      handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
      hash_algo = handshake_td->algorithm;
      sign_algo =
	_gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
      if (sign_algo == GNUTLS_SIGN_UNKNOWN)
	{
	  gnutls_assert ();
	  return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
	}

      ret = _gnutls_session_sign_algo_requested (session, sign_algo);
      if (ret < 0)
	{
	  gnutls_assert ();
	  _gnutls_x509_log
	    ("Server did not allow either '%s' or '%s' for signing\n",
	     gnutls_mac_get_name (hash_algo),
	     gnutls_mac_get_name (session->internals.handshake_mac_handle.
				  tls12.sha1.algorithm));
	  return ret;
	}
    }

  _gnutls_x509_log ("sign handshake cert vrfy: picked %s with %s\n",
		    gnutls_sign_algorithm_get_name (sign_algo),
		    gnutls_mac_get_name (hash_algo));

  ret = _gnutls_hash_copy (&td, handshake_td);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_hash_deinit (&td, concat);

  dconcat.data = concat;
  dconcat.size = _gnutls_hash_get_algo_len (hash_algo);

  ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return sign_algo;
}
Ejemplo n.º 3
0
/* Generates a signature of all the random data and the parameters.
 * Used in DHE_* ciphersuites.
 */
int
_gnutls_tls_sign_params (gnutls_session_t session, gnutls_cert * cert,
			 gnutls_privkey * pkey, gnutls_datum_t * params,
			 gnutls_datum_t * signature)
{
  gnutls_datum_t dconcat;
  int ret;
  digest_hd_st td_sha;
  opaque concat[36];
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);

  ret = _gnutls_hash_init (&td_sha, GNUTLS_MAC_SHA1);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_hash (&td_sha, session->security_parameters.client_random,
		GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, session->security_parameters.server_random,
		GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, params->data, params->size);

  switch (cert->subject_pk_algorithm)
    {
    case GNUTLS_PK_RSA:
      if (ver < GNUTLS_TLS1_2)
	{
	  digest_hd_st td_md5;

	  ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
	  if (ret < 0)
	    {
	      gnutls_assert ();
	      return ret;
	    }

	  _gnutls_hash (&td_md5, session->security_parameters.client_random,
			GNUTLS_RANDOM_SIZE);
	  _gnutls_hash (&td_md5, session->security_parameters.server_random,
			GNUTLS_RANDOM_SIZE);
	  _gnutls_hash (&td_md5, params->data, params->size);

	  _gnutls_hash_deinit (&td_md5, concat);
	  _gnutls_hash_deinit (&td_sha, &concat[16]);

	  dconcat.size = 36;
	}
      else
	{
#if 1
	  /* Use NULL parameters. */
	  memcpy (concat,
		  "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
		  15);
	  _gnutls_hash_deinit (&td_sha, &concat[15]);
	  dconcat.size = 35;
#else
	  /* No parameters field. */
	  memcpy (concat,
		  "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
	  _gnutls_hash_deinit (&td_sha, &concat[13]);
	  dconcat.size = 33;
#endif
	}
      dconcat.data = concat;
      break;
    case GNUTLS_PK_DSA:
      _gnutls_hash_deinit (&td_sha, concat);
      dconcat.data = concat;
      dconcat.size = 20;
      break;

    default:
      gnutls_assert ();
      _gnutls_hash_deinit (&td_sha, NULL);
      return GNUTLS_E_INTERNAL_ERROR;
    }
  ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
    }

  return ret;

}
Ejemplo n.º 4
0
/* Generates a signature of all the random data and the parameters.
 * Used in DHE_* ciphersuites.
 */
int
_gnutls_handshake_sign_data (gnutls_session_t session, gnutls_cert * cert,
			     gnutls_privkey * pkey, gnutls_datum_t * params,
			     gnutls_datum_t * signature,
			     gnutls_sign_algorithm_t * sign_algo)
{
  gnutls_datum_t dconcat;
  int ret;
  digest_hd_st td_sha;
  opaque concat[MAX_SIG_SIZE];
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
  gnutls_digest_algorithm_t hash_algo;

  *sign_algo =
    _gnutls_session_get_sign_algo (session, cert->subject_pk_algorithm,
				   &hash_algo);
  if (*sign_algo == GNUTLS_SIGN_UNKNOWN)
    {
      gnutls_assert ();
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
    }

  ret = _gnutls_hash_init (&td_sha, hash_algo);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_hash (&td_sha, session->security_parameters.client_random,
		GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, session->security_parameters.server_random,
		GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, params->data, params->size);

  switch (cert->subject_pk_algorithm)
    {
    case GNUTLS_PK_RSA:
      if (!_gnutls_version_has_selectable_prf (ver))
	{
	  digest_hd_st td_md5;

	  ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
	  if (ret < 0)
	    {
	      gnutls_assert ();
	      return ret;
	    }

	  _gnutls_hash (&td_md5, session->security_parameters.client_random,
			GNUTLS_RANDOM_SIZE);
	  _gnutls_hash (&td_md5, session->security_parameters.server_random,
			GNUTLS_RANDOM_SIZE);
	  _gnutls_hash (&td_md5, params->data, params->size);

	  _gnutls_hash_deinit (&td_md5, concat);
	  _gnutls_hash_deinit (&td_sha, &concat[16]);

	  dconcat.data = concat;
	  dconcat.size = 36;
	}
      else
	{			/* TLS 1.2 way */
	  gnutls_datum_t hash;

	  _gnutls_hash_deinit (&td_sha, concat);

	  hash.data = concat;
	  hash.size = _gnutls_hash_get_algo_len (hash_algo);
	  dconcat.data = concat;
	  dconcat.size = sizeof concat;

	  _gnutls_rsa_encode_sig (hash_algo, &hash, &dconcat);
	}
      break;
    case GNUTLS_PK_DSA:
      _gnutls_hash_deinit (&td_sha, concat);

      if (hash_algo != GNUTLS_DIG_SHA1)
	{
	  gnutls_assert ();
	  return GNUTLS_E_INTERNAL_ERROR;
	}
      dconcat.data = concat;
      dconcat.size = 20;
      break;

    default:
      gnutls_assert ();
      _gnutls_hash_deinit (&td_sha, NULL);
      return GNUTLS_E_INTERNAL_ERROR;
    }
  ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
    }

  return ret;

}