Skip to content

Commit

Permalink
7192189: Support endpoint identification algorithm in RFC 6125
Browse files Browse the repository at this point in the history
Reviewed-by: xuelei, rhalade
  • Loading branch information
seanjmullan committed Mar 8, 2022
1 parent 288d1af commit 72e987e
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 43 deletions.
41 changes: 4 additions & 37 deletions src/java.base/share/classes/sun/security/util/HostnameChecker.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -178,7 +178,7 @@ private static void matchIP(String expectedIP, X509Certificate cert)
* Certification Authorities are encouraged to use the dNSName instead.
*
* Matching is performed using the matching rules specified by
* [RFC5280]. If more than one identity of a given type is present in
* [RFC6125]. If more than one identity of a given type is present in
* the certificate (e.g., more than one dNSName name, a match in any one
* of the set is considered acceptable.)
*/
Expand Down Expand Up @@ -262,7 +262,7 @@ public static X500Name getSubjectX500Name(X509Certificate cert)
/**
* Returns true if name matches against template.<p>
*
* The matching is performed as per RFC 2818 rules for TLS and
* The matching is performed as per RFC 2818/6125 rules for TLS and
* RFC 2830 rules for LDAP.<p>
*
* The <code>name</code> parameter should represent a DNS name. The
Expand Down Expand Up @@ -299,9 +299,7 @@ private boolean isMatched(String name, String template,
return false;
}

if (checkType == TYPE_TLS) {
return matchAllWildcards(name, template);
} else if (checkType == TYPE_LDAP) {
if (checkType == TYPE_TLS || checkType == TYPE_LDAP) {
return matchLeftmostWildcard(name, template);
} else {
return false;
Expand Down Expand Up @@ -371,37 +369,6 @@ private static boolean hasIllegalWildcard(
return false;
}

/**
* Returns true if name matches against template.<p>
*
* According to RFC 2818, section 3.1 -
* 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. f*.com matches foo.com but not bar.com.
*/
private static boolean matchAllWildcards(String name,
String template) {
name = name.toLowerCase(Locale.ENGLISH);
template = template.toLowerCase(Locale.ENGLISH);
StringTokenizer nameSt = new StringTokenizer(name, ".");
StringTokenizer templateSt = new StringTokenizer(template, ".");

if (nameSt.countTokens() != templateSt.countTokens()) {
return false;
}

while (nameSt.hasMoreTokens()) {
if (!matchWildCards(nameSt.nextToken(),
templateSt.nextToken())) {
return false;
}
}
return true;
}


/**
* Returns true if name matches against template.<p>
*
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -23,16 +23,19 @@

/*
* @test
* @bug 4514108
* @summary Verify host name matching behaves as defined in RFC2818.
* @bug 4514108 7192189
* @summary Verify host name matching behaves as defined in RFC2818 and RFC6125.
* @library /test/lib
* @modules java.base/sun.security.util
* @modules java.base/sun.security.util java.base/sun.security.x509
*/

import java.security.cert.*;
import java.util.Collection;
import java.util.List;

import jdk.test.lib.security.CertUtils;
import sun.security.util.*;
import sun.security.x509.X509CertImpl;

/**
* Certificate 1:
Expand Down Expand Up @@ -193,10 +196,17 @@ public static void main(String[] args) throws Exception {
check(checker, "altfoo2.com", cert3, true);
check(checker, "5.6.7.8", cert3, true);
check(checker, "foo.bar.com", cert4, true);
check(checker, "altfoo.bar.com", cert4, true);
check(checker, "altfoo.bar.com", cert4, false);
check(checker, "2001:db8:3c4d:15::1a2f:1a2b", cert5, true);
check(checker, "2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b", cert5, true);
check(checker, "2002:db8:3c4d:15::1a2f:1a2b", cert5, false);
check(checker, "foo.bar.example.net", mock("foo.*.example.net"), false);
check(checker, "baz1.example.net", mock("baz*.example.net"), true);
check(checker, "foobaz.example.net", mock("*baz.example.net"), true);
check(checker, "buzz.example.net", mock("b*z.example.net"), true);
check(checker, "公司.example.net", mock("xn--5*.example.net"), false);
check(checker, "公司.江利子.example.net",
mock("*.xn--kcry6tjko.example.net"), true);

checker = HostnameChecker.getInstance(
HostnameChecker.TYPE_LDAP);
Expand All @@ -214,6 +224,15 @@ public static void main(String[] args) throws Exception {
check(checker, "altfoo.bar.com", cert4, false);
}

private static X509Certificate mock(String domain) {
return new X509CertImpl() {
@Override
public Collection<List<?>> getSubjectAlternativeNames() {
return List.of(List.of(2, domain));
}
};
}

private static void check(HostnameChecker checker, String name,
X509Certificate cert, boolean expectedResult)
throws Exception {
Expand All @@ -224,7 +243,7 @@ private static void check(HostnameChecker checker, String name,
}
} catch (CertificateException e) {
if (expectedResult == true) {
throw e;
throw new Exception("Failed valid test: " + name, e);
}
}
System.out.println("OK: " + name);
Expand Down

1 comment on commit 72e987e

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.