From 8874d58e68f251bb3a9367caa686e6ef08e55ce8 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Sat, 24 Jun 2017 10:05:30 +0200 Subject: also check for hostname in in certs if hostname is from trusted source --- .../de/duenndns/ssl/DomainHostnameVerifier.java | 10 ++++ .../de/duenndns/ssl/MemorizingTrustManager.java | 68 +++++++++------------- 2 files changed, 38 insertions(+), 40 deletions(-) create mode 100644 libs/MemorizingTrustManager/src/de/duenndns/ssl/DomainHostnameVerifier.java (limited to 'libs') diff --git a/libs/MemorizingTrustManager/src/de/duenndns/ssl/DomainHostnameVerifier.java b/libs/MemorizingTrustManager/src/de/duenndns/ssl/DomainHostnameVerifier.java new file mode 100644 index 000000000..62b625ab9 --- /dev/null +++ b/libs/MemorizingTrustManager/src/de/duenndns/ssl/DomainHostnameVerifier.java @@ -0,0 +1,10 @@ +package de.duenndns.ssl; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; + +public interface DomainHostnameVerifier extends HostnameVerifier { + + boolean verify(String domain, String hostname, SSLSession sslSession); + +} diff --git a/libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingTrustManager.java b/libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingTrustManager.java index e46b6d5fb..a3aa561ef 100644 --- a/libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingTrustManager.java +++ b/libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingTrustManager.java @@ -298,18 +298,11 @@ public class MemorizingTrustManager { * @return a new hostname verifier using the MTM's key store * @throws IllegalArgumentException if the defaultVerifier parameter is null */ - public HostnameVerifier wrapHostnameVerifier(final HostnameVerifier defaultVerifier) { - if (defaultVerifier == null) + public DomainHostnameVerifier wrapHostnameVerifier(final HostnameVerifier defaultVerifier, final boolean interactive) { + if (defaultVerifier == null) { throw new IllegalArgumentException("The default verifier may not be null"); - - return new MemorizingHostnameVerifier(defaultVerifier); - } - - public HostnameVerifier wrapHostnameVerifierNonInteractive(final HostnameVerifier defaultVerifier) { - if (defaultVerifier == null) - throw new IllegalArgumentException("The default verifier may not be null"); - - return new NonInteractiveMemorizingHostnameVerifier(defaultVerifier); + } + return new MemorizingHostnameVerifier(defaultVerifier, interactive); } X509TrustManager getTrustManager(KeyStore ks) { @@ -787,31 +780,40 @@ public class MemorizingTrustManager { } } - class MemorizingHostnameVerifier implements HostnameVerifier { - private HostnameVerifier defaultVerifier; + class MemorizingHostnameVerifier implements DomainHostnameVerifier { + private final HostnameVerifier defaultVerifier; + private final boolean interactive; - public MemorizingHostnameVerifier(HostnameVerifier wrapped) { - defaultVerifier = wrapped; + public MemorizingHostnameVerifier(HostnameVerifier wrapped, boolean interactive) { + this.defaultVerifier = wrapped; + this.interactive = interactive; } - protected boolean verify(String hostname, SSLSession session, boolean interactive) { - LOGGER.log(Level.FINE, "hostname verifier for " + hostname + ", trying default verifier first"); + @Override + public boolean verify(String domain, String hostname, SSLSession session) { + LOGGER.log(Level.FINE, "hostname verifier for " + domain + ", trying default verifier first"); // if the default verifier accepts the hostname, we are done - if (defaultVerifier.verify(hostname, session)) { - LOGGER.log(Level.FINE, "default verifier accepted " + hostname); - return true; + if (defaultVerifier instanceof DomainHostnameVerifier) { + if (((DomainHostnameVerifier) defaultVerifier).verify(domain, hostname, session)) { + return true; + } + } else { + if (defaultVerifier.verify(domain, session)) { + return true; + } } + // otherwise, we check if the hostname is an alias for this cert in our keystore try { X509Certificate cert = (X509Certificate) session.getPeerCertificates()[0]; //Log.d(TAG, "cert: " + cert); - if (cert.equals(appKeyStore.getCertificate(hostname.toLowerCase(Locale.US)))) { - LOGGER.log(Level.FINE, "certificate for " + hostname + " is in our keystore. accepting."); + if (cert.equals(appKeyStore.getCertificate(domain.toLowerCase(Locale.US)))) { + LOGGER.log(Level.FINE, "certificate for " + domain + " is in our keystore. accepting."); return true; } else { - LOGGER.log(Level.FINE, "server " + hostname + " provided wrong certificate, asking user."); + LOGGER.log(Level.FINE, "server " + domain + " provided wrong certificate, asking user."); if (interactive) { - return interactHostname(cert, hostname); + return interactHostname(cert, domain); } else { return false; } @@ -823,23 +825,9 @@ public class MemorizingTrustManager { } @Override - public boolean verify(String hostname, SSLSession session) { - return verify(hostname, session, true); - } - } - - class NonInteractiveMemorizingHostnameVerifier extends MemorizingHostnameVerifier { - - public NonInteractiveMemorizingHostnameVerifier(HostnameVerifier wrapped) { - super(wrapped); + public boolean verify(String domain, SSLSession sslSession) { + return verify(domain, null, sslSession); } - - @Override - public boolean verify(String hostname, SSLSession session) { - return verify(hostname, session, false); - } - - } public X509TrustManager getNonInteractive(String domain) { -- cgit v1.2.3