RFR: 8255739: x509Certificate returns � for invalid subjectAlternativeNames [v2]

Sean Mullan mullan at openjdk.java.net
Fri Jan 21 16:33:43 UTC 2022


On Fri, 14 Jan 2022 11:18:23 GMT, Masanori Yano <myano at openjdk.org> wrote:

>> Could you please review the JDK-8255739 bug fix?
>> 
>> I think sun.security.x509.SubjectAlternativeNameExtension() should throw an exception for incorrect SubjectAlternativeNames instead of returning the substituted characters, which is explained in the description of BugDB.
>> 
>> I modified DerValue.readStringInternal() not to read incorrect SubjectAlternativeNames and throw an IOException. sun.security.x509.X509CertInfo.parse() catch the IOExcepton and ignore it if SAN is a non-ciritical extension like the behavior of the IOException in readStringInternal(). So I added a test with -Djava.security.debug=x509 to confirm that.
>
> Masanori Yano has updated the pull request incrementally with one additional commit since the last revision:
> 
>   8255739: x509Certificate returns � for invalid subjectAlternativeNames

> _Mailing list message from [Michael StJohns](mailto:mstjohns at comcast.net) on [security-dev](mailto:security-dev at mail.openjdk.java.net):_
> 
> On 1/18/2022 4:10 PM, Sean Mullan wrote:
> 
> Hi -
> 
> Bouncycastle started enforcing properly encoded? INTEGERs a while back and that caused one of my programs to start failing due to a TPM X509 endorsement certificate just having the TPM serial number stuffed into the certificate serial number without normalizing it to the appropriate INTEGER encoding.? BC provided a work around (setting "org.bouncycastle.asn1.allow_unsafe_integer") which gave me time to re-code around the problem.? If you're going to break things, it may be useful to provide a work around similar to what they did.

Do you know the behavior of the JDK X.509 CertificateFactory implementation? Did it accept or reject this serial number?

> In any event, DerValue.java uses "new String(byteArrayValue, charsetType)" to produce the various String values including in getIA5String().? I.e.,
> 
> > public?String(byte[]?bytes,
> > Charset ?charset)
> > Constructs a new |String| by decoding the specified array of bytes
> > using the specified charset. The length of the new |String| is a
> > function of the charset, and hence may not be equal to the length of
> > the byte array.
> > _*This method always replaces malformed-input and unmappable-character
> > sequences with this charset's default replacement string.*_ The
> > |CharsetDecoder| class should be used when more control over the
> > decoding process is required.
> 
> Perhaps it might make sense to update the various places where this is used in DerValue to CharsetDecoder and to use charsetDecoder.onMalformedInput() and charsetDecoder.onUnmappableCharacter() to set the appropriate action related to parsing the byte array into a String of a given charset?? That action could be set based on the presence of the bypass property.

I believe that was originally suggested by the submitter as a potential solution. But it doesn't seem like it is that useful or there would be much demand for this.

> I don't think the change as proposed is backward-compatible safe enough, nor does it really address the general issue of poorly encoded DER String values in a certificate.

Yes, I have come to the conclusion that this is probably too risky to fix. An application that is depending on a DNSName should be doing additional matching checks to verify that the structure of the name is correct, and it doesn't violate other types of rules, such as wildcards involving public suffixes, etc. (The JDK code does these additional checks when verifying TLS server certificates).

See also https://groups.google.com/g/mozilla.dev.security.policy/c/Av6oZxbjvB4/m/NW6lGkgYBwAJ and the linked report of various anomalies in commonNames and Subject Alternative Names in server auth certificates issued by public CAs.

-------------

PR: https://git.openjdk.java.net/jdk/pull/6928



More information about the security-dev mailing list