Home | History | Annotate | Download | only in x509
      1 /*
      2  * Copyright (c) 2004, 2009, 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 
     31 import java.util.*;
     32 
     33 import sun.security.util.DerOutputStream;
     34 import sun.security.util.DerValue;
     35 
     36 /**
     37  * The Authority Information Access Extension (OID = 1.3.6.1.5.5.7.1.1).
     38  * <p>
     39  * The AIA extension identifies how to access CA information and services
     40  * for the certificate in which it appears. It enables CAs to issue their
     41  * certificates pre-configured with the URLs appropriate for contacting
     42  * services relevant to those certificates. For example, a CA may issue a
     43  * certificate that identifies the specific OCSP Responder to use when
     44  * performing on-line validation of that certificate.
     45  * <p>
     46  * This extension is defined in <a href="http://www.ietf.org/rfc/rfc3280.txt">
     47  * Internet X.509 PKI Certificate and Certificate Revocation List
     48  * (CRL) Profile</a>. The profile permits
     49  * the extension to be included in end-entity or CA certificates,
     50  * and it must be marked as non-critical. Its ASN.1 definition is as follows:
     51  * <pre>
     52  *   id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
     53  *
     54  *   AuthorityInfoAccessSyntax  ::=
     55  *         SEQUENCE SIZE (1..MAX) OF AccessDescription
     56  *
     57  *   AccessDescription  ::=  SEQUENCE {
     58  *         accessMethod          OBJECT IDENTIFIER,
     59  *         accessLocation        GeneralName  }
     60  * </pre>
     61  * <p>
     62  * @see Extension
     63  * @see CertAttrSet
     64  */
     65 
     66 public class AuthorityInfoAccessExtension extends Extension
     67         implements CertAttrSet<String> {
     68 
     69     /**
     70      * Identifier for this attribute, to be used with the
     71      * get, set, delete methods of Certificate, x509 type.
     72      */
     73     public static final String IDENT =
     74                                 "x509.info.extensions.AuthorityInfoAccess";
     75 
     76     /**
     77      * Attribute name.
     78      */
     79     public static final String NAME = "AuthorityInfoAccess";
     80     public static final String DESCRIPTIONS = "descriptions";
     81 
     82     /**
     83      * The List of AccessDescription objects.
     84      */
     85     private List<AccessDescription> accessDescriptions;
     86 
     87     /**
     88      * Create an AuthorityInfoAccessExtension from a List of
     89      * AccessDescription; the criticality is set to false.
     90      *
     91      * @param accessDescriptions the List of AccessDescription
     92      * @throws IOException on error
     93      */
     94     public AuthorityInfoAccessExtension(
     95             List<AccessDescription> accessDescriptions) throws IOException {
     96         this.extensionId = PKIXExtensions.AuthInfoAccess_Id;
     97         this.critical = false;
     98         this.accessDescriptions = accessDescriptions;
     99         encodeThis();
    100     }
    101 
    102     /**
    103      * Create the extension from the passed DER encoded value of the same.
    104      *
    105      * @param critical true if the extension is to be treated as critical.
    106      * @param value Array of DER encoded bytes of the actual value.
    107      * @exception IOException on error.
    108      */
    109     public AuthorityInfoAccessExtension(Boolean critical, Object value)
    110             throws IOException {
    111         this.extensionId = PKIXExtensions.AuthInfoAccess_Id;
    112         this.critical = critical.booleanValue();
    113 
    114         if (!(value instanceof byte[])) {
    115             throw new IOException("Illegal argument type");
    116         }
    117 
    118         extensionValue = (byte[])value;
    119         DerValue val = new DerValue(extensionValue);
    120         if (val.tag != DerValue.tag_Sequence) {
    121             throw new IOException("Invalid encoding for " +
    122                                   "AuthorityInfoAccessExtension.");
    123         }
    124         accessDescriptions = new ArrayList<AccessDescription>();
    125         while (val.data.available() != 0) {
    126             DerValue seq = val.data.getDerValue();
    127             AccessDescription accessDescription = new AccessDescription(seq);
    128             accessDescriptions.add(accessDescription);
    129         }
    130     }
    131 
    132     /**
    133      * Return the list of AccessDescription objects.
    134      */
    135     public List<AccessDescription> getAccessDescriptions() {
    136         return accessDescriptions;
    137     }
    138 
    139     /**
    140      * Return the name of this attribute.
    141      */
    142     public String getName() {
    143         return NAME;
    144     }
    145 
    146     /**
    147      * Write the extension to the DerOutputStream.
    148      *
    149      * @param out the DerOutputStream to write the extension to.
    150      * @exception IOException on encoding errors.
    151      */
    152     public void encode(OutputStream out) throws IOException {
    153         DerOutputStream tmp = new DerOutputStream();
    154         if (this.extensionValue == null) {
    155             this.extensionId = PKIXExtensions.AuthInfoAccess_Id;
    156             this.critical = false;
    157             encodeThis();
    158         }
    159         super.encode(tmp);
    160         out.write(tmp.toByteArray());
    161     }
    162 
    163     /**
    164      * Set the attribute value.
    165      */
    166     public void set(String name, Object obj) throws IOException {
    167         if (name.equalsIgnoreCase(DESCRIPTIONS)) {
    168             if (!(obj instanceof List)) {
    169                 throw new IOException("Attribute value should be of type List.");
    170             }
    171             accessDescriptions = (List<AccessDescription>)obj;
    172         } else {
    173             throw new IOException("Attribute name [" + name +
    174                                 "] not recognized by " +
    175                                 "CertAttrSet:AuthorityInfoAccessExtension.");
    176         }
    177         encodeThis();
    178     }
    179 
    180     /**
    181      * Get the attribute value.
    182      */
    183     public Object get(String name) throws IOException {
    184         if (name.equalsIgnoreCase(DESCRIPTIONS)) {
    185             return accessDescriptions;
    186         } else {
    187             throw new IOException("Attribute name [" + name +
    188                                 "] not recognized by " +
    189                                 "CertAttrSet:AuthorityInfoAccessExtension.");
    190         }
    191     }
    192 
    193     /**
    194      * Delete the attribute value.
    195      */
    196     public void delete(String name) throws IOException {
    197         if (name.equalsIgnoreCase(DESCRIPTIONS)) {
    198             accessDescriptions = new ArrayList<AccessDescription>();
    199         } else {
    200             throw new IOException("Attribute name [" + name +
    201                                 "] not recognized by " +
    202                                 "CertAttrSet:AuthorityInfoAccessExtension.");
    203         }
    204         encodeThis();
    205     }
    206 
    207     /**
    208      * Return an enumeration of names of attributes existing within this
    209      * attribute.
    210      */
    211     public Enumeration<String> getElements() {
    212         AttributeNameEnumeration elements = new AttributeNameEnumeration();
    213         elements.addElement(DESCRIPTIONS);
    214         return elements.elements();
    215     }
    216 
    217      // Encode this extension value
    218     private void encodeThis() throws IOException {
    219         if (accessDescriptions.isEmpty()) {
    220             this.extensionValue = null;
    221         } else {
    222             DerOutputStream ads = new DerOutputStream();
    223             for (AccessDescription accessDescription : accessDescriptions) {
    224                 accessDescription.encode(ads);
    225             }
    226             DerOutputStream seq = new DerOutputStream();
    227             seq.write(DerValue.tag_Sequence, ads);
    228             this.extensionValue = seq.toByteArray();
    229         }
    230     }
    231 
    232     /**
    233      * Return the extension as user readable string.
    234      */
    235     public String toString() {
    236         return super.toString() + "AuthorityInfoAccess [\n  "
    237                + accessDescriptions + "\n]\n";
    238     }
    239 
    240 }
    241