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.ASN1ObjectIdentifier; 10 import org.bouncycastle.asn1.ASN1OctetString; 11 import org.bouncycastle.asn1.ASN1Sequence; 12 import org.bouncycastle.asn1.ASN1TaggedObject; 13 import org.bouncycastle.asn1.DERBoolean; 14 import org.bouncycastle.asn1.DERObject; 15 import org.bouncycastle.asn1.DERObjectIdentifier; 16 import org.bouncycastle.asn1.DERSequence; 17 18 public class X509Extensions 19 extends ASN1Encodable 20 { 21 /** 22 * Subject Directory Attributes 23 * @deprecated use X509Extension value. 24 */ 25 public static final ASN1ObjectIdentifier SubjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9"); 26 27 /** 28 * Subject Key Identifier 29 * @deprecated use X509Extension value. 30 */ 31 public static final ASN1ObjectIdentifier SubjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14"); 32 33 /** 34 * Key Usage 35 * @deprecated use X509Extension value. 36 */ 37 public static final ASN1ObjectIdentifier KeyUsage = new ASN1ObjectIdentifier("2.5.29.15"); 38 39 /** 40 * Private Key Usage Period 41 * @deprecated use X509Extension value. 42 */ 43 public static final ASN1ObjectIdentifier PrivateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16"); 44 45 /** 46 * Subject Alternative Name 47 * @deprecated use X509Extension value. 48 */ 49 public static final ASN1ObjectIdentifier SubjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17"); 50 51 /** 52 * Issuer Alternative Name 53 * @deprecated use X509Extension value. 54 */ 55 public static final ASN1ObjectIdentifier IssuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18"); 56 57 /** 58 * Basic Constraints 59 * @deprecated use X509Extension value. 60 */ 61 public static final ASN1ObjectIdentifier BasicConstraints = new ASN1ObjectIdentifier("2.5.29.19"); 62 63 /** 64 * CRL Number 65 * @deprecated use X509Extension value. 66 */ 67 public static final ASN1ObjectIdentifier CRLNumber = new ASN1ObjectIdentifier("2.5.29.20"); 68 69 /** 70 * Reason code 71 * @deprecated use X509Extension value. 72 */ 73 public static final ASN1ObjectIdentifier ReasonCode = new ASN1ObjectIdentifier("2.5.29.21"); 74 75 /** 76 * Hold Instruction Code 77 * @deprecated use X509Extension value. 78 */ 79 public static final ASN1ObjectIdentifier InstructionCode = new ASN1ObjectIdentifier("2.5.29.23"); 80 81 /** 82 * Invalidity Date 83 * @deprecated use X509Extension value. 84 */ 85 public static final ASN1ObjectIdentifier InvalidityDate = new ASN1ObjectIdentifier("2.5.29.24"); 86 87 /** 88 * Delta CRL indicator 89 * @deprecated use X509Extension value. 90 */ 91 public static final ASN1ObjectIdentifier DeltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27"); 92 93 /** 94 * Issuing Distribution Point 95 * @deprecated use X509Extension value. 96 */ 97 public static final ASN1ObjectIdentifier IssuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28"); 98 99 /** 100 * Certificate Issuer 101 * @deprecated use X509Extension value. 102 */ 103 public static final ASN1ObjectIdentifier CertificateIssuer = new ASN1ObjectIdentifier("2.5.29.29"); 104 105 /** 106 * Name Constraints 107 * @deprecated use X509Extension value. 108 */ 109 public static final ASN1ObjectIdentifier NameConstraints = new ASN1ObjectIdentifier("2.5.29.30"); 110 111 /** 112 * CRL Distribution Points 113 * @deprecated use X509Extension value. 114 */ 115 public static final ASN1ObjectIdentifier CRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31"); 116 117 /** 118 * Certificate Policies 119 * @deprecated use X509Extension value. 120 */ 121 public static final ASN1ObjectIdentifier CertificatePolicies = new ASN1ObjectIdentifier("2.5.29.32"); 122 123 /** 124 * Policy Mappings 125 * @deprecated use X509Extension value. 126 */ 127 public static final ASN1ObjectIdentifier PolicyMappings = new ASN1ObjectIdentifier("2.5.29.33"); 128 129 /** 130 * Authority Key Identifier 131 * @deprecated use X509Extension value. 132 */ 133 public static final ASN1ObjectIdentifier AuthorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35"); 134 135 /** 136 * Policy Constraints 137 * @deprecated use X509Extension value. 138 */ 139 public static final ASN1ObjectIdentifier PolicyConstraints = new ASN1ObjectIdentifier("2.5.29.36"); 140 141 /** 142 * Extended Key Usage 143 * @deprecated use X509Extension value. 144 */ 145 public static final ASN1ObjectIdentifier ExtendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37"); 146 147 /** 148 * Freshest CRL 149 * @deprecated use X509Extension value. 150 */ 151 public static final ASN1ObjectIdentifier FreshestCRL = new ASN1ObjectIdentifier("2.5.29.46"); 152 153 /** 154 * Inhibit Any Policy 155 * @deprecated use X509Extension value. 156 */ 157 public static final ASN1ObjectIdentifier InhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54"); 158 159 /** 160 * Authority Info Access 161 * @deprecated use X509Extension value. 162 */ 163 public static final ASN1ObjectIdentifier AuthorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1"); 164 165 /** 166 * Subject Info Access 167 * @deprecated use X509Extension value. 168 */ 169 public static final ASN1ObjectIdentifier SubjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11"); 170 171 /** 172 * Logo Type 173 * @deprecated use X509Extension value. 174 */ 175 public static final ASN1ObjectIdentifier LogoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12"); 176 177 /** 178 * BiometricInfo 179 * @deprecated use X509Extension value. 180 */ 181 public static final ASN1ObjectIdentifier BiometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2"); 182 183 /** 184 * QCStatements 185 * @deprecated use X509Extension value. 186 */ 187 public static final ASN1ObjectIdentifier QCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3"); 188 189 /** 190 * Audit identity extension in attribute certificates. 191 * @deprecated use X509Extension value. 192 */ 193 public static final ASN1ObjectIdentifier AuditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4"); 194 195 /** 196 * NoRevAvail extension in attribute certificates. 197 * @deprecated use X509Extension value. 198 */ 199 public static final ASN1ObjectIdentifier NoRevAvail = new ASN1ObjectIdentifier("2.5.29.56"); 200 201 /** 202 * TargetInformation extension in attribute certificates. 203 * @deprecated use X509Extension value. 204 */ 205 public static final ASN1ObjectIdentifier TargetInformation = new ASN1ObjectIdentifier("2.5.29.55"); 206 207 private Hashtable extensions = new Hashtable(); 208 private Vector ordering = new Vector(); 209 210 public static X509Extensions getInstance( 211 ASN1TaggedObject obj, 212 boolean explicit) 213 { 214 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 215 } 216 217 public static X509Extensions getInstance( 218 Object obj) 219 { 220 if (obj == null || obj instanceof X509Extensions) 221 { 222 return (X509Extensions)obj; 223 } 224 225 if (obj instanceof ASN1Sequence) 226 { 227 return new X509Extensions((ASN1Sequence)obj); 228 } 229 230 if (obj instanceof ASN1TaggedObject) 231 { 232 return getInstance(((ASN1TaggedObject)obj).getObject()); 233 } 234 235 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 236 } 237 238 /** 239 * Constructor from ASN1Sequence. 240 * 241 * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString) 242 */ 243 public X509Extensions( 244 ASN1Sequence seq) 245 { 246 Enumeration e = seq.getObjects(); 247 248 while (e.hasMoreElements()) 249 { 250 ASN1Sequence s = ASN1Sequence.getInstance(e.nextElement()); 251 252 if (s.size() == 3) 253 { 254 extensions.put(s.getObjectAt(0), new X509Extension(DERBoolean.getInstance(s.getObjectAt(1)), ASN1OctetString.getInstance(s.getObjectAt(2)))); 255 } 256 else if (s.size() == 2) 257 { 258 extensions.put(s.getObjectAt(0), new X509Extension(false, ASN1OctetString.getInstance(s.getObjectAt(1)))); 259 } 260 else 261 { 262 throw new IllegalArgumentException("Bad sequence size: " + s.size()); 263 } 264 265 ordering.addElement(s.getObjectAt(0)); 266 } 267 } 268 269 /** 270 * constructor from a table of extensions. 271 * <p> 272 * it's is assumed the table contains OID/String pairs. 273 */ 274 public X509Extensions( 275 Hashtable extensions) 276 { 277 this(null, extensions); 278 } 279 280 /** 281 * Constructor from a table of extensions with ordering. 282 * <p> 283 * It's is assumed the table contains OID/String pairs. 284 */ 285 public X509Extensions( 286 Vector ordering, 287 Hashtable extensions) 288 { 289 Enumeration e; 290 291 if (ordering == null) 292 { 293 e = extensions.keys(); 294 } 295 else 296 { 297 e = ordering.elements(); 298 } 299 300 while (e.hasMoreElements()) 301 { 302 this.ordering.addElement(new ASN1ObjectIdentifier(((DERObjectIdentifier)e.nextElement()).getId())); 303 } 304 305 e = this.ordering.elements(); 306 307 while (e.hasMoreElements()) 308 { 309 ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(((DERObjectIdentifier)e.nextElement()).getId()); 310 X509Extension ext = (X509Extension)extensions.get(oid); 311 312 this.extensions.put(oid, ext); 313 } 314 } 315 316 /** 317 * Constructor from two vectors 318 * 319 * @param objectIDs a vector of the object identifiers. 320 * @param values a vector of the extension values. 321 */ 322 public X509Extensions( 323 Vector objectIDs, 324 Vector values) 325 { 326 Enumeration e = objectIDs.elements(); 327 328 while (e.hasMoreElements()) 329 { 330 this.ordering.addElement(e.nextElement()); 331 } 332 333 int count = 0; 334 335 e = this.ordering.elements(); 336 337 while (e.hasMoreElements()) 338 { 339 ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 340 X509Extension ext = (X509Extension)values.elementAt(count); 341 342 this.extensions.put(oid, ext); 343 count++; 344 } 345 } 346 347 /** 348 * return an Enumeration of the extension field's object ids. 349 */ 350 public Enumeration oids() 351 { 352 return ordering.elements(); 353 } 354 355 /** 356 * return the extension represented by the object identifier 357 * passed in. 358 * 359 * @return the extension if it's present, null otherwise. 360 */ 361 public X509Extension getExtension( 362 ASN1ObjectIdentifier oid) 363 { 364 return (X509Extension)extensions.get(oid); 365 } 366 367 /** 368 * @deprecated 369 * @param oid 370 * @return 371 */ 372 public X509Extension getExtension( 373 DERObjectIdentifier oid) 374 { 375 return (X509Extension)extensions.get(oid); 376 } 377 378 /** 379 * <pre> 380 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 381 * 382 * Extension ::= SEQUENCE { 383 * extnId EXTENSION.&id ({ExtensionSet}), 384 * critical BOOLEAN DEFAULT FALSE, 385 * extnValue OCTET STRING } 386 * </pre> 387 */ 388 public DERObject toASN1Object() 389 { 390 ASN1EncodableVector vec = new ASN1EncodableVector(); 391 Enumeration e = ordering.elements(); 392 393 while (e.hasMoreElements()) 394 { 395 ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 396 X509Extension ext = (X509Extension)extensions.get(oid); 397 ASN1EncodableVector v = new ASN1EncodableVector(); 398 399 v.add(oid); 400 401 if (ext.isCritical()) 402 { 403 // BEGIN android-changed 404 v.add(DERBoolean.TRUE); 405 // END android-changed 406 } 407 408 v.add(ext.getValue()); 409 410 vec.add(new DERSequence(v)); 411 } 412 413 return new DERSequence(vec); 414 } 415 416 public boolean equivalent( 417 X509Extensions other) 418 { 419 if (extensions.size() != other.extensions.size()) 420 { 421 return false; 422 } 423 424 Enumeration e1 = extensions.keys(); 425 426 while (e1.hasMoreElements()) 427 { 428 Object key = e1.nextElement(); 429 430 if (!extensions.get(key).equals(other.extensions.get(key))) 431 { 432 return false; 433 } 434 } 435 436 return true; 437 } 438 439 public ASN1ObjectIdentifier[] getExtensionOIDs() 440 { 441 return toOidArray(ordering); 442 } 443 444 public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs() 445 { 446 return getExtensionOIDs(false); 447 } 448 449 public ASN1ObjectIdentifier[] getCriticalExtensionOIDs() 450 { 451 return getExtensionOIDs(true); 452 } 453 454 private ASN1ObjectIdentifier[] getExtensionOIDs(boolean isCritical) 455 { 456 Vector oidVec = new Vector(); 457 458 for (int i = 0; i != ordering.size(); i++) 459 { 460 Object oid = ordering.elementAt(i); 461 462 if (((X509Extension)extensions.get(oid)).isCritical() == isCritical) 463 { 464 oidVec.addElement(oid); 465 } 466 } 467 468 return toOidArray(oidVec); 469 } 470 471 private ASN1ObjectIdentifier[] toOidArray(Vector oidVec) 472 { 473 ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[oidVec.size()]; 474 475 for (int i = 0; i != oids.length; i++) 476 { 477 oids[i] = (ASN1ObjectIdentifier)oidVec.elementAt(i); 478 } 479 return oids; 480 } 481 } 482