summaryrefslogtreecommitdiff
path: root/src/libstrongswan/credentials/keys
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@corsac.net>2017-11-21 10:22:31 +0100
committerYves-Alexis Perez <corsac@corsac.net>2017-11-21 10:22:31 +0100
commite1d78dc2faaa06e7c3f71ef674a71e4de2f0758e (patch)
treeae0c8b5f4cd8289d0797882ea18969f33ea59a1e /src/libstrongswan/credentials/keys
parent11d6b62db969bdd808d0f56706cb18f113927a31 (diff)
downloadvyos-strongswan-e1d78dc2faaa06e7c3f71ef674a71e4de2f0758e.tar.gz
vyos-strongswan-e1d78dc2faaa06e7c3f71ef674a71e4de2f0758e.zip
New upstream version 5.6.1
Diffstat (limited to 'src/libstrongswan/credentials/keys')
-rw-r--r--src/libstrongswan/credentials/keys/private_key.h6
-rw-r--r--src/libstrongswan/credentials/keys/public_key.c57
-rw-r--r--src/libstrongswan/credentials/keys/public_key.h16
-rw-r--r--src/libstrongswan/credentials/keys/signature_params.c366
-rw-r--r--src/libstrongswan/credentials/keys/signature_params.h129
5 files changed, 548 insertions, 26 deletions
diff --git a/src/libstrongswan/credentials/keys/private_key.h b/src/libstrongswan/credentials/keys/private_key.h
index b9f7dad55..d7cfdd74d 100644
--- a/src/libstrongswan/credentials/keys/private_key.h
+++ b/src/libstrongswan/credentials/keys/private_key.h
@@ -1,6 +1,7 @@
/*
+ * Copyright (C) 2017 Tobias Brunner
* Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * 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
@@ -42,11 +43,12 @@ struct private_key_t {
* Create a signature over a chunk of data.
*
* @param scheme signature scheme to use
+ * @param params optional parameters required by the specified scheme
* @param data chunk of data to sign
* @param signature where to allocate created signature
* @return TRUE if signature created
*/
- bool (*sign)(private_key_t *this, signature_scheme_t scheme,
+ bool (*sign)(private_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t *signature);
/**
* Decrypt a chunk of data.
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c
index 87f7e6664..89fa9b348 100644
--- a/src/libstrongswan/credentials/keys/public_key.c
+++ b/src/libstrongswan/credentials/keys/public_key.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2015 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2015-2017 Tobias Brunner
* Copyright (C) 2014-2016 Andreas Steffen
+ * Copyright (C) 2007 Martin Willi
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,6 +18,7 @@
#include <asn1/oid.h>
#include "public_key.h"
+#include "signature_params.h"
ENUM(key_type_names, KEY_ANY, KEY_BLISS,
"ANY",
@@ -42,6 +43,7 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_BLISS_WITH_SHA3_512,
"RSA_EMSA_PKCS1_SHA3_256",
"RSA_EMSA_PKCS1_SHA3_384",
"RSA_EMSA_PKCS1_SHA3_512",
+ "RSA_EMSA_PSS",
"ECDSA_WITH_SHA1_DER",
"ECDSA_WITH_SHA256_DER",
"ECDSA_WITH_SHA384_DER",
@@ -146,6 +148,8 @@ signature_scheme_t signature_scheme_from_oid(int oid)
return SIGN_RSA_EMSA_PKCS1_SHA3_384;
case OID_RSASSA_PKCS1V15_WITH_SHA3_512:
return SIGN_RSA_EMSA_PKCS1_SHA3_512;
+ case OID_RSASSA_PSS:
+ return SIGN_RSA_EMSA_PSS;
case OID_ECDSA_WITH_SHA1:
case OID_EC_PUBLICKEY:
return SIGN_ECDSA_WITH_SHA1_DER;
@@ -210,6 +214,8 @@ int signature_scheme_to_oid(signature_scheme_t scheme)
return OID_RSASSA_PKCS1V15_WITH_SHA3_384;
case SIGN_RSA_EMSA_PKCS1_SHA3_512:
return OID_RSASSA_PKCS1V15_WITH_SHA3_384;
+ case SIGN_RSA_EMSA_PSS:
+ return OID_RSASSA_PSS;
case SIGN_ECDSA_WITH_SHA1_DER:
return OID_ECDSA_WITH_SHA1;
case SIGN_ECDSA_WITH_SHA256_DER:
@@ -239,26 +245,42 @@ int signature_scheme_to_oid(signature_scheme_t scheme)
}
/**
+ * Parameters for RSA/PSS signature schemes
+ */
+#define PSS_PARAMS(bits) static rsa_pss_params_t pss_params_sha##bits = { \
+ .hash = HASH_SHA##bits, \
+ .mgf1_hash = HASH_SHA##bits, \
+ .salt_len = RSA_PSS_SALT_LEN_DEFAULT, \
+}
+
+PSS_PARAMS(256);
+PSS_PARAMS(384);
+PSS_PARAMS(512);
+
+/**
* 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;
+ signature_params_t params;
} scheme_map[] = {
- { SIGN_RSA_EMSA_PKCS1_SHA2_256, KEY_RSA, 3072 },
- { SIGN_RSA_EMSA_PKCS1_SHA2_384, KEY_RSA, 7680 },
- { SIGN_RSA_EMSA_PKCS1_SHA2_512, 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_ED25519, KEY_ED25519, 0 },
- { SIGN_ED448, KEY_ED448, 0 },
- { SIGN_BLISS_WITH_SHA2_256, KEY_BLISS, 128 },
- { SIGN_BLISS_WITH_SHA2_384, KEY_BLISS, 192 },
- { SIGN_BLISS_WITH_SHA2_512, KEY_BLISS, 0 }
+ { KEY_RSA, 3072, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha256, }},
+ { KEY_RSA, 7680, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha384, }},
+ { KEY_RSA, 0, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha512, }},
+ { KEY_RSA, 3072, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_256 }},
+ { KEY_RSA, 7680, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_384 }},
+ { KEY_RSA, 0, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_512 }},
+ { KEY_ECDSA, 256, { .scheme = SIGN_ECDSA_WITH_SHA256_DER }},
+ { KEY_ECDSA, 384, { .scheme = SIGN_ECDSA_WITH_SHA384_DER }},
+ { KEY_ECDSA, 0, { .scheme = SIGN_ECDSA_WITH_SHA512_DER }},
+ { KEY_ED25519, 0, { .scheme = SIGN_ED25519 }},
+ { KEY_ED448, 0, { .scheme = SIGN_ED448 }},
+ { KEY_BLISS, 128, { .scheme = SIGN_BLISS_WITH_SHA2_256 }},
+ { KEY_BLISS, 192, { .scheme = SIGN_BLISS_WITH_SHA2_384 }},
+ { KEY_BLISS, 0, { .scheme = SIGN_BLISS_WITH_SHA2_512 }},
};
/**
@@ -274,9 +296,9 @@ typedef struct {
METHOD(enumerator_t, signature_schemes_enumerate, bool,
private_enumerator_t *this, va_list args)
{
- signature_scheme_t *scheme;
+ signature_params_t **params;
- VA_ARGS_VGET(args, scheme);
+ VA_ARGS_VGET(args, params);
while (++this->index < countof(scheme_map))
{
@@ -284,7 +306,7 @@ METHOD(enumerator_t, signature_schemes_enumerate, bool,
(this->size <= scheme_map[this->index].max_keysize ||
!scheme_map[this->index].max_keysize))
{
- *scheme = scheme_map[this->index].scheme;
+ *params = &scheme_map[this->index].params;
return TRUE;
}
}
@@ -332,6 +354,7 @@ key_type_t key_type_from_signature_scheme(signature_scheme_t scheme)
case SIGN_RSA_EMSA_PKCS1_SHA3_256:
case SIGN_RSA_EMSA_PKCS1_SHA3_384:
case SIGN_RSA_EMSA_PKCS1_SHA3_512:
+ case SIGN_RSA_EMSA_PSS:
return KEY_RSA;
case SIGN_ECDSA_WITH_SHA1_DER:
case SIGN_ECDSA_WITH_SHA256_DER:
diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h
index 06c1aa488..877ed20a2 100644
--- a/src/libstrongswan/credentials/keys/public_key.h
+++ b/src/libstrongswan/credentials/keys/public_key.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2015 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2015-2017 Tobias Brunner
* Copyright (C) 2014-2017 Andreas Steffen
+ * Copyright (C) 2007 Martin Willi
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@ typedef enum key_type_t key_type_t;
typedef enum signature_scheme_t signature_scheme_t;
typedef enum encryption_scheme_t encryption_scheme_t;
-#include <library.h>
#include <utils/identification.h>
#include <credentials/cred_encoding.h>
@@ -89,6 +88,8 @@ enum signature_scheme_t {
SIGN_RSA_EMSA_PKCS1_SHA3_384,
/** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-3_512 */
SIGN_RSA_EMSA_PKCS1_SHA3_512,
+ /** EMSA-PSS signature as in PKCS#1 using RSA */
+ SIGN_RSA_EMSA_PSS,
/** ECDSA with SHA-1 using DER encoding as in RFC 3279 */
SIGN_ECDSA_WITH_SHA1_DER,
/** ECDSA with SHA-256 using DER encoding as in RFC 3279 */
@@ -168,12 +169,13 @@ struct public_key_t {
/**
* Verifies a signature against a chunk of data.
*
- * @param scheme signature scheme to use for verification, may be default
+ * @param scheme signature scheme to use for verification
+ * @param params optional parameters required by the specified scheme
* @param data data to check signature against
* @param signature signature to check
* @return TRUE if signature matches
*/
- bool (*verify)(public_key_t *this, signature_scheme_t scheme,
+ bool (*verify)(public_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t signature);
/**
@@ -279,11 +281,11 @@ 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.
+ * and size|strength ordered by increasing strength.
*
* @param type type of the key
* @param size size or strength of the key
- * @return enumerator over signature_scheme_t (increasing strength)
+ * @return enumerator over signature_params_t* (by strength)
*/
enumerator_t *signature_schemes_for_key(key_type_t type, int size);
diff --git a/src/libstrongswan/credentials/keys/signature_params.c b/src/libstrongswan/credentials/keys/signature_params.c
new file mode 100644
index 000000000..6b4d22e7b
--- /dev/null
+++ b/src/libstrongswan/credentials/keys/signature_params.c
@@ -0,0 +1,366 @@
+/*
+ * 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>
+
+/**
+ * Determine the salt length in case it is not configured
+ */
+static ssize_t rsa_pss_salt_length(rsa_pss_params_t *pss)
+{
+ ssize_t salt_len = pss->salt_len;
+
+ if (salt_len <= RSA_PSS_SALT_LEN_DEFAULT)
+ {
+ salt_len = hasher_hash_size(pss->hash);
+ if (!salt_len)
+ {
+ return -1;
+ }
+ }
+ return salt_len;
+}
+
+/**
+ * Compare two signature schemes and their parameters
+ */
+static bool compare_params(signature_params_t *a, signature_params_t *b,
+ bool strict)
+{
+ if (!a && !b)
+ {
+ return TRUE;
+ }
+ if (!a || !b)
+ {
+ return FALSE;
+ }
+ if (a->scheme != b->scheme)
+ {
+ return FALSE;
+ }
+ if (!a->params && !b->params)
+ {
+ return TRUE;
+ }
+ if (a->params && b->params)
+ {
+ switch (a->scheme)
+ {
+ case SIGN_RSA_EMSA_PSS:
+ {
+ rsa_pss_params_t *pss_a = a->params, *pss_b = b->params;
+
+ return pss_a->hash == pss_b->hash &&
+ pss_a->mgf1_hash == pss_b->mgf1_hash &&
+ (!strict ||
+ rsa_pss_salt_length(pss_a) == rsa_pss_salt_length(pss_b));
+ }
+ default:
+ break;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Described in header
+ */
+bool signature_params_equal(signature_params_t *a, signature_params_t *b)
+{
+ return compare_params(a, b, TRUE);
+}
+
+/*
+ * Described in header
+ */
+bool signature_params_comply(signature_params_t *c, signature_params_t *s)
+{ /* the salt is variable, so it does not necessarily have to be the same */
+ return compare_params(c, s, FALSE);
+}
+
+/*
+ * Described in header
+ */
+signature_params_t *signature_params_clone(signature_params_t *this)
+{
+ signature_params_t *clone;
+
+ if (!this)
+ {
+ return NULL;
+ }
+
+ INIT(clone,
+ .scheme = this->scheme,
+ );
+ if (this->params)
+ {
+ switch (this->scheme)
+ {
+ case SIGN_RSA_EMSA_PSS:
+ {
+ rsa_pss_params_t *pss, *pss_clone;
+
+ pss = this->params;
+ INIT(pss_clone,
+ .hash = pss->hash,
+ .mgf1_hash = pss->mgf1_hash,
+ .salt_len = pss->salt_len,
+ /* ignore salt as only used for unit tests */
+ );
+ clone->params = pss_clone;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return clone;
+}
+
+/*
+ * Described in header
+ */
+void signature_params_destroy(signature_params_t *this)
+{
+ if (this)
+ {
+ free(this->params);
+ free(this);
+ }
+}
+
+/*
+ * Described in header
+ */
+void signature_params_clear(signature_params_t *this)
+{
+ if (this)
+ {
+ free(this->params);
+ this->params = NULL;
+ this->scheme = SIGN_UNKNOWN;
+ }
+}
+
+/*
+ * 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
+ */
+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;
+ ssize_t salt_len;
+ 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_algorithmIdentifier_params(OID_MGF1,
+ asn1_algorithmIdentifier(alg));
+ }
+ salt_len = rsa_pss_salt_length(params);
+ if (salt_len < 0)
+ {
+ chunk_free(&hash);
+ chunk_free(&mgf);
+ return FALSE;
+ }
+ else if (salt_len != HASH_SIZE_SHA1)
+ {
+ slen = asn1_integer("m", asn1_integer_from_uint64(salt_len));
+ }
+ *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
new file mode 100644
index 000000000..6934c5e88
--- /dev/null
+++ b/src/libstrongswan/credentials/keys/signature_params.h
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup signature_params signature_params
+ * @{ @ingroup keys
+ */
+
+#ifndef SIGNATURE_PARAMS_H_
+#define SIGNATURE_PARAMS_H_
+
+typedef struct signature_params_t signature_params_t;
+typedef struct rsa_pss_params_t rsa_pss_params_t;
+
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Signature scheme with parameters
+ */
+struct signature_params_t {
+ /** Signature scheme */
+ signature_scheme_t scheme;
+ /** Parameters, depending on scheme */
+ void *params;
+};
+
+/**
+ * Compare two signature schemes and their parameters
+ *
+ * @param a first scheme
+ * @param b second scheme
+ * @return TRUE if schemes and parameters are equal
+ */
+bool signature_params_equal(signature_params_t *a, signature_params_t *b);
+
+/**
+ * Compare two signature schemes and their parameters
+ *
+ * @param c constraint
+ * @param s scheme
+ * @return TRUE if scheme complies to constraint
+ */
+bool signature_params_comply(signature_params_t *c, signature_params_t *s);
+
+/**
+ * Clone the given scheme and parameters, if any
+ *
+ * @return cloned object
+ */
+signature_params_t *signature_params_clone(signature_params_t *this);
+
+/**
+ * Destroy the given scheme and parameters, if any
+ */
+void signature_params_destroy(signature_params_t *this);
+
+/**
+ * Clear the given parameters, if any, sets the scheme to SIGN_UNKNOWN
+ */
+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 {
+ /** Hash algorithm */
+ hash_algorithm_t hash;
+ /** Hash for the MGF1 function */
+ hash_algorithm_t mgf1_hash;
+ /** Salt length, use RSA_PSS_SALT_LEN_DEFAULT for length equal to hash */
+ ssize_t salt_len;
+ /** Salt value, for unit tests (not all implementations support this) */
+ chunk_t salt;
+#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_ @}*/