예제 #1
0
/**
 * gnutls_privkey_sign_hash:
 * @signer: Holds the signer's key
 * @hash_algo: The hash algorithm used
 * @flags: Zero or one of %gnutls_privkey_flags_t
 * @hash_data: holds the data to be signed
 * @signature: will contain newly allocated signature
 *
 * 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-XXX for the DSA keys.
 *
 * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
 * the hash algorithm.
 *
 * Note that if %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA flag is specified this function
 * will ignore @hash_algo and perform a raw PKCS1 signature.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 2.12.0
 **/
int
gnutls_privkey_sign_hash(gnutls_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;

	if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
		return gnutls_privkey_sign_raw_data(signer, flags,
						    hash_data, signature);

	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, mac_to_entry(hash_algo),
			    &digest);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    gnutls_privkey_sign_raw_data(signer, flags, &digest,
					 signature);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = 0;

      cleanup:
	_gnutls_free_datum(&digest);
	return ret;
}
예제 #2
0
/**
 * gnutls_privkey_sign_data:
 * @signer: Holds the key
 * @hash: should be a digest algorithm
 * @flags: Zero or one of %gnutls_privkey_flags_t
 * @data: holds the data to be signed
 * @signature: will contain the signature allocate with gnutls_malloc()
 *
 * This function will sign the given 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 the SHA family for the DSA keys.
 *
 * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
 * the hash algorithm.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 * negative error value.
 *
 * Since: 2.12.0
 **/
int
gnutls_privkey_sign_data(gnutls_privkey_t signer,
			 gnutls_digest_algorithm_t hash,
			 unsigned int flags,
			 const gnutls_datum_t * data,
			 gnutls_datum_t * signature)
{
	int ret;
	gnutls_datum_t digest;
	const mac_entry_st *me = mac_to_entry(hash);

	if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

	ret = pk_hash_data(signer->pk_algorithm, me, NULL, data, &digest);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

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

	ret =
	    gnutls_privkey_sign_raw_data(signer, flags, &digest,
					 signature);
	_gnutls_free_datum(&digest);

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

	return 0;

      cleanup:
	_gnutls_free_datum(&digest);
	return ret;
}
예제 #3
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_soft_sign (signer->pk_algorithm, &signer->params,
                           &digest, signature);

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

  ret = 0;

cleanup:
  _gnutls_free_datum (&digest);
  return ret;
}
예제 #4
0
파일: gnutls_privkey.c 프로젝트: sqs/gnutls
/**
 * gnutls_privkey_sign_data:
 * @signer: Holds the key
 * @digest: should be a digest algorithm
 * @flags: should be 0 for now
 * @data: holds the data to be signed
 * @signature: will contain the signature allocate with gnutls_malloc()
 *
 * This function will sign the given 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 for the DSA keys.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 * negative error value.
 **/
int
gnutls_privkey_sign_data2 (gnutls_privkey_t signer,
                          gnutls_digest_algorithm_t hash,
                          unsigned int flags,
                          const gnutls_datum_t * data,
                          gnutls_datum_t * signature)
{
  int ret;
  gnutls_datum_t digest;

  ret = pk_hash_data (signer->pk_algorithm, hash, NULL, data, &digest);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

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

  ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
  _gnutls_free_datum (&digest);

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

  return 0;

cleanup:
  _gnutls_free_datum (&digest);
  return ret;
}
예제 #5
0
/* This will create a PKCS1 or DSA signature, as defined in the TLS protocol.
 * Cert is the certificate of the corresponding private key. It is only checked if
 * it supports signing.
 */
