001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.crypto.asn1.x509;
017:
018: import java.util.Enumeration;
019: import java.util.Hashtable;
020: import java.util.Vector;
021:
022: import org.apache.geronimo.crypto.asn1.ASN1Encodable;
023: import org.apache.geronimo.crypto.asn1.ASN1EncodableVector;
024: import org.apache.geronimo.crypto.asn1.ASN1OctetString;
025: import org.apache.geronimo.crypto.asn1.ASN1Sequence;
026: import org.apache.geronimo.crypto.asn1.ASN1TaggedObject;
027: import org.apache.geronimo.crypto.asn1.DERBoolean;
028: import org.apache.geronimo.crypto.asn1.DERObject;
029: import org.apache.geronimo.crypto.asn1.DERObjectIdentifier;
030: import org.apache.geronimo.crypto.asn1.DERSequence;
031:
032: public class X509Extensions extends ASN1Encodable {
033: /**
034: * Subject Directory Attributes
035: */
036: public static final DERObjectIdentifier SubjectDirectoryAttributes = new DERObjectIdentifier(
037: "2.5.29.9");
038:
039: /**
040: * Subject Key Identifier
041: */
042: public static final DERObjectIdentifier SubjectKeyIdentifier = new DERObjectIdentifier(
043: "2.5.29.14");
044:
045: /**
046: * Key Usage
047: */
048: public static final DERObjectIdentifier KeyUsage = new DERObjectIdentifier(
049: "2.5.29.15");
050:
051: /**
052: * Private Key Usage Period
053: */
054: public static final DERObjectIdentifier PrivateKeyUsagePeriod = new DERObjectIdentifier(
055: "2.5.29.16");
056:
057: /**
058: * Subject Alternative Name
059: */
060: public static final DERObjectIdentifier SubjectAlternativeName = new DERObjectIdentifier(
061: "2.5.29.17");
062:
063: /**
064: * Issuer Alternative Name
065: */
066: public static final DERObjectIdentifier IssuerAlternativeName = new DERObjectIdentifier(
067: "2.5.29.18");
068:
069: /**
070: * Basic Constraints
071: */
072: public static final DERObjectIdentifier BasicConstraints = new DERObjectIdentifier(
073: "2.5.29.19");
074:
075: /**
076: * CRL Number
077: */
078: public static final DERObjectIdentifier CRLNumber = new DERObjectIdentifier(
079: "2.5.29.20");
080:
081: /**
082: * Reason code
083: */
084: public static final DERObjectIdentifier ReasonCode = new DERObjectIdentifier(
085: "2.5.29.21");
086:
087: /**
088: * Hold Instruction Code
089: */
090: public static final DERObjectIdentifier InstructionCode = new DERObjectIdentifier(
091: "2.5.29.23");
092:
093: /**
094: * Invalidity Date
095: */
096: public static final DERObjectIdentifier InvalidityDate = new DERObjectIdentifier(
097: "2.5.29.24");
098:
099: /**
100: * Delta CRL indicator
101: */
102: public static final DERObjectIdentifier DeltaCRLIndicator = new DERObjectIdentifier(
103: "2.5.29.27");
104:
105: /**
106: * Issuing Distribution Point
107: */
108: public static final DERObjectIdentifier IssuingDistributionPoint = new DERObjectIdentifier(
109: "2.5.29.28");
110:
111: /**
112: * Certificate Issuer
113: */
114: public static final DERObjectIdentifier CertificateIssuer = new DERObjectIdentifier(
115: "2.5.29.29");
116:
117: /**
118: * Name Constraints
119: */
120: public static final DERObjectIdentifier NameConstraints = new DERObjectIdentifier(
121: "2.5.29.30");
122:
123: /**
124: * CRL Distribution Points
125: */
126: public static final DERObjectIdentifier CRLDistributionPoints = new DERObjectIdentifier(
127: "2.5.29.31");
128:
129: /**
130: * Certificate Policies
131: */
132: public static final DERObjectIdentifier CertificatePolicies = new DERObjectIdentifier(
133: "2.5.29.32");
134:
135: /**
136: * Policy Mappings
137: */
138: public static final DERObjectIdentifier PolicyMappings = new DERObjectIdentifier(
139: "2.5.29.33");
140:
141: /**
142: * Authority Key Identifier
143: */
144: public static final DERObjectIdentifier AuthorityKeyIdentifier = new DERObjectIdentifier(
145: "2.5.29.35");
146:
147: /**
148: * Policy Constraints
149: */
150: public static final DERObjectIdentifier PolicyConstraints = new DERObjectIdentifier(
151: "2.5.29.36");
152:
153: /**
154: * Extended Key Usage
155: */
156: public static final DERObjectIdentifier ExtendedKeyUsage = new DERObjectIdentifier(
157: "2.5.29.37");
158:
159: /**
160: * Freshest CRL
161: */
162: public static final DERObjectIdentifier FreshestCRL = new DERObjectIdentifier(
163: "2.5.29.46");
164:
165: /**
166: * Inhibit Any Policy
167: */
168: public static final DERObjectIdentifier InhibitAnyPolicy = new DERObjectIdentifier(
169: "2.5.29.54");
170:
171: /**
172: * Authority Info Access
173: */
174: public static final DERObjectIdentifier AuthorityInfoAccess = new DERObjectIdentifier(
175: "1.3.6.1.5.5.7.1.1");
176:
177: /**
178: * Subject Info Access
179: */
180: public static final DERObjectIdentifier SubjectInfoAccess = new DERObjectIdentifier(
181: "1.3.6.1.5.5.7.1.11");
182:
183: private Hashtable extensions = new Hashtable();
184: private Vector ordering = new Vector();
185:
186: public static X509Extensions getInstance(ASN1TaggedObject obj,
187: boolean explicit) {
188: return getInstance(ASN1Sequence.getInstance(obj, explicit));
189: }
190:
191: public static X509Extensions getInstance(Object obj) {
192: if (obj == null || obj instanceof X509Extensions) {
193: return (X509Extensions) obj;
194: }
195:
196: if (obj instanceof ASN1Sequence) {
197: return new X509Extensions((ASN1Sequence) obj);
198: }
199:
200: if (obj instanceof ASN1TaggedObject) {
201: return getInstance(((ASN1TaggedObject) obj).getObject());
202: }
203:
204: throw new IllegalArgumentException(
205: "illegal object in getInstance: "
206: + obj.getClass().getName());
207: }
208:
209: /**
210: * Constructor from ASN1Sequence.
211: *
212: * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString)
213: */
214: public X509Extensions(ASN1Sequence seq) {
215: Enumeration e = seq.getObjects();
216:
217: while (e.hasMoreElements()) {
218: ASN1Sequence s = (ASN1Sequence) e.nextElement();
219:
220: if (s.size() == 3) {
221: extensions.put(s.getObjectAt(0), new X509Extension(
222: (DERBoolean) s.getObjectAt(1),
223: (ASN1OctetString) s.getObjectAt(2)));
224: } else {
225: extensions.put(s.getObjectAt(0), new X509Extension(
226: false, (ASN1OctetString) s.getObjectAt(1)));
227: }
228:
229: ordering.addElement(s.getObjectAt(0));
230: }
231: }
232:
233: /**
234: * constructor from a table of extensions.
235: * <p>
236: * it's is assumed the table contains OID/String pairs.
237: */
238: public X509Extensions(Hashtable extensions) {
239: this (null, extensions);
240: }
241:
242: /**
243: * Constructor from a table of extensions with ordering.
244: * <p>
245: * It's is assumed the table contains OID/String pairs.
246: */
247: public X509Extensions(Vector ordering, Hashtable extensions) {
248: Enumeration e;
249:
250: if (ordering == null) {
251: e = extensions.keys();
252: } else {
253: e = ordering.elements();
254: }
255:
256: while (e.hasMoreElements()) {
257: this .ordering.addElement(e.nextElement());
258: }
259:
260: e = this .ordering.elements();
261:
262: while (e.hasMoreElements()) {
263: DERObjectIdentifier oid = (DERObjectIdentifier) e
264: .nextElement();
265: X509Extension ext = (X509Extension) extensions.get(oid);
266:
267: this .extensions.put(oid, ext);
268: }
269: }
270:
271: /**
272: * Constructor from two vectors
273: *
274: * @param objectIDs a vector of the object identifiers.
275: * @param values a vector of the extension values.
276: */
277: public X509Extensions(Vector objectIDs, Vector values) {
278: Enumeration e = objectIDs.elements();
279:
280: while (e.hasMoreElements()) {
281: this .ordering.addElement(e.nextElement());
282: }
283:
284: int count = 0;
285:
286: e = this .ordering.elements();
287:
288: while (e.hasMoreElements()) {
289: DERObjectIdentifier oid = (DERObjectIdentifier) e
290: .nextElement();
291: X509Extension ext = (X509Extension) values.elementAt(count);
292:
293: this .extensions.put(oid, ext);
294: count++;
295: }
296: }
297:
298: /**
299: * return an Enumeration of the extension field's object ids.
300: */
301: public Enumeration oids() {
302: return ordering.elements();
303: }
304:
305: /**
306: * return the extension represented by the object identifier
307: * passed in.
308: *
309: * @return the extension if it's present, null otherwise.
310: */
311: public X509Extension getExtension(DERObjectIdentifier oid) {
312: return (X509Extension) extensions.get(oid);
313: }
314:
315: /**
316: * <pre>
317: * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
318: *
319: * Extension ::= SEQUENCE {
320: * extnId EXTENSION.&id ({ExtensionSet}),
321: * critical BOOLEAN DEFAULT FALSE,
322: * extnValue OCTET STRING }
323: * </pre>
324: */
325: public DERObject toASN1Object() {
326: ASN1EncodableVector vec = new ASN1EncodableVector();
327: Enumeration e = ordering.elements();
328:
329: while (e.hasMoreElements()) {
330: DERObjectIdentifier oid = (DERObjectIdentifier) e
331: .nextElement();
332: X509Extension ext = (X509Extension) extensions.get(oid);
333: ASN1EncodableVector v = new ASN1EncodableVector();
334:
335: v.add(oid);
336:
337: if (ext.isCritical()) {
338: v.add(new DERBoolean(true));
339: }
340:
341: v.add(ext.getValue());
342:
343: vec.add(new DERSequence(v));
344: }
345:
346: return new DERSequence(vec);
347: }
348:
349: public int hashCode() {
350: Enumeration e = extensions.keys();
351: int hashCode = 0;
352:
353: while (e.hasMoreElements()) {
354: Object o = e.nextElement();
355:
356: hashCode ^= o.hashCode();
357: hashCode ^= extensions.get(o).hashCode();
358: }
359:
360: return hashCode;
361: }
362:
363: public boolean equals(Object o) {
364: if (o == null || !(o instanceof X509Extensions)) {
365: return false;
366: }
367:
368: X509Extensions other = (X509Extensions) o;
369:
370: Enumeration e1 = extensions.keys();
371: Enumeration e2 = other.extensions.keys();
372:
373: while (e1.hasMoreElements() && e2.hasMoreElements()) {
374: Object o1 = e1.nextElement();
375: Object o2 = e2.nextElement();
376:
377: if (!o1.equals(o2)) {
378: return false;
379: }
380: }
381:
382: if (e1.hasMoreElements() || e2.hasMoreElements()) {
383: return false;
384: }
385:
386: return true;
387: }
388: }
|