* Version 3.1.0 (unreleased)
+** libgnutls: Use the PKCS #1 1.5 encoding provided by nettle (2.5)
+for encryption and signatures.
+
** libgnutls: When decoding a PKCS #11 URL the pin-source field
is assumed to be a file that stores the pin. Based on patch
by David Smith.
in pkcs12 decoding tests.
** API and ABI modifications:
-No changes since last version.
+gnutls_pubkey_verify_hash2: Added
* Version 3.0.18 (released 2012-04-02)
signature verification operations with the underlying keys.
@showfuncdesc{gnutls_pubkey_verify_data2}
-@showfuncdesc{gnutls_pubkey_verify_hash}
+@showfuncdesc{gnutls_pubkey_verify_hash2}
@showfuncdesc{gnutls_pubkey_encrypt_data}
@showfuncdesc{gnutls_privkey_sign_data}
_gnutls_pubkey_get_mpis (gnutls_pubkey_t key,
gnutls_pk_params_st * params);
-int pubkey_verify_hashed_data (gnutls_pk_algorithm_t pk,
- const gnutls_datum_t * hash,
- const gnutls_datum_t * signature,
- gnutls_pk_params_st * issuer_params);
+int
+pubkey_verify_hashed_data (gnutls_pk_algorithm_t pk,
+ gnutls_digest_algorithm_t algo,
+ const gnutls_datum_t * hash,
+ const gnutls_datum_t * signature,
+ gnutls_pk_params_st * issuer_params);
int pubkey_verify_data (gnutls_pk_algorithm_t pk,
gnutls_digest_algorithm_t algo,
/* Functions for sign algorithms. */
gnutls_sign_algorithm_t _gnutls_x509_oid2sign_algorithm (const char *oid);
-gnutls_sign_algorithm_t _gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk,
- gnutls_digest_algorithm_t mac);
gnutls_pk_algorithm_t _gnutls_x509_sign_to_pk (gnutls_sign_algorithm_t sign);
const char *_gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t,
gnutls_digest_algorithm_t mac);
/**
* gnutls_sign_get_id:
- * @name: is a MAC algorithm name
+ * @name: is a sign algorithm name
*
* The names are compared in a case insensitive way.
*
* Returns: return a #gnutls_sign_algorithm_t value corresponding to
- * the specified cipher, or %GNUTLS_SIGN_UNKNOWN on error.
+ * the specified algorithm, or %GNUTLS_SIGN_UNKNOWN on error.
**/
gnutls_sign_algorithm_t
gnutls_sign_get_id (const char *name)
return ret;
}
+/**
+ * gnutls_pk_to_sign:
+ * @pk: is a public key algorithm
+ * @hash: a hash algorithm
+ *
+ * This function maps public key and hash algorithms combinations
+ * to signature algorithms.
+ *
+ * Returns: return a #gnutls_sign_algorithm_t value, or %GNUTLS_SIGN_UNKNOWN on error.
+ **/
gnutls_sign_algorithm_t
-_gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t mac)
+gnutls_pk_to_sign (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
{
gnutls_sign_algorithm_t ret = 0;
- GNUTLS_SIGN_LOOP (if (pk == p->pk && mac == p->mac)
+ GNUTLS_SIGN_LOOP (if (pk == p->pk && hash == p->mac)
{
ret = p->id; break;}
);
gnutls_sign_algorithm_t sign;
const char *ret = NULL;
- sign = _gnutls_x509_pk_to_sign (pk, mac);
+ sign = gnutls_pk_to_sign (pk, mac);
if (sign == GNUTLS_SIGN_UNKNOWN)
return NULL;
}
ret =
- _gnutls_pkcs1_rsa_encrypt (&sdata, &session->key->key,
- ¶ms, 2);
+ _gnutls_pk_encrypt (GNUTLS_PK_RSA, &sdata, &session->key->key,
+ ¶ms);
gnutls_pk_params_release(¶ms);
return ret;
}
- ret = _gnutls_pkcs1_rsa_decrypt (&plaintext, &ciphertext, params, 2); /* btype==2 */
+ ret = _gnutls_pk_decrypt (GNUTLS_PK_RSA, &plaintext, &ciphertext, params);
if (ret < 0 || plaintext.size != GNUTLS_MASTER_SIZE)
{
const gnutls_datum_t * data,
const gnutls_pk_params_st * priv);
int (*verify) (gnutls_pk_algorithm_t, const gnutls_datum_t * data,
- const gnutls_datum_t * signature,
+ const gnutls_datum_t * sig,
const gnutls_pk_params_st * pub);
+ /* given a signature and the public parameters,
+ * suggest a hash algorithm */
+ int (*hash_algorithm) (gnutls_pk_algorithm_t,
+ const gnutls_datum_t * sig,
+ gnutls_pk_params_st * issuer_params,
+ gnutls_digest_algorithm_t*);
+ /* sanity checks the public key parameters */
int (*verify_params) (gnutls_pk_algorithm_t,
const gnutls_pk_params_st * pub);
int (*generate) (gnutls_pk_algorithm_t, unsigned int nbits,
#include "gnutls_int.h"
#include "gnutls_errors.h"
#include "gnutls_num.h"
+#include <gnutls/gnutls.h>
#include <ext/signature.h>
#include <gnutls_state.h>
#include <gnutls_num.h>
|| priv->sign_algorithms_size == 0)
/* none set, allow SHA-1 only */
{
- return _gnutls_x509_pk_to_sign (cert_algo, GNUTLS_DIG_SHA1);
+ return gnutls_pk_to_sign (cert_algo, GNUTLS_DIG_SHA1);
}
for (i = 0; i < priv->sign_algorithms_size; i++)
#include <x509/common.h>
#include <random.h>
-/* Do PKCS-1 RSA encryption.
- * params is modulus, public exp.
- */
-int
-_gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
- const gnutls_datum_t * plaintext,
- gnutls_pk_params_st * params,
- unsigned btype)
-{
- unsigned int i, pad;
- int ret;
- uint8_t *edata, *ps;
- size_t k, psize;
- size_t mod_bits;
- gnutls_datum_t to_encrypt, encrypted;
-
- mod_bits = _gnutls_mpi_get_nbits (params->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->params_nr < 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->params_nr < 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, params);
- else /* sign */
- ret =
- _gnutls_pk_sign (GNUTLS_PK_RSA, &encrypted, &to_encrypt, 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 ();
- ret = GNUTLS_E_MEMORY_ERROR;
- goto cleanup;
- }
-
- memcpy (&ciphertext->data[pad], encrypted.data, encrypted.size);
- for (i = 0; i < pad; i++)
- ciphertext->data[i] = 0;
-
- ciphertext->size = k;
-
- ret = 0;
-
-cleanup:
- _gnutls_free_datum (&encrypted);
-
- return ret;
-}
-
-
-/* Do PKCS-1 RSA decryption.
- * params is modulus, public exp., private key
- * Can decrypt block type 1 and type 2 packets.
- */
-int
-_gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
- const gnutls_datum_t * ciphertext,
- gnutls_pk_params_st* params,
- unsigned btype)
-{
- unsigned int k, i;
- int ret;
- size_t esize, mod_bits;
-
- mod_bits = _gnutls_mpi_get_nbits (params->params[0]);
- k = mod_bits / 8;
- if (mod_bits % 8 != 0)
- k++;
-
- esize = ciphertext->size;
-
- if (esize != k)
- {
- gnutls_assert ();
- return GNUTLS_E_PK_DECRYPTION_FAILED;
- }
-
- /* we can use btype to see if the private key is
- * available.
- */
- if (btype == 2)
- {
- ret =
- _gnutls_pk_decrypt (GNUTLS_PK_RSA, plaintext, ciphertext, params);
- }
- else
- {
- ret =
- _gnutls_pk_encrypt (GNUTLS_PK_RSA, plaintext, ciphertext, params);
- }
-
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- /* EB = 00||BT||PS||00||D
- * (use block type 'btype')
- *
- * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
- * avoid attacks similar to the one described by Bleichenbacher in:
- * "Chosen Ciphertext Attacks against Protocols Based on RSA
- * Encryption Standard PKCS #1".
- */
- if (plaintext->data[0] != 0 || plaintext->data[1] != btype)
- {
- gnutls_assert ();
- _gnutls_free_datum (plaintext);
- return GNUTLS_E_DECRYPTION_FAILED;
- }
-
- ret = GNUTLS_E_DECRYPTION_FAILED;
- switch (btype)
- {
- case 2:
- for (i = 2; i < plaintext->size; i++)
- {
- if (plaintext->data[i] == 0)
- {
- ret = 0;
- break;
- }
- }
- break;
- case 1:
- for (i = 2; i < plaintext->size; i++)
- {
- if (plaintext->data[i] == 0 && i > 2)
- {
- ret = 0;
- break;
- }
- if (plaintext->data[i] != 0xff)
- {
- _gnutls_handshake_log ("PKCS #1 padding error");
- _gnutls_free_datum (plaintext);
- /* PKCS #1 padding error. Don't use
- GNUTLS_E_PKCS1_WRONG_PAD here. */
- break;
- }
- }
- break;
- default:
- gnutls_assert ();
- _gnutls_free_datum (plaintext);
- break;
- }
-
- if (ret < 0)
- {
- gnutls_assert ();
- _gnutls_free_datum (plaintext);
- return GNUTLS_E_DECRYPTION_FAILED;
- }
-
- i++;
- memmove (plaintext->data, &plaintext->data[i], esize - i);
- plaintext->size = esize - i;
-
- return 0;
-}
-
-
-int
-_gnutls_rsa_verify (const gnutls_datum_t * vdata,
- const gnutls_datum_t * ciphertext,
- gnutls_pk_params_st * params,
- int btype)
-{
-
- gnutls_datum_t plain;
- int ret;
-
- /* decrypt signature */
- if ((ret =
- _gnutls_pkcs1_rsa_decrypt (&plain, ciphertext, params,
- btype)) < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- if (plain.size != vdata->size)
- {
- gnutls_assert ();
- _gnutls_free_datum (&plain);
- return GNUTLS_E_PK_SIG_VERIFY_FAILED;
- }
-
- if (memcmp (plain.data, vdata->data, plain.size) != 0)
- {
- gnutls_assert ();
- _gnutls_free_datum (&plain);
- return GNUTLS_E_PK_SIG_VERIFY_FAILED;
- }
-
- _gnutls_free_datum (&plain);
-
- return 0; /* ok */
-}
-
/* encodes the Dss-Sig-Value structure
*/
int
NULL, pk, params);
}
+
+/* Writes the digest information and the digest in a DER encoded
+ * structure. The digest info is allocated and stored into the info structure.
+ */
+int
+encode_ber_digest_info (gnutls_digest_algorithm_t hash,
+ const gnutls_datum_t * digest,
+ gnutls_datum_t * output)
+{
+ ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
+ int result;
+ const char *algo;
+ uint8_t *tmp_output;
+ int tmp_output_size;
+
+ algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash);
+ if (algo == NULL)
+ {
+ gnutls_assert ();
+ _gnutls_debug_log ("Hash algorithm: %d has no OID\n", hash);
+ return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
+ }
+
+ if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
+ "GNUTLS.DigestInfo",
+ &dinfo)) != ASN1_SUCCESS)
+ {
+ gnutls_assert ();
+ return _gnutls_asn2err (result);
+ }
+
+ result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1);
+ if (result != ASN1_SUCCESS)
+ {
+ gnutls_assert ();
+ asn1_delete_structure (&dinfo);
+ return _gnutls_asn2err (result);
+ }
+
+ /* Write an ASN.1 NULL in the parameters field. This matches RFC
+ 3279 and RFC 4055, although is arguable incorrect from a historic
+ perspective (see those documents for more information).
+ Regardless of what is correct, this appears to be what most
+ implementations do. */
+ result = asn1_write_value (dinfo, "digestAlgorithm.parameters",
+ ASN1_NULL, ASN1_NULL_SIZE);
+ if (result != ASN1_SUCCESS)
+ {
+ gnutls_assert ();
+ asn1_delete_structure (&dinfo);
+ return _gnutls_asn2err (result);
+ }
+
+ result = asn1_write_value (dinfo, "digest", digest->data, digest->size);
+ if (result != ASN1_SUCCESS)
+ {
+ gnutls_assert ();
+ asn1_delete_structure (&dinfo);
+ return _gnutls_asn2err (result);
+ }
+
+ tmp_output_size = 0;
+ asn1_der_coding (dinfo, "", NULL, &tmp_output_size, NULL);
+
+ tmp_output = gnutls_malloc (tmp_output_size);
+ if (tmp_output == NULL)
+ {
+ gnutls_assert ();
+ asn1_delete_structure (&dinfo);
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ result = asn1_der_coding (dinfo, "", tmp_output, &tmp_output_size, NULL);
+ if (result != ASN1_SUCCESS)
+ {
+ gnutls_assert ();
+ asn1_delete_structure (&dinfo);
+ return _gnutls_asn2err (result);
+ }
+
+ asn1_delete_structure (&dinfo);
+
+ output->size = tmp_output_size;
+ output->data = tmp_output;
+
+ return 0;
+}
+
+/* Reads the digest information.
+ * we use DER here, although we should use BER. It works fine
+ * anyway.
+ */
+int
+decode_ber_digest_info (const gnutls_datum_t * info,
+ gnutls_digest_algorithm_t * hash,
+ uint8_t * digest, unsigned int *digest_size)
+{
+ ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
+ int result;
+ char str[1024];
+ int len;
+
+ if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
+ "GNUTLS.DigestInfo",
+ &dinfo)) != ASN1_SUCCESS)
+ {
+ gnutls_assert ();
+ return _gnutls_asn2err (result);
+ }
+
+ result = asn1_der_decoding (&dinfo, info->data, info->size, NULL);
+ if (result != ASN1_SUCCESS)
+ {
+ gnutls_assert ();
+ asn1_delete_structure (&dinfo);
+ return _gnutls_asn2err (result);
+ }
+
+ len = sizeof (str) - 1;
+ result = asn1_read_value (dinfo, "digestAlgorithm.algorithm", str, &len);
+ if (result != ASN1_SUCCESS)
+ {
+ gnutls_assert ();
+ asn1_delete_structure (&dinfo);
+ return _gnutls_asn2err (result);
+ }
+
+ *hash = _gnutls_x509_oid_to_digest (str);
+
+ if (*hash == GNUTLS_DIG_UNKNOWN)
+ {
+
+ _gnutls_debug_log ("verify.c: HASH OID: %s\n", str);
+
+ gnutls_assert ();
+ asn1_delete_structure (&dinfo);
+ return GNUTLS_E_UNKNOWN_ALGORITHM;
+ }
+
+ len = sizeof (str) - 1;
+ result = asn1_read_value (dinfo, "digestAlgorithm.parameters", str, &len);
+ /* To avoid permitting garbage in the parameters field, either the
+ parameters field is not present, or it contains 0x05 0x00. */
+ if (!(result == ASN1_ELEMENT_NOT_FOUND ||
+ (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
+ memcmp (str, ASN1_NULL, ASN1_NULL_SIZE) == 0)))
+ {
+ gnutls_assert ();
+ asn1_delete_structure (&dinfo);
+ return GNUTLS_E_ASN1_GENERIC_ERROR;
+ }
+
+ len = *digest_size;
+ result = asn1_read_value (dinfo, "digest", digest, &len);
+
+ if (result != ASN1_SUCCESS)
+ {
+ gnutls_assert ();
+ *digest_size = len;
+ asn1_delete_structure (&dinfo);
+ return _gnutls_asn2err (result);
+ }
+
+ *digest_size = len;
+ asn1_delete_structure (&dinfo);
+
+ return 0;
+}
+
#define _gnutls_pk_verify_params( algo, params) _gnutls_pk_ops.verify_params( algo, params)
#define _gnutls_pk_derive( algo, out, pub, priv) _gnutls_pk_ops.derive( algo, out, pub, priv)
#define _gnutls_pk_generate( algo, bits, priv) _gnutls_pk_ops.generate( algo, bits, priv)
+#define _gnutls_pk_hash_algorithm( pk, sig, params, hash) _gnutls_pk_ops.hash_algorithm(pk, sig, params, hash)
inline static int
_gnutls_pk_fixup (gnutls_pk_algorithm_t algo, gnutls_direction_t direction,
int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, const gnutls_pk_params_st * src);
/* The internal PK interface */
-int _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
- const gnutls_datum_t * plaintext,
- gnutls_pk_params_st * params,
- unsigned btype);
-int _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
- const gnutls_datum_t * ciphertext,
- gnutls_pk_params_st* params,
- unsigned btype);
-int _gnutls_rsa_verify (const gnutls_datum_t * vdata,
- const gnutls_datum_t * ciphertext,
- gnutls_pk_params_st*,
- int btype);
-
int
_gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s);
_gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r,
bigint_t * s);
+int
+encode_ber_digest_info (gnutls_digest_algorithm_t hash,
+ const gnutls_datum_t * digest,
+ gnutls_datum_t * output);
+
+int
+decode_ber_digest_info (const gnutls_datum_t * info,
+ gnutls_digest_algorithm_t * hash,
+ uint8_t * digest, unsigned int *digest_size);
+
int _gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk,
gnutls_pk_params_st*,
gnutls_digest_algorithm_t * dig,
* together with a hash functions. Different hash functions may be
* used for the RSA algorithm, but only the SHA family for the DSA keys.
*
- * Use gnutls_pubkey_get_preferred_hash_algorithm() to determine
+ * 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
* together with a hash functions. Different hash functions may be
* used for the RSA algorithm, but only SHA-XXX for the DSA keys.
*
- * Use gnutls_pubkey_get_preferred_hash_algorithm() to determine
+ * 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
hash, signature);
#endif
case GNUTLS_PRIVKEY_X509:
- return _gnutls_soft_sign (key->key.x509->pk_algorithm,
- &key->key.x509->params,
- hash, signature);
+ return _gnutls_pk_sign (key->key.x509->pk_algorithm,
+ signature, hash, &key->key.x509->params);
case GNUTLS_PRIVKEY_EXT:
if (key->key.ext.sign_func == NULL)
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
const gnutls_datum_t * ciphertext,
gnutls_datum_t * plaintext)
{
- if (key->pk_algorithm != GNUTLS_PK_RSA)
- {
- gnutls_assert ();
- return GNUTLS_E_INVALID_REQUEST;
- }
-
switch (key->type)
{
#ifdef ENABLE_OPENPGP
case GNUTLS_PRIVKEY_OPENPGP:
return _gnutls_openpgp_privkey_decrypt_data (key->key.openpgp, flags,
- ciphertext, plaintext);
+ ciphertext, plaintext);
#endif
case GNUTLS_PRIVKEY_X509:
- return _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext,
- &key->key.x509->params,
- 2);
+ return _gnutls_pk_decrypt (key->pk_algorithm, plaintext, ciphertext,
+ &key->key.x509->params);
#ifdef ENABLE_PKCS11
case GNUTLS_PRIVKEY_PKCS11:
return _gnutls_pkcs11_privkey_decrypt_data (key->key.pkcs11,
/*
- * GnuTLS PKCS#11 support
+ * GnuTLS public key support
* Copyright (C) 2010-2012 Free Software Foundation, Inc.
*
* Author: Nikos Mavrogiannopoulos
* parameters from the certificate.
*
* Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
- * is returned, and zero or positive code on success.
+ * is returned, and zero or positive code on success. Use gnutls_pubkey_verify_data2()
+ * instead of this function.
*
* Since: 2.12.0
**/
**/
int
gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey,
- gnutls_sign_algorithm_t algo,
- unsigned int flags,
- const gnutls_datum_t * data,
- const gnutls_datum_t * signature)
+ gnutls_sign_algorithm_t algo,
+ unsigned int flags,
+ const gnutls_datum_t * data,
+ const gnutls_datum_t * signature)
{
int ret;
return GNUTLS_E_INVALID_REQUEST;
}
- ret = pubkey_verify_data( pubkey->pk_algorithm, _gnutls_sign_get_hash_algorithm(algo), data, signature,
- &pubkey->params);
+ ret = pubkey_verify_data( pubkey->pk_algorithm, _gnutls_sign_get_hash_algorithm(algo),
+ data, signature, &pubkey->params);
if (ret < 0)
{
gnutls_assert();
* @signature: contains the signature
*
* This function will verify the given signed digest, using the
- * parameters from the public key.
+ * parameters from the public key. Use gnutls_pubkey_verify_hash2()
+ * instead of this function.
*
* Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
* is returned, and zero or positive code on success.
gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags,
const gnutls_datum_t * hash,
const gnutls_datum_t * signature)
+{
+gnutls_digest_algorithm_t algo;
+int ret;
+
+ ret = gnutls_pubkey_get_verify_algorithm (key, signature, &algo);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ return gnutls_pubkey_verify_hash2(key, gnutls_pk_to_sign(key->pk_algorithm, algo),
+ flags, hash, signature);
+}
+
+/**
+ * gnutls_pubkey_verify_hash2:
+ * @key: Holds the public key
+ * @algo: The signature algorithm used
+ * @flags: should be 0 for now
+ * @hash: holds the hash digest to be verified
+ * @signature: contains the signature
+ *
+ * This function will verify the given signed digest, using the
+ * parameters from the public key.
+ *
+ * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
+ * is returned, and zero or positive code on success.
+ *
+ * Since: 3.0
+ **/
+int
+gnutls_pubkey_verify_hash2 (gnutls_pubkey_t key,
+ gnutls_sign_algorithm_t algo,
+ unsigned int flags,
+ const gnutls_datum_t * hash,
+ const gnutls_datum_t * signature)
{
if (key == NULL)
{
}
if (flags & GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA)
- return _gnutls_rsa_verify (hash, signature, &key->params, 1);
+ return _gnutls_pk_verify (GNUTLS_PK_RSA, hash, signature, &key->params);
else
{
- return pubkey_verify_hashed_data (key->pk_algorithm, hash, signature,
- &key->params);
+ return pubkey_verify_hashed_data (key->pk_algorithm, _gnutls_sign_get_hash_algorithm(algo),
+ hash, signature, &key->params);
}
}
**/
int
gnutls_pubkey_encrypt_data (gnutls_pubkey_t key, unsigned int flags,
- const gnutls_datum_t * plaintext,
- gnutls_datum_t * ciphertext)
+ const gnutls_datum_t * plaintext,
+ gnutls_datum_t * ciphertext)
{
- if (key == NULL || key->pk_algorithm != GNUTLS_PK_RSA)
+ if (key == NULL)
{
gnutls_assert ();
return GNUTLS_E_INVALID_REQUEST;
}
- return _gnutls_pkcs1_rsa_encrypt (ciphertext, plaintext,
- &key->params,
- 2);
+ return _gnutls_pk_encrypt (key->pk_algorithm, ciphertext,
+ plaintext, &key->params);
}
/**
* params[1] is public key
*/
static int
-_pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
+_pkcs1_rsa_verify_sig (gnutls_digest_algorithm_t hash,
+ const gnutls_datum_t * text,
const gnutls_datum_t * prehash,
const gnutls_datum_t * signature,
gnutls_pk_params_st * params)
{
- gnutls_digest_algorithm_t hash = GNUTLS_DIG_UNKNOWN;
int ret;
- uint8_t digest[MAX_HASH_SIZE], md[MAX_HASH_SIZE], *cmp;
+ uint8_t md[MAX_HASH_SIZE], *cmp;
unsigned int digest_size;
+ gnutls_datum_t d, di;
digest_hd_st hd;
- gnutls_datum_t decrypted;
- ret =
- _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, 1);
- if (ret < 0)
+ digest_size = _gnutls_hash_get_algo_len (hash);
+ if (prehash)
{
- 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->data == NULL || prehash->size != digest_size)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- if (prehash && prehash->data && prehash->size == digest_size)
- {
cmp = prehash->data;
}
else
cmp = md;
}
+
+ d.data = cmp;
+ d.size = digest_size;
- if (memcmp (cmp, digest, digest_size) != 0)
- {
- gnutls_assert ();
- return GNUTLS_E_PK_SIG_VERIFY_FAILED;
- }
+ /* decrypted is a BER encoded data of type DigestInfo
+ */
- return 0;
+ ret = encode_ber_digest_info (hash, &d, &di);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = _gnutls_pk_verify (GNUTLS_PK_RSA, &di, signature, params);
+
+ _gnutls_free_datum (&di);
+
+ return ret;
}
/* Hashes input data and verifies a signature.
*/
static int
-dsa_verify_hashed_data (const gnutls_datum_t * hash,
+dsa_verify_hashed_data (gnutls_pk_algorithm_t pk,
+ gnutls_digest_algorithm_t algo,
+ const gnutls_datum_t * hash,
const gnutls_datum_t * signature,
- gnutls_pk_algorithm_t pk,
gnutls_pk_params_st* params)
{
gnutls_datum_t digest;
- unsigned int algo;
unsigned int hash_len;
- algo = _gnutls_dsa_q_to_hash (pk, params, &hash_len);
+ if (algo == GNUTLS_DIG_UNKNOWN)
+ algo = _gnutls_dsa_q_to_hash (pk, params, &hash_len);
+ else hash_len = _gnutls_hash_get_algo_len(algo);
/* SHA1 or better allowed */
if (!hash->data || hash->size < hash_len)
*/
int
pubkey_verify_hashed_data (gnutls_pk_algorithm_t pk,
- const gnutls_datum_t * hash,
- const gnutls_datum_t * signature,
- gnutls_pk_params_st * issuer_params)
+ gnutls_digest_algorithm_t hash_algo,
+ const gnutls_datum_t * hash,
+ const gnutls_datum_t * signature,
+ gnutls_pk_params_st * issuer_params)
{
switch (pk)
case GNUTLS_PK_RSA:
if (_pkcs1_rsa_verify_sig
- (NULL, hash, signature, issuer_params) != 0)
+ (hash_algo, NULL, hash, signature, issuer_params) != 0)
{
gnutls_assert ();
return GNUTLS_E_PK_SIG_VERIFY_FAILED;
case GNUTLS_PK_EC:
case GNUTLS_PK_DSA:
- if (dsa_verify_hashed_data(hash, signature, pk, issuer_params) != 0)
+ if (dsa_verify_hashed_data(pk, hash_algo, hash, signature, issuer_params) != 0)
{
gnutls_assert ();
return GNUTLS_E_PK_SIG_VERIFY_FAILED;
*/
int
pubkey_verify_data (gnutls_pk_algorithm_t pk,
- gnutls_digest_algorithm_t algo,
+ gnutls_digest_algorithm_t hash_algo,
const gnutls_datum_t * data,
const gnutls_datum_t * signature,
gnutls_pk_params_st * issuer_params)
case GNUTLS_PK_RSA:
if (_pkcs1_rsa_verify_sig
- (data, NULL, signature, issuer_params) != 0)
+ (hash_algo, data, NULL, signature, issuer_params) != 0)
{
gnutls_assert ();
return GNUTLS_E_PK_SIG_VERIFY_FAILED;
case GNUTLS_PK_EC:
case GNUTLS_PK_DSA:
- if (dsa_verify_data(pk, algo, data, signature, issuer_params) != 0)
+ if (dsa_verify_data(pk, hash_algo, data, signature, issuer_params) != 0)
{
gnutls_assert ();
return GNUTLS_E_PK_SIG_VERIFY_FAILED;
const gnutls_datum_t * hash_concat,
gnutls_datum_t * signature);
-static int
-encode_ber_digest_info (gnutls_digest_algorithm_t hash,
- const gnutls_datum_t * digest,
- gnutls_datum_t * output);
/* While this is currently equal to the length of RSA/SHA512
* signature, it should also be sufficient for DSS signature and any
}
-
-/* This will create a PKCS1 or DSA signature, using the given parameters, and the
- * given data. The output will be allocated and be put in signature.
- */
-int
-_gnutls_soft_sign (gnutls_pk_algorithm_t algo, gnutls_pk_params_st * params,
- const gnutls_datum_t * data,
- gnutls_datum_t * signature)
-{
- int ret;
-
- switch (algo)
- {
- case GNUTLS_PK_RSA:
- /* encrypt */
- if ((ret = _gnutls_pkcs1_rsa_encrypt (signature, data, params, 1)) < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- break;
- default:
- ret = _gnutls_pk_sign( algo, signature, data, params);
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
- break;
- }
-
- return 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
verify_tls_hash (gnutls_protocol_t ver, gnutls_pcert_st* cert,
- const gnutls_datum_t * hash_concat,
- gnutls_datum_t * signature, size_t sha1pos,
- gnutls_pk_algorithm_t pk_algo)
+ const gnutls_datum_t * hash_concat,
+ gnutls_datum_t * signature, size_t sha1pos,
+ gnutls_sign_algorithm_t sign_algo,
+ gnutls_pk_algorithm_t pk_algo)
{
int ret;
gnutls_datum_t vdata;
flags = GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA;
else
flags = 0;
-
-
break;
case GNUTLS_PK_DSA:
case GNUTLS_PK_EC:
-
vdata.data = &hash_concat->data[sha1pos];
vdata.size = hash_concat->size - sha1pos;
return GNUTLS_E_INTERNAL_ERROR;
}
- ret = gnutls_pubkey_verify_hash(cert->pubkey, flags, &vdata,
- signature);
+ ret = gnutls_pubkey_verify_hash2(cert->pubkey, sign_algo, flags,
+ &vdata, signature);
if (ret < 0)
return gnutls_assert_val(ret);
_gnutls_handshake_verify_data (gnutls_session_t session, gnutls_pcert_st* cert,
const gnutls_datum_t * params,
gnutls_datum_t * signature,
- gnutls_sign_algorithm_t algo)
+ gnutls_sign_algorithm_t sign_algo)
{
gnutls_datum_t dconcat;
int ret;
if (_gnutls_version_has_selectable_sighash (ver))
{
_gnutls_handshake_log ("HSK[%p]: verify handshake data: using %s\n",
- session, gnutls_sign_algorithm_get_name (algo));
+ session, gnutls_sign_algorithm_get_name (sign_algo));
- ret = _gnutls_pubkey_compatible_with_sig(cert->pubkey, ver, algo);
+ ret = _gnutls_pubkey_compatible_with_sig(cert->pubkey, ver, sign_algo);
if (ret < 0)
return gnutls_assert_val(ret);
- ret = _gnutls_session_sign_algo_enabled (session, algo);
+ ret = _gnutls_session_sign_algo_enabled (session, sign_algo);
if (ret < 0)
return gnutls_assert_val(ret);
- hash_algo = _gnutls_sign_get_hash_algorithm (algo);
+ hash_algo = _gnutls_sign_get_hash_algorithm (sign_algo);
}
else
{
ret = verify_tls_hash (ver, cert, &dconcat, signature,
dconcat.size -
_gnutls_hash_get_algo_len (hash_algo),
- _gnutls_sign_get_pk_algorithm (algo));
+ sign_algo,
+ _gnutls_sign_get_pk_algorithm (sign_algo));
if (ret < 0)
{
gnutls_assert ();
dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
ret =
- verify_tls_hash (ver, cert, &dconcat, signature, 0, pk);
+ verify_tls_hash (ver, cert, &dconcat, signature, 0, sign_algo, pk);
if (ret < 0)
{
gnutls_assert ();
if (_gnutls_version_has_selectable_sighash(ver))
return _gnutls_handshake_verify_crt_vrfy12 (session, cert, signature,
- sign_algo);
+ sign_algo);
ret =
_gnutls_hash_init (&td_md5, GNUTLS_DIG_MD5);
ret =
verify_tls_hash (ver, cert, &dconcat, signature, 16,
- gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL));
+ GNUTLS_SIGN_UNKNOWN,
+ gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL));
if (ret < 0)
{
gnutls_assert ();
return 0;
}
-/* Reads the digest information.
- * we use DER here, although we should use BER. It works fine
- * anyway.
- */
-int
-decode_ber_digest_info (const gnutls_datum_t * info,
- gnutls_digest_algorithm_t * hash,
- uint8_t * digest, unsigned int *digest_size)
-{
- ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
- int result;
- char str[1024];
- int len;
-
- if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
- "GNUTLS.DigestInfo",
- &dinfo)) != ASN1_SUCCESS)
- {
- gnutls_assert ();
- return _gnutls_asn2err (result);
- }
-
- result = asn1_der_decoding (&dinfo, info->data, info->size, NULL);
- if (result != ASN1_SUCCESS)
- {
- gnutls_assert ();
- asn1_delete_structure (&dinfo);
- return _gnutls_asn2err (result);
- }
-
- len = sizeof (str) - 1;
- result = asn1_read_value (dinfo, "digestAlgorithm.algorithm", str, &len);
- if (result != ASN1_SUCCESS)
- {
- gnutls_assert ();
- asn1_delete_structure (&dinfo);
- return _gnutls_asn2err (result);
- }
-
- *hash = _gnutls_x509_oid_to_digest (str);
-
- if (*hash == GNUTLS_DIG_UNKNOWN)
- {
-
- _gnutls_debug_log ("verify.c: HASH OID: %s\n", str);
-
- gnutls_assert ();
- asn1_delete_structure (&dinfo);
- return GNUTLS_E_UNKNOWN_ALGORITHM;
- }
-
- len = sizeof (str) - 1;
- result = asn1_read_value (dinfo, "digestAlgorithm.parameters", str, &len);
- /* To avoid permitting garbage in the parameters field, either the
- parameters field is not present, or it contains 0x05 0x00. */
- if (!(result == ASN1_ELEMENT_NOT_FOUND ||
- (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
- memcmp (str, ASN1_NULL, ASN1_NULL_SIZE) == 0)))
- {
- gnutls_assert ();
- asn1_delete_structure (&dinfo);
- return GNUTLS_E_ASN1_GENERIC_ERROR;
- }
-
- len = *digest_size;
- result = asn1_read_value (dinfo, "digest", digest, &len);
-
- if (result != ASN1_SUCCESS)
- {
- gnutls_assert ();
- *digest_size = len;
- asn1_delete_structure (&dinfo);
- return _gnutls_asn2err (result);
- }
-
- *digest_size = len;
- asn1_delete_structure (&dinfo);
-
- return 0;
-}
-
-/* Writes the digest information and the digest in a DER encoded
- * structure. The digest info is allocated and stored into the info structure.
- */
-static int
-encode_ber_digest_info (gnutls_digest_algorithm_t hash,
- const gnutls_datum_t * digest,
- gnutls_datum_t * output)
-{
- ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
- int result;
- const char *algo;
- uint8_t *tmp_output;
- int tmp_output_size;
-
- algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash);
- if (algo == NULL)
- {
- gnutls_assert ();
- _gnutls_debug_log ("Hash algorithm: %d has no OID\n", hash);
- return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
- }
-
- if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
- "GNUTLS.DigestInfo",
- &dinfo)) != ASN1_SUCCESS)
- {
- gnutls_assert ();
- return _gnutls_asn2err (result);
- }
-
- result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1);
- if (result != ASN1_SUCCESS)
- {
- gnutls_assert ();
- asn1_delete_structure (&dinfo);
- return _gnutls_asn2err (result);
- }
-
- /* Write an ASN.1 NULL in the parameters field. This matches RFC
- 3279 and RFC 4055, although is arguable incorrect from a historic
- perspective (see those documents for more information).
- Regardless of what is correct, this appears to be what most
- implementations do. */
- result = asn1_write_value (dinfo, "digestAlgorithm.parameters",
- ASN1_NULL, ASN1_NULL_SIZE);
- if (result != ASN1_SUCCESS)
- {
- gnutls_assert ();
- asn1_delete_structure (&dinfo);
- return _gnutls_asn2err (result);
- }
-
- result = asn1_write_value (dinfo, "digest", digest->data, digest->size);
- if (result != ASN1_SUCCESS)
- {
- gnutls_assert ();
- asn1_delete_structure (&dinfo);
- return _gnutls_asn2err (result);
- }
-
- tmp_output_size = 0;
- asn1_der_coding (dinfo, "", NULL, &tmp_output_size, NULL);
-
- tmp_output = gnutls_malloc (tmp_output_size);
- if (output->data == NULL)
- {
- gnutls_assert ();
- asn1_delete_structure (&dinfo);
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- result = asn1_der_coding (dinfo, "", tmp_output, &tmp_output_size, NULL);
- if (result != ASN1_SUCCESS)
- {
- gnutls_assert ();
- asn1_delete_structure (&dinfo);
- return _gnutls_asn2err (result);
- }
-
- asn1_delete_structure (&dinfo);
-
- output->size = tmp_output_size;
- output->data = tmp_output;
-
- return 0;
-}
gnutls_datum_t * signature,
gnutls_sign_algorithm_t algo);
-int _gnutls_soft_sign (gnutls_pk_algorithm_t algo,
- gnutls_pk_params_st* params,
- const gnutls_datum_t * data,
- gnutls_datum_t * signature);
-
int pk_prepare_hash (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
gnutls_datum_t * output);
int pk_hash_data (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
const gnutls_datum_t * hash,
gnutls_datum_t * signature);
-int
-decode_ber_digest_info (const gnutls_datum_t * info,
- gnutls_digest_algorithm_t * hash,
- uint8_t * digest, unsigned int *digest_size);
#endif
const gnutls_datum_t * hash,
const gnutls_datum_t * signature);
int
+gnutls_pubkey_verify_hash2 (gnutls_pubkey_t key,
+ gnutls_sign_algorithm_t algo,
+ unsigned int flags,
+ const gnutls_datum_t * hash,
+ const gnutls_datum_t * signature);
+
+int
gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
const gnutls_datum_t * signature,
gnutls_digest_algorithm_t * hash);
gnutls_cipher_algorithm_t gnutls_cipher_get (gnutls_session_t session);
gnutls_kx_algorithm_t gnutls_kx_get (gnutls_session_t session);
gnutls_mac_algorithm_t gnutls_mac_get (gnutls_session_t session);
- gnutls_compression_method_t
+ gnutls_compression_method_t
gnutls_compression_get (gnutls_session_t session);
- gnutls_certificate_type_t
+ gnutls_certificate_type_t
gnutls_certificate_type_get (gnutls_session_t session);
+
int gnutls_sign_algorithm_get_requested (gnutls_session_t session,
size_t indx,
gnutls_sign_algorithm_t * algo);
type);
const char *gnutls_pk_get_name (gnutls_pk_algorithm_t algorithm);
const char *gnutls_sign_get_name (gnutls_sign_algorithm_t algorithm);
+
+ gnutls_sign_algorithm_t gnutls_pk_to_sign (gnutls_pk_algorithm_t pk,
+ gnutls_digest_algorithm_t d);
+
#define gnutls_sign_algorithm_get_name gnutls_sign_get_name
gnutls_mac_algorithm_t gnutls_mac_get_id (const char *name);
gnutls_x509_trust_list_add_system_trust;
gnutls_x509_trust_list_add_trust_file;
gnutls_x509_trust_list_add_trust_mem;
+ gnutls_pubkey_verify_hash2;
+ gnutls_pk_to_sign;
} GNUTLS_3_0_0;
GNUTLS_PRIVATE {
#include <gnutls_errors.h>
#include <gnutls_datum.h>
#include <gnutls_global.h>
+#include <gnutls_sig.h>
#include <gnutls_num.h>
#include <x509/x509_int.h>
#include <x509/common.h>
memcpy (&priv->c, pk_params->params[5], sizeof (mpz_t));
memcpy (&priv->a, pk_params->params[6], sizeof (mpz_t));
memcpy (&priv->b, pk_params->params[7], sizeof (mpz_t));
+ priv->size = nettle_mpz_sizeinbase_256_u(TOMPZ(pk_params->params[RSA_MODULUS]));
+}
+static void
+_rsa_params_to_pubkey (const gnutls_pk_params_st * pk_params,
+ struct rsa_public_key *pub)
+{
+ memcpy (&pub->n, pk_params->params[RSA_MODULUS], sizeof (mpz_t));
+ memcpy (&pub->e, pk_params->params[RSA_PUB], sizeof (mpz_t));
+ pub->size = nettle_mpz_sizeinbase_256_u(pub->n);
}
static void
const gnutls_pk_params_st * pk_params)
{
int ret;
+ mpz_t p;
+
+ mpz_init(p);
switch (algo)
{
case GNUTLS_PK_RSA:
{
- bigint_t p;
+ struct rsa_public_key pub;
+
+ _rsa_params_to_pubkey (pk_params, &pub);
- if (_gnutls_mpi_scan_nz (&p, plaintext->data, plaintext->size) != 0)
+ ret = rsa_encrypt(&pub, NULL, rnd_func, plaintext->size, plaintext->data, p);
+ if (ret == 0)
{
- gnutls_assert ();
- return GNUTLS_E_MPI_SCAN_FAILED;
+ ret = gnutls_assert_val(GNUTLS_E_ENCRYPTION_FAILED);
+ goto cleanup;
}
- mpz_powm (p, p, TOMPZ (pk_params->params[1]) /*e */ ,
- TOMPZ (pk_params->params[0] /*m */ ));
-
ret = _gnutls_mpi_dprint_size (p, ciphertext, plaintext->size);
- _gnutls_mpi_release (&p);
-
if (ret < 0)
{
gnutls_assert ();
cleanup:
+ mpz_clear(p);
return ret;
}
-/* returns the blinded c and the inverse of a random
- * number r;
- */
-static bigint_t
-rsa_blind (bigint_t c, bigint_t e, bigint_t n, bigint_t * _ri)
-{
- bigint_t nc = NULL, r = NULL, ri = NULL;
-
- /* nc = c*(r^e)
- * ri = r^(-1)
- */
- nc = _gnutls_mpi_alloc_like (n);
- if (nc == NULL)
- {
- gnutls_assert ();
- return NULL;
- }
-
- ri = _gnutls_mpi_alloc_like (n);
- if (nc == NULL)
- {
- gnutls_assert ();
- goto fail;
- }
-
- r = _gnutls_mpi_randomize (NULL, _gnutls_mpi_get_nbits (n),
- GNUTLS_RND_NONCE);
- if (r == NULL)
- {
- gnutls_assert ();
- goto fail;
- }
-
- /* invert r */
- if (mpz_invert (ri, r, n) == 0)
- {
- gnutls_assert ();
- goto fail;
- }
-
- /* r = r^e */
-
- _gnutls_mpi_powm (r, r, e, n);
-
- _gnutls_mpi_mulm (nc, c, r, n);
-
- *_ri = ri;
-
- _gnutls_mpi_release (&r);
-
- return nc;
-fail:
- _gnutls_mpi_release (&nc);
- _gnutls_mpi_release (&r);
- return NULL;
-}
-
-/* c = c*ri mod n
- */
-static inline void
-rsa_unblind (bigint_t c, bigint_t ri, bigint_t n)
-{
- _gnutls_mpi_mulm (c, c, ri, n);
-}
-
static int
_wrap_nettle_pk_decrypt (gnutls_pk_algorithm_t algo,
gnutls_datum_t * plaintext,
{
int ret;
+ plaintext->data = NULL;
+
/* make a sexp from pkey */
switch (algo)
{
case GNUTLS_PK_RSA:
{
struct rsa_private_key priv;
- bigint_t c, ri, nc;
+ struct rsa_public_key pub;
+ unsigned length;
+ bigint_t c;
+
+ memset(&priv, 0, sizeof(priv));
+ _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)
{
- gnutls_assert ();
- return GNUTLS_E_MPI_SCAN_FAILED;
+ ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
+ goto cleanup;
}
- nc = rsa_blind (c, pk_params->params[1] /*e */ ,
- pk_params->params[0] /*m */ , &ri);
- _gnutls_mpi_release (&c);
- if (nc == NULL)
+ length = pub.size;
+ plaintext->data = gnutls_malloc(length);
+ if (plaintext->data == NULL)
{
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
+ 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;
- memset(&priv, 0, sizeof(priv));
- _rsa_params_to_privkey (pk_params, &priv);
-
- rsa_compute_root (&priv, TOMPZ (nc), TOMPZ (nc));
-
- rsa_unblind (nc, ri, pk_params->params[0] /*m */ );
-
- ret = _gnutls_mpi_dprint_size (nc, plaintext, ciphertext->size);
-
- _gnutls_mpi_release (&nc);
- _gnutls_mpi_release (&ri);
-
- if (ret < 0)
+ if (ret == 0)
{
- gnutls_assert ();
+ ret = gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
goto cleanup;
}
ret = 0;
cleanup:
+ if (ret < 0)
+ gnutls_free(plaintext->data);
return ret;
}
case GNUTLS_PK_RSA:
{
struct rsa_private_key priv;
- bigint_t hash, nc, ri;
-
- if (_gnutls_mpi_scan_nz (&hash, vdata->data, vdata->size) != 0)
- {
- gnutls_assert ();
- return GNUTLS_E_MPI_SCAN_FAILED;
- }
+ mpz_t s;
memset(&priv, 0, sizeof(priv));
_rsa_params_to_privkey (pk_params, &priv);
-
- nc = rsa_blind (hash, pk_params->params[1] /*e */ ,
- pk_params->params[0] /*m */ , &ri);
-
- _gnutls_mpi_release (&hash);
-
- if (nc == NULL)
+
+ mpz_init(s);
+// XXX change with _tr
+ ret = rsa_pkcs1_sign(&priv, vdata->size, vdata->data, s);
+ if (ret == 0)
{
- gnutls_assert ();
- ret = GNUTLS_E_MEMORY_ERROR;
+ gnutls_assert();
+ ret = GNUTLS_E_PK_SIGN_FAILED;
goto rsa_fail;
}
- rsa_compute_root (&priv, TOMPZ (nc), TOMPZ (nc));
-
- rsa_unblind (nc, ri, pk_params->params[0] /*m */ );
-
- ret = _gnutls_mpi_dprint (nc, signature);
+ ret = _gnutls_mpi_dprint (s, signature);
rsa_fail:
- _gnutls_mpi_release (&nc);
- _gnutls_mpi_release (&ri);
+ mpz_clear(s);
if (ret < 0)
{
return ret;
}
-static int
-_int_rsa_verify (const gnutls_pk_params_st * pk_params,
- bigint_t m, bigint_t s)
-{
- int res;
-
- mpz_t m1;
-
- if ((mpz_sgn (TOMPZ (s)) <= 0)
- || (mpz_cmp (TOMPZ (s), TOMPZ (pk_params->params[0])) >= 0))
- return GNUTLS_E_PK_SIG_VERIFY_FAILED;
-
- mpz_init (m1);
-
- mpz_powm (m1, TOMPZ (s), TOMPZ (pk_params->params[1]),
- TOMPZ (pk_params->params[0]));
-
- res = !mpz_cmp (TOMPZ (m), m1);
-
- mpz_clear (m1);
-
- if (res == 0)
- res = GNUTLS_E_PK_SIG_VERIFY_FAILED;
- else
- res = 0;
-
- return res;
-}
-
static int
_wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo,
const gnutls_datum_t * vdata,
}
case GNUTLS_PK_RSA:
{
- bigint_t hash;
-
- if (_gnutls_mpi_scan_nz (&hash, vdata->data, vdata->size) != 0)
- {
- gnutls_assert ();
- return GNUTLS_E_MPI_SCAN_FAILED;
- }
+ 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)
goto cleanup;
}
- ret = _int_rsa_verify (pk_params, hash, tmp[0]);
+ 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]);
- _gnutls_mpi_release (&hash);
break;
}
default:
return 0;
}
+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 = rsa_pkcs1_sign_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;
+
+}
+
+
int crypto_pk_prio = INT_MAX;
gnutls_crypto_pk_st _gnutls_pk_ops = {
+ .hash_algorithm = wrap_nettle_hash_algorithm,
.encrypt = _wrap_nettle_pk_encrypt,
.decrypt = _wrap_nettle_pk_decrypt,
.sign = _wrap_nettle_pk_sign,
void _cdk_kbnode_clone (cdk_kbnode_t node);
/*-- sesskey.c --*/
-cdk_error_t _cdk_digest_encode_pkcs1 (byte ** r_md, size_t * r_mdlen,
- int pk_algo,
- const byte * md,
- int digest_algo, unsigned nbits);
cdk_error_t _cdk_sk_unprotect_auto (cdk_ctx_t hd, cdk_pkt_seckey_t sk);
/*-- keydb.c --*/
#include <gnutls_int.h>
#include <gnutls_datum.h>
#include <gnutls_pk.h>
+#include <gnutls_sig.h>
#include <x509/common.h>
#include "opencdk.h"
#include "main.h"
cdk_error_t
cdk_pk_verify (cdk_pubkey_t pk, cdk_pkt_signature_t sig, const byte * md)
{
- gnutls_datum_t s_sig;
+ gnutls_datum_t s_sig = { NULL, 0}, di = {NULL, 0};
byte *encmd = NULL;
size_t enclen;
cdk_error_t rc;
int ret, algo;
unsigned int i;
- gnutls_datum_t data;
gnutls_pk_params_st params;
if (!pk || !sig || !md)
goto leave;
}
- rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, pk->pubkey_algo, md,
- sig->digest_algo, cdk_pk_get_nbits (pk));
- if (rc)
+ rc = _gnutls_set_datum (&di, md, _gnutls_hash_get_algo_len (sig->digest_algo));
+ if (rc < 0)
{
- gnutls_assert ();
+ rc = gnutls_assert_val(CDK_Out_Of_Core);
goto leave;
- }
+ }
- data.data = encmd;
- data.size = enclen;
+ rc = pk_prepare_hash (algo, sig->digest_algo, &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, &data, &s_sig, ¶ms);
+ ret = _gnutls_pk_verify (algo, &di, &s_sig, ¶ms);
if (ret < 0)
{
leave:
_gnutls_free_datum (&s_sig);
+ _gnutls_free_datum (&di);
cdk_free (encmd);
return rc;
}
#include "main.h"
#include "packet.h"
-
-/* We encode the MD in this way:
- *
- * 0 1 PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
- *
- * PAD consists of FF bytes.
- */
-static cdk_error_t
-do_encode_md (byte ** r_frame, size_t * r_flen, const byte * md, int algo,
- size_t len, unsigned nbits, const byte * asn, size_t asnlen)
-{
- byte *frame = NULL;
- size_t nframe = (nbits + 7) / 8;
- ssize_t i;
- size_t n = 0;
-
- if (!asn || !md || !r_frame || !r_flen)
- return CDK_Inv_Value;
-
- if (len + asnlen + 4 > nframe)
- return CDK_General_Error;
-
- frame = cdk_calloc (1, nframe);
- if (!frame)
- return CDK_Out_Of_Core;
- frame[n++] = 0;
- frame[n++] = 1;
- i = nframe - len - asnlen - 3;
- if (i < 0)
- {
- cdk_free (frame);
- return CDK_Inv_Value;
- }
- memset (frame + n, 0xFF, i);
- n += i;
- frame[n++] = 0;
- memcpy (frame + n, asn, asnlen);
- n += asnlen;
- memcpy (frame + n, md, len);
- n += len;
- if (n != nframe)
- {
- cdk_free (frame);
- return CDK_Inv_Value;
- }
- *r_frame = frame;
- *r_flen = n;
- return 0;
-}
-
-static const byte md5_asn[18] = /* Object ID is 1.2.840.113549.2.5 */
-{ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
-};
-
-static const byte sha1_asn[15] = /* Object ID is 1.3.14.3.2.26 */
-{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
- 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
-};
-
-static const byte sha224_asn[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
-{ 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
- 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
- 0x1C
-};
-
-static const byte sha256_asn[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */
-{ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
- 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
- 0x00, 0x04, 0x20
-};
-
-static const byte sha512_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */
-{
- 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
- 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
- 0x00, 0x04, 0x40
-};
-
-static const byte sha384_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */
-{
- 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
- 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
- 0x00, 0x04, 0x30
-};
-
-static const byte rmd160_asn[15] = /* Object ID is 1.3.36.3.2.1 */
-{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
- 0x02, 0x01, 0x05, 0x00, 0x04, 0x14
-};
-
-static int
-_gnutls_get_digest_oid (gnutls_digest_algorithm_t algo, const byte ** data)
-{
- switch (algo)
- {
- case GNUTLS_DIG_MD5:
- *data = md5_asn;
- return sizeof (md5_asn);
- case GNUTLS_DIG_SHA1:
- *data = sha1_asn;
- return sizeof (sha1_asn);
- case GNUTLS_DIG_RMD160:
- *data = rmd160_asn;
- return sizeof (rmd160_asn);
- case GNUTLS_DIG_SHA256:
- *data = sha256_asn;
- return sizeof (sha256_asn);
- case GNUTLS_DIG_SHA384:
- *data = sha384_asn;
- return sizeof (sha384_asn);
- case GNUTLS_DIG_SHA512:
- *data = sha512_asn;
- return sizeof (sha512_asn);
- case GNUTLS_DIG_SHA224:
- *data = sha224_asn;
- return sizeof (sha224_asn);
- default:
- gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
- }
-}
-
-
-/* Encode the given digest into a pkcs#1 compatible format. */
-cdk_error_t
-_cdk_digest_encode_pkcs1 (byte ** r_md, size_t * r_mdlen, int pk_algo,
- const byte * md, int digest_algo, unsigned nbits)
-{
- size_t dlen;
-
- if (!md || !r_md || !r_mdlen)
- return CDK_Inv_Value;
-
- dlen = _gnutls_hash_get_algo_len (digest_algo);
- if (dlen <= 0)
- return CDK_Inv_Algo;
- if (is_DSA (pk_algo))
- { /* DSS does not use a special encoding. */
- *r_md = cdk_malloc (dlen + 1);
- if (!*r_md)
- return CDK_Out_Of_Core;
- *r_mdlen = dlen;
- memcpy (*r_md, md, dlen);
- return 0;
- }
- else
- {
- const byte *asn;
- int asnlen;
- cdk_error_t rc;
-
- asnlen = _gnutls_get_digest_oid (digest_algo, &asn);
- if (asnlen < 0)
- return asnlen;
-
- rc = do_encode_md (r_md, r_mdlen, md, digest_algo, dlen,
- nbits, asn, asnlen);
- return rc;
- }
- return 0;
-}
-
-
/**
* cdk_s2k_new:
* @ret_s2k: output for the new S2K object
result =
- _gnutls_soft_sign (pk_algorithm, ¶ms, hash, signature);
+ _gnutls_pk_sign (pk_algorithm, signature, hash, ¶ms);
gnutls_pk_params_release(¶ms);
return result;
}
- if (pk_algorithm != GNUTLS_PK_RSA)
- {
- gnutls_assert ();
- return GNUTLS_E_INVALID_REQUEST;
- }
-
- result =
- _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext, ¶ms, 2);
+ result = _gnutls_pk_decrypt (pk_algorithm, plaintext, ciphertext, ¶ms);
gnutls_pk_params_release(¶ms);
if (result < 0)
- {
- gnutls_assert ();
- return result;
- }
+ return gnutls_assert_val(result);
return 0;
}
goto cleanup;
}
- ret = _gnutls_soft_sign (signer->pk_algorithm, &signer->params,
- &digest, signature);
+ ret = _gnutls_pk_sign (signer->pk_algorithm, signature, &digest, &signer->params);
if (ret < 0)
{
return GNUTLS_E_INVALID_REQUEST;
}
- result = _gnutls_soft_sign (key->pk_algorithm, &key->params,
- hash, signature);
+ result = _gnutls_pk_sign (key->pk_algorithm, signature, hash, &key->params);
+
if (result < 0)
{
gnutls_assert ();
gnutls_pk_algorithm_t pk,
gnutls_pk_params_st * issuer_params)
{
- uint8_t digest[MAX_HASH_SIZE];
- gnutls_datum_t decrypted;
- unsigned int digest_size;
- int ret;
-
- switch (pk)
- {
- case GNUTLS_PK_DSA:
- case GNUTLS_PK_EC:
-
- if (hash)
- *hash = _gnutls_dsa_q_to_hash (pk, issuer_params, 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, 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;
-
+ return _gnutls_pk_hash_algorithm(pk, signature, issuer_params, hash);
}
/* verifies if the certificate is properly signed.
return ret;
}
-int
-_gnutls_x509_verify_hashed_data (const gnutls_datum_t * hash,
- const gnutls_datum_t * signature,
- gnutls_x509_crt_t issuer)
-{
- gnutls_pk_params_st issuer_params;
- int ret;
-
- /* Read the MPI parameters from the issuer's certificate.
- */
- ret =
- _gnutls_x509_crt_get_mpis (issuer, &issuer_params);
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- ret =
- pubkey_verify_hashed_data (gnutls_x509_crt_get_pk_algorithm (issuer, NULL),
- hash, signature, &issuer_params);
- if (ret < 0)
- {
- gnutls_assert ();
- }
-
- /* release all allocated MPIs
- */
- gnutls_pk_params_release(&issuer_params);
-
- return ret;
-}
-
/**
* gnutls_x509_crt_list_verify:
* @cert_list: is the certificate list to be verified
const gnutls_datum_t * hash,
const gnutls_datum_t * signature)
{
- int result;
+ gnutls_pk_params_st params;
+ gnutls_digest_algorithm_t algo;
+ int ret;
if (crt == NULL)
{
return GNUTLS_E_INVALID_REQUEST;
}
- result = _gnutls_x509_verify_hashed_data (hash, signature, crt);
- if (result < 0)
+ ret = gnutls_x509_crt_get_verify_algorithm (crt, signature, &algo);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ /* Read the MPI parameters from the issuer's certificate.
+ */
+ ret =
+ _gnutls_x509_crt_get_mpis (crt, ¶ms);
+ if (ret < 0)
{
gnutls_assert ();
- return result;
+ return ret;
}
- return result;
+ ret =
+ pubkey_verify_hashed_data (gnutls_x509_crt_get_pk_algorithm (crt, NULL), algo,
+ hash, signature, ¶ms);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ }
+
+ /* release all allocated MPIs
+ */
+ gnutls_pk_params_release(¶ms);
+
+ return ret;
}
/**
const gnutls_datum_t * signature,
gnutls_x509_crt_t issuer);
-int _gnutls_x509_verify_hashed_data (const gnutls_datum_t * hash,
- const gnutls_datum_t * signature,
- gnutls_x509_crt_t issuer);
-
/* privkey.h */
ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t *
raw_key,
#include "utils.h"
+static void
+tls_log_func (int level, const char *str)
+{
+ fprintf (stderr, "<%d> %s", level, str);
+}
+
/* sha1 hash of "hello" string */
const gnutls_datum_t hash_data = {
(void *)
gnutls_pubkey_t pubkey;
gnutls_privkey_t privkey;
gnutls_digest_algorithm_t hash_algo;
+ gnutls_sign_algorithm_t sign_algo;
gnutls_datum_t signature;
gnutls_datum_t signature2;
int ret;
gnutls_global_init ();
+ gnutls_global_set_log_function (tls_log_func);
+ if (debug)
+ gnutls_global_set_log_level (6);
+
for (i = 0; i < sizeof (key_dat) / sizeof (key_dat[0]); i++)
{
if (debug)
ret = gnutls_pubkey_verify_hash (pubkey, 0, &hash_data, &signature);
if (ret < 0)
- fail ("gnutls_x509_privkey_verify_hash\n");
+ fail ("gnutls_x509_pubkey_verify_hash\n");
ret =
gnutls_pubkey_get_verify_algorithm (pubkey, &signature2, &hash_algo);
ret = gnutls_pubkey_verify_hash (pubkey, 0, &hash_data, &signature2);
if (ret < 0)
- fail ("gnutls_x509_privkey_verify_hash (hashed data)\n");
+ fail ("gnutls_x509_pubkey_verify_hash-1 (hashed data)\n");
/* should fail */
ret = gnutls_pubkey_verify_hash (pubkey, 0, &invalid_hash_data, &signature2);
if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED)
- fail ("gnutls_x509_privkey_verify_hash (hashed data)\n");
+ fail ("gnutls_x509_pubkey_verify_hash-2 (hashed data)\n");
+
+ sign_algo = gnutls_pk_to_sign(gnutls_pubkey_get_pk_algorithm(pubkey, NULL),
+ GNUTLS_DIG_SHA1);
+
+ ret = gnutls_pubkey_verify_hash2 (pubkey, sign_algo, 0, &hash_data, &signature2);
+ if (ret < 0)
+ fail ("gnutls_x509_pubkey_verify_hash2-1 (hashed data)\n");
+
+ /* should fail */
+ ret = gnutls_pubkey_verify_hash2 (pubkey, sign_algo, 0, &invalid_hash_data, &signature2);
+ if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED)
+ fail ("gnutls_x509_pubkey_verify_hash2-2 (hashed data)\n");
gnutls_free(signature.data);