]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
cga: Provide a virtual trust anchor for CGA parameter certificates
authorMartin Willi <martin@revosec.ch>
Wed, 28 Jan 2015 15:55:33 +0000 (16:55 +0100)
committerMartin Willi <martin@revosec.ch>
Tue, 24 Feb 2015 16:13:57 +0000 (17:13 +0100)
To give CGA parameters trust, we must validate it as certificate. To do so, a
static credential set provides a CA certificate as virtual trust anchor. If
enabled, any valid CGA parameters certificate can authenticate a matching IPv6
CGA identity.

As this allows any user to successfully authenticate with an IPv6 CGA, care
must be taken to limit connections to make use of CGA authenticated identities.
This is achieved by requiring a "trust" option to be explicitly enabled by the
administrator.

conf/Makefile.am
conf/plugins/cga.opt [new file with mode: 0644]
src/libstrongswan/plugins/cga/Makefile.am
src/libstrongswan/plugins/cga/cga_plugin.c
src/libstrongswan/plugins/cga/cga_trust.c [new file with mode: 0644]
src/libstrongswan/plugins/cga/cga_trust.h [new file with mode: 0644]

index 1085e48e1163a4cf530f73fabab0e3314e74e6a6..1d0cfde777dd890a176ad373ec70af39af089011 100644 (file)
@@ -29,6 +29,7 @@ plugins = \
        plugins/attr.opt \
        plugins/attr-sql.opt \
        plugins/certexpire.opt \
+       plugins/cga.opt \
        plugins/coupling.opt \
        plugins/dhcp.opt \
        plugins/dnscert.opt \
diff --git a/conf/plugins/cga.opt b/conf/plugins/cga.opt
new file mode 100644 (file)
index 0000000..59ab148
--- /dev/null
@@ -0,0 +1,9 @@
+charon.plugins.cga.trust = no
+       Whether to trust CGA verified IPv6 identities.
+
+       If set to yes, any CGA verified IPv6 identity is trusted and allows a
+       peer to authenticate with that identity. As anybody can generate a CGA
+       for a given public key, any peer can successfully authenticate with that
+       CGA. To exclude CGA authenticated IDs from specific connection definitions,
+       public key constraints may be used. Because of the security implications,
+       CGA trust is disabled by default.
index 25f0e1b82d760c7e55554b29822b14086c1b9426..e09d0a3e5a09f6502bf076edc394829d8aa45b6c 100644 (file)
@@ -12,6 +12,7 @@ endif
 
 libstrongswan_cga_la_SOURCES = \
        cga_cert.h cga_cert.c \
+       cga_trust.h cga_trust.c \
        cga_plugin.h cga_plugin.c
 
 libstrongswan_cga_la_LDFLAGS = -module -avoid-version
index 598d87ec1dff5c5ac1b66b135f6ab2925c333eab..a38ada5efcf1a639d5da850ddb09d3da456a9824 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "cga_plugin.h"
 #include "cga_cert.h"
+#include "cga_trust.h"
 
 #include <library.h>
 
@@ -29,6 +30,11 @@ struct private_cga_plugin_t {
         * Public functions
         */
        cga_plugin_t public;
+
+       /**
+        * Credential set providing a virtual CGA trust anchor
+        */
+       cga_trust_t *trust;
 };
 
 METHOD(plugin_t, get_name, char*,
@@ -54,9 +60,24 @@ METHOD(plugin_t, get_features, int,
        return countof(f);
 }
 
+METHOD(plugin_t, reload, bool,
+       private_cga_plugin_t *this)
+{
+       lib->credmgr->remove_set(lib->credmgr, &this->trust->set);
+       lib->credmgr->flush_cache(lib->credmgr, CERT_CGA_PARAMS);
+       if (lib->settings->get_bool(lib->settings,
+                                                               "%s.plugins.cga.trust", FALSE, lib->ns))
+       {
+               lib->credmgr->add_set(lib->credmgr, &this->trust->set);
+       }
+       return TRUE;
+}
+
 METHOD(plugin_t, destroy, void,
        private_cga_plugin_t *this)
 {
+       lib->credmgr->remove_set(lib->credmgr, &this->trust->set);
+       this->trust->destroy(this->trust);
        free(this);
 }
 
@@ -72,10 +93,14 @@ plugin_t *cga_plugin_create()
                        .plugin = {
                                .get_name = _get_name,
                                .get_features = _get_features,
+                               .reload = _reload,
                                .destroy = _destroy,
                        },
                },
+               .trust = cga_trust_create(),
        );
 
+       reload(this);
+
        return &this->public.plugin;
 }
