Try to build a trustchain for all configured certificates before enforcing one
authorMartin Willi <martin@revosec.ch>
Tue, 8 Jan 2013 13:53:12 +0000 (14:53 +0100)
committerMartin Willi <martin@revosec.ch>
Fri, 18 Jan 2013 08:33:15 +0000 (09:33 +0100)
This enables the daemon to select from multiple configured certificates
by building trustchains against the received certificate requests.

src/libstrongswan/credentials/credential_manager.c

index 9e40c5a..4bd2403 100644 (file)
@@ -1049,6 +1049,7 @@ METHOD(credential_manager_t, get_private, private_key_t*,
        certificate_t *cert;
        private_key_t *private = NULL;
        auth_cfg_t *trustchain;
+       auth_rule_t rule;
 
        /* check if this is a lookup by key ID, and do it if so */
        if (id && id->get_type(id) == ID_KEY_ID)
@@ -1062,7 +1063,34 @@ METHOD(credential_manager_t, get_private, private_key_t*,
 
        if (auth)
        {
-               /* if a specific certificate is preferred, check for a matching key */
+               /* try to find a trustchain with one of the configured subject certs */
+               enumerator = auth->create_enumerator(auth);
+               while (enumerator->enumerate(enumerator, &rule, &cert))
+               {
+                       if (rule == AUTH_RULE_SUBJECT_CERT)
+                       {
+                               private = get_private_by_cert(this, cert, type);
+                               if (private)
+                               {
+                                       trustchain = build_trustchain(this, cert, auth);
+                                       if (trustchain)
+                                       {
+                                               auth->merge(auth, trustchain, FALSE);
+                                               trustchain->destroy(trustchain);
+                                               break;
+                                       }
+                                       private->destroy(private);
+                                       private = NULL;
+                               }
+                       }
+               }
+               enumerator->destroy(enumerator);
+               if (private)
+               {
+                       return private;
+               }
+
+               /* if none yielded a trustchain, enforce the first configured cert */
                cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
                if (cert)
                {