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