1 package org.bouncycastle.x509; 2 3 import java.io.IOException; 4 import java.math.BigInteger; 5 import java.security.cert.CertificateExpiredException; 6 import java.security.cert.CertificateNotYetValidException; 7 import java.util.Collection; 8 import java.util.Collections; 9 import java.util.Date; 10 import java.util.HashSet; 11 import java.util.Iterator; 12 import java.util.Set; 13 14 import org.bouncycastle.asn1.ASN1InputStream; 15 import org.bouncycastle.asn1.ASN1Primitive; 16 import org.bouncycastle.asn1.DEROctetString; 17 import org.bouncycastle.asn1.x509.Extension; 18 import org.bouncycastle.asn1.x509.GeneralName; 19 import org.bouncycastle.asn1.x509.Target; 20 import org.bouncycastle.asn1.x509.TargetInformation; 21 import org.bouncycastle.asn1.x509.Targets; 22 import org.bouncycastle.util.Selector; 23 24 /** 25 * This class is an <code>Selector</code> like implementation to select 26 * attribute certificates from a given set of criteria. 27 * 28 * @see org.bouncycastle.x509.X509AttributeCertificate 29 * @see org.bouncycastle.x509.X509Store 30 * @deprecated use org.bouncycastle.cert.X509AttributeCertificateSelector and org.bouncycastle.cert.X509AttributeCertificateSelectorBuilder. 31 */ 32 public class X509AttributeCertStoreSelector 33 implements Selector 34 { 35 36 // TODO: name constraints??? 37 38 private AttributeCertificateHolder holder; 39 40 private AttributeCertificateIssuer issuer; 41 42 private BigInteger serialNumber; 43 44 private Date attributeCertificateValid; 45 46 private X509AttributeCertificate attributeCert; 47 48 private Collection targetNames = new HashSet(); 49 50 private Collection targetGroups = new HashSet(); 51 X509AttributeCertStoreSelector()52 public X509AttributeCertStoreSelector() 53 { 54 super(); 55 } 56 57 /** 58 * Decides if the given attribute certificate should be selected. 59 * 60 * @param obj The attribute certificate which should be checked. 61 * @return <code>true</code> if the attribute certificate can be selected, 62 * <code>false</code> otherwise. 63 */ match(Object obj)64 public boolean match(Object obj) 65 { 66 if (!(obj instanceof X509AttributeCertificate)) 67 { 68 return false; 69 } 70 71 X509AttributeCertificate attrCert = (X509AttributeCertificate) obj; 72 73 if (this.attributeCert != null) 74 { 75 if (!this.attributeCert.equals(attrCert)) 76 { 77 return false; 78 } 79 } 80 if (serialNumber != null) 81 { 82 if (!attrCert.getSerialNumber().equals(serialNumber)) 83 { 84 return false; 85 } 86 } 87 if (holder != null) 88 { 89 if (!attrCert.getHolder().equals(holder)) 90 { 91 return false; 92 } 93 } 94 if (issuer != null) 95 { 96 if (!attrCert.getIssuer().equals(issuer)) 97 { 98 return false; 99 } 100 } 101 102 if (attributeCertificateValid != null) 103 { 104 try 105 { 106 attrCert.checkValidity(attributeCertificateValid); 107 } 108 catch (CertificateExpiredException e) 109 { 110 return false; 111 } 112 catch (CertificateNotYetValidException e) 113 { 114 return false; 115 } 116 } 117 if (!targetNames.isEmpty() || !targetGroups.isEmpty()) 118 { 119 120 byte[] targetInfoExt = attrCert 121 .getExtensionValue(Extension.targetInformation.getId()); 122 if (targetInfoExt != null) 123 { 124 TargetInformation targetinfo; 125 try 126 { 127 targetinfo = TargetInformation 128 .getInstance(new ASN1InputStream( 129 ((DEROctetString) DEROctetString 130 .fromByteArray(targetInfoExt)).getOctets()) 131 .readObject()); 132 } 133 catch (IOException e) 134 { 135 return false; 136 } 137 catch (IllegalArgumentException e) 138 { 139 return false; 140 } 141 Targets[] targetss = targetinfo.getTargetsObjects(); 142 if (!targetNames.isEmpty()) 143 { 144 boolean found = false; 145 146 for (int i=0; i<targetss.length; i++) 147 { 148 Targets t = targetss[i]; 149 Target[] targets = t.getTargets(); 150 for (int j=0; j<targets.length; j++) 151 { 152 if (targetNames.contains(GeneralName.getInstance(targets[j] 153 .getTargetName()))) 154 { 155 found = true; 156 break; 157 } 158 } 159 } 160 if (!found) 161 { 162 return false; 163 } 164 } 165 if (!targetGroups.isEmpty()) 166 { 167 boolean found = false; 168 169 for (int i=0; i<targetss.length; i++) 170 { 171 Targets t = targetss[i]; 172 Target[] targets = t.getTargets(); 173 for (int j=0; j<targets.length; j++) 174 { 175 if (targetGroups.contains(GeneralName.getInstance(targets[j] 176 .getTargetGroup()))) 177 { 178 found = true; 179 break; 180 } 181 } 182 } 183 if (!found) 184 { 185 return false; 186 } 187 } 188 } 189 } 190 return true; 191 } 192 193 /** 194 * Returns a clone of this object. 195 * 196 * @return the clone. 197 */ clone()198 public Object clone() 199 { 200 X509AttributeCertStoreSelector sel = new X509AttributeCertStoreSelector(); 201 sel.attributeCert = attributeCert; 202 sel.attributeCertificateValid = getAttributeCertificateValid(); 203 sel.holder = holder; 204 sel.issuer = issuer; 205 sel.serialNumber = serialNumber; 206 sel.targetGroups = getTargetGroups(); 207 sel.targetNames = getTargetNames(); 208 return sel; 209 } 210 211 /** 212 * Returns the attribute certificate which must be matched. 213 * 214 * @return Returns the attribute certificate. 215 */ getAttributeCert()216 public X509AttributeCertificate getAttributeCert() 217 { 218 return attributeCert; 219 } 220 221 /** 222 * Set the attribute certificate to be matched. If <code>null</code> is 223 * given any will do. 224 * 225 * @param attributeCert The attribute certificate to set. 226 */ setAttributeCert(X509AttributeCertificate attributeCert)227 public void setAttributeCert(X509AttributeCertificate attributeCert) 228 { 229 this.attributeCert = attributeCert; 230 } 231 232 /** 233 * Get the criteria for the validity. 234 * 235 * @return Returns the attributeCertificateValid. 236 */ getAttributeCertificateValid()237 public Date getAttributeCertificateValid() 238 { 239 if (attributeCertificateValid != null) 240 { 241 return new Date(attributeCertificateValid.getTime()); 242 } 243 244 return null; 245 } 246 247 /** 248 * Set the time, when the certificate must be valid. If <code>null</code> 249 * is given any will do. 250 * 251 * @param attributeCertificateValid The attribute certificate validation 252 * time to set. 253 */ setAttributeCertificateValid(Date attributeCertificateValid)254 public void setAttributeCertificateValid(Date attributeCertificateValid) 255 { 256 if (attributeCertificateValid != null) 257 { 258 this.attributeCertificateValid = new Date(attributeCertificateValid 259 .getTime()); 260 } 261 else 262 { 263 this.attributeCertificateValid = null; 264 } 265 } 266 267 /** 268 * Gets the holder. 269 * 270 * @return Returns the holder. 271 */ getHolder()272 public AttributeCertificateHolder getHolder() 273 { 274 return holder; 275 } 276 277 /** 278 * Sets the holder. If <code>null</code> is given any will do. 279 * 280 * @param holder The holder to set. 281 */ setHolder(AttributeCertificateHolder holder)282 public void setHolder(AttributeCertificateHolder holder) 283 { 284 this.holder = holder; 285 } 286 287 /** 288 * Returns the issuer criterion. 289 * 290 * @return Returns the issuer. 291 */ getIssuer()292 public AttributeCertificateIssuer getIssuer() 293 { 294 return issuer; 295 } 296 297 /** 298 * Sets the issuer the attribute certificate must have. If <code>null</code> 299 * is given any will do. 300 * 301 * @param issuer The issuer to set. 302 */ setIssuer(AttributeCertificateIssuer issuer)303 public void setIssuer(AttributeCertificateIssuer issuer) 304 { 305 this.issuer = issuer; 306 } 307 308 /** 309 * Gets the serial number the attribute certificate must have. 310 * 311 * @return Returns the serialNumber. 312 */ getSerialNumber()313 public BigInteger getSerialNumber() 314 { 315 return serialNumber; 316 } 317 318 /** 319 * Sets the serial number the attribute certificate must have. If 320 * <code>null</code> is given any will do. 321 * 322 * @param serialNumber The serialNumber to set. 323 */ setSerialNumber(BigInteger serialNumber)324 public void setSerialNumber(BigInteger serialNumber) 325 { 326 this.serialNumber = serialNumber; 327 } 328 329 /** 330 * Adds a target name criterion for the attribute certificate to the target 331 * information extension criteria. The <code>X509AttributeCertificate</code> 332 * must contain at least one of the specified target names. 333 * <p> 334 * Each attribute certificate may contain a target information extension 335 * limiting the servers where this attribute certificate can be used. If 336 * this extension is not present, the attribute certificate is not targeted 337 * and may be accepted by any server. 338 * 339 * @param name The name as a GeneralName (not <code>null</code>) 340 */ addTargetName(GeneralName name)341 public void addTargetName(GeneralName name) 342 { 343 targetNames.add(name); 344 } 345 346 /** 347 * Adds a target name criterion for the attribute certificate to the target 348 * information extension criteria. The <code>X509AttributeCertificate</code> 349 * must contain at least one of the specified target names. 350 * <p> 351 * Each attribute certificate may contain a target information extension 352 * limiting the servers where this attribute certificate can be used. If 353 * this extension is not present, the attribute certificate is not targeted 354 * and may be accepted by any server. 355 * 356 * @param name a byte array containing the name in ASN.1 DER encoded form of a GeneralName 357 * @throws IOException if a parsing error occurs. 358 */ addTargetName(byte[] name)359 public void addTargetName(byte[] name) throws IOException 360 { 361 addTargetName(GeneralName.getInstance(ASN1Primitive.fromByteArray(name))); 362 } 363 364 /** 365 * Adds a collection with target names criteria. If <code>null</code> is 366 * given any will do. 367 * <p> 368 * The collection consists of either GeneralName objects or byte[] arrays representing 369 * DER encoded GeneralName structures. 370 * 371 * @param names A collection of target names. 372 * @throws IOException if a parsing error occurs. 373 * @see #addTargetName(byte[]) 374 * @see #addTargetName(GeneralName) 375 */ setTargetNames(Collection names)376 public void setTargetNames(Collection names) throws IOException 377 { 378 targetNames = extractGeneralNames(names); 379 } 380 381 /** 382 * Gets the target names. The collection consists of <code>GeneralName</code> 383 * objects. 384 * <p> 385 * The returned collection is immutable. 386 * 387 * @return The collection of target names 388 * @see #setTargetNames(Collection) 389 */ getTargetNames()390 public Collection getTargetNames() 391 { 392 return Collections.unmodifiableCollection(targetNames); 393 } 394 395 /** 396 * Adds a target group criterion for the attribute certificate to the target 397 * information extension criteria. The <code>X509AttributeCertificate</code> 398 * must contain at least one of the specified target groups. 399 * <p> 400 * Each attribute certificate may contain a target information extension 401 * limiting the servers where this attribute certificate can be used. If 402 * this extension is not present, the attribute certificate is not targeted 403 * and may be accepted by any server. 404 * 405 * @param group The group as GeneralName form (not <code>null</code>) 406 */ addTargetGroup(GeneralName group)407 public void addTargetGroup(GeneralName group) 408 { 409 targetGroups.add(group); 410 } 411 412 /** 413 * Adds a target group criterion for the attribute certificate to the target 414 * information extension criteria. The <code>X509AttributeCertificate</code> 415 * must contain at least one of the specified target groups. 416 * <p> 417 * Each attribute certificate may contain a target information extension 418 * limiting the servers where this attribute certificate can be used. If 419 * this extension is not present, the attribute certificate is not targeted 420 * and may be accepted by any server. 421 * 422 * @param name a byte array containing the group in ASN.1 DER encoded form of a GeneralName 423 * @throws IOException if a parsing error occurs. 424 */ addTargetGroup(byte[] name)425 public void addTargetGroup(byte[] name) throws IOException 426 { 427 addTargetGroup(GeneralName.getInstance(ASN1Primitive.fromByteArray(name))); 428 } 429 430 /** 431 * Adds a collection with target groups criteria. If <code>null</code> is 432 * given any will do. 433 * <p> 434 * The collection consists of <code>GeneralName</code> objects or <code>byte[]</code> representing DER 435 * encoded GeneralNames. 436 * 437 * @param names A collection of target groups. 438 * @throws IOException if a parsing error occurs. 439 * @see #addTargetGroup(byte[]) 440 * @see #addTargetGroup(GeneralName) 441 */ setTargetGroups(Collection names)442 public void setTargetGroups(Collection names) throws IOException 443 { 444 targetGroups = extractGeneralNames(names); 445 } 446 447 448 449 /** 450 * Gets the target groups. The collection consists of <code>GeneralName</code> objects. 451 * <p> 452 * The returned collection is immutable. 453 * 454 * @return The collection of target groups. 455 * @see #setTargetGroups(Collection) 456 */ getTargetGroups()457 public Collection getTargetGroups() 458 { 459 return Collections.unmodifiableCollection(targetGroups); 460 } 461 extractGeneralNames(Collection names)462 private Set extractGeneralNames(Collection names) 463 throws IOException 464 { 465 if (names == null || names.isEmpty()) 466 { 467 return new HashSet(); 468 } 469 Set temp = new HashSet(); 470 for (Iterator it = names.iterator(); it.hasNext();) 471 { 472 Object o = it.next(); 473 if (o instanceof GeneralName) 474 { 475 temp.add(o); 476 } 477 else 478 { 479 temp.add(GeneralName.getInstance(ASN1Primitive.fromByteArray((byte[])o))); 480 } 481 } 482 return temp; 483 } 484 } 485