From 919019b3cde6e1dc6aa5dab931aed8c15794f46a Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Tue, 26 Aug 2008 05:15:34 +0000 Subject: [PATCH] completed support of AUTHZ_CA_CERT and AUTHZ_CA_CERT_NAME attributes --- src/charon/credentials/credential_manager.c | 1 + src/charon/plugins/stroke/stroke_config.c | 35 ++++++++++++++--- src/charon/plugins/stroke/stroke_list.c | 43 +++++++++++++++------ src/charon/sa/tasks/ike_cert_pre.c | 31 +++++++++++---- 4 files changed, 87 insertions(+), 23 deletions(-) diff --git a/src/charon/credentials/credential_manager.c b/src/charon/credentials/credential_manager.c index 9902e40d8..48d066e17 100644 --- a/src/charon/credentials/credential_manager.c +++ b/src/charon/credentials/credential_manager.c @@ -1181,6 +1181,7 @@ static bool trusted_enumerate(trusted_enumerator_t *this, verify_trust_chain(this->this, this->pretrusted, this->auth, TRUE, this->crl, this->ocsp)) { + this->auth->add_item(this->auth, AUTHZ_CA_CERT, this->pretrusted); DBG1(DBG_CFG, " using trusted certificate \"%D\"", this->pretrusted->get_subject(this->pretrusted)); *cert = this->pretrusted; diff --git a/src/charon/plugins/stroke/stroke_config.c b/src/charon/plugins/stroke/stroke_config.c index 9df19dcc5..e9a9cc99d 100644 --- a/src/charon/plugins/stroke/stroke_config.c +++ b/src/charon/plugins/stroke/stroke_config.c @@ -335,7 +335,9 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg * build a peer_cfg from a stroke msg */ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this, - stroke_msg_t *msg, ike_cfg_t *ike_cfg) + stroke_msg_t *msg, ike_cfg_t *ike_cfg, + identification_t **my_issuer, + identification_t **other_issuer) { identification_t *me, *other, *peer_id = NULL; peer_cfg_t *mediated_by = NULL; @@ -420,6 +422,9 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this, cert = this->cred->load_peer(this->cred, msg->add_conn.me.cert); if (cert) { + identification_t *issuer = cert->get_issuer(cert); + + *my_issuer = issuer->clone(issuer); this->ca->check_for_hash_and_url(this->ca, cert); me = update_peerid(cert, me); cert->destroy(cert); @@ -430,6 +435,9 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this, cert = this->cred->load_peer(this->cred, msg->add_conn.other.cert); if (cert) { + identification_t *issuer = cert->get_issuer(cert); + + *other_issuer = issuer->clone(issuer); other = update_peerid(cert, other); cert->destroy(cert); } @@ -511,9 +519,11 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this, * fill in auth_info from stroke message */ static void build_auth_info(private_stroke_config_t *this, - stroke_msg_t *msg, auth_info_t *auth) + stroke_msg_t *msg, auth_info_t *auth, + identification_t *my_ca, + identification_t *other_ca) { - identification_t *my_ca = NULL, *other_ca = NULL, *id; + identification_t *id; bool my_ca_same = FALSE; bool other_ca_same = FALSE; cert_validation_t valid; @@ -539,6 +549,11 @@ static void build_auth_info(private_stroke_config_t *this, if (msg->add_conn.me.ca) { + if (my_ca) + { + my_ca->destroy(my_ca); + my_ca = NULL; + } if (streq(msg->add_conn.me.ca, "%same")) { my_ca_same = TRUE; @@ -548,8 +563,14 @@ static void build_auth_info(private_stroke_config_t *this, my_ca = identification_create_from_string(msg->add_conn.me.ca); } } + if (msg->add_conn.other.ca) { + if (other_ca) + { + other_ca->destroy(other_ca); + other_ca = NULL; + } if (streq(msg->add_conn.other.ca, "%same")) { other_ca_same = TRUE; @@ -559,6 +580,7 @@ static void build_auth_info(private_stroke_config_t *this, other_ca = identification_create_from_string(msg->add_conn.other.ca); } } + if (other_ca_same && my_ca) { other_ca = my_ca->clone(my_ca); @@ -584,6 +606,7 @@ static void build_auth_info(private_stroke_config_t *this, } other_ca->destroy(other_ca); } + if (my_ca) { DBG2(DBG_CFG, " my ca: %D", my_ca); @@ -737,6 +760,7 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg) ike_cfg_t *ike_cfg, *existing_ike; peer_cfg_t *peer_cfg, *existing; child_cfg_t *child_cfg; + identification_t *my_issuer = NULL, *other_issuer = NULL; enumerator_t *enumerator; bool use_existing = FALSE; @@ -745,14 +769,15 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg) { return; } - peer_cfg = build_peer_cfg(this, msg, ike_cfg); + peer_cfg = build_peer_cfg(this, msg, ike_cfg, &my_issuer, &other_issuer); if (!peer_cfg) { ike_cfg->destroy(ike_cfg); return; } - build_auth_info(this, msg, peer_cfg->get_auth(peer_cfg)); + build_auth_info(this, msg, peer_cfg->get_auth(peer_cfg), + my_issuer, other_issuer); enumerator = create_peer_cfg_enumerator(this, NULL, NULL); while (enumerator->enumerate(enumerator, &existing)) { diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c index 9e2418fcd..03c6ba15a 100644 --- a/src/charon/plugins/stroke/stroke_list.c +++ b/src/charon/plugins/stroke/stroke_list.c @@ -236,7 +236,6 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo if (all) { - identification_t *any_issuer = identification_create_from_string("%any"); peer_cfg_t *peer_cfg; char *plugin; host_t *host; @@ -274,11 +273,12 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends); while (enumerator->enumerate(enumerator, (void**)&peer_cfg)) { + void *ptr; + certificate_t *cert; auth_item_t item; auth_info_t *auth; enumerator_t *auth_enumerator; - certificate_t *cert; - identification_t *my_issuer = NULL, *other_issuer = NULL; + identification_t *my_ca = NULL, *other_ca = NULL; if (peer_cfg->get_ike_version(peer_cfg) != 2 || (name && !streq(name, peer_cfg->get_name(peer_cfg)))) @@ -289,15 +289,23 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo /* determine any required CAs */ auth = peer_cfg->get_auth(peer_cfg); auth_enumerator = auth->create_item_enumerator(auth); - while (auth_enumerator->enumerate(auth_enumerator, &item, &cert)) + while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr)) { switch (item) { case AUTHN_CA_CERT: - my_issuer = cert->get_subject(cert); + cert = (certificate_t *)ptr; + my_ca = cert->get_subject(cert); + break; + case AUTHN_CA_CERT_NAME: + my_ca = (identification_t *)ptr; break; case AUTHZ_CA_CERT: - other_issuer = cert->get_subject(cert); + cert = (certificate_t *)ptr; + other_ca = cert->get_subject(cert); + break; + case AUTHZ_CA_CERT_NAME: + other_ca = (identification_t *)ptr; break; default: break; @@ -309,11 +317,25 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo fprintf(out, "%12s: %s[%D]...%s[%D]\n", peer_cfg->get_name(peer_cfg), ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg), ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg)); - if (my_issuer || other_issuer) + if (my_ca || other_ca) { - fprintf(out, "%12s: CAs: \"%D\"...\"%D\"\n", peer_cfg->get_name(peer_cfg), - my_issuer? my_issuer:any_issuer, - other_issuer? other_issuer:any_issuer); + fprintf(out, "%12s: CAs: ", peer_cfg->get_name(peer_cfg)); + if (my_ca) + { + fprintf(out, "\"%D\"...", my_ca); + } + else + { + fprintf(out, "%%any..."); + } + if (other_ca) + { + fprintf(out, "\"%D\"\n", other_ca); + } + else + { + fprintf(out, "%%any\n"); + } } fprintf(out, "%12s: %N authentication", peer_cfg->get_name(peer_cfg), auth_class_names, get_auth_class(peer_cfg)); @@ -348,7 +370,6 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo children->destroy(children); } enumerator->destroy(enumerator); - any_issuer->destroy(any_issuer); } fprintf(out, "Security Associations:\n"); diff --git a/src/charon/sa/tasks/ike_cert_pre.c b/src/charon/sa/tasks/ike_cert_pre.c index 9e11f300c..79bc4f6e0 100644 --- a/src/charon/sa/tasks/ike_cert_pre.c +++ b/src/charon/sa/tasks/ike_cert_pre.c @@ -336,20 +336,37 @@ static void build_certreqs(private_ike_cert_pre_t *this, message_t *message) peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); if (peer_cfg) { + void *ptr; + identification_t *id; auth_item_t item; auth_info_t *auth = peer_cfg->get_auth(peer_cfg); + enumerator_t *auth_enumerator = auth->create_item_enumerator(auth); - enumerator = auth->create_item_enumerator(auth); - while (enumerator->enumerate(enumerator, &item, &cert)) + while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr)) { - if (item == AUTHZ_CA_CERT) + switch (item) { - restricted = TRUE; - add_certreq_payload(message, &x509_req, cert); + case AUTHZ_CA_CERT: + cert = (certificate_t *)ptr; + add_certreq_payload(message, &x509_req, cert); + restricted = TRUE; + break; + case AUTHZ_CA_CERT_NAME: + id = (identification_t *)ptr; + enumerator = charon->credentials->create_cert_enumerator( + charon->credentials, CERT_ANY, KEY_ANY, id, TRUE); + while (enumerator->enumerate(enumerator, &cert, TRUE)) + { + add_certreq_payload(message, &x509_req, cert); + restricted = TRUE; + } + enumerator->destroy(enumerator); + break; + default: + break; } - /* TODO: handle AUTHZ_CA_CERT_NAME case */ } - enumerator->destroy(enumerator); + auth_enumerator->destroy(auth_enumerator); } if (!restricted)