コード例 #1
0
ファイル: verify.c プロジェクト: dezelin/maily
/* This will return the appropriate hash to verify the given signature.
 * If signature is NULL it will return an (or the) appropriate hash for
 * the given parameters.
 */
int
_gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
                               const gnutls_datum_t * signature,
                               gnutls_pk_algorithm pk,
                               bigint_t * issuer_params,
                               unsigned int issuer_params_size)
{
  opaque digest[MAX_HASH_SIZE];
  gnutls_datum_t decrypted;
  int digest_size;
  int ret;

  switch (pk)
    {
    case GNUTLS_PK_DSA:

      if (hash)
        *hash = _gnutls_dsa_q_to_hash (issuer_params[1], NULL);

      ret = 0;
      break;
    case GNUTLS_PK_RSA:
      if (signature == NULL)
        {                       /* return a sensible algorithm */
          if (hash)
            *hash = GNUTLS_DIG_SHA256;
          return 0;
        }

      ret =
        _gnutls_pkcs1_rsa_decrypt (&decrypted, signature,
                                   issuer_params, issuer_params_size, 1);


      if (ret < 0)
        {
          gnutls_assert ();
          goto cleanup;
        }

      digest_size = sizeof (digest);
      if ((ret =
           decode_ber_digest_info (&decrypted, hash, digest,
                                   &digest_size)) != 0)
        {
          gnutls_assert ();
          _gnutls_free_datum (&decrypted);
          goto cleanup;
        }

      _gnutls_free_datum (&decrypted);
      if (digest_size != _gnutls_hash_get_algo_len (*hash))
        {
          gnutls_assert ();
          ret = GNUTLS_E_ASN1_GENERIC_ERROR;
          goto cleanup;
        }

      ret = 0;
      break;

    default:
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
    }

cleanup:

  return ret;

}
コード例 #2
0
ファイル: verify.c プロジェクト: dezelin/maily
/* if hash==MD5 then we do RSA-MD5
 * if hash==SHA then we do RSA-SHA
 * params[0] is modulus
 * params[1] is public key
 */
static int
_pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
                       const gnutls_datum_t * prehash,
                       const gnutls_datum_t * signature, bigint_t * params,
                       int params_len)
{
  gnutls_mac_algorithm_t hash = GNUTLS_MAC_UNKNOWN;
  int ret;
  opaque digest[MAX_HASH_SIZE], md[MAX_HASH_SIZE], *cmp;
  int digest_size;
  digest_hd_st hd;
  gnutls_datum_t decrypted;

  ret =
    _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, params_len, 1);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  /* decrypted is a BER encoded data of type DigestInfo
   */

  digest_size = sizeof (digest);
  if ((ret =
       decode_ber_digest_info (&decrypted, &hash, digest, &digest_size)) != 0)
    {
      gnutls_assert ();
      _gnutls_free_datum (&decrypted);
      return ret;
    }

  _gnutls_free_datum (&decrypted);

  if (digest_size != _gnutls_hash_get_algo_len (hash))
    {
      gnutls_assert ();
      return GNUTLS_E_ASN1_GENERIC_ERROR;
    }

  if (prehash && prehash->data && prehash->size == digest_size)
    {
      cmp = prehash->data;
    }
  else
    {
      if (!text)
        {
          gnutls_assert ();
          return GNUTLS_E_INVALID_REQUEST;
        }

      ret = _gnutls_hash_init (&hd, hash);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }

      _gnutls_hash (&hd, text->data, text->size);
      _gnutls_hash_deinit (&hd, md);

      cmp = md;
    }

  if (memcmp (cmp, digest, digest_size) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
    }

  return 0;
}
コード例 #3
0
ファイル: pk.c プロジェクト: intgr/gnutls
/* Given a signature and parameters, it should return
 * the hash algorithm used in the signature. This is a kludge
 * but until we deprecate gnutls_pubkey_get_verify_algorithm()
 * we depend on it.
 */
