From 938cd3b9e9562a0560744b2796de424c84de9988 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 10 Apr 2025 10:05:52 +0200 Subject: [PATCH] logging and code clean up in XmppDomainVerifier --- .../crypto/XmppDomainVerifier.java | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/XmppDomainVerifier.java b/src/main/java/eu/siacs/conversations/crypto/XmppDomainVerifier.java index a0b36985e3cd3fe6d298ee69335711dc34e0ec12..614bd185c6ae0a32bd3047b42f5e6c991fd80cc2 100644 --- a/src/main/java/eu/siacs/conversations/crypto/XmppDomainVerifier.java +++ b/src/main/java/eu/siacs/conversations/crypto/XmppDomainVerifier.java @@ -2,6 +2,8 @@ package eu.siacs.conversations.crypto; import android.util.Log; import android.util.Pair; +import androidx.annotation.NonNull; +import com.google.common.base.CharMatcher; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import java.io.IOException; @@ -12,6 +14,7 @@ import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Locale; import javax.net.ssl.SSLPeerUnverifiedException; @@ -36,18 +39,18 @@ public class XmppDomainVerifier { private static final String XMPP_ADDR = "1.3.6.1.5.5.7.8.5"; private static List getCommonNames(final X509Certificate certificate) { - List domains = new ArrayList<>(); + final var domains = new ImmutableList.Builder(); try { - X500Name x500name = new JcaX509CertificateHolder(certificate).getSubject(); - RDN[] rdns = x500name.getRDNs(BCStyle.CN); - for (int i = 0; i < rdns.length; ++i) { + final var x500name = new JcaX509CertificateHolder(certificate).getSubject(); + final RDN[] nameRDNs = x500name.getRDNs(BCStyle.CN); + for (int i = 0; i < nameRDNs.length; ++i) { domains.add( IETFUtils.valueToString( x500name.getRDNs(BCStyle.CN)[i].getFirst().getValue())); } - return domains; - } catch (CertificateEncodingException e) { - return domains; + return domains.build(); + } catch (final CertificateEncodingException e) { + return Collections.emptyList(); } } @@ -75,17 +78,24 @@ public class XmppDomainVerifier { } } - public static boolean matchDomain(final String needle, final List haystack) { - for (final String entry : haystack) { - if (entry.startsWith("*.")) { + public static boolean matchDomain(final String domain, final List certificateDomains) { + for (final String certificateDomain : certificateDomains) { + if (certificateDomain.startsWith("*.")) { // https://www.rfc-editor.org/rfc/rfc6125#section-6.4.3 // wild cards can only be in the left most label and don’t match '.' - final int i = needle.indexOf('.'); - if (i != -1 && needle.substring(i).equalsIgnoreCase(entry.substring(1))) { + final var wildcardEntry = certificateDomain.substring(1); + if (CharMatcher.is('.').countIn(wildcardEntry) < 2) { + Log.w(LOGTAG, "not enough labels in wildcard certificate"); + break; + } + final int position = domain.indexOf('.'); + if (position != -1 && domain.substring(position).equalsIgnoreCase(wildcardEntry)) { + Log.d(LOGTAG, "domain " + domain + " matched " + certificateDomain); return true; } } else { - if (entry.equalsIgnoreCase(needle)) { + if (certificateDomain.equalsIgnoreCase(domain)) { + Log.d(LOGTAG, "domain " + domain + " matched " + certificateDomain); return true; } } @@ -184,6 +194,7 @@ public class XmppDomainVerifier { return all.build(); } + @NonNull @Override public String toString() { return MoreObjects.toStringHelper(this)