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