mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-29 13:17:43 +00:00
Upgrade from SpongyCastle 1.58 to BouncyCastle 1.70
SpongyCastle was a fork of BouncyCastle needed before Android 3.0 because of a conflict with Android's own version of BC. It's no longer needed and rarely receives updates anymore [1]. Furthermore the version we were using was from 2015 and had security issues (although I'm not sure we were affected by them since we only use it to generate certificates). With this change we now also use Java's standard library to read the certs from a byte[] since the standard CertificateFactory can already do that. [1] https://github.com/rtyley/spongycastle/issues/34
This commit is contained in:
parent
51dfa2dd8c
commit
33e8e0407b
@ -159,7 +159,7 @@ dependencies {
|
|||||||
implementation 'org.apache.mina:mina-core:2.0.19' //For some reason, makes sshd-core:0.14.0 work without NIO, which isn't available until Android 8 (api 26)
|
implementation 'org.apache.mina:mina-core:2.0.19' //For some reason, makes sshd-core:0.14.0 work without NIO, which isn't available until Android 8 (api 26)
|
||||||
|
|
||||||
//implementation('com.github.bright:slf4android:0.1.6') { transitive = true } // For org.apache.sshd debugging
|
//implementation('com.github.bright:slf4android:0.1.6') { transitive = true } // For org.apache.sshd debugging
|
||||||
implementation 'com.madgag.spongycastle:bcpkix-jdk15on:1.58.0.0' //For SSL certificate generation
|
implementation 'org.bouncycastle:bcpkix-jdk15on:1.70' //For SSL certificate generation
|
||||||
|
|
||||||
implementation 'org.atteo.classindex:classindex:3.13'
|
implementation 'org.atteo.classindex:classindex:3.13'
|
||||||
annotationProcessor 'org.atteo.classindex:classindex:3.13'
|
annotationProcessor 'org.atteo.classindex:classindex:3.13'
|
||||||
|
@ -14,23 +14,20 @@ import android.preference.PreferenceManager;
|
|||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
import org.kde.kdeconnect.Helpers.DeviceHelper;
|
import org.kde.kdeconnect.Helpers.DeviceHelper;
|
||||||
import org.kde.kdeconnect.Helpers.RandomHelper;
|
import org.kde.kdeconnect.Helpers.RandomHelper;
|
||||||
import org.spongycastle.asn1.x500.RDN;
|
import org.bouncycastle.asn1.x500.RDN;
|
||||||
import org.spongycastle.asn1.x500.X500Name;
|
import org.bouncycastle.asn1.x500.X500Name;
|
||||||
import org.spongycastle.asn1.x500.X500NameBuilder;
|
import org.bouncycastle.asn1.x500.X500NameBuilder;
|
||||||
import org.spongycastle.asn1.x500.style.BCStyle;
|
import org.bouncycastle.asn1.x500.style.BCStyle;
|
||||||
import org.spongycastle.asn1.x500.style.IETFUtils;
|
import org.bouncycastle.asn1.x500.style.IETFUtils;
|
||||||
import org.spongycastle.cert.X509CertificateHolder;
|
import org.bouncycastle.cert.X509v3CertificateBuilder;
|
||||||
import org.spongycastle.cert.X509v3CertificateBuilder;
|
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
||||||
import org.spongycastle.cert.jcajce.JcaX509CertificateConverter;
|
import org.bouncycastle.operator.ContentSigner;
|
||||||
import org.spongycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
import org.bouncycastle.util.Arrays;
|
||||||
import org.spongycastle.operator.ContentSigner;
|
|
||||||
import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
|
|
||||||
import org.spongycastle.util.Arrays;
|
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
@ -43,11 +40,11 @@ import java.security.PublicKey;
|
|||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateEncodingException;
|
import java.security.cert.CertificateEncodingException;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -63,9 +60,15 @@ import javax.security.auth.x500.X500Principal;
|
|||||||
|
|
||||||
public class SslHelper {
|
public class SslHelper {
|
||||||
|
|
||||||
public static X509Certificate certificate; //my device's certificate
|
public static Certificate certificate; //my device's certificate
|
||||||
|
private static CertificateFactory factory;
|
||||||
public final static BouncyCastleProvider BC = new BouncyCastleProvider();
|
static {
|
||||||
|
try {
|
||||||
|
factory = CertificateFactory.getInstance("X.509");
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final static TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
|
private final static TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
|
||||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||||
@ -103,8 +106,7 @@ public class SslHelper {
|
|||||||
try {
|
try {
|
||||||
SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
byte[] certificateBytes = Base64.decode(globalSettings.getString("certificate", ""), 0);
|
byte[] certificateBytes = Base64.decode(globalSettings.getString("certificate", ""), 0);
|
||||||
X509CertificateHolder certificateHolder = new X509CertificateHolder(certificateBytes);
|
X509Certificate cert = (X509Certificate) parseCertificate(certificateBytes);
|
||||||
X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateHolder);
|
|
||||||
|
|
||||||
String certDeviceId = getCommonNameFromCertificate(cert);
|
String certDeviceId = getCommonNameFromCertificate(cert);
|
||||||
if (!certDeviceId.equals(deviceId)) {
|
if (!certDeviceId.equals(deviceId)) {
|
||||||
@ -145,11 +147,12 @@ public class SslHelper {
|
|||||||
nameBuilder.build(),
|
nameBuilder.build(),
|
||||||
publicKey
|
publicKey
|
||||||
);
|
);
|
||||||
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(privateKey);
|
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey);
|
||||||
certificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateBuilder.build(contentSigner));
|
byte[] certificateBytes = certificateBuilder.build(contentSigner).getEncoded();
|
||||||
|
certificate = parseCertificate(certificateBytes);
|
||||||
|
|
||||||
SharedPreferences.Editor edit = settings.edit();
|
SharedPreferences.Editor edit = settings.edit();
|
||||||
edit.putString("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
|
edit.putString("certificate", Base64.encodeToString(certificateBytes, 0));
|
||||||
edit.apply();
|
edit.apply();
|
||||||
|
|
||||||
setLocale(initialLocale, context);
|
setLocale(initialLocale, context);
|
||||||
@ -180,12 +183,11 @@ public class SslHelper {
|
|||||||
PrivateKey privateKey = RsaHelper.getPrivateKey(context);
|
PrivateKey privateKey = RsaHelper.getPrivateKey(context);
|
||||||
|
|
||||||
// Get remote device certificate if trusted
|
// Get remote device certificate if trusted
|
||||||
X509Certificate remoteDeviceCertificate = null;
|
Certificate remoteDeviceCertificate = null;
|
||||||
if (isDeviceTrusted) {
|
if (isDeviceTrusted) {
|
||||||
SharedPreferences devicePreferences = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE);
|
SharedPreferences devicePreferences = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE);
|
||||||
byte[] certificateBytes = Base64.decode(devicePreferences.getString("certificate", ""), 0);
|
byte[] certificateBytes = Base64.decode(devicePreferences.getString("certificate", ""), 0);
|
||||||
X509CertificateHolder certificateHolder = new X509CertificateHolder(certificateBytes);
|
remoteDeviceCertificate = parseCertificate(certificateBytes);
|
||||||
remoteDeviceCertificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateHolder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup keystore
|
// Setup keystore
|
||||||
@ -257,9 +259,8 @@ public class SslHelper {
|
|||||||
return formatter.toString();
|
return formatter.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Certificate parseCertificate(byte[] certificateBytes) throws IOException, CertificateException {
|
public static Certificate parseCertificate(byte[] certificateBytes) throws CertificateException {
|
||||||
X509CertificateHolder certificateHolder = new X509CertificateHolder(certificateBytes);
|
return factory.generateCertificate(new ByteArrayInputStream(certificateBytes));
|
||||||
return new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateHolder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getCommonNameFromCertificate(X509Certificate cert) {
|
private static String getCommonNameFromCertificate(X509Certificate cert) {
|
||||||
@ -269,7 +270,7 @@ public class SslHelper {
|
|||||||
return IETFUtils.valueToString(rdn.getFirst().getValue());
|
return IETFUtils.valueToString(rdn.getFirst().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getVerificationKey(X509Certificate certificateA, Certificate certificateB) {
|
public static String getVerificationKey(Certificate certificateA, Certificate certificateB) {
|
||||||
try {
|
try {
|
||||||
byte[] a = certificateA.getPublicKey().getEncoded();
|
byte[] a = certificateA.getPublicKey().getEncoded();
|
||||||
byte[] b = certificateB.getPublicKey().getEncoded();
|
byte[] b = certificateB.getPublicKey().getEncoded();
|
||||||
|
@ -24,7 +24,6 @@ import org.apache.sshd.server.sftp.SftpSubsystem;
|
|||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
import org.kde.kdeconnect.Helpers.RandomHelper;
|
import org.kde.kdeconnect.Helpers.RandomHelper;
|
||||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
||||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
@ -35,7 +34,6 @@ import java.security.GeneralSecurityException;
|
|||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.Security;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
@ -54,7 +52,6 @@ class SimpleSftpServer {
|
|||||||
private final SimplePublicKeyAuthenticator keyAuth = new SimplePublicKeyAuthenticator();
|
private final SimplePublicKeyAuthenticator keyAuth = new SimplePublicKeyAuthenticator();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Security.insertProviderAt(SslHelper.BC, 1);
|
|
||||||
SecurityUtils.setRegisterBouncyCastle(false);
|
SecurityUtils.setRegisterBouncyCastle(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user