KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > core > ejb > ca > crl > CreateCRLSessionBean


1 /*************************************************************************
2  * *
3  * EJBCA: The OpenSource Certificate Authority *
4  * *
5  * This software is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU Lesser General Public *
7  * License as published by the Free Software Foundation; either *
8  * version 2.1 of the License, or any later version. *
9  * *
10  * See terms of license at gnu.org. *
11  * *
12  *************************************************************************/

13
14 package org.ejbca.core.ejb.ca.crl;
15
16 import java.math.BigInteger JavaDoc;
17 import java.security.cert.X509CRL JavaDoc;
18 import java.util.Collection JavaDoc;
19 import java.util.Date JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.Vector JavaDoc;
22
23 import javax.ejb.CreateException JavaDoc;
24 import javax.ejb.EJBException JavaDoc;
25
26 import org.ejbca.core.ejb.BaseSessionBean;
27 import org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocal;
28 import org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocalHome;
29 import org.ejbca.core.ejb.ca.sign.ISignSessionLocal;
30 import org.ejbca.core.ejb.ca.sign.ISignSessionLocalHome;
31 import org.ejbca.core.ejb.ca.store.CertificateDataBean;
32 import org.ejbca.core.ejb.ca.store.CertificateDataLocal;
33 import org.ejbca.core.ejb.ca.store.CertificateDataLocalHome;
34 import org.ejbca.core.ejb.ca.store.CertificateDataPK;
35 import org.ejbca.core.ejb.ca.store.ICertificateStoreSessionLocal;
36 import org.ejbca.core.ejb.ca.store.ICertificateStoreSessionLocalHome;
37 import org.ejbca.core.ejb.log.ILogSessionLocal;
38 import org.ejbca.core.ejb.log.ILogSessionLocalHome;
39 import org.ejbca.core.model.InternalResources;
40 import org.ejbca.core.model.SecConst;
41 import org.ejbca.core.model.ca.caadmin.CADoesntExistsException;
42 import org.ejbca.core.model.ca.caadmin.CAInfo;
43 import org.ejbca.core.model.ca.caadmin.X509CAInfo;
44 import org.ejbca.core.model.ca.catoken.CATokenOfflineException;
45 import org.ejbca.core.model.ca.crl.RevokedCertInfo;
46 import org.ejbca.core.model.ca.store.CRLInfo;
47 import org.ejbca.core.model.log.Admin;
48 import org.ejbca.core.model.log.LogEntry;
49 import org.ejbca.util.CertTools;
50
51
52 /**
53  * Generates a new CRL by looking in the database for revoked certificates and
54  * generating a CRL.
55  *
56  * @version $Id: CreateCRLSessionBean.java,v 1.15 2007/01/16 11:42:23 anatom Exp $
57  * @ejb.bean
58  * description="Session bean handling hard token data, both about hard tokens and hard token issuers."
59  * display-name="CreateCRLSB"
60  * name="CreateCRLSession"
61  * jndi-name="CreateCRLSession"
62  * local-jndi-name="CreateCRLSessionLocal"
63  * view-type="both"
64  * type="Stateless"
65  * transaction-type="Container"
66  *
67  * @ejb.transaction type="Required"
68  *
69  * @weblogic.enable-call-by-reference True
70  *
71  * @ejb.home
72  * extends="javax.ejb.EJBHome"
73  * local-extends="javax.ejb.EJBLocalHome"
74  * local-class="org.ejbca.core.ejb.ca.crl.ICreateCRLSessionLocalHome"
75  * remote-class="org.ejbca.core.ejb.ca.crl.ICreateCRLSessionHome"
76  *
77  * @ejb.interface
78  * extends="javax.ejb.EJBObject"
79  * local-extends="javax.ejb.EJBLocalObject"
80  * local-class="org.ejbca.core.ejb.ca.crl.ICreateCRLSessionLocal"
81  * remote-class="org.ejbca.core.ejb.ca.crl.ICreateCRLSessionRemote"
82  *
83  * @ejb.ejb-external-ref
84  * description="The log session bean"
85  * view-type="local"
86  * ref-name="ejb/LogSessionLocal"
87  * type="Session"
88  * home="org.ejbca.core.ejb.log.ILogSessionLocalHome"
89  * business="org.ejbca.core.ejb.log.ILogSessionLocal"
90  * link="LogSession"
91  *
92  * @ejb.ejb-external-ref
93  * description="The Certificate entity bean used manipulate certificates"
94  * view-type="local"
95  * ref-name="ejb/CertificateDataLocal"
96  * type="Entity"
97  * home="org.ejbca.core.ejb.ca.store.CertificateDataLocalHome"
98  * business="org.ejbca.core.ejb.ca.store.CertificateDataLocal"
99  * link="CertificateData"
100  *
101  * @ejb.ejb-external-ref
102  * description="The CA Admin Session"
103  * view-type="local"
104  * ref-name="ejb/CAAdminSessionLocal"
105  * type="Session"
106  * home="org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocalHome"
107  * business="org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocal"
108  * link="CAAdminSession"
109  *
110  * @ejb.ejb-external-ref
111  * description="The Certificate Store session bean"
112  * view-type="local"
113  * ref-name="ejb/CertificateStoreSessionLocal"
114  * type="Session"
115  * home="org.ejbca.core.ejb.ca.store.ICertificateStoreSessionLocalHome"
116  * business="org.ejbca.core.ejb.ca.store.ICertificateStoreSessionLocal"
117  * link="CertificateStoreSession"
118  *
119  * @ejb.ejb-external-ref
120  * description="The signing session used to create CRL"
121  * view-type="local"
122  * ref-name="ejb/RSASignSessionLocal"
123  * type="Session"
124  * home="org.ejbca.core.ejb.ca.sign.ISignSessionLocalHome"
125  * business="org.ejbca.core.ejb.ca.sign.ISignSessionLocal"
126  * link="RSASignSession"
127  *
128  */

