summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorEvgenii Potapov <potapov@rutoken.ru>2020-11-12 09:23:34 +0300
committerArne Schwabe <arne@rfc2549.org>2020-11-23 10:53:22 +0100
commita6de5a9e4d8d757414c5e2f94eb806be9216dda3 (patch)
tree4fe085c140e4e3824a9cbfb2b1b59f99d190934d /main
parentdd6d365fb67ca992617e87a04ab61b17feffdecd (diff)
Provide a padding type for externalCertificateProvider
Based on server-side OpenSSL behaviour the data to be signed by externalCertificateProvider may be or may be not padded already. To choose the proper signing mechanism we need to pass external info.
Diffstat (limited to 'main')
-rw-r--r--main/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl21
-rw-r--r--main/src/main/java/de/blinkt/openvpn/VpnProfile.java26
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java14
3 files changed, 50 insertions, 11 deletions
diff --git a/main/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl b/main/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl
index c6db965b..951cff96 100644
--- a/main/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl
+++ b/main/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl
@@ -1,16 +1,16 @@
// ExternalCertificateProvider.aidl
package de.blinkt.openvpn.api;
-
/*
* This is very simple interface that is specialised to have only the minimal set of crypto
* operation that are needed for OpenVPN to authenticate with an external certificate
*/
interface ExternalCertificateProvider {
/**
+ * @deprecated use {@link #getSignedDataWithExtra} instead
* Requests signing the data with RSA/ECB/PKCS1PADDING
* for RSA certficate and with NONEwithECDSA for EC certificates
- * @parm alias the parameter that
+ * @param alias user certificate identifier
*/
byte[] getSignedData(in String alias, in byte[] data);
@@ -36,4 +36,21 @@ interface ExternalCertificateProvider {
*
*/
Bundle getCertificateMetaData(in String alias);
+
+ /**
+ * Requests signing the data with RSA/ECB/PKCS1PADDING or RSA/ECB/nopadding
+ * for RSA certficate and with NONEwithECDSA for EC certificates
+ * @param alias user certificate identifier
+ * @param data the data to be signed
+ * @param extra additional information.
+ * Should contain the following keys:
+ * <p><ul>
+ * <li>int key "de.blinkt.openvpn.api.RSA_PADDING_TYPE", may be set as:
+ * <p><ul>
+ * <li>0 - for RSA/ECB/nopadding
+ * <li>1 - for RSA/ECB/PKCS1PADDING
+ * </ul><p>
+ * </ul><p>
+ */
+ byte[] getSignedDataWithExtra(in String alias, in byte[] data, in Bundle extra);
}
diff --git a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java
index 2cb12296..2ccff18b 100644
--- a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java
+++ b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java
@@ -12,6 +12,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
+import android.os.Bundle;
import android.preference.PreferenceManager;
import android.security.KeyChain;
import android.security.KeyChainException;
@@ -82,6 +83,7 @@ public class VpnProfile implements Serializable, Cloneable {
private static final long serialVersionUID = 7085688938959334563L;
private static final int AUTH_RETRY_NONE_KEEP = 1;
private static final int AUTH_RETRY_INTERACT = 3;
+ private static final String EXTRA_RSA_PADDING_TYPE = "de.blinkt.openvpn.api.RSA_PADDING_TYPE";
public static String DEFAULT_DNS1 = "8.8.8.8";
public static String DEFAULT_DNS2 = "8.8.4.4";
// variable named wrong and should haven beeen transient
@@ -1148,10 +1150,16 @@ public class VpnProfile implements Serializable, Cloneable {
public String getSignedData(Context c, String b64data, boolean pkcs1padding) {
byte[] data = Base64.decode(b64data, Base64.DEFAULT);
byte[] signed_bytes;
- if (mAuthenticationType == TYPE_EXTERNAL_APP)
- signed_bytes = getExtAppSignedData(c, data);
- else
+ if (mAuthenticationType == TYPE_EXTERNAL_APP) {
+ RsaPaddingType paddingType = pkcs1padding ? RsaPaddingType.PKCS1_PADDING : RsaPaddingType.NO_PADDING;
+ Bundle extra = new Bundle();
+ extra.putInt(EXTRA_RSA_PADDING_TYPE, paddingType.ordinal());
+
+ signed_bytes = getExtAppSignedData(c, data, extra);
+ }
+ else {
signed_bytes = getKeyChainSignedData(data, pkcs1padding);
+ }
if (signed_bytes != null)
return Base64.encodeToString(signed_bytes, Base64.NO_WRAP);
@@ -1159,11 +1167,11 @@ public class VpnProfile implements Serializable, Cloneable {
return null;
}
- private byte[] getExtAppSignedData(Context c, byte[] data) {
+ private byte[] getExtAppSignedData(Context c, byte[] data, Bundle extra) {
if (TextUtils.isEmpty(mExternalAuthenticator))
return null;
try {
- return ExtAuthHelper.signData(c, mExternalAuthenticator, mAlias, data);
+ return ExtAuthHelper.signData(c, mExternalAuthenticator, mAlias, data, extra);
} catch (KeyChainException | InterruptedException e) {
VpnStatus.logError(R.string.error_extapp_sign, mExternalAuthenticator, e.getClass().toString(), e.getLocalizedMessage());
return null;
@@ -1257,7 +1265,13 @@ public class VpnProfile implements Serializable, Cloneable {
}
}
-
+ /**
+ * The order of elements is important!
+ */
+ private enum RsaPaddingType {
+ NO_PADDING,
+ PKCS1_PADDING
+ }
}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java b/main/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java
index a62a4c62..d102dce2 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java
@@ -108,15 +108,23 @@ public class ExtAuthHelper {
public static byte[] signData(@NonNull Context context,
@NonNull String extAuthPackageName,
@NonNull String alias,
- @NonNull byte[] data
+ @NonNull byte[] data,
+ @NonNull Bundle extra
) throws KeyChainException, InterruptedException
{
- try (ExternalAuthProviderConnection authProviderConnection = bindToExtAuthProvider(context.getApplicationContext(), extAuthPackageName)) {
+ try (ExternalAuthProviderConnection authProviderConnection =
+ bindToExtAuthProvider(context.getApplicationContext(), extAuthPackageName)) {
ExternalCertificateProvider externalAuthProvider = authProviderConnection.getService();
- return externalAuthProvider.getSignedData(alias, data);
+
+ byte[] result = externalAuthProvider.getSignedDataWithExtra(alias, data, extra);
+ // When the desired method is not implemented, a default implementation is called, returning null
+ if (result == null)
+ result = externalAuthProvider.getSignedData(alias, data);
+
+ return result;
} catch (RemoteException e) {
throw new KeyChainException(e);