aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2017-09-20 15:21:51 +0200
committerTobias Brunner <tobias@strongswan.org>2017-11-08 16:48:10 +0100
commita22316520b916723d72c24c0593c344343904acb (patch)
treeb9aef42e0fa1fb0332461d7ea807cadebbda9793 /src
parentc2b878cd6131091645a47eeb4c94ad4afa26720f (diff)
downloadstrongswan-a22316520b916723d72c24c0593c344343904acb.tar.bz2
strongswan-a22316520b916723d72c24c0593c344343904acb.tar.xz
signature-params: Add functions to parse/build ASN.1 RSASSA-PSS params
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/Android.mk1
-rw-r--r--src/libstrongswan/Makefile.am1
-rw-r--r--src/libstrongswan/credentials/keys/signature_params.c167
-rw-r--r--src/libstrongswan/credentials/keys/signature_params.h19
-rw-r--r--src/libstrongswan/tests/Makefile.am3
-rw-r--r--src/libstrongswan/tests/suites/test_signature_params.c230
-rw-r--r--src/libstrongswan/tests/tests.h1
7 files changed, 421 insertions, 1 deletions
diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk
index afca13428..0247add96 100644
--- a/src/libstrongswan/Android.mk
+++ b/src/libstrongswan/Android.mk
@@ -20,6 +20,7 @@ crypto/xofs/xof.c crypto/xofs/xof_bitspender.c \
credentials/credential_factory.c credentials/builder.c \
credentials/cred_encoding.c credentials/keys/private_key.c \
credentials/keys/public_key.c credentials/keys/shared_key.c \
+credentials/keys/signature_params.c \
credentials/certificates/certificate.c credentials/certificates/crl.c \
credentials/certificates/ocsp_response.c credentials/certificates/x509.c \
credentials/certificates/certificate_printer.c \
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am
index c0cc094d7..a9759aeee 100644
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
@@ -18,6 +18,7 @@ crypto/xofs/xof.c crypto/xofs/xof_bitspender.c \
credentials/credential_factory.c credentials/builder.c \
credentials/cred_encoding.c credentials/keys/private_key.c \
credentials/keys/public_key.c credentials/keys/shared_key.c \
+credentials/keys/signature_params.c \
credentials/certificates/certificate.c credentials/certificates/crl.c \
credentials/certificates/ocsp_response.c credentials/certificates/x509.c \
credentials/certificates/certificate_printer.c \
diff --git a/src/libstrongswan/credentials/keys/signature_params.c b/src/libstrongswan/credentials/keys/signature_params.c
new file mode 100644
index 000000000..72a61e15a
--- /dev/null
+++ b/src/libstrongswan/credentials/keys/signature_params.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2017 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "signature_params.h"
+
+#include <asn1/oid.h>
+#include <asn1/asn1_parser.h>
+
+/**
+ * ASN.1 definition of RSASSA-PSS-params
+ */
+static const asn1Object_t RSASSAPSSParamsObjects[] = {
+ { 0, "RSASSA-PSS-params", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "DEFAULT SHA-1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 1 */
+ { 2, "hashAlgorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
+ { 1, "DEFAULT MGF1SHA1", ASN1_CONTEXT_C_1, ASN1_DEF }, /* 3 */
+ { 2, "maskGenAlgorithm",ASN1_EOC, ASN1_RAW }, /* 4 */
+ { 1, "DEFAULT 20", ASN1_CONTEXT_C_2, ASN1_DEF }, /* 5 */
+ { 2, "saltLength", ASN1_INTEGER, ASN1_BODY }, /* 6 */
+ { 1, "DEFAULT 1", ASN1_CONTEXT_C_3, ASN1_DEF }, /* 7 */
+ { 2, "trailerField", ASN1_INTEGER, ASN1_BODY }, /* 8 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define RSASSA_PSS_PARAMS_HASH_ALG 2
+#define RSASSA_PSS_PARAMS_MGF_ALG 4
+#define RSASSA_PSS_PARAMS_SALT_LEN 6
+#define RSASSA_PSS_PARAMS_TRAILER 8
+
+/*
+ * Described in header
+ */
+bool rsa_pss_params_parse(chunk_t asn1, int level0, rsa_pss_params_t *params)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID, alg;
+ bool success = FALSE;
+
+ params->hash = HASH_SHA1;
+ params->mgf1_hash = HASH_SHA1;
+ params->salt_len = HASH_SIZE_SHA1;
+
+ parser = asn1_parser_create(RSASSAPSSParamsObjects, asn1);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ u_int level = parser->get_level(parser)+1;
+
+ switch (objectID)
+ {
+ case RSASSA_PSS_PARAMS_HASH_ALG:
+ if (object.len)
+ {
+ alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ params->hash = hasher_algorithm_from_oid(alg);
+ if (params->hash == HASH_UNKNOWN)
+ {
+ goto end;
+ }
+ }
+ break;
+ case RSASSA_PSS_PARAMS_MGF_ALG:
+ if (object.len)
+ {
+ chunk_t hash;
+
+ alg = asn1_parse_algorithmIdentifier(object, level, &hash);
+ if (alg != OID_MGF1)
+ {
+ goto end;
+ }
+ alg = asn1_parse_algorithmIdentifier(hash, level+1, NULL);
+ params->mgf1_hash = hasher_algorithm_from_oid(alg);
+ if (params->mgf1_hash == HASH_UNKNOWN)
+ {
+ goto end;
+ }
+ }
+ break;
+ case RSASSA_PSS_PARAMS_SALT_LEN:
+ if (object.len)
+ {
+ params->salt_len = (size_t)asn1_parse_integer_uint64(object);
+ }
+ break;
+ case RSASSA_PSS_PARAMS_TRAILER:
+ if (object.len && (object.len != 1 || *object.ptr != 1))
+ {
+ goto end;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/*
+ * Described in header
+ */
+bool rsa_pss_params_build(rsa_pss_params_t *params, chunk_t *asn1)
+{
+ chunk_t hash = chunk_empty, mgf = chunk_empty, slen = chunk_empty;
+ int alg;
+
+ if (params->hash != HASH_SHA1)
+ { /* with SHA-1 we MUST omit the field */
+ alg = hasher_algorithm_to_oid(params->hash);
+ if (alg == OID_UNKNOWN)
+ {
+ return FALSE;
+ }
+ hash = asn1_algorithmIdentifier(alg);
+ }
+ if (params->mgf1_hash != HASH_SHA1)
+ { /* with MGF1-SHA1 we MUST omit the field */
+ alg = hasher_algorithm_to_oid(params->mgf1_hash);
+ if (alg == OID_UNKNOWN)
+ {
+ chunk_free(&hash);
+ return FALSE;
+ }
+ mgf = asn1_wrap(ASN1_SEQUENCE, "mm", asn1_build_known_oid(OID_MGF1),
+ asn1_algorithmIdentifier(alg));
+ }
+ if (params->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
+ {
+ if (params->salt_len != HASH_SIZE_SHA1)
+ {
+ slen = asn1_integer("m", asn1_integer_from_uint64(params->salt_len));
+ }
+ }
+ else if (params->hash != HASH_SHA1)
+ {
+ size_t hlen = hasher_hash_size(params->hash);
+ if (!hlen)
+ {
+ chunk_free(&hash);
+ chunk_free(&mgf);
+ return FALSE;
+ }
+ slen = asn1_integer("m", asn1_integer_from_uint64(hlen));
+ }
+ *asn1 = asn1_wrap(ASN1_SEQUENCE, "mmm",
+ hash.len ? asn1_wrap(ASN1_CONTEXT_C_0, "m", hash) : chunk_empty,
+ mgf.len ? asn1_wrap(ASN1_CONTEXT_C_1, "m", mgf) : chunk_empty,
+ slen.len ? asn1_wrap(ASN1_CONTEXT_C_2, "m", slen) : chunk_empty);
+ return TRUE;
+}
diff --git a/src/libstrongswan/credentials/keys/signature_params.h b/src/libstrongswan/credentials/keys/signature_params.h
index 24f0f4068..f24395428 100644
--- a/src/libstrongswan/credentials/keys/signature_params.h
+++ b/src/libstrongswan/credentials/keys/signature_params.h
@@ -38,4 +38,23 @@ struct rsa_pss_params_t {
#define RSA_PSS_SALT_LEN_DEFAULT -1
};
+/**
+ * Parse the given ASN.1 algorithm identifier params
+ *
+ * @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 rsa_pss_params_parse(chunk_t asn1, int level0, rsa_pss_params_t *params);
+
+/**
+ * Build ASN.1 algorithm identifier params
+ *
+ * @param params parameters to encode
+ * @param asn1 ASN.1 encoded RSASSA-PSS-params (allocated)
+ * @return TRUE if successfully built
+ */
+bool rsa_pss_params_build(rsa_pss_params_t *params, chunk_t *asn1);
+
#endif /** SIGNATURE_PARAMS_H_ @}*/
diff --git a/src/libstrongswan/tests/Makefile.am b/src/libstrongswan/tests/Makefile.am
index 0231c1c14..d764a6a9e 100644
--- a/src/libstrongswan/tests/Makefile.am
+++ b/src/libstrongswan/tests/Makefile.am
@@ -56,7 +56,8 @@ tests_SOURCES = tests.h tests.c \
suites/test_test_rng.c \
suites/test_mgf1.c \
suites/test_ntru.c \
- suites/test_ed25519.c
+ suites/test_ed25519.c \
+ suites/test_signature_params.c
tests_CFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
diff --git a/src/libstrongswan/tests/suites/test_signature_params.c b/src/libstrongswan/tests/suites/test_signature_params.c
new file mode 100644
index 000000000..0b6988076
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_signature_params.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2017 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <credentials/keys/signature_params.h>
+
+struct {
+ chunk_t aid;
+ rsa_pss_params_t params;
+} rsa_pss_parse_tests[] = {
+ /* from RFC 7427, no parameters (empty sequence) */
+ { chunk_from_chars(0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x00),
+ { .hash = HASH_SHA1, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA1, }},
+ /* from RFC 7427, default parameters (SHA-1), would actually not be sent
+ * like this, as corrected in errata */
+ { chunk_from_chars(0x30,0x3e,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x31,0xa0,
+ 0x0b,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0xa1,0x18,0x30,0x16,
+ 0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,0x30,0x09,0x06,0x05,0x2b,
+ 0x0e,0x03,0x02,0x1a,0x05,0x00,0xa2,0x03,0x02,0x01,0x14,0xa3,0x03,0x02,0x01,0x01),
+ { .hash = HASH_SHA1, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA1, }},
+ /* from RFC 7427, SHA-256 */
+ { chunk_from_chars(0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x39,0xa0,
+ 0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,
+ 0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,0x30,
+ 0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0xa2,0x03,
+ 0x02,0x01,0x20,0xa3,0x03,0x02,0x01,0x01),
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = HASH_SIZE_SHA256, }},
+ /* from RFC 7427, SHA-256 (errata, without trailer, with len corrections) */
+ { chunk_from_chars(0x30,0x41,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x34,0xa0,
+ 0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,
+ 0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,0x30,
+ 0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0xa2,0x03,
+ 0x02,0x01,0x20),
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = HASH_SIZE_SHA256, }},
+ /* SHA-512 */
+ { chunk_from_chars(0x30,0x41,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x34,0xa0,
+ 0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,
+ 0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,0x30,
+ 0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0xa2,0x03,
+ 0x02,0x01,0x40),
+ { .hash = HASH_SHA512, .mgf1_hash = HASH_SHA512, .salt_len = HASH_SIZE_SHA512, }},
+ /* SHA-256, no salt */
+ { chunk_from_chars(0x30,0x41,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x34,0xa0,
+ 0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,
+ 0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,0x30,
+ 0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0xa2,0x03,
+ 0x02,0x01,0x00),
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = 0, }},
+ /* only hash specified */
+ { chunk_from_chars(0x30,0x1e,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x11,
+ 0xa0,0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,
+ 0x05,0x00),
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA1, }},
+ /* only mgf specified */
+ { chunk_from_chars(0x30,0x2b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x1e,
+ 0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,
+ 0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00),
+ { .hash = HASH_SHA1, .mgf1_hash = HASH_SHA256, .salt_len = HASH_SIZE_SHA1, }},
+ /* only salt specified */
+ { chunk_from_chars(0x30,0x12,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x05,0xa2,
+ 0x03,0x02,0x01,0x20),
+ { .hash = HASH_SHA1, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA256, }},
+};
+
+START_TEST(test_rsa_pss_params_parse)
+{
+ rsa_pss_params_t parsed;
+ chunk_t params;
+ int oid;
+
+ oid = asn1_parse_algorithmIdentifier(rsa_pss_parse_tests[_i].aid, 0, &params);
+ ck_assert_int_eq(OID_RSASSA_PSS, oid);
+ ck_assert(rsa_pss_params_parse(params, 1, &parsed));
+ ck_assert_int_eq(rsa_pss_parse_tests[_i].params.hash, parsed.hash);
+ ck_assert_int_eq(rsa_pss_parse_tests[_i].params.mgf1_hash, parsed.mgf1_hash);
+ ck_assert_int_eq(rsa_pss_parse_tests[_i].params.salt_len, parsed.salt_len);
+}
+END_TEST
+
+chunk_t rsa_pss_parse_invalid_tests[] = {
+ /* unknown hash */
+ chunk_from_chars(0x30,0x1e,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x11,
+ 0xa0,0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x00,
+ 0x05,0x00),
+ /* unknown mgf */
+ chunk_from_chars(0x30,0x2b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x1e,
+ 0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x00,
+ 0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00),
+ /* unknown mgf-1 hash */
+ chunk_from_chars(0x30,0x2b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x1e,
+ 0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,
+ 0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x00,0x05,0x00),
+ /* incorrect trailer */
+ chunk_from_chars(0x30,0x12,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x05,
+ 0xa3,0x03,0x02,0x01,0x02),
+ /* too long trailer */
+ chunk_from_chars(0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x06,
+ 0xa3,0x04,0x02,0x02,0x01,0x01),
+};
+
+START_TEST(test_rsa_pss_params_parse_invalid)
+{
+ rsa_pss_params_t parsed;
+ chunk_t params;
+ int oid;
+
+ oid = asn1_parse_algorithmIdentifier(rsa_pss_parse_invalid_tests[_i], 0, &params);
+ ck_assert_int_eq(OID_RSASSA_PSS, oid);
+ ck_assert(!rsa_pss_params_parse(params, 1, &parsed));
+}
+END_TEST
+
+struct {
+ chunk_t aid;
+ rsa_pss_params_t params;
+} rsa_pss_build_tests[] = {
+ /* default parameters -> empty sequence */
+ { chunk_from_chars(0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x00),
+ { .hash = HASH_SHA1, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA1, }},
+ /* SHA-256 */
+ { chunk_from_chars(0x30,0x41,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x34,0xa0,
+ 0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,
+ 0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,0x30,
+ 0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0xa2,0x03,
+ 0x02,0x01,0x20),
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ /* default salt length: SHA-1 */
+ { chunk_from_chars(0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x00),
+ { .hash = HASH_SHA1, .mgf1_hash = HASH_SHA1, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ /* default salt length: SHA-224 */
+ { chunk_from_chars(0x30,0x23,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x16,0xa0,
+ 0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,
+ 0xa2,0x03,0x02,0x01,0x1c),
+ { .hash = HASH_SHA224, .mgf1_hash = HASH_SHA1, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ /* default salt length: SHA-384 */
+ { chunk_from_chars(0x30,0x23,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x16,0xa0,
+ 0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,
+ 0xa2,0x03,0x02,0x01,0x30),
+ { .hash = HASH_SHA384, .mgf1_hash = HASH_SHA1, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ /* SHA-512 */
+ { chunk_from_chars(0x30,0x41,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x34,0xa0,
+ 0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,
+ 0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,0x30,
+ 0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0xa2,0x03,
+ 0x02,0x01,0x40),
+ { .hash = HASH_SHA512, .mgf1_hash = HASH_SHA512, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ /* SHA-256, no salt */
+ { chunk_from_chars(0x30,0x41,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x34,0xa0,
+ 0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,
+ 0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,0x30,
+ 0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0xa2,0x03,
+ 0x02,0x01,0x00),
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = 0, }},
+ /* SHA-256, rest default */
+ { chunk_from_chars(0x30,0x1e,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x11,
+ 0xa0,0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,
+ 0x05,0x00),
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA1, }},
+ /* MGF1-SHA-256, rest default */
+ { chunk_from_chars(0x30,0x2b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x1e,
+ 0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,
+ 0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00),
+ { .hash = HASH_SHA1, .mgf1_hash = HASH_SHA256, .salt_len = HASH_SIZE_SHA1, }},
+ /* only salt specified */
+ { chunk_from_chars(0x30,0x12,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x05,0xa2,
+ 0x03,0x02,0x01,0x20),
+ { .hash = HASH_SHA1, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA256, }},
+};
+
+START_TEST(test_rsa_pss_params_build)
+{
+ chunk_t params, aid;
+
+ ck_assert(rsa_pss_params_build(&rsa_pss_build_tests[_i].params, &params));
+ aid = asn1_wrap(ASN1_SEQUENCE, "mm", asn1_build_known_oid(OID_RSASSA_PSS),
+ params);
+ ck_assert_chunk_eq(rsa_pss_build_tests[_i].aid, aid);
+ chunk_free(&aid);
+}
+END_TEST
+
+rsa_pss_params_t rsa_pss_build_invalid_tests[] = {
+ /* unknown hash */
+ { .hash = HASH_UNKNOWN, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA1, },
+ /* invalid mgf */
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_UNKNOWN, .salt_len = HASH_SIZE_SHA256, },
+};
+
+START_TEST(test_rsa_pss_params_build_invalid)
+{
+ chunk_t params;
+
+ ck_assert(!rsa_pss_params_build(&rsa_pss_build_invalid_tests[_i], &params));
+}
+END_TEST
+
+Suite *signature_params_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("signature params");
+
+ tc = tcase_create("parse");
+ tcase_add_loop_test(tc, test_rsa_pss_params_parse, 0, countof(rsa_pss_parse_tests));
+ tcase_add_loop_test(tc, test_rsa_pss_params_parse_invalid, 0, countof(rsa_pss_parse_invalid_tests));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("build");
+ tcase_add_loop_test(tc, test_rsa_pss_params_build, 0, countof(rsa_pss_build_tests));
+ tcase_add_loop_test(tc, test_rsa_pss_params_build_invalid, 0, countof(rsa_pss_build_invalid_tests));
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/tests/tests.h b/src/libstrongswan/tests/tests.h
index c19cac25a..525bdeb94 100644
--- a/src/libstrongswan/tests/tests.h
+++ b/src/libstrongswan/tests/tests.h
@@ -51,4 +51,5 @@ TEST_SUITE_DEPEND(mgf1_sha256_suite_create, XOF, XOF_MGF1_SHA256)
TEST_SUITE_DEPEND(ntru_suite_create, DH, NTRU_112_BIT)
TEST_SUITE_DEPEND(fetch_http_suite_create, FETCHER, "http://")
TEST_SUITE_DEPEND(ed25519_suite_create, PRIVKEY_GEN, KEY_ED25519)
+TEST_SUITE(signature_params_suite_create)