signature-params: Add helpers to parse/build ASN.1 algorithmIdentifier for signature...
authorTobias Brunner <tobias@strongswan.org>
Tue, 24 Oct 2017 11:45:31 +0000 (13:45 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 8 Nov 2017 15:48:10 +0000 (16:48 +0100)
src/libstrongswan/credentials/keys/signature_params.c
src/libstrongswan/credentials/keys/signature_params.h
src/libstrongswan/tests/suites/test_signature_params.c

index 79453b4..6b4d22e 100644 (file)
@@ -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, &parameters);
+       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, &parameters))
+       {
+               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
  */
index 4cde94c..6934c5e 100644 (file)
@@ -72,6 +72,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
  */
 struct rsa_pss_params_t {
index 0ac00c3..38cb580 100644 (file)
@@ -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, &params_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(&params_build_tests[_i].params, &aid));
+               ck_assert_chunk_eq(params_build_tests[_i].aid, aid);
+               chunk_free(&aid);
+       }
+       else
+       {
+               ck_assert(!signature_params_build(&params_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;
 }