129 public class CreateCRLSessionBean extends BaseSessionBean {
130
131     /** Internal localization of logs and errors */
132     private static final InternalResources intres = InternalResources.getInstance();
133     
134     /** The local home interface of Certificate store */
135     private ICertificateStoreSessionLocalHome storeHome = null;
136
137     /** The local home interface of Certificate entity bean */
138     private CertificateDataLocalHome certHome = null;
139
140     /** The local home interface of the signing session */
141     private ISignSessionLocalHome signHome = null;
142
143     /** The local home interface of the caadmin session */
144     private ICAAdminSessionLocalHome caadminHome = null;
145
146     /** The local interface of the log session bean */
147     private ILogSessionLocal logsession;
148
149
150     /** Default create for SessionBean without any creation Arguments.
151      * @throws CreateException if bean instance can't be created
152      */

153     public void ejbCreate () throws CreateException JavaDoc {
154         caadminHome = (ICAAdminSessionLocalHome)getLocator().getLocalHome(ICAAdminSessionLocalHome.COMP_NAME);
155         storeHome = (ICertificateStoreSessionLocalHome)getLocator().getLocalHome(ICertificateStoreSessionLocalHome.COMP_NAME);
156         certHome = (CertificateDataLocalHome)getLocator().getLocalHome(CertificateDataLocalHome.COMP_NAME);
157         signHome = (ISignSessionLocalHome)getLocator().getLocalHome(ISignSessionLocalHome.COMP_NAME);
158         ILogSessionLocalHome logsessionhome = (ILogSessionLocalHome) getLocator().getLocalHome(ILogSessionLocalHome.COMP_NAME);
159         logsession = logsessionhome.create();
160     }
161
162     /**
163      * Generates a new CRL by looking in the database for revoked certificates and generating a
164      * CRL.
165      *
166      * @param admin administrator performing the task
167      * @param issuerdn of the ca (normalized for EJBCA)
168      *
169      * @throws EJBException om ett kommunikations eller systemfel intr?ffar.
170      * @ejb.interface-method
171      */

172     public void run(Admin admin, String JavaDoc issuerdn) throws CATokenOfflineException {
173         debug(">run()");
174         int caid = issuerdn.hashCode();
175         try {
176             ICAAdminSessionLocal caadmin = caadminHome.create();
177             ICertificateStoreSessionLocal store = storeHome.create();
178
179             CAInfo cainfo = caadmin.getCAInfo(admin, caid);
180             if (cainfo == null) {
181                 throw new CADoesntExistsException("CA not found: "+issuerdn);
182             }
183             int crlperiod = cainfo.getCRLPeriod();
184             // Find all revoked certificates
185
Collection JavaDoc revcerts = store.listRevokedCertificates(admin, issuerdn);
186             debug("Found "+revcerts.size()+" revoked certificates.");
187
188             // Go through them and create a CRL, at the same time archive expired certificates
189
Date JavaDoc now = new Date JavaDoc();
190             // crlperiod is hours = crlperiod*60*60*1000 milliseconds
191
now.setTime(now.getTime() - (crlperiod * 60 * 60 * 1000));
192             Vector JavaDoc certs = new Vector JavaDoc();
193             Iterator JavaDoc iter = revcerts.iterator();
194             while (iter.hasNext()) {
195                 CertificateDataPK pk = new CertificateDataPK((String JavaDoc)iter.next());
196                 CertificateDataLocal data = certHome.findByPrimaryKey(pk);
197                 // We want to include certificates that was revoked after the last CRL was issued, but before this one
198
// so the revoked certs are included in ONE CRL at least.
199
if ( (data.getStatus() == CertificateDataBean.CERT_REVOKED) &&
200                     (data.getExpireDate() < now.getTime()) )
201                 {
202                         data.setStatus(CertificateDataBean.CERT_ARCHIVED);
203                 } else
204                 {
205                     if (data.getRevocationDate() == -1)
206                         data.setRevocationDate((new Date JavaDoc()).getTime());
207                     RevokedCertInfo certinfo = new RevokedCertInfo(new BigInteger JavaDoc(data.getSerialNumber()),new Date JavaDoc(data.getRevocationDate()), data.getRevocationReason());
208                     certs.add(certinfo);
209                 }
210             }
211             ISignSessionLocal sign = signHome.create();
212             byte[] crlBytes = sign.createCRL(admin, caid, certs);
213             // This is logged in the database by SignSession
214
String JavaDoc msg = intres.getLocalizedMessage("createcrl.createdcrl", cainfo.getName(), cainfo.getSubjectDN());
215             log.info(msg);
216             if (log.isDebugEnabled()) {
217                 X509CRL JavaDoc crl = CertTools.getCRLfromByteArray(crlBytes);
218                 debug("Created CRL with expire date: "+crl.getNextUpdate());
219 // FileOutputStream fos = new FileOutputStream("c:\\java\\srvtestcrl.der");
220
// fos.write(crl.getEncoded());
221
// fos.close();
222
}
223
224         } catch (CATokenOfflineException e) {
225             throw e;
226         } catch (Exception JavaDoc e) {
227             String JavaDoc msg = intres.getLocalizedMessage("createcrl.errorcreate", new Integer JavaDoc(caid));
228             log.error(msg, e);
229             logsession.log(admin, caid, LogEntry.MODULE_CA, new java.util.Date JavaDoc(),null, null, LogEntry.EVENT_ERROR_CREATECRL, msg, e);
230             throw new EJBException JavaDoc(e);
231         }
232         debug("<run()");
233     }
234
235
236     /**
237      * Method that checks if there are any CRLs needed to be updated and then creates their
238      * CRLs. No overlap is used. This method can be called by a scheduler or a service.
239      *
240      * @param admin administrator performing the task
241      *
242      * @return the number of crls created.
243      * @throws EJBException om ett kommunikations eller systemfel intr?ffar.
244      * @ejb.interface-method
245      */

246     public int createCRLs(Admin admin) {
247         return createCRLs(admin, 0);
248     }
249     
250     /**
251      * Method that checks if there are any CRLs needed to be updated and then creates their
252      * CRLs. A CRL is created:
253      * 1. if the current CRL expires within the crloverlaptime (milliseconds)
254      * 2. if a crl issue interval is defined (>0) a CRL is issued when this interval has passed, even if the current CRL is still valid
255      *
256      * This method can be called by a scheduler or a service.
257      *
258      * @param admin administrator performing the task
259      * @param addtocrloverlaptime given in milliseconds and added to the CRL overlap time, if set to how often this method is run (poll time), it can be used to issue a new CRL if the current one expires within
260      * the CRL overlap time (configured in CA) and the poll time. The used CRL overlap time will be (crloverlaptime + addtocrloverlaptime)
261      *
262      * @return the number of crls created.
263      * @throws EJBException om ett kommunikations eller systemfel intr?ffar.
264      * @ejb.interface-method
265      */

266     public int createCRLs(Admin admin, long addtocrloverlaptime) {
267         int createdcrls = 0;
268         try {
269             Date JavaDoc currenttime = new Date JavaDoc();
270             ICAAdminSessionLocal caadmin = caadminHome.create();
271             ICertificateStoreSessionLocal store = storeHome.create();
272
273             Iterator JavaDoc iter = caadmin.getAvailableCAs(admin).iterator();
274             while(iter.hasNext()){
275                 int caid = ((Integer JavaDoc) iter.next()).intValue();
276                 log.debug("createCRLs for caid: "+caid);
277                 try {
278                    CAInfo cainfo = caadmin.getCAInfo(admin, caid);
279                    if (cainfo instanceof X509CAInfo) {
280                        if (cainfo.getStatus() == SecConst.CA_OFFLINE ) {
281                            String JavaDoc msg = intres.getLocalizedMessage("createcrl.caoffline", cainfo.getName(), new Integer JavaDoc(caid));
282                            log.error(msg);
283                            logsession.log(admin, caid, LogEntry.MODULE_CA, new java.util.Date JavaDoc(),null, null, LogEntry.EVENT_ERROR_CREATECRL, msg);
284                        } else {
285                            try {
286                                if (log.isDebugEnabled()) {
287                                    log.debug("Checking to see if CA '"+cainfo.getName()+"' needs CRL generation.");
288                                }
289                                CRLInfo crlinfo = store.getLastCRLInfo(admin,cainfo.getSubjectDN());
290                                if (log.isDebugEnabled()) {
291                                    if (crlinfo == null) {
292                                        log.debug("Crlinfo was null");
293                                    } else {
294                                        log.debug("Read crlinfo for CA: "+cainfo.getName()+", lastNumber="+crlinfo.getLastCRLNumber()+", expireDate="+crlinfo.getExpireDate());
295                                    }
296                                }
297                                int crlissueinterval = cainfo.getCRLIssueInterval();
298                                if (log.isDebugEnabled()) {
299                                    log.debug("crlissueinterval="+crlissueinterval);
300                                    log.debug("crloverlaptime="+cainfo.getCRLOverlapTime());
301                                }
302                                long overlap = (cainfo.getCRLOverlapTime() * 60 * 1000) + addtocrloverlaptime; // Overlaptime is in minutes, default if crlissueinterval == 0
303
long nextUpdate = 0; // if crlinfo == 0, we will issue a crl now
304
if (crlinfo != null) {
305                                    // CRL issueinterval in hours. If this is 0, we should only issue a CRL when
306
// the old one is about to expire, i.e. when currenttime + overlaptime > expiredate
307
// if isseuinterval is > 0 we will issue a new CRL when currenttime > createtime + issueinterval
308
nextUpdate = crlinfo.getExpireDate().getTime(); // Default if crlissueinterval == 0
309
if (crlissueinterval > 0) {
310                                        long crlissueintervalmillisec = ((long)crlissueinterval) * 60 * 60 * 1000;
311                                        if (log.isDebugEnabled()) {
312                                            log.debug("crlissueinterval milliseconds: "+crlissueintervalmillisec);
313                                        }
314                                        long u = crlinfo.getCreateDate().getTime() + (crlissueintervalmillisec);
315                                        // If this period for some reason (we missed to issue some?) is larger than when the CRL expires,
316
// we need to issue one when the CRL expires
317
if ((u + overlap) < nextUpdate) {
318                                            nextUpdate = u;
319                                            // When we issue CRLs before the real expiration date we don't use overlap
320
overlap = 0;
321                                        }
322                                    }
323                                    log.debug("Calculated nextUpdate to "+nextUpdate);
324                                } else {
325                                    String JavaDoc msg = intres.getLocalizedMessage("createcrl.crlinfonull");
326                                    log.info(msg);
327                                }
328                                if ((currenttime.getTime() + overlap) >= nextUpdate) {
329                                    if (log.isDebugEnabled()) {
330                                        log.debug("Creating CRL for CA, because:"+currenttime.getTime()+overlap+" >= "+nextUpdate);
331                                    }
332                                    this.run(admin, cainfo.getSubjectDN());
333                                    createdcrls++;
334                                }
335                                
336                            } catch (CATokenOfflineException e) {
337                                String JavaDoc msg = intres.getLocalizedMessage("createcrl.caoffline", cainfo.getName(), new Integer JavaDoc(caid));
338                                log.error(msg);
339                                logsession.log(admin, caid, LogEntry.MODULE_CA, new java.util.Date JavaDoc(),null, null, LogEntry.EVENT_ERROR_CREATECRL, msg);
340                            }
341                        }
342                    }
343                 } catch(Exception JavaDoc e) {
344                     String JavaDoc msg = intres.getLocalizedMessage("createcrl.generalerror", new Integer JavaDoc(caid));
345                     error(msg, e);
346                     logsession.log(admin, caid, LogEntry.MODULE_CA, new java.util.Date JavaDoc(),null, null, LogEntry.EVENT_ERROR_CREATECRL,msg,e);
347                     if (e instanceof EJBException JavaDoc) {
348                         throw (EJBException JavaDoc)e;
349                     }
350                     throw new EJBException JavaDoc(e);
351                 }
352             }
353         } catch (Exception JavaDoc e) {
354             String JavaDoc msg = intres.getLocalizedMessage("createcrl.erroravailcas");
355             error(msg, e);
356             logsession.log(admin, admin.getCaId(), LogEntry.MODULE_CA, new java.util.Date JavaDoc(),null, null, LogEntry.EVENT_ERROR_CREATECRL,msg,e);
357             if (e instanceof EJBException JavaDoc) {
358                 throw (EJBException JavaDoc)e;
359             }
360             throw new EJBException JavaDoc(e);
361         }
362
363         return createdcrls;
364     }
365
366 }
367
368
Popular Tags