x509: Add support for signature schemes with parameters

Also adds support for specifying the hash algorithm for attribute
certificate signatures.
This commit is contained in:
Tobias Brunner
2017-11-08 16:48:10 +01:00
parent 0c23a5693c
commit bbfe39f597
5 changed files with 220 additions and 143 deletions
+39 -28
View File
@@ -72,9 +72,9 @@ struct private_x509_pkcs10_t {
chunk_t challengePassword;
/**
* Signature algorithm
* Signature scheme
*/
int algorithm;
signature_params_t *scheme;
/**
* Signature
@@ -124,22 +124,15 @@ METHOD(certificate_t, has_subject, id_match_t,
METHOD(certificate_t, issued_by, bool,
private_x509_pkcs10_t *this, certificate_t *issuer,
signature_params_t **schemep)
signature_params_t **scheme)
{
public_key_t *key;
signature_scheme_t scheme;
bool valid;
if (&this->public.interface.interface != issuer)
{
return FALSE;
}
/* determine signature scheme */
scheme = signature_scheme_from_oid(this->algorithm);
if (scheme == SIGN_UNKNOWN)
{
return FALSE;
}
if (this->self_signed)
{
valid = TRUE;
@@ -152,14 +145,12 @@ METHOD(certificate_t, issued_by, bool,
{
return FALSE;
}
valid = key->verify(key, scheme, NULL, this->certificationRequestInfo,
this->signature);
valid = key->verify(key, this->scheme->scheme, this->scheme->params,
this->certificationRequestInfo, this->signature);
}
if (valid && schemep)
if (valid && scheme)
{
INIT(*schemep,
.scheme = scheme,
);
*scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -413,7 +404,7 @@ static bool parse_certificate_request(private_x509_pkcs10_t *this)
case PKCS10_SUBJECT_PUBLIC_KEY_INFO:
this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
if (this->public_key == NULL)
if (!this->public_key)
{
goto end;
}
@@ -441,7 +432,12 @@ static bool parse_certificate_request(private_x509_pkcs10_t *this)
}
break;
case PKCS10_ALGORITHM:
this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
INIT(this->scheme);
if (!signature_params_parse(object, level, this->scheme))
{
DBG1(DBG_ASN, " unable to parse signature algorithm");
goto end;
}
break;
case PKCS10_SIGNATURE:
this->signature = chunk_skip(object, 1);
@@ -477,6 +473,7 @@ METHOD(certificate_t, destroy, void,
{
this->subjectAltNames->destroy_offset(this->subjectAltNames,
offsetof(identification_t, destroy));
signature_params_destroy(this->scheme);
DESTROY_IF(this->subject);
DESTROY_IF(this->public_key);
chunk_free(&this->encoding);
@@ -533,25 +530,34 @@ static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
{
chunk_t key_info, subjectAltNames, attributes;
chunk_t extensionRequest = chunk_empty;
chunk_t challengePassword = chunk_empty;
signature_scheme_t scheme;
chunk_t challengePassword = chunk_empty, sig_scheme = chunk_empty;
identification_t *subject;
subject = cert->subject;
cert->public_key = sign_key->get_public_key(sign_key);
/* select signature scheme */
cert->algorithm = hasher_signature_algorithm_to_oid(digest_alg,
sign_key->get_type(sign_key));
if (cert->algorithm == OID_UNKNOWN)
/* select signature scheme, if not already specified */
if (!cert->scheme)
{
INIT(cert->scheme,
.scheme = signature_scheme_from_oid(
hasher_signature_algorithm_to_oid(digest_alg,
sign_key->get_type(sign_key))),
);
}
if (cert->scheme->scheme == SIGN_UNKNOWN)
{
return FALSE;
}
if (!signature_params_build(cert->scheme, &sig_scheme))
{
return FALSE;
}
scheme = signature_scheme_from_oid(cert->algorithm);
if (!cert->public_key->get_encoding(cert->public_key,
PUBKEY_SPKI_ASN1_DER, &key_info))
{
chunk_free(&sig_scheme);
return FALSE;
}
@@ -587,15 +593,16 @@ static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
key_info,
attributes);
if (!sign_key->sign(sign_key, scheme, NULL, cert->certificationRequestInfo,
&cert->signature))
if (!sign_key->sign(sign_key, cert->scheme->scheme, cert->scheme->params,
cert->certificationRequestInfo, &cert->signature))
{
chunk_free(&sig_scheme);
return FALSE;
}
cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm",
cert->certificationRequestInfo,
asn1_algorithmIdentifier(cert->algorithm),
sig_scheme,
asn1_bitstring("c", cert->signature));
return TRUE;
}
@@ -677,6 +684,10 @@ x509_pkcs10_t *x509_pkcs10_gen(certificate_type_t type, va_list args)
case BUILD_CHALLENGE_PWD:
cert->challengePassword = chunk_clone(va_arg(args, chunk_t));
continue;
case BUILD_SIGNATURE_SCHEME:
cert->scheme = va_arg(args, signature_params_t*);
cert->scheme = signature_params_clone(cert->scheme);
continue;
case BUILD_DIGEST_ALG:
digest_alg = va_arg(args, int);
continue;