Home | History | Annotate | Download | only in x509
      1 /*
      2  * Copyright (c) 1997, 2011, 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.util.Enumeration;
     31 
     32 import sun.security.util.*;
     33 
     34 /**
     35  * This represents the Issuer Alternative Name Extension.
     36  *
     37  * This extension, if present, allows the issuer to specify multiple
     38  * alternative names.
     39  *
     40  * <p>Extensions are represented as a sequence of the extension identifier
     41  * (Object Identifier), a boolean flag stating whether the extension is to
     42  * be treated as being critical and the extension value itself (this is again
     43  * a DER encoding of the extension value).
     44  *
     45  * @author Amit Kapoor
     46  * @author Hemma Prafullchandra
     47  * @see Extension
     48  * @see CertAttrSet
     49  */
     50 public class IssuerAlternativeNameExtension
     51 extends Extension implements CertAttrSet<String> {
     52     /**
     53      * Identifier for this attribute, to be used with the
     54      * get, set, delete methods of Certificate, x509 type.
     55      */
     56     public static final String IDENT =
     57                          "x509.info.extensions.IssuerAlternativeName";
     58     /**
     59      * Attribute names.
     60      */
     61     public static final String NAME = "IssuerAlternativeName";
     62     public static final String ISSUER_NAME = "issuer_name";
     63 
     64     // private data members
     65     GeneralNames names = null;
     66 
     67     // Encode this extension
     68     private void encodeThis() throws IOException {
     69         if (names == null || names.isEmpty()) {
     70             this.extensionValue = null;
     71             return;
     72         }
     73         DerOutputStream os = new DerOutputStream();
     74         names.encode(os);
     75         this.extensionValue = os.toByteArray();
     76     }
     77 
     78     /**
     79      * Create a IssuerAlternativeNameExtension with the passed GeneralNames.
     80      *
     81      * @param names the GeneralNames for the issuer.
     82      * @exception IOException on error.
     83      */
     84     public IssuerAlternativeNameExtension(GeneralNames names)
     85     throws IOException {
     86         this.names = names;
     87         this.extensionId = PKIXExtensions.IssuerAlternativeName_Id;
     88         this.critical = false;
     89         encodeThis();
     90     }
     91 
     92     /**
     93      * Create a IssuerAlternativeNameExtension with the passed criticality
     94      * and GeneralNames.
     95      *
     96      * @param critical true if the extension is to be treated as critical.
     97      * @param names the GeneralNames for the issuer.
     98      * @exception IOException on error.
     99      */
    100     public IssuerAlternativeNameExtension(Boolean critical, GeneralNames names)
    101     throws IOException {
    102         this.names = names;
    103         this.extensionId = PKIXExtensions.IssuerAlternativeName_Id;
    104         this.critical = critical.booleanValue();
    105         encodeThis();
    106     }
    107 
    108     /**
    109      * Create a default IssuerAlternativeNameExtension.
    110      */
    111     public IssuerAlternativeNameExtension() {
    112         extensionId = PKIXExtensions.IssuerAlternativeName_Id;
    113         critical = false;
    114         names = new GeneralNames();
    115     }
    116 
    117     /**
    118      * Create the extension from the passed DER encoded value.
    119      *
    120      * @param critical true if the extension is to be treated as critical.
    121      * @param value an array of DER encoded bytes of the actual value.
    122      * @exception ClassCastException if value is not an array of bytes
    123      * @exception IOException on error.
    124      */
    125     public IssuerAlternativeNameExtension(Boolean critical, Object value)
    126     throws IOException {
    127         this.extensionId = PKIXExtensions.IssuerAlternativeName_Id;
    128         this.critical = critical.booleanValue();
    129         this.extensionValue = (byte[]) value;
    130         DerValue val = new DerValue(this.extensionValue);
    131         if (val.data == null) {
    132             names = new GeneralNames();
    133             return;
    134         }
    135 
    136         names = new GeneralNames(val);
    137     }
    138 
    139     /**
    140      * Returns a printable representation of the IssuerAlternativeName.
    141      */
    142     public String toString() {
    143 
    144         String result = super.toString() + "IssuerAlternativeName [\n";
    145         if(names == null) {
    146             result += "  null\n";
    147         } else {
    148             for(GeneralName name: names.names()) {
    149                 result += "  "+name+"\n";
    150             }
    151         }
    152         result += "]\n";
    153         return result;
    154     }
    155 
    156     /**
    157      * Write the extension to the OutputStream.
    158      *
    159      * @param out the OutputStream to write the extension to.
    160      * @exception IOException on encoding error.
    161      */
    162     public void encode(OutputStream out) throws IOException {
    163         DerOutputStream tmp = new DerOutputStream();
    164         if (extensionValue == null) {
    165             extensionId = PKIXExtensions.IssuerAlternativeName_Id;
    166             critical = false;
    167             encodeThis();
    168         }
    169         super.encode(tmp);
    170         out.write(tmp.toByteArray());
    171     }
    172 
    173     /**
    174      * Set the attribute value.
    175      */
    176     public void set(String name, Object obj) throws IOException {
    177         if (name.equalsIgnoreCase(ISSUER_NAME)) {
    178             if (!(obj instanceof GeneralNames)) {
    179               throw new IOException("Attribute value should be of" +
    180                                     " type GeneralNames.");
    181             }
    182             names = (GeneralNames)obj;
    183         } else {
    184           throw new IOException("Attribute name not recognized by " +
    185                         "CertAttrSet:IssuerAlternativeName.");
    186         }
    187         encodeThis();
    188     }
    189 
    190     /**
    191      * Get the attribute value.
    192      */
    193     public GeneralNames get(String name) throws IOException {
    194         if (name.equalsIgnoreCase(ISSUER_NAME)) {
    195             return (names);
    196         } else {
    197           throw new IOException("Attribute name not recognized by " +
    198                         "CertAttrSet:IssuerAlternativeName.");
    199         }
    200     }
    201 
    202     /**
    203      * Delete the attribute value.
    204      */
    205     public void delete(String name) throws IOException {
    206         if (name.equalsIgnoreCase(ISSUER_NAME)) {
    207             names = null;
    208         } else {
    209           throw new IOException("Attribute name not recognized by " +
    210                         "CertAttrSet:IssuerAlternativeName.");
    211         }
    212         encodeThis();
    213     }
    214 
    215     /**
    216      * Return an enumeration of names of attributes existing within this
    217      * attribute.
    218      */
    219     public Enumeration<String> getElements() {
    220         AttributeNameEnumeration elements = new AttributeNameEnumeration();
    221         elements.addElement(ISSUER_NAME);
    222 
    223         return (elements.elements());
    224     }
    225 
    226     /**
    227      * Return the name of this attribute.
    228      */
    229     public String getName() {
    230         return (NAME);
    231     }
    232 }
    233