Skip to content

Commit

Permalink
Add test.
Browse files Browse the repository at this point in the history
Fix host as well.
  • Loading branch information
arturobernalg committed Jan 5, 2025
1 parent accc382 commit 2c31053
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -230,43 +230,51 @@ private static boolean matchIdentity(final String host, final String identity,
final DomainType domainType,
final boolean strict) {

final String unicodeIdentity;
final String normalizedHost;
final String normalizedIdentity;
try {
unicodeIdentity = IDN.toUnicode(identity);
normalizedHost = IDN.toUnicode(host);
normalizedIdentity = IDN.toUnicode(identity);
} catch (final IllegalArgumentException e) {
return false;
}

// Public suffix check on the Unicode identity
if (publicSuffixMatcher != null && host.contains(".")) {
if (publicSuffixMatcher.getDomainRoot(unicodeIdentity, domainType) == null) {
if (publicSuffixMatcher != null && normalizedHost.contains(".")) {
if (publicSuffixMatcher.getDomainRoot(normalizedIdentity, domainType) == null) {
return false;
}
}

// Handle wildcard in the Unicode identity
final int asteriskIdx = unicodeIdentity.indexOf('*');
// RFC 2818, 3.1. Server Identity
// "...Names may contain the wildcard
// character * which is considered to match any single domain name
// component or component fragment..."
// Based on this statement presuming only singular wildcard is legal
final int asteriskIdx = normalizedIdentity.indexOf('*');
if (asteriskIdx != -1) {
final String prefix = unicodeIdentity.substring(0, asteriskIdx);
final String suffix = unicodeIdentity.substring(asteriskIdx + 1);
final String prefix = normalizedIdentity.substring(0, asteriskIdx);
final String suffix = normalizedIdentity.substring(asteriskIdx + 1);

if (!prefix.isEmpty() && !host.startsWith(prefix)) {
if (!prefix.isEmpty() && !normalizedHost.startsWith(prefix)) {
return false;
}
if (!suffix.isEmpty() && !host.endsWith(suffix)) {
if (!suffix.isEmpty() && !normalizedHost.endsWith(suffix)) {
return false;
}

// Additional sanity checks on the wildcard portion
// Additional sanity checks on content selected by wildcard can be done here
if (strict) {
final String remainder = host.substring(prefix.length(), host.length() - suffix.length());
final String remainder = normalizedHost.substring(
prefix.length(),
normalizedHost.length() - suffix.length()
);
return !remainder.contains(".");
}
return true;
}

// Direct Unicode comparison
return host.equalsIgnoreCase(unicodeIdentity);
return normalizedHost.equalsIgnoreCase(normalizedIdentity);
}

static boolean matchIdentity(final String host, final String identity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -473,21 +473,94 @@ void testMatchDNSName() throws Exception {
}

@Test
void testMatchIdentityWithIDN() {
final String unicodeHost = "поиск-слов.рф";
final String punycodeHost = "xn----dtbqigoecuc.xn--p1ai";
void testMatchIdentity() {
// Test 1: IDN matching punycode
final String unicodeHost1 = "поиск-слов.рф";
final String punycodeHost1 = "xn----dtbqigoecuc.xn--p1ai";

// These should now match, thanks to IDN.toASCII():
Assertions.assertTrue(
DefaultHostnameVerifier.matchIdentity(unicodeHost, punycodeHost),
DefaultHostnameVerifier.matchIdentity(unicodeHost1, punycodeHost1),
"Expected the Unicode host and its punycode to match"
);

// ‘example.com’ vs. an unrelated punycode domain should fail:
Assertions.assertFalse(
DefaultHostnameVerifier.matchIdentity("example.com", punycodeHost),
DefaultHostnameVerifier.matchIdentity("example.com", punycodeHost1),
"Expected mismatch between example.com and xn----dtbqigoecuc.xn--p1ai"
);

// Test 2: Unicode host and Unicode identity
final String unicodeHost2 = "пример.рф";
final String unicodeIdentity2 = "пример.рф";
Assertions.assertTrue(
DefaultHostnameVerifier.matchIdentity(unicodeHost2, unicodeIdentity2),
"Expected Unicode host and Unicode identity to match"
);

// Test 3: Punycode host and Unicode identity
final String punycodeHost2 = "xn--e1afmkfd.xn--p1ai";
final String unicodeIdentity3 = "пример.рф";
Assertions.assertTrue(
DefaultHostnameVerifier.matchIdentity(punycodeHost2, unicodeIdentity3),
"Expected punycode host and Unicode identity to match"
);

// Test 4: Unicode host and Punycode identity
final String unicodeHost3 = "пример.рф";
final String punycodeIdentity3 = "xn--e1afmkfd.xn--p1ai";
Assertions.assertTrue(
DefaultHostnameVerifier.matchIdentity(unicodeHost3, punycodeIdentity3),
"Expected Unicode host and punycode identity to match"
);

// Test 5: Wildcard matching in the left-most label
final String unicodeHost4 = "sub.пример.рф";
final String unicodeIdentity4 = "*.пример.рф";
Assertions.assertTrue(
DefaultHostnameVerifier.matchIdentity(unicodeHost4, unicodeIdentity4),
"Expected wildcard to match subdomain"
);

// Test 6: Invalid host
final String invalidHost = "invalid_host";
final String unicodeIdentity5 = "пример.рф";
Assertions.assertFalse(
DefaultHostnameVerifier.matchIdentity(invalidHost, unicodeIdentity5),
"Expected invalid host to not match"
);

// Test 7: Invalid identity
final String unicodeHost4b = "пример.рф";
final String invalidIdentity = "xn--invalid-punycode";
Assertions.assertFalse(
DefaultHostnameVerifier.matchIdentity(unicodeHost4b, invalidIdentity),
"Expected invalid identity to not match"
);

// Test 8: Mixed case comparison
final String unicodeHost5 = "ПрИмеР.рф";
final String unicodeIdentity6 = "пример.рф";
Assertions.assertTrue(
DefaultHostnameVerifier.matchIdentity(unicodeHost5, unicodeIdentity6),
"Expected case-insensitive Unicode comparison to match"
);

// Test 9: Wildcard with punycode host
final String punycodeHost3 = "xn--a-7h.xn--e1afmkfd.xn--p1ai";
final String unicodeIdentity7 = "*.пример.рф";
Assertions.assertTrue(
DefaultHostnameVerifier.matchIdentity(punycodeHost3, unicodeIdentity7),
"Expected wildcard to match punycode-encoded host"
);

// Test 10: Wildcard in the middle label (per RFC 2818, should match)
final String unicodeHost6 = "sub.пример.рф";
final String unicodeIdentity8 = "sub.*.рф";
Assertions.assertTrue(
DefaultHostnameVerifier.matchIdentity(unicodeHost6, unicodeIdentity8),
"Expected wildcard in the middle label to match"
);
}

}

0 comments on commit 2c31053

Please sign in to comment.