diff --git a/NEWS b/NEWS index 51688d264..8dc5e314d 100644 --- 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. diff --git a/man/ipsec.conf.5.in b/man/ipsec.conf.5.in index 851bd1750..696c6a12f 100644 --- a/man/ipsec.conf.5.in +++ b/man/ipsec.conf.5.in @@ -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 diff --git a/src/libcharon/plugins/eap_tls/eap_tls.c b/src/libcharon/plugins/eap_tls/eap_tls.c index dffbaf266..bc01ba5df 100644 --- a/src/libcharon/plugins/eap_tls/eap_tls.c +++ b/src/libcharon/plugins/eap_tls/eap_tls.c @@ -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, }, }, diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.c b/src/libcharon/plugins/eap_ttls/eap_ttls.c index 703cd3f29..c99d47f8d 100644 --- a/src/libcharon/plugins/eap_ttls/eap_ttls.c +++ b/src/libcharon/plugins/eap_ttls/eap_ttls.c @@ -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, }, }, diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index 3e40a7888..88abe4951 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -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) { diff --git a/src/libcharon/sa/eap/eap_method.h b/src/libcharon/sa/eap/eap_method.h index 6242a5a6e..689c0f990 100644 --- a/src/libcharon/sa/eap/eap_method.h +++ b/src/libcharon/sa/eap/eap_method.h @@ -136,6 +136,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. */ diff --git a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c index eed6d1996..ebef31930 100644 --- a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c +++ b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c @@ -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; } diff --git a/src/libtls/tls.c b/src/libtls/tls.c index 201612470..08a06f5ef 100644 --- a/src/libtls/tls.c +++ b/src/libtls/tls.c @@ -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, diff --git a/src/libtls/tls.h b/src/libtls/tls.h index fc1d9b9fd..f3dc198cf 100644 --- a/src/libtls/tls.h +++ b/src/libtls/tls.h @@ -251,6 +251,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. */ diff --git a/src/libtls/tls_eap.c b/src/libtls/tls_eap.c index ebe5bc3a8..12d5aed53 100644 --- a/src/libtls/tls_eap.c +++ b/src/libtls/tls_eap.c @@ -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, diff --git a/src/libtls/tls_eap.h b/src/libtls/tls_eap.h index f3fbba078..df41fc4d7 100644 --- a/src/libtls/tls_eap.h +++ b/src/libtls/tls_eap.h @@ -76,6 +76,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. */ diff --git a/src/libtls/tls_handshake.h b/src/libtls/tls_handshake.h index 7fa660c58..7edb49ba0 100644 --- a/src/libtls/tls_handshake.h +++ b/src/libtls/tls_handshake.h @@ -97,6 +97,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. */ diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c index a95b40f55..08e36de36 100644 --- a/src/libtls/tls_peer.c +++ b/src/libtls/tls_peer.c @@ -324,6 +324,7 @@ static public_key_t *find_public_key(private_tls_peer_t *this) while (enumerator->enumerate(enumerator, ¤t, &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, }, }, diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c index aeb5a714f..b6e706d23 100644 --- a/src/libtls/tls_server.c +++ b/src/libtls/tls_server.c @@ -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, }, },