Home | History | Annotate | Download | only in x509
      1 /*
      2  * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 package sun.security.x509;
     27 
     28 import java.io.IOException;
     29 import java.io.OutputStream;
     30 import java.math.BigInteger;
     31 import java.util.Enumeration;
     32 
     33 import sun.security.util.*;
     34 
     35 /**
     36  * Represent the CRL Number Extension.
     37  *
     38  * <p>This extension, if present, conveys a monotonically increasing
     39  * sequence number for each CRL issued by a given CA through a specific
     40  * CA X.500 Directory entry or CRL distribution point. This extension
     41  * allows users to easily determine when a particular CRL supersedes
     42  * another CRL.
     43  *
     44  * @author Hemma Prafullchandra
     45  * @see Extension
     46  * @see CertAttrSet
     47  */
     48 public class CRLNumberExtension extends Extension
     49 implements CertAttrSet<String> {
     50 
     51     /**
     52      * Attribute name.
     53      */
     54     public static final String NAME = "CRLNumber";
     55     public static final String NUMBER = "value";
     56 
     57     private static final String LABEL = "CRL Number";
     58 
     59     private BigInteger crlNumber = null;
     60     private String extensionName;
     61     private String extensionLabel;
     62 
     63     // Encode this extension value
     64     private void encodeThis() throws IOException {
     65         if (crlNumber == null) {
     66             this.extensionValue = null;
     67             return;
     68         }
     69         DerOutputStream os = new DerOutputStream();
     70         os.putInteger(this.crlNumber);
     71         this.extensionValue = os.toByteArray();
     72     }
     73 
     74     /**
     75      * Create a CRLNumberExtension with the integer value .
     76      * The criticality is set to false.
     77      *
     78      * @param crlNum the value to be set for the extension.
     79      */
     80     public CRLNumberExtension(int crlNum) throws IOException {
     81         this(PKIXExtensions.CRLNumber_Id, false, BigInteger.valueOf(crlNum),
     82         NAME, LABEL);
     83     }
     84 
     85     /**
     86      * Create a CRLNumberExtension with the BigInteger value .
     87      * The criticality is set to false.
     88      *
     89      * @param crlNum the value to be set for the extension.
     90      */
     91     public CRLNumberExtension(BigInteger crlNum) throws IOException {
     92         this(PKIXExtensions.CRLNumber_Id, false, crlNum, NAME, LABEL);
     93     }
     94 
     95     /**
     96      * Creates the extension (also called by the subclass).
     97      */
     98     protected CRLNumberExtension(ObjectIdentifier extensionId,
     99         boolean isCritical, BigInteger crlNum, String extensionName,
    100         String extensionLabel) throws IOException {
    101 
    102         this.extensionId = extensionId;
    103         this.critical = isCritical;
    104         this.crlNumber = crlNum;
    105         this.extensionName = extensionName;
    106         this.extensionLabel = extensionLabel;
    107         encodeThis();
    108     }
    109 
    110     /**
    111      * Create the extension from the passed DER encoded value of the same.
    112      *
    113      * @param critical true if the extension is to be treated as critical.
    114      * @param value an array of DER encoded bytes of the actual value.
    115      * @exception ClassCastException if value is not an array of bytes
    116      * @exception IOException on error.
    117      */
    118     public CRLNumberExtension(Boolean critical, Object value)
    119     throws IOException {
    120         this(PKIXExtensions.CRLNumber_Id, critical, value, NAME, LABEL);
    121     }
    122 
    123     /**
    124      * Creates the extension (also called by the subclass).
    125      */
    126     protected CRLNumberExtension(ObjectIdentifier extensionId,
    127         Boolean critical, Object value, String extensionName,
    128         String extensionLabel) throws IOException {
    129 
    130         this.extensionId = extensionId;
    131         this.critical = critical.booleanValue();
    132         this.extensionValue = (byte[]) value;
    133         DerValue val = new DerValue(this.extensionValue);
    134         this.crlNumber = val.getBigInteger();
    135         this.extensionName = extensionName;
    136         this.extensionLabel = extensionLabel;
    137     }
    138 
    139     /**
    140      * Set the attribute value.
    141      */
    142     public void set(String name, Object obj) throws IOException {
    143         if (name.equalsIgnoreCase(NUMBER)) {
    144             if (!(obj instanceof BigInteger)) {
    145                 throw new IOException("Attribute must be of type BigInteger.");
    146             }
    147             crlNumber = (BigInteger)obj;
    148         } else {
    149           throw new IOException("Attribute name not recognized by"
    150                                 + " CertAttrSet:" + extensionName + ".");
    151         }
    152         encodeThis();
    153     }
    154 
    155     /**
    156      * Get the attribute value.
    157      */
    158     public Object get(String name) throws IOException {
    159         if (name.equalsIgnoreCase(NUMBER)) {
    160             if (crlNumber == null) return null;
    161             else return crlNumber;
    162         } else {
    163           throw new IOException("Attribute name not recognized by"
    164                                 + " CertAttrSet:" + extensionName + ".");
    165         }
    166     }
    167 
    168     /**
    169      * Delete the attribute value.
    170      */
    171     public void delete(String name) throws IOException {
    172         if (name.equalsIgnoreCase(NUMBER)) {
    173             crlNumber = null;
    174         } else {
    175           throw new IOException("Attribute name not recognized by"
    176                                 + " CertAttrSet:" + extensionName + ".");
    177         }
    178         encodeThis();
    179     }
    180 
    181     /**
    182      * Returns a printable representation of the CRLNumberExtension.
    183      */
    184     public String toString() {
    185         String s = super.toString() + extensionLabel + ": " +
    186                    ((crlNumber == null) ? "" : Debug.toHexString(crlNumber))
    187                    + "\n";
    188         return (s);
    189     }
    190 
    191     /**
    192      * Write the extension to the DerOutputStream.
    193      *
    194      * @param out the DerOutputStream to write the extension to.
    195      * @exception IOException on encoding errors.
    196      */
    197     public void encode(OutputStream out) throws IOException {
    198        DerOutputStream  tmp = new DerOutputStream();
    199         encode(out, PKIXExtensions.CRLNumber_Id, true);
    200     }
    201 
    202     /**
    203      * Write the extension to the DerOutputStream.
    204      * (Also called by the subclass)
    205      */
    206     protected void encode(OutputStream out, ObjectIdentifier extensionId,
    207         boolean isCritical) throws IOException {
    208 
    209        DerOutputStream  tmp = new DerOutputStream();
    210 
    211        if (this.extensionValue == null) {
    212            this.extensionId = extensionId;
    213            this.critical = isCritical;
    214            encodeThis();
    215        }
    216        super.encode(tmp);
    217        out.write(tmp.toByteArray());
    218     }
    219 
    220     /**
    221      * Return an enumeration of names of attributes existing within this
    222      * attribute.
    223      */
    224     public Enumeration<String> getElements() {
    225         AttributeNameEnumeration elements = new AttributeNameEnumeration();
    226         elements.addElement(NUMBER);
    227         return (elements.elements());
    228     }
    229 
    230     /**
    231      * Return the name of this attribute.
    232      */
    233     public String getName() {
    234         return (extensionName);
    235     }
    236 }
    237