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:
parent
0c23a5693c
commit
bbfe39f597
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Tobias Brunner
|
||||
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
|
||||
* Copyright (C) 2003 Martin Berner, Lukas Suter
|
||||
* Copyright (C) 2002-2017 Andreas Steffen
|
||||
|
@ -116,9 +117,9 @@ struct private_x509_ac_t {
|
|||
bool noRevAvail;
|
||||
|
||||
/**
|
||||
* Signature algorithm
|
||||
* Signature scheme
|
||||
*/
|
||||
int algorithm;
|
||||
signature_params_t *scheme;
|
||||
|
||||
/**
|
||||
* Signature
|
||||
|
@ -425,7 +426,7 @@ static bool parse_certificate(private_x509_ac_t *this)
|
|||
int objectID;
|
||||
int type = OID_UNKNOWN;
|
||||
int extn_oid = OID_UNKNOWN;
|
||||
int sig_alg = OID_UNKNOWN;
|
||||
signature_params_t sig_alg;
|
||||
bool success = FALSE;
|
||||
bool critical;
|
||||
|
||||
|
@ -476,7 +477,11 @@ static bool parse_certificate(private_x509_ac_t *this)
|
|||
}
|
||||
break;
|
||||
case AC_OBJ_SIG_ALG:
|
||||
sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
|
||||
if (!signature_params_parse(object, level, &sig_alg))
|
||||
{
|
||||
DBG1(DBG_ASN, " unable to parse signature algorithm");
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case AC_OBJ_SERIAL_NUMBER:
|
||||
this->serialNumber = chunk_clone(object);
|
||||
|
@ -550,12 +555,15 @@ static bool parse_certificate(private_x509_ac_t *this)
|
|||
break;
|
||||
}
|
||||
case AC_OBJ_ALGORITHM:
|
||||
this->algorithm = asn1_parse_algorithmIdentifier(object, level,
|
||||
NULL);
|
||||
if (this->algorithm != sig_alg)
|
||||
INIT(this->scheme);
|
||||
if (!signature_params_parse(object, level, this->scheme))
|
||||
{
|
||||
DBG1(DBG_ASN, " unable to parse signature algorithm");
|
||||
goto end;
|
||||
}
|
||||
if (!signature_params_equal(this->scheme, &sig_alg))
|
||||
{
|
||||
DBG1(DBG_ASN, " signature algorithms do not agree");
|
||||
success = FALSE;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
|
@ -570,6 +578,7 @@ static bool parse_certificate(private_x509_ac_t *this)
|
|||
|
||||
end:
|
||||
parser->destroy(parser);
|
||||
signature_params_clear(&sig_alg);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -742,13 +751,13 @@ static chunk_t build_extensions(private_x509_ac_t *this)
|
|||
/**
|
||||
* build attributeCertificateInfo
|
||||
*/
|
||||
static chunk_t build_attr_cert_info(private_x509_ac_t *this)
|
||||
static chunk_t build_attr_cert_info(private_x509_ac_t *this, chunk_t sig_scheme)
|
||||
{
|
||||
return asn1_wrap(ASN1_SEQUENCE, "cmmmmmmm",
|
||||
return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
|
||||
ASN1_INTEGER_1,
|
||||
build_holder(this),
|
||||
build_v2_form(this),
|
||||
asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
|
||||
sig_scheme,
|
||||
asn1_simple_object(ASN1_INTEGER, this->serialNumber),
|
||||
build_attr_cert_validity(this),
|
||||
build_attributes(this),
|
||||
|
@ -758,20 +767,39 @@ static chunk_t build_attr_cert_info(private_x509_ac_t *this)
|
|||
/**
|
||||
* build an X.509 attribute certificate
|
||||
*/
|
||||
static bool build_ac(private_x509_ac_t *this)
|
||||
static bool build_ac(private_x509_ac_t *this, hash_algorithm_t digest_alg)
|
||||
{
|
||||
chunk_t signatureValue, attributeCertificateInfo;
|
||||
chunk_t signatureValue, attributeCertificateInfo, sig_scheme;
|
||||
private_key_t *key = this->signerKey;
|
||||
|
||||
attributeCertificateInfo = build_attr_cert_info(this);
|
||||
if (!this->signerKey->sign(this->signerKey, SIGN_RSA_EMSA_PKCS1_SHA1, NULL,
|
||||
attributeCertificateInfo, &signatureValue))
|
||||
if (!this->scheme)
|
||||
{
|
||||
INIT(this->scheme,
|
||||
.scheme = signature_scheme_from_oid(
|
||||
hasher_signature_algorithm_to_oid(digest_alg,
|
||||
key->get_type(key))),
|
||||
);
|
||||
}
|
||||
if (this->scheme->scheme == SIGN_UNKNOWN)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!signature_params_build(this->scheme, &sig_scheme))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
attributeCertificateInfo = build_attr_cert_info(this, sig_scheme);
|
||||
if (!key->sign(key, this->scheme->scheme, this->scheme->params,
|
||||
attributeCertificateInfo, &signatureValue))
|
||||
{
|
||||
free(attributeCertificateInfo.ptr);
|
||||
free(sig_scheme.ptr);
|
||||
return FALSE;
|
||||
}
|
||||
this->encoding = asn1_wrap(ASN1_SEQUENCE, "mmm",
|
||||
attributeCertificateInfo,
|
||||
asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
|
||||
sig_scheme,
|
||||
asn1_bitstring("m", signatureValue));
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -887,10 +915,9 @@ METHOD(certificate_t, has_issuer, id_match_t,
|
|||
|
||||
METHOD(certificate_t, issued_by, bool,
|
||||
private_x509_ac_t *this, certificate_t *issuer,
|
||||
signature_params_t **schemep)
|
||||
signature_params_t **scheme)
|
||||
{
|
||||
public_key_t *key;
|
||||
signature_scheme_t scheme;
|
||||
bool valid;
|
||||
x509_t *x509 = (x509_t*)issuer;
|
||||
|
||||
|
@ -927,21 +954,16 @@ METHOD(certificate_t, issued_by, bool,
|
|||
}
|
||||
}
|
||||
|
||||
/* determine signature scheme */
|
||||
scheme = signature_scheme_from_oid(this->algorithm);
|
||||
|
||||
if (scheme == SIGN_UNKNOWN || key == NULL)
|
||||
if (!key)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
valid = key->verify(key, scheme, NULL, this->certificateInfo,
|
||||
this->signature);
|
||||
valid = key->verify(key, this->scheme->scheme, this->scheme->params,
|
||||
this->certificateInfo, this->signature);
|
||||
key->destroy(key);
|
||||
if (valid && schemep)
|
||||
if (valid && scheme)
|
||||
{
|
||||
INIT(*schemep,
|
||||
.scheme = scheme,
|
||||
);
|
||||
*scheme = signature_params_clone(this->scheme);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
@ -1024,6 +1046,7 @@ METHOD(certificate_t, destroy, void,
|
|||
DESTROY_IF(this->signerCert);
|
||||
DESTROY_IF(this->signerKey);
|
||||
this->groups->destroy_function(this->groups, (void*)group_destroy);
|
||||
signature_params_destroy(this->scheme);
|
||||
free(this->serialNumber.ptr);
|
||||
free(this->authKeyIdentifier.ptr);
|
||||
free(this->encoding.ptr);
|
||||
|
@ -1130,6 +1153,7 @@ static void add_groups_from_list(private_x509_ac_t *this, linked_list_t *list)
|
|||
*/
|
||||
x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args)
|
||||
{
|
||||
hash_algorithm_t digest_alg = HASH_SHA1;
|
||||
private_x509_ac_t *ac;
|
||||
|
||||
ac = create_empty();
|
||||
|
@ -1161,6 +1185,13 @@ x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args)
|
|||
ac->signerKey = va_arg(args, private_key_t*);
|
||||
ac->signerKey->get_ref(ac->signerKey);
|
||||
continue;
|
||||
case BUILD_SIGNATURE_SCHEME:
|
||||
ac->scheme = va_arg(args, signature_params_t*);
|
||||
ac->scheme = signature_params_clone(ac->scheme);
|
||||
continue;
|
||||
case BUILD_DIGEST_ALG:
|
||||
digest_alg = va_arg(args, int);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
|
@ -1174,7 +1205,7 @@ x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args)
|
|||
ac->holderCert->get_type(ac->holderCert) == CERT_X509 &&
|
||||
ac->signerCert->get_type(ac->signerCert) == CERT_X509)
|
||||
{
|
||||
if (build_ac(ac))
|
||||
if (build_ac(ac, digest_alg))
|
||||
{
|
||||
return &ac->public;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2002 Mario Strasser
|
||||
* Copyright (C) 2000-2017 Andreas Steffen
|
||||
* Copyright (C) 2006-2009 Martin Willi
|
||||
* Copyright (C) 2008 Tobias Brunner
|
||||
* Copyright (C) 2008-2017 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -197,9 +197,9 @@ struct private_x509_cert_t {
|
|||
x509_flag_t flags;
|
||||
|
||||
/**
|
||||
* Signature algorithm
|
||||
* Signature scheme
|
||||
*/
|
||||
int algorithm;
|
||||
signature_params_t *scheme;
|
||||
|
||||
/**
|
||||
* Signature
|
||||
|
@ -1375,7 +1375,7 @@ static bool parse_certificate(private_x509_cert_t *this)
|
|||
chunk_t object;
|
||||
int objectID;
|
||||
int extn_oid = OID_UNKNOWN;
|
||||
int sig_alg = OID_UNKNOWN;
|
||||
signature_params_t sig_alg = {};
|
||||
bool success = FALSE;
|
||||
bool critical = FALSE;
|
||||
|
||||
|
@ -1406,7 +1406,11 @@ static bool parse_certificate(private_x509_cert_t *this)
|
|||
this->serialNumber = object;
|
||||
break;
|
||||
case X509_OBJ_SIG_ALG:
|
||||
sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
|
||||
if (!signature_params_parse(object, level, &sig_alg))
|
||||
{
|
||||
DBG1(DBG_ASN, " unable to parse signature algorithm");
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case X509_OBJ_ISSUER:
|
||||
this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
|
||||
|
@ -1560,8 +1564,13 @@ static bool parse_certificate(private_x509_cert_t *this)
|
|||
break;
|
||||
}
|
||||
case X509_OBJ_ALGORITHM:
|
||||
this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
|
||||
if (this->algorithm != sig_alg)
|
||||
INIT(this->scheme);
|
||||
if (!signature_params_parse(object, level, this->scheme))
|
||||
{
|
||||
DBG1(DBG_ASN, " unable to parse signature algorithm");
|
||||
goto end;
|
||||
}
|
||||
if (!signature_params_equal(this->scheme, &sig_alg))
|
||||
{
|
||||
DBG1(DBG_ASN, " signature algorithms do not agree");
|
||||
goto end;
|
||||
|
@ -1578,6 +1587,7 @@ static bool parse_certificate(private_x509_cert_t *this)
|
|||
|
||||
end:
|
||||
parser->destroy(parser);
|
||||
signature_params_clear(&sig_alg);
|
||||
if (success)
|
||||
{
|
||||
hasher_t *hasher;
|
||||
|
@ -1677,26 +1687,21 @@ METHOD(certificate_t, has_issuer, id_match_t,
|
|||
|
||||
METHOD(certificate_t, issued_by, bool,
|
||||
private_x509_cert_t *this, certificate_t *issuer,
|
||||
signature_params_t **schemep)
|
||||
signature_params_t **scheme)
|
||||
{
|
||||
public_key_t *key;
|
||||
signature_scheme_t scheme;
|
||||
bool valid;
|
||||
x509_t *x509 = (x509_t*)issuer;
|
||||
|
||||
/* determine signature scheme */
|
||||
scheme = signature_scheme_from_oid(this->algorithm);
|
||||
if (scheme == SIGN_UNKNOWN)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (&this->public.interface.interface == issuer)
|
||||
{
|
||||
if (this->flags & X509_SELF_SIGNED)
|
||||
{
|
||||
valid = TRUE;
|
||||
goto out;
|
||||
if (scheme)
|
||||
{
|
||||
*scheme = signature_params_clone(this->scheme);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1721,16 +1726,12 @@ METHOD(certificate_t, issued_by, bool,
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
valid = key->verify(key, scheme, NULL, this->tbsCertificate,
|
||||
this->signature);
|
||||
valid = key->verify(key, this->scheme->scheme, this->scheme->params,
|
||||
this->tbsCertificate, this->signature);
|
||||
key->destroy(key);
|
||||
|
||||
out:
|
||||
if (valid && schemep)
|
||||
if (valid && scheme)
|
||||
{
|
||||
INIT(*schemep,
|
||||
.scheme = scheme,
|
||||
);
|
||||
*scheme = signature_params_clone(this->scheme);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
@ -1930,6 +1931,7 @@ METHOD(certificate_t, destroy, void,
|
|||
(void*)cert_policy_destroy);
|
||||
this->policy_mappings->destroy_function(this->policy_mappings,
|
||||
(void*)policy_mapping_destroy);
|
||||
signature_params_destroy(this->scheme);
|
||||
DESTROY_IF(this->issuer);
|
||||
DESTROY_IF(this->subject);
|
||||
DESTROY_IF(this->public_key);
|
||||
|
@ -2185,10 +2187,9 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
|
|||
chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
|
||||
chunk_t policyConstraints = chunk_empty, inhibitAnyPolicy = chunk_empty;
|
||||
chunk_t ikeIntermediate = chunk_empty, msSmartcardLogon = chunk_empty;
|
||||
chunk_t ipAddrBlocks = chunk_empty;
|
||||
chunk_t ipAddrBlocks = chunk_empty, sig_scheme = chunk_empty;
|
||||
identification_t *issuer, *subject;
|
||||
chunk_t key_info;
|
||||
signature_scheme_t scheme;
|
||||
hasher_t *hasher;
|
||||
enumerator_t *enumerator;
|
||||
char *uri;
|
||||
|
@ -2221,18 +2222,28 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
|
|||
cert->notAfter = cert->notBefore + 60 * 60 * 24 * 365;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -2557,10 +2568,10 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
|
|||
ipAddrBlocks));
|
||||
}
|
||||
|
||||
cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm",
|
||||
cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmccmcmm",
|
||||
asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2),
|
||||
asn1_integer("c", cert->serialNumber),
|
||||
asn1_algorithmIdentifier(cert->algorithm),
|
||||
sig_scheme,
|
||||
issuer->get_encoding(issuer),
|
||||
asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||
asn1_from_time(&cert->notBefore, ASN1_UTCTIME),
|
||||
|
@ -2568,13 +2579,14 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
|
|||
subject->get_encoding(subject),
|
||||
key_info, extensions);
|
||||
|
||||
if (!sign_key->sign(sign_key, scheme, NULL, cert->tbsCertificate,
|
||||
&cert->signature))
|
||||
if (!sign_key->sign(sign_key, cert->scheme->scheme, cert->scheme->params,
|
||||
cert->tbsCertificate, &cert->signature))
|
||||
{
|
||||
chunk_free(&sig_scheme);
|
||||
return FALSE;
|
||||
}
|
||||
cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm", cert->tbsCertificate,
|
||||
asn1_algorithmIdentifier(cert->algorithm),
|
||||
sig_scheme,
|
||||
asn1_bitstring("c", cert->signature));
|
||||
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||
|
@ -2638,7 +2650,7 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
|
|||
private_x509_cert_t *cert;
|
||||
certificate_t *sign_cert = NULL;
|
||||
private_key_t *sign_key = NULL;
|
||||
hash_algorithm_t digest_alg = HASH_SHA1;
|
||||
hash_algorithm_t digest_alg = HASH_SHA256;
|
||||
u_int constraint;
|
||||
|
||||
cert = create_empty();
|
||||
|
@ -2830,6 +2842,10 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
|
|||
case BUILD_SERIAL:
|
||||
cert->serialNumber = 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;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2017 Tobias Brunner
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
|
@ -121,9 +122,9 @@ struct private_x509_crl_t {
|
|||
chunk_t baseCrlNumber;
|
||||
|
||||
/**
|
||||
* Signature algorithm
|
||||
* Signature scheme
|
||||
*/
|
||||
int algorithm;
|
||||
signature_params_t *scheme;
|
||||
|
||||
/**
|
||||
* Signature
|
||||
|
@ -225,7 +226,7 @@ static bool parse(private_x509_crl_t *this)
|
|||
chunk_t extnID = chunk_empty;
|
||||
chunk_t userCertificate = chunk_empty;
|
||||
int objectID;
|
||||
int sig_alg = OID_UNKNOWN;
|
||||
signature_params_t sig_alg = {};
|
||||
bool success = FALSE;
|
||||
bool critical = FALSE;
|
||||
revoked_t *revoked = NULL;
|
||||
|
@ -246,7 +247,11 @@ static bool parse(private_x509_crl_t *this)
|
|||
DBG2(DBG_ASN, " v%d", this->version);
|
||||
break;
|
||||
case CRL_OBJ_SIG_ALG:
|
||||
sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
|
||||
if (!signature_params_parse(object, level, &sig_alg))
|
||||
{
|
||||
DBG1(DBG_ASN, " unable to parse signature algorithm");
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case CRL_OBJ_ISSUER:
|
||||
this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
|
||||
|
@ -342,8 +347,13 @@ static bool parse(private_x509_crl_t *this)
|
|||
}
|
||||
case CRL_OBJ_ALGORITHM:
|
||||
{
|
||||
this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
|
||||
if (this->algorithm != sig_alg)
|
||||
INIT(this->scheme);
|
||||
if (!signature_params_parse(object, level, this->scheme))
|
||||
{
|
||||
DBG1(DBG_ASN, " unable to parse signature algorithm");
|
||||
goto end;
|
||||
}
|
||||
if (!signature_params_equal(this->scheme, &sig_alg))
|
||||
{
|
||||
DBG1(DBG_ASN, " signature algorithms do not agree");
|
||||
goto end;
|
||||
|
@ -361,6 +371,7 @@ static bool parse(private_x509_crl_t *this)
|
|||
|
||||
end:
|
||||
parser->destroy(parser);
|
||||
signature_params_clear(&sig_alg);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -458,10 +469,9 @@ METHOD(certificate_t, has_issuer, id_match_t,
|
|||
|
||||
METHOD(certificate_t, issued_by, bool,
|
||||
private_x509_crl_t *this, certificate_t *issuer,
|
||||
signature_params_t **schemep)
|
||||
signature_params_t **scheme)
|
||||
{
|
||||
public_key_t *key;
|
||||
signature_scheme_t scheme;
|
||||
bool valid;
|
||||
x509_t *x509 = (x509_t*)issuer;
|
||||
chunk_t keyid = chunk_empty;
|
||||
|
@ -493,23 +503,17 @@ METHOD(certificate_t, issued_by, bool,
|
|||
}
|
||||
}
|
||||
|
||||
scheme = signature_scheme_from_oid(this->algorithm);
|
||||
if (scheme == SIGN_UNKNOWN)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
key = issuer->get_public_key(issuer);
|
||||
if (!key)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
valid = key->verify(key, scheme, NULL, this->tbsCertList, this->signature);
|
||||
valid = key->verify(key, this->scheme->scheme, this->scheme->params,
|
||||
this->tbsCertList, this->signature);
|
||||
key->destroy(key);
|
||||
if (valid && schemep)
|
||||
if (valid && scheme)
|
||||
{
|
||||
INIT(*schemep,
|
||||
.scheme = scheme,
|
||||
);
|
||||
*scheme = signature_params_clone(this->scheme);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
@ -596,6 +600,7 @@ METHOD(certificate_t, destroy, void,
|
|||
this->revoked->destroy_function(this->revoked, (void*)revoked_destroy);
|
||||
this->crl_uris->destroy_function(this->crl_uris,
|
||||
(void*)x509_cdp_destroy);
|
||||
signature_params_destroy(this->scheme);
|
||||
DESTROY_IF(this->issuer);
|
||||
free(this->authKeyIdentifier.ptr);
|
||||
free(this->encoding.ptr);
|
||||
|
@ -712,6 +717,7 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
|
|||
{
|
||||
chunk_t extensions = chunk_empty, certList = chunk_empty, serial;
|
||||
chunk_t crlDistributionPoints = chunk_empty, baseCrlNumber = chunk_empty;
|
||||
chunk_t sig_scheme = chunk_empty;
|
||||
enumerator_t *enumerator;
|
||||
crl_reason_t reason;
|
||||
time_t date;
|
||||
|
@ -724,10 +730,20 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
|
|||
|
||||
this->authKeyIdentifier = chunk_clone(x509->get_subjectKeyIdentifier(x509));
|
||||
|
||||
/* select signature scheme */
|
||||
this->algorithm = hasher_signature_algorithm_to_oid(digest_alg,
|
||||
key->get_type(key));
|
||||
if (this->algorithm == OID_UNKNOWN)
|
||||
/* select signature scheme, if not already specified */
|
||||
if (!this->scheme)
|
||||
{
|
||||
INIT(this->scheme,
|
||||
.scheme = signature_scheme_from_oid(
|
||||
hasher_signature_algorithm_to_oid(digest_alg,
|
||||
key->get_type(key))),
|
||||
);
|
||||
}
|
||||
if (this->scheme->scheme == SIGN_UNKNOWN)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!signature_params_build(this->scheme, &sig_scheme))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -781,23 +797,24 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
|
|||
asn1_integer("c", this->crlNumber))),
|
||||
crlDistributionPoints, baseCrlNumber));
|
||||
|
||||
this->tbsCertList = asn1_wrap(ASN1_SEQUENCE, "cmcmmmm",
|
||||
this->tbsCertList = asn1_wrap(ASN1_SEQUENCE, "cccmmmm",
|
||||
ASN1_INTEGER_1,
|
||||
asn1_algorithmIdentifier(this->algorithm),
|
||||
sig_scheme,
|
||||
this->issuer->get_encoding(this->issuer),
|
||||
asn1_from_time(&this->thisUpdate, ASN1_UTCTIME),
|
||||
asn1_from_time(&this->nextUpdate, ASN1_UTCTIME),
|
||||
asn1_wrap(ASN1_SEQUENCE, "m", certList),
|
||||
extensions);
|
||||
|
||||
if (!key->sign(key, signature_scheme_from_oid(this->algorithm), NULL,
|
||||
if (!key->sign(key, this->scheme->scheme, this->scheme->params,
|
||||
this->tbsCertList, &this->signature))
|
||||
{
|
||||
chunk_free(&sig_scheme);
|
||||
return FALSE;
|
||||
}
|
||||
this->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm",
|
||||
this->tbsCertList,
|
||||
asn1_algorithmIdentifier(this->algorithm),
|
||||
sig_scheme,
|
||||
asn1_bitstring("c", this->signature));
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -836,6 +853,10 @@ x509_crl_t *x509_crl_gen(certificate_type_t type, va_list args)
|
|||
crl->crlNumber = va_arg(args, chunk_t);
|
||||
crl->crlNumber = chunk_clone(crl->crlNumber);
|
||||
continue;
|
||||
case BUILD_SIGNATURE_SCHEME:
|
||||
crl->scheme = va_arg(args, signature_params_t*);
|
||||
crl->scheme = signature_params_clone(crl->scheme);
|
||||
continue;
|
||||
case BUILD_DIGEST_ALG:
|
||||
digest_alg = va_arg(args, int);
|
||||
continue;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/**
|
||||
/*
|
||||
* Copyright (C) 2017 Tobias Brunner
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Copyright (C) 2007-2015 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
|
@ -63,9 +64,9 @@ struct private_x509_ocsp_response_t {
|
|||
chunk_t tbsResponseData;
|
||||
|
||||
/**
|
||||
* signature algorithm (OID)
|
||||
* signature scheme
|
||||
*/
|
||||
int signatureAlgorithm;
|
||||
signature_params_t *scheme;
|
||||
|
||||
/**
|
||||
* signature
|
||||
|
@ -576,8 +577,13 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
|
|||
}
|
||||
break;
|
||||
case BASIC_RESPONSE_ALGORITHM:
|
||||
this->signatureAlgorithm = asn1_parse_algorithmIdentifier(object,
|
||||
parser->get_level(parser)+1, NULL);
|
||||
INIT(this->scheme);
|
||||
if (!signature_params_parse(object, parser->get_level(parser)+1,
|
||||
this->scheme))
|
||||
{
|
||||
DBG1(DBG_ASN, " unable to parse signature algorithm");
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case BASIC_RESPONSE_SIGNATURE:
|
||||
this->signature = chunk_skip(object, 1);
|
||||
|
@ -703,10 +709,9 @@ METHOD(certificate_t, has_issuer, id_match_t,
|
|||
|
||||
METHOD(certificate_t, issued_by, bool,
|
||||
private_x509_ocsp_response_t *this, certificate_t *issuer,
|
||||
signature_params_t **schemep)
|
||||
signature_params_t **scheme)
|
||||
{
|
||||
public_key_t *key;
|
||||
signature_scheme_t scheme;
|
||||
bool valid;
|
||||
x509_t *x509 = (x509_t*)issuer;
|
||||
|
||||
|
@ -743,24 +748,17 @@ METHOD(certificate_t, issued_by, bool,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* get the public key of the issuer */
|
||||
key = issuer->get_public_key(issuer);
|
||||
|
||||
/* determine signature scheme */
|
||||
scheme = signature_scheme_from_oid(this->signatureAlgorithm);
|
||||
|
||||
if (scheme == SIGN_UNKNOWN || key == NULL)
|
||||
if (!key)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
valid = key->verify(key, scheme, NULL, this->tbsResponseData,
|
||||
this->signature);
|
||||
valid = key->verify(key, this->scheme->scheme, this->scheme->params,
|
||||
this->tbsResponseData, this->signature);
|
||||
key->destroy(key);
|
||||
if (valid && schemep)
|
||||
if (valid && scheme)
|
||||
{
|
||||
INIT(*schemep,
|
||||
.scheme = scheme,
|
||||
);
|
||||
*scheme = signature_params_clone(this->scheme);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
@ -842,6 +840,7 @@ METHOD(certificate_t, destroy, void,
|
|||
{
|
||||
this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
|
||||
this->responses->destroy_function(this->responses, free);
|
||||
signature_params_destroy(this->scheme);
|
||||
DESTROY_IF(this->responderId);
|
||||
free(this->encoding.ptr);
|
||||
free(this);
|
||||
|
@ -882,7 +881,6 @@ static x509_ocsp_response_t *load(chunk_t blob)
|
|||
.producedAt = UNDEFINED_TIME,
|
||||
.usableUntil = UNDEFINED_TIME,
|
||||
.responses = linked_list_create(),
|
||||
.signatureAlgorithm = OID_UNKNOWN,
|
||||
.certs = linked_list_create(),
|
||||
);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue