]> git.ipfire.org Git - people/ms/strongswan.git/commitdiff
charon-nm: Simplify certificate enumeration and allow IDs other than DNs
authorTobias Brunner <tobias@strongswan.org>
Wed, 9 Jun 2021 14:36:57 +0000 (16:36 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 14 Jun 2021 10:13:47 +0000 (12:13 +0200)
This allows using SANs as identity instead of having to use the subject DN.

References strongswan/strongswan#437.

src/charon-nm/nm/nm_creds.c

index 2660d6f5a451be66a8e4373e405b36d2876b8269..2aede7ff0ff3cd434ce3b81b5325ff97760f70b7 100644 (file)
@@ -77,32 +77,11 @@ struct private_nm_creds_t {
 };
 
 /**
- * Enumerator for user certificate
+ * Enumerator for user certificate (lock has to be locked)
  */
 static enumerator_t *create_usercert_enumerator(private_nm_creds_t *this,
                                                        certificate_type_t cert, key_type_t key)
 {
-       public_key_t *public;
-
-       if (cert != CERT_ANY && cert != this->usercert->get_type(this->usercert))
-       {
-               return NULL;
-       }
-       if (key != KEY_ANY)
-       {
-               public = this->usercert->get_public_key(this->usercert);
-               if (!public)
-               {
-                       return NULL;
-               }
-               if (public->get_type(public) != key)
-               {
-                       public->destroy(public);
-                       return NULL;
-               }
-               public->destroy(public);
-       }
-       this->lock->read_lock(this->lock);
        return enumerator_create_cleaner(
                                                                enumerator_create_single(this->usercert, NULL),
                                                                (void*)this->lock->unlock, this->lock);
@@ -114,6 +93,8 @@ static enumerator_t *create_usercert_enumerator(private_nm_creds_t *this,
 typedef struct {
        /** ref to credential credential store */
        private_nm_creds_t *this;
+       /** certificate type we are looking for */
+       certificate_type_t type;
        /** type of key we are looking for */
        key_type_t key;
        /** CA certificate ID */
@@ -131,55 +112,36 @@ CALLBACK(cert_filter, bool,
        cert_data_t *data, enumerator_t *orig, va_list args)
 {
        certificate_t *cert, **out;
-       public_key_t *public;
 
        VA_ARGS_VGET(args, out);
 
        while (orig->enumerate(orig, &cert))
        {
-               public = cert->get_public_key(cert);
-               if (!public)
+               if (certificate_matches(cert, data->type, data->key, data->id))
                {
-                       continue;
-               }
-               if (data->key != KEY_ANY && public->get_type(public) != data->key)
-               {
-                       public->destroy(public);
-                       continue;
-               }
-               if (data->id && data->id->get_type(data->id) == ID_KEY_ID &&
-                       public->has_fingerprint(public, data->id->get_encoding(data->id)))
-               {
-                       public->destroy(public);
                        *out = cert;
                        return TRUE;
                }
-               public->destroy(public);
-               if (data->id && !cert->has_subject(cert, data->id))
-               {
-                       continue;
-               }
-               *out = cert;
-               return TRUE;
        }
        return FALSE;
 }
 
 /**
- * Create enumerator for trusted certificates
+ * Create enumerator for trusted certificates (lock has to be locked)
  */
 static enumerator_t *create_trusted_cert_enumerator(private_nm_creds_t *this,
-                                                                               key_type_t key, identification_t *id)
+                                                                               certificate_type_t type, key_type_t key,
+                                                                               identification_t *id)
 {
        cert_data_t *data;
 
        INIT(data,
                .this = this,
-               .id = id,
+               .type = type,
                .key = key,
+               .id = id,
        );
 
-       this->lock->read_lock(this->lock);
        return enumerator_create_filter(
                                        this->certs->create_enumerator(this->certs),
                                        cert_filter, data, cert_data_destroy);
@@ -189,16 +151,14 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
        private_nm_creds_t *this, certificate_type_t cert, key_type_t key,
        identification_t *id, bool trusted)
 {
+       this->lock->read_lock(this->lock);
+
        if (id && this->usercert &&
-               id->equals(id, this->usercert->get_subject(this->usercert)))
+               certificate_matches(this->usercert, cert, key, id))
        {
                return create_usercert_enumerator(this, cert, key);
        }
-       if (cert == CERT_X509 || cert == CERT_ANY)
-       {
-               return create_trusted_cert_enumerator(this, key, id);
-       }
-       return NULL;
+       return create_trusted_cert_enumerator(this, cert, key, id);
 }
 
 METHOD(credential_set_t, create_private_enumerator, enumerator_t*,