]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Verify trustchain for each candidate certificate only once
authorMartin Willi <martin@revosec.ch>
Thu, 23 Dec 2010 13:36:20 +0000 (14:36 +0100)
committerMartin Willi <martin@revosec.ch>
Wed, 5 Jan 2011 15:46:06 +0000 (16:46 +0100)
src/libstrongswan/credentials/credential_manager.c

index a3f9a53cb15f97f57404c5f4bab9f46bcf3552a9..91ed3cfb46c4d9680c50b951265e1b25f0b2860d 100644 (file)
@@ -656,6 +656,14 @@ static bool verify_trust_chain(private_credential_manager_t *this,
        return trusted;
 }
 
+/**
+ * List find match function for certificates
+ */
+static bool cert_equals(certificate_t *a, certificate_t *b)
+{
+       return a->equals(a, b);
+}
+
 /**
  * enumerator for trusted certificates
  */
@@ -676,6 +684,8 @@ typedef struct {
        certificate_t *pretrusted;
        /** currently enumerating auth config */
        auth_cfg_t *auth;
+       /** list of failed candidates */
+       linked_list_t *failed;
 } trusted_enumerator_t;
 
 METHOD(enumerator_t, trusted_enumerate, bool,
@@ -723,6 +733,12 @@ METHOD(enumerator_t, trusted_enumerate, bool,
                        continue;
                }
 
+               if (this->failed->find_first(this->failed, (void*)cert_equals,
+                                                                        NULL, current) == SUCCESS)
+               {       /* check each candidate only once */
+                       continue;
+               }
+
                DBG1(DBG_CFG, "  using certificate \"%Y\"",
                         current->get_subject(current));
                if (verify_trust_chain(this->this, current, this->auth, FALSE,
@@ -735,6 +751,7 @@ METHOD(enumerator_t, trusted_enumerate, bool,
                        }
                        return TRUE;
                }
+               this->failed->insert_last(this->failed, current->get_ref(current));
        }
        return FALSE;
 }
@@ -745,6 +762,7 @@ METHOD(enumerator_t, trusted_destroy, void,
        DESTROY_IF(this->pretrusted);
        DESTROY_IF(this->auth);
        DESTROY_IF(this->candidates);
+       this->failed->destroy_offset(this->failed, offsetof(certificate_t, destroy));
        free(this);
 }
 
@@ -763,6 +781,7 @@ METHOD(credential_manager_t, create_trusted_enumerator, enumerator_t*,
                .type = type,
                .id = id,
                .online = online,
+               .failed = linked_list_create(),
        );
        return &enumerator->public;
 }