Extensions.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
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.ASN1EncodableVector; 9import org.bouncycastle.asn1.ASN1Object; 10import org.bouncycastle.asn1.ASN1ObjectIdentifier; 11import org.bouncycastle.asn1.ASN1OctetString; 12import org.bouncycastle.asn1.ASN1Primitive; 13import org.bouncycastle.asn1.ASN1Sequence; 14import org.bouncycastle.asn1.ASN1TaggedObject; 15import org.bouncycastle.asn1.DERSequence; 16 17public class Extensions 18 extends ASN1Object 19{ 20 private Hashtable extensions = new Hashtable(); 21 private Vector ordering = new Vector(); 22 23 public static Extensions getInstance( 24 ASN1TaggedObject obj, 25 boolean explicit) 26 { 27 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 28 } 29 30 public static Extensions getInstance( 31 Object obj) 32 { 33 if (obj instanceof Extensions) 34 { 35 return (Extensions)obj; 36 } 37 else if (obj != null) 38 { 39 return new Extensions(ASN1Sequence.getInstance(obj)); 40 } 41 42 return null; 43 } 44 45 /** 46 * Constructor from ASN1Sequence. 47 * 48 * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString) 49 */ 50 private Extensions( 51 ASN1Sequence seq) 52 { 53 Enumeration e = seq.getObjects(); 54 55 while (e.hasMoreElements()) 56 { 57 ASN1Sequence s = ASN1Sequence.getInstance(e.nextElement()); 58 59 if (s.size() == 3) 60 { 61 extensions.put(s.getObjectAt(0), new Extension(ASN1ObjectIdentifier.getInstance(s.getObjectAt(0)), ASN1Boolean.getInstance(s.getObjectAt(1)), ASN1OctetString.getInstance(s.getObjectAt(2)))); 62 } 63 else if (s.size() == 2) 64 { 65 extensions.put(s.getObjectAt(0), new Extension(ASN1ObjectIdentifier.getInstance(s.getObjectAt(0)), false, ASN1OctetString.getInstance(s.getObjectAt(1)))); 66 } 67 else 68 { 69 throw new IllegalArgumentException("Bad sequence size: " + s.size()); 70 } 71 72 ordering.addElement(s.getObjectAt(0)); 73 } 74 } 75 76 /** 77 * Base Constructor 78 * 79 * @param extensions an array of extensions. 80 */ 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 */ 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 */ 107 public Extension getExtension( 108 ASN1ObjectIdentifier oid) 109 { 110 return (Extension)extensions.get(oid); 111 } 112 113 /** 114 * <pre> 115 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 116 * 117 * Extension ::= SEQUENCE { 118 * extnId EXTENSION.&id ({ExtensionSet}), 119 * critical BOOLEAN DEFAULT FALSE, 120 * extnValue OCTET STRING } 121 * </pre> 122 */ 123 public ASN1Primitive toASN1Primitive() 124 { 125 ASN1EncodableVector vec = new ASN1EncodableVector(); 126 Enumeration e = ordering.elements(); 127 128 while (e.hasMoreElements()) 129 { 130 ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 131 Extension ext = (Extension)extensions.get(oid); 132 ASN1EncodableVector v = new ASN1EncodableVector(); 133 134 v.add(oid); 135 136 if (ext.isCritical()) 137 { 138 v.add(ASN1Boolean.getInstance(true)); 139 } 140 141 v.add(ext.getExtnValue()); 142 143 vec.add(new DERSequence(v)); 144 } 145 146 return new DERSequence(vec); 147 } 148 149 public boolean equivalent( 150 Extensions other) 151 { 152 if (extensions.size() != other.extensions.size()) 153 { 154 return false; 155 } 156 157 Enumeration e1 = extensions.keys(); 158 159 while (e1.hasMoreElements()) 160 { 161 Object key = e1.nextElement(); 162 163 if (!extensions.get(key).equals(other.extensions.get(key))) 164 { 165 return false; 166 } 167 } 168 169 return true; 170 } 171 172 public ASN1ObjectIdentifier[] getExtensionOIDs() 173 { 174 return toOidArray(ordering); 175 } 176 177 public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs() 178 { 179 return getExtensionOIDs(false); 180 } 181 182 public ASN1ObjectIdentifier[] getCriticalExtensionOIDs() 183 { 184 return getExtensionOIDs(true); 185 } 186 187 private ASN1ObjectIdentifier[] getExtensionOIDs(boolean isCritical) 188 { 189 Vector oidVec = new Vector(); 190 191 for (int i = 0; i != ordering.size(); i++) 192 { 193 Object oid = ordering.elementAt(i); 194 195 if (((Extension)extensions.get(oid)).isCritical() == isCritical) 196 { 197 oidVec.addElement(oid); 198 } 199 } 200 201 return toOidArray(oidVec); 202 } 203 204 private ASN1ObjectIdentifier[] toOidArray(Vector oidVec) 205 { 206 ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[oidVec.size()]; 207 208 for (int i = 0; i != oids.length; i++) 209 { 210 oids[i] = (ASN1ObjectIdentifier)oidVec.elementAt(i); 211 } 212 return oids; 213 } 214} 215