summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-08-03 16:46:32 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-08-04 11:08:51 +0200
commitf10289f6d8c04111d3a7777f4ed9710a8114ef2f (patch)
treefb5bb71fb5ede40be849a2f4b330613d4bd7b3f5
parent78b693365707dfc5556040739dff7bcdcd70170c (diff)
downloadgnutls-f10289f6d8c04111d3a7777f4ed9710a8114ef2f.tar.gz
gnutls_x509_privkey_generate*: allow specifying the SPKI parameters for key generation
This in turn removes the need for reading the flag GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE on the key generation process. The flag is now only used during key signing which is also its documented purpose. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/includes/gnutls/x509.h2
-rw-r--r--lib/privkey.c8
-rw-r--r--lib/x509/privkey.c32
3 files changed, 26 insertions, 16 deletions
diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h
index d0a0da14cb..3175dcff8f 100644
--- a/lib/includes/gnutls/x509.h
+++ b/lib/includes/gnutls/x509.h
@@ -1209,12 +1209,14 @@ void gnutls_x509_privkey_set_flags(gnutls_x509_privkey_t key, unsigned int flags
* gnutls_keygen_types_t:
* @GNUTLS_KEYGEN_SEED: Specifies the seed to be used in key generation.
* @GNUTLS_KEYGEN_DIGEST: The size field specifies the hash algorithm to be used in key generation.
+ * @GNUTLS_KEYGEN_SPKI: data points to a %gnutls_x509_spki_t structure; it is not used after the key generation call.
*
* Enumeration of different key exchange algorithms.
*/
typedef enum {
GNUTLS_KEYGEN_SEED = 1,
GNUTLS_KEYGEN_DIGEST = 2,
+ GNUTLS_KEYGEN_SPKI = 3
} gnutls_keygen_types_t;
typedef struct {
diff --git a/lib/privkey.c b/lib/privkey.c
index 543886eef0..2011ca8a45 100644
--- a/lib/privkey.c
+++ b/lib/privkey.c
@@ -345,10 +345,10 @@ _gnutls_privkey_update_spki_params(gnutls_privkey_t key,
salt_size = params->salt_size;
}
- if (!(flags & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE))
- salt_size = _gnutls_find_rsa_pss_salt_size(bits, me, salt_size);
-
- params->salt_size = salt_size;
+ if (flags & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE)
+ params->salt_size = 0;
+ else
+ params->salt_size = _gnutls_find_rsa_pss_salt_size(bits, me, salt_size);
params->rsa_pss_dig = dig;
}
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index c5236223df..cc3c72d7a8 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -1619,6 +1619,9 @@ gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
* For DSA keys, if the subgroup size needs to be specified check
* the GNUTLS_SUBGROUP_TO_BITS() macro.
*
+ * When generating RSA-PSS keys which should require specific parameters, you should
+ * use @data of type %GNUTLS_KEYGEN_SPKI to specify the SubjectPublicKeyInfo parameters.
+ *
* Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits().
*
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
@@ -1631,6 +1634,7 @@ gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key,
{
int ret;
unsigned i;
+ gnutls_x509_spki_t tpki = NULL;
if (key == NULL) {
gnutls_assert();
@@ -1645,6 +1649,8 @@ gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key,
memcpy(key->params.seed, data[i].data, data[i].size);
} else if (data[i].type == GNUTLS_KEYGEN_DIGEST) {
key->params.palgo = data[i].size;
+ } else if (data[i].type == GNUTLS_KEYGEN_SPKI) {
+ tpki = (void*)data[i].data;
}
}
@@ -1672,14 +1678,12 @@ gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key,
return ret;
}
- if (algo == GNUTLS_PK_RSA_PSS && (flags & GNUTLS_PRIVKEY_FLAG_CA)) {
+ if (algo == GNUTLS_PK_RSA_PSS && (flags & GNUTLS_PRIVKEY_FLAG_CA) &&
+ !key->params.spki.pk) {
const mac_entry_st *me;
-
key->params.spki.pk = GNUTLS_PK_RSA_PSS;
- if (key->params.palgo != GNUTLS_DIG_UNKNOWN)
- key->params.spki.rsa_pss_dig = key->params.palgo;
- else
- key->params.spki.rsa_pss_dig = _gnutls_pk_bits_to_sha_hash(bits);
+
+ key->params.spki.rsa_pss_dig = _gnutls_pk_bits_to_sha_hash(bits);
me = hash_to_entry(key->params.spki.rsa_pss_dig);
if (unlikely(me == NULL)) {
@@ -1688,12 +1692,8 @@ gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key,
goto cleanup;
}
- if (flags & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE)
- key->params.spki.salt_size = 0;
- else {
- key->params.spki.salt_size =
- _gnutls_find_rsa_pss_salt_size(bits, me, 0);
- }
+ key->params.spki.salt_size =
+ _gnutls_find_rsa_pss_salt_size(bits, me, 0);
}
ret = _gnutls_pk_generate_keys(algo, bits, &key->params, 0);
@@ -1708,6 +1708,14 @@ gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key,
goto cleanup;
}
+ if (tpki) {
+ ret = gnutls_x509_privkey_set_spki(key, tpki, 0);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+ }
+
ret = _gnutls_asn1_encode_privkey(&key->key, &key->params, key->flags&GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT);
if (ret < 0) {
gnutls_assert();