Example #1
0
/* Do DSA signature calculation. params is p, q, g, y, x in that order.
 */
int
_gnutls_dsa_sign (gnutls_datum_t * signature,
		  const gnutls_datum_t * hash, bigint_t * params,
		  unsigned int params_len)
{
  int ret;
  size_t i;
  size_t k;
  gnutls_pk_params_st pk_params;

  for (i = 0; i < params_len; i++)
    pk_params.params[i] = params[i];
  pk_params.params_nr = params_len;

  k = hash->size;
  if (k < 20)
    {				/* SHA1 or better only */
      gnutls_assert ();
      return GNUTLS_E_PK_SIGN_FAILED;
    }

  ret = _gnutls_pk_sign (GNUTLS_PK_DSA, signature, hash, &pk_params);
  /* rs[0], rs[1] now hold r,s */

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

  return 0;
}
Example #2
0
/*-
 * gnutls_privkey_sign_raw_data:
 * @key: Holds the key
 * @flags: should be zero
 * @data: holds the data to be signed
 * @signature: will contain the signature allocated with gnutls_malloc()
 *
 * This function will sign the given data using a signature algorithm
 * supported by the private key. Note that this is a low-level function
 * and does not apply any preprocessing or hash on the signed data. 
 * For example on an RSA key the input @data should be of the DigestInfo
 * PKCS #1 1.5 format. Use it only if you know what are you doing.
 *
 * Note this function is equivalent to using the %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA
 * flag with gnutls_privkey_sign_hash().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 * negative error value.
 *
 * Since: 3.1.10
 -*/
static int
_gnutls_privkey_sign_raw_data(gnutls_privkey_t key,
			     unsigned flags,
			     const gnutls_datum_t * data,
			     gnutls_datum_t * signature)
{
	switch (key->type) {
#ifdef ENABLE_OPENPGP
	case GNUTLS_PRIVKEY_OPENPGP:
		return gnutls_openpgp_privkey_sign_hash(key->key.openpgp,
							data, signature);
#endif
#ifdef ENABLE_PKCS11
	case GNUTLS_PRIVKEY_PKCS11:
		return _gnutls_pkcs11_privkey_sign_hash(key->key.pkcs11,
							data, signature);
#endif
	case GNUTLS_PRIVKEY_X509:
		return _gnutls_pk_sign(key->key.x509->pk_algorithm,
				       signature, data, &key->key.x509->params);
	case GNUTLS_PRIVKEY_EXT:
		if (key->key.ext.sign_func == NULL)
			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
		return key->key.ext.sign_func(key, key->key.ext.userdata,
					      data, signature);
	default:
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}
}
Example #3
0
/* Do DSA signature calculation. params is p, q, g, y, x in that order.
 */
