summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS9
-rw-r--r--doc/cha-cert-auth2.texi2
-rw-r--r--lib/abstract_int.h10
-rw-r--r--lib/algorithms.h2
-rw-r--r--lib/algorithms/sign.c16
-rw-r--r--lib/ext/signature.c2
-rw-r--r--lib/gnutls_pubkey.c60
-rw-r--r--lib/gnutls_sig.c21
-rw-r--r--lib/includes/gnutls/abstract.h8
-rw-r--r--lib/includes/gnutls/gnutls.h.in3
-rw-r--r--lib/libgnutls.map2
-rw-r--r--lib/x509/verify.c33
-rw-r--r--lib/x509/x509.c33
-rw-r--r--lib/x509/x509_int.h4
-rw-r--r--tests/x509sign-verify.c29
15 files changed, 158 insertions, 76 deletions
diff --git a/NEWS b/NEWS
index b540980a32..8282a1dd4a 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,15 @@ GnuTLS NEWS -- History of user-visible changes. -*- outline -*-
Copyright (C) 2000-2012 Free Software Foundation, Inc.
See the end for copying conditions.
+* Version 3.0.20 (unreleased)
+
+** libgnutls: Added gnutls_pubkey_verify_hash2()
+
+** API and ABI modifications:
+gnutls_pk_to_sign: Added
+gnutls_pubkey_verify_hash2: Added
+
+
* Version 3.0.19 (released 2012-04-22)
** libgnutls: When decoding a PKCS #11 URL the pin-source field
diff --git a/doc/cha-cert-auth2.texi b/doc/cha-cert-auth2.texi
index 6838bf5b94..df0c79990a 100644
--- a/doc/cha-cert-auth2.texi
+++ b/doc/cha-cert-auth2.texi
@@ -615,7 +615,7 @@ The abstract key types can be used to access signing and
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}
diff --git a/lib/abstract_int.h b/lib/abstract_int.h
index ca2be2b853..429d27e50f 100644
--- a/lib/abstract_int.h
+++ b/lib/abstract_int.h
@@ -36,10 +36,12 @@ int
_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 hash_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,
diff --git a/lib/algorithms.h b/lib/algorithms.h
index e2600c605a..9fe0272541 100644
--- a/lib/algorithms.h
+++ b/lib/algorithms.h
@@ -106,8 +106,6 @@ enum encipher_type _gnutls_kx_encipher_type (gnutls_kx_algorithm_t algorithm);
/* 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);
diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c
index ab81b830d3..d0cbfacb22 100644
--- a/lib/algorithms/sign.c
+++ b/lib/algorithms/sign.c
@@ -178,12 +178,22 @@ _gnutls_x509_oid2sign_algorithm (const char *oid)
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;}
);
@@ -200,7 +210,7 @@ _gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t pk,
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;
diff --git a/lib/ext/signature.c b/lib/ext/signature.c
index 4fe9795d8e..1da555e992 100644
--- a/lib/ext/signature.c
+++ b/lib/ext/signature.c
@@ -264,7 +264,7 @@ _gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_pcert_st* cert)
|| 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++)
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index 6496537ca7..39246f7748 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -1373,7 +1373,6 @@ gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey,
return ret;
}
-
/**
* gnutls_pubkey_verify_hash:
* @key: Holds the public key
@@ -1382,7 +1381,8 @@ gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey,
* @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.
@@ -1394,6 +1394,41 @@ 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_hash:
+ * @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)
{
gnutls_assert ();
@@ -1404,8 +1439,8 @@ gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags,
return _gnutls_rsa_verify (hash, signature, &key->params, 1);
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);
}
}
@@ -1535,7 +1570,8 @@ _gnutls_pubkey_get_mpis (gnutls_pubkey_t key,
* 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_algo,
+ const gnutls_datum_t * text,
const gnutls_datum_t * prehash,
const gnutls_datum_t * signature,
gnutls_pk_params_st * params)
@@ -1569,6 +1605,9 @@ _pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
_gnutls_free_datum (&decrypted);
+ if (hash_algo != GNUTLS_DIG_UNKNOWN && hash_algo != hash)
+ return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
+
if (digest_size != _gnutls_hash_get_algo_len (hash))
{
gnutls_assert ();
@@ -1672,9 +1711,10 @@ dsa_verify_data (gnutls_pk_algorithm_t pk,
*/
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)
@@ -1682,7 +1722,7 @@ pubkey_verify_hashed_data (gnutls_pk_algorithm_t 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;
@@ -1724,7 +1764,7 @@ pubkey_verify_data (gnutls_pk_algorithm_t pk,
case GNUTLS_PK_RSA:
if (_pkcs1_rsa_verify_sig
- (data, NULL, signature, issuer_params) != 0)
+ (algo, data, NULL, signature, issuer_params) != 0)
{
gnutls_assert ();
return GNUTLS_E_PK_SIG_VERIFY_FAILED;
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index 051fe854f6..b30dcc3308 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -272,6 +272,7 @@ 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_sign_algorithm_t sign_algo,
gnutls_pk_algorithm_t pk_algo)
{
int ret;
@@ -326,8 +327,8 @@ verify_tls_hash (gnutls_protocol_t ver, gnutls_pcert_st* cert,
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);
@@ -344,7 +345,7 @@ int
_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;
@@ -357,17 +358,17 @@ _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_pcert_st* cert,
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
{
@@ -420,7 +421,8 @@ _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_pcert_st* cert,
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 ();
@@ -465,7 +467,7 @@ _gnutls_handshake_verify_crt_vrfy12 (gnutls_session_t session,
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 ();
@@ -560,6 +562,7 @@ _gnutls_handshake_verify_crt_vrfy (gnutls_session_t session,
ret =
verify_tls_hash (ver, cert, &dconcat, signature, 16,
+ GNUTLS_SIGN_UNKNOWN,
gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL));
if (ret < 0)
{
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index b89da86c30..50c1ecac35 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -140,6 +140,14 @@ int
gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags,
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,
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 035f63857a..5eff94ab66 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -791,6 +791,9 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
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);
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 31938482ed..33df09be8d 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -786,6 +786,8 @@ GNUTLS_3_0_0 {
gnutls_x509_crt_set_private_key_usage_period;
gnutls_x509_crq_set_private_key_usage_period;
gnutls_session_get_random;
+ gnutls_pubkey_verify_hash2;
+ gnutls_pk_to_sign;
} GNUTLS_2_12;
GNUTLS_PRIVATE {
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index 4a133d451e..23bdcf72c5 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -788,39 +788,6 @@ _gnutls_x509_verify_data (gnutls_digest_algorithm_t algo,
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
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index d0de3cb97f..643f316f99 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -2693,7 +2693,7 @@ gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt, unsigned int flags,
* This function will verify the given signed digest, using the
* parameters from the certificate.
*
- * Deprecated. Please use gnutls_pubkey_verify_data().
+ * Deprecated. Please use gnutls_pubkey_verify_data2() or gnutls_pubkey_verify_hash2().
*
* Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
* is returned, and zero or positive code on success.
@@ -2703,7 +2703,9 @@ gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt, unsigned int flags,
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)
{
@@ -2711,14 +2713,33 @@ gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt, unsigned int flags,
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, &params);
+ 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, &params);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ }
+
+ /* release all allocated MPIs
+ */
+ gnutls_pk_params_release(&params);
+
+ return ret;
}
/**
diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h
index 19c2c1238b..3cc18e4bb0 100644
--- a/lib/x509/x509_int.h
+++ b/lib/x509/x509_int.h
@@ -151,10 +151,6 @@ int _gnutls_x509_verify_data (gnutls_digest_algorithm_t algo,
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,
diff --git a/tests/x509sign-verify.c b/tests/x509sign-verify.c
index 9ac6b5d466..7e0727cf1f 100644
--- a/tests/x509sign-verify.c
+++ b/tests/x509sign-verify.c
@@ -40,6 +40,12 @@
#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 *)
@@ -147,6 +153,7 @@ doit (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;
@@ -154,6 +161,10 @@ doit (void)
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)
@@ -210,7 +221,7 @@ doit (void)
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);
@@ -219,12 +230,24 @@ doit (void)
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);