From: Nikos Mavrogiannopoulos Date: Mon, 31 May 2010 15:13:49 +0000 (+0200) Subject: The get_preferred_hash_algorithm() functions have now an extra argument to indicate X-Git-Tag: gnutls_2_11_3~202 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ff8ec39189625a9705fbccd2f906d18d38bece2a;p=thirdparty%2Fgnutls.git The get_preferred_hash_algorithm() functions have now an extra argument to indicate whether it is mandatory to use this algorithm. --- diff --git a/lib/gnutls_pk.c b/lib/gnutls_pk.c index b262eb0f95..9739869ad5 100644 --- a/lib/gnutls_pk.c +++ b/lib/gnutls_pk.c @@ -644,3 +644,18 @@ bigint_t tmp = _gnutls_mpi_alloc_like(params[0]); return 0; } +int _gnutls_pk_get_hash_algorithm(gnutls_pk_algorithm_t pk, bigint_t* params, int params_size, + gnutls_digest_algorithm_t *dig, unsigned int *mand) +{ + if (mand) + { + if (pk == GNUTLS_PK_DSA) + *mand = 1; + else + *mand = 0; + } + + return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) dig, + NULL, pk, params, params_size); + +} diff --git a/lib/gnutls_pk.h b/lib/gnutls_pk.h index 826c0e21a3..5aa9622c1c 100644 --- a/lib/gnutls_pk.h +++ b/lib/gnutls_pk.h @@ -79,4 +79,7 @@ _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r, int _gnutls_calc_rsa_exp(bigint_t* params, unsigned int params_size); +int _gnutls_pk_get_hash_algorithm(gnutls_pk_algorithm_t pk, bigint_t* params, int params_size, + gnutls_digest_algorithm_t *dig, unsigned int *mand); + #endif /* GNUTLS_PK_H */ diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c index 4303ca76a2..58f93b17a2 100644 --- a/lib/gnutls_pubkey.c +++ b/lib/gnutls_pubkey.c @@ -187,6 +187,7 @@ int gnutls_pubkey_import_x509(gnutls_pubkey_t key, gnutls_x509_crt_t crt, * gnutls_pubkey_get_preferred_hash_algorithm: * @key: Holds the certificate * @hash: The result of the call with the hash algorithm used for signature + * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL. * * This function will read the certifcate and return the appropriate digest * algorithm to use for signing with this certificate. Some certificates (i.e. @@ -199,7 +200,7 @@ int gnutls_pubkey_import_x509(gnutls_pubkey_t key, gnutls_x509_crt_t crt, **/ int gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key, - gnutls_digest_algorithm_t * hash) + gnutls_digest_algorithm_t * hash, unsigned int *mand) { int ret; @@ -209,9 +210,8 @@ gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key, return GNUTLS_E_INVALID_REQUEST; } - ret = _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) hash, - NULL, key->pk_algorithm, - key->params, key->params_size); + ret = _gnutls_pk_get_hash_algorithm(key->pk_algorithm, + key->params, key->params_size, hash, mand); return ret; } diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h index 4731faa656..77e7994a5e 100644 --- a/lib/includes/gnutls/abstract.h +++ b/lib/includes/gnutls/abstract.h @@ -24,7 +24,7 @@ int gnutls_pubkey_import_openpgp(gnutls_pubkey_t pkey, unsigned int flags); int gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key, - gnutls_digest_algorithm_t * hash); + gnutls_digest_algorithm_t * hash, unsigned int *mand); int gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t crt, gnutls_datum_t * m, gnutls_datum_t * e); diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h index 004177087a..59138982e0 100644 --- a/lib/includes/gnutls/x509.h +++ b/lib/includes/gnutls/x509.h @@ -140,7 +140,7 @@ extern "C" 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); + 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); @@ -742,7 +742,7 @@ extern "C" const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format); int gnutls_x509_crq_get_preferred_hash_algorithm (gnutls_x509_crq_t crq, - gnutls_digest_algorithm_t * hash); + gnutls_digest_algorithm_t * hash, unsigned int* mand); int gnutls_x509_crq_get_dn (gnutls_x509_crq_t crq, char *buf, size_t * sizeof_buf); diff --git a/lib/x509/crq.c b/lib/x509/crq.c index 604d0e48c1..f80c280c26 100644 --- a/lib/x509/crq.c +++ b/lib/x509/crq.c @@ -1066,7 +1066,7 @@ int gnutls_x509_crq_sign (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key) { gnutls_digest_algorithm_t dig; -int ret = gnutls_x509_crq_get_preferred_hash_algorithm (crq, &dig); +int ret = gnutls_x509_crq_get_preferred_hash_algorithm (crq, &dig, NULL); if (ret < 0) { @@ -2281,6 +2281,7 @@ gnutls_x509_crq_set_key_purpose_oid (gnutls_x509_crq_t crq, * gnutls_x509_crq_get_preferred_hash_algorithm: * @crq: Holds the certificate * @hash: The result of the call with the hash algorithm used for signature + * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL. * * This function will read the certifcate and return the appropriate digest * algorithm to use for signing with this certificate. Some certificates (i.e. @@ -2293,13 +2294,13 @@ gnutls_x509_crq_set_key_purpose_oid (gnutls_x509_crq_t crq, **/ int gnutls_x509_crq_get_preferred_hash_algorithm (gnutls_x509_crq_t crq, - gnutls_digest_algorithm_t * hash) + gnutls_digest_algorithm_t * hash, unsigned int *mand) { bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; int params_size; int ret, i; - if (crt == NULL) + if (crq == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; @@ -2313,9 +2314,8 @@ gnutls_x509_crq_get_preferred_hash_algorithm (gnutls_x509_crq_t crq, return ret; } - ret = _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) hash, - NULL, gnutls_x509_crq_get_pk_algorithm (crq, NULL), - params, params_size); + ret = _gnutls_pk_get_hash_algorithm(gnutls_x509_crq_get_pk_algorithm (crq, NULL), + params, params_size, hash, mand); /* release allocated mpis */ for (i = 0; i < params_size; i++) diff --git a/lib/x509/x509.c b/lib/x509/x509.c index d6dddb2491..acca0d15e8 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -2533,10 +2533,13 @@ gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt, return ret; } + + /** * gnutls_x509_crt_get_preferred_hash_algorithm: * @crt: Holds the certificate * @hash: The result of the call with the hash algorithm used for signature + * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL. * * This function will read the certifcate and return the appropriate digest * algorithm to use for signing with this certificate. Some certificates (i.e. @@ -2549,7 +2552,7 @@ gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt, **/ int gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt, - gnutls_digest_algorithm_t * hash) + gnutls_digest_algorithm_t * hash, unsigned int *mand) { bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE]; int issuer_params_size; @@ -2571,9 +2574,8 @@ gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt, return ret; } - ret = _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) hash, - NULL, gnutls_x509_crt_get_pk_algorithm (crt, NULL), - issuer_params, issuer_params_size); + ret = _gnutls_pk_get_hash_algorithm(gnutls_x509_crt_get_pk_algorithm (crt, NULL), + issuer_params, issuer_params_size, hash, mand); /* release allocated mpis */ for (i = 0; i < issuer_params_size; i++) diff --git a/src/certtool.c b/src/certtool.c index 020a56879d..87c3a13f4f 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -701,19 +701,19 @@ static gnutls_digest_algorithm_t get_dig(gnutls_x509_crt crt) { gnutls_digest_algorithm_t dig; int result; +unsigned int mand; - if (default_dig != GNUTLS_DIG_UNKNOWN) - dig = default_dig; - else + result = gnutls_x509_crt_get_preferred_hash_algorithm(crt, &dig, &mand); + if (result < 0) { - result = gnutls_x509_crt_get_preferred_hash_algorithm(crt, &dig); - if (result < 0) - { error (EXIT_FAILURE, 0, "crl_preferred_hash_algorithm: %s", gnutls_strerror (result)); - } } + /* if algorithm allows alternatives */ + if (mand == 0 && default_dig != GNUTLS_DIG_UNKNOWN) + dig = default_dig; + return dig; } @@ -970,11 +970,6 @@ gaa_parser (int argc, char **argv) default_dig = GNUTLS_DIG_UNKNOWN; if (info.hash != NULL) { - fprintf(stderr, "Warning: It is suggested that you do not use this parameter unless you know what you are doing. " - "It is not always possible to set specific algorithms, for example DSA keys are unable to use any algorithm and " - "thus using the defaults is highly recommended!\n"); - sleep(2); - if (strcasecmp (info.hash, "md5") == 0) { fprintf (stderr,