diff --git a/src/libstrongswan/plugins/cga/cga_trust.c b/src/libstrongswan/plugins/cga/cga_trust.c
new file mode 100644 (file)
index 0000000..b4a62e2
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "cga_trust.h"
+
+#include <library.h>
+#include <utils/debug.h>
+
+
+typedef struct private_cga_trust_t private_cga_trust_t;
+typedef struct private_cga_anchor_t private_cga_anchor_t;
+
+/**
+ * Private data of a cga_trust_t object.
+ */
+struct private_cga_trust_t {
+
+       /**
+        * Public interface for this credential set.
+        */
+       cga_trust_t public;
+
+       /**
+        * Trust anchor identity
+        */
+       identification_t *ta;
+};
+
+/**
+ * Private data of trust anchor certificate.
+ */
+struct private_cga_anchor_t {
+
+       /**
+        * Implements certificate_t.
+        */
+       certificate_t public;
+
+       /**
+        * Trust anchor identity
+        */
+       identification_t *ta;
+
+       /**
+        * Reference count
+        */
+       refcount_t ref;
+};
+
+METHOD(certificate_t, get_type, certificate_type_t,
+       private_cga_anchor_t *this)
+{
+       return CERT_CGA_PARAMS;
+}
+
+METHOD(certificate_t, get_ta, identification_t*,
+       private_cga_anchor_t *this)
+{
+       return this->ta;
+}
+
+METHOD(certificate_t, has_ta, id_match_t,
+       private_cga_anchor_t *this, identification_t *id)
+{
+       return this->ta->matches(this->ta, id);
+}
+
+METHOD(certificate_t, issued_by, bool,
+       private_cga_anchor_t *this, certificate_t *issuer,
+       signature_scheme_t *schemep)
+{
+       if (&this->public == issuer)
+       {
+               if (schemep)
+               {
+                       *schemep = SIGN_CGA_SHA1;
+               }
+               return TRUE;
+       }
+       return FALSE;
+}
+
+METHOD(certificate_t, get_public_key, public_key_t*,
+       private_cga_anchor_t *this)
+{
+       return NULL;
+}
+
+METHOD(certificate_t, get_ref, certificate_t*,
+       private_cga_anchor_t *this)
+{
+       ref_get(&this->ref);
+       return &this->public;
+}
+
+METHOD(certificate_t, get_validity, bool,
+       private_cga_anchor_t *this, time_t *when, time_t *not_before,
+       time_t *not_after)
+{
+       if (not_before)
+       {
+               *not_before = UNDEFINED_TIME;
+       }
+       if (not_after)
+       {
+               *not_after = UNDEFINED_TIME;
+       }
+       return TRUE;
+}
+
+METHOD(certificate_t, get_encoding, bool,
+       private_cga_anchor_t *this, cred_encoding_type_t type, chunk_t *encoding)
+{
+       return FALSE;
+}
+
+METHOD(certificate_t, equals, bool,
+       private_cga_anchor_t *this, certificate_t *other)
+{
+       return &this->public == other;
+}
+
+METHOD(certificate_t, anchor_destroy, void,
+       private_cga_anchor_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               free(this);
+       }
+}
+
+METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
+       private_cga_trust_t *this, certificate_type_t cert, key_type_t key,
+       identification_t *id, bool trusted)
+{
+       private_cga_anchor_t *anchor;
+
+       if (cert != CERT_CGA_PARAMS)
+       {
+               return enumerator_create_empty();
+       }
+       if (id && !id->matches(id, this->ta))
+       {
+               return enumerator_create_empty();
+       }
+
+       INIT(anchor,
+               .public = {
+                       .get_type = _get_type,
+                       .get_subject = _get_ta,
+                       .get_issuer = _get_ta,
+                       .has_subject = _has_ta,
+                       .has_issuer = _has_ta,
+                       .issued_by = _issued_by,
+                       .get_public_key = _get_public_key,
+                       .get_validity = _get_validity,
+                       .get_encoding = _get_encoding,
+                       .equals = _equals,
+                       .get_ref = _get_ref,
+                       .destroy = _anchor_destroy,
+               },
+               .ref = 1,
+               .ta = this->ta,
+       );
+
+       return enumerator_create_single(anchor, (void*)anchor_destroy);
+}
+
+METHOD(cga_trust_t, destroy, void,
+       private_cga_trust_t *this)
+{
+       this->ta->destroy(this->ta);
+       free(this);
+}
+
+/**
+ * See header.
+ */
+cga_trust_t *cga_trust_create()
+{
+       private_cga_trust_t *this;
+
+       INIT(this,
+               .public = {
+                       .set = {
+                               .create_shared_enumerator = (void*)enumerator_create_empty,
+                               .create_private_enumerator = (void*)enumerator_create_empty,
+                               .create_cert_enumerator = _create_cert_enumerator,
+                               .create_cdp_enumerator  = (void*)enumerator_create_empty,
+                               .cache_cert = (void*)nop,
+                       },
+                       .destroy = _destroy,
+               },
+               .ta = identification_create_from_string("CGA Trust Anchor"),
+       );
+
+       return &this->public;
+}
diff --git a/src/libstrongswan/plugins/cga/cga_trust.h b/src/libstrongswan/plugins/cga/cga_trust.h
new file mode 100644 (file)
index 0000000..5bda2d4
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup cga_trust cga_trust
+ * @{ @ingroup cga_p
+ */
+
+#ifndef CGA_TRUST_H_
+#define CGA_TRUST_H_
+
+typedef struct cga_trust_t cga_trust_t;
+
+#include <credentials/builder.h>
+#include <credentials/certificates/certificate.h>
+
+/**
+ * IPv6 CGA trust anchor provider.
+ */
+struct cga_trust_t {
+
+       /**
+        * Implements the credential_set_t
+        */
+       credential_set_t set;
+
+       /**
+        * Destroy credential set.
+        */
+       void (*destroy)(cga_trust_t *this);
+};
+
+/**
+ * Create a credential set providing a trust anchor for verified CGAs.
+ *
+ * @return                     credential set
+ */
+cga_trust_t *cga_trust_create();
+
+#endif /** CGA_TRUST_H_ @}*/