signature-params: Add helper struct for signature scheme and parameters

This commit is contained in:
Tobias Brunner
2017-11-08 16:48:10 +01:00
parent 72b7c0ffd8
commit c2935b03c4
3 changed files with 319 additions and 18 deletions
@@ -18,6 +18,147 @@
#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;
}
}
/**
* ASN.1 definition of RSASSA-PSS-params
*/
@@ -119,6 +260,7 @@ end:
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)
@@ -141,23 +283,16 @@ bool rsa_pss_params_build(rsa_pss_params_t *params, chunk_t *asn1)
mgf = asn1_wrap(ASN1_SEQUENCE, "mm", asn1_build_known_oid(OID_MGF1),
asn1_algorithmIdentifier(alg));
}
if (params->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
salt_len = rsa_pss_salt_length(params);
if (salt_len < 0)
{
if (params->salt_len != HASH_SIZE_SHA1)
{
slen = asn1_integer("m", asn1_integer_from_uint64(params->salt_len));
}
chunk_free(&hash);
chunk_free(&mgf);
return FALSE;
}
else if (params->hash != HASH_SHA1)
else if (salt_len != HASH_SIZE_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));
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,
@@ -21,10 +21,56 @@
#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);
/**
* Parameters for SIGN_RSA_EMSA_PSS signature scheme
*/