]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
certificate: Extract helper function to filter certificates
authorTobias Brunner <tobias@strongswan.org>
Wed, 20 May 2020 12:25:33 +0000 (14:25 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 20 Jul 2020 12:05:38 +0000 (14:05 +0200)
src/libcharon/plugins/stroke/stroke_ca.c
src/libstrongswan/credentials/certificates/certificate.c
src/libstrongswan/credentials/certificates/certificate.h
src/libstrongswan/credentials/sets/mem_cred.c

index bfaa9a9d94a742555d484507fd0fd43b0e7d6e36..0dbe707455fbfc29286e6b966901fde03f757d0f 100644 (file)
@@ -175,46 +175,15 @@ CALLBACK(certs_filter, bool,
        cert_data_t *data, enumerator_t *orig, va_list args)
 {
        ca_cert_t *cacert;
-       public_key_t *public;
        certificate_t **out;
 
        VA_ARGS_VGET(args, out);
 
        while (orig->enumerate(orig, &cacert))
        {
-               certificate_t *cert = cacert->cert;
-
-               if (data->cert != CERT_ANY && data->cert != cert->get_type(cert))
-               {
-                       continue;
-               }
-               public = cert->get_public_key(cert);
-               if (public)
-               {
-                       if (data->key == KEY_ANY || data->key == public->get_type(public))
-                       {
-                               if (data->id && public->has_fingerprint(public,
-                                                                                       data->id->get_encoding(data->id)))
-                               {
-                                       public->destroy(public);
-                                       *out = cert;
-                                       return TRUE;
-                               }
-                       }
-                       else
-                       {
-                               public->destroy(public);
-                               continue;
-                       }
-                       public->destroy(public);
-               }
-               else if (data->key != KEY_ANY)
-               {
-                       continue;
-               }
-               if (!data->id || cert->has_subject(cert, data->id))
+               if (certificate_matches(cacert->cert, data->cert, data->key, data->id))
                {
-                       *out = cert;
+                       *out = cacert->cert;
                        return TRUE;
                }
        }
index 76108298667434f124f7c6580cc86d30c826d582..d8e2223b703432401a189108a23297bd2611d368 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2020 Tobias Brunner
  * Copyright (C) 2007 Martin Willi
  * Copyright (C) 2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
@@ -61,3 +62,40 @@ bool certificate_is_newer(certificate_t *this, certificate_t *other)
                 type, &that_update, FALSE, newer ? "replaced" : "retained");
        return newer;
 }
+
+/*
+ * Described in header
+ */
+bool certificate_matches(certificate_t *cert, certificate_type_t type,
+                                                key_type_t key, identification_t *id)
+{
+       public_key_t *public;
+
+       if (type != CERT_ANY && type != cert->get_type(cert))
+       {
+               return FALSE;
+       }
+       public = cert->get_public_key(cert);
+       if (public)
+       {
+               if (key == KEY_ANY || key == public->get_type(public))
+               {
+                       if (id && public->has_fingerprint(public, id->get_encoding(id)))
+                       {
+                               public->destroy(public);
+                               return TRUE;
+                       }
+               }
+               else
+               {
+                       public->destroy(public);
+                       return FALSE;
+               }
+               public->destroy(public);
+       }
+       else if (key != KEY_ANY)
+       {
+               return FALSE;
+       }
+       return !id || cert->has_subject(cert, id);
+}
index 71620aa9132cc1d0de19d4ba7b13f2e658de1004..cf2f2ae698f5e912cad1c9c6497088ed785a0804 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2020 Tobias Brunner
  * Copyright (C) 2007-2008 Martin Willi
  * HSR Hochschule fuer Technik Rapperswil
  *
@@ -204,4 +205,18 @@ struct certificate_t {
  */
 bool certificate_is_newer(certificate_t *cert, certificate_t *other);
 
+/**
+ * Check if the given certificate matches the given type, key type and identity,
+ * all of which are optional.
+ *
+ * Note that the identity may also be a public key fingerprint.
+ *
+ * @param cert                 certificate
+ * @param type                 certificate type to match, or CERT_ANY
+ * @param key                  key type to match, or KEY_ANY
+ * @param id                   identity to match, or NULL
+ */
+bool certificate_matches(certificate_t *cert, certificate_type_t type,
+                                                key_type_t key, identification_t *id);
+
 #endif /** CERTIFICATE_H_ @}*/
index 86b232a3ed62794cf648595729781dc5e0812eb5..0a4d512d2a4cd6c8d3bde9f10fb35a44c3662060 100644 (file)
@@ -84,42 +84,13 @@ CALLBACK(cert_data_destroy, void,
 CALLBACK(certs_filter, bool,
        cert_data_t *data, enumerator_t *orig, va_list args)
 {
-       public_key_t *public;
        certificate_t *cert, **out;
 
        VA_ARGS_VGET(args, out);
 
        while (orig->enumerate(orig, &cert))
        {
-               if (data->cert != CERT_ANY && data->cert != cert->get_type(cert))
-               {
-                       continue;
-               }
-               public = cert->get_public_key(cert);
-               if (public)
-               {
-                       if (data->key == KEY_ANY || data->key == public->get_type(public))
-                       {
-                               if (data->id && public->has_fingerprint(public,
-                                                                                       data->id->get_encoding(data->id)))
-                               {
-                                       public->destroy(public);
-                                       *out = cert;
-                                       return TRUE;
-                               }
-                       }
-                       else
-                       {
-                               public->destroy(public);
-                               continue;
-                       }
-                       public->destroy(public);
-               }
-               else if (data->key != KEY_ANY)
-               {
-                       continue;
-               }
-               if (!data->id || cert->has_subject(cert, data->id))
+               if (certificate_matches(cert, data->cert, data->key, data->id))
                {
                        *out = cert;
                        return TRUE;