001 /** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package org.apache.geronimo.util.asn1.x509; 020 021 import java.util.Enumeration; 022 import java.util.Hashtable; 023 import java.util.Vector; 024 025 import org.apache.geronimo.util.asn1.ASN1Encodable; 026 import org.apache.geronimo.util.asn1.ASN1EncodableVector; 027 import org.apache.geronimo.util.asn1.ASN1OctetString; 028 import org.apache.geronimo.util.asn1.ASN1Sequence; 029 import org.apache.geronimo.util.asn1.ASN1TaggedObject; 030 import org.apache.geronimo.util.asn1.DERBoolean; 031 import org.apache.geronimo.util.asn1.DERObject; 032 import org.apache.geronimo.util.asn1.DERObjectIdentifier; 033 import org.apache.geronimo.util.asn1.DERSequence; 034 035 public class X509Extensions 036 extends ASN1Encodable 037 { 038 /** 039 * Subject Directory Attributes 040 */ 041 public static final DERObjectIdentifier SubjectDirectoryAttributes = new DERObjectIdentifier("2.5.29.9"); 042 043 /** 044 * Subject Key Identifier 045 */ 046 public static final DERObjectIdentifier SubjectKeyIdentifier = new DERObjectIdentifier("2.5.29.14"); 047 048 /** 049 * Key Usage 050 */ 051 public static final DERObjectIdentifier KeyUsage = new DERObjectIdentifier("2.5.29.15"); 052 053 /** 054 * Private Key Usage Period 055 */ 056 public static final DERObjectIdentifier PrivateKeyUsagePeriod = new DERObjectIdentifier("2.5.29.16"); 057 058 /** 059 * Subject Alternative Name 060 */ 061 public static final DERObjectIdentifier SubjectAlternativeName = new DERObjectIdentifier("2.5.29.17"); 062 063 /** 064 * Issuer Alternative Name 065 */ 066 public static final DERObjectIdentifier IssuerAlternativeName = new DERObjectIdentifier("2.5.29.18"); 067 068 /** 069 * Basic Constraints 070 */ 071 public static final DERObjectIdentifier BasicConstraints = new DERObjectIdentifier("2.5.29.19"); 072 073 /** 074 * CRL Number 075 */ 076 public static final DERObjectIdentifier CRLNumber = new DERObjectIdentifier("2.5.29.20"); 077 078 /** 079 * Reason code 080 */ 081 public static final DERObjectIdentifier ReasonCode = new DERObjectIdentifier("2.5.29.21"); 082 083 /** 084 * Hold Instruction Code 085 */ 086 public static final DERObjectIdentifier InstructionCode = new DERObjectIdentifier("2.5.29.23"); 087 088 /** 089 * Invalidity Date 090 */ 091 public static final DERObjectIdentifier InvalidityDate = new DERObjectIdentifier("2.5.29.24"); 092 093 /** 094 * Delta CRL indicator 095 */ 096 public static final DERObjectIdentifier DeltaCRLIndicator = new DERObjectIdentifier("2.5.29.27"); 097 098 /** 099 * Issuing Distribution Point 100 */ 101 public static final DERObjectIdentifier IssuingDistributionPoint = new DERObjectIdentifier("2.5.29.28"); 102 103 /** 104 * Certificate Issuer 105 */ 106 public static final DERObjectIdentifier CertificateIssuer = new DERObjectIdentifier("2.5.29.29"); 107 108 /** 109 * Name Constraints 110 */ 111 public static final DERObjectIdentifier NameConstraints = new DERObjectIdentifier("2.5.29.30"); 112 113 /** 114 * CRL Distribution Points 115 */ 116 public static final DERObjectIdentifier CRLDistributionPoints = new DERObjectIdentifier("2.5.29.31"); 117 118 /** 119 * Certificate Policies 120 */ 121 public static final DERObjectIdentifier CertificatePolicies = new DERObjectIdentifier("2.5.29.32"); 122 123 /** 124 * Policy Mappings 125 */ 126 public static final DERObjectIdentifier PolicyMappings = new DERObjectIdentifier("2.5.29.33"); 127 128 /** 129 * Authority Key Identifier 130 */ 131 public static final DERObjectIdentifier AuthorityKeyIdentifier = new DERObjectIdentifier("2.5.29.35"); 132 133 /** 134 * Policy Constraints 135 */ 136 public static final DERObjectIdentifier PolicyConstraints = new DERObjectIdentifier("2.5.29.36"); 137 138 /** 139 * Extended Key Usage 140 */ 141 public static final DERObjectIdentifier ExtendedKeyUsage = new DERObjectIdentifier("2.5.29.37"); 142 143 /** 144 * Freshest CRL 145 */ 146 public static final DERObjectIdentifier FreshestCRL = new DERObjectIdentifier("2.5.29.46"); 147 148 /** 149 * Inhibit Any Policy 150 */ 151 public static final DERObjectIdentifier InhibitAnyPolicy = new DERObjectIdentifier("2.5.29.54"); 152 153 /** 154 * Authority Info Access 155 */ 156 public static final DERObjectIdentifier AuthorityInfoAccess= new DERObjectIdentifier("1.3.6.1.5.5.7.1.1"); 157 158 /** 159 * Subject Info Access 160 */ 161 public static final DERObjectIdentifier SubjectInfoAccess= new DERObjectIdentifier("1.3.6.1.5.5.7.1.11"); 162 163 private Hashtable extensions = new Hashtable(); 164 private Vector ordering = new Vector(); 165 166 public static X509Extensions getInstance( 167 ASN1TaggedObject obj, 168 boolean explicit) 169 { 170 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 171 } 172 173 public static X509Extensions getInstance( 174 Object obj) 175 { 176 if (obj == null || obj instanceof X509Extensions) 177 { 178 return (X509Extensions)obj; 179 } 180 181 if (obj instanceof ASN1Sequence) 182 { 183 return new X509Extensions((ASN1Sequence)obj); 184 } 185 186 if (obj instanceof ASN1TaggedObject) 187 { 188 return getInstance(((ASN1TaggedObject)obj).getObject()); 189 } 190 191 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 192 } 193 194 /** 195 * Constructor from ASN1Sequence. 196 * 197 * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString) 198 */ 199 public X509Extensions( 200 ASN1Sequence seq) 201 { 202 Enumeration e = seq.getObjects(); 203 204 while (e.hasMoreElements()) 205 { 206 ASN1Sequence s = (ASN1Sequence)e.nextElement(); 207 208 if (s.size() == 3) 209 { 210 extensions.put(s.getObjectAt(0), new X509Extension((DERBoolean)s.getObjectAt(1), (ASN1OctetString)s.getObjectAt(2))); 211 } 212 else 213 { 214 extensions.put(s.getObjectAt(0), new X509Extension(false, (ASN1OctetString)s.getObjectAt(1))); 215 } 216 217 ordering.addElement(s.getObjectAt(0)); 218 } 219 } 220 221 /** 222 * constructor from a table of extensions. 223 * <p> 224 * it's is assumed the table contains OID/String pairs. 225 */ 226 public X509Extensions( 227 Hashtable extensions) 228 { 229 this(null, extensions); 230 } 231 232 /** 233 * Constructor from a table of extensions with ordering. 234 * <p> 235 * It's is assumed the table contains OID/String pairs. 236 */ 237 public X509Extensions( 238 Vector ordering, 239 Hashtable extensions) 240 { 241 Enumeration e; 242 243 if (ordering == null) 244 { 245 e = extensions.keys(); 246 } 247 else 248 { 249 e = ordering.elements(); 250 } 251 252 while (e.hasMoreElements()) 253 { 254 this.ordering.addElement(e.nextElement()); 255 } 256 257 e = this.ordering.elements(); 258 259 while (e.hasMoreElements()) 260 { 261 DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); 262 X509Extension ext = (X509Extension)extensions.get(oid); 263 264 this.extensions.put(oid, ext); 265 } 266 } 267 268 /** 269 * Constructor from two vectors 270 * 271 * @param objectIDs a vector of the object identifiers. 272 * @param values a vector of the extension values. 273 */ 274 public X509Extensions( 275 Vector objectIDs, 276 Vector values) 277 { 278 Enumeration e = objectIDs.elements(); 279 280 while (e.hasMoreElements()) 281 { 282 this.ordering.addElement(e.nextElement()); 283 } 284 285 int count = 0; 286 287 e = this.ordering.elements(); 288 289 while (e.hasMoreElements()) 290 { 291 DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); 292 X509Extension ext = (X509Extension)values.elementAt(count); 293 294 this.extensions.put(oid, ext); 295 count++; 296 } 297 } 298 299 /** 300 * return an Enumeration of the extension field's object ids. 301 */ 302 public Enumeration oids() 303 { 304 return ordering.elements(); 305 } 306 307 /** 308 * return the extension represented by the object identifier 309 * passed in. 310 * 311 * @return the extension if it's present, null otherwise. 312 */ 313 public X509Extension getExtension( 314 DERObjectIdentifier oid) 315 { 316 return (X509Extension)extensions.get(oid); 317 } 318 319 /** 320 * <pre> 321 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 322 * 323 * Extension ::= SEQUENCE { 324 * extnId EXTENSION.&id ({ExtensionSet}), 325 * critical BOOLEAN DEFAULT FALSE, 326 * extnValue OCTET STRING } 327 * </pre> 328 */ 329 public DERObject toASN1Object() 330 { 331 ASN1EncodableVector vec = new ASN1EncodableVector(); 332 Enumeration e = ordering.elements(); 333 334 while (e.hasMoreElements()) 335 { 336 DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement(); 337 X509Extension ext = (X509Extension)extensions.get(oid); 338 ASN1EncodableVector v = new ASN1EncodableVector(); 339 340 v.add(oid); 341 342 if (ext.isCritical()) 343 { 344 v.add(new DERBoolean(true)); 345 } 346 347 v.add(ext.getValue()); 348 349 vec.add(new DERSequence(v)); 350 } 351 352 return new DERSequence(vec); 353 } 354 355 public int hashCode() 356 { 357 Enumeration e = extensions.keys(); 358 int hashCode = 0; 359 360 while (e.hasMoreElements()) 361 { 362 Object o = e.nextElement(); 363 364 hashCode ^= o.hashCode(); 365 hashCode ^= extensions.get(o).hashCode(); 366 } 367 368 return hashCode; 369 } 370 371 public boolean equals( 372 Object o) 373 { 374 if (o == null || !(o instanceof X509Extensions)) 375 { 376 return false; 377 } 378 379 X509Extensions other = (X509Extensions)o; 380 381 Enumeration e1 = extensions.keys(); 382 Enumeration e2 = other.extensions.keys(); 383 384 while (e1.hasMoreElements() && e2.hasMoreElements()) 385 { 386 Object o1 = e1.nextElement(); 387 Object o2 = e2.nextElement(); 388 389 if (!o1.equals(o2)) 390 { 391 return false; 392 } 393 } 394 395 if (e1.hasMoreElements() || e2.hasMoreElements()) 396 { 397 return false; 398 } 399 400 return true; 401 } 402 }