001: /*
002: * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.security.x509;
027:
028: import java.io.IOException;
029: import java.io.OutputStream;
030: import java.util.*;
031:
032: import java.security.cert.CertificateException;
033:
034: import sun.security.util.*;
035:
036: /**
037: * Represent the Policy Mappings Extension.
038: *
039: * This extension, if present, identifies the certificate policies considered
040: * identical between the issuing and the subject CA.
041: * <p>Extensions are addiitonal attributes which can be inserted in a X509
042: * v3 certificate. For example a "Driving License Certificate" could have
043: * the driving license number as a extension.
044: *
045: * <p>Extensions are represented as a sequence of the extension identifier
046: * (Object Identifier), a boolean flag stating whether the extension is to
047: * be treated as being critical and the extension value itself (this is again
048: * a DER encoding of the extension value).
049: *
050: * @author Amit Kapoor
051: * @author Hemma Prafullchandra
052: * @version 1.26
053: * @see Extension
054: * @see CertAttrSet
055: */
056: public class PolicyMappingsExtension extends Extension implements
057: CertAttrSet<String> {
058: /**
059: * Identifier for this attribute, to be used with the
060: * get, set, delete methods of Certificate, x509 type.
061: */
062: public static final String IDENT = "x509.info.extensions.PolicyMappings";
063: /**
064: * Attribute names.
065: */
066: public static final String NAME = "PolicyMappings";
067: public static final String MAP = "map";
068:
069: // Private data members
070: private List<CertificatePolicyMap> maps;
071:
072: // Encode this extension value
073: private void encodeThis() throws IOException {
074: if (maps == null || maps.isEmpty()) {
075: this .extensionValue = null;
076: return;
077: }
078: DerOutputStream os = new DerOutputStream();
079: DerOutputStream tmp = new DerOutputStream();
080:
081: for (CertificatePolicyMap map : maps) {
082: map.encode(tmp);
083: }
084:
085: os.write(DerValue.tag_Sequence, tmp);
086: this .extensionValue = os.toByteArray();
087: }
088:
089: /**
090: * Create a PolicyMappings with the List of CertificatePolicyMap.
091: *
092: * @param maps the List of CertificatePolicyMap.
093: */
094: public PolicyMappingsExtension(List<CertificatePolicyMap> map)
095: throws IOException {
096: this .maps = map;
097: this .extensionId = PKIXExtensions.PolicyMappings_Id;
098: this .critical = false;
099: encodeThis();
100: }
101:
102: /**
103: * Create a default PolicyMappingsExtension.
104: */
105: public PolicyMappingsExtension() {
106: extensionId = PKIXExtensions.KeyUsage_Id;
107: critical = false;
108: maps = new ArrayList<CertificatePolicyMap>();
109: }
110:
111: /**
112: * Create the extension from the passed DER encoded value.
113: *
114: * @params critical true if the extension is to be treated as critical.
115: * @params value an array of DER encoded bytes of the actual value.
116: * @exception ClassCastException if value is not an array of bytes
117: * @exception IOException on error.
118: */
119: public PolicyMappingsExtension(Boolean critical, Object value)
120: throws IOException {
121: this .extensionId = PKIXExtensions.PolicyMappings_Id;
122: this .critical = critical.booleanValue();
123:
124: this .extensionValue = (byte[]) value;
125: DerValue val = new DerValue(this .extensionValue);
126: if (val.tag != DerValue.tag_Sequence) {
127: throw new IOException("Invalid encoding for "
128: + "PolicyMappingsExtension.");
129: }
130: maps = new ArrayList<CertificatePolicyMap>();
131: while (val.data.available() != 0) {
132: DerValue seq = val.data.getDerValue();
133: CertificatePolicyMap map = new CertificatePolicyMap(seq);
134: maps.add(map);
135: }
136: }
137:
138: /**
139: * Returns a printable representation of the policy map.
140: */
141: public String toString() {
142: if (maps == null)
143: return "";
144: String s = super .toString() + "PolicyMappings [\n"
145: + maps.toString() + "]\n";
146:
147: return (s);
148: }
149:
150: /**
151: * Write the extension to the OutputStream.
152: *
153: * @param out the OutputStream to write the extension to.
154: * @exception IOException on encoding errors.
155: */
156: public void encode(OutputStream out) throws IOException {
157: DerOutputStream tmp = new DerOutputStream();
158: if (extensionValue == null) {
159: extensionId = PKIXExtensions.PolicyMappings_Id;
160: critical = false;
161: encodeThis();
162: }
163: super .encode(tmp);
164: out.write(tmp.toByteArray());
165: }
166:
167: /**
168: * Set the attribute value.
169: */
170: public void set(String name, Object obj) throws IOException {
171: if (name.equalsIgnoreCase(MAP)) {
172: if (!(obj instanceof List)) {
173: throw new IOException("Attribute value should be of"
174: + " type List.");
175: }
176: maps = (List<CertificatePolicyMap>) obj;
177: } else {
178: throw new IOException("Attribute name not recognized by "
179: + "CertAttrSet:PolicyMappingsExtension.");
180: }
181: encodeThis();
182: }
183:
184: /**
185: * Get the attribute value.
186: */
187: public Object get(String name) throws IOException {
188: if (name.equalsIgnoreCase(MAP)) {
189: return (maps);
190: } else {
191: throw new IOException("Attribute name not recognized by "
192: + "CertAttrSet:PolicyMappingsExtension.");
193: }
194: }
195:
196: /**
197: * Delete the attribute value.
198: */
199: public void delete(String name) throws IOException {
200: if (name.equalsIgnoreCase(MAP)) {
201: maps = null;
202: } else {
203: throw new IOException("Attribute name not recognized by "
204: + "CertAttrSet:PolicyMappingsExtension.");
205: }
206: encodeThis();
207: }
208:
209: /**
210: * Return an enumeration of names of attributes existing within this
211: * attribute.
212: */
213: public Enumeration<String> getElements() {
214: AttributeNameEnumeration elements = new AttributeNameEnumeration();
215: elements.addElement(MAP);
216:
217: return elements.elements();
218: }
219:
220: /**
221: * Return the name of this attribute.
222: */
223: public String getName() {
224: return (NAME);
225: }
226: }
|