Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/x509/BasicConstraintsExtension.java
38831 views
/*1* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.x509;2627import java.io.IOException;28import java.io.OutputStream;29import java.util.Enumeration;3031import sun.security.util.*;3233/**34* This class represents the Basic Constraints Extension.35*36* <p>The basic constraints extension identifies whether the subject of the37* certificate is a CA and how deep a certification path may exist38* through that CA.39*40* <pre>41* The ASN.1 syntax for this extension is:42* BasicConstraints ::= SEQUENCE {43* cA BOOLEAN DEFAULT FALSE,44* pathLenConstraint INTEGER (0..MAX) OPTIONAL45* }46* </pre>47* @author Amit Kapoor48* @author Hemma Prafullchandra49* @see CertAttrSet50* @see Extension51*/52public class BasicConstraintsExtension extends Extension53implements CertAttrSet<String> {54/**55* Identifier for this attribute, to be used with the56* get, set, delete methods of Certificate, x509 type.57*/58public static final String IDENT = "x509.info.extensions.BasicConstraints";59/**60* Attribute names.61*/62public static final String NAME = "BasicConstraints";63public static final String IS_CA = "is_ca";64public static final String PATH_LEN = "path_len";6566// Private data members67private boolean ca = false;68private int pathLen = -1;6970// Encode this extension value71private void encodeThis() throws IOException {72DerOutputStream out = new DerOutputStream();73DerOutputStream tmp = new DerOutputStream();7475if (ca) {76tmp.putBoolean(ca);77// Only encode pathLen when ca == true78if (pathLen >= 0) {79tmp.putInteger(pathLen);80}81}82out.write(DerValue.tag_Sequence, tmp);83this.extensionValue = out.toByteArray();84}8586/**87* Default constructor for this object. The extension is marked88* critical if the ca flag is true, false otherwise.89*90* @param ca true, if the subject of the Certificate is a CA.91* @param len specifies the depth of the certification path.92*/93public BasicConstraintsExtension(boolean ca, int len) throws IOException {94this(Boolean.valueOf(ca), ca, len);95}9697/**98* Constructor for this object with specified criticality.99*100* @param critical true, if the extension should be marked critical101* @param ca true, if the subject of the Certificate is a CA.102* @param len specifies the depth of the certification path.103*/104public BasicConstraintsExtension(Boolean critical, boolean ca, int len)105throws IOException {106this.ca = ca;107this.pathLen = len;108this.extensionId = PKIXExtensions.BasicConstraints_Id;109this.critical = critical.booleanValue();110encodeThis();111}112113/**114* Create the extension from the passed DER encoded value of the same.115*116* @param critical flag indicating if extension is critical or not117* @param value an array containing the DER encoded bytes of the extension.118* @exception ClassCastException if value is not an array of bytes119* @exception IOException on error.120*/121public BasicConstraintsExtension(Boolean critical, Object value)122throws IOException123{124this.extensionId = PKIXExtensions.BasicConstraints_Id;125this.critical = critical.booleanValue();126127this.extensionValue = (byte[]) value;128DerValue val = new DerValue(this.extensionValue);129if (val.tag != DerValue.tag_Sequence) {130throw new IOException("Invalid encoding of BasicConstraints");131}132133if (val.data == null || val.data.available() == 0) {134// non-CA cert ("cA" field is FALSE by default), return -1135return;136}137DerValue opt = val.data.getDerValue();138if (opt.tag != DerValue.tag_Boolean) {139// non-CA cert ("cA" field is FALSE by default), return -1140return;141}142143this.ca = opt.getBoolean();144if (val.data.available() == 0) {145// From PKIX profile:146// Where pathLenConstraint does not appear, there is no147// limit to the allowed length of the certification path.148this.pathLen = Integer.MAX_VALUE;149return;150}151152opt = val.data.getDerValue();153if (opt.tag != DerValue.tag_Integer) {154throw new IOException("Invalid encoding of BasicConstraints");155}156this.pathLen = opt.getInteger();157/*158* Activate this check once again after PKIX profiling159* is a standard and this check no longer imposes an160* interoperability barrier.161* if (ca) {162* if (!this.critical) {163* throw new IOException("Criticality cannot be false for CA.");164* }165* }166*/167}168169/**170* Return user readable form of extension.171*/172public String toString() {173String s = super.toString() + "BasicConstraints:[\n";174175s += ((ca) ? (" CA:true") : (" CA:false")) + "\n";176if (pathLen >= 0) {177s += " PathLen:" + pathLen + "\n";178} else {179s += " PathLen: undefined\n";180}181return (s + "]\n");182}183184/**185* Encode this extension value to the output stream.186*187* @param out the DerOutputStream to encode the extension to.188*/189public void encode(OutputStream out) throws IOException {190DerOutputStream tmp = new DerOutputStream();191if (extensionValue == null) {192this.extensionId = PKIXExtensions.BasicConstraints_Id;193if (ca) {194critical = true;195} else {196critical = false;197}198encodeThis();199}200super.encode(tmp);201202out.write(tmp.toByteArray());203}204205/**206* Set the attribute value.207*/208public void set(String name, Object obj) throws IOException {209if (name.equalsIgnoreCase(IS_CA)) {210if (!(obj instanceof Boolean)) {211throw new IOException("Attribute value should be of type Boolean.");212}213ca = ((Boolean)obj).booleanValue();214} else if (name.equalsIgnoreCase(PATH_LEN)) {215if (!(obj instanceof Integer)) {216throw new IOException("Attribute value should be of type Integer.");217}218pathLen = ((Integer)obj).intValue();219} else {220throw new IOException("Attribute name not recognized by " +221"CertAttrSet:BasicConstraints.");222}223encodeThis();224}225226/**227* Get the attribute value.228*/229public Object get(String name) throws IOException {230if (name.equalsIgnoreCase(IS_CA)) {231return (Boolean.valueOf(ca));232} else if (name.equalsIgnoreCase(PATH_LEN)) {233return (Integer.valueOf(pathLen));234} else {235throw new IOException("Attribute name not recognized by " +236"CertAttrSet:BasicConstraints.");237}238}239240/**241* Delete the attribute value.242*/243public void delete(String name) throws IOException {244if (name.equalsIgnoreCase(IS_CA)) {245ca = false;246} else if (name.equalsIgnoreCase(PATH_LEN)) {247pathLen = -1;248} else {249throw new IOException("Attribute name not recognized by " +250"CertAttrSet:BasicConstraints.");251}252encodeThis();253}254255/**256* Return an enumeration of names of attributes existing within this257* attribute.258*/259public Enumeration<String> getElements() {260AttributeNameEnumeration elements = new AttributeNameEnumeration();261elements.addElement(IS_CA);262elements.addElement(PATH_LEN);263264return (elements.elements());265}266267/**268* Return the name of this attribute.269*/270public String getName() {271return (NAME);272}273}274275276