Add signature schemes to auth_cfg during trustchain validation
authorMartin Willi <martin@revosec.ch>
Mon, 11 Jun 2012 12:52:37 +0000 (14:52 +0200)
committerMartin Willi <martin@revosec.ch>
Tue, 12 Jun 2012 12:24:49 +0000 (14:24 +0200)
src/libstrongswan/credentials/credential_manager.c
src/libstrongswan/credentials/credential_manager.h
src/libstrongswan/credentials/sets/cert_cache.c
src/libstrongswan/credentials/sets/cert_cache.h
src/libstrongswan/plugins/revocation/revocation_validator.c

index d54359e..8704cd2 100644 (file)
@@ -569,7 +569,8 @@ static certificate_t *get_pretrusted_cert(private_credential_manager_t *this,
  * Get the issuing certificate of a subject certificate
  */
 static certificate_t *get_issuer_cert(private_credential_manager_t *this,
-                                                                         certificate_t *subject, bool trusted)
+                                                                         certificate_t *subject, bool trusted,
+                                                                         signature_scheme_t *scheme)
 {
        enumerator_t *enumerator;
        certificate_t *issuer = NULL, *candidate;
@@ -578,7 +579,7 @@ static certificate_t *get_issuer_cert(private_credential_manager_t *this,
                                                                                subject->get_issuer(subject), trusted);
        while (enumerator->enumerate(enumerator, &candidate))
        {
-               if (this->cache->issued_by(this->cache, subject, candidate))
+               if (this->cache->issued_by(this->cache, subject, candidate, scheme))
                {
                        issuer = candidate->get_ref(candidate);
                        break;
@@ -628,6 +629,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
 {
        certificate_t *current, *issuer;
        auth_cfg_t *auth;
+       signature_scheme_t scheme;
        int pathlen;
 
        auth = auth_cfg_create();
@@ -637,11 +639,11 @@ static bool verify_trust_chain(private_credential_manager_t *this,
 
        for (pathlen = 0; pathlen <= MAX_TRUST_PATH_LEN; pathlen++)
        {
-               issuer = get_issuer_cert(this, current, TRUE);
+               issuer = get_issuer_cert(this, current, TRUE, &scheme);
                if (issuer)
                {
                        /* accept only self-signed CAs as trust anchor */
-                       if (this->cache->issued_by(this->cache, issuer, issuer))
+                       if (this->cache->issued_by(this->cache, issuer, issuer, NULL))
                        {
                                auth->add(auth, AUTH_RULE_CA_CERT, issuer->get_ref(issuer));
                                DBG1(DBG_CFG, "  using trusted ca certificate \"%Y\"",
@@ -654,10 +656,11 @@ static bool verify_trust_chain(private_credential_manager_t *this,
                                DBG1(DBG_CFG, "  using trusted intermediate ca certificate "
                                         "\"%Y\"", issuer->get_subject(issuer));
                        }
+                       auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, scheme);
                }
                else
                {
-                       issuer = get_issuer_cert(this, current, FALSE);
+                       issuer = get_issuer_cert(this, current, FALSE, &scheme);
                        if (issuer)
                        {
                                if (current->equals(current, issuer))
@@ -670,6 +673,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
                                auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer));
                                DBG1(DBG_CFG, "  using untrusted intermediate certificate "
                                         "\"%Y\"", issuer->get_subject(issuer));
+                               auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, scheme);
                        }
                        else
                        {
@@ -764,7 +768,7 @@ METHOD(enumerator_t, trusted_enumerate, bool,
                         * However, in order to fulfill authorization rules, we try to build
                         * the trust chain if it is not self signed */
                        if (this->this->cache->issued_by(this->this->cache,
-                                                                  this->pretrusted, this->pretrusted) ||
+                                                                  this->pretrusted, this->pretrusted, NULL) ||
                                verify_trust_chain(this->this, this->pretrusted, this->auth,
                                                                   TRUE, this->online))
                        {
@@ -972,7 +976,7 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
                else
                {
                        if (!has_anchor &&
-                               this->cache->issued_by(this->cache, current, current))
+                               this->cache->issued_by(this->cache, current, current, NULL))
                        {       /* If no trust anchor specified, accept any CA */
                                trustchain->add(trustchain, AUTH_RULE_CA_CERT, current);
                                return trustchain;
@@ -983,7 +987,7 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
                {
                        break;
                }
-               issuer = get_issuer_cert(this, current, FALSE);
+               issuer = get_issuer_cert(this, current, FALSE, NULL);
                if (!issuer)
                {
                        if (!has_anchor)
@@ -1116,9 +1120,9 @@ METHOD(credential_manager_t, flush_cache, void,
 
 METHOD(credential_manager_t, issued_by, bool,
        private_credential_manager_t *this, certificate_t *subject,
-       certificate_t *issuer)
+       certificate_t *issuer, signature_scheme_t *scheme)
 {
-       return this->cache->issued_by(this->cache, subject, issuer);
+       return this->cache->issued_by(this->cache, subject, issuer, scheme);
 }
 
 METHOD(credential_manager_t, add_set, void,
index ad789c7..d9a47b7 100644 (file)
@@ -204,10 +204,12 @@ struct credential_manager_t {
         *
         * @param subject       subject certificate to check
         * @param issuer        issuer certificate that potentially has signed subject
+        * @param scheme        receives used signature scheme, if given
         * @return                      TRUE if issuer signed subject
         */
        bool (*issued_by)(credential_manager_t *this,
-                                         certificate_t *subject, certificate_t *issuer);
+                                         certificate_t *subject, certificate_t *issuer,
+                                         signature_scheme_t *scheme);
 
        /**
         * Register a credential set to the manager.
index 24007ba..a7d0ed8 100644 (file)
@@ -47,6 +47,11 @@ struct relation_t {
        certificate_t *issuer;
 
        /**
+        * Signature scheme used to sign this relation
+        */
+       signature_scheme_t scheme;
+
+       /**
         * Cache hits
         */
        u_int hits;
@@ -77,7 +82,8 @@ struct private_cert_cache_t {
  * Cache relation in a free slot/replace an other
  */
 static void cache(private_cert_cache_t *this,
-                                 certificate_t *subject, certificate_t *issuer)
+                                 certificate_t *subject, certificate_t *issuer,
+                                 signature_scheme_t scheme)
 {
        relation_t *rel;
        int i, offset, try;
@@ -95,6 +101,7 @@ static void cache(private_cert_cache_t *this,
                        {
                                rel->subject = subject->get_ref(subject);
                                rel->issuer = issuer->get_ref(issuer);
+                               rel->scheme = scheme;
                                return rel->lock->unlock(rel->lock);
                        }
                        rel->lock->unlock(rel->lock);
@@ -123,6 +130,7 @@ static void cache(private_cert_cache_t *this,
                                }
                                rel->subject = subject->get_ref(subject);
                                rel->issuer = issuer->get_ref(issuer);
+                               rel->scheme = scheme;
                                rel->hits = 0;
                                return rel->lock->unlock(rel->lock);
                        }
@@ -133,9 +141,11 @@ static void cache(private_cert_cache_t *this,
 }
 
 METHOD(cert_cache_t, issued_by, bool,
-       private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer)
+       private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer,
+       signature_scheme_t *schemep)
 {
        relation_t *found = NULL, *current;
+       signature_scheme_t scheme;
        int i;
 
        for (i = 0; i < CACHE_SIZE; i++)
@@ -154,7 +164,11 @@ METHOD(cert_cache_t, issued_by, bool,
                                {
                                        /* write hit counter is not locked, but not critical */
                                        current->hits++;
-                                       found = current;
+                                       found = current;;
+                                       if (schemep)
+                                       {
+                                               *schemep = current->scheme;
+                                       }
                                }
                        }
                }
@@ -165,9 +179,13 @@ METHOD(cert_cache_t, issued_by, bool,
                }
        }
        /* no cache hit, check and cache signature */
-       if (subject->issued_by(subject, issuer, NULL))
+       if (subject->issued_by(subject, issuer, &scheme))
        {
-               cache(this, subject, issuer);
+               cache(this, subject, issuer, scheme);
+               if (schemep)
+               {
+                       *schemep = scheme;
+               }
                return TRUE;
        }
        return FALSE;
index d272186..2bcdbe4 100644 (file)
@@ -45,10 +45,12 @@ struct cert_cache_t {
         *
         * @param subject               certificate to verify
         * @param issuer                issuing certificate to verify subject
+        * @param scheme                receives used signature scheme, if given
         * @return                              TRUE if subject issued by issuer
         */
        bool (*issued_by)(cert_cache_t *this,
-                                         certificate_t *subject, certificate_t *issuer);
+                                         certificate_t *subject, certificate_t *issuer,
+                                         signature_scheme_t *scheme);
 
        /**
         * Flush the certificate cache.
index ff3ef14..dc8e454 100644 (file)
@@ -111,7 +111,7 @@ static bool verify_ocsp(ocsp_response_t *response, auth_cfg_t *auth)
                                                                                                        KEY_ANY, responder, FALSE);
        while (enumerator->enumerate(enumerator, &issuer, &current))
        {
-               if (lib->credmgr->issued_by(lib->credmgr, subject, issuer))
+               if (lib->credmgr->issued_by(lib->credmgr, subject, issuer, NULL))
                {
                        DBG1(DBG_CFG, "  ocsp response correctly signed by \"%Y\"",
                                                         issuer->get_subject(issuer));
@@ -341,7 +341,7 @@ static bool verify_crl(certificate_t *crl, auth_cfg_t *auth)
                                                                                KEY_ANY, crl->get_issuer(crl), FALSE);
        while (enumerator->enumerate(enumerator, &issuer, &current))
        {
-               if (lib->credmgr->issued_by(lib->credmgr, crl, issuer))
+               if (lib->credmgr->issued_by(lib->credmgr, crl, issuer, NULL))
                {
                        DBG1(DBG_CFG, "  crl correctly signed by \"%Y\"",
                                                   issuer->get_subject(issuer));