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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user