GNU Classpath (0.95) | |
Frames | No Frames |
1: /* X509CRLSelector.java -- selects X.509 CRLs by criteria. 2: Copyright (C) 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.security.cert; 40: 41: import gnu.classpath.SystemProperties; 42: import gnu.java.security.der.DERReader; 43: import gnu.java.security.der.DERValue; 44: 45: import java.io.IOException; 46: import java.io.InputStream; 47: import java.math.BigInteger; 48: import java.util.ArrayList; 49: import java.util.Collection; 50: import java.util.Collections; 51: import java.util.Date; 52: import java.util.Iterator; 53: import java.util.LinkedList; 54: import java.util.List; 55: 56: import javax.security.auth.x500.X500Principal; 57: 58: /** 59: * A class for matching X.509 certificate revocation lists by criteria. 60: * 61: * <p>Use of this class requires extensive knowledge of the Internet 62: * Engineering Task Force's Public Key Infrastructure (X.509). The primary 63: * document describing this standard is <a 64: * href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509 65: * Public Key Infrastructure Certificate and Certificate Revocation List 66: * (CRL) Profile</a>. 67: * 68: * <p>Note that this class is not thread-safe. If multiple threads will 69: * use or modify this class then they need to synchronize on the object. 70: * 71: * @author Casey Marshall (csm@gnu.org) 72: * @since 1.4 73: */ 74: public class X509CRLSelector implements CRLSelector, Cloneable 75: { 76: 77: // Fields. 78: // ------------------------------------------------------------------------- 79: 80: private static final String CRL_NUMBER_ID = "2.5.29.20"; 81: 82: private List issuerNames; 83: private BigInteger maxCrlNumber; 84: private BigInteger minCrlNumber; 85: private Date date; 86: private X509Certificate cert; 87: 88: // Constructor. 89: // ------------------------------------------------------------------------- 90: 91: /** 92: * Creates a new CRL selector with no criteria enabled; i.e., every CRL 93: * will be matched. 94: */ 95: public X509CRLSelector() 96: { 97: } 98: 99: // Instance methods. 100: // ------------------------------------------------------------------------- 101: 102: /** 103: * Add an issuer name to the set of issuer names criteria, as the DER 104: * encoded form. 105: * 106: * @param name The name to add, as DER bytes. 107: * @throws IOException If the argument is not a valid DER-encoding. 108: */ 109: public void addIssuerName(byte[] name) throws IOException 110: { 111: X500Principal p = null; 112: try 113: { 114: p = new X500Principal(name); 115: } 116: catch (IllegalArgumentException iae) 117: { 118: IOException ioe = new IOException("malformed name"); 119: ioe.initCause(iae); 120: throw ioe; 121: } 122: if (issuerNames == null) 123: issuerNames = new LinkedList(); 124: issuerNames.add(p); 125: } 126: 127: /** 128: * Add an issuer name to the set of issuer names criteria, as a 129: * String representation. 130: * 131: * @param name The name to add. 132: * @throws IOException If the argument is not a valid name. 133: */ 134: public void addIssuerName(String name) throws IOException 135: { 136: X500Principal p = null; 137: try 138: { 139: p = new X500Principal(name); 140: } 141: catch (IllegalArgumentException iae) 142: { 143: IOException ioe = new IOException("malformed name: " + name); 144: ioe.initCause(iae); 145: throw ioe; 146: } 147: if (issuerNames == null) 148: issuerNames = new LinkedList(); 149: issuerNames.add(p); 150: } 151: 152: /** 153: * Sets the issuer names criterion. Pass <code>null</code> to clear this 154: * value. CRLs matched by this selector must have an issuer name in this 155: * set. 156: * 157: * @param names The issuer names. 158: * @throws IOException If any of the elements in the collection is not 159: * a valid name. 160: */ 161: public void setIssuerNames(Collection<?> names) throws IOException 162: { 163: if (names == null) 164: { 165: issuerNames = null; 166: return; 167: } 168: List l = new ArrayList(names.size()); 169: for (Iterator it = names.iterator(); it.hasNext(); ) 170: { 171: Object o = it.next(); 172: if (o instanceof X500Principal) 173: l.add(o); 174: else if (o instanceof String) 175: { 176: try 177: { 178: l.add(new X500Principal((String) o)); 179: } 180: catch (IllegalArgumentException iae) 181: { 182: IOException ioe = new IOException("malformed name: " + o); 183: ioe.initCause(iae); 184: throw ioe; 185: } 186: } 187: else if (o instanceof byte[]) 188: { 189: try 190: { 191: l.add(new X500Principal((byte[]) o)); 192: } 193: catch (IllegalArgumentException iae) 194: { 195: IOException ioe = new IOException("malformed name"); 196: ioe.initCause(iae); 197: throw ioe; 198: } 199: } 200: else if (o instanceof InputStream) 201: { 202: try 203: { 204: l.add(new X500Principal((InputStream) o)); 205: } 206: catch (IllegalArgumentException iae) 207: { 208: IOException ioe = new IOException("malformed name"); 209: ioe.initCause(iae); 210: throw ioe; 211: } 212: } 213: else 214: throw new IOException("not a valid name: " + 215: (o != null ? o.getClass().getName() : "null")); 216: 217: } 218: issuerNames = l; 219: } 220: 221: /** 222: * Returns the set of issuer names that are matched by this selector, 223: * or <code>null</code> if this criteria is not set. The returned 224: * collection is not modifiable. 225: * 226: * @return The set of issuer names. 227: */ 228: public Collection<Object> getIssuerNames() 229: { 230: if (issuerNames != null) 231: return Collections.unmodifiableList(issuerNames); 232: else 233: return null; 234: } 235: 236: /** 237: * Returns the maximum value of the CRLNumber extension present in 238: * CRLs matched by this selector, or <code>null</code> if this 239: * criteria is not set. 240: * 241: * @return The maximum CRL number. 242: */ 243: public BigInteger getMaxCRL() 244: { 245: return maxCrlNumber; 246: } 247: 248: /** 249: * Returns the minimum value of the CRLNumber extension present in 250: * CRLs matched by this selector, or <code>null</code> if this 251: * criteria is not set. 252: * 253: * @return The minimum CRL number. 254: */ 255: public BigInteger getMinCRL() 256: { 257: return minCrlNumber; 258: } 259: 260: /** 261: * Sets the maximum value of the CRLNumber extension present in CRLs 262: * matched by this selector. Specify <code>null</code> to clear this 263: * criterion. 264: * 265: * @param maxCrlNumber The maximum CRL number. 266: */ 267: public void setMaxCRLNumber(BigInteger maxCrlNumber) 268: { 269: this.maxCrlNumber = maxCrlNumber; 270: } 271: 272: /** 273: * Sets the minimum value of the CRLNumber extension present in CRLs 274: * matched by this selector. Specify <code>null</code> to clear this 275: * criterion. 276: * 277: * @param minCrlNumber The minimum CRL number. 278: */ 279: public void setMinCRLNumber(BigInteger minCrlNumber) 280: { 281: this.minCrlNumber = minCrlNumber; 282: } 283: 284: /** 285: * Returns the date when this CRL must be valid; that is, the date 286: * must be after the thisUpdate date, but before the nextUpdate date. 287: * Returns <code>null</code> if this criterion is not set. 288: * 289: * @return The date. 290: */ 291: public Date getDateAndTime() 292: { 293: return date != null ? (Date) date.clone() : null; 294: } 295: 296: /** 297: * Sets the date at which this CRL must be valid. Specify 298: * <code>null</code> to clear this criterion. 299: * 300: * @param date The date. 301: */ 302: public void setDateAndTime(Date date) 303: { 304: this.date = date != null ? (Date) date.clone() : null; 305: } 306: 307: /** 308: * Returns the certificate being checked, or <code>null</code> if this 309: * value is not set. 310: * 311: * @return The certificate. 312: */ 313: public X509Certificate getCertificateChecking() 314: { 315: return cert; 316: } 317: 318: /** 319: * Sets the certificate being checked. This is not a criterion, but 320: * info used by certificate store implementations to aid in searching. 321: * 322: * @param cert The certificate. 323: */ 324: public void setCertificateChecking(X509Certificate cert) 325: { 326: this.cert = cert; 327: } 328: 329: /** 330: * Returns a string representation of this selector. The string will 331: * only describe the enabled criteria, so if none are enabled this will 332: * return a string that contains little else besides the class name. 333: * 334: * @return The string. 335: */ 336: public String toString() 337: { 338: StringBuffer str = new StringBuffer(X509CRLSelector.class.getName()); 339: String nl = SystemProperties.getProperty("line.separator"); 340: String eol = ";" + nl; 341: 342: str.append(" {").append(nl); 343: if (issuerNames != null) 344: str.append(" issuer names = ").append(issuerNames).append(eol); 345: if (maxCrlNumber != null) 346: str.append(" max CRL = ").append(maxCrlNumber).append(eol); 347: if (minCrlNumber != null) 348: str.append(" min CRL = ").append(minCrlNumber).append(eol); 349: if (date != null) 350: str.append(" date = ").append(date).append(eol); 351: if (cert != null) 352: str.append(" certificate = ").append(cert).append(eol); 353: str.append("}").append(nl); 354: return str.toString(); 355: } 356: 357: /** 358: * Checks a CRL against the criteria of this selector, returning 359: * <code>true</code> if the given CRL matches all the criteria. 360: * 361: * @param _crl The CRL being checked. 362: * @return True if the CRL matches, false otherwise. 363: */ 364: public boolean match(CRL _crl) 365: { 366: if (!(_crl instanceof X509CRL)) 367: return false; 368: X509CRL crl = (X509CRL) _crl; 369: if (issuerNames != null) 370: { 371: if (!issuerNames.contains(crl.getIssuerX500Principal())) 372: return false; 373: } 374: BigInteger crlNumber = null; 375: if (maxCrlNumber != null) 376: { 377: byte[] b = crl.getExtensionValue(CRL_NUMBER_ID); 378: if (b == null) 379: return false; 380: try 381: { 382: DERValue val = DERReader.read(b); 383: if (!(val.getValue() instanceof BigInteger)) 384: return false; 385: crlNumber = (BigInteger) val.getValue(); 386: } 387: catch (IOException ioe) 388: { 389: return false; 390: } 391: if (maxCrlNumber.compareTo(crlNumber) < 0) 392: return false; 393: } 394: if (minCrlNumber != null) 395: { 396: if (crlNumber == null) 397: { 398: byte[] b = crl.getExtensionValue(CRL_NUMBER_ID); 399: if (b == null) 400: return false; 401: try 402: { 403: DERValue val = DERReader.read(b); 404: if (!(val.getValue() instanceof BigInteger)) 405: return false; 406: crlNumber = (BigInteger) val.getValue(); 407: } 408: catch (IOException ioe) 409: { 410: return false; 411: } 412: } 413: if (minCrlNumber.compareTo(crlNumber) > 0) 414: return false; 415: } 416: if (date != null) 417: { 418: if (date.compareTo(crl.getThisUpdate()) < 0 || 419: date.compareTo(crl.getNextUpdate()) > 0) 420: return false; 421: } 422: return true; 423: } 424: 425: /** 426: * Returns a copy of this object. 427: * 428: * @return The copy. 429: */ 430: public Object clone() 431: { 432: try 433: { 434: return super.clone(); 435: } 436: catch (CloneNotSupportedException shouldNotHappen) 437: { 438: throw new Error(shouldNotHappen); 439: } 440: } 441: }
GNU Classpath (0.95) |