android: Use optional custom proposals for IKE and ESP
authorTobias Brunner <tobias@strongswan.org>
Tue, 14 Nov 2017 08:49:24 +0000 (09:49 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 17 Nov 2017 13:31:06 +0000 (14:31 +0100)
If the proposal is invalid we fall back to the defaults.

src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java
src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c

index 61535ff..95c2ccd 100644 (file)
@@ -261,6 +261,8 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
                                                        writer.setValue("connection.local_id", mCurrentProfile.getLocalId());
                                                        writer.setValue("connection.remote_id", mCurrentProfile.getRemoteId());
                                                        writer.setValue("connection.certreq", (mCurrentProfile.getFlags() & VpnProfile.FLAGS_SUPPRESS_CERT_REQS) == 0);
+                                                       writer.setValue("connection.ike_proposal", mCurrentProfile.getIkeProposal());
+                                                       writer.setValue("connection.esp_proposal", mCurrentProfile.getEspProposal());
                                                        initiate(writer.serialize());
                                                }
                                                else
index 809814b..5c4a038 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2016 Tobias Brunner
+ * Copyright (C) 2010-2017 Tobias Brunner
  * Copyright (C) 2012 Giuliano Grassi
  * Copyright (C) 2012 Ralf Sager
  * HSR Hochschule fuer Technik Rapperswil
@@ -707,6 +707,27 @@ static bool add_auth_cfg_cert(private_android_service_t *this,
        return TRUE;
 }
 
+static proposal_t *parse_proposal(private_android_service_t *this,
+                                                                 protocol_id_t proto, char *opt)
+{
+       proposal_t *proposal = NULL;
+       char *prop;
+
+       prop = this->settings->get_str(this->settings, opt, NULL);
+       if (!prop || !strlen(prop))
+       {
+               return NULL;
+       }
+
+       proposal = proposal_create_from_string(proto, prop);
+       if (!proposal)
+       {
+               DBG1(DBG_CFG, "invalid %N proposal '%s', falling back to defaults",
+                        protocol_id_names, proto, prop);
+       }
+       return proposal;
+}
+
 static job_requeue_t initiate(private_android_service_t *this)
 {
        identification_t *gateway = NULL;
@@ -714,6 +735,7 @@ static job_requeue_t initiate(private_android_service_t *this)
        peer_cfg_t *peer_cfg;
        child_cfg_t *child_cfg;
        traffic_selector_t *ts;
+       proposal_t *proposal;
        ike_sa_t *ike_sa;
        auth_cfg_t *auth;
        peer_cfg_create_t peer = {
@@ -747,8 +769,16 @@ static job_requeue_t initiate(private_android_service_t *this)
        ike_cfg = ike_cfg_create(IKEV2, certreq, TRUE, "0.0.0.0",
                                                         charon->socket->get_port(charon->socket, FALSE),
                                                         server, port, FRAGMENTATION_YES, 0);
-       ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
-       ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
+       proposal = parse_proposal(this, PROTO_IKE, "connection.ike_proposal");
+       if (proposal)
+       {
+               ike_cfg->add_proposal(ike_cfg, proposal);
+       }
+       else
+       {
+               ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+               ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
+       }
 
        peer_cfg = peer_cfg_create("android", ike_cfg, &peer);
        peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET));
@@ -795,27 +825,34 @@ static job_requeue_t initiate(private_android_service_t *this)
        peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
 
        child_cfg = child_cfg_create("android", &child);
-       /* create ESP proposals with and without DH groups, let responder decide
-        * if PFS is used */
-       child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
-                                                       "aes128gcm16-aes256gcm16-chacha20poly1305-"
-                                                       "curve25519-ecp256-modp3072"));
-       child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
-                                                       "aes128-sha256-curve25519-ecp256-modp3072"));
-       child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
-                                                       "aes256-sha384-ecp521-modp8192"));
-       child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
-                                                       "aes128-aes192-aes256-sha1-sha256-sha384-sha512-"
-                                                       "curve25519-ecp256-ecp384-ecp521-"
-                                                       "modp2048-modp3072-modp4096-modp1024"));
-       child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
-                                                       "aes128gcm16-aes256gcm16-chacha20poly1305"));
-       child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
-                                                       "aes128-sha256"));
-       child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
-                                                       "aes256-sha384"));
-       child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
-                                                       "aes128-aes192-aes256-sha1-sha256-sha384-sha512"));
+       proposal = parse_proposal(this, PROTO_ESP, "connection.esp_proposal");
+       if (proposal)
+       {
+               child_cfg->add_proposal(child_cfg, proposal);
+       }
+       else
+       {       /* create ESP proposals with and without DH groups, let responder decide
+                * if PFS is used */
+               child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
+                                                               "aes128gcm16-aes256gcm16-chacha20poly1305-"
+                                                               "curve25519-ecp256-modp3072"));
+               child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
+                                                               "aes128-sha256-curve25519-ecp256-modp3072"));
+               child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
+                                                               "aes256-sha384-ecp521-modp8192"));
+               child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
+                                                               "aes128-aes192-aes256-sha1-sha256-sha384-sha512-"
+                                                               "curve25519-ecp256-ecp384-ecp521-"
+                                                               "modp2048-modp3072-modp4096-modp1024"));
+               child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
+                                                               "aes128gcm16-aes256gcm16-chacha20poly1305"));
+               child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
+                                                               "aes128-sha256"));
+               child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
+                                                               "aes256-sha384"));
+               child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
+                                                               "aes128-aes192-aes256-sha1-sha256-sha384-sha512"));
+       }
        ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
        child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
        ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);