JDK-4917253 : URIName can't handle URI name constraints
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 1.4.0,1.4.2
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,linux
  • CPU: generic,x86
  • Submitted: 2003-09-04
  • Updated: 2003-09-27
  • Resolved: 2003-09-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 tigerFixed
Related Reports
Duplicate :  
Description
The sun.security.x509.URIName class throws an exception if it's asked to parse a valid URI name constraint. It complains that "Name does not include a <scheme>". But URI name constraints (as described in RFC 2459 and RFC 3280) don't have a scheme. They just contain a DNS name (optionally prefixed with a period).

This means that Sun's JDK (any version from 1.4 to current 1.5 builds, I think) can't parse a certificate that contains a valid URI name constraint. This could result in perfectly good certificates being rejected for no valid reason, which could cause authentication or other security functions to fail (denying access to services).

This is not a security hole. No unauthorized actions will be permitted (unless the application writer did something very strange and dumb, like granting total access when a certificate can't be parsed!). And URI name constraints are not widely used. But they are used somewhat and this bug should be fixed.

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger FIXED IN: tiger INTEGRATED IN: tiger tiger-b22
14-06-2004

WORK AROUND There's no practical workaround. You could write your own certificate classes or just ignore certificates. But that's not very practical.
11-06-2004

SUGGESTED FIX Change the parsing code and the name constraint matching code in URIName to handle properly formatted URI name constraints. Below is the source code for the fix. The JDK 1.4.2 source code is marked with < and the fix is marked with >. URIName.java doesn't seem to have changed at all in JDK 1.5, so it should be easy to apply this fix. Sorry that the diffs aren't very readable. The changes are actually pretty simple. Note also that I have attached files which constitute a test case for this fix. Detach the files into an empty directory, then build and run URINC.java. If the fix is in place, it will print "path validates OK" to standard out. If the fix is not in place, it will print "path doesn't validate". Changes to URIName.java: 125a126,171 > if (name.length() == 0) > throw new IOException("URIName cannot be zero length."); > > try { > // See if this is a full URI > parseFullName(); > } catch (IOException ioe) { > // If it's not a full URI, see if it's a URI name constraint > host = name; > // Verify host portion is a valid DNS name > try { > if (host.charAt(0) == '.') { > hostDNS = new DNSName(host.substring(1)); > } else > hostDNS = new DNSName(host); > } catch (IOException ioe2) { > // If not, throw the original exception > throw ioe; > } > } > } > > /** > * parse the URIName into scheme, host, and remainder. > * Host includes only the fully-qualified domain name > * or IP address. Remainder includes everything except the > * scheme and host. > * <p> > * Since RFC2459 specifies that email addresses must be specified > * using emailaddress= attribute in X500Name or using RFC822Name, > * we do not need to support the "mailto:###@###.###" scheme > * that has no //. > * <p> > * Format:, where > * <ul> > * <li>[] encloses optional elements > * <li>'[' and ']' are literal square brackets > * <li>{} encloses a choice > * <li>| separates elements in a choice > * <li>&lt;&gt; encloses an element > * <p> > * &lt;scheme&gt; :// [ &lt;username&gt; @ ] { '['&lt;IPv6 addr&gt;']' | &lt;IPv4 addr&gt; | &lt;DNSName&gt; } [: &lt;port&gt;] [ / [ &lt;directory&gt; ] ] > * <p> > * @throws IOException if name is not a full URIName > */ > private void parseFullName() throws IOException { 196,199c242 < if (host.charAt(0) == '.') { < hostDNS = new DNSName(host.substring(1)); < } else < hostDNS = new DNSName(host); --- > hostDNS = new DNSName(host); 287,288c330 < * @param name full URIName < * @returns scheme portion of full name --- > * @returns scheme portion of name 297d338 < * @param name full URIName 369c410,413 < String otherScheme = ((URIName)inputName).getScheme(); --- > // Assuming from here on that one or both of these is > // actually a URI name constraint (not a URI), so we > // only need to compare the host portion of the name > 372,374c416,417 < if (!(scheme.equalsIgnoreCase(otherScheme))) < constraintType = NAME_SAME_TYPE; < else if (otherHost.equals(host)) --- > // Quick check for equality > if (otherHost.equals(host)) 376,397c419,438 < else if ((((URIName)inputName).getHostObject() instanceof IPAddressName) && < hostIP != null) { < return hostIP.constrains((IPAddressName)((URIName)inputName).getHostObject()); < } else { < //At least one host is not an IPAddressName < if (otherHost.charAt(0) == '.' || host.charAt(0) == '.') { < //DNSName constraint semantics specify subdomains without an initial < //period on the constraint. URIName constraint semantics specify subdomains < //only when the constraint host name starts with a period. < DNSName hostDNS; < DNSName otherDNS; < try { < if (host.charAt(0) == '.') < hostDNS = new DNSName(host.substring(1)); < else < hostDNS = new DNSName(host); < if (otherHost.charAt(0) == '.') < otherDNS = new DNSName(otherHost.substring(1)); < else < otherDNS = new DNSName(otherHost); < constraintType = hostDNS.constrains(otherDNS); < } catch (IOException ioe2) { --- > else { > Object otherHostObject = ((URIName)inputName).getHostObject(); > > if ((hostDNS == null) || > !(otherHostObject instanceof DNSName)) { > // If one (or both) is an IP address, only same type > constraintType = NAME_SAME_TYPE; > } else { > // Both host portions are DNS names. Are they domains? > boolean thisDomain = (host.charAt(0) == '.'); > boolean otherDomain = (otherHost.charAt(0) == '.'); > DNSName otherDNS = (DNSName) otherHostObject; > > // Run DNSName.constrains. > constraintType = hostDNS.constrains(otherDNS); > // If neither one is a domain, then they can't > // widen or narrow. That's just SAME_TYPE. > if ((!thisDomain && !otherDomain) && > ((constraintType == NAME_WIDENS) || > (constraintType == NAME_NARROWS))) 399,401c440,451 < } catch (UnsupportedOperationException uoe) { < //At least one of the hosts is not a valid DNS name < constraintType = NAME_SAME_TYPE; --- > > // If one is a domain and the other isn't, > // then they can't match. The one that's a > // domain doesn't include the one that's > // not a domain. > if ((thisDomain != otherDomain) && > (constraintType == NAME_MATCH)) { > if (thisDomain) { > constraintType = NAME_WIDENS; > } else { > constraintType = NAME_NARROWS; > } 403,404d452 < } else { < constraintType = NAME_SAME_TYPE;
11-06-2004

PUBLIC COMMENTS
10-06-2004

EVALUATION ###@###.### 2003-09-10 Yes, I have verified that this is a bug.
10-09-2003