to allow determining the hash algorithm to use during signing. This is needed in the case of DSA
that uses specific versions of SHA depending on the size of the parameters.
gnutls_certificate_set_server_retrieve_function: DEPRECATED
gnutls_certificate_set_client_retrieve_function: DEPRECATED
gnutls_sign_callback_set: DEPRECATED
+gnutls_pubkey_get_preferred_hash_algorithm: ADDED
+gnutls_x509_crt_get_preferred_hash_algorithm: ADDED
gnutls_x509_privkey_export_rsa_raw2: ADDED
gnutls_rnd: ADDED
gnutls_sec_param_to_pk_bits: ADDED
return 0;
}
+/**
+ * gnutls_pubkey_get_preferred_hash_algorithm:
+ * @key: Holds the certificate
+ * @hash: The result of the call with the hash algorithm used for signature
+ *
+ * This function will read the certifcate and return the appropriate digest
+ * algorithm to use for signing with this certificate. Some certificates (i.e.
+ * DSA might not be able to sign without the preferred algorithm).
+ *
+ * Returns: the 0 if the hash algorithm is found. A negative value is
+ * returned on error.
+ *
+ * Since: 2.11.0
+ **/
+int
+gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key,
+ gnutls_digest_algorithm_t * hash)
+{
+ int ret;
+
+ if (key == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ ret = _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) hash,
+ NULL, key->pk_algorithm,
+ key->params, key->params_size);
+
+ return ret;
+}
+
+
/**
* gnutls_pubkey_import_pkcs11:
* @key: The public key
gnutls_openpgp_keyid_t keyid,
unsigned int flags);
+int gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key,
+ gnutls_digest_algorithm_t * hash);
+
int gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t crt,
gnutls_datum_t * m, gnutls_datum_t * e);
int gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t crt,
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);
int gnutls_x509_crt_set_authority_key_id (gnutls_x509_crt_t cert,
const void *id, size_t id_size);
gnutls_pkcs11_copy_x509_privkey;
gnutls_pkcs11_delete_url;
gnutls_x509_privkey_export_rsa_raw2;
+ gnutls_pubkey_get_preferred_hash_algorithm;
+ gnutls_x509_crt_get_preferred_hash_algorithm;
gnutls_sec_param_to_pk_bits;
gnutls_sec_param_get_name;
* *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
* be returned.
*
+ * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
+ * the hash algorithm.
+ *
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
* negative error value.
**/
* *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
* be returned.
*
+ * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
+ * the hash algorithm.
+ *
* Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
* negative error value.
**/
}
}
+/* This will return the appropriate hash to verify the given signature.
+ * If signature is NULL it will return an (or the) appropriate hash for
+ * the given parameters.
+ */
int
_gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
const gnutls_datum_t * signature,
ret = 0;
break;
case GNUTLS_PK_RSA:
+ if (signature == NULL) /* return a sensible algorithm */
+ return GNUTLS_DIG_SHA256;
+
ret =
_gnutls_pkcs1_rsa_decrypt (&decrypted, signature,
issuer_params, issuer_params_size, 1);
* @cert: should contain a #gnutls_x509_crt_t structure
*
* This function will return a value of the #gnutls_sign_algorithm_t
- * enumeration that is the signature algorithm.
+ * enumeration that is the signature algorithm that has been used to
+ * sign this certificate.
*
* Returns: a #gnutls_sign_algorithm_t value, or a negative value on
* error.
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
+ *
+ * This function will read the certifcate and return the appropriate digest
+ * algorithm to use for signing with this certificate. Some certificates (i.e.
+ * DSA might not be able to sign without the preferred algorithm).
+ *
+ * Returns: the 0 if the hash algorithm is found. A negative value is
+ * returned on error.
+ *
+ * Since: 2.11.0
+ **/
+int
+gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt,
+ gnutls_digest_algorithm_t * hash)
+{
+ bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE];
+ int issuer_params_size;
+ int ret, i;
+
+ if (crt == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
+ ret =
+ _gnutls_x509_crt_get_mpis (crt, issuer_params,
+ &issuer_params_size);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ 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);
+
+ /* release allocated mpis */
+ for (i = 0; i < issuer_params_size; i++)
+ {
+ _gnutls_mpi_release (&issuer_params[i]);
+ }
+
+ return ret;
+}
+
/**
* gnutls_x509_crt_verify_data:
* @crt: Holds the certificate
static void print_hex_datum (gnutls_datum_t * dat);
-
static gaainfo info;
FILE *outfile;
FILE *infile;
-gnutls_digest_algorithm_t dig = GNUTLS_DIG_SHA1;
+gnutls_digest_algorithm_t default_dig;
/* non interactive operation if set
*/
return crl;
}
-void
-generate_self_signed (void)
+static gnutls_digest_algorithm_t get_dig(gnutls_x509_crt crt)
+{
+gnutls_digest_algorithm_t dig;
+int result;
+
+ if (default_dig != GNUTLS_DIG_UNKNOWN)
+ dig = default_dig;
+ else
+ {
+ 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));
+ }
+ }
+
+ return dig;
+}
+
+void generate_self_signed (void)
{
gnutls_x509_crt_t crt;
gnutls_x509_privkey_t key;
fprintf (stderr, "\n\nSigning certificate...\n");
- result = gnutls_x509_crt_sign2 (crt, crt, key, dig, 0);
+ result = gnutls_x509_crt_sign2 (crt, crt, key, get_dig(crt), 0);
if (result < 0)
error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
fprintf (stderr, "\n\nSigning certificate...\n");
- result = gnutls_x509_crt_sign2 (crt, ca_crt, ca_key, dig, 0);
+ result = gnutls_x509_crt_sign2 (crt, ca_crt, ca_key, get_dig(ca_crt), 0);
if (result < 0)
error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
fprintf (stderr, "\n\nSigning certificate...\n");
- result = gnutls_x509_crt_sign2 (crt, eecrt, eekey, dig, 0);
+ result = gnutls_x509_crt_sign2 (crt, eecrt, eekey, get_dig(eecrt), 0);
if (result < 0)
error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
fprintf (stderr, "\n\nSigning certificate...\n");
- result = gnutls_x509_crt_sign2 (crt, ca_crt, ca_key, dig, 0);
+ result = gnutls_x509_crt_sign2 (crt, ca_crt, ca_key, get_dig(ca_crt), 0);
if (result < 0)
error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result));
else
info.outcert_format = GNUTLS_X509_FMT_PEM;
+ 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,
"Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
- dig = GNUTLS_DIG_MD5;
+ default_dig = GNUTLS_DIG_MD5;
}
else if (strcasecmp (info.hash, "sha1") == 0)
- dig = GNUTLS_DIG_SHA1;
+ default_dig = GNUTLS_DIG_SHA1;
else if (strcasecmp (info.hash, "sha256") == 0)
- dig = GNUTLS_DIG_SHA256;
+ default_dig = GNUTLS_DIG_SHA256;
else if (strcasecmp (info.hash, "sha384") == 0)
- dig = GNUTLS_DIG_SHA384;
+ default_dig = GNUTLS_DIG_SHA384;
else if (strcasecmp (info.hash, "sha512") == 0)
- dig = GNUTLS_DIG_SHA512;
+ default_dig = GNUTLS_DIG_SHA512;
else if (strcasecmp (info.hash, "rmd160") == 0)
- dig = GNUTLS_DIG_RMD160;
+ default_dig = GNUTLS_DIG_RMD160;
else
error (EXIT_FAILURE, 0, "invalid hash: %s", info.hash);
}