001: /*************************************************************************
002: * *
003: * EJBCA: The OpenSource Certificate Authority *
004: * *
005: * This software is free software; you can redistribute it and/or *
006: * modify it under the terms of the GNU Lesser General Public *
007: * License as published by the Free Software Foundation; either *
008: * version 2.1 of the License, or any later version. *
009: * *
010: * See terms of license at gnu.org. *
011: * *
012: *************************************************************************/package org.ejbca.core.ejb.ca.store;
013:
014: import java.security.cert.Certificate;
015: import java.security.cert.CertificateEncodingException;
016: import java.security.cert.CertificateException;
017: import java.security.cert.X509Certificate;
018: import java.util.Date;
019:
020: import javax.ejb.CreateException;
021:
022: import org.apache.log4j.Logger;
023: import org.ejbca.core.ejb.BaseEntityBean;
024: import org.ejbca.core.model.SecConst;
025: import org.ejbca.core.model.ca.crl.RevokedCertInfo;
026: import org.ejbca.util.Base64;
027: import org.ejbca.util.CertTools;
028:
029: /**
030: * Entity Bean representing a certificate. Information stored:
031: * <pre>
032: * Certificate (base64Cert)
033: * Subject DN (subjectDN)
034: * Issuer DN (issuerDN)
035: * Serial number (serialNumber)
036: * SHA1 fingerprint (fingerprint)
037: * Status (status)
038: * Type (type; endentity, ca etc)
039: * CA SHA1 fingerprint (cAFingerprint)
040: * Expiration date (expireDate)
041: * Revocation date (revocationDate)
042: * Revocation reason (revocationReason)
043: * Username (username)
044: * </pre>
045: *
046: * @version $Id: CertificateDataBean.java,v 1.5 2006/11/10 09:28:51 anatom Exp $
047: *
048: * @ejb.bean description="This enterprise bean entity represents a certificate with accompanying data"
049: * display-name="CertificateDataEB"
050: * name="CertificateData"
051: * jndi-name="CertificateData"
052: * view-type="local"
053: * type="CMP"
054: * reentrant="False"
055: * cmp-version="2.x"
056: * transaction-type="Container"
057: * schema="CertificateDataBean"
058: *
059: * @ejb.transaction type="Required"
060: *
061: * @ejb.pk class="org.ejbca.core.ejb.ca.store.CertificateDataPK"
062: * extends="java.lang.Object"
063: * implements="java.io.Serializable"
064: *
065: * @ejb.persistence table-name = "CertificateData"
066: *
067: * @ejb.home
068: * generate="local"
069: * local-extends="javax.ejb.EJBLocalHome"
070: * local-class="org.ejbca.core.ejb.ca.store.CertificateDataLocalHome"
071: *
072: * @ejb.interface
073: * generate="local"
074: * local-extends="javax.ejb.EJBLocalObject"
075: * local-class="org.ejbca.core.ejb.ca.store.CertificateDataLocal"
076: *
077: * @ejb.finder description="findByExpireDate"
078: * signature="Collection findByExpireDate(long date)"
079: * query="SELECT OBJECT(a) from CertificateDataBean a WHERE a.expireDate<?1"
080: *
081: * @ejb.finder description="findBySubjectDNAndIssuerDN"
082: * signature="Collection findBySubjectDNAndIssuerDN(java.lang.String subjectDN, java.lang.String issuerDN)"
083: * query="SELECT OBJECT(a) from CertificateDataBean a WHERE a.subjectDN=?1 AND a.issuerDN=?2"
084: *
085: * @ejb.finder description="findBySubjectDN"
086: * signature="Collection findBySubjectDN(java.lang.String subjectDN)"
087: * query="SELECT OBJECT(a) from CertificateDataBean a WHERE a.subjectDN=?1"
088: *
089: * @ejb.finder description="findBySerialNumber"
090: * signature="Collection findBySerialNumber(java.lang.String sn)"
091: * query="SELECT OBJECT(a) from CertificateDataBean a WHERE a.serialNumber=?1"
092: *
093: * @ejb.finder description="findByIssuerDNSerialNumber"
094: * signature="Collection findByIssuerDNSerialNumber(java.lang.String issuerDN, java.lang.String serialNumber)"
095: * query="SELECT OBJECT(a) from CertificateDataBean a WHERE a.issuerDN=?1 AND a.serialNumber=?2"
096: *
097: * @ejb.finder description="findByUsername"
098: * signature="Collection findByUsername(java.lang.String username)"
099: * query="SELECT OBJECT(a) from CertificateDataBean a WHERE a.username=?1"
100: *
101: * @jonas.jdbc-mapping
102: * jndi-name="${datasource.jndi-name}"
103: */
104: public abstract class CertificateDataBean extends BaseEntityBean {
105:
106: /** Certificate doesn't belong to anyone */
107: public static final int CERT_UNASSIGNED = 0;
108:
109: /** Assigned, but not yet active */
110: public static final int CERT_INACTIVE = 10;
111:
112: /** Certificate is active and assigned */
113: public static final int CERT_ACTIVE = 20;
114:
115: /** Certificate is still active and the user is notified that it
116: * will soon expire. */
117: public static final int CERT_NOTIFIEDABOUTEXPIRATION = 21;
118:
119: /** Certificate is temporarily blocked (reversible) */
120: public static final int CERT_TEMP_REVOKED = 30;
121:
122: /** Certificate is permanently blocked (terminated) */
123: public static final int CERT_REVOKED = 40;
124:
125: /** Certificate is expired */
126: public static final int CERT_EXPIRED = 50;
127:
128: /** Certificate is expired and kept for archive purpose */
129: public static final int CERT_ARCHIVED = 60;
130:
131: // Certificate types used to create certificates
132: /** Certificate used for encryption. */
133: public static final int CERT_TYPE_ENCRYPTION = 0x1;
134:
135: /** Certificate used for digital signatures. */
136: public static final int CERT_TYPE_SIGNATURE = 0x2;
137:
138: /** Certificate used for both encryption and signatures. */
139: public static final int CERT_TYPE_ENCSIGN = 0x3;
140:
141: // Constants used in certificate generation and publication. */
142: /** Certificate belongs to an end entity. */
143: public static final int CERTTYPE_ENDENTITY = 0x1;
144: /** Certificate belongs to a sub ca. */
145: public static final int CERTTYPE_SUBCA = 0x2;
146: /** Certificate belongs to a root ca. */
147: public static final int CERTTYPE_ROOTCA = 0x8;
148: /** Certificate belongs on a hard token. */
149: public static final int CERTTYPE_HARDTOKEN = 0x16;
150:
151: // Constants used to contruct KeyUsage
152: /**
153: * @see org.ejbca.core.ejb.ca.sign.ISignSessionRemote
154: */
155: public static final int digitalSignature = (1 << 7);
156: public static final int nonRepudiation = (1 << 6);
157: public static final int keyEncipherment = (1 << 5);
158: public static final int dataEncipherment = (1 << 4);
159: public static final int keyAgreement = (1 << 3);
160: public static final int keyCertSign = (1 << 2);
161: public static final int cRLSign = (1 << 1);
162: public static final int encipherOnly = (1 << 0);
163: public static final int decipherOnly = (1 << 15);
164:
165: private static final Logger log = Logger
166: .getLogger(CertificateDataBean.class);
167:
168: /**
169: * DN of issuer of certificate
170: *
171: * @return issuer dn
172: * @ejb.persistence column-name="issuerDN"
173: * @ejb.interface-method
174: */
175: public abstract String getIssuerDN();
176:
177: /**
178: * Use setIssuer instead
179: *
180: * @param issuerDN issuer dn
181: *
182: * @see #setIssuer(String)
183: */
184: public abstract void setIssuerDN(String issuerDN);
185:
186: /**
187: * DN of subject in certificate
188: *
189: * @return subject dn
190: * @ejb.persistence column-name="subjectDN"
191: * @ejb.interface-method
192: */
193: public abstract String getSubjectDN();
194:
195: /**
196: * Use setSubject instead
197: *
198: * @param subjectDN subject dn
199: *
200: * @see #setSubject(String)
201: */
202: public abstract void setSubjectDN(String subjectDN);
203:
204: /**
205: * Fingerprint of certificate
206: *
207: * @return fingerprint
208: * @ejb.persistence column-name="fingerprint"
209: * @ejb.interface-method
210: * @ejb.pk-field
211: */
212: public abstract String getFingerprint();
213:
214: /**
215: * Fingerprint of certificate
216: *
217: * @param fingerprint fingerprint
218: */
219: public abstract void setFingerprint(String fingerprint);
220:
221: /**
222: * Fingerprint of CA certificate
223: *
224: * @return fingerprint
225: * @ejb.persistence column-name="cAFingerprint"
226: * @ejb.interface-method
227: */
228: public abstract String getCaFingerprint();
229:
230: /**
231: * Fingerprint of CA certificate
232: *
233: * @param cAFingerprint fingerprint
234: * @ejb.interface-method
235: */
236: public abstract void setCaFingerprint(String caFingerprint);
237:
238: /**
239: * status of certificate, ex CertificateData.CERT_ACTIVE
240: *
241: * @return status
242: * @ejb.persistence column-name="status"
243: * @ejb.interface-method
244: */
245: public abstract int getStatus();
246:
247: /**
248: * status of certificate, ex CertificateData.CERT_ACTIVE
249: *
250: * @param status status
251: * @ejb.interface-method
252: */
253: public abstract void setStatus(int status);
254:
255: /**
256: * What type of user the certificate belongs to, ex SecConst.USER_ENDUSER
257: *
258: * @return user type
259: * @ejb.persistence column-name="type"
260: * @ejb.interface-method
261: */
262: public abstract int getType();
263:
264: /**
265: * What type of user the certificate belongs to, ex SecConst.USER_ENDUSER
266: *
267: * @param type type
268: * @ejb.interface-method
269: */
270: public abstract void setType(int type);
271:
272: /**
273: * Serialnumber formated as BigInteger.toString()
274: *
275: * @return serial number
276: * @ejb.persistence column-name="serialNumber"
277: * @ejb.interface-method
278: */
279: public abstract String getSerialNumber();
280:
281: /**
282: * Serialnumber formated as BigInteger.toString()
283: *
284: * @param serialNumber serial number
285: * @ejb.interface-method
286: */
287: public abstract void setSerialNumber(String serialNumber);
288:
289: /**
290: * Date formated as seconds since 1970 (== Date.getTime())
291: *
292: * @return expire date
293: * @ejb.persistence column-name="expireDate"
294: * @ejb.interface-method
295: */
296: public abstract long getExpireDate();
297:
298: /**
299: * Date formated as seconds since 1970 (== Date.getTime())
300: *
301: * @param expireDate expire date
302: * @ejb.interface-method
303: */
304: public abstract void setExpireDate(long expireDate);
305:
306: /**
307: * Set to date when revocation occured if status== CERT_REVOKED. Format == Date.getTime()
308: *
309: * @return revocation date
310: * @ejb.persistence column-name="revocationDate"
311: * @ejb.interface-method
312: */
313: public abstract long getRevocationDate();
314:
315: /**
316: * Set to date when revocation occured if status== CERT_REVOKED. Format == Date.getTime()
317: *
318: * @param revocationDate revocation date
319: * @ejb.interface-method
320: */
321: public abstract void setRevocationDate(long revocationDate);
322:
323: /**
324: * Set to revocation reason if status== CERT_REVOKED
325: *
326: * @return revocation reason
327: * @ejb.persistence column-name="revocationReason"
328: * @ejb.interface-method
329: */
330: public abstract int getRevocationReason();
331:
332: /**
333: * Set to revocation reason if status== CERT_REVOKED
334: *
335: * @param revocationReason revocation reason
336: * @ejb.interface-method
337: */
338: public abstract void setRevocationReason(int revocationReason);
339:
340: /**
341: * certificate itself
342: *
343: * @return base64 encoded certificate
344: * @ejb.persistence jdbc-type="LONGVARCHAR" column-name="base64Cert"
345: * @ejb.interface-method
346: */
347: public abstract String getBase64Cert();
348:
349: /**
350: * certificate itself
351: *
352: * @param base64Cert base64 encoded certificate
353: * @ejb.interface-method
354: */
355: public abstract void setBase64Cert(String base64Cert);
356:
357: /**
358: * username in database
359: *
360: * @return username
361: * @ejb.persistence column-name="username"
362: * @ejb.interface-method
363: */
364: public abstract String getUsername();
365:
366: /**
367: * username must be called 'striped' using StringTools.strip()
368: *
369: * @param username username
370: *
371: * @see org.ejbca.util.StringTools
372: * @ejb.interface-method
373: */
374: public abstract void setUsername(String username);
375:
376: //
377: // Public business methods used to help us manage certificates
378: //
379:
380: /**
381: * certificate itself
382: *
383: * @return certificate
384: * @ejb.interface-method
385: */
386: public Certificate getCertificate() {
387: X509Certificate cert = null;
388: try {
389: cert = CertTools.getCertfromByteArray(Base64
390: .decode(getBase64Cert().getBytes()));
391: } catch (CertificateException ce) {
392: log.error("Can't decode certificate.", ce);
393: return null;
394: }
395: return cert;
396: }
397:
398: /**
399: * certificate itself
400: *
401: * @param incert certificate
402: * @ejb.interface-method
403: */
404: public void setCertificate(Certificate incert) {
405: try {
406: String b64Cert = new String(Base64.encode(incert
407: .getEncoded()));
408: setBase64Cert(b64Cert);
409:
410: X509Certificate tmpcert = (X509Certificate) incert;
411: String fp = CertTools.getFingerprintAsString(tmpcert);
412: setFingerprint(fp);
413: setSubjectDN(CertTools.getSubjectDN(tmpcert));
414: setIssuerDN(CertTools.getIssuerDN(tmpcert));
415: setSerialNumber(tmpcert.getSerialNumber().toString());
416: } catch (CertificateEncodingException cee) {
417: log
418: .error(
419: "Can't extract DER encoded certificate information.",
420: cee);
421: }
422: }
423:
424: /**
425: * DN of issuer of certificate
426: *
427: * @param dn issuer dn
428: * @ejb.interface-method
429: */
430: public void setIssuer(String dn) {
431: setIssuerDN(CertTools.stringToBCDNString(dn));
432: }
433:
434: /**
435: * DN of subject in certificate
436: *
437: * @param dn subject dn
438: * @ejb.interface-method
439: */
440: public void setSubject(String dn) {
441: setSubjectDN(CertTools.stringToBCDNString(dn));
442: }
443:
444: /**
445: * expire date of certificate
446: *
447: * @param expireDate expire date
448: * @ejb.interface-method
449: */
450: public void setExpireDate(Date expireDate) {
451: if (expireDate == null) {
452: setExpireDate(-1L);
453: } else {
454: setExpireDate(expireDate.getTime());
455: }
456: }
457:
458: /**
459: * date the certificate was revoked
460: *
461: * @param revocationDate revocation date
462: * @ejb.interface-method
463: */
464: public void setRevocationDate(Date revocationDate) {
465: if (revocationDate == null) {
466: setRevocationDate(-1L);
467: } else {
468: setRevocationDate(revocationDate.getTime());
469: }
470: }
471:
472: //
473: // Fields required by Container
474: //
475:
476: /**
477: * Entity Bean holding info about a certficate. Create by sending in the certificate, which
478: * extracts (from the cert) fingerprint (primary key), subjectDN, issuerDN, serial number,
479: * expiration date. Status, Type, CAFingerprint, revocationDate and revocationReason are set
480: * to default values (CERT_UNASSIGNED, USER_INVALID, null, null and
481: * REVOKATION_REASON_UNSPECIFIED) and should be set using the respective set-methods.
482: *
483: * @param incert the (X509)Certificate to be stored in the database.
484: *
485: * @return primary key
486: * @ejb.create-method
487: */
488: public CertificateDataPK ejbCreate(Certificate incert)
489: throws CreateException {
490: // Exctract all fields to store with the certificate.
491: X509Certificate tmpcert;
492:
493: try {
494: String b64Cert = new String(Base64.encode(incert
495: .getEncoded()));
496: setBase64Cert(b64Cert);
497: tmpcert = (X509Certificate) incert;
498:
499: String fp = CertTools.getFingerprintAsString(tmpcert);
500: setFingerprint(fp);
501:
502: // Make sure names are always looking the same
503: setSubjectDN(CertTools.getSubjectDN(tmpcert));
504: setIssuerDN(CertTools.getIssuerDN(tmpcert));
505: log.debug("Creating certdata, subject=" + getSubjectDN()
506: + ", issuer=" + getIssuerDN());
507: setSerialNumber(tmpcert.getSerialNumber().toString());
508:
509: // Default values for status and type
510: setStatus(CERT_UNASSIGNED);
511: setType(SecConst.USER_INVALID);
512: setCaFingerprint(null);
513: setExpireDate(tmpcert.getNotAfter());
514: setRevocationDate(-1L);
515: setRevocationReason(RevokedCertInfo.NOT_REVOKED);
516: } catch (CertificateEncodingException cee) {
517: log
518: .error(
519: "Can't extract DER encoded certificate information.",
520: cee);
521: // TODO should throw an exception
522: }
523: return null;
524: }
525:
526: /**
527: * required method, does nothing
528: *
529: * @param incert certificate
530: */
531: public void ejbPostCreate(Certificate incert) {
532: // Do nothing. Required.
533: }
534: }
|