diff options
Diffstat (limited to 'src')
14 files changed, 101 insertions, 87 deletions
diff --git a/src/frontends/android/jni/Android.mk b/src/frontends/android/jni/Android.mk index 2af0d2412..670e83de1 100644 --- a/src/frontends/android/jni/Android.mk +++ b/src/frontends/android/jni/Android.mk @@ -7,7 +7,7 @@ strongswan_USE_BYOD := true strongswan_CHARON_PLUGINS := android-log openssl fips-prf random nonce pubkey \ pkcs1 pkcs8 pem xcbc hmac socket-default kernel-netlink \ - eap-identity eap-mschapv2 eap-md5 eap-gtc + eap-identity eap-mschapv2 eap-md5 eap-gtc eap-tls ifneq ($(strongswan_USE_BYOD),) strongswan_BYOD_PLUGINS := eap-ttls eap-tnc tnc-imc tnc-tnccs tnccs-20 diff --git a/src/frontends/android/jni/libandroidbridge/backend/android_creds.c b/src/frontends/android/jni/libandroidbridge/backend/android_creds.c index e0f6e8e6f..ddc032638 100644 --- a/src/frontends/android/jni/libandroidbridge/backend/android_creds.c +++ b/src/frontends/android/jni/libandroidbridge/backend/android_creds.c @@ -92,7 +92,7 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, { enumerator_t *enumerator; - if (!trusted || (cert != CERT_ANY && cert != CERT_X509)) + if (cert != CERT_ANY && cert != CERT_X509) { return NULL; } diff --git a/src/frontends/android/jni/libandroidbridge/backend/android_private_key.c b/src/frontends/android/jni/libandroidbridge/backend/android_private_key.c index 1985f0e98..769ea3f31 100644 --- a/src/frontends/android/jni/libandroidbridge/backend/android_private_key.c +++ b/src/frontends/android/jni/libandroidbridge/backend/android_private_key.c @@ -68,6 +68,9 @@ METHOD(private_key_t, sign, bool, case KEY_RSA: switch (scheme) { + case SIGN_RSA_EMSA_PKCS1_NULL: + method = "NONEwithRSA"; + break; case SIGN_RSA_EMSA_PKCS1_MD5: method = "MD5withRSA"; break; @@ -93,12 +96,18 @@ METHOD(private_key_t, sign, bool, case KEY_ECDSA: switch (scheme) { + case SIGN_ECDSA_WITH_SHA1_DER: + method = "SHA1withECDSA"; + break; + case SIGN_ECDSA_WITH_SHA256_DER: case SIGN_ECDSA_256: method = "SHA256withECDSA"; break; + case SIGN_ECDSA_WITH_SHA384_DER: case SIGN_ECDSA_384: method = "SHA384withECDSA"; break; + case SIGN_ECDSA_WITH_SHA512_DER: case SIGN_ECDSA_521: method = "SHA512withECDSA"; break; @@ -189,30 +198,36 @@ METHOD(private_key_t, sign, bool, default: break; } - - /* we get an ASN.1 encoded sequence of integers r and s */ - parse = encoded = chunk_from_byte_array(env, jsigarray); - if (asn1_unwrap(&parse, &parse) != ASN1_SEQUENCE || - asn1_unwrap(&parse, &r) != ASN1_INTEGER || - asn1_unwrap(&parse, &s) != ASN1_INTEGER) + if (len) { + /* we get an ASN.1 encoded sequence of integers r and s */ + parse = encoded = chunk_from_byte_array(env, jsigarray); + if (asn1_unwrap(&parse, &parse) != ASN1_SEQUENCE || + asn1_unwrap(&parse, &r) != ASN1_INTEGER || + asn1_unwrap(&parse, &s) != ASN1_INTEGER) + { + chunk_free(&encoded); + goto failed; + } + r = chunk_skip_zero(r); + s = chunk_skip_zero(s); + if (r.len > len || s.len > len) + { + chunk_free(&encoded); + goto failed; + } + + /* concatenate r and s (forced to the defined length) */ + *signature = chunk_alloc(2*len); + memset(signature->ptr, 0, signature->len); + memcpy(signature->ptr + (len - r.len), r.ptr, r.len); + memcpy(signature->ptr + len + (len - s.len), s.ptr, s.len); chunk_free(&encoded); - goto failed; } - r = chunk_skip_zero(r); - s = chunk_skip_zero(s); - if (r.len > len || s.len > len) + else { - chunk_free(&encoded); - goto failed; + *signature = chunk_from_byte_array(env, jsigarray); } - - /* concatenate r and s (forced to the defined length) */ - *signature = chunk_alloc(2*len); - memset(signature->ptr, 0, signature->len); - memcpy(signature->ptr + (len - r.len), r.ptr, r.len); - memcpy(signature->ptr + len + (len - s.len), s.ptr, s.len); - chunk_free(&encoded); } else { diff --git a/src/frontends/android/jni/libandroidbridge/backend/android_service.c b/src/frontends/android/jni/libandroidbridge/backend/android_service.c index 881ff00f1..960edbee5 100644 --- a/src/frontends/android/jni/libandroidbridge/backend/android_service.c +++ b/src/frontends/android/jni/libandroidbridge/backend/android_service.c @@ -617,8 +617,8 @@ METHOD(listener_t, ike_reestablish_post, bool, return TRUE; } -static void add_auth_cfg_eap(private_android_service_t *this, - peer_cfg_t *peer_cfg, bool byod) +static void add_auth_cfg_pw(private_android_service_t *this, + peer_cfg_t *peer_cfg, bool byod) { identification_t *user; auth_cfg_t *auth; @@ -653,7 +653,17 @@ static bool add_auth_cfg_cert(private_android_service_t *this, } auth = auth_cfg_create(); - auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); + if (strpfx("ikev2-eap-tls", this->type)) + { + auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP); + auth->add(auth, AUTH_RULE_EAP_TYPE, EAP_TLS); + id = identification_create_from_string("%any"); + auth->add(auth, AUTH_RULE_AAA_IDENTITY, id); + } + else + { + auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); + } auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert); id = cert->get_subject(cert); @@ -698,7 +708,8 @@ static job_requeue_t initiate(private_android_service_t *this) /* local auth config */ if (streq("ikev2-cert", this->type) || - streq("ikev2-cert-eap", this->type)) + streq("ikev2-cert-eap", this->type) || + streq("ikev2-eap-tls", this->type)) { if (!add_auth_cfg_cert(this, peer_cfg)) { @@ -712,15 +723,15 @@ static job_requeue_t initiate(private_android_service_t *this) streq("ikev2-cert-eap", this->type) || streq("ikev2-byod-eap", this->type)) { - add_auth_cfg_eap(this, peer_cfg, strpfx(this->type, "ikev2-byod")); + add_auth_cfg_pw(this, peer_cfg, strpfx(this->type, "ikev2-byod")); } /* remote auth config */ auth = auth_cfg_create(); - auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); gateway = identification_create_from_string(this->gateway); auth->add(auth, AUTH_RULE_IDENTITY, gateway); auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, TRUE); + auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE); child_cfg = child_cfg_create("android", &lifetime, NULL, TRUE, MODE_TUNNEL, diff --git a/src/frontends/android/res/values-de/arrays.xml b/src/frontends/android/res/values-de/arrays.xml index 30578c0a8..d05140165 100644 --- a/src/frontends/android/res/values-de/arrays.xml +++ b/src/frontends/android/res/values-de/arrays.xml @@ -19,6 +19,7 @@ <item>IKEv2 EAP (Benutzername/Passwort)</item> <item>IKEv2 Zertifikat</item> <item>IKEv2 Zertifikat + EAP (Benutzername/Passwort)</item> + <item>IKEv2 EAP-TLS (Zertifikat)</item> <item>IKEv2 EAP-TNC (Benutzername/Passwort)</item> </string-array> </resources>
\ No newline at end of file diff --git a/src/frontends/android/res/values-pl/arrays.xml b/src/frontends/android/res/values-pl/arrays.xml index 1a04cbf2e..30e43f1fb 100644 --- a/src/frontends/android/res/values-pl/arrays.xml +++ b/src/frontends/android/res/values-pl/arrays.xml @@ -19,6 +19,7 @@ <item>IKEv2 EAP (użytkownik/hasło)</item> <item>IKEv2 certyfikat</item> <item>IKEv2 certyfikat + EAP (użytkownik/hasło)</item> + <item>IKEv2 EAP-TLS (certyfikat)</item> <item>IKEv2 EAP-TNC (użytkownik/hasło)</item> </string-array> </resources>
\ No newline at end of file diff --git a/src/frontends/android/res/values-ru/arrays.xml b/src/frontends/android/res/values-ru/arrays.xml index 713f8e404..5fbd43168 100644 --- a/src/frontends/android/res/values-ru/arrays.xml +++ b/src/frontends/android/res/values-ru/arrays.xml @@ -18,6 +18,7 @@ <item>IKEv2 EAP (Логин/Пароль)</item> <item>IKEv2 Сертификат</item> <item>IKEv2 Сертификат + EAP (Логин/Пароль)</item> + <item>IKEv2 EAP-TLS (Сертификат)</item> <item>IKEv2 EAP-TNC (Логин/Пароль)</item> </string-array> </resources> diff --git a/src/frontends/android/res/values-ua/arrays.xml b/src/frontends/android/res/values-ua/arrays.xml index 4bd92fe0a..1acc0d769 100644 --- a/src/frontends/android/res/values-ua/arrays.xml +++ b/src/frontends/android/res/values-ua/arrays.xml @@ -18,6 +18,7 @@ <item>IKEv2 EAP (Логін/Пароль)</item> <item>IKEv2 Сертифікати</item> <item>IKEv2 Сертифікати + EAP (Логін/Пароль)</item> + <item>IKEv2 EAP-TLS (Сертифікати)</item> <item>IKEv2 EAP-TNC (Логін/Пароль)</item> </string-array> </resources> diff --git a/src/frontends/android/res/values/arrays.xml b/src/frontends/android/res/values/arrays.xml index 29f999d9a..b324b594f 100644 --- a/src/frontends/android/res/values/arrays.xml +++ b/src/frontends/android/res/values/arrays.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2012-2013 Tobias Brunner + Copyright (C) 2012-2014 Tobias Brunner Hochschule fuer Technik Rapperswil This program is free software; you can redistribute it and/or modify it @@ -19,6 +19,7 @@ <item>IKEv2 EAP (Username/Password)</item> <item>IKEv2 Certificate</item> <item>IKEv2 Certificate + EAP (Username/Password)</item> + <item>IKEv2 EAP-TLS (Certificate)</item> <item>IKEv2 EAP-TNC (Username/Password)</item> </string-array> </resources>
\ No newline at end of file diff --git a/src/frontends/android/src/org/strongswan/android/data/VpnType.java b/src/frontends/android/src/org/strongswan/android/data/VpnType.java index f62c96d76..bffa8384c 100644 --- a/src/frontends/android/src/org/strongswan/android/data/VpnType.java +++ b/src/frontends/android/src/org/strongswan/android/data/VpnType.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Tobias Brunner + * Copyright (C) 2012-2014 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -15,45 +15,44 @@ package org.strongswan.android.data; +import java.util.EnumSet; + public enum VpnType { /* the order here must match the items in R.array.vpn_types */ - IKEV2_EAP("ikev2-eap", true, false), - IKEV2_CERT("ikev2-cert", false, true), - IKEV2_CERT_EAP("ikev2-cert-eap", true, true), - IKEV2_BYOD_EAP("ikev2-byod-eap", true, false, true); - - private String mIdentifier; - private boolean mCertificate; - private boolean mUsernamePassword; - private boolean mBYOD; + IKEV2_EAP("ikev2-eap", EnumSet.of(VpnTypeFeature.USER_PASS)), + IKEV2_CERT("ikev2-cert", EnumSet.of(VpnTypeFeature.CERTIFICATE)), + IKEV2_CERT_EAP("ikev2-cert-eap", EnumSet.of(VpnTypeFeature.USER_PASS, VpnTypeFeature.CERTIFICATE)), + IKEV2_EAP_TLS("ikev2-eap-tls", EnumSet.of(VpnTypeFeature.CERTIFICATE)), + IKEV2_BYOD_EAP("ikev2-byod-eap", EnumSet.of(VpnTypeFeature.USER_PASS, VpnTypeFeature.CERTIFICATE, VpnTypeFeature.BYOD)); /** - * Enum which provides additional information about the supported VPN types. - * - * @param id identifier used to store and transmit this specific type - * @param userpass true if username and password are required - * @param certificate true if a client certificate is required + * Features of a VPN type. */ - VpnType(String id, boolean userpass, boolean certificate) + public enum VpnTypeFeature { - this(id, userpass, certificate, false); + /** client certificate is required */ + CERTIFICATE, + /** username and password are required */ + USER_PASS, + /** enable BYOD features */ + BYOD; } + private String mIdentifier; + private EnumSet<VpnTypeFeature> mFeatures; + /** * Enum which provides additional information about the supported VPN types. * * @param id identifier used to store and transmit this specific type - * @param userpass true if username and password are required + * @param features of the given VPN type * @param certificate true if a client certificate is required - * @param byod true to enable BYOD features */ - VpnType(String id, boolean userpass, boolean certificate, boolean byod) + VpnType(String id, EnumSet<VpnTypeFeature> features) { mIdentifier = id; - mUsernamePassword = userpass; - mCertificate = certificate; - mBYOD = byod; + mFeatures = features; } /** @@ -66,33 +65,13 @@ public enum VpnType } /** - * Whether username and password are required for this type of VPN. - * - * @return true if username and password are required - */ - public boolean getRequiresUsernamePassword() - { - return mUsernamePassword; - } - - /** - * Whether a certificate is required for this type of VPN. - * - * @return true if a certificate is required - */ - public boolean getRequiresCertificate() - { - return mCertificate; - } - - /** - * Whether BYOD features should be enabled. + * Checks whether a feature is supported/required by this type of VPN. * - * @return true if BYOD features are to be enabled + * @return true if the feature is supported/required */ - public boolean getEnableBYOD() + public boolean has(VpnTypeFeature feature) { - return mBYOD; + return mFeatures.contains(feature); } /** diff --git a/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java index c8f3b344f..7cdaee735 100644 --- a/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java @@ -26,6 +26,7 @@ import java.util.List; import org.strongswan.android.data.VpnProfile; import org.strongswan.android.data.VpnProfileDataSource; +import org.strongswan.android.data.VpnType.VpnTypeFeature; import org.strongswan.android.logic.VpnStateService.ErrorState; import org.strongswan.android.logic.VpnStateService.State; import org.strongswan.android.logic.imc.ImcState; @@ -211,7 +212,7 @@ public class CharonVpnService extends VpnService implements Runnable mIsDisconnecting = false; BuilderAdapter builder = new BuilderAdapter(mCurrentProfile.getName()); - if (initializeCharon(builder, mLogFile, mCurrentProfile.getVpnType().getEnableBYOD())) + if (initializeCharon(builder, mLogFile, mCurrentProfile.getVpnType().has(VpnTypeFeature.BYOD))) { Log.i(TAG, "charon started"); initiate(mCurrentProfile.getVpnType().getIdentifier(), diff --git a/src/frontends/android/src/org/strongswan/android/ui/MainActivity.java b/src/frontends/android/src/org/strongswan/android/ui/MainActivity.java index a2ad80e82..e1b3e0783 100644 --- a/src/frontends/android/src/org/strongswan/android/ui/MainActivity.java +++ b/src/frontends/android/src/org/strongswan/android/ui/MainActivity.java @@ -20,6 +20,7 @@ package org.strongswan.android.ui; import org.strongswan.android.R; import org.strongswan.android.data.VpnProfile; import org.strongswan.android.data.VpnProfileDataSource; +import org.strongswan.android.data.VpnType.VpnTypeFeature; import org.strongswan.android.logic.CharonVpnService; import org.strongswan.android.logic.TrustedCertificateManager; import org.strongswan.android.logic.VpnStateService; @@ -219,7 +220,7 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen profileInfo.putLong(VpnProfileDataSource.KEY_ID, profile.getId()); profileInfo.putString(VpnProfileDataSource.KEY_USERNAME, profile.getUsername()); profileInfo.putString(VpnProfileDataSource.KEY_PASSWORD, profile.getPassword()); - profileInfo.putBoolean(PROFILE_REQUIRES_PASSWORD, profile.getVpnType().getRequiresUsernamePassword()); + profileInfo.putBoolean(PROFILE_REQUIRES_PASSWORD, profile.getVpnType().has(VpnTypeFeature.USER_PASS)); profileInfo.putString(PROFILE_NAME, profile.getName()); removeFragmentByTag(DIALOG_TAG); diff --git a/src/frontends/android/src/org/strongswan/android/ui/VpnProfileDetailActivity.java b/src/frontends/android/src/org/strongswan/android/ui/VpnProfileDetailActivity.java index 39d37005d..41cd6e98c 100644 --- a/src/frontends/android/src/org/strongswan/android/ui/VpnProfileDetailActivity.java +++ b/src/frontends/android/src/org/strongswan/android/ui/VpnProfileDetailActivity.java @@ -23,6 +23,7 @@ import org.strongswan.android.R; import org.strongswan.android.data.VpnProfile; import org.strongswan.android.data.VpnProfileDataSource; import org.strongswan.android.data.VpnType; +import org.strongswan.android.data.VpnType.VpnTypeFeature; import org.strongswan.android.logic.TrustedCertificateManager; import org.strongswan.android.security.TrustedCertificateEntry; @@ -240,11 +241,11 @@ public class VpnProfileDetailActivity extends Activity */ private void updateCredentialView() { - mUsernamePassword.setVisibility(mVpnType.getRequiresUsernamePassword() ? View.VISIBLE : View.GONE); - mUserCertificate.setVisibility(mVpnType.getRequiresCertificate() ? View.VISIBLE : View.GONE); - mTncNotice.setVisibility(mVpnType.getEnableBYOD() ? View.VISIBLE : View.GONE); + mUsernamePassword.setVisibility(mVpnType.has(VpnTypeFeature.USER_PASS) ? View.VISIBLE : View.GONE); + mUserCertificate.setVisibility(mVpnType.has(VpnTypeFeature.CERTIFICATE) ? View.VISIBLE : View.GONE); + mTncNotice.setVisibility(mVpnType.has(VpnTypeFeature.BYOD) ? View.VISIBLE : View.GONE); - if (mVpnType.getRequiresCertificate()) + if (mVpnType.has(VpnTypeFeature.CERTIFICATE)) { if (mUserCertLoading != null) { @@ -349,7 +350,7 @@ public class VpnProfileDetailActivity extends Activity mGateway.setError(getString(R.string.alert_text_no_input_gateway)); valid = false; } - if (mVpnType.getRequiresUsernamePassword()) + if (mVpnType.has(VpnTypeFeature.USER_PASS)) { if (mUsername.getText().toString().trim().isEmpty()) { @@ -357,7 +358,7 @@ public class VpnProfileDetailActivity extends Activity valid = false; } } - if (mVpnType.getRequiresCertificate() && mUserCertEntry == null) + if (mVpnType.has(VpnTypeFeature.CERTIFICATE) && mUserCertEntry == null) { /* let's show an error icon */ ((TextView)mSelectUserCert.findViewById(android.R.id.text1)).setError(""); valid = false; @@ -381,14 +382,14 @@ public class VpnProfileDetailActivity extends Activity mProfile.setName(name.isEmpty() ? gateway : name); mProfile.setGateway(gateway); mProfile.setVpnType(mVpnType); - if (mVpnType.getRequiresUsernamePassword()) + if (mVpnType.has(VpnTypeFeature.USER_PASS)) { mProfile.setUsername(mUsername.getText().toString().trim()); String password = mPassword.getText().toString().trim(); password = password.isEmpty() ? null : password; mProfile.setPassword(password); } - if (mVpnType.getRequiresCertificate()) + if (mVpnType.has(VpnTypeFeature.CERTIFICATE)) { mProfile.setUserCertificateAlias(mUserCertEntry.getAlias()); } diff --git a/src/frontends/android/src/org/strongswan/android/ui/adapter/VpnProfileAdapter.java b/src/frontends/android/src/org/strongswan/android/ui/adapter/VpnProfileAdapter.java index 85dc8370a..f3bb271bc 100644 --- a/src/frontends/android/src/org/strongswan/android/ui/adapter/VpnProfileAdapter.java +++ b/src/frontends/android/src/org/strongswan/android/ui/adapter/VpnProfileAdapter.java @@ -23,6 +23,7 @@ import java.util.List; import org.strongswan.android.R; import org.strongswan.android.data.VpnProfile; +import org.strongswan.android.data.VpnType.VpnTypeFeature; import android.content.Context; import android.view.LayoutInflater; @@ -64,7 +65,7 @@ public class VpnProfileAdapter extends ArrayAdapter<VpnProfile> tv = (TextView)vpnProfileView.findViewById(R.id.profile_item_gateway); tv.setText(getContext().getString(R.string.profile_gateway_label) + " " + profile.getGateway()); tv = (TextView)vpnProfileView.findViewById(R.id.profile_item_username); - if (profile.getVpnType().getRequiresUsernamePassword()) + if (profile.getVpnType().has(VpnTypeFeature.USER_PASS)) { /* if the view is reused we make sure it is visible */ tv.setVisibility(View.VISIBLE); tv.setText(getContext().getString(R.string.profile_username_label) + " " + profile.getUsername()); @@ -74,7 +75,7 @@ public class VpnProfileAdapter extends ArrayAdapter<VpnProfile> tv.setVisibility(View.GONE); } tv = (TextView)vpnProfileView.findViewById(R.id.profile_item_certificate); - if (profile.getVpnType().getRequiresCertificate()) + if (profile.getVpnType().has(VpnTypeFeature.CERTIFICATE)) { tv.setText(getContext().getString(R.string.profile_user_certificate_label) + " " + profile.getUserCertificateAlias()); tv.setVisibility(View.VISIBLE); |