Home | History | Annotate | Download | only in x509
      1 package org.bouncycastle.x509;
      2 
      3 import java.io.ByteArrayInputStream;
      4 import java.io.IOException;
      5 import java.io.InputStream;
      6 import java.math.BigInteger;
      7 import java.security.InvalidKeyException;
      8 import java.security.NoSuchAlgorithmException;
      9 import java.security.NoSuchProviderException;
     10 import java.security.PublicKey;
     11 import java.security.Signature;
     12 import java.security.SignatureException;
     13 import java.security.cert.CertificateException;
     14 import java.security.cert.CertificateExpiredException;
     15 import java.security.cert.CertificateNotYetValidException;
     16 import java.text.ParseException;
     17 import java.util.ArrayList;
     18 import java.util.Date;
     19 import java.util.Enumeration;
     20 import java.util.HashSet;
     21 import java.util.List;
     22 import java.util.Set;
     23 
     24 import org.bouncycastle.asn1.ASN1Encodable;
     25 import org.bouncycastle.asn1.ASN1InputStream;
     26 import org.bouncycastle.asn1.ASN1Sequence;
     27 import org.bouncycastle.asn1.DERBitString;
     28 import org.bouncycastle.asn1.DERObjectIdentifier;
     29 import org.bouncycastle.asn1.x509.AttributeCertificate;
     30 import org.bouncycastle.asn1.x509.X509Extension;
     31 import org.bouncycastle.asn1.x509.X509Extensions;
     32 import org.bouncycastle.util.Arrays;
     33 
     34 /**
     35  * An implementation of a version 2 X.509 Attribute Certificate.
     36  * @deprecated use org.bouncycastle.cert.X509AttributeCertificateHolder
     37  */
     38 public class X509V2AttributeCertificate
     39     implements X509AttributeCertificate
     40 {
     41     private AttributeCertificate    cert;
     42     private Date                    notBefore;
     43     private Date                    notAfter;
     44 
     45     private static AttributeCertificate getObject(InputStream in)
     46         throws IOException
     47     {
     48         try
     49         {
     50             return AttributeCertificate.getInstance(new ASN1InputStream(in).readObject());
     51         }
     52         catch (IOException e)
     53         {
     54             throw e;
     55         }
     56         catch (Exception e)
     57         {
     58             throw new IOException("exception decoding certificate structure: " + e.toString());
     59         }
     60     }
     61 
     62     public X509V2AttributeCertificate(
     63         InputStream encIn)
     64         throws IOException
     65     {
     66         this(getObject(encIn));
     67     }
     68 
     69     public X509V2AttributeCertificate(
     70         byte[]  encoded)
     71         throws IOException
     72     {
     73         this(new ByteArrayInputStream(encoded));
     74     }
     75 
     76     X509V2AttributeCertificate(
     77         AttributeCertificate    cert)
     78         throws IOException
     79     {
     80         this.cert = cert;
     81 
     82         try
     83         {
     84             this.notAfter = cert.getAcinfo().getAttrCertValidityPeriod().getNotAfterTime().getDate();
     85             this.notBefore = cert.getAcinfo().getAttrCertValidityPeriod().getNotBeforeTime().getDate();
     86         }
     87         catch (ParseException e)
     88         {
     89             throw new IOException("invalid data structure in certificate!");
     90         }
     91     }
     92 
     93     public int getVersion()
     94     {
     95         return cert.getAcinfo().getVersion().getValue().intValue() + 1;
     96     }
     97 
     98     public BigInteger getSerialNumber()
     99     {
    100         return cert.getAcinfo().getSerialNumber().getValue();
    101     }
    102 
    103     public AttributeCertificateHolder getHolder()
    104     {
    105         return new AttributeCertificateHolder((ASN1Sequence)cert.getAcinfo().getHolder().toASN1Object());
    106     }
    107 
    108     public AttributeCertificateIssuer getIssuer()
    109     {
    110         return new AttributeCertificateIssuer(cert.getAcinfo().getIssuer());
    111     }
    112 
    113     public Date getNotBefore()
    114     {
    115         return notBefore;
    116     }
    117 
    118     public Date getNotAfter()
    119     {
    120         return notAfter;
    121     }
    122 
    123     public boolean[] getIssuerUniqueID()
    124     {
    125         DERBitString    id = cert.getAcinfo().getIssuerUniqueID();
    126 
    127         if (id != null)
    128         {
    129             byte[]          bytes = id.getBytes();
    130             boolean[]       boolId = new boolean[bytes.length * 8 - id.getPadBits()];
    131 
    132             for (int i = 0; i != boolId.length; i++)
    133             {
    134                 boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
    135             }
    136 
    137             return boolId;
    138         }
    139 
    140         return null;
    141     }
    142 
    143     public void checkValidity()
    144         throws CertificateExpiredException, CertificateNotYetValidException
    145     {
    146         this.checkValidity(new Date());
    147     }
    148 
    149     public void checkValidity(
    150         Date    date)
    151         throws CertificateExpiredException, CertificateNotYetValidException
    152     {
    153         if (date.after(this.getNotAfter()))
    154         {
    155             throw new CertificateExpiredException("certificate expired on " + this.getNotAfter());
    156         }
    157 
    158         if (date.before(this.getNotBefore()))
    159         {
    160             throw new CertificateNotYetValidException("certificate not valid till " + this.getNotBefore());
    161         }
    162     }
    163 
    164     public byte[] getSignature()
    165     {
    166         return cert.getSignatureValue().getBytes();
    167     }
    168 
    169     public final void verify(
    170             PublicKey   key,
    171             String      provider)
    172             throws CertificateException, NoSuchAlgorithmException,
    173             InvalidKeyException, NoSuchProviderException, SignatureException
    174     {
    175         Signature   signature = null;
    176 
    177         if (!cert.getSignatureAlgorithm().equals(cert.getAcinfo().getSignature()))
    178         {
    179             throw new CertificateException("Signature algorithm in certificate info not same as outer certificate");
    180         }
    181 
    182         signature = Signature.getInstance(cert.getSignatureAlgorithm().getObjectId().getId(), provider);
    183 
    184         signature.initVerify(key);
    185 
    186         try
    187         {
    188             signature.update(cert.getAcinfo().getEncoded());
    189         }
    190         catch (IOException e)
    191         {
    192             throw new SignatureException("Exception encoding certificate info object");
    193         }
    194 
    195         if (!signature.verify(this.getSignature()))
    196         {
    197             throw new InvalidKeyException("Public key presented not for certificate signature");
    198         }
    199     }
    200 
    201     public byte[] getEncoded()
    202         throws IOException
    203     {
    204         return cert.getEncoded();
    205     }
    206 
    207     public byte[] getExtensionValue(String oid)
    208     {
    209         X509Extensions  extensions = cert.getAcinfo().getExtensions();
    210 
    211         if (extensions != null)
    212         {
    213             X509Extension   ext = extensions.getExtension(new DERObjectIdentifier(oid));
    214 
    215             if (ext != null)
    216             {
    217                 try
    218                 {
    219                     return ext.getValue().getEncoded(ASN1Encodable.DER);
    220                 }
    221                 catch (Exception e)
    222                 {
    223                     throw new RuntimeException("error encoding " + e.toString());
    224                 }
    225             }
    226         }
    227 
    228         return null;
    229     }
    230 
    231     private Set getExtensionOIDs(
    232         boolean critical)
    233     {
    234         X509Extensions  extensions = cert.getAcinfo().getExtensions();
    235 
    236         if (extensions != null)
    237         {
    238             Set             set = new HashSet();
    239             Enumeration     e = extensions.oids();
    240 
    241             while (e.hasMoreElements())
    242             {
    243                 DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
    244                 X509Extension       ext = extensions.getExtension(oid);
    245 
    246                 if (ext.isCritical() == critical)
    247                 {
    248                     set.add(oid.getId());
    249                 }
    250             }
    251 
    252             return set;
    253         }
    254 
    255         return null;
    256     }
    257 
    258     public Set getNonCriticalExtensionOIDs()
    259     {
    260         return getExtensionOIDs(false);
    261     }
    262 
    263     public Set getCriticalExtensionOIDs()
    264     {
    265         return getExtensionOIDs(true);
    266     }
    267 
    268     public boolean hasUnsupportedCriticalExtension()
    269     {
    270         Set  extensions = getCriticalExtensionOIDs();
    271 
    272         return extensions != null && !extensions.isEmpty();
    273     }
    274 
    275     public X509Attribute[] getAttributes()
    276     {
    277         ASN1Sequence    seq = cert.getAcinfo().getAttributes();
    278         X509Attribute[] attrs = new X509Attribute[seq.size()];
    279 
    280         for (int i = 0; i != seq.size(); i++)
    281         {
    282             attrs[i] = new X509Attribute((ASN1Encodable)seq.getObjectAt(i));
    283         }
    284 
    285         return attrs;
    286     }
    287 
    288     public X509Attribute[] getAttributes(String oid)
    289     {
    290         ASN1Sequence    seq = cert.getAcinfo().getAttributes();
    291         List            list = new ArrayList();
    292 
    293         for (int i = 0; i != seq.size(); i++)
    294         {
    295             X509Attribute attr = new X509Attribute((ASN1Encodable)seq.getObjectAt(i));
    296             if (attr.getOID().equals(oid))
    297             {
    298                 list.add(attr);
    299             }
    300         }
    301 
    302         if (list.size() == 0)
    303         {
    304             return null;
    305         }
    306 
    307         return (X509Attribute[])list.toArray(new X509Attribute[list.size()]);
    308     }
    309 
    310     public boolean equals(
    311         Object o)
    312     {
    313         if (o == this)
    314         {
    315             return true;
    316         }
    317 
    318         if (!(o instanceof X509AttributeCertificate))
    319         {
    320             return false;
    321         }
    322 
    323         X509AttributeCertificate other = (X509AttributeCertificate)o;
    324 
    325         try
    326         {
    327             byte[] b1 = this.getEncoded();
    328             byte[] b2 = other.getEncoded();
    329 
    330             return Arrays.areEqual(b1, b2);
    331         }
    332         catch (IOException e)
    333         {
    334             return false;
    335         }
    336     }
    337 
    338     public int hashCode()
    339     {
    340         try
    341         {
    342             return Arrays.hashCode(this.getEncoded());
    343         }
    344         catch (IOException e)
    345         {
    346             return 0;
    347         }
    348     }
    349 }
    350