示例#1
0
static int
_wrap_nettle_pk_encrypt(gnutls_pk_algorithm_t algo,
			gnutls_datum_t * ciphertext,
			const gnutls_datum_t * plaintext,
			const gnutls_pk_params_st * pk_params)
{
	int ret;
	mpz_t p;

	mpz_init(p);

	switch (algo) {
	case GNUTLS_PK_RSA:
		{
			struct rsa_public_key pub;

			_rsa_params_to_pubkey(pk_params, &pub);

			ret =
			    rsa_encrypt(&pub, NULL, rnd_func,
					plaintext->size, plaintext->data,
					p);
			if (ret == 0) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_ENCRYPTION_FAILED);
				goto cleanup;
			}

			ret =
			    _gnutls_mpi_dprint_size(p, ciphertext,
						    pub.size);
			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}

			break;
		}
	default:
		gnutls_assert();
		ret = GNUTLS_E_INTERNAL_ERROR;
		goto cleanup;
	}

	ret = 0;

      cleanup:
	mpz_clear(p);

	FAIL_IF_LIB_ERROR;
	return ret;
}
示例#2
0
文件: pk.c 项目: intgr/gnutls
static int
_wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo,
                        const gnutls_datum_t * vdata,
                        const gnutls_datum_t * signature,
                        const gnutls_pk_params_st * pk_params)
{
  int ret;
  unsigned int hash_len;
  bigint_t tmp[2] = { NULL, NULL };

  switch (algo)
    {
    case GNUTLS_PK_EC: /* ECDSA */
      {
        ecc_key pub;
        struct dsa_signature sig;
        int stat;
        int curve_id = pk_params->flags;

        if (is_supported_curve(curve_id) == 0)
          return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);

        ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]);
        if (ret < 0)
          {
            gnutls_assert ();
            goto cleanup;
          }

        _ecc_params_to_pubkey(pk_params, &pub);
        memcpy (&sig.r, tmp[0], sizeof (sig.r));
        memcpy (&sig.s, tmp[1], sizeof (sig.s));

        _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
        if (hash_len > vdata->size)
          hash_len = vdata->size;

        ret = ecc_verify_hash(&sig, vdata->data, hash_len, &stat, &pub, curve_id);
        if (ret != 0 || stat != 1)
          {
            gnutls_assert();
            ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
          }
        else
          ret = 0;

        _gnutls_mpi_release (&tmp[0]);
        _gnutls_mpi_release (&tmp[1]);
        _ecc_params_clear( &pub);
        break;
      }
    case GNUTLS_PK_DSA:
      {
        struct dsa_public_key pub;
        struct dsa_signature sig;

        ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]);
        if (ret < 0)
          {
            gnutls_assert ();
            goto cleanup;
          }
        memset(&pub, 0, sizeof(pub));
        _dsa_params_to_pubkey (pk_params, &pub);
        memcpy (&sig.r, tmp[0], sizeof (sig.r));
        memcpy (&sig.s, tmp[1], sizeof (sig.s));

        _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
        if (hash_len > vdata->size)
          hash_len = vdata->size;

        ret = _dsa_verify (&pub, hash_len, vdata->data, &sig);
        if (ret == 0)
          {
            gnutls_assert();
            ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
          }
        else
          ret = 0;

        _gnutls_mpi_release (&tmp[0]);
        _gnutls_mpi_release (&tmp[1]);
        break;
      }
    case GNUTLS_PK_RSA:
      {
        struct rsa_public_key pub;
        
        _rsa_params_to_pubkey (pk_params, &pub);

        ret = _gnutls_mpi_scan_nz (&tmp[0], signature->data, signature->size);
        if (ret < 0)
          {
            gnutls_assert ();
            goto cleanup;
          }

        ret = rsa_pkcs1_verify (&pub, vdata->size, vdata->data, TOMPZ(tmp[0]));
        if (ret == 0) 
          ret = gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
        else ret = 0;
        
        _gnutls_mpi_release (&tmp[0]);
        break;
      }
    default:
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

cleanup:

  return ret;
}
示例#3
0
文件: pk.c 项目: intgr/gnutls
/* in case of DSA puts into data, r,s
 */
