From eae80fdedc9b71f0a5a9619110e5fa8769c3112c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 24 Oct 2017 13:45:31 +0200 Subject: signature-params: Add helpers to parse/build ASN.1 algorithmIdentifier for signature schemes --- .../credentials/keys/signature_params.c | 64 ++++++++++++ .../credentials/keys/signature_params.h | 21 ++++ .../tests/suites/test_signature_params.c | 111 +++++++++++++++++++++ 3 files changed, 196 insertions(+) diff --git a/src/libstrongswan/credentials/keys/signature_params.c b/src/libstrongswan/credentials/keys/signature_params.c index 79453b4ad..6b4d22e7b 100644 --- a/src/libstrongswan/credentials/keys/signature_params.c +++ b/src/libstrongswan/credentials/keys/signature_params.c @@ -159,6 +159,70 @@ void signature_params_clear(signature_params_t *this) } } +/* + * Described in header + */ +bool signature_params_parse(chunk_t asn1, int level0, + signature_params_t *params) +{ + chunk_t parameters = chunk_empty; + int oid; + + oid = asn1_parse_algorithmIdentifier(asn1, level0, ¶meters); + params->scheme = signature_scheme_from_oid(oid); + switch (params->scheme) + { + case SIGN_UNKNOWN: + return FALSE; + case SIGN_RSA_EMSA_PSS: + { + rsa_pss_params_t *pss = malloc_thing(rsa_pss_params_t); + + if (!rsa_pss_params_parse(parameters, level0+1, pss)) + { + DBG1(DBG_IKE, "failed parsing RSASSA-PSS parameters"); + free(pss); + return FALSE; + } + params->params = pss; + break; + } + default: + params->params = NULL; + break; + } + return TRUE; +} + +/* + * Described in header + */ +bool signature_params_build(signature_params_t *params, chunk_t *asn1) +{ + chunk_t parameters = chunk_empty; + int oid; + + oid = signature_scheme_to_oid(params->scheme); + if (oid == OID_UNKNOWN) + { + return FALSE; + } + if (params->scheme == SIGN_RSA_EMSA_PSS && + !rsa_pss_params_build(params->params, ¶meters)) + { + return FALSE; + } + if (parameters.len) + { + *asn1 = asn1_algorithmIdentifier_params(oid, parameters); + } + else + { + *asn1 = asn1_algorithmIdentifier(oid); + } + return TRUE; +} + /** * ASN.1 definition of RSASSA-PSS-params */ diff --git a/src/libstrongswan/credentials/keys/signature_params.h b/src/libstrongswan/credentials/keys/signature_params.h index 4cde94c8f..6934c5e88 100644 --- a/src/libstrongswan/credentials/keys/signature_params.h +++ b/src/libstrongswan/credentials/keys/signature_params.h @@ -71,6 +71,27 @@ void signature_params_destroy(signature_params_t *this); */ void signature_params_clear(signature_params_t *this); +/** + * Parse an ASN.1 algorithmIdentifier with parameters denoting a signature + * scheme. + * + * @param asn1 ASN.1 encoded RSASSA-PSS-params + * @param level0 current level of the ASN.1 parser + * @param params parsed parameters + * @return TRUE if successfully parsed + */ +bool signature_params_parse(chunk_t asn1, int level0, + signature_params_t *params); + +/** + * Build ASN.1 algorithmIdentifier with parameters denoting a signature scheme. + * + * @param params signature scheme and parameters to encode + * @param asn1 ASN.1 encoded algorithmIdentifier (allocated) + * @return TRUE if successfully built + */ +bool signature_params_build(signature_params_t *params, chunk_t *asn1); + /** * Parameters for SIGN_RSA_EMSA_PSS signature scheme */ diff --git a/src/libstrongswan/tests/suites/test_signature_params.c b/src/libstrongswan/tests/suites/test_signature_params.c index 0ac00c3c7..38cb5803f 100644 --- a/src/libstrongswan/tests/suites/test_signature_params.c +++ b/src/libstrongswan/tests/suites/test_signature_params.c @@ -314,6 +314,105 @@ START_TEST(test_params_clear_null) } END_TEST +START_TEST(test_params_parse_rsa_pss) +{ + signature_params_t parsed, res = { .scheme = SIGN_RSA_EMSA_PSS, }; + + ck_assert(signature_params_parse(rsa_pss_parse_tests[_i].aid, 0, &parsed)); + res.params = &rsa_pss_parse_tests[_i].params; + ck_assert(signature_params_equal(&parsed, &res)); + signature_params_clear(&parsed); +} +END_TEST + +START_TEST(test_params_parse_rsa_pss_invalid) +{ + signature_params_t parsed; + + ck_assert(!signature_params_parse(rsa_pss_parse_invalid_tests[_i], 0, &parsed)); +} +END_TEST + +static struct { + bool valid; + chunk_t aid; + signature_params_t params; +} params_parse_tests[] = { + { TRUE, chunk_from_chars(0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0b,0x05,0x00), + { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_256, }}, + { TRUE, chunk_from_chars(0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x04,0x03,0x02), + { .scheme = SIGN_ECDSA_WITH_SHA256_DER, }}, + { FALSE, chunk_from_chars(0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x04,0x03,0xff), }, +}; + +START_TEST(test_params_parse_other) +{ + signature_params_t parsed; + + if (params_parse_tests[_i].valid) + { + ck_assert(signature_params_parse(params_parse_tests[_i].aid, 0, &parsed)); + ck_assert(signature_params_equal(&parsed, ¶ms_parse_tests[_i].params)); + signature_params_clear(&parsed); + } + else + { + ck_assert(!signature_params_parse(params_parse_tests[_i].aid, 0, &parsed)); + } +} +END_TEST + +START_TEST(test_params_build_rsa_pss) +{ + signature_params_t scheme = { .scheme = SIGN_RSA_EMSA_PSS, }; + chunk_t aid; + + scheme.params = &rsa_pss_build_tests[_i].params; + ck_assert(signature_params_build(&scheme, &aid)); + ck_assert_chunk_eq(rsa_pss_build_tests[_i].aid, aid); + chunk_free(&aid); +} +END_TEST + +START_TEST(test_params_build_rsa_pss_invalid) +{ + signature_params_t scheme = { .scheme = SIGN_RSA_EMSA_PSS, }; + chunk_t aid; + + scheme.params = &rsa_pss_build_invalid_tests[_i]; + ck_assert(!signature_params_build(&scheme, &aid)); +} +END_TEST + +static struct { + bool valid; + signature_params_t params; + chunk_t aid; +} params_build_tests[] = { + { TRUE, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_256, }, + chunk_from_chars(0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0b,0x05,0x00), }, + { TRUE, { .scheme = SIGN_ECDSA_WITH_SHA256_DER, }, + chunk_from_chars(0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x04,0x03,0x02), }, + { FALSE, { .scheme = SIGN_UNKNOWN, }, }, +}; + +START_TEST(test_params_build_other) +{ + chunk_t aid; + + if (params_build_tests[_i].valid) + { + ck_assert(signature_params_build(¶ms_build_tests[_i].params, &aid)); + ck_assert_chunk_eq(params_build_tests[_i].aid, aid); + chunk_free(&aid); + } + else + { + ck_assert(!signature_params_build(¶ms_build_tests[_i].params, &aid)); + } +} +END_TEST + Suite *signature_params_suite_create() { Suite *s; @@ -346,5 +445,17 @@ Suite *signature_params_suite_create() tcase_add_test(tc, test_params_clear_null); suite_add_tcase(s, tc); + tc = tcase_create("parse"); + tcase_add_loop_test(tc, test_params_parse_rsa_pss, 0, countof(rsa_pss_parse_tests)); + tcase_add_loop_test(tc, test_params_parse_rsa_pss_invalid, 0, countof(rsa_pss_parse_invalid_tests)); + tcase_add_loop_test(tc, test_params_parse_other, 0, countof(params_parse_tests)); + suite_add_tcase(s, tc); + + tc = tcase_create("build"); + tcase_add_loop_test(tc, test_params_build_rsa_pss, 0, countof(rsa_pss_build_tests)); + tcase_add_loop_test(tc, test_params_build_rsa_pss_invalid, 0, countof(rsa_pss_build_invalid_tests)); + tcase_add_loop_test(tc, test_params_build_other, 0, countof(params_build_tests)); + suite_add_tcase(s, tc); + return s; } -- cgit v1.2.3