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 
getObject(InputStream in)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 
X509V2AttributeCertificate( InputStream encIn)63     public X509V2AttributeCertificate(
64         InputStream encIn)
65         throws IOException
66     {
67         this(getObject(encIn));
68     }
69 
X509V2AttributeCertificate( byte[] encoded)70     public X509V2AttributeCertificate(
71         byte[]  encoded)
72         throws IOException
73     {
74         this(new ByteArrayInputStream(encoded));
75     }
76 
X509V2AttributeCertificate( AttributeCertificate cert)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 
getVersion()94     public int getVersion()
95     {
96         return cert.getAcinfo().getVersion().intValueExact() + 1;
97     }
98 
getSerialNumber()99     public BigInteger getSerialNumber()
100     {
101         return cert.getAcinfo().getSerialNumber().getValue();
102     }
103 
getHolder()104     public AttributeCertificateHolder getHolder()
105     {
106         return new AttributeCertificateHolder((ASN1Sequence)cert.getAcinfo().getHolder().toASN1Primitive());
107     }
108 
getIssuer()109     public AttributeCertificateIssuer getIssuer()
110     {
111         return new AttributeCertificateIssuer(cert.getAcinfo().getIssuer());
112     }
113 
getNotBefore()114     public Date getNotBefore()
115     {
116         return notBefore;
117     }
118 
getNotAfter()119     public Date getNotAfter()
120     {
121         return notAfter;
122     }
123 
getIssuerUniqueID()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 
checkValidity()144     public void checkValidity()
145         throws CertificateExpiredException, CertificateNotYetValidException
146     {
147         this.checkValidity(new Date());
148     }
149 
checkValidity( Date date)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 
getSignature()165     public byte[] getSignature()
166     {
167         return cert.getSignatureValue().getOctets();
168     }
169 
verify( PublicKey key, String provider)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 
getEncoded()202     public byte[] getEncoded()
203         throws IOException
204     {
205         return cert.getEncoded();
206     }
207 
getExtensionValue(String oid)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 
getExtensionOIDs( boolean critical)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 
getNonCriticalExtensionOIDs()259     public Set getNonCriticalExtensionOIDs()
260     {
261         return getExtensionOIDs(false);
262     }
263 
getCriticalExtensionOIDs()264     public Set getCriticalExtensionOIDs()
265     {
266         return getExtensionOIDs(true);
267     }
268 
hasUnsupportedCriticalExtension()269     public boolean hasUnsupportedCriticalExtension()
270     {
271         Set  extensions = getCriticalExtensionOIDs();
272 
273         return extensions != null && !extensions.isEmpty();
274     }
275 
getAttributes()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 
getAttributes(String oid)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 
equals( Object o)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 
hashCode()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