wildcard certificates only match one label
Daniel Gultsch
created 8 months ago
Names may contain the wildcard character * which is considered to match any single domain name component or component fragment. E.g., *.a.com matches foo.a.com but not bar.foo.a.com
Change summary
src/main/java/eu/siacs/conversations/crypto/DomainHostnameVerifier.java | 11
src/main/java/eu/siacs/conversations/crypto/XmppDomainVerifier.java | 41
2 files changed, 16 insertions(+), 36 deletions(-)
Detailed changes
@@ -1,11 +0,0 @@
-package eu.siacs.conversations.crypto;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-
-public interface DomainHostnameVerifier extends HostnameVerifier {
-
- boolean verify(String domain, String hostname, SSLSession sslSession) throws SSLPeerUnverifiedException;
-
-}
@@ -2,22 +2,8 @@ package eu.siacs.conversations.crypto;
import android.util.Log;
import android.util.Pair;
-
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
-
-import org.bouncycastle.asn1.ASN1Object;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERIA5String;
-import org.bouncycastle.asn1.DERUTF8String;
-import org.bouncycastle.asn1.DLSequence;
-import org.bouncycastle.asn1.x500.RDN;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x500.style.BCStyle;
-import org.bouncycastle.asn1.x500.style.IETFUtils;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
-
import java.io.IOException;
import java.net.IDN;
import java.security.cert.Certificate;
@@ -28,9 +14,19 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
-
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERIA5String;
+import org.bouncycastle.asn1.DERUTF8String;
+import org.bouncycastle.asn1.DLSequence;
+import org.bouncycastle.asn1.x500.RDN;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x500.style.BCStyle;
+import org.bouncycastle.asn1.x500.style.IETFUtils;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
public class XmppDomainVerifier {
@@ -82,16 +78,11 @@ public class XmppDomainVerifier {
public static boolean matchDomain(final String needle, final List<String> haystack) {
for (final String entry : haystack) {
if (entry.startsWith("*.")) {
- int offset = 0;
- while (offset < needle.length()) {
- int i = needle.indexOf('.', offset);
- if (i < 0) {
- break;
- }
- if (needle.substring(i).equalsIgnoreCase(entry.substring(1))) {
- return true;
- }
- offset = i + 1;
+ // 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))) {
+ return true;
}
} else {
if (entry.equalsIgnoreCase(needle)) {