summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/x509
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/x509')
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.c89
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c97
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.c85
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_request.c4
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_response.c35
-rw-r--r--src/libstrongswan/plugins/x509/x509_pkcs10.c80
7 files changed, 237 insertions, 155 deletions
diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in
index 3596d1f85..0f54f8cf0 100644
--- a/src/libstrongswan/plugins/x509/Makefile.in
+++ b/src/libstrongswan/plugins/x509/Makefile.in
@@ -246,9 +246,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c
index ba459288b..7a5a31af7 100644
--- a/src/libstrongswan/plugins/x509/x509_ac.c
+++ b/src/libstrongswan/plugins/x509/x509_ac.c
@@ -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,
- 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;
}
@@ -886,10 +914,10 @@ METHOD(certificate_t, has_issuer, id_match_t,
}
METHOD(certificate_t, issued_by, bool,
- private_x509_ac_t *this, certificate_t *issuer, signature_scheme_t *schemep)
+ private_x509_ac_t *this, certificate_t *issuer,
+ signature_params_t **scheme)
{
public_key_t *key;
- signature_scheme_t scheme;
bool valid;
x509_t *x509 = (x509_t*)issuer;
@@ -926,18 +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, 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)
{
- *schemep = scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -1020,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);
@@ -1126,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();
@@ -1157,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:
@@ -1170,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;
}
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
index 974e687f9..d1f9d9aac 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.c
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -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
@@ -241,16 +241,6 @@ static bool gn_to_string(identification_t *id, char **uri)
}
/**
- * Destroy a CertificateDistributionPoint
- */
-static void crl_uri_destroy(x509_cdp_t *this)
-{
- free(this->uri);
- DESTROY_IF(this->issuer);
- free(this);
-}
-
-/**
* Destroy a CertificatePolicy
*/
static void cert_policy_destroy(x509_cert_policy_t *this)
@@ -1385,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;
@@ -1416,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);
@@ -1570,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;
@@ -1588,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;
@@ -1687,10 +1687,9 @@ METHOD(certificate_t, has_issuer, id_match_t,
METHOD(certificate_t, issued_by, bool,
private_x509_cert_t *this, certificate_t *issuer,
- signature_scheme_t *schemep)
+ signature_params_t **scheme)
{
public_key_t *key;
- signature_scheme_t scheme;
bool valid;
x509_t *x509 = (x509_t*)issuer;
@@ -1698,6 +1697,10 @@ METHOD(certificate_t, issued_by, bool,
{
if (this->flags & X509_SELF_SIGNED)
{
+ if (scheme)
+ {
+ *scheme = signature_params_clone(this->scheme);
+ }
return TRUE;
}
}
@@ -1717,23 +1720,18 @@ METHOD(certificate_t, issued_by, bool,
return FALSE;
}
- /* determine signature scheme */
- scheme = signature_scheme_from_oid(this->algorithm);
- if (scheme == SIGN_UNKNOWN)
- {
- return FALSE;
- }
/* get the public key of the issuer */
key = issuer->get_public_key(issuer);
if (!key)
{
return FALSE;
}
- valid = key->verify(key, scheme, this->tbsCertificate, this->signature);
+ valid = key->verify(key, this->scheme->scheme, this->scheme->params,
+ this->tbsCertificate, this->signature);
key->destroy(key);
- if (valid && schemep)
+ if (valid && scheme)
{
- *schemep = scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -1920,7 +1918,8 @@ METHOD(certificate_t, destroy, void,
{
this->subjectAltNames->destroy_offset(this->subjectAltNames,
offsetof(identification_t, destroy));
- this->crl_uris->destroy_function(this->crl_uris, (void*)crl_uri_destroy);
+ this->crl_uris->destroy_function(this->crl_uris,
+ (void*)x509_cdp_destroy);
this->ocsp_uris->destroy_function(this->ocsp_uris, free);
this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
offsetof(traffic_selector_t, destroy));
@@ -1932,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);
@@ -2187,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;
@@ -2223,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;
}
@@ -2559,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),
@@ -2570,12 +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, 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);
@@ -2639,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();
@@ -2831,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;
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
index d8913ad73..699ac5a39 100644
--- a/src/libstrongswan/plugins/x509/x509_crl.c
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -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;
}
@@ -457,10 +468,10 @@ METHOD(certificate_t, has_issuer, id_match_t,
}
METHOD(certificate_t, issued_by, bool,
- private_x509_crl_t *this, certificate_t *issuer, signature_scheme_t *schemep)
+ private_x509_crl_t *this, certificate_t *issuer,
+ 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;
@@ -492,21 +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, 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)
{
- *schemep = scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -585,23 +592,15 @@ static void revoked_destroy(revoked_t *revoked)
free(revoked);
}
-/**
- * Destroy a CDP entry
- */
-static void cdp_destroy(x509_cdp_t *this)
-{
- free(this->uri);
- DESTROY_IF(this->issuer);
- free(this);
-}
-
METHOD(certificate_t, destroy, void,
private_x509_crl_t *this)
{
if (ref_put(&this->ref))
{
this->revoked->destroy_function(this->revoked, (void*)revoked_destroy);
- this->crl_uris->destroy_function(this->crl_uris, (void*)cdp_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);
@@ -718,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;
@@ -730,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;
}
@@ -787,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),
+ 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;
}
@@ -842,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;
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
index aef76af32..de22ab6be 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
@@ -276,7 +276,7 @@ static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this,
return chunk_empty;
}
- if (!this->key->sign(this->key, scheme, tbsRequest, &signature))
+ if (!this->key->sign(this->key, scheme, NULL, tbsRequest, &signature))
{
DBG1(DBG_LIB, "creating OCSP signature failed, skipped");
return chunk_empty;
@@ -372,7 +372,7 @@ METHOD(certificate_t, has_issuer, id_match_t,
METHOD(certificate_t, issued_by, bool,
private_x509_ocsp_request_t *this, certificate_t *issuer,
- signature_scheme_t *scheme)
+ signature_params_t **scheme)
{
DBG1(DBG_LIB, "OCSP request validation not implemented!");
return FALSE;
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
index 140e9bfa9..aa4999cbd 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
@@ -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_scheme_t *schemep)
+ signature_params_t **scheme)
{
public_key_t *key;
- signature_scheme_t scheme;
bool valid;
x509_t *x509 = (x509_t*)issuer;
@@ -743,21 +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, 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)
{
- *schemep = scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -839,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);
@@ -879,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(),
);
diff --git a/src/libstrongswan/plugins/x509/x509_pkcs10.c b/src/libstrongswan/plugins/x509/x509_pkcs10.c
index e39e24bff..587fbd5d6 100644
--- a/src/libstrongswan/plugins/x509/x509_pkcs10.c
+++ b/src/libstrongswan/plugins/x509/x509_pkcs10.c
@@ -72,9 +72,9 @@ struct private_x509_pkcs10_t {
chunk_t challengePassword;
/**
- * Signature algorithm
+ * Signature scheme
*/
- int algorithm;
+ signature_params_t *scheme;
/**
* Signature
@@ -124,10 +124,9 @@ METHOD(certificate_t, has_subject, id_match_t,
METHOD(certificate_t, issued_by, bool,
private_x509_pkcs10_t *this, certificate_t *issuer,
- signature_scheme_t *schemep)
+ signature_params_t **scheme)
{
public_key_t *key;
- signature_scheme_t scheme;
bool valid;
if (&this->public.interface.interface != issuer)
@@ -136,27 +135,22 @@ METHOD(certificate_t, issued_by, bool,
}
if (this->self_signed)
{
- return TRUE;
+ valid = TRUE;
}
-
- /* determine signature scheme */
- scheme = signature_scheme_from_oid(this->algorithm);
- if (scheme == SIGN_UNKNOWN)
+ else
{
- return FALSE;
- }
-
- /* get the public key contained in the certificate request */
- key = this->public_key;
- if (!key)
- {
- return FALSE;
+ /* get the public key contained in the certificate request */
+ key = this->public_key;
+ if (!key)
+ {
+ return FALSE;
+ }
+ valid = key->verify(key, this->scheme->scheme, this->scheme->params,
+ this->certificationRequestInfo, this->signature);
}
- valid = key->verify(key, scheme, this->certificationRequestInfo,
- this->signature);
- if (valid && schemep)
+ if (valid && scheme)
{
- *schemep = scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -410,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;
}
@@ -438,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);
@@ -474,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);
@@ -530,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;
}
@@ -584,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, 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;
}
@@ -674,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;