diff options
Diffstat (limited to 'src/libstrongswan/credentials')
-rw-r--r-- | src/libstrongswan/credentials/auth_cfg.c | 39 | ||||
-rw-r--r-- | src/libstrongswan/credentials/certificates/ocsp_request.h | 2 | ||||
-rw-r--r-- | src/libstrongswan/credentials/certificates/ocsp_response.h | 2 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/mem_cred.c | 58 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/mem_cred.h | 12 |
5 files changed, 84 insertions, 29 deletions
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index 0ca45a15b..1e93f021a 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -514,9 +514,10 @@ METHOD(auth_cfg_t, complies, bool, private_auth_cfg_t *this, auth_cfg_t *constraints, bool log_error) { enumerator_t *e1, *e2; - bool success = TRUE, group_match = FALSE, cert_match = FALSE; + bool success = TRUE, group_match = FALSE; + bool ca_match = FALSE, cert_match = FALSE; identification_t *require_group = NULL; - certificate_t *require_cert = NULL; + certificate_t *require_ca = NULL, *require_cert = NULL; signature_scheme_t scheme = SIGN_UNKNOWN; u_int strength = 0; auth_rule_t t1, t2; @@ -531,26 +532,21 @@ METHOD(auth_cfg_t, complies, bool, case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: { - certificate_t *c1, *c2; + certificate_t *cert; - c1 = (certificate_t*)value; + /* for CA certs, a match of a single cert is sufficient */ + require_ca = (certificate_t*)value; - success = FALSE; e2 = create_enumerator(this); - while (e2->enumerate(e2, &t2, &c2)) + while (e2->enumerate(e2, &t2, &cert)) { if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) && - c1->equals(c1, c2)) + cert->equals(cert, require_ca)) { - success = TRUE; + ca_match = TRUE; } } e2->destroy(e2); - if (!success && log_error) - { - DBG1(DBG_CFG, "constraint check failed: peer not " - "authenticated by CA '%Y'.", c1->get_subject(c1)); - } break; } case AUTH_RULE_SUBJECT_CERT: @@ -665,7 +661,9 @@ METHOD(auth_cfg_t, complies, bool, } case AUTH_RULE_EAP_TYPE: { - if ((uintptr_t)value != (uintptr_t)get(this, t1)) + if ((uintptr_t)value != (uintptr_t)get(this, t1) && + (uintptr_t)value != EAP_DYNAMIC && + (uintptr_t)value != EAP_RADIUS) { success = FALSE; if (log_error) @@ -853,13 +851,22 @@ METHOD(auth_cfg_t, complies, bool, } return FALSE; } - + if (require_ca && !ca_match) + { + if (log_error) + { + DBG1(DBG_CFG, "constraint check failed: peer not " + "authenticated by CA '%Y'", + require_ca->get_subject(require_ca)); + } + return FALSE; + } if (require_cert && !cert_match) { if (log_error) { DBG1(DBG_CFG, "constraint check failed: peer not " - "authenticated with peer cert '%Y'.", + "authenticated with peer cert '%Y'", require_cert->get_subject(require_cert)); } return FALSE; diff --git a/src/libstrongswan/credentials/certificates/ocsp_request.h b/src/libstrongswan/credentials/certificates/ocsp_request.h index 0b1871309..730d95d70 100644 --- a/src/libstrongswan/credentials/certificates/ocsp_request.h +++ b/src/libstrongswan/credentials/certificates/ocsp_request.h @@ -31,7 +31,7 @@ typedef struct ocsp_request_t ocsp_request_t; struct ocsp_request_t { /** - * Implements certificiate_t interface + * Implements certificate_t interface */ certificate_t interface; }; diff --git a/src/libstrongswan/credentials/certificates/ocsp_response.h b/src/libstrongswan/credentials/certificates/ocsp_response.h index 157577458..9c5637b9f 100644 --- a/src/libstrongswan/credentials/certificates/ocsp_response.h +++ b/src/libstrongswan/credentials/certificates/ocsp_response.h @@ -50,7 +50,7 @@ extern enum_name_t *ocsp_status_names; struct ocsp_response_t { /** - * Implements certificiate_t interface + * Implements certificate_t interface */ certificate_t certificate; diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c index 7ad011b5e..4884c4bfa 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.c +++ b/src/libstrongswan/credentials/sets/mem_cred.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013 Tobias Brunner + * Copyright (C) 2010-2015 Tobias Brunner * Hochschule fuer Technik Rapperwsil * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG @@ -197,7 +197,7 @@ METHOD(mem_cred_t, get_cert_ref, certificate_t*, { certificate_t *cached; - this->lock->write_lock(this->lock); + this->lock->read_lock(this->lock); if (this->untrusted->find_first(this->untrusted, (linked_list_match_t)certificate_equals, (void**)&cached, cert) == SUCCESS) @@ -643,6 +643,49 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*, } +static void reset_certs(private_mem_cred_t *this) +{ + this->trusted->destroy_offset(this->trusted, + offsetof(certificate_t, destroy)); + this->untrusted->destroy_offset(this->untrusted, + offsetof(certificate_t, destroy)); + this->trusted = linked_list_create(); + this->untrusted = linked_list_create(); +} + +static void copy_certs(linked_list_t *dst, linked_list_t *src, bool clone) +{ + enumerator_t *enumerator; + certificate_t *cert; + + enumerator = src->create_enumerator(src); + while (enumerator->enumerate(enumerator, &cert)) + { + if (clone) + { + cert = cert->get_ref(cert); + } + else + { + src->remove_at(src, enumerator); + } + dst->insert_last(dst, cert); + } + enumerator->destroy(enumerator); +} + +METHOD(mem_cred_t, replace_certs, void, + private_mem_cred_t *this, mem_cred_t *other_set, bool clone) +{ + private_mem_cred_t *other = (private_mem_cred_t*)other_set; + + this->lock->write_lock(this->lock); + reset_certs(this); + copy_certs(this->untrusted, other->untrusted, clone); + copy_certs(this->trusted, other->trusted, clone); + this->lock->unlock(this->lock); +} + static void reset_secrets(private_mem_cred_t *this) { this->keys->destroy_offset(this->keys, offsetof(private_key_t, destroy)); @@ -710,17 +753,11 @@ METHOD(mem_cred_t, clear_, void, private_mem_cred_t *this) { this->lock->write_lock(this->lock); - this->trusted->destroy_offset(this->trusted, - offsetof(certificate_t, destroy)); - this->untrusted->destroy_offset(this->untrusted, - offsetof(certificate_t, destroy)); this->cdps->destroy_function(this->cdps, (void*)cdp_destroy); - this->trusted = linked_list_create(); - this->untrusted = linked_list_create(); this->cdps = linked_list_create(); + reset_certs(this); + reset_secrets(this); this->lock->unlock(this->lock); - - clear_secrets(this); } METHOD(mem_cred_t, destroy, void, @@ -760,6 +797,7 @@ mem_cred_t *mem_cred_create() .add_shared = _add_shared, .add_shared_list = _add_shared_list, .add_cdp = _add_cdp, + .replace_certs = _replace_certs, .replace_secrets = _replace_secrets, .clear = _clear_, .clear_secrets = _clear_secrets, diff --git a/src/libstrongswan/credentials/sets/mem_cred.h b/src/libstrongswan/credentials/sets/mem_cred.h index 3ce815abc..51f0b8c30 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.h +++ b/src/libstrongswan/credentials/sets/mem_cred.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013 Tobias Brunner + * Copyright (C) 2010-2015 Tobias Brunner * Hochschule fuer Technik Rapperswil * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG @@ -102,6 +102,7 @@ struct mem_cred_t { */ void (*add_shared_list)(mem_cred_t *this, shared_key_t *shared, linked_list_t *owners); + /** * Add a certificate distribution point to the set. * @@ -113,6 +114,15 @@ struct mem_cred_t { identification_t *id, char *uri); /** + * Replace all certificates in this credential set with those of another. + * + * @param other credential set to get certificates from + * @param clone TRUE to clone certs, FALSE to adopt them (they + * get removed from the other set) + */ + void (*replace_certs)(mem_cred_t *this, mem_cred_t *other, bool clone); + + /** * Replace all secrets (private and shared keys) in this credential set * with those of another. * |