diff options
Diffstat (limited to 'src/libstrongswan/credentials/credential_manager.c')
-rw-r--r-- | src/libstrongswan/credentials/credential_manager.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index 97e8d8887..3e54368ff 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -452,8 +452,13 @@ static void cache_queue(private_credential_manager_t *this) * check a certificate for its lifetime */ static bool check_certificate(private_credential_manager_t *this, +<<<<<<< HEAD certificate_t *subject, certificate_t *issuer, bool online, int pathlen, auth_cfg_t *auth) +======= + certificate_t *subject, certificate_t *issuer, bool online, + int pathlen, bool trusted, auth_cfg_t *auth) +>>>>>>> upstream/4.5.1 { time_t not_before, not_after; cert_validator_t *validator; @@ -471,6 +476,7 @@ static bool check_certificate(private_credential_manager_t *this, ¬_before, FALSE, ¬_after, FALSE); return FALSE; } +<<<<<<< HEAD if (issuer->get_type(issuer) == CERT_X509 && subject->get_type(subject) == CERT_X509) { @@ -488,12 +494,18 @@ static bool check_certificate(private_credential_manager_t *this, return FALSE; } } +======= +>>>>>>> upstream/4.5.1 enumerator = this->validators->create_enumerator(this->validators); while (enumerator->enumerate(enumerator, &validator)) { if (!validator->validate(validator, subject, issuer, +<<<<<<< HEAD online, pathlen, auth)) +======= + online, pathlen, trusted, auth)) +>>>>>>> upstream/4.5.1 { enumerator->destroy(enumerator); return FALSE; @@ -551,6 +563,40 @@ static certificate_t *get_issuer_cert(private_credential_manager_t *this, } /** +<<<<<<< HEAD +======= + * Get the strength of certificate, add it to auth + */ +static void get_key_strength(certificate_t *cert, auth_cfg_t *auth) +{ + uintptr_t strength; + public_key_t *key; + key_type_t type; + + key = cert->get_public_key(cert); + if (key) + { + type = key->get_type(key); + strength = key->get_keysize(key); + DBG2(DBG_CFG, " certificate \"%Y\" key: %d bit %N", + cert->get_subject(cert), strength, key_type_names, type); + switch (type) + { + case KEY_RSA: + auth->add(auth, AUTH_RULE_RSA_STRENGTH, strength); + break; + case KEY_ECDSA: + auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength); + break; + default: + break; + } + key->destroy(key); + } +} + +/** +>>>>>>> upstream/4.5.1 * try to verify the trust chain of subject, return TRUE if trusted */ static bool verify_trust_chain(private_credential_manager_t *this, @@ -562,7 +608,13 @@ static bool verify_trust_chain(private_credential_manager_t *this, int pathlen; auth = auth_cfg_create(); +<<<<<<< HEAD + current = subject->get_ref(subject); +======= + get_key_strength(subject, auth); current = subject->get_ref(subject); + auth->add(auth, AUTH_RULE_SUBJECT_CERT, current->get_ref(current)); +>>>>>>> upstream/4.5.1 for (pathlen = 0; pathlen <= MAX_TRUST_PATH_LEN; pathlen++) { @@ -607,13 +659,25 @@ static bool verify_trust_chain(private_credential_manager_t *this, break; } } +<<<<<<< HEAD if (!check_certificate(this, current, issuer, online, pathlen, current == subject ? auth : NULL)) +======= + if (!check_certificate(this, current, issuer, online, + pathlen, trusted, auth)) +>>>>>>> upstream/4.5.1 { trusted = FALSE; issuer->destroy(issuer); break; } +<<<<<<< HEAD +======= + if (issuer) + { + get_key_strength(issuer, auth); + } +>>>>>>> upstream/4.5.1 current->destroy(current); current = issuer; if (trusted) @@ -637,6 +701,17 @@ static bool verify_trust_chain(private_credential_manager_t *this, } /** +<<<<<<< HEAD +======= + * List find match function for certificates + */ +static bool cert_equals(certificate_t *a, certificate_t *b) +{ + return a->equals(a, b); +} + +/** +>>>>>>> upstream/4.5.1 * enumerator for trusted certificates */ typedef struct { @@ -656,6 +731,11 @@ typedef struct { certificate_t *pretrusted; /** currently enumerating auth config */ auth_cfg_t *auth; +<<<<<<< HEAD +======= + /** list of failed candidates */ + linked_list_t *failed; +>>>>>>> upstream/4.5.1 } trusted_enumerator_t; METHOD(enumerator_t, trusted_enumerate, bool, @@ -683,11 +763,22 @@ METHOD(enumerator_t, trusted_enumerate, bool, verify_trust_chain(this->this, this->pretrusted, this->auth, TRUE, this->online)) { +<<<<<<< HEAD this->auth->add(this->auth, AUTH_RULE_SUBJECT_CERT, this->pretrusted->get_ref(this->pretrusted)); DBG1(DBG_CFG, " using trusted certificate \"%Y\"", this->pretrusted->get_subject(this->pretrusted)); *cert = this->pretrusted; +======= + DBG1(DBG_CFG, " using trusted certificate \"%Y\"", + this->pretrusted->get_subject(this->pretrusted)); + *cert = this->pretrusted; + if (!this->auth->get(this->auth, AUTH_RULE_SUBJECT_CERT)) + { /* add cert to auth info, if not returned by trustchain */ + this->auth->add(this->auth, AUTH_RULE_SUBJECT_CERT, + this->pretrusted->get_ref(this->pretrusted)); + } +>>>>>>> upstream/4.5.1 if (auth) { *auth = this->auth; @@ -705,6 +796,15 @@ METHOD(enumerator_t, trusted_enumerate, bool, continue; } +<<<<<<< HEAD +======= + if (this->failed->find_first(this->failed, (void*)cert_equals, + NULL, current) == SUCCESS) + { /* check each candidate only once */ + continue; + } + +>>>>>>> upstream/4.5.1 DBG1(DBG_CFG, " using certificate \"%Y\"", current->get_subject(current)); if (verify_trust_chain(this->this, current, this->auth, FALSE, @@ -717,6 +817,10 @@ METHOD(enumerator_t, trusted_enumerate, bool, } return TRUE; } +<<<<<<< HEAD +======= + this->failed->insert_last(this->failed, current->get_ref(current)); +>>>>>>> upstream/4.5.1 } return FALSE; } @@ -727,6 +831,10 @@ METHOD(enumerator_t, trusted_destroy, void, DESTROY_IF(this->pretrusted); DESTROY_IF(this->auth); DESTROY_IF(this->candidates); +<<<<<<< HEAD +======= + this->failed->destroy_offset(this->failed, offsetof(certificate_t, destroy)); +>>>>>>> upstream/4.5.1 free(this); } @@ -745,6 +853,10 @@ METHOD(credential_manager_t, create_trusted_enumerator, enumerator_t*, .type = type, .id = id, .online = online, +<<<<<<< HEAD +======= + .failed = linked_list_create(), +>>>>>>> upstream/4.5.1 ); return &enumerator->public; } |