mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8251468: X509Certificate.get{Subject,Issuer}AlternativeNames and getExtendedKeyUsage do not throw CertificateParsingException if extension is unparseable
Reviewed-by: weijun
This commit is contained in:
parent
4c3491bfa5
commit
8cc59509fe
4 changed files with 199 additions and 53 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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
|
||||
|
@ -28,13 +28,10 @@ package sun.security.x509;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.HexDumpEncoder;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
|
@ -109,11 +106,10 @@ public class CertificateExtensions implements CertAttrSet<Extension> {
|
|||
|
||||
Object[] passed = new Object[] {Boolean.valueOf(ext.isCritical()),
|
||||
ext.getExtensionValue()};
|
||||
CertAttrSet<?> certExt = (CertAttrSet<?>)
|
||||
cons.newInstance(passed);
|
||||
if (map.put(certExt.getName(), (Extension)certExt) != null) {
|
||||
throw new IOException("Duplicate extensions not allowed");
|
||||
}
|
||||
CertAttrSet<?> certExt = (CertAttrSet<?>) cons.newInstance(passed);
|
||||
if (map.put(certExt.getName(), (Extension)certExt) != null) {
|
||||
throw new IOException("Duplicate extensions not allowed");
|
||||
}
|
||||
} catch (InvocationTargetException invk) {
|
||||
Throwable e = invk.getCause();
|
||||
if (ext.isCritical() == false) {
|
||||
|
@ -352,32 +348,3 @@ public class CertificateExtensions implements CertAttrSet<Extension> {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
class UnparseableExtension extends Extension {
|
||||
private String name;
|
||||
private String exceptionDescription;
|
||||
|
||||
public UnparseableExtension(Extension ext, Throwable why) {
|
||||
super(ext);
|
||||
|
||||
name = "";
|
||||
try {
|
||||
Class<?> extClass = OIDMap.getClass(ext.getExtensionId());
|
||||
if (extClass != null) {
|
||||
Field field = extClass.getDeclaredField("NAME");
|
||||
name = (String)(field.get(null)) + " ";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// If we cannot find the name, just ignore it
|
||||
}
|
||||
|
||||
this.exceptionDescription = why.toString();
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return super.toString() +
|
||||
"Unparseable " + name + "extension due to\n" +
|
||||
exceptionDescription + "\n\n" +
|
||||
new HexDumpEncoder().encodeBuffer(getExtensionValue());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import sun.security.util.HexDumpEncoder;
|
||||
|
||||
/**
|
||||
* An extension that cannot be parsed due to decoding errors or invalid
|
||||
* content.
|
||||
*/
|
||||
class UnparseableExtension extends Extension {
|
||||
private String name;
|
||||
private String exceptionDescription;
|
||||
private String exceptionMessage;
|
||||
|
||||
UnparseableExtension(Extension ext, Throwable why) {
|
||||
super(ext);
|
||||
|
||||
name = "";
|
||||
try {
|
||||
Class<?> extClass = OIDMap.getClass(ext.getExtensionId());
|
||||
if (extClass != null) {
|
||||
Field field = extClass.getDeclaredField("NAME");
|
||||
name = (String)(field.get(null)) + " ";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// If we cannot find the name, just ignore it
|
||||
}
|
||||
|
||||
this.exceptionDescription = why.toString();
|
||||
this.exceptionMessage = why.getMessage();
|
||||
}
|
||||
|
||||
String exceptionMessage() {
|
||||
return exceptionMessage;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return super.toString() +
|
||||
"Unparseable " + name + "extension due to\n" +
|
||||
exceptionDescription + "\n\n" +
|
||||
new HexDumpEncoder().encodeBuffer(getExtensionValue());
|
||||
}
|
||||
}
|
|
@ -1439,24 +1439,45 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
|||
}
|
||||
|
||||
/**
|
||||
* This method are the overridden implementation of
|
||||
* This method is the overridden implementation of the
|
||||
* getExtendedKeyUsage method in X509Certificate in the Sun
|
||||
* provider. It is better performance-wise since it returns cached
|
||||
* values.
|
||||
*/
|
||||
@Override
|
||||
public synchronized List<String> getExtendedKeyUsage()
|
||||
throws CertificateParsingException {
|
||||
if (readOnly && extKeyUsage != null) {
|
||||
return extKeyUsage;
|
||||
} else {
|
||||
ExtendedKeyUsageExtension ext = getExtendedKeyUsageExtension();
|
||||
if (ext == null) {
|
||||
return null;
|
||||
}
|
||||
extKeyUsage =
|
||||
Collections.unmodifiableList(ext.getExtendedKeyUsage());
|
||||
return extKeyUsage;
|
||||
}
|
||||
ExtendedKeyUsageExtension ext = (ExtendedKeyUsageExtension)
|
||||
getExtensionIfParseable(PKIXExtensions.ExtendedKeyUsage_Id);
|
||||
if (ext == null) {
|
||||
return null;
|
||||
}
|
||||
extKeyUsage = Collections.unmodifiableList(ext.getExtendedKeyUsage());
|
||||
return extKeyUsage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extension identified by OID or null if it doesn't exist
|
||||
* and is not unparseable.
|
||||
*
|
||||
* @throws CertificateParsingException if extension is unparseable
|
||||
*/
|
||||
private Extension getExtensionIfParseable(ObjectIdentifier oid)
|
||||
throws CertificateParsingException {
|
||||
Extension ext = getExtension(oid);
|
||||
if (ext == null) {
|
||||
// check if unparseable
|
||||
UnparseableExtension unparseableExt =
|
||||
(UnparseableExtension)getUnparseableExtension(oid);
|
||||
if (unparseableExt != null) {
|
||||
throw new CertificateParsingException(
|
||||
unparseableExt.exceptionMessage());
|
||||
}
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1602,11 +1623,12 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
|||
}
|
||||
|
||||
/**
|
||||
* This method are the overridden implementation of
|
||||
* This method is the overridden implementation of the
|
||||
* getSubjectAlternativeNames method in X509Certificate in the Sun
|
||||
* provider. It is better performance-wise since it returns cached
|
||||
* values.
|
||||
*/
|
||||
@Override
|
||||
public synchronized Collection<List<?>> getSubjectAlternativeNames()
|
||||
throws CertificateParsingException {
|
||||
// return cached value if we can
|
||||
|
@ -1614,7 +1636,8 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
|||
return cloneAltNames(subjectAlternativeNames);
|
||||
}
|
||||
SubjectAlternativeNameExtension subjectAltNameExt =
|
||||
getSubjectAlternativeNameExtension();
|
||||
(SubjectAlternativeNameExtension)getExtensionIfParseable(
|
||||
PKIXExtensions.SubjectAlternativeName_Id);
|
||||
if (subjectAltNameExt == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1632,7 +1655,7 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
|||
|
||||
/**
|
||||
* This static method is the default implementation of the
|
||||
* getSubjectAlternaitveNames method in X509Certificate. A
|
||||
* getSubjectAlternativeNames method in X509Certificate. A
|
||||
* X509Certificate provider generally should overwrite this to
|
||||
* provide among other things caching for better performance.
|
||||
*/
|
||||
|
@ -1666,11 +1689,12 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
|||
}
|
||||
|
||||
/**
|
||||
* This method are the overridden implementation of
|
||||
* This method is the overridden implementation of the
|
||||
* getIssuerAlternativeNames method in X509Certificate in the Sun
|
||||
* provider. It is better performance-wise since it returns cached
|
||||
* values.
|
||||
*/
|
||||
@Override
|
||||
public synchronized Collection<List<?>> getIssuerAlternativeNames()
|
||||
throws CertificateParsingException {
|
||||
// return cached value if we can
|
||||
|
@ -1678,7 +1702,8 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
|||
return cloneAltNames(issuerAlternativeNames);
|
||||
}
|
||||
IssuerAlternativeNameExtension issuerAltNameExt =
|
||||
getIssuerAlternativeNameExtension();
|
||||
(IssuerAlternativeNameExtension)getExtensionIfParseable(
|
||||
PKIXExtensions.IssuerAlternativeName_Id);
|
||||
if (issuerAltNameExt == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1696,7 +1721,7 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
|||
|
||||
/**
|
||||
* This static method is the default implementation of the
|
||||
* getIssuerAlternaitveNames method in X509Certificate. A
|
||||
* getIssuerAlternativeNames method in X509Certificate. A
|
||||
* X509Certificate provider generally should overwrite this to
|
||||
* provide among other things caching for better performance.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue