001: /*
002: * Copyright 2004-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:
031: import java.util.*;
032:
033: import sun.security.util.DerOutputStream;
034: import sun.security.util.DerValue;
035:
036: /**
037: * The Authority Information Access Extension (OID = 1.3.6.1.5.5.7.1.1).
038: * <p>
039: * The AIA extension identifies how to access CA information and services
040: * for the certificate in which it appears. It enables CAs to issue their
041: * certificates pre-configured with the URLs appropriate for contacting
042: * services relevant to those certificates. For example, a CA may issue a
043: * certificate that identifies the specific OCSP Responder to use when
044: * performing on-line validation of that certificate.
045: * <p>
046: * This extension is defined in
047: * <a href="http://www.ietf.org/rfc/rfc3280.txt">Internet X.509 PKI Certificate and Certificate Revocation List (CRL) Profile</a>. The profile permits
048: * the extension to be included in end-entity or CA certificates,
049: * and it must be marked as non-critical. Its ASN.1 definition is as follows:
050: * <pre>
051: * id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
052: *
053: * AuthorityInfoAccessSyntax ::=
054: * SEQUENCE SIZE (1..MAX) OF AccessDescription
055: *
056: * AccessDescription ::= SEQUENCE {
057: * accessMethod OBJECT IDENTIFIER,
058: * accessLocation GeneralName }
059: * </pre>
060: * <p>
061: * @see Extension
062: * @see CertAttrSet
063: */
064:
065: public class AuthorityInfoAccessExtension extends Extension implements
066: CertAttrSet<String> {
067:
068: /**
069: * Identifier for this attribute, to be used with the
070: * get, set, delete methods of Certificate, x509 type.
071: */
072: public static final String IDENT = "x509.info.extensions.AuthorityInfoAccess";
073:
074: /**
075: * Attribute name.
076: */
077: public static final String NAME = "AuthorityInfoAccess";
078: public static final String DESCRIPTIONS = "descriptions";
079:
080: /**
081: * The List of AccessDescription objects.
082: */
083: private List<AccessDescription> accessDescriptions;
084:
085: /**
086: * Create an AuthorityInfoAccessExtension from a List of
087: * AccessDescription; the criticality is set to false.
088: *
089: * @param accessDescriptions the List of AccessDescription
090: * @throws IOException on error
091: */
092: public AuthorityInfoAccessExtension(
093: List<AccessDescription> accessDescriptions)
094: throws IOException {
095: this .extensionId = PKIXExtensions.AuthInfoAccess_Id;
096: this .critical = false;
097: this .accessDescriptions = accessDescriptions;
098: encodeThis();
099: }
100:
101: /**
102: * Create the extension from the passed DER encoded value of the same.
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 AuthorityInfoAccessExtension(Boolean critical, Object value)
109: throws IOException {
110: this .extensionId = PKIXExtensions.AuthInfoAccess_Id;
111: this .critical = critical.booleanValue();
112:
113: if (!(value instanceof byte[])) {
114: throw new IOException("Illegal argument type");
115: }
116:
117: extensionValue = (byte[]) value;
118: DerValue val = new DerValue(extensionValue);
119: if (val.tag != DerValue.tag_Sequence) {
120: throw new IOException("Invalid encoding for "
121: + "AuthorityInfoAccessExtension.");
122: }
123: accessDescriptions = new ArrayList<AccessDescription>();
124: while (val.data.available() != 0) {
125: DerValue seq = val.data.getDerValue();
126: AccessDescription accessDescription = new AccessDescription(
127: 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(
170: "Attribute value should be of type List.");
171: }
172: accessDescriptions = (List<AccessDescription>) obj;
173: } else {
174: throw new IOException("Attribute name [" + name
175: + "] not recognized by "
176: + "CertAttrSet:AuthorityInfoAccessExtension.");
177: }
178: encodeThis();
179: }
180:
181: /**
182: * Get the attribute value.
183: */
184: public Object get(String name) throws IOException {
185: if (name.equalsIgnoreCase(DESCRIPTIONS)) {
186: return accessDescriptions;
187: } else {
188: throw new IOException("Attribute name [" + name
189: + "] not recognized by "
190: + "CertAttrSet:AuthorityInfoAccessExtension.");
191: }
192: }
193:
194: /**
195: * Delete the attribute value.
196: */
197: public void delete(String name) throws IOException {
198: if (name.equalsIgnoreCase(DESCRIPTIONS)) {
199: accessDescriptions = new ArrayList<AccessDescription>();
200: } else {
201: throw new IOException("Attribute name [" + name
202: + "] not recognized by "
203: + "CertAttrSet:AuthorityInfoAccessExtension.");
204: }
205: encodeThis();
206: }
207:
208: /**
209: * Return an enumeration of names of attributes existing within this
210: * attribute.
211: */
212: public Enumeration<String> getElements() {
213: AttributeNameEnumeration elements = new AttributeNameEnumeration();
214: elements.addElement(DESCRIPTIONS);
215: return elements.elements();
216: }
217:
218: // Encode this extension value
219: private void encodeThis() throws IOException {
220: if (accessDescriptions.isEmpty()) {
221: this .extensionValue = null;
222: } else {
223: DerOutputStream ads = new DerOutputStream();
224: for (AccessDescription accessDescription : accessDescriptions) {
225: accessDescription.encode(ads);
226: }
227: DerOutputStream seq = new DerOutputStream();
228: seq.write(DerValue.tag_Sequence, ads);
229: this .extensionValue = seq.toByteArray();
230: }
231: }
232:
233: /**
234: * Return the extension as user readable string.
235: */
236: public String toString() {
237: return super .toString() + "AuthorityInfoAccess [\n "
238: + accessDescriptions + "\n]\n";
239: }
240:
241: }
|