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