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 se.anatom.ejbca.ca.store;
013:
014: import java.rmi.RemoteException;
015: import java.security.KeyPair;
016: import java.security.cert.Certificate;
017: import java.security.cert.X509Certificate;
018: import java.util.Collection;
019: import java.util.Date;
020: import java.util.Iterator;
021: import java.util.Random;
022:
023: import javax.naming.Context;
024: import javax.naming.NamingException;
025:
026: import junit.framework.TestCase;
027:
028: import org.apache.log4j.Logger;
029: import org.ejbca.core.ejb.ca.store.CertificateDataBean;
030: import org.ejbca.core.ejb.ca.store.ICertificateStoreSessionHome;
031: import org.ejbca.core.ejb.ca.store.ICertificateStoreSessionRemote;
032: import org.ejbca.core.model.SecConst;
033: import org.ejbca.core.model.ca.catoken.CATokenConstants;
034: import org.ejbca.core.model.ca.catoken.CATokenInfo;
035: import org.ejbca.core.model.ca.crl.RevokedCertInfo;
036: import org.ejbca.core.model.ca.store.CertReqHistory;
037: import org.ejbca.core.model.ca.store.CertificateInfo;
038: import org.ejbca.core.model.log.Admin;
039: import org.ejbca.core.model.ra.UserDataVO;
040: import org.ejbca.util.CertTools;
041: import org.ejbca.util.KeyTools;
042:
043: /**
044: * Tests certificate store.
045: *
046: * @version $Id: TestCertificateData.java,v 1.9 2006/10/31 08:24:53 anatom Exp $
047: */
048: public class TestCertificateData extends TestCase {
049:
050: private static Logger log = Logger
051: .getLogger(TestCertificateData.class);
052: private static Context ctx;
053: private static ICertificateStoreSessionHome storehome;
054: private static X509Certificate cert;
055: private static X509Certificate cert1;
056: private static X509Certificate cert2;
057: private static String username = "";
058: private static Admin admin = null;
059: private static KeyPair keyPair;
060:
061: /**
062: * Creates a new TestCertificateData object.
063: *
064: * @param name name
065: */
066: public TestCertificateData(String name) {
067: super (name);
068: }
069:
070: protected void setUp() throws Exception {
071: log.debug(">setUp()");
072: CertTools.installBCProvider();
073:
074: admin = new Admin(Admin.TYPE_INTERNALUSER);
075: ctx = getInitialContext();
076: Object obj2 = ctx.lookup("CertificateStoreSession");
077: storehome = (ICertificateStoreSessionHome) javax.rmi.PortableRemoteObject
078: .narrow(obj2, ICertificateStoreSessionHome.class);
079:
080: log.debug("<setUp()");
081: }
082:
083: protected void tearDown() throws Exception {
084: }
085:
086: private Context getInitialContext() throws NamingException {
087: log.debug(">getInitialContext");
088: Context ctx = new javax.naming.InitialContext();
089: log.debug("<getInitialContext");
090: return ctx;
091: }
092:
093: /**
094: * creates new certs
095: *
096: * @throws Exception error
097: */
098: public void test01CreateNewCertRSASha1() throws Exception {
099: log.debug(">test01CreateNewCert()");
100: // create a key pair and a new self signed certificate
101: log
102: .info("Generating a small key pair, might take a few seconds...");
103: keyPair = KeyTools.genKeys("512",
104: CATokenConstants.KEYALGORITHM_RSA);
105: cert = CertTools.genSelfCert(
106: "C=SE,O=PrimeCA,OU=TestCertificateData,CN=MyNameIsFoo",
107: 24, null, keyPair.getPrivate(), keyPair.getPublic(),
108: CATokenInfo.SIGALG_SHA1_WITH_RSA, false);
109: String fp = CertTools.getFingerprintAsString(cert);
110:
111: ICertificateStoreSessionRemote store = storehome.create();
112: try {
113: Certificate ce = store.findCertificateByFingerprint(admin,
114: fp);
115: if (ce != null) {
116: assertTrue(
117: "Certificate with fp="
118: + fp
119: + " already exists in db, very strange since I just generated it.",
120: false);
121: }
122: boolean ret = store.storeCertificate(admin, cert, "foo",
123: "1234", CertificateDataBean.CERT_INACTIVE,
124: CertificateDataBean.CERT_TYPE_ENCRYPTION);
125: //log.info("Stored new cert with fp="+fp);
126: assertTrue("Failed to store", ret);
127: log.debug("stored it!");
128: } catch (RemoteException e) {
129: log.error("Error storing certificate: ", e);
130: assertTrue("Error storing certificate.", false);
131: return;
132: }
133: log.debug("<test01CreateNewCert()");
134: }
135:
136: /**
137: * finds and alters certificates
138: *
139: * @throws Exception error
140: */
141: public void test02FindAndChange() throws Exception {
142: log.debug(">test02FindAndChange()");
143: String fp = CertTools.getFingerprintAsString(cert);
144: ICertificateStoreSessionRemote store = storehome.create();
145: try {
146: X509Certificate ce = (X509Certificate) store
147: .findCertificateByFingerprint(admin, fp);
148: assertNotNull("Cannot find certificate with fp=" + fp, ce);
149: CertificateInfo info = store.getCertificateInfo(admin, fp);
150: //log.info("Got certificate info for cert with fp="+fp);
151: assertEquals("fingerprint does not match.", fp, info
152: .getFingerprint());
153: assertEquals("CAfingerprint does not match.", "1234", info
154: .getCAFingerprint());
155: assertEquals("serialnumber does not match.", ce
156: .getSerialNumber(), info.getSerialNumber());
157: assertEquals("issuerdn does not match.", CertTools
158: .getIssuerDN(ce), info.getIssuerDN());
159: assertEquals("subjectdn does not match.", CertTools
160: .getSubjectDN(ce), info.getSubjectDN());
161: // The cert was just stored above with status INACTIVE
162: assertEquals("status does not match.",
163: CertificateDataBean.CERT_INACTIVE, info.getStatus());
164: assertEquals("type does not match.",
165: CertificateDataBean.CERT_TYPE_ENCRYPTION, info
166: .getType());
167: assertEquals("exiredate does not match.", ce.getNotAfter(),
168: info.getExpireDate());
169: // We just stored it above, not revoked
170: assertEquals("revocation reason does not match.",
171: RevokedCertInfo.NOT_REVOKED, info
172: .getRevocationReason());
173: log.info("revocationdate (before rev)="
174: + info.getRevocationDate());
175: store.revokeCertificate(admin, ce, null,
176: RevokedCertInfo.REVOKATION_REASON_KEYCOMPROMISE);
177: CertificateInfo info1 = store.getCertificateInfo(admin, fp);
178: assertEquals("revocation reason does not match.",
179: RevokedCertInfo.REVOKATION_REASON_KEYCOMPROMISE,
180: info1.getRevocationReason());
181: log.info("revocationdate (after rev)="
182: + info1.getRevocationDate());
183: assertTrue("Revocation date in future.", new Date()
184: .compareTo(info1.getRevocationDate()) >= 0);
185: } catch (RemoteException e) {
186: log.error("Error getting or revoking certificate: ", e);
187: assertTrue("Error getting or revoking certificate.", false);
188: return;
189: }
190: log.debug("<test02FindAndChange()");
191: }
192:
193: /**
194: * listst and revokes certs
195: *
196: * @throws Exception error
197: */
198: public void test03listAndRevoke() throws Exception {
199: log.debug(">test03listAndRevoke()");
200: ICertificateStoreSessionRemote store = storehome.create();
201: String issuerDN = CertTools.getIssuerDN(cert);
202: String subjectDN = CertTools.getSubjectDN(cert);
203: // List all certificates to see
204: Collection certfps = store.listAllCertificates(admin, issuerDN);
205: assertNotNull("failed to list certs", certfps);
206: assertTrue("failed to list certs", certfps.size() != 0);
207:
208: int size = certfps.size();
209: log.debug("List certs: " + size);
210:
211: // List all certificates for user foo, which we have created in TestSignSession
212: certfps = store.findCertificatesBySubjectAndIssuer(new Admin(
213: Admin.TYPE_INTERNALUSER), subjectDN, issuerDN);
214: assertTrue("something weird with size, all < foos",
215: size >= certfps.size());
216: log.debug("List certs for foo: " + certfps.size());
217: Iterator iter = certfps.iterator();
218: while (iter.hasNext()) {
219: X509Certificate cert = (X509Certificate) iter.next();
220: String fp = CertTools.getFingerprintAsString(cert);
221: log.debug("revoking cert with fp=" + fp);
222: // Revoke all foos certificates, note that revokeCertificate will not change status of certificates that are already revoked
223: store
224: .revokeCertificate(
225: admin,
226: cert,
227: null,
228: RevokedCertInfo.REVOKATION_REASON_AFFILIATIONCHANGED);
229: log.debug("Revoked cert " + fp);
230: }
231: log.debug("<test03listAndRevoke()");
232: }
233:
234: /**
235: * checks revoked certs
236: *
237: * @throws Exception error
238: */
239: public void test04CheckRevoked() throws Exception {
240: log.debug(">test04CheckRevoked()");
241:
242: ICertificateStoreSessionRemote store = storehome.create();
243: String issuerDN = CertTools.getIssuerDN(cert);
244: String subjectDN = CertTools.getSubjectDN(cert);
245: // List all certificates for user foo, which we have created in TestSignSession
246: Collection certfps = store
247: .findCertificatesBySubjectAndIssuer(new Admin(
248: Admin.TYPE_INTERNALUSER), subjectDN, issuerDN);
249: assertNotNull("failed to list certs", certfps);
250: assertTrue("failed to list certs", certfps.size() != 0);
251:
252: // Verify that cert are revoked
253: Iterator iter = certfps.iterator();
254: while (iter.hasNext()) {
255: X509Certificate cert = (X509Certificate) iter.next();
256: String fp = CertTools.getFingerprintAsString(cert);
257: CertificateInfo rev = store.getCertificateInfo(admin, fp);
258: log.info("revocationdate (after rev)="
259: + rev.getRevocationDate());
260: assertTrue("Revocation date in future.", new Date()
261: .compareTo(rev.getRevocationDate()) >= 0);
262: assertTrue(rev.getStatus() == CertificateDataBean.CERT_REVOKED);
263: }
264:
265: log.debug("<test04CheckRevoked()");
266: }
267:
268: /**
269: * finds certificates again
270: *
271: * @throws Exception error
272: */
273: public void test05FindAgain() throws Exception {
274: log.debug(">test05FindAgain()");
275:
276: String fp = CertTools.getFingerprintAsString(cert);
277:
278: ICertificateStoreSessionRemote store = storehome.create();
279: CertificateInfo data3 = store.getCertificateInfo(admin, fp);
280: assertNotNull("Failed to find cert", data3);
281: log.debug("found by key! =" + data3);
282: log.debug("fp=" + data3.getFingerprint());
283: log.debug("issuer=" + data3.getIssuerDN());
284: log.debug("subject=" + data3.getSubjectDN());
285: log.debug("cafp=" + data3.getCAFingerprint());
286: assertNotNull("wrong CAFingerprint", data3.getCAFingerprint());
287: log.debug("status=" + data3.getStatus());
288: assertTrue("wrong status",
289: data3.getStatus() == CertificateDataBean.CERT_REVOKED);
290: log.debug("type=" + data3.getType());
291: assertTrue(
292: "wrong type",
293: (data3.getType() & SecConst.USER_ENDUSER) == SecConst.USER_ENDUSER);
294: log.debug("serno=" + data3.getSerialNumber());
295: log.debug("expiredate=" + data3.getExpireDate());
296: log.debug("revocationdate=" + data3.getRevocationDate());
297: log.debug("revocationreason=" + data3.getRevocationReason());
298: assertEquals("Wrong revocation reason", data3
299: .getRevocationReason(),
300: RevokedCertInfo.REVOKATION_REASON_KEYCOMPROMISE);
301:
302: log.debug("Looking for cert with DN="
303: + CertTools.getSubjectDN(cert));
304: Collection certs = store.findCertificatesBySubjectAndIssuer(
305: new Admin(Admin.TYPE_INTERNALUSER), CertTools
306: .getSubjectDN(cert), CertTools
307: .getIssuerDN(cert));
308: Iterator iter = certs.iterator();
309: while (iter.hasNext()) {
310: X509Certificate xcert = (X509Certificate) iter.next();
311: log.debug(CertTools.getSubjectDN(xcert) + " - "
312: + xcert.getSerialNumber().toString());
313: //log.debug(certs[i].toString());
314: }
315: log.debug("<test05FindAgain()");
316: }
317:
318: /**
319: * finds certs by expire time
320: *
321: * @throws Exception error
322: */
323: public void test06FindByExpireTime() throws Exception {
324: log.debug(">test06FindByExpireTime()");
325:
326: ICertificateStoreSessionRemote store = storehome.create();
327: String fp = CertTools.getFingerprintAsString(cert);
328:
329: CertificateInfo data = store.getCertificateInfo(admin, fp);
330: assertNotNull("Failed to find cert", data);
331: log.debug("expiredate=" + data.getExpireDate());
332:
333: // Seconds in a year
334: long yearmillis = 365 * 24 * 60 * 60 * 1000;
335: long findDateSecs = data.getExpireDate().getTime()
336: - (yearmillis * 100);
337: Date findDate = new Date(findDateSecs);
338:
339: log.info("1. Looking for cert with expireDate=" + findDate);
340:
341: Collection certs = store.findCertificatesByExpireTime(
342: new Admin(Admin.TYPE_INTERNALUSER), findDate);
343: log.debug("findCertificatesByExpireTime returned "
344: + certs.size() + " certs.");
345: assertTrue("No certs should have expired before this date",
346: certs.size() == 0);
347: findDateSecs = data.getExpireDate().getTime() + 10000;
348: findDate = new Date(findDateSecs);
349: log.info("2. Looking for cert with expireDate=" + findDate);
350: certs = store.findCertificatesByExpireTime(new Admin(
351: Admin.TYPE_INTERNALUSER), findDate);
352: log.debug("findCertificatesByExpireTime returned "
353: + certs.size() + " certs.");
354: assertTrue("Some certs should have expired before this date",
355: certs.size() != 0);
356:
357: Iterator iter = certs.iterator();
358:
359: while (iter.hasNext()) {
360: X509Certificate cert = (X509Certificate) iter.next();
361: Date retDate = cert.getNotAfter();
362: log.debug(retDate);
363: assertTrue(
364: "This cert is not expired by the specified Date.",
365: retDate.getTime() < findDate.getTime());
366: }
367:
368: log.debug("<test06FindByExpireTime()");
369: }
370:
371: /**
372: * finds certs by issuer and serialno
373: *
374: * @throws Exception error
375: */
376: public void test07FindByIssuerAndSerno() throws Exception {
377: log.debug(">test07FindByIssuerAndSerno()");
378:
379: String issuerDN = CertTools.getIssuerDN(cert);
380: ICertificateStoreSessionRemote store = storehome.create();
381: String fp = CertTools.getFingerprintAsString(cert);
382: CertificateInfo data3 = store.getCertificateInfo(admin, fp);
383: assertNotNull("Failed to find cert", data3);
384:
385: log.debug("Looking for cert with DN:"
386: + CertTools.getIssuerDN(cert) + " and serno "
387: + cert.getSerialNumber());
388: Certificate fcert = store.findCertificateByIssuerAndSerno(
389: new Admin(Admin.TYPE_INTERNALUSER), issuerDN, cert
390: .getSerialNumber());
391: assertNotNull("Cant find by issuer and serno", fcert);
392:
393: //log.debug(fcert.toString());
394: log.debug("<test07FindByIssuerAndSerno()");
395: }
396:
397: /**
398: * checks if a certificate is revoked
399: *
400: * @throws Exception error
401: */
402: public void test08IsRevoked() throws Exception {
403: log.debug(">test08IsRevoked()");
404: ICertificateStoreSessionRemote store = storehome.create();
405: String fp = CertTools.getFingerprintAsString(cert);
406: CertificateInfo data3 = store.getCertificateInfo(admin, fp);
407: assertNotNull("Failed to find cert", data3);
408: log.debug("found by key! =" + data3);
409: log.debug("fp=" + data3.getFingerprint());
410: log.debug("issuer=" + data3.getIssuerDN());
411: log.debug("subject=" + data3.getSubjectDN());
412: log.debug("cafp=" + data3.getCAFingerprint());
413: assertNotNull("wrong CAFingerprint", data3.getCAFingerprint());
414: log.debug("status=" + data3.getStatus());
415: assertTrue("wrong status",
416: data3.getStatus() == CertificateDataBean.CERT_REVOKED);
417: log.debug("type=" + data3.getType());
418: assertTrue(
419: "wrong type",
420: (data3.getType() == CertificateDataBean.CERTTYPE_ENDENTITY));
421: log.debug("serno=" + data3.getSerialNumber());
422: log.debug("expiredate=" + data3.getExpireDate());
423: log.debug("revocationdate=" + data3.getRevocationDate());
424: log.debug("revocationreason=" + data3.getRevocationReason());
425: assertEquals("wrong reason", data3.getRevocationReason(),
426: RevokedCertInfo.REVOKATION_REASON_KEYCOMPROMISE);
427:
428: log.debug("Checking if cert is revoked DN:'"
429: + CertTools.getIssuerDN(cert) + "', serno:'"
430: + cert.getSerialNumber().toString() + "'.");
431: RevokedCertInfo revinfo = store.isRevoked(new Admin(
432: Admin.TYPE_INTERNALUSER), CertTools.getIssuerDN(cert),
433: cert.getSerialNumber());
434: assertNotNull("Certificate not found, it should be!", revinfo);
435: int reason = revinfo.getReason();
436: assertEquals("Certificate not revoked, it should be!",
437: RevokedCertInfo.REVOKATION_REASON_KEYCOMPROMISE, reason);
438: assertTrue("Wrong revocationDate!", revinfo.getRevocationDate()
439: .compareTo(data3.getRevocationDate()) == 0);
440: assertTrue("Wrong reason!", revinfo.getReason() == data3
441: .getRevocationReason());
442: log.debug("Removed it!");
443: log.debug("<test08IsRevoked()");
444: }
445:
446: /**
447: * Adds two certificate request histroy datas to the database.
448: *
449: * @throws Exception error
450: */
451: public void test09addCertReqHist() throws Exception {
452: log.debug(">test09addCertReqHist()");
453: ICertificateStoreSessionRemote store = storehome.create();
454:
455: cert1 = CertTools
456: .genSelfCert(
457: "C=SE,O=PrimeCA,OU=TestCertificateData,CN=CertReqHist1",
458: 24, null, keyPair.getPrivate(), keyPair
459: .getPublic(),
460: CATokenInfo.SIGALG_SHA1_WITH_RSA, false);
461: cert2 = CertTools
462: .genSelfCert(
463: "C=SE,O=PrimeCA,OU=TestCertificateData,CN=CertReqHist2",
464: 24, null, keyPair.getPrivate(), keyPair
465: .getPublic(),
466: CATokenInfo.SIGALG_SHA1_WITH_RSA, false);
467:
468: UserDataVO userdata = new UserDataVO();
469: Random rand = new Random(new Date().getTime() + 4711);
470: for (int i = 0; i < 6; i++) {
471: int randint = rand.nextInt(9);
472: username += (new Integer(randint)).toString();
473: }
474: log.debug("Generated random username: username =" + username);
475: userdata.setUsername(username);
476: userdata
477: .setDN("C=SE,O=PrimeCA,OU=TestCertificateData,CN=CertReqHist1");
478: store.addCertReqHistoryData(admin, cert1, userdata);
479:
480: userdata
481: .setDN("C=SE,O=PrimeCA,OU=TestCertificateData,CN=CertReqHist2");
482: store.addCertReqHistoryData(admin, cert2, userdata);
483: log.debug("<test09addCertReqHist()");
484: }
485:
486: /**
487: * checks that getCertReqHistory(Admin admin, BigInteger certificateSN, String issuerDN)
488: * returns the right data.
489: *
490: * @throws Exception error
491: */
492: public void test10getCertReqHistByIssuerDNAndSerial()
493: throws Exception {
494: log.debug(">test10getCertReqHistByIssuerDNAndSerial()");
495: ICertificateStoreSessionRemote store = storehome.create();
496:
497: CertReqHistory certreqhist = store
498: .getCertReqHistory(admin, cert1.getSerialNumber(),
499: cert1.getIssuerDN().toString());
500:
501: assertNotNull(
502: "Error couldn't find the certificate request data stored previously",
503: certreqhist);
504:
505: UserDataVO userdata = certreqhist.getUserDataVO();
506: assertTrue("Error wrong username.", (userdata.getUsername()
507: .equals(username)));
508: assertTrue(
509: "Error wrong DN.",
510: (userdata.getDN()
511: .equals("C=SE,O=PrimeCA,OU=TestCertificateData,CN=CertReqHist1")));
512:
513: log.debug("<test10getCertReqHistByIssuerDNAndSerial()");
514: }
515:
516: /**
517: * checks that getCertReqHistory(Admin admin, String username)
518: * returns the the two CertReqHistory object previously stored.
519: *
520: * @throws Exception error
521: */
522: public void test11getCertReqHistByUsername() throws Exception {
523: log.debug(">test11getCertReqHistByUsername()");
524: ICertificateStoreSessionRemote store = storehome.create();
525:
526: Collection result = store.getCertReqHistory(admin, username);
527: assertTrue("Error size of the returned collection.", (result
528: .size() == 2));
529:
530: Iterator iter = result.iterator();
531: while (iter.hasNext()) {
532: CertReqHistory certreqhist = (CertReqHistory) iter.next();
533: assertTrue(
534: "Error wrong DN",
535: ((certreqhist.getUserDataVO().getDN()
536: .equals("C=SE,O=PrimeCA,OU=TestCertificateData,CN=CertReqHist1")) || (certreqhist
537: .getUserDataVO().getDN()
538: .equals("C=SE,O=PrimeCA,OU=TestCertificateData,CN=CertReqHist2"))));
539: }
540: log.debug("<test11getCertReqHistByUsername()");
541: }
542:
543: /**
544: * Removes all the previously stored certreqhist data.
545: *
546: * @throws Exception error
547: */
548: public void test12removeCertReqHistData() throws Exception {
549: log.debug(">test12removeCertReqHistData()");
550: ICertificateStoreSessionRemote store = storehome.create();
551:
552: store.removeCertReqHistoryData(admin, CertTools
553: .getFingerprintAsString(cert1));
554: store.removeCertReqHistoryData(admin, CertTools
555: .getFingerprintAsString(cert2));
556:
557: CertReqHistory certreqhist = store
558: .getCertReqHistory(admin, cert1.getSerialNumber(),
559: cert1.getIssuerDN().toString());
560: assertNull(
561: "Error removing cert req history data, cert1 data is still there",
562: certreqhist);
563:
564: certreqhist = store.getCertReqHistory(admin, cert2
565: .getSerialNumber(), cert2.getIssuerDN().toString());
566: assertNull(
567: "Error removing cert req history data, cert2 data is still there",
568: certreqhist);
569:
570: log.debug("<test12removeCertReqHistData()");
571: }
572:
573: }
|