Untrusted: refactoring

pull/203/head
M66B 4 years ago
parent 75b7261dfb
commit adfcc4b391

@ -1443,7 +1443,7 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
} }
} }
String fingerprint = EntityCertificate.getFingerprint(cert); String fingerprint = EntityCertificate.getFingerprintSha256(cert);
List<String> emails = EntityCertificate.getEmailAddresses(cert); List<String> emails = EntityCertificate.getEmailAddresses(cert);
if (emails.size() == 0) if (emails.size() == 0)

@ -40,10 +40,6 @@ import com.sun.mail.smtp.SMTPTransport;
import com.sun.mail.util.MailConnectException; import com.sun.mail.util.MailConnectException;
import com.sun.mail.util.SocketConnectException; import com.sun.mail.util.SocketConnectException;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
@ -58,10 +54,8 @@ import java.net.SocketException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.Principal; import java.security.Principal;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.ArrayList; import java.util.ArrayList;
@ -490,7 +484,7 @@ public class EmailService implements AutoCloseable {
Throwable ce = ex; Throwable ce = ex;
while (ce != null) { while (ce != null) {
if (factory != null && ce instanceof CertificateException) if (factory != null && ce instanceof CertificateException)
throw new UntrustedException(factory.getFingerPrintSelect(), ex); throw new UntrustedException(factory.certificate, ex);
if (ce instanceof IOException) if (ce instanceof IOException)
ioError = true; ioError = true;
ce = ce.getCause(); ce = ce.getCause();
@ -989,12 +983,12 @@ public class EmailService implements AutoCloseable {
private static boolean matches(X509Certificate certificate, @NonNull String trustedFingerprint) { private static boolean matches(X509Certificate certificate, @NonNull String trustedFingerprint) {
// Get certificate fingerprint // Get certificate fingerprint
try { try {
String fingerprint = getFingerPrint(certificate); String fingerprint = EntityCertificate.getFingerprintSha1(certificate);
int slash = trustedFingerprint.indexOf('/'); int slash = trustedFingerprint.indexOf('/');
if (slash < 0) if (slash < 0)
return trustedFingerprint.equals(fingerprint); return trustedFingerprint.equals(fingerprint);
else { else {
String keyId = getKeyId(certificate); String keyId = EntityCertificate.getKeyId(certificate);
if (trustedFingerprint.substring(slash + 1).equals(keyId)) if (trustedFingerprint.substring(slash + 1).equals(keyId))
return true; return true;
return trustedFingerprint.substring(0, slash).equals(fingerprint); return trustedFingerprint.substring(0, slash).equals(fingerprint);
@ -1004,37 +998,6 @@ public class EmailService implements AutoCloseable {
return false; return false;
} }
} }
private static String getKeyId(X509Certificate certificate) {
try {
byte[] extension = certificate.getExtensionValue(Extension.subjectKeyIdentifier.getId());
if (extension == null)
return null;
byte[] bytes = DEROctetString.getInstance(extension).getOctets();
SubjectKeyIdentifier keyId = SubjectKeyIdentifier.getInstance(bytes);
return Helper.hex(keyId.getKeyIdentifier());
} catch (Throwable ex) {
Log.e(ex);
return null;
}
}
private static String getFingerPrint(X509Certificate certificate) throws CertificateEncodingException, NoSuchAlgorithmException {
return Helper.sha1(certificate.getEncoded());
}
String getFingerPrintSelect() {
try {
if (certificate == null)
return null;
String keyId = getKeyId(certificate);
String fingerPrint = getFingerPrint(certificate);
return fingerPrint + (keyId == null ? "" : "/" + keyId);
} catch (Throwable ex) {
Log.e(ex);
return null;
}
}
} }
private static void configureSocketOptions(Socket socket) throws SocketException { private static void configureSocketOptions(Socket socket) throws SocketException {
@ -1075,15 +1038,28 @@ public class EmailService implements AutoCloseable {
} }
class UntrustedException extends MessagingException { class UntrustedException extends MessagingException {
private String fingerprint; private X509Certificate certificate;
UntrustedException(@NonNull String fingerprint, @NonNull Exception cause) { UntrustedException(@NonNull X509Certificate certificate, @NonNull Exception cause) {
super("Untrusted", cause); super("Untrusted", cause);
this.fingerprint = fingerprint; this.certificate = certificate;
}
X509Certificate getCertificate() {
return certificate;
} }
String getFingerprint() { String getFingerprint() {
return fingerprint; try {
if (certificate == null)
return null;
String keyId = EntityCertificate.getKeyId(certificate);
String fingerPrint = EntityCertificate.getFingerprintSha1(certificate);
return fingerPrint + (keyId == null ? "" : "/" + keyId);
} catch (Throwable ex) {
Log.e(ex);
return null;
}
} }
@NonNull @NonNull

@ -27,11 +27,14 @@ import androidx.room.Index;
import androidx.room.PrimaryKey; import androidx.room.PrimaryKey;
import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.AttributeTypeAndValue;
import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -85,7 +88,7 @@ public class EntityCertificate {
static EntityCertificate from(X509Certificate certificate, boolean intermediate, String email) throws CertificateEncodingException, NoSuchAlgorithmException { static EntityCertificate from(X509Certificate certificate, boolean intermediate, String email) throws CertificateEncodingException, NoSuchAlgorithmException {
EntityCertificate record = new EntityCertificate(); EntityCertificate record = new EntityCertificate();
record.fingerprint = getFingerprint(certificate); record.fingerprint = getFingerprintSha256(certificate);
record.intermediate = intermediate; record.intermediate = intermediate;
record.email = email; record.email = email;
record.subject = getSubject(certificate); record.subject = getSubject(certificate);
@ -118,10 +121,28 @@ public class EntityCertificate {
return ((this.after != null && now <= this.after) || (this.before != null && now > this.before)); return ((this.after != null && now <= this.after) || (this.before != null && now > this.before));
} }
static String getFingerprint(X509Certificate certificate) throws CertificateEncodingException, NoSuchAlgorithmException { static String getFingerprintSha256(X509Certificate certificate) throws CertificateEncodingException, NoSuchAlgorithmException {
return Helper.sha256(certificate.getEncoded()); return Helper.sha256(certificate.getEncoded());
} }
static String getFingerprintSha1(X509Certificate certificate) throws CertificateEncodingException, NoSuchAlgorithmException {
return Helper.sha1(certificate.getEncoded());
}
static String getKeyId(X509Certificate certificate) {
try {
byte[] extension = certificate.getExtensionValue(Extension.subjectKeyIdentifier.getId());
if (extension == null)
return null;
byte[] bytes = DEROctetString.getInstance(extension).getOctets();
SubjectKeyIdentifier keyId = SubjectKeyIdentifier.getInstance(bytes);
return Helper.hex(keyId.getKeyIdentifier());
} catch (Throwable ex) {
Log.e(ex);
return null;
}
}
static String getSubject(X509Certificate certificate) { static String getSubject(X509Certificate certificate) {
return certificate.getSubjectX500Principal().getName(X500Principal.RFC2253); return certificate.getSubjectX500Principal().getName(X500Principal.RFC2253);
} }
@ -199,7 +220,7 @@ public class EntityCertificate {
certificate.data = json.getString("data"); certificate.data = json.getString("data");
X509Certificate cert = certificate.getCertificate(); X509Certificate cert = certificate.getCertificate();
certificate.fingerprint = getFingerprint(cert); certificate.fingerprint = getFingerprintSha256(cert);
certificate.subject = getSubject(cert); certificate.subject = getSubject(cert);
Date after = cert.getNotBefore(); Date after = cert.getNotBefore();

@ -7018,7 +7018,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
if (s.verify(verifier)) { if (s.verify(verifier)) {
boolean known = true; boolean known = true;
String fingerprint = EntityCertificate.getFingerprint(cert); String fingerprint = EntityCertificate.getFingerprintSha256(cert);
List<String> emails = EntityCertificate.getEmailAddresses(cert); List<String> emails = EntityCertificate.getEmailAddresses(cert);
for (String email : emails) { for (String email : emails) {
EntityCertificate record = db.certificate().getCertificate(fingerprint, email); EntityCertificate record = db.certificate().getCertificate(fingerprint, email);
@ -7349,7 +7349,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
if (message == null) if (message == null)
return null; return null;
String fingerprint = EntityCertificate.getFingerprint(cert); String fingerprint = EntityCertificate.getFingerprintSha256(cert);
List<String> emails = EntityCertificate.getEmailAddresses(cert); List<String> emails = EntityCertificate.getEmailAddresses(cert);
for (String email : emails) { for (String email : emails) {
EntityCertificate record = db.certificate().getCertificate(fingerprint, email); EntityCertificate record = db.certificate().getCertificate(fingerprint, email);

Loading…
Cancel
Save