1 package org.bouncycastle.asn1.x509; 2 3 import java.util.Enumeration; 4 import java.util.Hashtable; 5 import java.util.Vector; 6 7 import org.bouncycastle.asn1.ASN1Encodable; 8 import org.bouncycastle.asn1.ASN1EncodableVector; 9 import org.bouncycastle.asn1.ASN1Object; 10 import org.bouncycastle.asn1.ASN1ObjectIdentifier; 11 import org.bouncycastle.asn1.ASN1Primitive; 12 import org.bouncycastle.asn1.ASN1Sequence; 13 import org.bouncycastle.asn1.ASN1TaggedObject; 14 import org.bouncycastle.asn1.DERSequence; 15 16 public class Extensions 17 extends ASN1Object 18 { 19 private Hashtable extensions = new Hashtable(); 20 private Vector ordering = new Vector(); 21 getInstance( ASN1TaggedObject obj, boolean explicit)22 public static Extensions getInstance( 23 ASN1TaggedObject obj, 24 boolean explicit) 25 { 26 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 27 } 28 getInstance( Object obj)29 public static Extensions getInstance( 30 Object obj) 31 { 32 if (obj instanceof Extensions) 33 { 34 return (Extensions)obj; 35 } 36 else if (obj != null) 37 { 38 return new Extensions(ASN1Sequence.getInstance(obj)); 39 } 40 41 return null; 42 } 43 44 /** 45 * Constructor from ASN1Sequence. 46 * <p> 47 * The extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString) 48 * </p> 49 */ Extensions( ASN1Sequence seq)50 private Extensions( 51 ASN1Sequence seq) 52 { 53 Enumeration e = seq.getObjects(); 54 55 while (e.hasMoreElements()) 56 { 57 Extension ext = Extension.getInstance(e.nextElement()); 58 59 extensions.put(ext.getExtnId(), ext); 60 ordering.addElement(ext.getExtnId()); 61 } 62 } 63 64 /** 65 * Base Constructor 66 * 67 * @param extension a single extension. 68 */ Extensions( Extension extension)69 public Extensions( 70 Extension extension) 71 { 72 this.ordering.addElement(extension.getExtnId()); 73 this.extensions.put(extension.getExtnId(), extension); 74 } 75 76 /** 77 * Base Constructor 78 * 79 * @param extensions an array of extensions. 80 */ Extensions( Extension[] extensions)81 public Extensions( 82 Extension[] extensions) 83 { 84 for (int i = 0; i != extensions.length; i++) 85 { 86 Extension ext = extensions[i]; 87 88 this.ordering.addElement(ext.getExtnId()); 89 this.extensions.put(ext.getExtnId(), ext); 90 } 91 } 92 93 /** 94 * return an Enumeration of the extension field's object ids. 95 */ oids()96 public Enumeration oids() 97 { 98 return ordering.elements(); 99 } 100 101 /** 102 * return the extension represented by the object identifier 103 * passed in. 104 * 105 * @return the extension if it's present, null otherwise. 106 */ getExtension( ASN1ObjectIdentifier oid)107 public Extension getExtension( 108 ASN1ObjectIdentifier oid) 109 { 110 return (Extension)extensions.get(oid); 111 } 112 113 /** 114 * return the parsed value of the extension represented by the object identifier 115 * passed in. 116 * 117 * @return the parsed value of the extension if it's present, null otherwise. 118 */ getExtensionParsedValue(ASN1ObjectIdentifier oid)119 public ASN1Encodable getExtensionParsedValue(ASN1ObjectIdentifier oid) 120 { 121 Extension ext = this.getExtension(oid); 122 123 if (ext != null) 124 { 125 return ext.getParsedValue(); 126 } 127 128 return null; 129 } 130 131 /** 132 * <pre> 133 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 134 * 135 * Extension ::= SEQUENCE { 136 * extnId EXTENSION.&id ({ExtensionSet}), 137 * critical BOOLEAN DEFAULT FALSE, 138 * extnValue OCTET STRING } 139 * </pre> 140 */ toASN1Primitive()141 public ASN1Primitive toASN1Primitive() 142 { 143 ASN1EncodableVector vec = new ASN1EncodableVector(); 144 Enumeration e = ordering.elements(); 145 146 while (e.hasMoreElements()) 147 { 148 ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 149 Extension ext = (Extension)extensions.get(oid); 150 151 vec.add(ext); 152 } 153 154 return new DERSequence(vec); 155 } 156 equivalent( Extensions other)157 public boolean equivalent( 158 Extensions other) 159 { 160 if (extensions.size() != other.extensions.size()) 161 { 162 return false; 163 } 164 165 Enumeration e1 = extensions.keys(); 166 167 while (e1.hasMoreElements()) 168 { 169 Object key = e1.nextElement(); 170 171 if (!extensions.get(key).equals(other.extensions.get(key))) 172 { 173 return false; 174 } 175 } 176 177 return true; 178 } 179 getExtensionOIDs()180 public ASN1ObjectIdentifier[] getExtensionOIDs() 181 { 182 return toOidArray(ordering); 183 } 184 getNonCriticalExtensionOIDs()185 public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs() 186 { 187 return getExtensionOIDs(false); 188 } 189 getCriticalExtensionOIDs()190 public ASN1ObjectIdentifier[] getCriticalExtensionOIDs() 191 { 192 return getExtensionOIDs(true); 193 } 194 getExtensionOIDs(boolean isCritical)195 private ASN1ObjectIdentifier[] getExtensionOIDs(boolean isCritical) 196 { 197 Vector oidVec = new Vector(); 198 199 for (int i = 0; i != ordering.size(); i++) 200 { 201 Object oid = ordering.elementAt(i); 202 203 if (((Extension)extensions.get(oid)).isCritical() == isCritical) 204 { 205 oidVec.addElement(oid); 206 } 207 } 208 209 return toOidArray(oidVec); 210 } 211 toOidArray(Vector oidVec)212 private ASN1ObjectIdentifier[] toOidArray(Vector oidVec) 213 { 214 ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[oidVec.size()]; 215 216 for (int i = 0; i != oids.length; i++) 217 { 218 oids[i] = (ASN1ObjectIdentifier)oidVec.elementAt(i); 219 } 220 return oids; 221 } 222 } 223