From 48ed9c23b052d3fed465967eb4193a7c87d0a24d Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 25 Jul 2017 17:48:26 +0100 Subject: [PATCH] Add public key method enumeration function. Add functions to enumerate public key methods. Add test to ensure table is in the correct order. Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/4015) --- crypto/evp/pmeth_lib.c | 21 ++++++++++++ doc/man3/EVP_PKEY_meth_get_count.pod | 50 ++++++++++++++++++++++++++++ include/openssl/evp.h | 2 ++ test/pkey_meth_test.c | 38 +++++++++++++++++---- 4 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 doc/man3/EVP_PKEY_meth_get_count.pod diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index fd83570b1d..b317e41399 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -290,6 +290,27 @@ int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) return 1; } +size_t EVP_PKEY_meth_get_count(void) +{ + size_t rv = OSSL_NELEM(standard_methods); + + if (app_pkey_methods) + rv += sk_EVP_PKEY_METHOD_num(app_pkey_methods); + return rv; +} + +const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx) +{ + if (idx < OSSL_NELEM(standard_methods)) + return standard_methods[idx]; + if (app_pkey_methods == NULL) + return NULL; + idx -= OSSL_NELEM(standard_methods); + if (idx >= (size_t)sk_EVP_PKEY_METHOD_num(app_pkey_methods)) + return NULL; + return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx); +} + void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { if (ctx == NULL) diff --git a/doc/man3/EVP_PKEY_meth_get_count.pod b/doc/man3/EVP_PKEY_meth_get_count.pod new file mode 100644 index 0000000000..9cf69ddbf8 --- /dev/null +++ b/doc/man3/EVP_PKEY_meth_get_count.pod @@ -0,0 +1,50 @@ +=pod + +=head1 NAME + +EVP_PKEY_meth_get_count, EVP_PKEY_meth_get0, EVP_PKEY_meth_get0_info - enumeratepublic key methods + +=head1 SYNOPSIS + + #include + + size_t EVP_PKEY_meth_get_count(void); + const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx); + void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, + const EVP_PKEY_METHOD *meth); + +=head1 DESCRIPTION + +EVP_PKEY_meth_count() returns a count of the number of public key methods +available: it includes standard methods and any methods added by the +application. + +EVP_PKEY_meth_get0() returns the public key method B. The value of B +must be between zero and EVP_PKEY_meth_get_count() - 1. + +EVP_PKEY_meth_get0_info() returns the public key ID (a NID) and any flags +associated with the public key method B<*meth>. + +=head1 RETURN VALUES + +EVP_PKEY_meth_count() returns the number of available public key methods. + +EVP_PKEY_meth_get0() return a public key method or B if B is +out of range. + +EVP_PKEY_meth_get0_info() does not return a value. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/include/openssl/evp.h b/include/openssl/evp.h index f935e99eaf..af7043b2ea 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1263,6 +1263,8 @@ void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); +size_t EVP_PKEY_meth_get_count(void); +const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx); EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); diff --git a/test/pkey_meth_test.c b/test/pkey_meth_test.c index 5e6a7d4257..ea77790a03 100644 --- a/test/pkey_meth_test.c +++ b/test/pkey_meth_test.c @@ -15,13 +15,8 @@ #include #include "testutil.h" -/********************************************************************** - * - * Test of EVP_PKEY_ASN1 method ordering - * - ***/ - -static int test_asn1_meths() +/* Test of EVP_PKEY_ASN1_METHOD ordering */ +static int test_asn1_meths(void) { int i; int prev = -1; @@ -52,8 +47,37 @@ static int test_asn1_meths() return good; } +/* Test of EVP_PKEY_METHOD ordering */ +static int test_pkey_meths() +{ + size_t i; + int prev = -1; + int good = 1; + int pkey_id; + const EVP_PKEY_METHOD *pmeth; + + for (i = 0; i < EVP_PKEY_meth_get_count(); i++) { + pmeth = EVP_PKEY_meth_get0(i); + EVP_PKEY_meth_get0_info(&pkey_id, NULL, pmeth); + if (pkey_id < prev) + good = 0; + prev = pkey_id; + + } + if (!good) { + TEST_error("EVP_PKEY_METHOD table out of order"); + for (i = 0; i < EVP_PKEY_meth_get_count(); i++) { + pmeth = EVP_PKEY_meth_get0(i); + EVP_PKEY_meth_get0_info(&pkey_id, NULL, pmeth); + TEST_note("%d : %s", pkey_id, OBJ_nid2ln(pkey_id)); + } + } + return good; +} + int setup_tests() { ADD_TEST(test_asn1_meths); + ADD_TEST(test_pkey_meths); return 1; } -- 2.25.1