diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-03-02 14:51:31 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-03-02 23:45:07 +0100 |
commit | 8deb88e713dc3a5a0682d88bebd4e9a24707f184 (patch) | |
tree | 6f7a236017bd398b79e57d4ab8212360c906dae9 | |
parent | 7ac0e16bde3b54ed6b6f435a88f180b64056f9f7 (diff) | |
download | gnutls-8deb88e713dc3a5a0682d88bebd4e9a24707f184.tar.gz |
gnutls_privkey_import_ext4: enhanced with GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS flag
That flag is utilized by the information function to obtain the
value of the parameters (e.g., modulus). That information is necessary
to safely handle RSA-PSS keys.
For RSA-PSS keys this is a regression since 3.6.0 where this API was
introduced, but as this change is necessary and 3.6.x is not yet marked
as stable, it should be acceptable.
Relates #402
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r-- | lib/abstract_int.h | 1 | ||||
-rw-r--r-- | lib/includes/gnutls/abstract.h | 3 | ||||
-rw-r--r-- | lib/privkey.c | 12 | ||||
-rw-r--r-- | tests/sign-verify-ext4.c | 5 | ||||
-rw-r--r-- | tests/tls-neg-ext4-key.c | 5 |
5 files changed, 23 insertions, 3 deletions
diff --git a/lib/abstract_int.h b/lib/abstract_int.h index 4013296653..5eaf6e9460 100644 --- a/lib/abstract_int.h +++ b/lib/abstract_int.h @@ -42,6 +42,7 @@ struct gnutls_privkey_st { gnutls_privkey_deinit_func deinit_func; gnutls_privkey_info_func info_func; void *userdata; + unsigned bits; } ext; } key; diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h index 4c638fda42..e15bd3a0f5 100644 --- a/lib/includes/gnutls/abstract.h +++ b/lib/includes/gnutls/abstract.h @@ -115,6 +115,9 @@ typedef void (*gnutls_privkey_deinit_func) (gnutls_privkey_t key, * (obtained with GNUTLS_FLAGS_TO_SIGN_ALGO) is supported. */ #define GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO (1<<2) +/* Should return the number of bits of the public key algorithm (required for RSA-PSS) + * It is the value that should be retuned by gnutls_pubkey_get_pk_algorithm() */ +#define GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS (1<<3) /* returns information on the public key associated with userdata */ typedef int (*gnutls_privkey_info_func) (gnutls_privkey_t key, unsigned int flags, void *userdata); diff --git a/lib/privkey.c b/lib/privkey.c index 63cc7fcbd3..10afdf90f1 100644 --- a/lib/privkey.c +++ b/lib/privkey.c @@ -137,7 +137,8 @@ int gnutls_privkey_get_pk_algorithm(gnutls_privkey_t key, unsigned int *bits) return gnutls_x509_privkey_get_pk_algorithm(key->key.x509); case GNUTLS_PRIVKEY_EXT: if (bits) - *bits = 0; + *bits = key->key.ext.bits; + return key->pk_algorithm; default: gnutls_assert(); @@ -816,8 +817,9 @@ gnutls_privkey_import_ext3(gnutls_privkey_t pkey, * unless prohibited by the type of the algorithm (e.g., as with Ed25519). * * The @info_fn must provide information on the signature algorithms supported by - * this private key, and should support the flags %GNUTLS_PRIVKEY_INFO_PK_ALGO and - * %GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO. It must return -1 on unknown flags. + * this private key, and should support the flags %GNUTLS_PRIVKEY_INFO_PK_ALGO, + * %GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO and %GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS. + * It must return -1 on unknown flags. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. @@ -859,6 +861,10 @@ gnutls_privkey_import_ext4(gnutls_privkey_t pkey, pkey->pk_algorithm = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO, pkey->key.ext.userdata); + ret = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS, pkey->key.ext.userdata); + if (ret >= 0) + pkey->key.ext.bits = ret; + /* Ensure gnutls_privkey_deinit() calls the deinit_func */ if (deinit_fn) pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE; diff --git a/tests/sign-verify-ext4.c b/tests/sign-verify-ext4.c index 94daf000e7..81aa345bf0 100644 --- a/tests/sign-verify-ext4.c +++ b/tests/sign-verify-ext4.c @@ -71,6 +71,7 @@ struct key_cb_data { gnutls_privkey_t rkey; /* the real thing */ unsigned pk; unsigned sig; + unsigned bits; }; static int key_cb_info_func(gnutls_privkey_t key, unsigned int flags, void *userdata) @@ -79,6 +80,8 @@ static int key_cb_info_func(gnutls_privkey_t key, unsigned int flags, void *user if (flags & GNUTLS_PRIVKEY_INFO_PK_ALGO) return p->pk; + else if (flags & GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS) + return p->bits; else if (flags & GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO) { unsigned sig = GNUTLS_FLAGS_TO_SIGN_ALGO(flags); @@ -153,6 +156,8 @@ static gnutls_privkey_t load_virt_privkey(const gnutls_datum_t *txtkey, gnutls_p if (ret < 0) fail("gnutls_privkey_import\n"); + gnutls_privkey_get_pk_algorithm(userdata->rkey, &userdata->bits); + userdata->pk = pk; userdata->sig = sig; diff --git a/tests/tls-neg-ext4-key.c b/tests/tls-neg-ext4-key.c index b916294d3e..04365c598d 100644 --- a/tests/tls-neg-ext4-key.c +++ b/tests/tls-neg-ext4-key.c @@ -73,6 +73,7 @@ struct key_cb_data { gnutls_privkey_t rkey; /* the real thing */ unsigned pk; unsigned sig; + unsigned bits; }; static int key_cb_info_func(gnutls_privkey_t key, unsigned int flags, void *userdata) @@ -81,6 +82,8 @@ static int key_cb_info_func(gnutls_privkey_t key, unsigned int flags, void *user if (flags & GNUTLS_PRIVKEY_INFO_PK_ALGO) return p->pk; + else if (flags & GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS) + return p->bits; else if (flags & GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO) { unsigned sig = GNUTLS_FLAGS_TO_SIGN_ALGO(flags); @@ -159,6 +162,8 @@ static gnutls_privkey_t load_virt_privkey(const char *name, const gnutls_datum_t if (ret < 0) testfail("gnutls_privkey_import\n"); + gnutls_privkey_get_pk_algorithm(userdata->rkey, &userdata->bits); + userdata->pk = pk; userdata->sig = sig; |