Exemplo n.º 1
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_pcert_st* cert, gnutls_privkey_t 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;

  sign_algo =
    _gnutls_session_get_sign_algo (session, cert);
  if (sign_algo == GNUTLS_SIGN_UNKNOWN)
    {
      gnutls_assert ();
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
    }

  hash_algo = _gnutls_sign_get_hash_algorithm (sign_algo);

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

  if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha1.algorithm)
    handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
  else if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha256.algorithm)
    handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
  else
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); /* too bad we only support SHA1 and SHA256 */

  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 = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return sign_algo;
}
Exemplo n.º 2
0
/* the same as _gnutls_handshake_sign_crt_vrfy except that it is made for TLS 1.2
 */
static int
_gnutls_handshake_sign_crt_vrfy12(gnutls_session_t session,
				  gnutls_pcert_st * cert,
				  gnutls_privkey_t pkey,
				  gnutls_datum_t * signature)
{
	gnutls_datum_t dconcat;
	int ret;
	uint8_t concat[MAX_SIG_SIZE];
	gnutls_sign_algorithm_t sign_algo;
	const mac_entry_st *me;

	sign_algo = _gnutls_session_get_sign_algo(session, cert);
	if (sign_algo == GNUTLS_SIGN_UNKNOWN) {
		gnutls_assert();
		return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
	}

	gnutls_sign_algorithm_set_client(session, sign_algo);

	me = hash_to_entry(gnutls_sign_get_hash_algorithm(sign_algo));

	_gnutls_debug_log("sign handshake cert vrfy: picked %s with %s\n",
			  gnutls_sign_algorithm_get_name(sign_algo),
			  _gnutls_mac_get_name(me));

	ret =
	    _gnutls_hash_fast((gnutls_digest_algorithm_t)me->id,
			      session->internals.handshake_hash_buffer.
			      data,
			      session->internals.handshake_hash_buffer.
			      length, concat);
	if (ret < 0)
		return gnutls_assert_val(ret);

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

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

	return sign_algo;
}
Exemplo n.º 3
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_pcert_st * cert, gnutls_privkey_t 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;
	uint8_t concat[MAX_SIG_SIZE];
	const version_entry_st *ver = get_version(session);
	const mac_entry_st *hash_algo;

	*sign_algo = _gnutls_session_get_sign_algo(session, cert);
	if (*sign_algo == GNUTLS_SIGN_UNKNOWN) {
		gnutls_assert();
		return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
	}

	gnutls_sign_algorithm_set_server(session, *sign_algo);

	hash_algo =
	    hash_to_entry(gnutls_sign_get_hash_algorithm(*sign_algo));
	if (hash_algo == NULL)
		return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);

	_gnutls_handshake_log
	    ("HSK[%p]: signing handshake data: using %s\n", session,
	     gnutls_sign_algorithm_get_name(*sign_algo));

	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 (gnutls_privkey_get_pk_algorithm(pkey, NULL)) {
	case GNUTLS_PK_RSA:
		if (!_gnutls_version_has_selectable_sighash(ver)) {
			digest_hd_st td_md5;

			ret =
			    _gnutls_hash_init(&td_md5,
					      hash_to_entry
					      (GNUTLS_DIG_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_hash_deinit(&td_sha, concat);

			dconcat.data = concat;
			dconcat.size =
			    _gnutls_hash_get_algo_len(hash_algo);
		}
		break;
	case GNUTLS_PK_DSA:
	case GNUTLS_PK_EC:
		_gnutls_hash_deinit(&td_sha, concat);

		if (!IS_SHA((gnutls_digest_algorithm_t)hash_algo->id)) {
			gnutls_assert();
			return GNUTLS_E_INTERNAL_ERROR;
		}
		dconcat.data = concat;
		dconcat.size = _gnutls_hash_get_algo_len(hash_algo);
		break;

	default:
		gnutls_assert();
		_gnutls_hash_deinit(&td_sha, NULL);
		return GNUTLS_E_INTERNAL_ERROR;
	}

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

	return ret;

}
Exemplo 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;

}
Exemplo n.º 5
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_pcert_st* cert,
                             gnutls_privkey_t 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);
  if (*sign_algo == GNUTLS_SIGN_UNKNOWN)
    {
      gnutls_assert ();
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
    }

  hash_algo = _gnutls_sign_get_hash_algorithm (*sign_algo);

  _gnutls_handshake_log ("HSK[%p]: signing handshake data: using %s\n",
                    session, gnutls_sign_algorithm_get_name (*sign_algo));

  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 (gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL))
    {
    case GNUTLS_PK_RSA:
      if (!_gnutls_version_has_selectable_sighash (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_hash_deinit (&td_sha, concat);

          dconcat.data = concat;
          dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
        }
      break;
    case GNUTLS_PK_DSA:
      _gnutls_hash_deinit (&td_sha, concat);

      if ((hash_algo != GNUTLS_DIG_SHA1) && (hash_algo != GNUTLS_DIG_SHA224)
          && (hash_algo != GNUTLS_DIG_SHA256))
        {
          gnutls_assert ();
          return GNUTLS_E_INTERNAL_ERROR;
        }
      dconcat.data = concat;
      dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
      break;

    default:
      gnutls_assert ();
      _gnutls_hash_deinit (&td_sha, NULL);
      return GNUTLS_E_INTERNAL_ERROR;
    }

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

  return ret;

}