static int
sign_tls_hash(gnutls_session_t session, const mac_entry_st * hash_algo,
	      gnutls_pcert_st * cert, gnutls_privkey_t pkey,
	      const gnutls_datum_t * hash_concat,
	      gnutls_datum_t * signature)
{
	const version_entry_st *ver = get_version(session);
	unsigned int key_usage = 0;

	/* If our certificate supports signing
	 */
	if (cert != NULL) {
		gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);

		if (key_usage != 0)
			if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) {
				gnutls_assert();
				_gnutls_audit_log(session,
						  "Peer's certificate does not allow digital signatures. Key usage violation detected (ignored).\n");
			}

		/* External signing. Deprecated. To be removed. */
		if (!pkey) {
			int ret;

			if (!session->internals.sign_func)
				return
				    gnutls_assert_val
				    (GNUTLS_E_INSUFFICIENT_CREDENTIALS);

			if (!_gnutls_version_has_selectable_sighash(ver))
				return (*session->internals.sign_func)
				    (session,
				     session->internals.sign_func_userdata,
				     cert->type, &cert->cert, hash_concat,
				     signature);
			else {
				gnutls_datum_t digest;

				ret =
				    _gnutls_set_datum(&digest,
						      hash_concat->data,
						      hash_concat->size);
				if (ret < 0)
					return gnutls_assert_val(ret);

				ret =
				    pk_prepare_hash
				    (gnutls_pubkey_get_pk_algorithm
				     (cert->pubkey, NULL), hash_algo,
				     &digest);
				if (ret < 0) {
					gnutls_assert();
					goto es_cleanup;
				}

				ret = (*session->internals.sign_func)
				    (session,
				     session->internals.sign_func_userdata,
				     cert->type, &cert->cert, &digest,
				     signature);
			      es_cleanup:
				gnutls_free(digest.data);

				return ret;
			}
		}
	}

	if (!_gnutls_version_has_selectable_sighash(ver))
		return gnutls_privkey_sign_raw_data(pkey, 0, hash_concat,
						    signature);
	else
		return gnutls_privkey_sign_hash(pkey, 
						(gnutls_digest_algorithm_t)hash_algo->id,
						0, hash_concat, signature);
}
예제 #6
0
파일: pubkey.c 프로젝트: GostCrypt/GnuTLS
/**
 * cdk_pk_verify:
 * @pk: the public key
 * @sig: signature
 * @md: the message digest
 *
 * Verify the signature in @sig and compare it with the message digest in @md.
 **/
cdk_error_t
cdk_pk_verify(cdk_pubkey_t pk, cdk_pkt_signature_t sig, const byte * md)
{
	gnutls_datum_t s_sig = { NULL, 0 }, di = {
	NULL, 0};
	byte *encmd = NULL;
	cdk_error_t rc;
	int ret, algo;
	unsigned int i;
	gnutls_pk_params_st params;
	const mac_entry_st *me;

	if (!pk || !sig || !md) {
		gnutls_assert();
		return CDK_Inv_Value;
	}

	if (is_DSA(pk->pubkey_algo))
		algo = GNUTLS_PK_DSA;
	else if (is_RSA(pk->pubkey_algo))
		algo = GNUTLS_PK_RSA;
	else {
		gnutls_assert();
		return CDK_Inv_Value;
	}

	rc = sig_to_datum(&s_sig, sig);
	if (rc) {
		gnutls_assert();
		goto leave;
	}

	me = mac_to_entry(sig->digest_algo);
	rc = _gnutls_set_datum(&di, md, _gnutls_hash_get_algo_len(me));
	if (rc < 0) {
		rc = gnutls_assert_val(CDK_Out_Of_Core);
		goto leave;
	}

	rc = pk_prepare_hash(algo, me, &di);
	if (rc < 0) {
		rc = gnutls_assert_val(CDK_General_Error);
		goto leave;
	}

	params.params_nr = cdk_pk_get_npkey(pk->pubkey_algo);
	for (i = 0; i < params.params_nr; i++)
		params.params[i] = pk->mpi[i];
	params.flags = 0;
	ret = _gnutls_pk_verify(algo, &di, &s_sig, &params);

	if (ret < 0) {
		gnutls_assert();
		rc = map_gnutls_error(ret);
		goto leave;
	}

	rc = 0;

      leave:
	_gnutls_free_datum(&s_sig);
	_gnutls_free_datum(&di);
	cdk_free(encmd);
	return rc;
}