~brian-thomason/+junk/bouncycastle

« back to all changes in this revision

Viewing changes to jdk1.1/java/security/cert/X509CRLSelector.java

  • Committer: Brian Thomason
  • Date: 2011-12-20 17:20:32 UTC
  • Revision ID: brian.thomason@canonical.com-20111220172032-rdtm13jgdxtksacr
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package java.security.cert;
 
2
 
 
3
import java.io.ByteArrayInputStream;
 
4
import java.io.IOException;
 
5
import java.math.BigInteger;
 
6
import java.util.Collection;
 
7
import java.util.Date;
 
8
import java.util.HashSet;
 
9
import java.util.Iterator;
 
10
import java.util.Set;
 
11
 
 
12
import org.bouncycastle.asn1.ASN1InputStream;
 
13
import org.bouncycastle.asn1.ASN1OctetString;
 
14
import org.bouncycastle.asn1.ASN1Sequence;
 
15
import org.bouncycastle.asn1.DERInteger;
 
16
import org.bouncycastle.asn1.DERObject;
 
17
import org.bouncycastle.asn1.x509.X509Extensions;
 
18
import org.bouncycastle.asn1.x509.X509Name;
 
19
import org.bouncycastle.jce.PrincipalUtil;
 
20
 
 
21
/**
 
22
 * A <code>CRLSelector</code> that selects <code>X509CRLs</code> that
 
23
 * match all specified criteria. This class is particularly useful when
 
24
 * selecting CRLs from a <code>CertStore</code> to check revocation status
 
25
 * of a particular certificate.<br />
 
26
 * <br />
 
27
 * When first constructed, an <code>X509CRLSelector</code> has no criteria
 
28
 * enabled and each of the <code>get</code> methods return a default
 
29
 * value (<code>null</code>). Therefore, the {@link #match match} method 
 
30
 * would return <code>true</code> for any <code>X509CRL</code>. Typically, 
 
31
 * several criteria are enabled (by calling {@link #setIssuerNames setIssuerNames} 
 
32
 * or {@link #setDateAndTime setDateAndTime}, for instance) and then the
 
33
 * <code>X509CRLSelector</code> is passed to
 
34
 * {@link CertStore#getCRLs CertStore.getCRLs} or some similar
 
35
 * method.<br />
 
36
 * <br />
 
37
 * Please refer to RFC 2459 for definitions of the X.509 CRL fields and
 
38
 * extensions mentioned below.<br />
 
39
 * <br />
 
40
 * <b>Concurrent Access</b><br />
 
41
 * <br />
 
42
 * Unless otherwise specified, the methods defined in this class are not
 
43
 * thread-safe. Multiple threads that need to access a single
 
44
 * object concurrently should synchronize amongst themselves and
 
45
 * provide the necessary locking. Multiple threads each manipulating
 
46
 * separate objects need not synchronize.<br />
 
47
 * <br />
 
48
 * Uses {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream},
 
49
 * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence},
 
50
 * {@link org.bouncycastle.asn1.DERObjectIdentifier DERObjectIdentifier},
 
51
 * {@link org.bouncycastle.asn1.DEROutputStream DEROutputStream},
 
52
 * {@link org.bouncycastle.asn1.DERObject DERObject},
 
53
 * {@link org.bouncycastle.asn1.x509.X509Name X509Name} and
 
54
 * {@link org.bouncycastle.asn1.util.ASN1Dump#_dumpAsString _dumpAsString}
 
55
 *
 
56
 * @see CRLSelector
 
57
 * @see X509CRL
 
58
 **/
 
59
public class X509CRLSelector implements CRLSelector
 
