[HTTPCLIENT-1410: Browser compatible hostname verifier no longer rejects *.co.<countrycode>, *.gov.<countrycode>, *.info.<countrycode>, etc as invalid
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1528744 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
75937296d9
commit
fea3c55520
|
@ -1,6 +1,10 @@
|
|||
Changes since 4.3
|
||||
-------------------
|
||||
|
||||
* [HTTPCLIENT-1410] Browser compatible hostname verifier no longer rejects
|
||||
*.co.<countrycode>, *.gov.<countrycode>, *.info.<countrycode>, etc as invalid.
|
||||
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
||||
|
||||
* Ensure X509HostnameVerifier is never null.
|
||||
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
||||
|
||||
|
|
|
@ -201,10 +201,9 @@ public abstract class AbstractVerifier implements X509HostnameVerifier {
|
|||
// action. It also can't be [*.co.uk] or [*.co.jp] or
|
||||
// [*.org.uk], etc...
|
||||
final String parts[] = cn.split("\\.");
|
||||
final boolean doWildcard = parts.length >= 3 &&
|
||||
parts[0].endsWith("*") &&
|
||||
acceptableCountryWildcard(cn) &&
|
||||
!isIPAddress(host);
|
||||
final boolean doWildcard =
|
||||
parts.length >= 3 && parts[0].endsWith("*") &&
|
||||
validCountryWildcard(cn) && !isIPAddress(host);
|
||||
|
||||
if(doWildcard) {
|
||||
final String firstpart = parts[0];
|
||||
|
@ -233,6 +232,10 @@ public abstract class AbstractVerifier implements X509HostnameVerifier {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated (4.3.1) should not be a part of public APIs.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean acceptableCountryWildcard(final String cn) {
|
||||
final String parts[] = cn.split("\\.");
|
||||
if (parts.length != 3 || parts[2].length() != 2) {
|
||||
|
@ -241,6 +244,14 @@ public abstract class AbstractVerifier implements X509HostnameVerifier {
|
|||
return Arrays.binarySearch(BAD_COUNTRY_2LDS, parts[1]) < 0;
|
||||
}
|
||||
|
||||
boolean validCountryWildcard(final String cn) {
|
||||
final String parts[] = cn.split("\\.");
|
||||
if (parts.length != 3 || parts[2].length() != 2) {
|
||||
return true; // it's not an attempt to wildcard a 2TLD within a country code
|
||||
}
|
||||
return Arrays.binarySearch(BAD_COUNTRY_2LDS, parts[1]) < 0;
|
||||
}
|
||||
|
||||
public static String[] getCNs(final X509Certificate cert) {
|
||||
final LinkedList<String> cnList = new LinkedList<String>();
|
||||
/*
|
||||
|
|
|
@ -54,6 +54,11 @@ public class BrowserCompatHostnameVerifier extends AbstractVerifier {
|
|||
verify(host, cns, subjectAlts, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean validCountryWildcard(final String cn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return "BROWSER_COMPATIBLE";
|
||||
|
|
|
@ -150,9 +150,9 @@ public class TestHostnameVerifier {
|
|||
// using "*.co.jp".
|
||||
DEFAULT.verify("*.co.jp", x509);
|
||||
STRICT.verify("*.co.jp", x509);
|
||||
exceptionPlease(DEFAULT, "foo.co.jp", x509);
|
||||
DEFAULT.verify("foo.co.jp", x509);
|
||||
exceptionPlease(STRICT, "foo.co.jp", x509);
|
||||
exceptionPlease(DEFAULT, "\u82b1\u5b50.co.jp", x509);
|
||||
DEFAULT.verify("\u82b1\u5b50.co.jp", x509);
|
||||
exceptionPlease(STRICT, "\u82b1\u5b50.co.jp", x509);
|
||||
|
||||
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_WILD_FOO_BAR_HANAKO);
|
||||
|
@ -285,10 +285,10 @@ public class TestHostnameVerifier {
|
|||
checkMatching(shv, "s.a.b.c", cns, alt, true); // subdomain not OK
|
||||
|
||||
alt = new String []{"*.gov.uk"};
|
||||
checkMatching(bhv, "a.gov.uk", cns, alt, true); // Bad 2TLD
|
||||
checkMatching(bhv, "a.gov.uk", cns, alt, false); // OK
|
||||
checkMatching(shv, "a.gov.uk", cns, alt, true); // Bad 2TLD
|
||||
|
||||
checkMatching(bhv, "s.a.gov.uk", cns, alt, true); // Bad 2TLD
|
||||
checkMatching(bhv, "s.a.gov.uk", cns, alt, false); // OK
|
||||
checkMatching(shv, "s.a.gov.uk", cns, alt, true); // Bad 2TLD/no subdomain allowed
|
||||
|
||||
alt = new String []{"*.gov.com"};
|
||||
|
@ -299,7 +299,7 @@ public class TestHostnameVerifier {
|
|||
checkMatching(shv, "s.a.gov.com", cns, alt, true); // no subdomain allowed
|
||||
|
||||
cns = new String []{"a*.gov.uk"}; // 2TLD check applies to wildcards
|
||||
checkMatching(bhv, "a.gov.uk", cns, alt, true); // Bad 2TLD
|
||||
checkMatching(bhv, "a.gov.uk", cns, alt, false); // OK
|
||||
checkMatching(shv, "a.gov.uk", cns, alt, true); // Bad 2TLD
|
||||
|
||||
checkMatching(bhv, "s.a.gov.uk", cns, alt, true); // Bad 2TLD
|
||||
|
@ -336,10 +336,6 @@ public class TestHostnameVerifier {
|
|||
|
||||
checkMatching(bhv, "a.a.b.c", cns, alt, false); // OK
|
||||
checkMatching(shv, "a.a.b.c", cns, alt, true); // subdomain not OK
|
||||
|
||||
checkWildcard("s*.co.uk", false); // 2 character TLD, invalid 2TLD
|
||||
checkWildcard("s*.gov.uk", false); // 2 character TLD, invalid 2TLD
|
||||
checkWildcard("s*.gouv.uk", false); // 2 character TLD, invalid 2TLD
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -353,23 +349,6 @@ public class TestHostnameVerifier {
|
|||
checkMatching(shv, "mail.a.b.c.com", cns, alt, false); // OK
|
||||
}
|
||||
|
||||
// Helper
|
||||
private void checkWildcard(final String host, final boolean isOK) {
|
||||
Assert.assertTrue(host+" should be "+isOK, isOK==AbstractVerifier.acceptableCountryWildcard(host));
|
||||
}
|
||||
|
||||
@Test
|
||||
// Various checks of 2TLDs
|
||||
public void testAcceptableCountryWildcards() {
|
||||
checkWildcard("*.co.org", true); // Not a 2 character TLD
|
||||
checkWildcard("s*.co.org", true); // Not a 2 character TLD
|
||||
checkWildcard("*.co.uk", false); // 2 character TLD, invalid 2TLD
|
||||
checkWildcard("*.gov.uk", false); // 2 character TLD, invalid 2TLD
|
||||
checkWildcard("*.gouv.uk", false); // 2 character TLD, invalid 2TLD
|
||||
checkWildcard("*.a.co.uk", true); // 2 character TLD, invalid 2TLD, but using subdomain
|
||||
checkWildcard("s*.a.co.uk", true); // 2 character TLD, invalid 2TLD, but using subdomain
|
||||
}
|
||||
|
||||
public void testGetCNs() {
|
||||
final Principal principal = Mockito.mock(Principal.class);
|
||||
final X509Certificate cert = Mockito.mock(X509Certificate.class);
|
||||
|
|
Loading…
Reference in New Issue