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