60
{
 
61
    private Set issuerNames = null;
 
62
    private Set issuerNamesX509 = null;
 
63
    private BigInteger minCRL = null;
 
64
    private BigInteger maxCRL = null;
 
65
    private Date dateAndTime = null;
 
66
    private X509Certificate certChecking = null;
 
67
 
 
68
    /**
 
69
     * Creates an <code>X509CRLSelector</code>. Initially, no criteria are set
 
70
     * so any <code>X509CRL</code> will match.
 
71
     */
 
72
    public X509CRLSelector() {}
 
73
 
 
74
    /**
 
75
     * Sets the issuerNames criterion. The issuer distinguished name in the
 
76
     * <code>X509CRL</code> must match at least one of the specified
 
77
     * distinguished names. If <code>null</code>, any issuer distinguished name
 
78
     * will do.<br />
 
79
     * <br />
 
80
     * This method allows the caller to specify, with a single method call,
 
81
     * the complete set of issuer names which <code>X509CRLs</code> may contain.
 
82
     * The specified value replaces the previous value for the issuerNames
 
83
     * criterion.<br />
 
84
     * <br />
 
85
     * The <code>names</code> parameter (if not <code>null</code>) is a
 
86
     * <code>Collection</code> of names. Each name is a <code>String</code>
 
87
     * or a byte array representing a distinguished name (in RFC 2253 or
 
88
     * ASN.1 DER encoded form, respectively). If <code>null</code> is supplied
 
89
     * as the value for this argument, no issuerNames check will be performed.<br />
 
90
     * <br />
 
91
     * Note that the <code>names</code> parameter can contain duplicate
 
92
     * distinguished names, but they may be removed from the 
 
93
     * <code>Collection</code> of names returned by the
 
94
     * {@link #getIssuerNames getIssuerNames} method.<br />
 
95
     * <br />
 
96
     * If a name is specified as a byte array, it should contain a single DER
 
97
     * encoded distinguished name, as defined in X.501. The ASN.1 notation for
 
98
     * this structure is as follows.
 
99
     * <pre><code>
 
100
     * Name ::= CHOICE {
 
101
     *   RDNSequence }
 
102
     *
 
103
     * RDNSequence ::= SEQUENCE OF RDN
 
104
     *
 
105
     * RDN ::=
 
106
     *   SET SIZE (1 .. MAX) OF AttributeTypeAndValue
 
107
     *
 
108
     * AttributeTypeAndValue ::= SEQUENCE {
 
109
     *   type     AttributeType,
 
110
     *   value    AttributeValue }
 
111
     *
 
112
     * AttributeType ::= OBJECT IDENTIFIER
 
113
     *
 
114
     * AttributeValue ::= ANY DEFINED BY AttributeType
 
115
     * ....
 
116
     * DirectoryString ::= CHOICE {
 
117
     *       teletexString           TeletexString (SIZE (1..MAX)),
 
118
     *       printableString         PrintableString (SIZE (1..MAX)),
 
119
     *       universalString         UniversalString (SIZE (1..MAX)),
 
120
     *       utf8String              UTF8String (SIZE (1.. MAX)),
 
121
     *       bmpString               BMPString (SIZE (1..MAX)) }
 
122
     * </code></pre><br />
 
123
     * <br />
 
124
     * Note that a deep copy is performed on the <code>Collection</code> to
 
125
     * protect against subsequent modifications.
 
126
     *
 
127
     * @param names a <code>Collection</code> of names (or <code>null</code>)
 
128
     *
 
129
     * @exception IOException if a parsing error occurs
 
130
     *
 
131
     * @see #getIssuerNames
 
132
     */
 
133
    public void setIssuerNames(Collection names)
 
134
    throws IOException
 
135
    {
 
136
    if ( names == null || names.isEmpty() )
 
137
    {
 
138
        issuerNames = null;
 
139
        issuerNamesX509 = null;
 
140
    }
 
141
    else
 
142
    {
 
143
        Object item;
 
144
        Iterator iter = names.iterator();
 
145
        while ( iter.hasNext() )
 
146
        {
 
147
        item = iter.next();
 
148
        if ( item instanceof String )
 
149
            addIssuerName( (String)item );
 
150
        else if ( item instanceof byte[] )
 
151
            addIssuerName( (byte[])item );
 
152
        else
 
153
            throw new IOException( "name not byte[]or String: " + item.toString() );
 
154
        }
 
155
    }
 
156
    }
 
157
 
 
158
    /**
 
159
     * Adds a name to the issuerNames criterion. The issuer distinguished
 
160
     * name in the <code>X509CRL</code> must match at least one of the specified
 
161
     * distinguished names.<br />
 
162
     * <br />
 
163
     * This method allows the caller to add a name to the set of issuer names
 
164
     * which <code>X509CRLs</code> may contain. The specified name is added to
 
165
     * any previous value for the issuerNames criterion.
 
166
     * If the specified name is a duplicate, it may be ignored.<br />
 
167
     * <br />
 
168
     * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for parsing the name
 
169
     *
 
170
     * @param name the name in RFC 2253 form
 
171
     *
 
172
     * @exception IOException if a parsing error occurs
 
173
     */
 
174
    public void addIssuerName(String name)
 
175
    throws IOException
 
176
    {
 
177
    if ( issuerNames == null )
 
178
    {
 
179
        issuerNames = new HashSet();
 
180
        issuerNamesX509 = new HashSet();
 
181
    }
 
182
    X509Name nameX509;
 
183
    try {
 
184
        nameX509 = new X509Name(name);
 
185
    } catch ( IllegalArgumentException ex ) {
 
186
        throw new IOException(ex.getMessage());
 
187
    }
 
188
    issuerNamesX509.add(nameX509);
 
189
    issuerNames.add(name);
 
190
    }
 
191
 
 
192
    /**
 
193
     * Adds a name to the issuerNames criterion. The issuer distinguished
 
194
     * name in the <code>X509CRL</code> must match at least one of the specified
 
195
     * distinguished names.<br />
 
196
     * <br />
 
197
     * This method allows the caller to add a name to the set of issuer names
 
198
     * which <code>X509CRLs</code> may contain. The specified name is added to
 
199
     * any previous value for the issuerNames criterion. If the specified name
 
200
     * is a duplicate, it may be ignored.
 
201
     * If a name is specified as a byte array, it should contain a single DER
 
202
     * encoded distinguished name, as defined in X.501. The ASN.1 notation for
 
203
     * this structure is as follows.<br />
 
204
     * <br />
 
205
     * The name is provided as a byte array. This byte array should contain
 
206
     * a single DER encoded distinguished name, as defined in X.501. The ASN.1
 
207
     * notation for this structure appears in the documentation for
 
208
     * {@link #setIssuerNames setIssuerNames(Collection names)}.<br />
 
209
     * <br />
 
210
     * Note that the byte array supplied here is cloned to protect against
 
211
     * subsequent modifications.<br />
 
212
     * <br />
 
213
     * Uses {@link org.bouncycastle.asn1.x509.X509Name X509Name} for parsing the name,
 
214
     * {@link org.bouncycastle.asn1.ASN1InputStream ASN1InputStream},
 
215
     * {@link org.bouncycastle.asn1.DERObject DERObject} and
 
216
     * {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence}
 
217
     *
 
218
     * @param name a byte array containing the name in ASN.1 DER encoded form
 
219
     *
 
220
     * @exception IOException if a parsing error occurs
 
221
     */
 
222
    public void addIssuerName(byte[] name)
 
223
    throws IOException
 
224
    {
 
225
    if ( issuerNames == null ) {
 
226
        issuerNames = new HashSet();
 
227
        issuerNamesX509 = new HashSet();
 
228
    }
 
229
 
 
230
    ByteArrayInputStream inStream = new ByteArrayInputStream(name);
 
231
    ASN1InputStream derInStream = new ASN1InputStream(inStream);
 
232
    DERObject obj = derInStream.readObject();
 
233
    if ( obj instanceof ASN1Sequence )
 
234
    {
 
235
        issuerNamesX509.add(new X509Name((ASN1Sequence)obj));
 
236
    }
 
237
    else
 
238
    {
 
239
        throw new IOException("parsing error");
 
240
    }
 
241
    issuerNames.add(name.clone());
 
242
    }
 
243
 
 
244
    /**
 
245
     * Sets the minCRLNumber criterion. The <code>X509CRL</code> must have a
 
246
     * CRL number extension whose value is greater than or equal to the
 
247
     * specified value. If <code>null</code>, no minCRLNumber check will be 
 
248
     * done.
 
249
     *
 
250
     * @param minCRL the minimum CRL number accepted (or <code>null</code>)
 
251
     */
 
252
    public void setMinCRLNumber(BigInteger minCRL)
 
253
    {
 
254
    this.minCRL = minCRL;
 
255
    }
 
256
 
 
257
    /**
 
258
     * Sets the maxCRLNumber criterion. The <code>X509CRL</code> must have a
 
259
     * CRL number extension whose value is less than or equal to the
 
260
     * specified value. If <code>null</code>, no maxCRLNumber check will be 
 
261
     * done.
 
262
     *
 
263
     * @param maxCRL the maximum CRL number accepted (or <code>null</code>)
 
264
     */
 
265
    public void setMaxCRLNumber(BigInteger maxCRL)
 
266
    {
 
267
    this.maxCRL = maxCRL;
 
268
    }
 
269
 
 
270
    /**
 
271
     * Sets the dateAndTime criterion. The specified date must be
 
272
     * equal to or later than the value of the thisUpdate component
 
273
     * of the <code>X509CRL</code> and earlier than the value of the
 
274
     * nextUpdate component. There is no match if the <code>X509CRL</code>
 
275
     * does not contain a nextUpdate component.
 
276
     * If <code>null</code>, no dateAndTime check will be done.<br />
 
277
     * <br />
 
278
     * Note that the <code>Date</code> supplied here is cloned to protect 
 
279
     * against subsequent modifications.
 
280
     *
 
281
     * @param dateAndTime the <code>Date</code> to match against
 
282
     *                    (or <code>null</code>)
 
283
     *
 
284
     * @see #getDateAndTime
 
285
     */
 
286
    public void setDateAndTime(Date dateAndTime)
 
287
    {
 
288
    if ( dateAndTime == null )
 
289
        this.dateAndTime = null;
 
290
    else
 
291
        this.dateAndTime = new Date( dateAndTime.getTime() );
 
292
    }
 
293
 
 
294
    /**
 
295
     * Sets the certificate being checked. This is not a criterion. Rather,
 
296
     * it is optional information that may help a <code>CertStore</code>
 
297
     * find CRLs that would be relevant when checking revocation for the
 
298
     * specified certificate. If <code>null</code> is specified, then no
 
299
     * such optional information is provided.
 
300
     *
 
301
     * @param cert the <code>X509Certificate</code> being checked
 
302
     *             (or <code>null</code>)
 
303
     *
 
304
     * @see #getCertificateChecking
 
305
     */
 
306
    public void setCertificateChecking(X509Certificate cert)
 
307
    {
 
308
    certChecking = cert;
 
309
    }
 
310
 
 
311
    /**
 
312
     * Returns a copy of the issuerNames criterion. The issuer distinguished
 
313
     * name in the <code>X509CRL</code> must match at least one of the specified
 
314
     * distinguished names. If the value returned is <code>null</code>, any
 
315
     * issuer distinguished name will do.<br />
 
316
     * <br />
 
317
     * If the value returned is not <code>null</code>, it is a
 
318
     * <code>Collection</code> of names. Each name is a <code>String</code>
 
319
     * or a byte array representing a distinguished name (in RFC 2253 or
 
320
     * ASN.1 DER encoded form, respectively).  Note that the 
 
321
     * <code>Collection</code> returned may contain duplicate names.<br />
 
322
     * <br />
 
323
     * If a name is specified as a byte array, it should contain a single DER
 
324
     * encoded distinguished name, as defined in X.501. The ASN.1 notation for
 
325
     * this structure is given in the documentation for
 
326
     * {@link #setIssuerNames setIssuerNames(Collection names)}.<br />
 
327
     * <br />
 
328
     * Note that a deep copy is performed on the <code>Collection</code> to
 
329
     * protect against subsequent modifications.
 
330
     *
 
331
     * @return a <code>Collection</code> of names (or <code>null</code>)
 
332
     * @see #setIssuerNames
 
333
     */
 
334
    public Collection getIssuerNames()
 
335
    {
 
336
    if ( issuerNames == null )
 
337
        return null;
 
338
    
 
339
    Collection set = new HashSet();
 
340
    Iterator iter = issuerNames.iterator();
 
341
    Object item;
 
342
    while ( iter.hasNext() )
 
343
    {
 
344
        item = iter.next();
 
345
        if ( item instanceof String )
 
346
        set.add(new String((String)item));
 
347
        else if ( item instanceof byte[] )
 
348
        set.add(((byte[])item).clone());
 
349
    }
 
350
    return set;
 
351
    }
 
352
 
 
353
    /**
 
354
     * Returns the minCRLNumber criterion. The <code>X509CRL</code> must have a
 
355
     * CRL number extension whose value is greater than or equal to the
 
356
     * specified value. If <code>null</code>, no minCRLNumber check will be done.
 
357
     *
 
358
     * @return the minimum CRL number accepted (or <code>null</code>)
 
359
     */
 
360
    public BigInteger getMinCRL()
 
361
    {
 
362
    return minCRL;
 
363
    }
 
364
 
 
365
    /**
 
366
     * Returns the maxCRLNumber criterion. The <code>X509CRL</code> must have a
 
367
     * CRL number extension whose value is less than or equal to the
 
368
     * specified value. If <code>null</code>, no maxCRLNumber check will be 
 
369
     * done.
 
370
     *
 
371
     * @return the maximum CRL number accepted (or <code>null</code>)
 
372
     */
 
373
    public BigInteger getMaxCRL()
 
374
    {
 
375
    return maxCRL;
 
376
    }
 
377
 
 
378
    /**
 
379
     * Returns the dateAndTime criterion. The specified date must be
 
380
     * equal to or later than the value of the thisUpdate component
 
381
     * of the <code>X509CRL</code> and earlier than the value of the
 
382
     * nextUpdate component. There is no match if the
 
383
     * <code>X509CRL</code> does not contain a nextUpdate component.
 
384
     * If <code>null</code>, no dateAndTime check will be done.<br />
 
385
     * <br />
 
386
     * Note that the <code>Date</code> returned is cloned to protect against
 
387
     * subsequent modifications.
 
388
     *
 
389
     * @return the <code>Date</code> to match against (or <code>null</code>)
 
390
     *
 
391
     * @see #setDateAndTime
 
392
     */
 
393
    public Date getDateAndTime()
 
394
    {
 
395
    if ( dateAndTime == null )
 
396
        return null;
 
397
 
 
398
    return new Date(dateAndTime.getTime());
 
399
    }
 
400
 
 
401
    /**
 
402
     * Returns the certificate being checked. This is not a criterion. Rather,
 
403
     * it is optional information that may help a <code>CertStore</code>
 
404
     * find CRLs that would be relevant when checking revocation for the
 
405
     * specified certificate. If the value returned is <code>null</code>, then 
 
406
     * no such optional information is provided.
 
407
     *
 
408
     * @return the certificate being checked (or <code>null</code>)
 
409
     *
 
410
     * @see #setCertificateChecking
 
411
     */
 
412
    public X509Certificate getCertificateChecking()
 
413
    {
 
414
    return certChecking;
 
415
    }
 
416
 
 
417
    /**
 
418
     * Returns a printable representation of the <code>X509CRLSelector</code>.<br />
 
419
     * <br />
 
420
     * Uses {@link org.bouncycastle.asn1.x509.X509Name#toString X509Name.toString} to format the output
 
421
     *
 
422
     * @return a <code>String</code> describing the contents of the
 
423
     *         <code>X509CRLSelector</code>.
 
424
     */
 
425
    public String toString()
 
426
    {
 
427
    StringBuffer s = new StringBuffer();
 
428
    s.append( "X509CRLSelector: [\n" );
 
429
    if ( issuerNamesX509 != null ) {
 
430
            s.append("  IssuerNames:\n");
 
431
        Iterator iter = issuerNamesX509.iterator();
 
432
        while ( iter.hasNext() ) {
 
433
        s.append( "    ").append(iter.next()).append('\n' );
 
434
        }
 
435
    }
 
436
        if (minCRL != null)
 
437
            s.append("  minCRLNumber: ").append(minCRL).append('\n');
 
438
        if (maxCRL != null)
 
439
            s.append("  maxCRLNumber: ").append(maxCRL).append('\n');
 
440
        if (dateAndTime != null)
 
441
            s.append("  dateAndTime: ").append(dateAndTime).append('\n');
 
442
        if (certChecking != null)
 
443
            s.append("  Certificate being checked: ").append(certChecking).append('\n');
 
444
        s.append(']');
 
445
    return s.toString();
 
446
    }
 
447
 
 
448
    /**
 
449
     * Decides whether a <code>CRL</code> should be selected.<br />
 
450
     * <br />
 
451
     * Uses {@link org.bouncycastle.asn1.x509.X509Name#toString X509Name.toString}
 
452
     * to parse and to compare the crl parameter issuer and
 
453
     * {@link org.bouncycastle.asn1.x509.X509Extensions#CRLNumber CRLNumber} to access
 
454
     * the CRL number extension.
 
455
     *
 
456
     * @param crl the <code>CRL</code> to be checked
 
457
     *
 
458
     * @return <code>true</code> if the <code>CRL</code> should be selected,
 
459
     *         <code>false</code> otherwise
 
460
     */
 
461
    public boolean match(CRL crl)
 
462
    {
 
463
    if ( ! ( crl instanceof X509CRL ) )
 
464
        return false;
 
465
    
 
466
    X509CRL crlX509 = (X509CRL)crl;
 
467
    boolean test;
 
468
 
 
469
    if ( issuerNamesX509 != null )
 
470
    {
 
471
        Iterator iter = issuerNamesX509.iterator();
 
472
        test = false;
 
473
        X509Name crlIssuer = null;
 
474
        try {
 
475
            crlIssuer = PrincipalUtil.getIssuerX509Principal(crlX509);
 
476
        } catch ( Exception ex ) {
 
477
        return false;
 
478
        }
 
479
        
 
480
        while ( iter.hasNext() )
 
481
        {
 
482
            if ( crlIssuer.equals(iter.next(), true) )
 
483
            {
 
484
                test = true;
 
485
                break;
 
486
            }
 
487
        }
 
488
        if ( ! test )
 
489
        {
 
490
            return false;
 
491
        }
 
492
    }
 
493
 
 
494
    byte[] data = crlX509.getExtensionValue( X509Extensions.CRLNumber.getId() );
 
495
    if ( data != null )
 
496
    {
 
497
        try {
 
498
        ByteArrayInputStream inStream = new ByteArrayInputStream(data);
 
499
        ASN1InputStream derInputStream = new ASN1InputStream(inStream);
 
500
        inStream = new ByteArrayInputStream(((ASN1OctetString)derInputStream.readObject()).getOctets());
 
501
        derInputStream = new ASN1InputStream(inStream);
 
502
        BigInteger crlNumber = ((DERInteger)derInputStream.readObject()).getPositiveValue();
 
503
        if ( minCRL != null && minCRL.compareTo( crlNumber ) > 0 )
 
504
            return false;
 
505
        if ( maxCRL != null && maxCRL.compareTo( crlNumber ) < 0 )
 
506
            return false;
 
507
        } catch ( IOException ex ) {
 
508
        return false;
 
509
        }
 
510
    } else if ( minCRL != null || maxCRL != null )
 
511
    {
 
512
        return false;
 
513
    }
 
514
 
 
515
    if ( dateAndTime != null )
 
516
    {
 
517
        Date check = crlX509.getThisUpdate();
 
518
        if ( check == null )
 
519
        {
 
520
        return false;
 
521
        }
 
522
        else if ( dateAndTime.before( check ) )
 
523
        {
 
524
        return false;
 
525
        }
 
526
 
 
527
        check = crlX509.getNextUpdate();
 
528
        if ( check == null )
 
529
        {
 
530
        return false;
 
531
        }
 
532
        else if ( ! dateAndTime.before( check ) )
 
533
        {
 
534
        return false;
 
535
        }
 
536
    }
 
537
 
 
538
    return true;
 
539
    }
 
540
 
 
541
    /**
 
542
     * Returns a copy of this object.
 
543
     *
 
544
     * @return the copy
 
545
     */
 
546
    public Object clone()
 
547
    {
 
548
    try {
 
549
        X509CRLSelector copy = (X509CRLSelector)super.clone();
 
550
        if ( issuerNames != null )
 
551
        {
 
552
        copy.issuerNames = new HashSet();
 
553
        Iterator iter = issuerNames.iterator();
 
554
        Object obj;
 
555
        while ( iter.hasNext() )
 
556
        {
 
557
            obj = iter.next();
 
558
            if ( obj instanceof byte[] )
 
559
            copy.issuerNames.add( ((byte[])obj).clone() );
 
560
             else
 
561
             copy.issuerNames.add( obj );
 
562
        }
 
563
        copy.issuerNamesX509 = new HashSet( issuerNamesX509 );
 
564
        }
 
565
        return copy;
 
566
    } catch (CloneNotSupportedException e) {
 
567
        /* Cannot happen */
 
568
        throw new InternalError(e.toString());
 
569
    }
 
570
    }
 
571
 
 
572
    /**
 
573
     * Decides whether a <code>CRL</code> should be selected.
 
574
     *
 
575
     * @param crl the <code>CRL</code> to be checked
 
576
     *
 
577
     * @return <code>true</code> if the <code>CRL</code> should be selected,
 
578
     *         <code>false</code> otherwise
 
579
     */
 
580
    public boolean equals( Object obj )
 
581
    {
 
582
    if ( ! ( obj instanceof X509CRLSelector ) )
 
583
        return false;
 
584
 
 
585
    X509CRLSelector equalsCRL = (X509CRLSelector)obj;
 
586
 
 
587
    if ( ! equals(dateAndTime, equalsCRL.dateAndTime) )
 
588
         return false;
 
589
 
 
590
    if ( ! equals(minCRL, equalsCRL.minCRL) )
 
591
        return false;
 
592
 
 
593
    if ( ! equals(maxCRL, equalsCRL.maxCRL) )
 
594
        return false;
 
595
 
 
596
    if ( ! equals(issuerNamesX509, equalsCRL.issuerNamesX509) )
 
597
        return false;
 
598
 
 
599
    if ( ! equals( certChecking, equalsCRL.certChecking) )
 
600
        return false;
 
601
 
 
602
    return true;
 
603
    }
 
604
 
 
605
    /**
 
606
     * Return <code>true</code> if two Objects are unequal.
 
607
     * This means that one is <code>null</code> and the other is
 
608
     * not or <code>obj1.equals(obj2)</code> returns
 
609
     * <code>false</code>.
 
610
     **/
 
611
    private boolean equals( Object obj1, Object obj2 )
 
612
    {
 
613
    if ( obj1 == null ) {
 
614
        if ( obj2 != null )
 
615
        return true;
 
616
    }
 
617
    else if ( ! obj1.equals( obj2 ) )
 
618
        return true;
 
619
    return false;
 
620
    }    
 
621
}