diff options
Diffstat (limited to 'src/libstrongswan/plugins/x509')
-rw-r--r-- | src/libstrongswan/plugins/x509/Makefile.in | 2 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_ac.c | 89 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_cert.c | 97 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_crl.c | 85 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_ocsp_request.c | 4 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_ocsp_response.c | 35 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_pkcs10.c | 80 |
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; |