Home | History | Annotate | Download | only in ocsp
      1 package org.bouncycastle.cert.ocsp;
      2 
      3 import java.io.OutputStream;
      4 import java.math.BigInteger;
      5 
      6 import org.bouncycastle.asn1.ASN1Encoding;
      7 import org.bouncycastle.asn1.ASN1Integer;
      8 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
      9 import org.bouncycastle.asn1.ASN1OctetString;
     10 import org.bouncycastle.asn1.DERNull;
     11 import org.bouncycastle.asn1.DEROctetString;
     12 import org.bouncycastle.asn1.ocsp.CertID;
     13 import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
     14 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
     15 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
     16 import org.bouncycastle.cert.X509CertificateHolder;
     17 import org.bouncycastle.operator.DigestCalculator;
     18 import org.bouncycastle.operator.DigestCalculatorProvider;
     19 import org.bouncycastle.operator.OperatorCreationException;
     20 
     21 public class CertificateID
     22 {
     23     public static final AlgorithmIdentifier HASH_SHA1 = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
     24 
     25     private final CertID id;
     26 
     27     public CertificateID(
     28         CertID id)
     29     {
     30         if (id == null)
     31         {
     32             throw new IllegalArgumentException("'id' cannot be null");
     33         }
     34         this.id = id;
     35     }
     36 
     37     /**
     38      * create from an issuer certificate and the serial number of the
     39      * certificate it signed.
     40      *
     41      * @param issuerCert issuing certificate
     42      * @param number serial number
     43      *
     44      * @exception OCSPException if any problems occur creating the id fields.
     45      */
     46     public CertificateID(
     47         DigestCalculator digestCalculator, X509CertificateHolder issuerCert,
     48         BigInteger number)
     49         throws OCSPException
     50     {
     51         this.id = createCertID(digestCalculator, issuerCert, new ASN1Integer(number));
     52     }
     53 
     54     public ASN1ObjectIdentifier getHashAlgOID()
     55     {
     56         return id.getHashAlgorithm().getAlgorithm();
     57     }
     58 
     59     public byte[] getIssuerNameHash()
     60     {
     61         return id.getIssuerNameHash().getOctets();
     62     }
     63 
     64     public byte[] getIssuerKeyHash()
     65     {
     66         return id.getIssuerKeyHash().getOctets();
     67     }
     68 
     69     /**
     70      * return the serial number for the certificate associated
     71      * with this request.
     72      */
     73     public BigInteger getSerialNumber()
     74     {
     75         return id.getSerialNumber().getValue();
     76     }
     77 
     78     public boolean matchesIssuer(X509CertificateHolder issuerCert, DigestCalculatorProvider digCalcProvider)
     79         throws OCSPException
     80     {
     81         try
     82         {
     83             return createCertID(digCalcProvider.get(id.getHashAlgorithm()), issuerCert, id.getSerialNumber()).equals(id);
     84         }
     85         catch (OperatorCreationException e)
     86         {
     87             throw new OCSPException("unable to create digest calculator: " + e.getMessage(), e);
     88         }
     89     }
     90 
     91     public CertID toASN1Primitive()
     92     {
     93         return id;
     94     }
     95 
     96     public boolean equals(
     97         Object  o)
     98     {
     99         if (!(o instanceof CertificateID))
    100         {
    101             return false;
    102         }
    103 
    104         CertificateID obj = (CertificateID)o;
    105 
    106         return id.toASN1Primitive().equals(obj.id.toASN1Primitive());
    107     }
    108 
    109     public int hashCode()
    110     {
    111         return id.toASN1Primitive().hashCode();
    112     }
    113 
    114     /**
    115      * Create a new CertificateID for a new serial number derived from a previous one
    116      * calculated for the same CA certificate.
    117      *
    118      * @param original the previously calculated CertificateID for the CA.
    119      * @param newSerialNumber the serial number for the new certificate of interest.
    120      *
    121      * @return a new CertificateID for newSerialNumber
    122      */
    123     public static CertificateID deriveCertificateID(CertificateID original, BigInteger newSerialNumber)
    124     {
    125         return new CertificateID(new CertID(original.id.getHashAlgorithm(), original.id.getIssuerNameHash(), original.id.getIssuerKeyHash(), new ASN1Integer(newSerialNumber)));
    126     }
    127 
    128     private static CertID createCertID(DigestCalculator digCalc, X509CertificateHolder issuerCert, ASN1Integer serialNumber)
    129         throws OCSPException
    130     {
    131         try
    132         {
    133             OutputStream dgOut = digCalc.getOutputStream();
    134 
    135             dgOut.write(issuerCert.toASN1Structure().getSubject().getEncoded(ASN1Encoding.DER));
    136             dgOut.close();
    137 
    138             ASN1OctetString issuerNameHash = new DEROctetString(digCalc.getDigest());
    139 
    140             SubjectPublicKeyInfo info = issuerCert.getSubjectPublicKeyInfo();
    141 
    142             dgOut = digCalc.getOutputStream();
    143 
    144             dgOut.write(info.getPublicKeyData().getBytes());
    145             dgOut.close();
    146 
    147             ASN1OctetString issuerKeyHash = new DEROctetString(digCalc.getDigest());
    148 
    149             return new CertID(digCalc.getAlgorithmIdentifier(), issuerNameHash, issuerKeyHash, serialNumber);
    150         }
    151         catch (Exception e)
    152         {
    153             throw new OCSPException("problem creating ID: " + e, e);
    154         }
    155     }
    156 }
    157