From: Nikos Mavrogiannopoulos Date: Sat, 15 Jan 2011 13:23:48 +0000 (+0100) Subject: gnutls_x509_crt_verify_hash: DEPRECATED X-Git-Tag: gnutls_2_11_7~93 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b3704c5e6c4efdff0e87165c9e5da0d6a35ec20d;p=thirdparty%2Fgnutls.git gnutls_x509_crt_verify_hash: DEPRECATED gnutls_x509_crt_verify_data: DEPRECATED gnutls_x509_crt_get_verify_algorithm: DEPRECATED gnutls_x509_crt_get_preferred_hash_algorithm: DEPRECATED Removed the new gnutls_x509_privkey_sign_data2() and gnutls_x509_privkey_sign_hash2(). That functionality will be only in the abstract.h pubkey and privkey structures, to avoid duplication for every certificate type. --- diff --git a/NEWS b/NEWS index c7df258997..d009d11de7 100644 --- a/NEWS +++ b/NEWS @@ -31,8 +31,6 @@ Reported by "Brendan Doherty" . gnutls_pubkey_import_privkey: ADDED gnutls_pubkey_verify_data: ADDED gnutls_privkey_sign_hash2: ADDED -gnutls_x509_privkey_sign_hash2: ADDED -gnutls_x509_privkey_sign_data2: ADDED gnutls_privkey_sign_data2: ADDED (in place of gnutls_privkey_sign_data) gnutls_x509_privkey_sign_data: DEPRECATED gnutls_x509_privkey_sign_hash: DEPRECATED @@ -40,6 +38,10 @@ gnutls_x509_privkey_verify_data: DEPRECATED gnutls_psk_netconf_derive_key: DEPRECATED gnutls_session_set_finished_function: DEPRECATED gnutls_ext_register: DEPRECATED +gnutls_x509_crt_verify_hash: DEPRECATED +gnutls_x509_crt_verify_data: DEPRECATED +gnutls_x509_crt_get_verify_algorithm: DEPRECATED +gnutls_x509_crt_get_preferred_hash_algorithm: DEPRECATED gnutls_openpgp_privkey_sign_hash: REMOVED gnutls_openpgp_privkey_decrypt_data: REMOVED gnutls_pkcs11_privkey_sign_hash: REMOVED diff --git a/lib/includes/gnutls/compat.h b/lib/includes/gnutls/compat.h index 926f233136..befae6f1ed 100644 --- a/lib/includes/gnutls/compat.h +++ b/lib/includes/gnutls/compat.h @@ -218,7 +218,7 @@ gnutls_sign_callback_get (gnutls_session_t session, void **userdata) _GNUTLS_GCC_ATTR_DEPRECATED; /* This is a very dangerous and error-prone function. - * Do not use. + * Use gnutls_privkey_sign_hash2() instead. */ int gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key, const gnutls_datum_t * hash, @@ -234,7 +234,7 @@ gnutls_sign_callback_get (gnutls_session_t session, void **userdata) const gnutls_datum_t * signature) _GNUTLS_GCC_ATTR_DEPRECATED; -/* we support the gnutls_x509_privkey_sign_data2() instead. +/* we support the gnutls_privkey_sign_data2() instead. */ int gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key, gnutls_digest_algorithm_t digest, @@ -244,4 +244,33 @@ gnutls_sign_callback_get (gnutls_session_t session, void **userdata) size_t * signature_size) _GNUTLS_GCC_ATTR_DEPRECATED; + /* gnutls_pubkey_verify_data() */ + int gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt, + unsigned int flags, + const gnutls_datum_t * data, + const gnutls_datum_t * signature) + _GNUTLS_GCC_ATTR_DEPRECATED; + + + /* gnutls_pubkey_verify_hash() */ + int gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt, + unsigned int flags, + const gnutls_datum_t * hash, + const gnutls_datum_t * signature) + _GNUTLS_GCC_ATTR_DEPRECATED; + + /* gnutls_pubkey_get_verify_algorithm() */ + int gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt, + const gnutls_datum_t * signature, + gnutls_digest_algorithm_t * hash) + _GNUTLS_GCC_ATTR_DEPRECATED; + + /* gnutls_pubkey_get_preferred_hash_algorithm() */ + int gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt, + gnutls_digest_algorithm_t + * hash, + unsigned int *mand) + _GNUTLS_GCC_ATTR_DEPRECATED; + + #endif /* _GNUTLS_COMPAT_H */ diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h index d19228875c..579bb91605 100644 --- a/lib/includes/gnutls/x509.h +++ b/lib/includes/gnutls/x509.h @@ -140,10 +140,6 @@ extern "C" unsigned int flags, unsigned char *output_data, size_t * output_data_size); - int gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt, - gnutls_digest_algorithm_t - * hash, - unsigned int *mand); int gnutls_x509_crt_set_authority_key_id (gnutls_x509_crt_t cert, const void *id, size_t id_size); @@ -708,35 +704,6 @@ extern "C" gnutls_datum_t * q, gnutls_datum_t * u); -/* Signing stuff. - */ - int gnutls_x509_privkey_sign_data2 (gnutls_x509_privkey_t key, - gnutls_digest_algorithm_t digest, - unsigned int flags, - const gnutls_datum_t * data, - gnutls_datum_t * signature); - int gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt, - unsigned int flags, - const gnutls_datum_t * data, - const gnutls_datum_t * signature); - - 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 gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt, - unsigned int flags, - const gnutls_datum_t * hash, - const gnutls_datum_t * signature); - - int gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt, - const gnutls_datum_t * signature, - gnutls_digest_algorithm_t * hash); - - - /* Certificate request stuff. */ struct gnutls_x509_crq_int; diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 422c90bbf3..ac2cf7795b 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -641,7 +641,6 @@ GNUTLS_2_12 gnutls_privkey_import_pkcs11; gnutls_privkey_import_x509; gnutls_privkey_import_openpgp; - gnutls_privkey_sign_data; gnutls_privkey_decrypt_data; gnutls_pkcs11_privkey_export_url; gnutls_x509_crq_privkey_sign; @@ -692,11 +691,8 @@ GNUTLS_2_12 gnutls_pkcs11_token_set_pin; gnutls_pkcs11_token_get_mechanism; gnutls_privkey_sign_hash2; - gnutls_openpgp_privkey_sign_data2; - gnutls_openpgp_privkey_sign_hash2; - gnutls_x509_privkey_sign_hash2; + gnutls_privkey_sign_data2; gnutls_openpgp_crt_verify_hash; - gnutls_x509_privkey_sign_data2; gnutls_pkcs11_privkey_sign_hash2; gnutls_pubkey_import_privkey; gnutls_pubkey_verify_data; diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c index 5317dbc089..c322934e13 100644 --- a/lib/x509/privkey.c +++ b/lib/x509/privkey.c @@ -1654,15 +1654,15 @@ cleanup: #ifdef ENABLE_PKI -/** - * gnutls_x509_privkey_sign_data2: - * @signer: Holds the key - * @digest: should be MD5 or SHA1 - * @flags: should be 0 for now - * @data: holds the data to be signed - * @signature: will contain the signature allocate with gnutls_malloc() +/*- + * _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: zero for now * - * This function will sign the given data using a signature algorithm + * 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 @@ -1673,33 +1673,38 @@ cleanup: * * The RSA algorithm is used in PKCS #1 v1.5 mode. * - * If the buffer provided is not long enough to hold the output, then - * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will - * be returned. - * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. - **/ -int -gnutls_x509_privkey_sign_data2 (gnutls_x509_privkey_t signer, - gnutls_digest_algorithm_t hash, + -*/ +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 * data, + const gnutls_datum_t * hash_data, gnutls_datum_t * signature) { int ret; gnutls_datum_t digest; - ret = - pk_hash_data (signer->pk_algorithm, hash, signer->params, data, &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 (); - return ret; + goto cleanup; } - ret = - gnutls_x509_privkey_sign_hash2 (signer, hash, flags, &digest, signature); + ret = _gnutls_soft_sign (signer->pk_algorithm, signer->params, + signer->params_size, &digest, signature); + if (ret < 0) { gnutls_assert (); @@ -1714,7 +1719,7 @@ cleanup: } /*- - * gnutls_x509_privkey_sign_hash: + * _gnutls_x509_privkey_sign_hash: * @key: Holds the key * @hash: holds the data to be signed * @signature: will contain newly allocated signature @@ -1753,70 +1758,6 @@ gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key, return 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: zero 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 is returned, otherwise a - * negative error value. - **/ -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, - signer->params_size, &digest, signature); - - if (ret < 0) - { - gnutls_assert (); - goto cleanup; - } - - ret = 0; - -cleanup: - _gnutls_free_datum (&digest); - return ret; -} - /*- * gnutls_x509_privkey_sign_data: * @key: Holds the key @@ -1851,6 +1792,7 @@ gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key, { int result; gnutls_datum_t sig = { NULL, 0 }; + gnutls_datum_t hash; if (key == NULL) { @@ -1858,13 +1800,25 @@ gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key, return GNUTLS_E_INVALID_REQUEST; } - result = gnutls_x509_privkey_sign_data2 (key, digest, flags, data, &sig); + result = + pk_hash_data (key->pk_algorithm, digest, key->params, data, &hash); if (result < 0) { gnutls_assert (); return result; } + result = + _gnutls_x509_privkey_sign_hash2 (key, digest, flags, &hash, signature); + + _gnutls_free_datum(&hash); + + if (result < 0) + { + gnutls_assert (); + return result; + } + if (*signature_size < sig.size) { *signature_size = sig.size; diff --git a/lib/x509/x509.c b/lib/x509/x509.c index 9aaeff8f80..c34f544758 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -2493,6 +2493,8 @@ gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert, * This function will read the certifcate and the signed data to * determine the hash algorithm used to generate the signature. * + * Deprecated: Use gnutls_pubkey_get_verify_algorithm() instead. + * * Returns: the 0 if the hash algorithm is found. A negative value is * returned on error. * @@ -2548,6 +2550,8 @@ gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt, * algorithm to use for signing with this certificate. Some certificates (i.e. * DSA might not be able to sign without the preferred algorithm). * + * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm(). + * * Returns: the 0 if the hash algorithm is found. A negative value is * returned on error. * @@ -2600,6 +2604,8 @@ gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt, * This function will verify the given signed data, using the * parameters from the certificate. * + * Deprecated. Please use gnutls_pubkey_verify_data(). + * * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED * is returned, and a positive code on success. **/ @@ -2636,6 +2642,8 @@ 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(). + * * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED * is returned, and a positive code on success. **/ diff --git a/src/certtool.c b/src/certtool.c index a470f42377..826b05c759 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -766,16 +766,28 @@ static gnutls_digest_algorithm_t get_dig (gnutls_x509_crt crt) { gnutls_digest_algorithm_t dig; + gnutls_pubkey_t pubkey; int result; unsigned int mand; - result = gnutls_x509_crt_get_preferred_hash_algorithm (crt, &dig, &mand); + gnutls_pubkey_init(&pubkey); + + result = gnutls_pubkey_import_x509(pubkey, crt, 0); + if (result < 0) + { + error (EXIT_FAILURE, 0, "gnutls_pubkey_import_x509: %s", + gnutls_strerror (result)); + } + + result = gnutls_pubkey_get_preferred_hash_algorithm (pubkey, &dig, &mand); if (result < 0) { - error (EXIT_FAILURE, 0, "crl_preferred_hash_algorithm: %s", + error (EXIT_FAILURE, 0, "crt_get_preferred_hash_algorithm: %s", gnutls_strerror (result)); } + gnutls_pubkey_deinit(pubkey); + /* if algorithm allows alternatives */ if (mand == 0 && default_dig != GNUTLS_DIG_UNKNOWN) dig = default_dig; diff --git a/tests/cve-2009-1415.c b/tests/cve-2009-1415.c index d1e23c5e2b..122b799cba 100644 --- a/tests/cve-2009-1415.c +++ b/tests/cve-2009-1415.c @@ -46,6 +46,7 @@ #include #include +#include static char dsa_cert[] = "-----BEGIN CERTIFICATE-----\n" @@ -77,6 +78,7 @@ int main (void) { gnutls_x509_crt_t crt; + gnutls_pubkey_t pubkey; gnutls_datum_t data = { (char *) "foo", 3 }; gnutls_datum_t sig = { (char *) "bar", 3 }; int ret; @@ -87,17 +89,26 @@ main (void) if (ret < 0) return 1; + ret = gnutls_pubkey_init (&pubkey); + if (ret < 0) + return 1; + ret = gnutls_x509_crt_import (crt, &dsa_cert_dat, GNUTLS_X509_FMT_PEM); if (ret < 0) return 1; - ret = gnutls_x509_crt_verify_data (crt, 0, &data, &sig); + ret = gnutls_pubkey_import_x509( pubkey, crt, 0); + if (ret < 0) + return 1; + + ret = gnutls_pubkey_verify_data (pubkey, 0, &data, &sig); if (ret < 0 && ret != GNUTLS_E_PK_SIG_VERIFY_FAILED) return 1; //printf ("success!\n"); gnutls_x509_crt_deinit (crt); + gnutls_pubkey_deinit( pubkey); gnutls_global_deinit (); return 0; diff --git a/tests/x509sign-verify.c b/tests/x509sign-verify.c index 85e9ce7883..7791117c60 100644 --- a/tests/x509sign-verify.c +++ b/tests/x509sign-verify.c @@ -169,14 +169,26 @@ doit (void) if (ret < 0) fail ("gnutls_x509_privkey_import\n"); + ret = gnutls_pubkey_init (&pubkey); + if (ret < 0) + fail ("gnutls_privkey_init\n"); + + ret = gnutls_privkey_init (&privkey); + if (ret < 0) + fail ("gnutls_pubkey_init\n"); + + ret = gnutls_privkey_import_x509 (privkey, key, 0); + if (ret < 0) + fail ("gnutls_privkey_import_x509\n"); + ret = - gnutls_x509_privkey_sign_hash2 (key, GNUTLS_DIG_SHA1, 0, &hash_data, + gnutls_privkey_sign_hash2 (privkey, GNUTLS_DIG_SHA1, 0, &hash_data, &signature2); if (ret < 0) - fail ("gnutls_x509_privkey_sign_hash\n"); + fail ("gnutls_privkey_sign_hash\n"); ret = - gnutls_x509_privkey_sign_data2 (key, GNUTLS_DIG_SHA1, 0, &raw_data, + gnutls_privkey_sign_data2 (privkey, GNUTLS_DIG_SHA1, 0, &raw_data, &signature); if (ret < 0) fail ("gnutls_x509_privkey_sign_hash\n"); @@ -190,25 +202,30 @@ doit (void) fail ("gnutls_x509_crt_import\n"); ret = - gnutls_x509_crt_get_verify_algorithm (crt, &signature, &hash_algo); + gnutls_pubkey_import_x509 (pubkey, crt, 0); + if (ret < 0) + fail ("gnutls_x509_pubkey_import\n"); + + ret = + gnutls_pubkey_get_verify_algorithm (pubkey, &signature, &hash_algo); if (ret < 0 || hash_algo != GNUTLS_DIG_SHA1) fail ("gnutls_x509_crt_get_verify_algorithm\n"); - ret = gnutls_x509_crt_verify_hash (crt, 0, &hash_data, &signature); + ret = gnutls_pubkey_verify_hash (pubkey, 0, &hash_data, &signature); if (ret < 0) fail ("gnutls_x509_privkey_verify_hash\n"); ret = - gnutls_x509_crt_get_verify_algorithm (crt, &signature2, &hash_algo); + gnutls_pubkey_get_verify_algorithm (pubkey, &signature2, &hash_algo); if (ret < 0 || hash_algo != GNUTLS_DIG_SHA1) fail ("gnutls_x509_crt_get_verify_algorithm (hashed data)\n"); - ret = gnutls_x509_crt_verify_hash (crt, 0, &hash_data, &signature2); + ret = gnutls_pubkey_verify_hash (pubkey, 0, &hash_data, &signature2); if (ret < 0) fail ("gnutls_x509_privkey_verify_hash (hashed data)\n"); /* should fail */ - ret = gnutls_x509_crt_verify_hash (crt, 0, &invalid_hash_data, &signature2); + 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"); @@ -217,64 +234,9 @@ doit (void) gnutls_free(signature2.data); gnutls_x509_privkey_deinit (key); gnutls_x509_crt_deinit (crt); + gnutls_privkey_deinit (privkey); + gnutls_pubkey_deinit (pubkey); } - /* now try verifying using a pubkey that imports the - * key from an RSA private key. - */ - - ret = gnutls_x509_privkey_init (&key); - if (ret < 0) - fail ("gnutls_x509_privkey_init\n"); - - ret = gnutls_pubkey_init (&pubkey); - if (ret < 0) - fail ("gnutls_privkey_init\n"); - - ret = gnutls_privkey_init (&privkey); - if (ret < 0) - fail ("gnutls_pubkey_init\n"); - - ret = gnutls_x509_privkey_generate (key, GNUTLS_PK_RSA, 1024, 0); - if (ret < 0) - fail ("gnutls_x509_privkey_generate\n"); - - ret = - gnutls_x509_privkey_sign_data2 (key, GNUTLS_DIG_SHA1, 0, &raw_data, - &signature); - if (ret < 0) - fail ("gnutls_x509_privkey_sign_hash\n"); - - /* try verifying */ - ret = gnutls_privkey_import_x509 (privkey, key, 0); - if (ret < 0) - fail ("gnutls_privkey_import_x509\n"); - - ret = - gnutls_pubkey_import_privkey (pubkey, privkey, - GNUTLS_KEY_DIGITAL_SIGNATURE | - GNUTLS_KEY_KEY_ENCIPHERMENT, 0); - if (ret < 0) - fail ("gnutls_pubkey_import_privkey\n"); - - ret = gnutls_pubkey_get_verify_algorithm (pubkey, &signature, &hash_algo); - if (ret < 0 || hash_algo != GNUTLS_DIG_SHA1) - fail ("gnutls_pubkey_get_verify_algorithm\n"); - - /* should fail */ - ret = gnutls_pubkey_verify_hash (pubkey, 0, &invalid_hash_data, - &signature); if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED) - fail ("gnutls_x509_privkey_verify_hash 1\n"); - - /* should succeed */ - ret = gnutls_pubkey_verify_data (pubkey, 0, &raw_data, &signature); - if (ret < 0) - fail ("gnutls_x509_privkey_verify_data\n"); - - gnutls_x509_privkey_deinit(key); - gnutls_privkey_deinit (privkey); - gnutls_pubkey_deinit (pubkey); - gnutls_free(signature.data); - gnutls_global_deinit (); }