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.*;
     31 
     32 import sun.security.util.*;
     33 
     34 /**
     35  * Represent the Policy Mappings Extension.
     36  *
     37  * This extension, if present, identifies the certificate policies considered
     38  * identical between the issuing and the subject CA.
     39  * <p>Extensions are addiitonal attributes which can be inserted in a X509
     40  * v3 certificate. For example a "Driving License Certificate" could have
     41  * the driving license number as a extension.
     42  *
     43  * <p>Extensions are represented as a sequence of the extension identifier
     44  * (Object Identifier), a boolean flag stating whether the extension is to
     45  * be treated as being critical and the extension value itself (this is again
     46  * a DER encoding of the extension value).
     47  *
     48  * @author Amit Kapoor
     49  * @author Hemma Prafullchandra
     50  * @see Extension
     51  * @see CertAttrSet
     52  */
     53 public class PolicyMappingsExtension extends Extension
     54 implements CertAttrSet<String> {
     55     /**
     56      * Identifier for this attribute, to be used with the
     57      * get, set, delete methods of Certificate, x509 type.
     58      */
     59     public static final String IDENT = "x509.info.extensions.PolicyMappings";
     60     /**
     61      * Attribute names.
     62      */
     63     public static final String NAME = "PolicyMappings";
     64     public static final String MAP = "map";
     65 
     66     // Private data members
     67     private List<CertificatePolicyMap> maps;
     68 
     69     // Encode this extension value
     70     private void encodeThis() throws IOException {
     71         if (maps == null || maps.isEmpty()) {
     72             this.extensionValue = null;
     73             return;
     74         }
     75         DerOutputStream os = new DerOutputStream();
     76         DerOutputStream tmp = new DerOutputStream();
     77 
     78         for (CertificatePolicyMap map : maps) {
     79             map.encode(tmp);
     80         }
     81 
     82         os.write(DerValue.tag_Sequence, tmp);
     83         this.extensionValue = os.toByteArray();
     84     }
     85 
     86     /**
     87      * Create a PolicyMappings with the List of CertificatePolicyMap.
     88      *
     89      * @param maps the List of CertificatePolicyMap.
     90      */
     91     public PolicyMappingsExtension(List<CertificatePolicyMap> map)
     92             throws IOException {
     93         this.maps = map;
     94         this.extensionId = PKIXExtensions.PolicyMappings_Id;
     95         this.critical = false;
     96         encodeThis();
     97     }
     98 
     99     /**
    100      * Create a default PolicyMappingsExtension.
    101      */
    102     public PolicyMappingsExtension() {
    103         extensionId = PKIXExtensions.KeyUsage_Id;
    104         critical = false;
    105         maps = Collections.<CertificatePolicyMap>emptyList();
    106     }
    107 
    108     /**
    109      * Create the extension from the passed DER encoded value.
    110      *
    111      * @params critical true if the extension is to be treated as critical.
    112      * @params value an array of DER encoded bytes of the actual value.
    113      * @exception ClassCastException if value is not an array of bytes
    114      * @exception IOException on error.
    115      */
    116     public PolicyMappingsExtension(Boolean critical, Object value)
    117     throws IOException {
    118         this.extensionId = PKIXExtensions.PolicyMappings_Id;
    119         this.critical = critical.booleanValue();
    120 
    121         this.extensionValue = (byte[]) value;
    122         DerValue val = new DerValue(this.extensionValue);
    123         if (val.tag != DerValue.tag_Sequence) {
    124             throw new IOException("Invalid encoding for " +
    125                                   "PolicyMappingsExtension.");
    126         }
    127         maps = new ArrayList<CertificatePolicyMap>();
    128         while (val.data.available() != 0) {
    129             DerValue seq = val.data.getDerValue();
    130             CertificatePolicyMap map = new CertificatePolicyMap(seq);
    131             maps.add(map);
    132         }
    133     }
    134 
    135     /**
    136      * Returns a printable representation of the policy map.
    137      */
    138     public String toString() {
    139         if (maps == null) return "";
    140         String s = super.toString() + "PolicyMappings [\n"
    141                  + maps.toString() + "]\n";
    142 
    143         return (s);
    144     }
    145 
    146     /**
    147      * Write the extension to the OutputStream.
    148      *
    149      * @param out the OutputStream 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 (extensionValue == null) {
    155             extensionId = PKIXExtensions.PolicyMappings_Id;
    156             critical = false;
    157             encodeThis();
    158         }
    159         super.encode(tmp);
    160         out.write(tmp.toByteArray());
    161     }
    162 
    163     /**
    164      * Set the attribute value.
    165      */
    166     @SuppressWarnings("unchecked") // Checked with instanceof
    167     public void set(String name, Object obj) throws IOException {
    168         if (name.equalsIgnoreCase(MAP)) {
    169             if (!(obj instanceof List)) {
    170               throw new IOException("Attribute value should be of" +
    171                                     " type List.");
    172             }
    173             maps = (List<CertificatePolicyMap>)obj;
    174         } else {
    175           throw new IOException("Attribute name not recognized by " +
    176                         "CertAttrSet:PolicyMappingsExtension.");
    177         }
    178         encodeThis();
    179     }
    180 
    181     /**
    182      * Get the attribute value.
    183      */
    184     public List<CertificatePolicyMap> get(String name) throws IOException {
    185         if (name.equalsIgnoreCase(MAP)) {
    186             return (maps);
    187         } else {
    188           throw new IOException("Attribute name not recognized by " +
    189                         "CertAttrSet:PolicyMappingsExtension.");
    190         }
    191     }
    192 
    193     /**
    194      * Delete the attribute value.
    195      */
    196     public void delete(String name) throws IOException {
    197         if (name.equalsIgnoreCase(MAP)) {
    198             maps = null;
    199         } else {
    200           throw new IOException("Attribute name not recognized by " +
    201                         "CertAttrSet:PolicyMappingsExtension.");
    202         }
    203         encodeThis();
    204     }
    205 
    206     /**
    207      * Return an enumeration of names of attributes existing within this
    208      * attribute.
    209      */
    210     public Enumeration<String> getElements () {
    211         AttributeNameEnumeration elements = new AttributeNameEnumeration();
    212         elements.addElement(MAP);
    213 
    214         return elements.elements();
    215     }
    216 
    217     /**
    218      * Return the name of this attribute.
    219      */
    220     public String getName () {
    221         return (NAME);
    222     }
    223 }
    224