static int
_wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo,
                      gnutls_datum_t * signature,
                      const gnutls_datum_t * vdata,
                      const gnutls_pk_params_st * pk_params)
{
  int ret;
  unsigned int hash;
  unsigned int hash_len;

  switch (algo)
    {
    case GNUTLS_PK_EC: /* we do ECDSA */
      {
        ecc_key priv;
        struct dsa_signature sig;
        int curve_id = pk_params->flags;

        if (is_supported_curve(curve_id) == 0)
          return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);

        _ecc_params_to_privkey(pk_params, &priv);

        dsa_signature_init (&sig);

        hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
        if (hash_len > vdata->size)
          {
            gnutls_assert ();
            _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len);
            hash_len = vdata->size;
          }

        ret = ecc_sign_hash(vdata->data, hash_len,
                            &sig, NULL, rnd_func, &priv, curve_id);
        if (ret != 0)
          {
            gnutls_assert ();
            ret = GNUTLS_E_PK_SIGN_FAILED;
            goto ecdsa_fail;
          }

        ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s);

      ecdsa_fail:
        dsa_signature_clear (&sig);
        _ecc_params_clear( &priv);

        if (ret < 0)
          {
            gnutls_assert ();
            goto cleanup;
          }
        break;
      }
    case GNUTLS_PK_DSA:
      {
        struct dsa_public_key pub;
        struct dsa_private_key priv;
        struct dsa_signature sig;

        memset(&priv, 0, sizeof(priv));
        memset(&pub, 0, sizeof(pub));
        _dsa_params_to_pubkey (pk_params, &pub);
        _dsa_params_to_privkey (pk_params, &priv);

        dsa_signature_init (&sig);

        hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
        if (hash_len > vdata->size)
          {
            gnutls_assert ();
            _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len);
            hash_len = vdata->size;
          }

        ret =
          _dsa_sign (&pub, &priv, NULL, rnd_func,
                     hash_len, vdata->data, &sig);
        if (ret == 0)
          {
            gnutls_assert ();
            ret = GNUTLS_E_PK_SIGN_FAILED;
            goto dsa_fail;
          }

        ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s);

      dsa_fail:
        dsa_signature_clear (&sig);

        if (ret < 0)
          {
            gnutls_assert ();
            goto cleanup;
          }
        break;
      }
    case GNUTLS_PK_RSA:
      {
        struct rsa_private_key priv;
        struct rsa_public_key pub;
        mpz_t s;

        _rsa_params_to_privkey (pk_params, &priv);
        _rsa_params_to_pubkey (pk_params, &pub);
        
        mpz_init(s);

        ret = rsa_pkcs1_sign_tr(&pub, &priv, NULL, rnd_func,
                                vdata->size, vdata->data, s);
        if (ret == 0)
          {
            gnutls_assert();
            ret = GNUTLS_E_PK_SIGN_FAILED;
            goto rsa_fail;
          }

        ret = _gnutls_mpi_dprint (s, signature);

rsa_fail:
        mpz_clear(s);

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

        break;
      }
    default:
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  ret = 0;

cleanup:

  return ret;
}
示例#4
0
文件: pk.c 项目: intgr/gnutls
static int
_wrap_nettle_pk_decrypt (gnutls_pk_algorithm_t algo,
                         gnutls_datum_t * plaintext,
                         const gnutls_datum_t * ciphertext,
                         const gnutls_pk_params_st * pk_params)
{
  int ret;

  plaintext->data = NULL;

  /* make a sexp from pkey */
  switch (algo)
    {
    case GNUTLS_PK_RSA:
      {
        struct rsa_private_key priv;
        struct rsa_public_key pub;
        unsigned length;
        bigint_t c;

        _rsa_params_to_privkey (pk_params, &priv);
        _rsa_params_to_pubkey (pk_params, &pub);

        if (_gnutls_mpi_scan_nz (&c, ciphertext->data, ciphertext->size) != 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
            goto cleanup;
          }

        length = pub.size;
        plaintext->data = gnutls_malloc(length);
        if (plaintext->data == NULL)
          {
            ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
            goto cleanup;
          }
        
        ret = rsa_decrypt_tr(&pub, &priv, NULL, rnd_func, &length, plaintext->data,
                             TOMPZ(c));
        _gnutls_mpi_release (&c);
        plaintext->size = length;

        if (ret == 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
            goto cleanup;
          }

        break;
      }
    default:
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  ret = 0;

cleanup:
  if (ret < 0)
    gnutls_free(plaintext->data);

  return ret;
}
示例#5
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;

}