GNU Classpath (0.20) | |
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: */ 73: public class X509CRLSelector implements CRLSelector, Cloneable 74: { 75: 76: // Fields. 77: // ------------------------------------------------------------------------- 78: 79: private static final String CRL_NUMBER_ID = "2.5.29.20"; 80: 81: private List issuerNames; 82: private BigInteger maxCrlNumber; 83: private BigInteger minCrlNumber; 84: private Date date; 85: private X509Certificate cert; 86: 87: // Constructor. 88: // ------------------------------------------------------------------------- 89: 90: /** 91: * Creates a new CRL selector with no criteria enabled; i.e., every CRL 92: * will be matched. 93: */ 94: public X509CRLSelector() 95: { 96: } 97: 98: // Instance methods. 99: // ------------------------------------------------------------------------- 100: 101: /** 102: * Add an issuer name to the set of issuer names criteria, as the DER 103: * encoded form. 104: * 105: * @param name The name to add, as DER bytes. 106: * @throws IOException If the argument is not a valid DER-encoding. 107: */ 108: public void addIssuerName(byte[] name) throws IOException 109: { 110: X500Principal p = null; 111: try 112: { 113: p = new X500Principal(name); 114: } 115: catch (IllegalArgumentException iae) 116: { 117: IOException ioe = new IOException("malformed name"); 118: ioe.initCause(iae); 119: throw ioe; 120: } 121: if (issuerNames == null) 122: issuerNames = new LinkedList(); 123: issuerNames.add(p); 124: } 125: 126: /** 127: * Add an issuer name to the set of issuer names criteria, as a 128: * String representation. 129: * 130: * @param name The name to add. 131: * @throws IOException If the argument is not a valid name. 132: */ 133: public void addIssuerName(String name) throws IOException 134: { 135: X500Principal p = null; 136: try 137: { 138: p = new X500Principal(name); 139: } 140: catch (IllegalArgumentException iae) 141: { 142: IOException ioe = new IOException("malformed name: " + name); 143: ioe.initCause(iae); 144: throw ioe; 145: } 146: if (issuerNames == null) 147: issuerNames = new LinkedList(); 148: issuerNames.add(p); 149: } 150: 151: /** 152: * Sets the issuer names criterion. Pass <code>null</code> to clear this 153: * value. CRLs matched by this selector must have an issuer name in this 154: * set. 155: * 156: * @param names The issuer names. 157: * @throws IOException If any of the elements in the collection is not 158: * a valid name. 159: */ 160: public void setIssuerNames(Collection names) throws IOException 161: { 162: if (names == null) 163: { 164: issuerNames = null; 165: return; 166: } 167: List l = new ArrayList(names.size()); 168: for (Iterator it = names.iterator(); it.hasNext(); ) 169: { 170: Object o = it.next(); 171: if (o instanceof X500Principal) 172: l.add(o); 173: else if (o instanceof String) 174: { 175: try 176: { 177: l.add(new X500Principal((String) o)); 178: } 179: catch (IllegalArgumentException iae) 180: { 181: IOException ioe = new IOException("malformed name: " + o); 182: ioe.initCause(iae); 183: throw ioe; 184: } 185: } 186: else if (o instanceof byte[]) 187: { 188: try 189: { 190: l.add(new X500Principal((byte[]) o)); 191: } 192: catch (IllegalArgumentException iae) 193: { 194: IOException ioe = new IOException("malformed name"); 195: ioe.initCause(iae); 196: throw ioe; 197: } 198: } 199: else if (o instanceof InputStream) 200: { 201: try 202: { 203: l.add(new X500Principal((InputStream) o)); 204: } 205: catch (IllegalArgumentException iae) 206: { 207: IOException ioe = new IOException("malformed name"); 208: ioe.initCause(iae); 209: throw ioe; 210: } 211: } 212: else 213: throw new IOException("not a valid name: " + 214: (o != null ? o.getClass().getName() : "null")); 215: 216: } 217: issuerNames = l; 218: } 219: 220: /** 221: * Returns the set of issuer names that are matched by this selector, 222: * or <code>null</code> if this criteria is not set. The returned 223: * collection is not modifiable. 224: * 225: * @return The set of issuer names. 226: */ 227: public Collection getIssuerNames() 228: { 229: if (issuerNames != null) 230: return Collections.unmodifiableList(issuerNames); 231: else 232: return null; 233: } 234: 235: /** 236: * Returns the maximum value of the CRLNumber extension present in 237: * CRLs matched by this selector, or <code>null</code> if this 238: * criteria is not set. 239: * 240: * @return The maximum CRL number. 241: */ 242: public BigInteger getMaxCRL() 243: { 244: return maxCrlNumber; 245: } 246: 247: /** 248: * Returns the minimum value of the CRLNumber extension present in 249: * CRLs matched by this selector, or <code>null</code> if this 250: * criteria is not set. 251: * 252: * @return The minimum CRL number. 253: */ 254: public BigInteger getMinCRL() 255: { 256: return minCrlNumber; 257: } 258: 259: /** 260: * Sets the maximum value of the CRLNumber extension present in CRLs 261: * matched by this selector. Specify <code>null</code> to clear this 262: * criterion. 263: * 264: * @param maxCrlNumber The maximum CRL number. 265: */ 266: public void setMaxCRLNumber(BigInteger maxCrlNumber) 267: { 268: this.maxCrlNumber = maxCrlNumber; 269: } 270: 271: /** 272: * Sets the minimum value of the CRLNumber extension present in CRLs 273: * matched by this selector. Specify <code>null</code> to clear this 274: * criterion. 275: * 276: * @param minCrlNumber The minimum CRL number. 277: */ 278: public void setMinCRLNumber(BigInteger minCrlNumber) 279: { 280: this.minCrlNumber = minCrlNumber; 281: } 282: 283: /** 284: * Returns the date when this CRL must be valid; that is, the date 285: * must be after the thisUpdate date, but before the nextUpdate date. 286: * Returns <code>null</code> if this criterion is not set. 287: * 288: * @return The date. 289: */ 290: public Date getDateAndTime() 291: { 292: return date != null ? (Date) date.clone() : null; 293: } 294: 295: /** 296: * Sets the date at which this CRL must be valid. Specify 297: * <code>null</code> to clear this criterion. 298: * 299: * @param date The date. 300: */ 301: public void setDateAndTime(Date date) 302: { 303: this.date = date != null ? (Date) date.clone() : null; 304: } 305: 306: /** 307: * Returns the certificate being checked, or <code>null</code> if this 308: * value is not set. 309: * 310: * @return The certificate. 311: */ 312: public X509Certificate getCertificateChecking() 313: { 314: return cert; 315: } 316: 317: /** 318: * Sets the certificate being checked. This is not a criterion, but 319: * info used by certificate store implementations to aid in searching. 320: * 321: * @param cert The certificate. 322: */ 323: public void setCertificateChecking(X509Certificate cert) 324: { 325: this.cert = cert; 326: } 327: 328: /** 329: * Returns a string representation of this selector. The string will 330: * only describe the enabled criteria, so if none are enabled this will 331: * return a string that contains little else besides the class name. 332: * 333: * @return The string. 334: */ 335: public String toString() 336: { 337: StringBuffer str = new StringBuffer(X509CRLSelector.class.getName()); 338: String nl = SystemProperties.getProperty("line.separator"); 339: String eol = ";" + nl; 340: 341: str.append(" {").append(nl); 342: if (issuerNames != null) 343: str.append(" issuer names = ").append(issuerNames).append(eol); 344: if (maxCrlNumber != null) 345: str.append(" max CRL = ").append(maxCrlNumber).append(eol); 346: if (minCrlNumber != null) 347: str.append(" min CRL = ").append(minCrlNumber).append(eol); 348: if (date != null) 349: str.append(" date = ").append(date).append(eol); 350: if (cert != null) 351: str.append(" certificate = ").append(cert).append(eol); 352: str.append("}").append(nl); 353: return str.toString(); 354: } 355: 356: /** 357: * Checks a CRL against the criteria of this selector, returning 358: * <code>true</code> if the given CRL matches all the criteria. 359: * 360: * @param _crl The CRL being checked. 361: * @return True if the CRL matches, false otherwise. 362: */ 363: public boolean match(CRL _crl) 364: { 365: if (!(_crl instanceof X509CRL)) 366: return false; 367: X509CRL crl = (X509CRL) _crl; 368: if (issuerNames != null) 369: { 370: if (!issuerNames.contains(crl.getIssuerX500Principal())) 371: return false; 372: } 373: BigInteger crlNumber = null; 374: if (maxCrlNumber != null) 375: { 376: byte[] b = crl.getExtensionValue(CRL_NUMBER_ID); 377: if (b == null) 378: return false; 379: try 380: { 381: DERValue val = DERReader.read(b); 382: if (!(val.getValue() instanceof BigInteger)) 383: return false; 384: crlNumber = (BigInteger) val.getValue(); 385: } 386: catch (IOException ioe) 387: { 388: return false; 389: } 390: if (maxCrlNumber.compareTo(crlNumber) < 0) 391: return false; 392: } 393: if (minCrlNumber != null) 394: { 395: if (crlNumber == null) 396: { 397: byte[] b = crl.getExtensionValue(CRL_NUMBER_ID); 398: if (b == null) 399: return false; 400: try 401: { 402: DERValue val = DERReader.read(b); 403: if (!(val.getValue() instanceof BigInteger)) 404: return false; 405: crlNumber = (BigInteger) val.getValue(); 406: } 407: catch (IOException ioe) 408: { 409: return false; 410: } 411: } 412: if (minCrlNumber.compareTo(crlNumber) > 0) 413: return false; 414: } 415: if (date != null) 416: { 417: if (date.compareTo(crl.getThisUpdate()) < 0 || 418: date.compareTo(crl.getNextUpdate()) > 0) 419: return false; 420: } 421: return true; 422: } 423: 424: /** 425: * Returns a copy of this object. 426: * 427: * @return The copy. 428: */ 429: public Object clone() 430: { 431: try 432: { 433: return super.clone(); 434: } 435: catch (CloneNotSupportedException shouldNotHappen) 436: { 437: throw new Error(shouldNotHappen); 438: } 439: } 440: }
GNU Classpath (0.20) |