Merge branch 'eap-constraints'
authorMartin Willi <martin@revosec.ch>
Tue, 3 Mar 2015 13:08:55 +0000 (14:08 +0100)
committerMartin Willi <martin@revosec.ch>
Tue, 3 Mar 2015 13:08:55 +0000 (14:08 +0100)
Introduces basic support for EAP server module authentication constraints. With
EAP-(T)TLS, public key, signature and end entity or CA certificate constraints
can be enforced for connections.

Fixes #762.

14 files changed:
NEWS
man/ipsec.conf.5.in
src/libcharon/plugins/eap_tls/eap_tls.c
src/libcharon/plugins/eap_ttls/eap_ttls.c
src/libcharon/plugins/stroke/stroke_config.c
src/libcharon/sa/eap/eap_method.h
src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
src/libtls/tls.c
src/libtls/tls.h
src/libtls/tls_eap.c
src/libtls/tls_eap.h
src/libtls/tls_handshake.h
src/libtls/tls_peer.c
src/libtls/tls_server.c

diff --git a/NEWS b/NEWS
index 51688d2..8dc5e31 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,11 @@ strongswan-5.3.0
   Windows 7 IKEv2 clients, which announces its services over the tunnel if the
   negotiated IPsec policy allows it.
 
+- EAP server methods now can fulfill public key constraints, such as rightcert
+  or rightca. Additionally, public key and signature constraints can be
+  specified for EAP methods in the rightauth keyword. Currently the EAP-TLS and
+  EAP-TTLS methods provide verification details to constraints checking.
+
 - Upgrade of the BLISS post-quantum signature algorithm to the improved BLISS-B
   variant. Can be used in conjunction with the SHA256, SHA384 and SHA512 hash
   algorithms with SHA512 being the default.
index 851bd17..696c6a1 100644 (file)
@@ -614,7 +614,9 @@ Alternatively, IANA assigned EAP method numbers are accepted. Vendor specific
 EAP methods are defined in the form
 .B eap-type-vendor
 .RB "(e.g. " eap-7-12345 ).
-For
+To specify signature and trust chain constraints for EAP-(T)TLS, append a colon
+to the EAP method, followed by the key type/size and hash algorithm as discussed
+above. For
 .B xauth,
 an XAuth authentication backend can be specified, such as
 .B xauth-generic
index dffbaf2..bc01ba5 100644 (file)
@@ -109,6 +109,12 @@ METHOD(eap_method_t, is_mutual, bool,
        return TRUE;
 }
 
+METHOD(eap_method_t, get_auth, auth_cfg_t*,
+       private_eap_tls_t *this)
+{
+       return this->tls_eap->get_auth(this->tls_eap);
+}
+
 METHOD(eap_method_t, destroy, void,
        private_eap_tls_t *this)
 {
@@ -138,6 +144,7 @@ static eap_tls_t *eap_tls_create(identification_t *server,
                                .get_msk = _get_msk,
                                .get_identifier = _get_identifier,
                                .set_identifier = _set_identifier,
+                               .get_auth = _get_auth,
                                .destroy = _destroy,
                        },
                },
index 703cd3f..c99d47f 100644 (file)
@@ -111,6 +111,12 @@ METHOD(eap_method_t, is_mutual, bool,
        return TRUE;
 }
 
+METHOD(eap_method_t, get_auth, auth_cfg_t*,
+       private_eap_ttls_t *this)
+{
+       return this->tls_eap->get_auth(this->tls_eap);
+}
+
 METHOD(eap_method_t, destroy, void,
        private_eap_ttls_t *this)
 {
@@ -141,6 +147,7 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
                                .get_identifier = _get_identifier,
                                .set_identifier = _set_identifier,
                                .get_msk = _get_msk,
+                               .get_auth = _get_auth,
                                .destroy = _destroy,
                        },
                },
