001package org.apache.commons.ssl.org.bouncycastle.asn1.x509; 002 003import java.util.Enumeration; 004import java.util.Hashtable; 005import java.util.Vector; 006 007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable; 008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector; 009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1ObjectIdentifier; 011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive; 012import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence; 013import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject; 014import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence; 015 016public class Extensions 017 extends ASN1Object 018{ 019 private Hashtable extensions = new Hashtable(); 020 private Vector ordering = new Vector(); 021 022 public static Extensions getInstance( 023 ASN1TaggedObject obj, 024 boolean explicit) 025 { 026 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 027 } 028 029 public static Extensions getInstance( 030 Object obj) 031 { 032 if (obj instanceof Extensions) 033 { 034 return (Extensions)obj; 035 } 036 else if (obj != null) 037 { 038 return new Extensions(ASN1Sequence.getInstance(obj)); 039 } 040 041 return null; 042 } 043 044 /** 045 * Constructor from ASN1Sequence. 046 * <p> 047 * The extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString) 048 * </p> 049 */ 050 private Extensions( 051 ASN1Sequence seq) 052 { 053 Enumeration e = seq.getObjects(); 054 055 while (e.hasMoreElements()) 056 { 057 Extension ext = Extension.getInstance(e.nextElement()); 058 059 extensions.put(ext.getExtnId(), ext); 060 ordering.addElement(ext.getExtnId()); 061 } 062 } 063 064 /** 065 * Base Constructor 066 * 067 * @param extension a single extension. 068 */ 069 public Extensions( 070 Extension extension) 071 { 072 this.ordering.addElement(extension.getExtnId()); 073 this.extensions.put(extension.getExtnId(), extension); 074 } 075 076 /** 077 * Base Constructor 078 * 079 * @param extensions an array of extensions. 080 */ 081 public Extensions( 082 Extension[] extensions) 083 { 084 for (int i = 0; i != extensions.length; i++) 085 { 086 Extension ext = extensions[i]; 087 088 this.ordering.addElement(ext.getExtnId()); 089 this.extensions.put(ext.getExtnId(), ext); 090 } 091 } 092 093 /** 094 * return an Enumeration of the extension field's object ids. 095 */ 096 public Enumeration oids() 097 { 098 return ordering.elements(); 099 } 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 * 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 */ 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 */ 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 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 180 public ASN1ObjectIdentifier[] getExtensionOIDs() 181 { 182 return toOidArray(ordering); 183 } 184 185 public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs() 186 { 187 return getExtensionOIDs(false); 188 } 189 190 public ASN1ObjectIdentifier[] getCriticalExtensionOIDs() 191 { 192 return getExtensionOIDs(true); 193 } 194 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 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}