Home | History | Annotate | Download | only in x509
      1 package org.bouncycastle.asn1.x509;
      2 
      3 import java.util.Enumeration;
      4 import java.util.NoSuchElementException;
      5 
      6 import org.bouncycastle.asn1.ASN1EncodableVector;
      7 import org.bouncycastle.asn1.ASN1GeneralizedTime;
      8 import org.bouncycastle.asn1.ASN1Integer;
      9 import org.bouncycastle.asn1.ASN1Object;
     10 import org.bouncycastle.asn1.ASN1Primitive;
     11 import org.bouncycastle.asn1.ASN1Sequence;
     12 import org.bouncycastle.asn1.ASN1TaggedObject;
     13 import org.bouncycastle.asn1.ASN1UTCTime;
     14 import org.bouncycastle.asn1.DERSequence;
     15 import org.bouncycastle.asn1.DERTaggedObject;
     16 import org.bouncycastle.asn1.x500.X500Name;
     17 
     18 /**
     19  * PKIX RFC-2459 - TBSCertList object.
     20  * <pre>
     21  * TBSCertList  ::=  SEQUENCE  {
     22  *      version                 Version OPTIONAL,
     23  *                                   -- if present, shall be v2
     24  *      signature               AlgorithmIdentifier,
     25  *      issuer                  Name,
     26  *      thisUpdate              Time,
     27  *      nextUpdate              Time OPTIONAL,
     28  *      revokedCertificates     SEQUENCE OF SEQUENCE  {
     29  *           userCertificate         CertificateSerialNumber,
     30  *           revocationDate          Time,
     31  *           crlEntryExtensions      Extensions OPTIONAL
     32  *                                         -- if present, shall be v2
     33  *                                }  OPTIONAL,
     34  *      crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
     35  *                                         -- if present, shall be v2
     36  *                                }
     37  * </pre>
     38  */
     39 public class TBSCertList
     40     extends ASN1Object
     41 {
     42     public static class CRLEntry
     43         extends ASN1Object
     44     {
     45         ASN1Sequence  seq;
     46 
     47         Extensions    crlEntryExtensions;
     48 
     49         private CRLEntry(
     50             ASN1Sequence  seq)
     51         {
     52             if (seq.size() < 2 || seq.size() > 3)
     53             {
     54                 throw new IllegalArgumentException("Bad sequence size: " + seq.size());
     55             }
     56 
     57             this.seq = seq;
     58         }
     59 
     60         public static CRLEntry getInstance(Object o)
     61         {
     62             if (o instanceof CRLEntry)
     63             {
     64                 return ((CRLEntry)o);
     65             }
     66             else if (o != null)
     67             {
     68                 return new CRLEntry(ASN1Sequence.getInstance(o));
     69             }
     70 
     71             return null;
     72         }
     73 
     74         public ASN1Integer getUserCertificate()
     75         {
     76             return ASN1Integer.getInstance(seq.getObjectAt(0));
     77         }
     78 
     79         public Time getRevocationDate()
     80         {
     81             return Time.getInstance(seq.getObjectAt(1));
     82         }
     83 
     84         public Extensions getExtensions()
     85         {
     86             if (crlEntryExtensions == null && seq.size() == 3)
     87             {
     88                 crlEntryExtensions = Extensions.getInstance(seq.getObjectAt(2));
     89             }
     90 
     91             return crlEntryExtensions;
     92         }
     93 
     94         public ASN1Primitive toASN1Primitive()
     95         {
     96             return seq;
     97         }
     98 
     99         public boolean hasExtensions()
    100         {
    101             return seq.size() == 3;
    102         }
    103     }
    104 
    105     private class RevokedCertificatesEnumeration
    106         implements Enumeration
    107     {
    108         private final Enumeration en;
    109 
    110         RevokedCertificatesEnumeration(Enumeration en)
    111         {
    112             this.en = en;
    113         }
    114 
    115         public boolean hasMoreElements()
    116         {
    117             return en.hasMoreElements();
    118         }
    119 
    120         public Object nextElement()
    121         {
    122             return CRLEntry.getInstance(en.nextElement());
    123         }
    124     }
    125 
    126     private class EmptyEnumeration
    127         implements Enumeration
    128     {
    129         public boolean hasMoreElements()
    130         {
    131             return false;
    132         }
    133 
    134         public Object nextElement()
    135         {
    136             throw new NoSuchElementException("Empty Enumeration");
    137         }
    138     }
    139 
    140     ASN1Integer             version;
    141     AlgorithmIdentifier     signature;
    142     X500Name                issuer;
    143     Time                    thisUpdate;
    144     Time                    nextUpdate;
    145     ASN1Sequence            revokedCertificates;
    146     Extensions              crlExtensions;
    147 
    148     public static TBSCertList getInstance(
    149         ASN1TaggedObject obj,
    150         boolean          explicit)
    151     {
    152         return getInstance(ASN1Sequence.getInstance(obj, explicit));
    153     }
    154 
    155     public static TBSCertList getInstance(
    156         Object  obj)
    157     {
    158         if (obj instanceof TBSCertList)
    159         {
    160             return (TBSCertList)obj;
    161         }
    162         else if (obj != null)
    163         {
    164             return new TBSCertList(ASN1Sequence.getInstance(obj));
    165         }
    166 
    167         return null;
    168     }
    169 
    170     public TBSCertList(
    171         ASN1Sequence  seq)
    172     {
    173         if (seq.size() < 3 || seq.size() > 7)
    174         {
    175             throw new IllegalArgumentException("Bad sequence size: " + seq.size());
    176         }
    177 
    178         int seqPos = 0;
    179 
    180         if (seq.getObjectAt(seqPos) instanceof ASN1Integer)
    181         {
    182             version = ASN1Integer.getInstance(seq.getObjectAt(seqPos++));
    183         }
    184         else
    185         {
    186             version = null;  // version is optional
    187         }
    188 
    189         signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqPos++));
    190         issuer = X500Name.getInstance(seq.getObjectAt(seqPos++));
    191         thisUpdate = Time.getInstance(seq.getObjectAt(seqPos++));
    192 
    193         if (seqPos < seq.size()
    194             && (seq.getObjectAt(seqPos) instanceof ASN1UTCTime
    195                || seq.getObjectAt(seqPos) instanceof ASN1GeneralizedTime
    196                || seq.getObjectAt(seqPos) instanceof Time))
    197         {
    198             nextUpdate = Time.getInstance(seq.getObjectAt(seqPos++));
    199         }
    200 
    201         if (seqPos < seq.size()
    202             && !(seq.getObjectAt(seqPos) instanceof ASN1TaggedObject))
    203         {
    204             revokedCertificates = ASN1Sequence.getInstance(seq.getObjectAt(seqPos++));
    205         }
    206 
    207         if (seqPos < seq.size()
    208             && seq.getObjectAt(seqPos) instanceof ASN1TaggedObject)
    209         {
    210             crlExtensions = Extensions.getInstance(ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(seqPos), true));
    211         }
    212     }
    213 
    214     public int getVersionNumber()
    215     {
    216         if (version == null)
    217         {
    218             return 1;
    219         }
    220         return version.getValue().intValue() + 1;
    221     }
    222 
    223     public ASN1Integer getVersion()
    224     {
    225         return version;
    226     }
    227 
    228     public AlgorithmIdentifier getSignature()
    229     {
    230         return signature;
    231     }
    232 
    233     public X500Name getIssuer()
    234     {
    235         return issuer;
    236     }
    237 
    238     public Time getThisUpdate()
    239     {
    240         return thisUpdate;
    241     }
    242 
    243     public Time getNextUpdate()
    244     {
    245         return nextUpdate;
    246     }
    247 
    248     public CRLEntry[] getRevokedCertificates()
    249     {
    250         if (revokedCertificates == null)
    251         {
    252             return new CRLEntry[0];
    253         }
    254 
    255         CRLEntry[] entries = new CRLEntry[revokedCertificates.size()];
    256 
    257         for (int i = 0; i < entries.length; i++)
    258         {
    259             entries[i] = CRLEntry.getInstance(revokedCertificates.getObjectAt(i));
    260         }
    261 
    262         return entries;
    263     }
    264 
    265     public Enumeration getRevokedCertificateEnumeration()
    266     {
    267         if (revokedCertificates == null)
    268         {
    269             return new EmptyEnumeration();
    270         }
    271 
    272         return new RevokedCertificatesEnumeration(revokedCertificates.getObjects());
    273     }
    274 
    275     public Extensions getExtensions()
    276     {
    277         return crlExtensions;
    278     }
    279 
    280     public ASN1Primitive toASN1Primitive()
    281     {
    282         ASN1EncodableVector v = new ASN1EncodableVector();
    283 
    284         if (version != null)
    285         {
    286             v.add(version);
    287         }
    288         v.add(signature);
    289         v.add(issuer);
    290 
    291         v.add(thisUpdate);
    292         if (nextUpdate != null)
    293         {
    294             v.add(nextUpdate);
    295         }
    296 
    297         // Add CRLEntries if they exist
    298         if (revokedCertificates != null)
    299         {
    300             v.add(revokedCertificates);
    301         }
    302 
    303         if (crlExtensions != null)
    304         {
    305             v.add(new DERTaggedObject(0, crlExtensions));
    306         }
    307 
    308         return new DERSequence(v);
    309     }
    310 }
    311