• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.jce.provider;
2 
3 import org.bouncycastle.asn1.ASN1Encodable;
4 import org.bouncycastle.asn1.ASN1InputStream;
5 import org.bouncycastle.asn1.ASN1Sequence;
6 import org.bouncycastle.asn1.DEREnumerated;
7 import org.bouncycastle.asn1.DERObjectIdentifier;
8 import org.bouncycastle.asn1.DEROutputStream;
9 import org.bouncycastle.asn1.util.ASN1Dump;
10 import org.bouncycastle.asn1.x509.CRLReason;
11 import org.bouncycastle.asn1.x509.GeneralName;
12 import org.bouncycastle.asn1.x509.GeneralNames;
13 import org.bouncycastle.asn1.x509.TBSCertList;
14 import org.bouncycastle.asn1.x509.X509Extension;
15 import org.bouncycastle.asn1.x509.X509Extensions;
16 import org.bouncycastle.x509.extension.X509ExtensionUtil;
17 
18 import javax.security.auth.x500.X500Principal;
19 import java.io.ByteArrayOutputStream;
20 import java.io.IOException;
21 import java.math.BigInteger;
22 import java.security.cert.CRLException;
23 import java.security.cert.X509CRLEntry;
24 import java.util.Date;
25 import java.util.Enumeration;
26 import java.util.HashSet;
27 import java.util.Set;
28 
29 /**
30  * The following extensions are listed in RFC 2459 as relevant to CRL Entries
31  *
32  * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer
33  * (critical)
34  */
35 public class X509CRLEntryObject extends X509CRLEntry
36 {
37     private TBSCertList.CRLEntry c;
38 
39     private boolean isIndirect;
40 
41     private X500Principal previousCertificateIssuer;
42     private X500Principal certificateIssuer;
43     private int           hashValue;
44     private boolean       isHashValueSet;
45 
X509CRLEntryObject(TBSCertList.CRLEntry c)46     public X509CRLEntryObject(TBSCertList.CRLEntry c)
47     {
48         this.c = c;
49         this.certificateIssuer = loadCertificateIssuer();
50     }
51 
52     /**
53      * Constructor for CRLEntries of indirect CRLs. If <code>isIndirect</code>
54      * is <code>false</code> {@link #getCertificateIssuer()} will always
55      * return <code>null</code>, <code>previousCertificateIssuer</code> is
56      * ignored. If this <code>isIndirect</code> is specified and this CRLEntry
57      * has no certificate issuer CRL entry extension
58      * <code>previousCertificateIssuer</code> is returned by
59      * {@link #getCertificateIssuer()}.
60      *
61      * @param c
62      *            TBSCertList.CRLEntry object.
63      * @param isIndirect
64      *            <code>true</code> if the corresponding CRL is a indirect
65      *            CRL.
66      * @param previousCertificateIssuer
67      *            Certificate issuer of the previous CRLEntry.
68      */
X509CRLEntryObject( TBSCertList.CRLEntry c, boolean isIndirect, X500Principal previousCertificateIssuer)69     public X509CRLEntryObject(
70         TBSCertList.CRLEntry c,
71         boolean isIndirect,
72         X500Principal previousCertificateIssuer)
73     {
74         this.c = c;
75         this.isIndirect = isIndirect;
76         this.previousCertificateIssuer = previousCertificateIssuer;
77         this.certificateIssuer = loadCertificateIssuer();
78     }
79 
80     /**
81      * Will return true if any extensions are present and marked as critical as
82      * we currently dont handle any extensions!
83      */
hasUnsupportedCriticalExtension()84     public boolean hasUnsupportedCriticalExtension()
85     {
86         Set extns = getCriticalExtensionOIDs();
87 
88         return extns != null && !extns.isEmpty();
89     }
90 
loadCertificateIssuer()91     private X500Principal loadCertificateIssuer()
92     {
93         if (!isIndirect)
94         {
95             return null;
96         }
97 
98         byte[] ext = getExtensionValue(X509Extensions.CertificateIssuer.getId());
99         if (ext == null)
100         {
101             return previousCertificateIssuer;
102         }
103 
104         try
105         {
106             GeneralName[] names = GeneralNames.getInstance(
107                     X509ExtensionUtil.fromExtensionValue(ext)).getNames();
108             for (int i = 0; i < names.length; i++)
109             {
110                 if (names[i].getTagNo() == GeneralName.directoryName)
111                 {
112                     return new X500Principal(names[i].getName().getDERObject().getDEREncoded());
113                 }
114             }
115             return null;
116         }
117         catch (IOException e)
118         {
119             return null;
120         }
121     }
122 
getCertificateIssuer()123     public X500Principal getCertificateIssuer()
124     {
125         return certificateIssuer;
126     }
127 
getExtensionOIDs(boolean critical)128     private Set getExtensionOIDs(boolean critical)
129     {
130         X509Extensions extensions = c.getExtensions();
131 
132         if (extensions != null)
133         {
134             Set set = new HashSet();
135             Enumeration e = extensions.oids();
136 
137             while (e.hasMoreElements())
138             {
139                 DERObjectIdentifier oid = (DERObjectIdentifier) e.nextElement();
140                 X509Extension ext = extensions.getExtension(oid);
141 
142                 if (critical == ext.isCritical())
143                 {
144                     set.add(oid.getId());
145                 }
146             }
147 
148             return set;
149         }
150 
151         return null;
152     }
153 
getCriticalExtensionOIDs()154     public Set getCriticalExtensionOIDs()
155     {
156         return getExtensionOIDs(true);
157     }
158 
getNonCriticalExtensionOIDs()159     public Set getNonCriticalExtensionOIDs()
160     {
161         return getExtensionOIDs(false);
162     }
163 
getExtensionValue(String oid)164     public byte[] getExtensionValue(String oid)
165     {
166         X509Extensions exts = c.getExtensions();
167 
168         if (exts != null)
169         {
170             X509Extension ext = exts.getExtension(new DERObjectIdentifier(oid));
171 
172             if (ext != null)
173             {
174                 try
175                 {
176                     return ext.getValue().getEncoded();
177                 }
178                 catch (Exception e)
179                 {
180                     throw new RuntimeException("error encoding " + e.toString());
181                 }
182             }
183         }
184 
185         return null;
186     }
187 
188     /**
189      * Cache the hashCode value - calculating it with the standard method.
190      * @return  calculated hashCode.
191      */
hashCode()192     public int hashCode()
193     {
194         if (!isHashValueSet)
195         {
196             hashValue = super.hashCode();
197             isHashValueSet = true;
198         }
199 
200         return hashValue;
201     }
202 
getEncoded()203     public byte[] getEncoded()
204         throws CRLException
205     {
206         try
207         {
208             return c.getEncoded(ASN1Encodable.DER);
209         }
210         catch (IOException e)
211         {
212             throw new CRLException(e.toString());
213         }
214     }
215 
getSerialNumber()216     public BigInteger getSerialNumber()
217     {
218         return c.getUserCertificate().getValue();
219     }
220 
getRevocationDate()221     public Date getRevocationDate()
222     {
223         return c.getRevocationDate().getDate();
224     }
225 
hasExtensions()226     public boolean hasExtensions()
227     {
228         return c.getExtensions() != null;
229     }
230 
toString()231     public String toString()
232     {
233         StringBuffer buf = new StringBuffer();
234         String nl = System.getProperty("line.separator");
235 
236         buf.append("      userCertificate: ").append(this.getSerialNumber()).append(nl);
237         buf.append("       revocationDate: ").append(this.getRevocationDate()).append(nl);
238         buf.append("       certificateIssuer: ").append(this.getCertificateIssuer()).append(nl);
239 
240         X509Extensions extensions = c.getExtensions();
241 
242         if (extensions != null)
243         {
244             Enumeration e = extensions.oids();
245             if (e.hasMoreElements())
246             {
247                 buf.append("   crlEntryExtensions:").append(nl);
248 
249                 while (e.hasMoreElements())
250                 {
251                     DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
252                     X509Extension ext = extensions.getExtension(oid);
253                     if (ext.getValue() != null)
254                     {
255                         byte[]                  octs = ext.getValue().getOctets();
256                         ASN1InputStream dIn = new ASN1InputStream(octs);
257                         buf.append("                       critical(").append(ext.isCritical()).append(") ");
258                         try
259                         {
260                             if (oid.equals(X509Extensions.ReasonCode))
261                             {
262                                 buf.append(new CRLReason(DEREnumerated.getInstance(dIn.readObject()))).append(nl);
263                             }
264                             else if (oid.equals(X509Extensions.CertificateIssuer))
265                             {
266                                 buf.append("Certificate issuer: ").append(new GeneralNames((ASN1Sequence)dIn.readObject())).append(nl);
267                             }
268                             else
269                             {
270                                 buf.append(oid.getId());
271                                 buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
272                             }
273                         }
274                         catch (Exception ex)
275                         {
276                             buf.append(oid.getId());
277                             buf.append(" value = ").append("*****").append(nl);
278                         }
279                     }
280                     else
281                     {
282                         buf.append(nl);
283                     }
284                 }
285             }
286         }
287 
288         return buf.toString();
289     }
290 }
291