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