index 3e40a78..88abe49 100644 (file)
@@ -620,9 +620,16 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
        else if (strpfx(auth, "eap"))
        {
                eap_vendor_type_t *type;
+               char *pos;
 
                cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
-
+               /* check for public key constraints for EAP-TLS etc. */
+               pos = strchr(auth, ':');
+               if (pos)
+               {
+                       *pos = 0;
+                       parse_pubkey_constraints(pos + 1, cfg);
+               }
                type = eap_vendor_type_from_string(auth);
                if (type)
                {
index 6242a5a..689c0f9 100644 (file)
@@ -137,6 +137,18 @@ struct eap_method_t {
        void (*set_identifier) (eap_method_t *this, u_int8_t identifier);
 
        /**
+        * Get authentication details performed by this EAP method.
+        *
+        * After EAP completion, the auth data contains additional information
+        * of the authentication process, used certificates etc.
+        * This method is optional to implement, but if it is, it must return
+        * a valid auth_cfg.
+        *
+        * @return                              auth method, internal data
+        */
+       auth_cfg_t* (*get_auth)(eap_method_t *this);
+
+       /**
         * Destroys a eap_method_t object.
         */
        void (*destroy) (eap_method_t *this);
index eed6d19..ebef319 100644 (file)
@@ -522,6 +522,13 @@ METHOD(authenticator_t, process_server, status_t,
                {
                        return FAILED;
                }
+               if (this->method->get_auth)
+               {
+                       auth_cfg_t *auth;
+
+                       auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+                       auth->merge(auth, this->method->get_auth(this->method), FALSE);
+               }
                return NEED_MORE;
        }
 
index 2016124..08a06f5 100644 (file)
@@ -415,6 +415,12 @@ METHOD(tls_t, get_eap_msk, chunk_t,
        return this->crypto->get_eap_msk(this->crypto);
 }
 
+METHOD(tls_t, get_auth, auth_cfg_t*,
+       private_tls_t *this)
+{
+       return this->handshake->get_auth(this->handshake);
+}
+
 METHOD(tls_t, destroy, void,
        private_tls_t *this)
 {
@@ -465,6 +471,7 @@ tls_t *tls_create(bool is_server, identification_t *server,
                        .get_purpose = _get_purpose,
                        .is_complete = _is_complete,
                        .get_eap_msk = _get_eap_msk,
+                       .get_auth = _get_auth,
                        .destroy = _destroy,
                },
                .is_server = is_server,
index fc1d9b9..f3dc198 100644 (file)
@@ -252,6 +252,13 @@ struct tls_t {
        chunk_t (*get_eap_msk)(tls_t *this);
 
        /**
+        * Get the authentication details after completing the handshake.
+        *
+        * @return                      authentication details, internal data
+        */
+       auth_cfg_t* (*get_auth)(tls_t *this);
+
+       /**
         * Destroy a tls_t.
         */
        void (*destroy)(tls_t *this);
index ebe5bc3..12d5aed 100644 (file)
@@ -426,6 +426,12 @@ METHOD(tls_eap_t, set_identifier, void,
        this->identifier = identifier;
 }
 
+METHOD(tls_eap_t, get_auth, auth_cfg_t*,
+       private_tls_eap_t *this)
+{
+       return this->tls->get_auth(this->tls);
+}
+
 METHOD(tls_eap_t, destroy, void,
        private_tls_eap_t *this)
 {
@@ -453,6 +459,7 @@ tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size,
                        .get_msk = _get_msk,
                        .get_identifier = _get_identifier,
                        .set_identifier = _set_identifier,
+                       .get_auth = _get_auth,
                        .destroy = _destroy,
                },
                .type = type,
index f3fbba0..df41fc4 100644 (file)
@@ -77,6 +77,13 @@ struct tls_eap_t {
        void (*set_identifier) (tls_eap_t *this, uint8_t identifier);
 
        /**
+        * Get the authentication details after completing the handshake.
+        *
+        * @return                              authentication details, internal data
+        */
+       auth_cfg_t* (*get_auth)(tls_eap_t *this);
+
+       /**
         * Destroy a tls_eap_t.
         */
        void (*destroy)(tls_eap_t *this);
index 7fa660c..7edb49b 100644 (file)
@@ -98,6 +98,13 @@ struct tls_handshake_t {
        identification_t* (*get_server_id)(tls_handshake_t *this);
 
        /**
+        * Get the peers authentication information after completing the handshake.
+        *
+        * @return                      authentication data, internal data
+        */
+       auth_cfg_t* (*get_auth)(tls_handshake_t *this);
+
+       /**
         * Destroy a tls_handshake_t.
         */
        void (*destroy)(tls_handshake_t *this);
index a95b40f..08e36de 100644 (file)
@@ -324,6 +324,7 @@ static public_key_t *find_public_key(private_tls_peer_t *this)
                while (enumerator->enumerate(enumerator, &current, &auth))
                {
                        public = current->get_ref(current);
+                       this->server_auth->merge(this->server_auth, auth, FALSE);
                        break;
                }
                enumerator->destroy(enumerator);
@@ -1153,6 +1154,12 @@ METHOD(tls_handshake_t, get_server_id, identification_t*,
        return this->server;
 }
 
+METHOD(tls_handshake_t, get_auth, auth_cfg_t*,
+       private_tls_peer_t *this)
+{
+       return this->server_auth;
+}
+
 METHOD(tls_handshake_t, destroy, void,
        private_tls_peer_t *this)
 {
@@ -1186,6 +1193,7 @@ tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto, tls_alert_t *alert
                                .finished = _finished,
                                .get_peer_id = _get_peer_id,
                                .get_server_id = _get_server_id,
+                               .get_auth = _get_auth,
                                .destroy = _destroy,
                        },
                },
index aeb5a71..b6e706d 100644 (file)
@@ -551,6 +551,7 @@ static status_t process_cert_verify(private_tls_server_t *this,
                sig->destroy(sig);
                if (verified)
                {
+                       this->peer_auth->merge(this->peer_auth, auth, FALSE);
                        break;
                }
                DBG1(DBG_TLS, "signature verification failed, trying another key");
@@ -1073,6 +1074,12 @@ METHOD(tls_handshake_t, get_server_id, identification_t*,
        return this->server;
 }
 
+METHOD(tls_handshake_t, get_auth, auth_cfg_t*,
+       private_tls_server_t *this)
+{
+       return this->peer_auth;
+}
+
 METHOD(tls_handshake_t, destroy, void,
        private_tls_server_t *this)
 {
@@ -1107,6 +1114,7 @@ tls_server_t *tls_server_create(tls_t *tls,
                                .finished = _finished,
                                .get_peer_id = _get_peer_id,
                                .get_server_id = _get_server_id,
+                               .get_auth = _get_auth,
                                .destroy = _destroy,
                        },
                },