From: Tobias Brunner Date: Thu, 26 Feb 2015 16:31:18 +0000 (+0100) Subject: public-key: Add helper to determine acceptable signature schemes for keys X-Git-Tag: 5.3.0dr1~39^2~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f648d756b8d3a6542b3b2271de7c2236f91feb6;p=thirdparty%2Fstrongswan.git public-key: Add helper to determine acceptable signature schemes for keys --- diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c index b6e521692a..bd5915e601 100644 --- a/src/libstrongswan/credentials/keys/public_key.c +++ b/src/libstrongswan/credentials/keys/public_key.c @@ -191,6 +191,73 @@ int signature_scheme_to_oid(signature_scheme_t scheme) return OID_UNKNOWN; } +/** + * Map for signature schemes to the key type and maximum key size allowed. + * We only cover schemes with hash algorithms supported by IKEv2 signature + * authentication. + */ +static struct { + signature_scheme_t scheme; + key_type_t type; + int max_keysize; +} scheme_map[] = { + { SIGN_RSA_EMSA_PKCS1_SHA256, KEY_RSA, 3072 }, + { SIGN_RSA_EMSA_PKCS1_SHA384, KEY_RSA, 7680 }, + { SIGN_RSA_EMSA_PKCS1_SHA512, KEY_RSA, 0 }, + { SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, 256 }, + { SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, 384 }, + { SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, 0 }, + { SIGN_BLISS_WITH_SHA256, KEY_BLISS, 128 }, + { SIGN_BLISS_WITH_SHA384, KEY_BLISS, 192 }, + { SIGN_BLISS_WITH_SHA512, KEY_BLISS, 0 }, +}; + +/** + * Private data for signature scheme enumerator + */ +typedef struct { + enumerator_t public; + int index; + key_type_t type; + int size; +} private_enumerator_t; + +METHOD(enumerator_t, signature_schemes_enumerate, bool, + private_enumerator_t *this, signature_scheme_t *scheme) +{ + while (++this->index < countof(scheme_map)) + { + if (this->type == scheme_map[this->index].type && + (this->size <= scheme_map[this->index].max_keysize || + !scheme_map[this->index].max_keysize)) + { + *scheme = scheme_map[this->index].scheme; + return TRUE; + } + } + return FALSE; +} + +/* + * Defined in header. + */ +enumerator_t *signature_schemes_for_key(key_type_t type, int size) +{ + private_enumerator_t *this; + + INIT(this, + .public = { + .enumerate = (void*)_signature_schemes_enumerate, + .destroy = (void*)free, + }, + .index = -1, + .type = type, + .size = size, + ); + + return &this->public; +} + /* * Defined in header. */ diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h index a106663703..66e98b2941 100644 --- a/src/libstrongswan/credentials/keys/public_key.h +++ b/src/libstrongswan/credentials/keys/public_key.h @@ -256,6 +256,16 @@ signature_scheme_t signature_scheme_from_oid(int oid); */ int signature_scheme_to_oid(signature_scheme_t scheme); +/** + * Enumerate signature schemes that are appropriate for a key of the given type + * and size|strength. + * + * @param type type of the key + * @param size size or strength of the key + * @return enumerator over signature_scheme_t (increasing strength) + */ +enumerator_t *signature_schemes_for_key(key_type_t type, int size); + /** * Determine the type of key associated with a given signature scheme. * @@ -264,4 +274,5 @@ int signature_scheme_to_oid(signature_scheme_t scheme); */ key_type_t key_type_from_signature_scheme(signature_scheme_t scheme); + #endif /** PUBLIC_KEY_H_ @}*/ diff --git a/src/libstrongswan/tests/suites/test_utils.c b/src/libstrongswan/tests/suites/test_utils.c index abca4620eb..85a854456f 100644 --- a/src/libstrongswan/tests/suites/test_utils.c +++ b/src/libstrongswan/tests/suites/test_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Tobias Brunner + * Copyright (C) 2013-2015 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -695,6 +696,44 @@ START_TEST(test_mark_from_string) } END_TEST +/******************************************************************************* + * signature_schemes_for_key + */ + +static struct { + key_type_t type; + int size; + signature_scheme_t expected[4]; +} scheme_data[] = { + {KEY_RSA, 1024, { SIGN_RSA_EMSA_PKCS1_SHA256, SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_RSA, 2048, { SIGN_RSA_EMSA_PKCS1_SHA256, SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_RSA, 4096, { SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_RSA, 8192, { SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_ECDSA, 256, { SIGN_ECDSA_WITH_SHA256_DER, SIGN_ECDSA_WITH_SHA384_DER, SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }}, + {KEY_ECDSA, 384, { SIGN_ECDSA_WITH_SHA384_DER, SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }}, + {KEY_ECDSA, 512, { SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }}, + {KEY_BLISS, 128, { SIGN_BLISS_WITH_SHA256, SIGN_BLISS_WITH_SHA384, SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }}, + {KEY_BLISS, 192, { SIGN_BLISS_WITH_SHA384, SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }}, + {KEY_BLISS, 256, { SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }}, +}; + +START_TEST(test_signature_schemes_for_key) +{ + enumerator_t *enumerator; + signature_scheme_t scheme; + int i; + + enumerator = signature_schemes_for_key(scheme_data[_i].type, scheme_data[_i].size); + for (i = 0; scheme_data[_i].expected[i] != SIGN_UNKNOWN; i++) + { + ck_assert(enumerator->enumerate(enumerator, &scheme)); + ck_assert_int_eq(scheme_data[_i].expected[i], scheme); + } + ck_assert(!enumerator->enumerate(enumerator, &scheme)); + enumerator->destroy(enumerator); +} +END_TEST + Suite *utils_suite_create() { Suite *s; @@ -777,5 +816,9 @@ Suite *utils_suite_create() tcase_add_loop_test(tc, test_mark_from_string, 0, countof(mark_data)); suite_add_tcase(s, tc); + tc = tcase_create("signature_schemes_for_key"); + tcase_add_loop_test(tc, test_signature_schemes_for_key, 0, countof(scheme_data)); + suite_add_tcase(s, tc); + return s; }