int
_gnutls_dsa_sign (gnutls_datum_t * signature,
		  const gnutls_datum_t * hash, mpi_t * params,
		  unsigned params_len)
{
  mpi_t rs[2], mdata;
  int ret;
  size_t k;

  k = hash->size;
  if (k != 20)
    {				/* SHA only */
      gnutls_assert ();
      return GNUTLS_E_PK_SIGN_FAILED;
    }

  if (_gnutls_mpi_scan_nz (&mdata, hash->data, &k) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  ret = _gnutls_pk_sign (GCRY_PK_DSA, rs, mdata, params, params_len);
  /* rs[0], rs[1] now hold r,s */
  _gnutls_mpi_release (&mdata);

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

  ret = encode_ber_rs (signature, rs[0], rs[1]);

  /* free r,s */
  _gnutls_mpi_release (&rs[0]);
  _gnutls_mpi_release (&rs[1]);

  if (ret != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  return 0;
}
Example #4
0
/*-
 * _gnutls_x509_privkey_sign_hash2:
 * @signer: Holds the signer's key
 * @hash_algo: The hash algorithm used
 * @hash_data: holds the data to be signed
 * @signature: will contain newly allocated signature
 * @flags: (0) for now
 *
 * This function will sign the given hashed data using a signature algorithm
 * supported by the private key. Signature algorithms are always used
 * together with a hash functions.  Different hash functions may be
 * used for the RSA algorithm, but only SHA-1,SHA-224 and SHA-256 
 * for the DSA keys, depending on their bit size.
 *
 * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
 * the hash algorithm.
 *
 * The RSA algorithm is used in PKCS #1 v1.5 mode.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 -*/
static int
_gnutls_x509_privkey_sign_hash2 (gnutls_x509_privkey_t signer,
                                gnutls_digest_algorithm_t hash_algo,
                                unsigned int flags,
                                const gnutls_datum_t * hash_data,
                                gnutls_datum_t * signature)
{
  int ret;
  gnutls_datum_t digest;

  digest.data = gnutls_malloc (hash_data->size);
  if (digest.data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }
  digest.size = hash_data->size;
  memcpy (digest.data, hash_data->data, digest.size);

  ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest);
  if (ret < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  ret = _gnutls_pk_sign (signer->pk_algorithm, signature, &digest, &signer->params);

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

  ret = 0;

cleanup:
  _gnutls_free_datum (&digest);
  return ret;
}
Example #5
0
/**
 * gnutls_x509_privkey_sign_hash:
 * @key: Holds the key
 * @hash: holds the data to be signed
 * @signature: will contain newly allocated signature
 *
 * This function will sign the given hash using the private key. Do not
 * use this function directly unless you know what it is. Typical signing
 * requires the data to be hashed and stored in special formats 
 * (e.g. BER Digest-Info for RSA).
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Deprecated in: 2.12.0
 */
int
gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key,
                               const gnutls_datum_t * hash,
                               gnutls_datum_t * signature)
{
  int result;

  if (key == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  result = _gnutls_pk_sign (key->pk_algorithm, signature, hash, &key->params);

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

  return 0;
}
Example #6
0
/* Do PKCS-1 RSA encryption. 
 * params is modulus, public exp.
 */
int
_gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
			   const gnutls_datum_t * plaintext,
			   mpi_t * params, unsigned params_len,
			   unsigned btype)
{
  unsigned int i, pad;
  int ret;
  mpi_t m, res;
  opaque *edata, *ps;
  size_t k, psize;
  size_t mod_bits;

  mod_bits = _gnutls_mpi_get_nbits (params[0]);
  k = mod_bits / 8;
  if (mod_bits % 8 != 0)
    k++;

  if (plaintext->size > k - 11)
    {
      gnutls_assert ();
      return GNUTLS_E_PK_ENCRYPTION_FAILED;
    }

  edata = gnutls_alloca (k);
  if (edata == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* EB = 00||BT||PS||00||D 
   * (use block type 'btype')
   */

  edata[0] = 0;
  edata[1] = btype;
  psize = k - 3 - plaintext->size;

  ps = &edata[2];
  switch (btype)
    {
    case 2:
      /* using public key */
      if (params_len < RSA_PUBLIC_PARAMS)
	{
	  gnutls_assert ();
	  gnutls_afree (edata);
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      if (gc_pseudo_random (ps, psize) != GC_OK)
	{
	  gnutls_assert ();
	  gnutls_afree (edata);
	  return GNUTLS_E_RANDOM_FAILED;
	}
      for (i = 0; i < psize; i++)
	while (ps[i] == 0)
	  {
	    if (gc_pseudo_random (&ps[i], 1) != GC_OK)
	      {
		gnutls_assert ();
		gnutls_afree (edata);
		return GNUTLS_E_RANDOM_FAILED;
	      }
	  }
      break;
    case 1:
      /* using private key */

      if (params_len < RSA_PRIVATE_PARAMS)
	{
	  gnutls_assert ();
	  gnutls_afree (edata);
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      for (i = 0; i < psize; i++)
	ps[i] = 0xff;
      break;
    default:
      gnutls_assert ();
      gnutls_afree (edata);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ps[psize] = 0;
  memcpy (&ps[psize + 1], plaintext->data, plaintext->size);

  if (_gnutls_mpi_scan_nz (&m, edata, &k) != 0)
    {
      gnutls_assert ();
      gnutls_afree (edata);
      return GNUTLS_E_MPI_SCAN_FAILED;
    }
  gnutls_afree (edata);

  if (btype == 2)		/* encrypt */
    ret = _gnutls_pk_encrypt (GCRY_PK_RSA, &res, m, params, params_len);
  else				/* sign */
    ret = _gnutls_pk_sign (GCRY_PK_RSA, &res, m, params, params_len);

  _gnutls_mpi_release (&m);

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

  _gnutls_mpi_print (NULL, &psize, res);

  if (psize < k)
    {
      /* padding psize */
      pad = k - psize;
      psize = k;
    }
  else if (psize == k)
    {
      pad = 0;
    }
  else
    {				/* psize > k !!! */
      /* This is an impossible situation */
      gnutls_assert ();
      _gnutls_mpi_release (&res);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ciphertext->data = gnutls_malloc (psize);
  if (ciphertext->data == NULL)
    {
      gnutls_assert ();
      _gnutls_mpi_release (&res);
      return GNUTLS_E_MEMORY_ERROR;
    }
  _gnutls_mpi_print (&ciphertext->data[pad], &psize, res);
  for (i = 0; i < pad; i++)
    ciphertext->data[i] = 0;

  ciphertext->size = k;

  _gnutls_mpi_release (&res);

  return 0;
}
Example #7
0
/* Do PKCS-1 RSA encryption. 
 * params is modulus, public exp.
 */
int
_gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
			   const gnutls_datum_t * plaintext,
			   bigint_t * params, unsigned params_len,
			   unsigned btype)
{
  unsigned int i, pad;
  int ret;
  opaque *edata, *ps;
  size_t k, psize;
  size_t mod_bits;
  gnutls_pk_params_st pk_params;
  gnutls_datum to_encrypt, encrypted;

  for (i = 0; i < params_len; i++)
    pk_params.params[i] = params[i];
  pk_params.params_nr = params_len;

  mod_bits = _gnutls_mpi_get_nbits (params[0]);
  k = mod_bits / 8;
  if (mod_bits % 8 != 0)
    k++;

  if (plaintext->size > k - 11)
    {
      gnutls_assert ();
      return GNUTLS_E_PK_ENCRYPTION_FAILED;
    }

  edata = gnutls_malloc (k);
  if (edata == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* EB = 00||BT||PS||00||D 
   * (use block type 'btype')
   */

  edata[0] = 0;
  edata[1] = btype;
  psize = k - 3 - plaintext->size;

  ps = &edata[2];
  switch (btype)
    {
    case 2:
      /* using public key */
      if (params_len < RSA_PUBLIC_PARAMS)
	{
	  gnutls_assert ();
	  gnutls_free (edata);
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      ret = _gnutls_rnd (GNUTLS_RND_RANDOM, ps, psize);
      if (ret < 0)
	{
	  gnutls_assert ();
	  gnutls_free (edata);
	  return ret;
	}
      for (i = 0; i < psize; i++)
	while (ps[i] == 0)
	  {
	    ret = _gnutls_rnd (GNUTLS_RND_RANDOM, &ps[i], 1);
	    if (ret < 0)
	      {
		gnutls_assert ();
		gnutls_free (edata);
		return ret;
	      }
	  }
      break;
    case 1:
      /* using private key */

      if (params_len < RSA_PRIVATE_PARAMS)
	{
	  gnutls_assert ();
	  gnutls_free (edata);
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      for (i = 0; i < psize; i++)
	ps[i] = 0xff;
      break;
    default:
      gnutls_assert ();
      gnutls_free (edata);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ps[psize] = 0;
  memcpy (&ps[psize + 1], plaintext->data, plaintext->size);

  to_encrypt.data = edata;
  to_encrypt.size = k;

  if (btype == 2)		/* encrypt */
    ret =
      _gnutls_pk_encrypt (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params);
  else				/* sign */
    ret =
      _gnutls_pk_sign (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params);

  gnutls_free (edata);

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

  psize = encrypted.size;
  if (psize < k)
    {
      /* padding psize */
      pad = k - psize;
      psize = k;
    }
  else if (psize == k)
    {
      /* pad = 0; 
       * no need to do anything else
       */
      ciphertext->data = encrypted.data;
      ciphertext->size = encrypted.size;
      return 0;
    }
  else
    {				/* psize > k !!! */
      /* This is an impossible situation */
      gnutls_assert ();
      _gnutls_free_datum (&encrypted);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ciphertext->data = gnutls_malloc (psize);
  if (ciphertext->data == NULL)
    {
      gnutls_assert ();
      _gnutls_free_datum (&encrypted);
      return GNUTLS_E_MEMORY_ERROR;
    }

  memcpy (&ciphertext->data[pad], encrypted.data, encrypted.size);
  for (i = 0; i < pad; i++)
    ciphertext->data[i] = 0;

  ciphertext->size = k;

  _gnutls_free_datum (&encrypted);

  return 0;
}
Example #8
0
/**
 * gnutls_openpgp_privkey_sign_hash:
 * @key: Holds the key
 * @hash: holds the data to be signed
 * @signature: will contain newly allocated signature
 *
 * This function will sign the given hash using the private key.  You
 * should use gnutls_openpgp_privkey_set_preferred_key_id() before
 * calling this function to set the subkey to use.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Deprecated: Use gnutls_privkey_sign_hash() instead.
 */
int
gnutls_openpgp_privkey_sign_hash(gnutls_openpgp_privkey_t key,
				 const gnutls_datum_t * hash,
				 gnutls_datum_t * signature)
{
	int result;
	gnutls_pk_params_st params;
	int pk_algorithm;
	uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
	char buf[2 * GNUTLS_OPENPGP_KEYID_SIZE + 1];

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	result = gnutls_openpgp_privkey_get_preferred_key_id(key, keyid);
	if (result == 0) {
		uint32_t kid[2];
		int idx;

		KEYID_IMPORT(kid, keyid);

		_gnutls_hard_log("Signing using PGP key ID %s\n",
				 _gnutls_bin2hex(keyid,
						 GNUTLS_OPENPGP_KEYID_SIZE,
						 buf, sizeof(buf), NULL));

		idx = gnutls_openpgp_privkey_get_subkey_idx(key, keyid);
		pk_algorithm =
		    gnutls_openpgp_privkey_get_subkey_pk_algorithm(key,
								   idx,
								   NULL);
		result =
		    _gnutls_openpgp_privkey_get_mpis(key, kid, &params);
	} else {
		_gnutls_hard_log("Signing using master PGP key\n");

		pk_algorithm =
		    gnutls_openpgp_privkey_get_pk_algorithm(key, NULL);
		result =
		    _gnutls_openpgp_privkey_get_mpis(key, NULL, &params);
	}

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


	result = _gnutls_pk_sign(pk_algorithm, signature, hash, &params);

	gnutls_pk_params_clear(&params);
	gnutls_pk_params_release(&params);

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

	return 0;
}
Example #9
0
static int pct_test(gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* params)
{
int ret;
gnutls_datum_t sig = {NULL, 0};
const char const_data[20] = "onetwothreefourfive";
gnutls_datum_t ddata, tmp = {NULL,0};
char* gen_data = NULL;

	if (algo == GNUTLS_PK_DSA || algo == GNUTLS_PK_EC) {
		unsigned hash_len;

		_gnutls_dsa_q_to_hash(algo, params, &hash_len);
		gen_data = gnutls_malloc(hash_len);
		gnutls_rnd(GNUTLS_RND_NONCE, gen_data, hash_len);

		ddata.data = (void*)gen_data;
		ddata.size = hash_len;
	} else {
		ddata.data = (void*)const_data;
		ddata.size = sizeof(const_data);
	}

	switch (algo) {
	case GNUTLS_PK_RSA:
		ret = _gnutls_pk_encrypt(algo, &sig, &ddata, params);
		if (ret < 0) {
			ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
			goto cleanup;
		}

		if (ddata.size == sig.size && memcmp(ddata.data, sig.data, sig.size) == 0) {
			ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
			gnutls_assert();
			goto cleanup;
		}

		ret = _gnutls_pk_decrypt(algo, &tmp, &sig, params);
		if (ret < 0) {
			ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
			gnutls_assert();
			goto cleanup;
		}

		if (tmp.size != ddata.size || memcmp(tmp.data, ddata.data, tmp.size) != 0) {
			ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
			gnutls_assert();
			goto cleanup;
		}

		free(sig.data);
		sig.data = NULL;

		/* Here we don't know the purpose of the key. Check both
		 * signing and encryption.
		 */
	case GNUTLS_PK_EC: /* we only do keys for ECDSA */
	case GNUTLS_PK_DSA:
		ret = _gnutls_pk_sign(algo, &sig, &ddata, params);
		if (ret < 0) {
			ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
			goto cleanup;
		}

		ret = _gnutls_pk_verify(algo, &ddata, &sig, params);
		if (ret < 0) {
			ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
			gnutls_assert();
			goto cleanup;
		}
		break;

	default:
		ret = gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM);
		goto cleanup;
	}

	ret = 0;
cleanup:
	if (ret == GNUTLS_E_PK_GENERATION_ERROR) {
		_gnutls_switch_lib_state(LIB_STATE_ERROR);
	}
	gnutls_free(gen_data);
	gnutls_free(sig.data);
	gnutls_free(tmp.data);
	return ret;
}