diff options
-rw-r--r-- | lib/includes/gnutls/x509.h | 2 | ||||
-rw-r--r-- | lib/privkey.c | 8 | ||||
-rw-r--r-- | lib/x509/privkey.c | 32 |
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(); |