Path: blob/master/src/java.base/share/classes/sun/security/x509/CRLDistributionPointsExtension.java
41159 views
/*1* Copyright (c) 2002, 2011, 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;2930import java.util.*;31import java.util.Collections;3233import sun.security.util.DerOutputStream;34import sun.security.util.DerValue;35import sun.security.util.ObjectIdentifier;3637/**38* Represent the CRL Distribution Points Extension (OID = 2.5.29.31).39* <p>40* The CRL distribution points extension identifies how CRL information41* is obtained. The extension SHOULD be non-critical, but the PKIX profile42* recommends support for this extension by CAs and applications.43* <p>44* For PKIX, if the cRLDistributionPoints extension contains a45* DistributionPointName of type URI, the following semantics MUST be46* assumed: the URI is a pointer to the current CRL for the associated47* reasons and will be issued by the associated cRLIssuer. The48* expected values for the URI conform to the following rules. The49* name MUST be a non-relative URL, and MUST follow the URL syntax and50* encoding rules specified in [RFC 1738]. The name must include both51* a scheme (e.g., "http" or "ftp") and a scheme-specific-part. The52* scheme- specific-part must include a fully qualified domain name or53* IP address as the host. As specified in [RFC 1738], the scheme54* name is not case-sensitive (e.g., "http" is equivalent to "HTTP").55* The host part is also not case-sensitive, but other components of56* the scheme-specific-part may be case-sensitive. When comparing57* URIs, conforming implementations MUST compare the scheme and host58* without regard to case, but assume the remainder of the59* scheme-specific-part is case sensitive. Processing rules for other60* values are not defined by this specification. If the61* distributionPoint omits reasons, the CRL MUST include revocations62* for all reasons. If the distributionPoint omits cRLIssuer, the CRL63* MUST be issued by the CA that issued the certificate.64* <p>65* The ASN.1 definition for this is:66* <pre>67* id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 }68*69* cRLDistributionPoints ::= {70* CRLDistPointsSyntax }71*72* CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint73* </pre>74*75* @author Anne Anderson76* @author Andreas Sterbenz77* @since 1.4.278* @see DistributionPoint79* @see Extension80* @see CertAttrSet81*/82public class CRLDistributionPointsExtension extends Extension83implements CertAttrSet<String> {8485/**86* Identifier for this attribute, to be used with the87* get, set, delete methods of Certificate, x509 type.88*/89public static final String IDENT =90"x509.info.extensions.CRLDistributionPoints";9192/**93* Attribute name.94*/95public static final String NAME = "CRLDistributionPoints";96public static final String POINTS = "points";9798/**99* The List of DistributionPoint objects.100*/101private List<DistributionPoint> distributionPoints;102103private String extensionName;104105/**106* Create a CRLDistributionPointsExtension from a List of107* DistributionPoint; the criticality is set to false.108*109* @param distributionPoints the list of distribution points110* @throws IOException on error111*/112public CRLDistributionPointsExtension(113List<DistributionPoint> distributionPoints) throws IOException {114115this(false, distributionPoints);116}117118/**119* Create a CRLDistributionPointsExtension from a List of120* DistributionPoint.121*122* @param isCritical the criticality setting.123* @param distributionPoints the list of distribution points124* @throws IOException on error125*/126public CRLDistributionPointsExtension(boolean isCritical,127List<DistributionPoint> distributionPoints) throws IOException {128129this(PKIXExtensions.CRLDistributionPoints_Id, isCritical,130distributionPoints, NAME);131}132133/**134* Creates the extension (also called by the subclass).135*/136protected CRLDistributionPointsExtension(ObjectIdentifier extensionId,137boolean isCritical, List<DistributionPoint> distributionPoints,138String extensionName) throws IOException {139140this.extensionId = extensionId;141this.critical = isCritical;142this.distributionPoints = distributionPoints;143encodeThis();144this.extensionName = extensionName;145}146147/**148* Create the extension from the passed DER encoded value of the same.149*150* @param critical true if the extension is to be treated as critical.151* @param value Array of DER encoded bytes of the actual value.152* @exception IOException on error.153*/154public CRLDistributionPointsExtension(Boolean critical, Object value)155throws IOException {156this(PKIXExtensions.CRLDistributionPoints_Id, critical, value, NAME);157}158159/**160* Creates the extension (also called by the subclass).161*/162protected CRLDistributionPointsExtension(ObjectIdentifier extensionId,163Boolean critical, Object value, String extensionName)164throws IOException {165166this.extensionId = extensionId;167this.critical = critical.booleanValue();168169if (!(value instanceof byte[])) {170throw new IOException("Illegal argument type");171}172173extensionValue = (byte[])value;174DerValue val = new DerValue(extensionValue);175if (val.tag != DerValue.tag_Sequence) {176throw new IOException("Invalid encoding for " + extensionName +177" extension.");178}179distributionPoints = new ArrayList<DistributionPoint>();180while (val.data.available() != 0) {181DerValue seq = val.data.getDerValue();182DistributionPoint point = new DistributionPoint(seq);183distributionPoints.add(point);184}185this.extensionName = extensionName;186}187188/**189* Return the name of this attribute.190*/191public String getName() {192return extensionName;193}194195/**196* Write the extension to the DerOutputStream.197*198* @param out the DerOutputStream to write the extension to.199* @exception IOException on encoding errors.200*/201public void encode(OutputStream out) throws IOException {202encode(out, PKIXExtensions.CRLDistributionPoints_Id, false);203}204205/**206* Write the extension to the DerOutputStream.207* (Also called by the subclass)208*/209protected void encode(OutputStream out, ObjectIdentifier extensionId,210boolean isCritical) throws IOException {211212DerOutputStream tmp = new DerOutputStream();213if (this.extensionValue == null) {214this.extensionId = extensionId;215this.critical = isCritical;216encodeThis();217}218super.encode(tmp);219out.write(tmp.toByteArray());220}221222/**223* Set the attribute value.224*/225@SuppressWarnings("unchecked") // Checked with instanceof226public void set(String name, Object obj) throws IOException {227if (name.equalsIgnoreCase(POINTS)) {228if (!(obj instanceof List)) {229throw new IOException("Attribute value should be of type List.");230}231distributionPoints = (List<DistributionPoint>)obj;232} else {233throw new IOException("Attribute name [" + name +234"] not recognized by " +235"CertAttrSet:" + extensionName + '.');236}237encodeThis();238}239240/**241* Get the attribute value.242*/243public List<DistributionPoint> get(String name) throws IOException {244if (name.equalsIgnoreCase(POINTS)) {245return distributionPoints;246} else {247throw new IOException("Attribute name [" + name +248"] not recognized by " +249"CertAttrSet:" + extensionName + '.');250}251}252253/**254* Delete the attribute value.255*/256public void delete(String name) throws IOException {257if (name.equalsIgnoreCase(POINTS)) {258distributionPoints =259Collections.<DistributionPoint>emptyList();260} else {261throw new IOException("Attribute name [" + name +262"] not recognized by " +263"CertAttrSet:" + extensionName + '.');264}265encodeThis();266}267268/**269* Return an enumeration of names of attributes existing within this270* attribute.271*/272public Enumeration<String> getElements() {273AttributeNameEnumeration elements = new AttributeNameEnumeration();274elements.addElement(POINTS);275return elements.elements();276}277278// Encode this extension value279private void encodeThis() throws IOException {280if (distributionPoints.isEmpty()) {281this.extensionValue = null;282} else {283DerOutputStream pnts = new DerOutputStream();284for (DistributionPoint point : distributionPoints) {285point.encode(pnts);286}287DerOutputStream seq = new DerOutputStream();288seq.write(DerValue.tag_Sequence, pnts);289this.extensionValue = seq.toByteArray();290}291}292293/**294* Return the extension as user readable string.295*/296public String toString() {297return super.toString() + extensionName + " [\n "298+ distributionPoints + "]\n";299}300301}302303304