Home | History | Annotate | Download | only in x509
      1 package org.bouncycastle.jcajce.provider.asymmetric.x509;
      2 
      3 import java.io.IOException;
      4 import java.math.BigInteger;
      5 import java.security.cert.CRLException;
      6 import java.security.cert.X509CRLEntry;
      7 import java.util.Date;
      8 import java.util.Enumeration;
      9 import java.util.HashSet;
     10 import java.util.Set;
     11 
     12 import javax.security.auth.x500.X500Principal;
     13 
     14 import org.bouncycastle.asn1.ASN1Encoding;
     15 import org.bouncycastle.asn1.ASN1Enumerated;
     16 import org.bouncycastle.asn1.ASN1InputStream;
     17 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
     18 import org.bouncycastle.asn1.util.ASN1Dump;
     19 import org.bouncycastle.asn1.x500.X500Name;
     20 import org.bouncycastle.asn1.x509.CRLReason;
     21 import org.bouncycastle.asn1.x509.Extension;
     22 import org.bouncycastle.asn1.x509.Extensions;
     23 import org.bouncycastle.asn1.x509.GeneralName;
     24 import org.bouncycastle.asn1.x509.GeneralNames;
     25 import org.bouncycastle.asn1.x509.TBSCertList;
     26 import org.bouncycastle.util.Strings;
     27 
     28 /**
     29  * The following extensions are listed in RFC 2459 as relevant to CRL Entries
     30  *
     31  * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer
     32  * (critical)
     33  */
     34 class X509CRLEntryObject extends X509CRLEntry
     35 {
     36     private TBSCertList.CRLEntry c;
     37 
     38     private X500Name certificateIssuer;
     39     private int           hashValue;
     40     private boolean       isHashValueSet;
     41 
     42     protected X509CRLEntryObject(TBSCertList.CRLEntry c)
     43     {
     44         this.c = c;
     45         this.certificateIssuer = null;
     46     }
     47 
     48     /**
     49      * Constructor for CRLEntries of indirect CRLs. If <code>isIndirect</code>
     50      * is <code>false</code> {@link #getCertificateIssuer()} will always
     51      * return <code>null</code>, <code>previousCertificateIssuer</code> is
     52      * ignored. If this <code>isIndirect</code> is specified and this CRLEntry
     53      * has no certificate issuer CRL entry extension
     54      * <code>previousCertificateIssuer</code> is returned by
     55      * {@link #getCertificateIssuer()}.
     56      *
     57      * @param c
     58      *            TBSCertList.CRLEntry object.
     59      * @param isIndirect
     60      *            <code>true</code> if the corresponding CRL is a indirect
     61      *            CRL.
     62      * @param previousCertificateIssuer
     63      *            Certificate issuer of the previous CRLEntry.
     64      */
     65     protected X509CRLEntryObject(
     66         TBSCertList.CRLEntry c,
     67         boolean isIndirect,
     68         X500Name previousCertificateIssuer)
     69     {
     70         this.c = c;
     71         this.certificateIssuer = loadCertificateIssuer(isIndirect, previousCertificateIssuer);
     72     }
     73 
     74     /**
     75      * Will return true if any extensions are present and marked as critical as
     76      * we currently don't handle any extensions!
     77      */
     78     public boolean hasUnsupportedCriticalExtension()
     79     {
     80         Set extns = getCriticalExtensionOIDs();
     81 
     82         return extns != null && !extns.isEmpty();
     83     }
     84 
     85     private X500Name loadCertificateIssuer(boolean isIndirect, X500Name previousCertificateIssuer)
     86     {
     87         if (!isIndirect)
     88         {
     89             return null;
     90         }
     91 
     92         Extension ext = getExtension(Extension.certificateIssuer);
     93         if (ext == null)
     94         {
     95             return previousCertificateIssuer;
     96         }
     97 
     98         try
     99         {
    100             GeneralName[] names = GeneralNames.getInstance(ext.getParsedValue()).getNames();
    101             for (int i = 0; i < names.length; i++)
    102             {
    103                 if (names[i].getTagNo() == GeneralName.directoryName)
    104                 {
    105                     return X500Name.getInstance(names[i].getName());
    106                 }
    107             }
    108             return null;
    109         }
    110         catch (Exception e)
    111         {
    112             return null;
    113         }
    114     }
    115 
    116     public X500Principal getCertificateIssuer()
    117     {
    118         if (certificateIssuer == null)
    119         {
    120             return null;
    121         }
    122         try
    123         {
    124             return new X500Principal(certificateIssuer.getEncoded());
    125         }
    126         catch (IOException e)
    127         {
    128             return null;
    129         }
    130     }
    131 
    132     private Set getExtensionOIDs(boolean critical)
    133     {
    134         Extensions extensions = c.getExtensions();
    135 
    136         if (extensions != null)
    137         {
    138             Set set = new HashSet();
    139             Enumeration e = extensions.oids();
    140 
    141             while (e.hasMoreElements())
    142             {
    143                 ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement();
    144                 Extension ext = extensions.getExtension(oid);
    145 
    146                 if (critical == ext.isCritical())
    147                 {
    148                     set.add(oid.getId());
    149                 }
    150             }
    151 
    152             return set;
    153         }
    154 
    155         return null;
    156     }
    157 
    158     public Set getCriticalExtensionOIDs()
    159     {
    160         return getExtensionOIDs(true);
    161     }
    162 
    163     public Set getNonCriticalExtensionOIDs()
    164     {
    165         return getExtensionOIDs(false);
    166     }
    167 
    168     private Extension getExtension(ASN1ObjectIdentifier oid)
    169     {
    170         Extensions exts = c.getExtensions();
    171 
    172         if (exts != null)
    173         {
    174             return exts.getExtension(oid);
    175         }
    176 
    177         return null;
    178     }
    179 
    180     public byte[] getExtensionValue(String oid)
    181     {
    182         Extension ext = getExtension(new ASN1ObjectIdentifier(oid));
    183 
    184         if (ext != null)
    185         {
    186             try
    187             {
    188                 return ext.getExtnValue().getEncoded();
    189             }
    190             catch (Exception e)
    191             {
    192                 throw new IllegalStateException("Exception encoding: " + e.toString());
    193             }
    194         }
    195 
    196         return null;
    197     }
    198 
    199     /**
    200      * Cache the hashCode value - calculating it with the standard method.
    201      * @return  calculated hashCode.
    202      */
    203     public int hashCode()
    204     {
    205         if (!isHashValueSet)
    206         {
    207             hashValue = super.hashCode();
    208             isHashValueSet = true;
    209         }
    210 
    211         return hashValue;
    212     }
    213 
    214     public boolean equals(Object o)
    215     {
    216         if (o == this)
    217         {
    218             return true;
    219         }
    220 
    221         if (o instanceof X509CRLEntryObject)
    222         {
    223             X509CRLEntryObject other = (X509CRLEntryObject)o;
    224 
    225             return this.c.equals(other.c);
    226         }
    227 
    228         return super.equals(this);
    229     }
    230 
    231     public byte[] getEncoded()
    232         throws CRLException
    233     {
    234         try
    235         {
    236             return c.getEncoded(ASN1Encoding.DER);
    237         }
    238         catch (IOException e)
    239         {
    240             throw new CRLException(e.toString());
    241         }
    242     }
    243 
    244     public BigInteger getSerialNumber()
    245     {
    246         return c.getUserCertificate().getValue();
    247     }
    248 
    249     public Date getRevocationDate()
    250     {
    251         return c.getRevocationDate().getDate();
    252     }
    253 
    254     public boolean hasExtensions()
    255     {
    256         return c.getExtensions() != null;
    257     }
    258 
    259     public String toString()
    260     {
    261         StringBuffer buf = new StringBuffer();
    262         String nl = Strings.lineSeparator();
    263 
    264         buf.append("      userCertificate: ").append(this.getSerialNumber()).append(nl);
    265         buf.append("       revocationDate: ").append(this.getRevocationDate()).append(nl);
    266         buf.append("       certificateIssuer: ").append(this.getCertificateIssuer()).append(nl);
    267 
    268         Extensions extensions = c.getExtensions();
    269 
    270         if (extensions != null)
    271         {
    272             Enumeration e = extensions.oids();
    273             if (e.hasMoreElements())
    274             {
    275                 buf.append("   crlEntryExtensions:").append(nl);
    276 
    277                 while (e.hasMoreElements())
    278                 {
    279                     ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
    280                     Extension ext = extensions.getExtension(oid);
    281                     if (ext.getExtnValue() != null)
    282                     {
    283                         byte[]                  octs = ext.getExtnValue().getOctets();
    284                         ASN1InputStream dIn = new ASN1InputStream(octs);
    285                         buf.append("                       critical(").append(ext.isCritical()).append(") ");
    286                         try
    287                         {
    288                             if (oid.equals(Extension.reasonCode))
    289                             {
    290                                 buf.append(CRLReason.getInstance(ASN1Enumerated.getInstance(dIn.readObject()))).append(nl);
    291                             }
    292                             else if (oid.equals(Extension.certificateIssuer))
    293                             {
    294                                 buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl);
    295                             }
    296                             else
    297                             {
    298                                 buf.append(oid.getId());
    299                                 buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
    300                             }
    301                         }
    302                         catch (Exception ex)
    303                         {
    304                             buf.append(oid.getId());
    305                             buf.append(" value = ").append("*****").append(nl);
    306                         }
    307                     }
    308                     else
    309                     {
    310                         buf.append(nl);
    311                     }
    312                 }
    313             }
    314         }
    315 
    316         return buf.toString();
    317     }
    318 }
    319