Use key ID instead of fingerprint when possible

pull/172/head
M66B 6 years ago
parent 72eeb98389
commit f920601a22

@ -20,7 +20,10 @@ import net.openid.appauth.ClientAuthentication;
import net.openid.appauth.ClientSecretPost; import net.openid.appauth.ClientSecretPost;
import net.openid.appauth.NoClientAuthentication; import net.openid.appauth.NoClientAuthentication;
import org.bouncycastle.asn1.DEROctetString;
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.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.IOException; import java.io.IOException;
@ -306,7 +309,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.getFingerPrint(), ex); throw new UntrustedException(factory.getFingerPrintSelect(), ex);
if (ce instanceof IOException) if (ce instanceof IOException)
ioError = true; ioError = true;
ce = ce.getCause(); ce = ce.getCause();
@ -563,6 +566,8 @@ public class EmailService implements AutoCloseable {
final X509TrustManager rtm = (X509TrustManager) tms[0]; final X509TrustManager rtm = (X509TrustManager) tms[0];
X509TrustManager tm = new X509TrustManager() { X509TrustManager tm = new X509TrustManager() {
// openssl s_client -connect <host>
@Override @Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
if (secure) if (secure)
@ -574,16 +579,8 @@ public class EmailService implements AutoCloseable {
certificate = chain[0]; certificate = chain[0];
if (secure) { if (secure) {
// Get certificate fingerprint
String fingerprint;
try {
fingerprint = getFingerPrint(certificate);
} catch (Throwable ex) {
throw new CertificateException(ex);
}
// Check if selected fingerprint // Check if selected fingerprint
if (fingerprint.equals(trustedFingerprint)) { if (trustedFingerprint != null && matches(certificate, trustedFingerprint)) {
Log.i("Trusted selected fingerprint"); Log.i("Trusted selected fingerprint");
return; return;
} }
@ -731,13 +728,48 @@ public class EmailService implements AutoCloseable {
return result; return result;
} }
private static boolean matches(X509Certificate certificate, @NonNull String trustedFingerprint) {
// Get certificate fingerprint
try {
String fingerprint = getFingerPrint(certificate);
int slash = trustedFingerprint.indexOf('/');
if (slash < 0)
return trustedFingerprint.equals(fingerprint);
else {
String keyId = getKeyId(certificate);
if (trustedFingerprint.substring(slash + 1).equals(keyId))
return true;
return trustedFingerprint.substring(0, slash).equals(fingerprint);
}
} catch (Throwable ex) {
Log.w(ex);
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 { private static String getFingerPrint(X509Certificate certificate) throws CertificateEncodingException, NoSuchAlgorithmException {
return Helper.sha1(certificate.getEncoded()); return Helper.sha1(certificate.getEncoded());
} }
String getFingerPrint() { String getFingerPrintSelect() {
try { try {
return getFingerPrint(certificate); String keyId = getKeyId(certificate);
String fingerPrint = getFingerPrint(certificate);
return fingerPrint + (keyId == null ? "" : "/" + keyId);
} catch (Throwable ex) { } catch (Throwable ex) {
Log.e(ex); Log.e(ex);
return null; return null;

@ -829,6 +829,10 @@ public class Helper {
static String sha(String digest, byte[] data) throws NoSuchAlgorithmException { static String sha(String digest, byte[] data) throws NoSuchAlgorithmException {
byte[] bytes = MessageDigest.getInstance(digest).digest(data); byte[] bytes = MessageDigest.getInstance(digest).digest(data);
return hex(bytes);
}
static String hex(byte[] bytes) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (byte b : bytes) for (byte b : bytes)
sb.append(String.format("%02x", b)); sb.append(String.format("%02x", b));

Loading…
Cancel
Save