static int wrap_nettle_hash_algorithm (gnutls_pk_algorithm_t pk, 
    const gnutls_datum_t * sig, gnutls_pk_params_st * issuer_params,
    gnutls_digest_algorithm_t* hash_algo)
{
  uint8_t digest[MAX_HASH_SIZE];
  uint8_t digest_info[MAX_HASH_SIZE*3];
  gnutls_datum_t di;
  unsigned digest_size;
  mpz_t s;
  struct rsa_public_key pub;
  int ret;

  mpz_init(s);

  switch (pk)
    {
    case GNUTLS_PK_DSA:
    case GNUTLS_PK_EC:

      if (hash_algo)
        *hash_algo = _gnutls_dsa_q_to_hash (pk, issuer_params, NULL);

      ret = 0;
      break;
    case GNUTLS_PK_RSA:
      if (sig == NULL)
        {                       /* return a sensible algorithm */
          if (hash_algo)
            *hash_algo = GNUTLS_DIG_SHA256;
          return 0;
        }

      _rsa_params_to_pubkey (issuer_params, &pub);

      digest_size = sizeof(digest);
      
      nettle_mpz_set_str_256_u(s, sig->size, sig->data);
      
      digest_size = sizeof (digest_info);
      ret = extract_digest_info( &pub, &digest_size, digest_info, s);
      if (ret == 0)
        {
          ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
          gnutls_assert ();
          goto cleanup;
        }

      di.data = digest_info;
      di.size = digest_size;
      
      digest_size = sizeof(digest);
      if ((ret =
           decode_ber_digest_info (&di, hash_algo, digest,
                                   &digest_size)) < 0)
        {
          gnutls_assert ();
          goto cleanup;
        }

      if (digest_size != _gnutls_hash_get_algo_len (*hash_algo))
        {
          gnutls_assert ();
          ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
          goto cleanup;
        }

      ret = 0;
      break;

    default:
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
    }

cleanup:
  mpz_clear(s);
  return ret;

}
コード例 #4
0
ファイル: keys-win.c プロジェクト: gnutls/gnutls
static
int cng_sign(gnutls_privkey_t key, void *userdata,
	     const gnutls_datum_t * raw_data, gnutls_datum_t * signature)
{
	priv_st *priv = userdata;
	BCRYPT_PKCS1_PADDING_INFO _info;
	void *info = NULL;
	DWORD ret_sig = 0;
	int ret;
	DWORD flags = 0;
	gnutls_datum_t data = { raw_data->data, raw_data->size };
	uint8_t digest[MAX_HASH_SIZE];
	unsigned int digest_size;
	gnutls_digest_algorithm_t algo;
	SECURITY_STATUS r;

	signature->data = NULL;
	signature->size = 0;

	if (priv->pk == GNUTLS_PK_RSA) {

		flags = BCRYPT_PAD_PKCS1;
		info = &_info;

		if (raw_data->size == 36) {	/* TLS 1.0 MD5+SHA1 */
			_info.pszAlgId = NULL;
		} else {
			digest_size = sizeof(digest);
			ret =
			    decode_ber_digest_info(raw_data, &algo, digest,
						   &digest_size);
			if (ret < 0)
				return gnutls_assert_val(ret);

			switch (algo) {
			case GNUTLS_DIG_SHA1:
				_info.pszAlgId = NCRYPT_SHA1_ALGORITHM;
				break;
#ifdef NCRYPT_SHA224_ALGORITHM
			case GNUTLS_DIG_SHA224:
				_info.pszAlgId = NCRYPT_SHA224_ALGORITHM;
				break;
#endif
			case GNUTLS_DIG_SHA256:
				_info.pszAlgId = NCRYPT_SHA256_ALGORITHM;
				break;
			case GNUTLS_DIG_SHA384:
				_info.pszAlgId = NCRYPT_SHA384_ALGORITHM;
				break;
			case GNUTLS_DIG_SHA512:
				_info.pszAlgId = NCRYPT_SHA512_ALGORITHM;
				break;
			default:
				return
				    gnutls_assert_val
				    (GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
			}
			data.data = digest;
			data.size = digest_size;
		}
	}

	r = pNCryptSignHash(priv->nc, info, data.data, data.size,
			    NULL, 0, &ret_sig, flags);
	if (FAILED(r)) {
		gnutls_assert();
		_gnutls_debug_log("error in pre-signing: %d\n",
				  (int)GetLastError());
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	signature->size = ret_sig;
	signature->data = gnutls_malloc(signature->size);
	if (signature->data == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	r = pNCryptSignHash(priv->nc, info, data.data, data.size,
			    signature->data, signature->size, &ret_sig, flags);
	if (FAILED(r)) {
		gnutls_assert();
		_gnutls_debug_log("error in signing: %d\n",
				  (int)GetLastError());
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	signature->size = ret_sig;

	return 0;
 fail:
	gnutls_free(signature->data);
	return ret;
}
コード例 #5
0
ファイル: keys-win.c プロジェクト: gnutls/gnutls
static
int capi_sign(gnutls_privkey_t key, void *userdata,
	      const gnutls_datum_t * raw_data, gnutls_datum_t * signature)
{
	priv_st *priv = (priv_st *) userdata;
	ALG_ID Algid;
	HCRYPTHASH hHash = NULL;
	uint8_t digest[MAX_HASH_SIZE];
	unsigned int digest_size;
	gnutls_digest_algorithm_t algo;
	DWORD size1 = 0, sizesize = sizeof(DWORD);
	DWORD ret_sig = 0;
	int ret;

	signature->data = NULL;
	signature->size = 0;

	digest_size = raw_data->size;

	switch (digest_size) {
	case 16:
		Algid = CALG_MD5;
		break;
		//case 35:  size=20;                                    // DigestInfo SHA1
	case 20:
		Algid = CALG_SHA1;
		break;
		//case 51:  size=32;                                    // DigestInto SHA-256
	case 32:
		Algid = CALG_SHA_256;
		break;
	case 36:
		Algid = CALG_SSL3_SHAMD5;
		break;
	case 48:
		Algid = CALG_SHA_384;
		break;
	case 64:
		Algid = CALG_SHA_512;
		break;
	default:
		digest_size = sizeof(digest);
		ret =
		    decode_ber_digest_info(raw_data, &algo, digest,
					   &digest_size);
		if (ret < 0)
			return gnutls_assert_val(ret);

		switch (algo) {
		case GNUTLS_DIG_SHA1:
			Algid = CALG_SHA1;
			break;
#ifdef NCRYPT_SHA224_ALGORITHM
		case GNUTLS_DIG_SHA224:
			Algid = CALG_SHA_224;
			break;
#endif
		case GNUTLS_DIG_SHA256:
			Algid = CALG_SHA_256;
			break;
		case GNUTLS_DIG_SHA384:
			Algid = CALG_SHA_384;
			break;
		case GNUTLS_DIG_SHA512:
			Algid = CALG_SHA_512;
			break;
		default:
			return
			    gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
		}
	}

	if (!CryptCreateHash(priv->hCryptProv, Algid, 0, 0, &hHash)) {
		gnutls_assert();
		_gnutls_debug_log("error in create hash: %d\n",
				  (int)GetLastError());
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	if (!CryptSetHashParam(hHash, HP_HASHVAL, digest, 0)) {
		gnutls_assert();
		_gnutls_debug_log("error in set hash val: %d\n",
				  (int)GetLastError());
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	if (!CryptGetHashParam
	    (hHash, HP_HASHSIZE, (BYTE *) & size1, &sizesize, 0)
	    || digest_size != size1) {
		gnutls_assert();
		_gnutls_debug_log("error in hash size: %d\n", (int)size1);
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	if (!CryptSignHash(hHash, priv->dwKeySpec, NULL, 0, NULL, &ret_sig)) {
		gnutls_assert();
		_gnutls_debug_log("error in pre-signing: %d\n",
				  (int)GetLastError());
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	signature->size = ret_sig;
	signature->data = (unsigned char *)gnutls_malloc(signature->size);

	if (signature->data == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	if (!CryptSignHash
	    (hHash, priv->dwKeySpec, NULL, 0, signature->data, &ret_sig)) {
		gnutls_assert();
		_gnutls_debug_log("error in signing: %d\n",
				  (int)GetLastError());
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	memrev(signature->data, signature->size);

	CryptDestroyHash(hHash);
	signature->size = ret_sig;

	return 0;
 fail:
	if (hHash != 0)
		CryptDestroyHash(hHash);
	gnutls_free(signature->data);
	return ret;
}
コード例 #6
0
ファイル: verify.c プロジェクト: Chronic-Dev/gnutls
int
_gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
			       const gnutls_datum_t * signature,
			       const gnutls_x509_crt_t issuer)
{
  bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE];
  opaque digest[MAX_HASH_SIZE];
  gnutls_datum_t decrypted;
  int issuer_params_size;
  int digest_size;
  int ret, i;

  issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
  ret =
    _gnutls_x509_crt_get_mpis (issuer, issuer_params, &issuer_params_size);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  switch (gnutls_x509_crt_get_pk_algorithm (issuer, NULL))
    {
    case GNUTLS_PK_DSA:

      if (hash)
	*hash = _gnutls_dsa_q_to_hash (issuer_params[1]);

      ret = 0;
      break;

    case GNUTLS_PK_RSA:

      ret =
	_gnutls_pkcs1_rsa_decrypt (&decrypted, signature,
				   issuer_params, issuer_params_size, 1);


      if (ret < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}

      digest_size = sizeof (digest);
      if ((ret =
	   decode_ber_digest_info (&decrypted, hash, digest,
				   &digest_size)) != 0)
	{
	  gnutls_assert ();
	  _gnutls_free_datum (&decrypted);
	  goto cleanup;
	}

      _gnutls_free_datum (&decrypted);
      if (digest_size != _gnutls_hash_get_algo_len (*hash))
	{
	  gnutls_assert ();
	  ret = GNUTLS_E_ASN1_GENERIC_ERROR;
	  goto cleanup;
	}

      ret = 0;
      break;

    default:
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
    }

cleanup:
  /* release allocated mpis */
  for (i = 0; i < issuer_params_size; i++)
    {
      _gnutls_mpi_release (&issuer_params[i]);
    }

  return ret;

}