1 package org.bouncycastle.asn1.x509; 2 3 import java.io.IOException; 4 5 import org.bouncycastle.asn1.ASN1Boolean; 6 import org.bouncycastle.asn1.ASN1Encodable; 7 import org.bouncycastle.asn1.ASN1EncodableVector; 8 import org.bouncycastle.asn1.ASN1Object; 9 import org.bouncycastle.asn1.ASN1ObjectIdentifier; 10 import org.bouncycastle.asn1.ASN1OctetString; 11 import org.bouncycastle.asn1.ASN1Primitive; 12 import org.bouncycastle.asn1.ASN1Sequence; 13 import org.bouncycastle.asn1.DEROctetString; 14 import org.bouncycastle.asn1.DERSequence; 15 16 /** 17 * an object for the elements in the X.509 V3 extension block. 18 */ 19 public class Extension 20 extends ASN1Object 21 { 22 /** 23 * Subject Directory Attributes 24 */ 25 public static final ASN1ObjectIdentifier subjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9").intern(); 26 27 /** 28 * Subject Key Identifier 29 */ 30 public static final ASN1ObjectIdentifier subjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14").intern(); 31 32 /** 33 * Key Usage 34 */ 35 public static final ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier("2.5.29.15").intern(); 36 37 /** 38 * Private Key Usage Period 39 */ 40 public static final ASN1ObjectIdentifier privateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16").intern(); 41 42 /** 43 * Subject Alternative Name 44 */ 45 public static final ASN1ObjectIdentifier subjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17").intern(); 46 47 /** 48 * Issuer Alternative Name 49 */ 50 public static final ASN1ObjectIdentifier issuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18").intern(); 51 52 /** 53 * Basic Constraints 54 */ 55 public static final ASN1ObjectIdentifier basicConstraints = new ASN1ObjectIdentifier("2.5.29.19").intern(); 56 57 /** 58 * CRL Number 59 */ 60 public static final ASN1ObjectIdentifier cRLNumber = new ASN1ObjectIdentifier("2.5.29.20").intern(); 61 62 /** 63 * Reason code 64 */ 65 public static final ASN1ObjectIdentifier reasonCode = new ASN1ObjectIdentifier("2.5.29.21").intern(); 66 67 /** 68 * Hold Instruction Code 69 */ 70 public static final ASN1ObjectIdentifier instructionCode = new ASN1ObjectIdentifier("2.5.29.23").intern(); 71 72 /** 73 * Invalidity Date 74 */ 75 public static final ASN1ObjectIdentifier invalidityDate = new ASN1ObjectIdentifier("2.5.29.24").intern(); 76 77 /** 78 * Delta CRL indicator 79 */ 80 public static final ASN1ObjectIdentifier deltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27").intern(); 81 82 /** 83 * Issuing Distribution Point 84 */ 85 public static final ASN1ObjectIdentifier issuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28").intern(); 86 87 /** 88 * Certificate Issuer 89 */ 90 public static final ASN1ObjectIdentifier certificateIssuer = new ASN1ObjectIdentifier("2.5.29.29").intern(); 91 92 /** 93 * Name Constraints 94 */ 95 public static final ASN1ObjectIdentifier nameConstraints = new ASN1ObjectIdentifier("2.5.29.30").intern(); 96 97 /** 98 * CRL Distribution Points 99 */ 100 public static final ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31").intern(); 101 102 /** 103 * Certificate Policies 104 */ 105 public static final ASN1ObjectIdentifier certificatePolicies = new ASN1ObjectIdentifier("2.5.29.32").intern(); 106 107 /** 108 * Policy Mappings 109 */ 110 public static final ASN1ObjectIdentifier policyMappings = new ASN1ObjectIdentifier("2.5.29.33").intern(); 111 112 /** 113 * Authority Key Identifier 114 */ 115 public static final ASN1ObjectIdentifier authorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35").intern(); 116 117 /** 118 * Policy Constraints 119 */ 120 public static final ASN1ObjectIdentifier policyConstraints = new ASN1ObjectIdentifier("2.5.29.36").intern(); 121 122 /** 123 * Extended Key Usage 124 */ 125 public static final ASN1ObjectIdentifier extendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37").intern(); 126 127 /** 128 * Freshest CRL 129 */ 130 public static final ASN1ObjectIdentifier freshestCRL = new ASN1ObjectIdentifier("2.5.29.46").intern(); 131 132 /** 133 * Inhibit Any Policy 134 */ 135 public static final ASN1ObjectIdentifier inhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54").intern(); 136 137 /** 138 * Authority Info Access 139 */ 140 public static final ASN1ObjectIdentifier authorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1").intern(); 141 142 /** 143 * Subject Info Access 144 */ 145 public static final ASN1ObjectIdentifier subjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11").intern(); 146 147 /** 148 * Logo Type 149 */ 150 public static final ASN1ObjectIdentifier logoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12").intern(); 151 152 /** 153 * BiometricInfo 154 */ 155 public static final ASN1ObjectIdentifier biometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2").intern(); 156 157 /** 158 * QCStatements 159 */ 160 public static final ASN1ObjectIdentifier qCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3").intern(); 161 162 /** 163 * Audit identity extension in attribute certificates. 164 */ 165 public static final ASN1ObjectIdentifier auditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4").intern(); 166 167 /** 168 * NoRevAvail extension in attribute certificates. 169 */ 170 public static final ASN1ObjectIdentifier noRevAvail = new ASN1ObjectIdentifier("2.5.29.56").intern(); 171 172 /** 173 * TargetInformation extension in attribute certificates. 174 */ 175 public static final ASN1ObjectIdentifier targetInformation = new ASN1ObjectIdentifier("2.5.29.55").intern(); 176 177 /** 178 * Expired Certificates on CRL extension 179 */ 180 public static final ASN1ObjectIdentifier expiredCertsOnCRL = new ASN1ObjectIdentifier("2.5.29.60").intern(); 181 182 private ASN1ObjectIdentifier extnId; 183 private boolean critical; 184 private ASN1OctetString value; 185 Extension( ASN1ObjectIdentifier extnId, ASN1Boolean critical, ASN1OctetString value)186 public Extension( 187 ASN1ObjectIdentifier extnId, 188 ASN1Boolean critical, 189 ASN1OctetString value) 190 { 191 this(extnId, critical.isTrue(), value); 192 } 193 Extension( ASN1ObjectIdentifier extnId, boolean critical, byte[] value)194 public Extension( 195 ASN1ObjectIdentifier extnId, 196 boolean critical, 197 byte[] value) 198 { 199 this(extnId, critical, new DEROctetString(value)); 200 } 201 Extension( ASN1ObjectIdentifier extnId, boolean critical, ASN1OctetString value)202 public Extension( 203 ASN1ObjectIdentifier extnId, 204 boolean critical, 205 ASN1OctetString value) 206 { 207 this.extnId = extnId; 208 this.critical = critical; 209 this.value = value; 210 } 211 Extension(ASN1Sequence seq)212 private Extension(ASN1Sequence seq) 213 { 214 if (seq.size() == 2) 215 { 216 this.extnId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); 217 this.critical = false; 218 this.value = ASN1OctetString.getInstance(seq.getObjectAt(1)); 219 } 220 else if (seq.size() == 3) 221 { 222 this.extnId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); 223 this.critical = ASN1Boolean.getInstance(seq.getObjectAt(1)).isTrue(); 224 this.value = ASN1OctetString.getInstance(seq.getObjectAt(2)); 225 } 226 else 227 { 228 throw new IllegalArgumentException("Bad sequence size: " + seq.size()); 229 } 230 } 231 getInstance(Object obj)232 public static Extension getInstance(Object obj) 233 { 234 if (obj instanceof Extension) 235 { 236 return (Extension)obj; 237 } 238 else if (obj != null) 239 { 240 return new Extension(ASN1Sequence.getInstance(obj)); 241 } 242 243 return null; 244 } 245 getExtnId()246 public ASN1ObjectIdentifier getExtnId() 247 { 248 return extnId; 249 } 250 isCritical()251 public boolean isCritical() 252 { 253 return critical; 254 } 255 getExtnValue()256 public ASN1OctetString getExtnValue() 257 { 258 return value; 259 } 260 getParsedValue()261 public ASN1Encodable getParsedValue() 262 { 263 return convertValueToObject(this); 264 } 265 hashCode()266 public int hashCode() 267 { 268 if (this.isCritical()) 269 { 270 return this.getExtnValue().hashCode() ^ this.getExtnId().hashCode(); 271 } 272 273 return ~(this.getExtnValue().hashCode() ^ this.getExtnId().hashCode()); 274 } 275 equals( Object o)276 public boolean equals( 277 Object o) 278 { 279 if (!(o instanceof Extension)) 280 { 281 return false; 282 } 283 284 Extension other = (Extension)o; 285 286 return other.getExtnId().equals(this.getExtnId()) 287 && other.getExtnValue().equals(this.getExtnValue()) 288 && (other.isCritical() == this.isCritical()); 289 } 290 toASN1Primitive()291 public ASN1Primitive toASN1Primitive() 292 { 293 ASN1EncodableVector v = new ASN1EncodableVector(); 294 295 v.add(extnId); 296 297 if (critical) 298 { 299 v.add(ASN1Boolean.getInstance(true)); 300 } 301 302 v.add(value); 303 304 return new DERSequence(v); 305 } 306 307 /** 308 * Convert the value of the passed in extension to an object 309 * @param ext the extension to parse 310 * @return the object the value string contains 311 * @exception IllegalArgumentException if conversion is not possible 312 */ convertValueToObject( Extension ext)313 private static ASN1Primitive convertValueToObject( 314 Extension ext) 315 throws IllegalArgumentException 316 { 317 try 318 { 319 return ASN1Primitive.fromByteArray(ext.getExtnValue().getOctets()); 320 } 321 catch (IOException e) 322 { 323 throw new IllegalArgumentException("can't convert extension: " + e); 324 } 325 } 326 } 327