Home | History | Annotate | Download | only in selector
      1 package org.bouncycastle.cert.selector;
      2 
      3 import java.math.BigInteger;
      4 
      5 import org.bouncycastle.asn1.ASN1OctetString;
      6 import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
      7 import org.bouncycastle.asn1.x500.X500Name;
      8 import org.bouncycastle.asn1.x509.Extension;
      9 import org.bouncycastle.cert.X509CertificateHolder;
     10 import org.bouncycastle.util.Arrays;
     11 import org.bouncycastle.util.Selector;
     12 
     13 /**
     14  * a basic index for a X509CertificateHolder class
     15  */
     16 public class X509CertificateHolderSelector
     17     implements Selector
     18 {
     19     private byte[] subjectKeyId;
     20 
     21     private X500Name issuer;
     22     private BigInteger serialNumber;
     23 
     24     /**
     25      * Construct a selector with the value of a public key's subjectKeyId.
     26      *
     27      * @param subjectKeyId a subjectKeyId
     28      */
     29     public X509CertificateHolderSelector(byte[] subjectKeyId)
     30     {
     31         this(null, null, subjectKeyId);
     32     }
     33 
     34     /**
     35      * Construct a signer ID based on the issuer and serial number of the signer's associated
     36      * certificate.
     37      *
     38      * @param issuer the issuer of the signer's associated certificate.
     39      * @param serialNumber the serial number of the signer's associated certificate.
     40      */
     41     public X509CertificateHolderSelector(X500Name issuer, BigInteger serialNumber)
     42     {
     43         this(issuer, serialNumber, null);
     44     }
     45 
     46     /**
     47      * Construct a signer ID based on the issuer and serial number of the signer's associated
     48      * certificate.
     49      *
     50      * @param issuer the issuer of the signer's associated certificate.
     51      * @param serialNumber the serial number of the signer's associated certificate.
     52      * @param subjectKeyId the subject key identifier to use to match the signers associated certificate.
     53      */
     54     public X509CertificateHolderSelector(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyId)
     55     {
     56         this.issuer = issuer;
     57         this.serialNumber = serialNumber;
     58         this.subjectKeyId = subjectKeyId;
     59     }
     60 
     61     public X500Name getIssuer()
     62     {
     63         return issuer;
     64     }
     65 
     66     public BigInteger getSerialNumber()
     67     {
     68         return serialNumber;
     69     }
     70 
     71     public byte[] getSubjectKeyIdentifier()
     72     {
     73         return Arrays.clone(subjectKeyId);
     74     }
     75 
     76     public int hashCode()
     77     {
     78         int code = Arrays.hashCode(subjectKeyId);
     79 
     80         if (this.serialNumber != null)
     81         {
     82             code ^= this.serialNumber.hashCode();
     83         }
     84 
     85         if (this.issuer != null)
     86         {
     87             code ^= this.issuer.hashCode();
     88         }
     89 
     90         return code;
     91     }
     92 
     93     public boolean equals(
     94         Object  o)
     95     {
     96         if (!(o instanceof X509CertificateHolderSelector))
     97         {
     98             return false;
     99         }
    100 
    101         X509CertificateHolderSelector id = (X509CertificateHolderSelector)o;
    102 
    103         return Arrays.areEqual(subjectKeyId, id.subjectKeyId)
    104             && equalsObj(this.serialNumber, id.serialNumber)
    105             && equalsObj(this.issuer, id.issuer);
    106     }
    107 
    108     private boolean equalsObj(Object a, Object b)
    109     {
    110         return (a != null) ? a.equals(b) : b == null;
    111     }
    112 
    113     public boolean match(Object obj)
    114     {
    115         if (obj instanceof X509CertificateHolder)
    116         {
    117             X509CertificateHolder certHldr = (X509CertificateHolder)obj;
    118 
    119             if (this.getSerialNumber() != null)
    120             {
    121                 IssuerAndSerialNumber iAndS = new IssuerAndSerialNumber(certHldr.toASN1Structure());
    122 
    123                 return iAndS.getName().equals(this.issuer)
    124                     && iAndS.getSerialNumber().getValue().equals(this.serialNumber);
    125             }
    126             else if (subjectKeyId != null)
    127             {
    128                 Extension ext = certHldr.getExtension(Extension.subjectKeyIdentifier);
    129 
    130                 if (ext == null)
    131                 {
    132                     return Arrays.areEqual(subjectKeyId, MSOutlookKeyIdCalculator.calculateKeyId(certHldr.getSubjectPublicKeyInfo()));
    133                 }
    134 
    135                 byte[] subKeyID = ASN1OctetString.getInstance(ext.getParsedValue()).getOctets();
    136 
    137                 return Arrays.areEqual(subjectKeyId, subKeyID);
    138             }
    139         }
    140         else if (obj instanceof byte[])
    141         {
    142             return Arrays.areEqual(subjectKeyId, (byte[])obj);
    143         }
    144 
    145         return false;
    146     }
    147 
    148     public Object clone()
    149     {
    150         return new X509CertificateHolderSelector(this.issuer, this.serialNumber, this.subjectKeyId);
    151     }
    152 }
    153