package org.cagrid.dorian.federation; import java.math.BigInteger; import java.security.KeyPair; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Map; import junit.framework.TestCase; import org.cagrid.dorian.common.CommonUtils; import org.cagrid.dorian.model.exceptions.InvalidUserCertificateException; import org.cagrid.dorian.model.exceptions.InvalidUserCertificateFault; import org.cagrid.dorian.model.federation.DateRange; import org.cagrid.dorian.model.federation.UserCertificateFilter; import org.cagrid.dorian.model.federation.UserCertificateRecord; import org.cagrid.dorian.model.federation.UserCertificateStatus; import org.cagrid.dorian.model.federation.UserCertificateUpdate; import org.cagrid.dorian.service.CertificateSignatureAlgorithm; import org.cagrid.dorian.service.ca.CertificateAuthority; import org.cagrid.dorian.service.federation.CertificateBlacklistManager; import org.cagrid.dorian.service.federation.Publisher; import org.cagrid.dorian.service.federation.UserCertificateManager; import org.cagrid.gaards.dorian.test.Utils; import org.cagrid.gaards.pki.CertUtil; import org.cagrid.gaards.pki.KeyUtil; import org.cagrid.tools.database.Database; public class TestUserCertificateManager extends TestCase implements Publisher { private static final int DEFAULT_SECONDS = 5000; private static final int DEFAULT_SECONDS_OFFSET = 300; private Database db; private CertificateAuthority ca; private String caSubject; private int crlPublishCount; private List<BigInteger> crl; private UserCertificateManager man; private CertificateBlacklistManager blackList; public void testSingleUserCertificate() { try { String uid = "jdoe"; X509Certificate cert = getAndValidateCertificate(uid, DEFAULT_SECONDS); man.addUserCertifcate(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName()), cert); UserCertificateRecord r = getAndValidateCertificateRecord(cert); checkCRL(man.getCompromisedCertificates(), 0); Map<Long, UserCertificateRecord> expected = new HashMap<Long, UserCertificateRecord>(); // Test empty filter UserCertificateFilter empty = new UserCertificateFilter(); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(empty, expected); // Test Serial Number UserCertificateFilter sn = new UserCertificateFilter(); sn.setSerialNumber(new Long(r.getSerialNumber())); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(sn, expected); expected.clear(); sn.setSerialNumber(new Long(0)); validateFind(sn, expected); // Test Grid Identity UserCertificateFilter gid = new UserCertificateFilter(); gid.setGridIdentity(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName())); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(gid, expected); expected.clear(); gid.setGridIdentity(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName() + "2")); validateFind(gid, expected); // Test Status UserCertificateFilter status = new UserCertificateFilter(); status.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(status, expected); expected.clear(); status.setStatus(UserCertificateStatus.COMPROMISED); validateFind(status, expected); // Test end outside date range UserCertificateFilter endOutside = new UserCertificateFilter(); DateRange endOutsideRange = new DateRange(); Calendar endOutsideStart = new GregorianCalendar(); endOutsideStart.setTime(cert.getNotBefore()); endOutsideStart.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET)); endOutsideRange.setStartDate(endOutsideStart); Calendar endOutsideEnd = new GregorianCalendar(); endOutsideEnd.setTime(cert.getNotAfter()); endOutsideEnd.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET)); endOutsideRange.setEndDate(endOutsideEnd); endOutside.setDateRange(endOutsideRange); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(endOutside, expected); // Test start outside date range UserCertificateFilter startOutside = new UserCertificateFilter(); DateRange startOutsideRange = new DateRange(); Calendar startOutsideStart = new GregorianCalendar(); startOutsideStart.setTime(cert.getNotBefore()); startOutsideStart.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * -1)); startOutsideRange.setStartDate(startOutsideStart); Calendar startOutsideEnd = new GregorianCalendar(); startOutsideEnd.setTime(cert.getNotAfter()); startOutsideEnd.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * -1)); startOutsideRange.setEndDate(startOutsideEnd); startOutside.setDateRange(startOutsideRange); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(startOutside, expected); // Test outside date range UserCertificateFilter outside = new UserCertificateFilter(); DateRange outsideRange = new DateRange(); Calendar outsideStart = new GregorianCalendar(); outsideStart.setTime(cert.getNotBefore()); outsideStart.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * -1)); outsideRange.setStartDate(outsideStart); Calendar outsideEnd = new GregorianCalendar(); outsideEnd.setTime(cert.getNotAfter()); outsideEnd.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET)); outsideRange.setEndDate(outsideEnd); outside.setDateRange(outsideRange); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(outside, expected); // Test inside date range UserCertificateFilter inside = new UserCertificateFilter(); DateRange insideRange = new DateRange(); Calendar insideStart = new GregorianCalendar(); insideStart.setTime(cert.getNotBefore()); insideStart.add(Calendar.SECOND, DEFAULT_SECONDS_OFFSET); insideRange.setStartDate(insideStart); Calendar insideEnd = new GregorianCalendar(); insideEnd.setTime(cert.getNotAfter()); insideEnd.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * -1)); insideRange.setEndDate(insideEnd); inside.setDateRange(insideRange); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(inside, expected); // Test exact date range UserCertificateFilter exactDates = new UserCertificateFilter(); DateRange range = new DateRange(); GregorianCalendar start = new GregorianCalendar(); start.setTime(cert.getNotBefore()); range.setStartDate(start); GregorianCalendar end = new GregorianCalendar(); end.setTime(cert.getNotAfter()); range.setEndDate(end); exactDates.setDateRange(range); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(exactDates, expected); // Test invalid start UserCertificateFilter startInvalid = new UserCertificateFilter(); DateRange startInvalidRange = new DateRange(); Calendar startInvalidStart = new GregorianCalendar(); startInvalidStart.setTime(cert.getNotBefore()); startInvalidStart.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * -2)); startInvalidRange.setStartDate(startInvalidStart); Calendar startInvalidEnd = new GregorianCalendar(); startInvalidEnd.setTime(cert.getNotAfter()); startInvalidEnd.add(Calendar.SECOND, ((DEFAULT_SECONDS + DEFAULT_SECONDS_OFFSET) * -1)); startInvalidRange.setEndDate(startInvalidEnd); startInvalid.setDateRange(startInvalidRange); expected.clear(); validateFind(startInvalid, expected); // Test invalid end UserCertificateFilter endInvalid = new UserCertificateFilter(); DateRange endInvalidRange = new DateRange(); Calendar endInvalidStart = new GregorianCalendar(); endInvalidStart.setTime(cert.getNotBefore()); endInvalidStart.add(Calendar.SECOND, ((DEFAULT_SECONDS + DEFAULT_SECONDS_OFFSET) * 1)); endInvalidRange.setStartDate(endInvalidStart); Calendar endInvalidEnd = new GregorianCalendar(); endInvalidEnd.setTime(cert.getNotAfter()); endInvalidEnd.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * 2)); endInvalidRange.setEndDate(endInvalidEnd); endInvalid.setDateRange(endInvalidRange); expected.clear(); validateFind(endInvalid, expected); // Test update String msg = "Hello World"; UserCertificateUpdate u = new UserCertificateUpdate(); u.setSerialNumber(cert.getSerialNumber().longValue()); u.setStatus(UserCertificateStatus.COMPROMISED); u.setNotes(msg); man.updateUserCertificateRecord(u); r.setStatus(UserCertificateStatus.COMPROMISED); r.setNotes(msg); // Test Update Results UserCertificateFilter update = new UserCertificateFilter(); update.setStatus(UserCertificateStatus.OK); update.setNotes(msg); expected.clear(); validateFind(update, expected); expected.clear(); update.setStatus(UserCertificateStatus.COMPROMISED); update.setNotes(msg); expected.put(new Long(r.getSerialNumber()), r); validateFind(update, expected); checkCRL(man.getCompromisedCertificates(), 1); // Test All UserCertificateFilter all = new UserCertificateFilter(); all.setSerialNumber(new Long(r.getSerialNumber())); all.setGridIdentity(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName())); all.setStatus(UserCertificateStatus.COMPROMISED); all.setNotes(msg); all.setDateRange(insideRange); expected.put(new Long(r.getSerialNumber()), r); validateFind(all, expected); man.removeCertificate(r.getSerialNumber()); assertEquals(false, man.determineIfRecordExistBySerialNumber(r.getSerialNumber())); assertTrue(blackList.memberOfBlackList(r.getSerialNumber())); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } public void testMultipleUserCertificates() { try { int count = 3; List<UserCertificateRecord> records = new ArrayList<UserCertificateRecord>(); for (int i = 0; i < count; i++) { String uid = "jdoe" + i; X509Certificate cert = getAndValidateCertificate(uid, DEFAULT_SECONDS); man.addUserCertifcate(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName()), cert); UserCertificateRecord r = getAndValidateCertificateRecord(cert); records.add(r); checkCRL(man.getCompromisedCertificates(), i); Map<Long, UserCertificateRecord> expected = new HashMap<Long, UserCertificateRecord>(); // Test empty filter UserCertificateFilter empty = new UserCertificateFilter(); expected.clear(); for (int j = 0; j < records.size(); j++) { expected.put(records.get(j).getSerialNumber(), records.get(j)); } validateFind(empty, expected); // Test Serial Number UserCertificateFilter sn = new UserCertificateFilter(); sn.setSerialNumber(new Long(r.getSerialNumber())); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(sn, expected); expected.clear(); sn.setSerialNumber(new Long(0)); validateFind(sn, expected); // Test Grid Identity UserCertificateFilter gid = new UserCertificateFilter(); gid.setGridIdentity(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName())); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(gid, expected); expected.clear(); gid.setGridIdentity(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName() + "2")); validateFind(gid, expected); // Test Status UserCertificateFilter status = new UserCertificateFilter(); status.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(status, expected); expected.clear(); for (int j = 0; j < i; j++) { expected.put(records.get(j).getSerialNumber(), records.get(j)); } status.setStatus(UserCertificateStatus.COMPROMISED); validateFind(status, expected); // Test end outside date range UserCertificateFilter endOutside = new UserCertificateFilter(); DateRange endOutsideRange = new DateRange(); Calendar endOutsideStart = new GregorianCalendar(); endOutsideStart.setTime(cert.getNotBefore()); endOutsideStart.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET)); endOutsideRange.setStartDate(endOutsideStart); Calendar endOutsideEnd = new GregorianCalendar(); endOutsideEnd.setTime(cert.getNotAfter()); endOutsideEnd.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET)); endOutsideRange.setEndDate(endOutsideEnd); endOutside.setDateRange(endOutsideRange); expected.clear(); for (int j = 0; j < records.size(); j++) { expected.put(records.get(j).getSerialNumber(), records.get(j)); } validateFind(endOutside, expected); // Test start outside date range UserCertificateFilter startOutside = new UserCertificateFilter(); DateRange startOutsideRange = new DateRange(); Calendar startOutsideStart = new GregorianCalendar(); startOutsideStart.setTime(cert.getNotBefore()); startOutsideStart.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * -1)); startOutsideRange.setStartDate(startOutsideStart); Calendar startOutsideEnd = new GregorianCalendar(); startOutsideEnd.setTime(cert.getNotAfter()); startOutsideEnd.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * -1)); startOutsideRange.setEndDate(startOutsideEnd); startOutside.setDateRange(startOutsideRange); expected.clear(); for (int j = 0; j < records.size(); j++) { expected.put(records.get(j).getSerialNumber(), records.get(j)); } validateFind(startOutside, expected); // Test outside date range UserCertificateFilter outside = new UserCertificateFilter(); DateRange outsideRange = new DateRange(); Calendar outsideStart = new GregorianCalendar(); outsideStart.setTime(cert.getNotBefore()); outsideStart.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * -1)); outsideRange.setStartDate(outsideStart); Calendar outsideEnd = new GregorianCalendar(); outsideEnd.setTime(cert.getNotAfter()); outsideEnd.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET)); outsideRange.setEndDate(outsideEnd); outside.setDateRange(outsideRange); expected.clear(); for (int j = 0; j < records.size(); j++) { expected.put(records.get(j).getSerialNumber(), records.get(j)); } validateFind(outside, expected); // Test inside date range UserCertificateFilter inside = new UserCertificateFilter(); DateRange insideRange = new DateRange(); Calendar insideStart = new GregorianCalendar(); insideStart.setTime(cert.getNotBefore()); insideStart.add(Calendar.SECOND, DEFAULT_SECONDS_OFFSET); insideRange.setStartDate(insideStart); Calendar insideEnd = new GregorianCalendar(); insideEnd.setTime(cert.getNotAfter()); insideEnd.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * -1)); insideRange.setEndDate(insideEnd); inside.setDateRange(insideRange); expected.clear(); for (int j = 0; j < records.size(); j++) { expected.put(records.get(j).getSerialNumber(), records.get(j)); } validateFind(inside, expected); // Test exact date range UserCertificateFilter exactDates = new UserCertificateFilter(); DateRange range = new DateRange(); GregorianCalendar start = new GregorianCalendar(); start.setTime(cert.getNotBefore()); range.setStartDate(start); GregorianCalendar end = new GregorianCalendar(); end.setTime(cert.getNotAfter()); range.setEndDate(end); exactDates.setDateRange(range); expected.clear(); for (int j = 0; j < records.size(); j++) { expected.put(records.get(j).getSerialNumber(), records.get(j)); } validateFind(exactDates, expected); // Test invalid start UserCertificateFilter startInvalid = new UserCertificateFilter(); DateRange startInvalidRange = new DateRange(); Calendar startInvalidStart = new GregorianCalendar(); startInvalidStart.setTime(cert.getNotBefore()); startInvalidStart.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * -2)); startInvalidRange.setStartDate(startInvalidStart); Calendar startInvalidEnd = new GregorianCalendar(); startInvalidEnd.setTime(cert.getNotAfter()); startInvalidEnd.add(Calendar.SECOND, ((DEFAULT_SECONDS + DEFAULT_SECONDS_OFFSET) * -1)); startInvalidRange.setEndDate(startInvalidEnd); startInvalid.setDateRange(startInvalidRange); expected.clear(); validateFind(startInvalid, expected); // Test invalid end UserCertificateFilter endInvalid = new UserCertificateFilter(); DateRange endInvalidRange = new DateRange(); Calendar endInvalidStart = new GregorianCalendar(); endInvalidStart.setTime(cert.getNotBefore()); endInvalidStart.add(Calendar.SECOND, ((DEFAULT_SECONDS + DEFAULT_SECONDS_OFFSET) * 1)); endInvalidRange.setStartDate(endInvalidStart); Calendar endInvalidEnd = new GregorianCalendar(); endInvalidEnd.setTime(cert.getNotAfter()); endInvalidEnd.add(Calendar.SECOND, (DEFAULT_SECONDS_OFFSET * 2)); endInvalidRange.setEndDate(endInvalidEnd); endInvalid.setDateRange(endInvalidRange); expected.clear(); validateFind(endInvalid, expected); // Test update String msg = "Hello " + i; UserCertificateUpdate u = new UserCertificateUpdate(); u.setSerialNumber(cert.getSerialNumber().longValue()); u.setStatus(UserCertificateStatus.COMPROMISED); u.setNotes(msg); man.updateUserCertificateRecord(u); r.setStatus(UserCertificateStatus.COMPROMISED); r.setNotes(msg); // Test Update Results UserCertificateFilter update = new UserCertificateFilter(); update.setStatus(UserCertificateStatus.OK); update.setNotes(msg); expected.clear(); validateFind(update, expected); expected.clear(); update.setStatus(UserCertificateStatus.COMPROMISED); update.setNotes(msg); expected.put(new Long(r.getSerialNumber()), r); validateFind(update, expected); checkCRL(man.getCompromisedCertificates(), (i + 1)); // Test All UserCertificateFilter all = new UserCertificateFilter(); all.setSerialNumber(new Long(r.getSerialNumber())); all.setGridIdentity(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName())); all.setStatus(UserCertificateStatus.COMPROMISED); all.setNotes(msg); all.setDateRange(insideRange); expected.put(new Long(r.getSerialNumber()), r); validateFind(all, expected); } for (int i = 0; i < count; i++) { UserCertificateRecord r = records.get(i); man.removeCertificates(r.getGridIdentity()); assertEquals(false, man.determineIfRecordExistBySerialNumber(r.getSerialNumber())); assertTrue(blackList.memberOfBlackList(r.getSerialNumber())); } } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } public void testUpdateNonExistingCertificate() { try { checkCRL(man.getCompromisedCertificates(), 0); UserCertificateUpdate update = new UserCertificateUpdate(); update.setSerialNumber(1); update.setStatus(UserCertificateStatus.COMPROMISED); try { man.updateUserCertificateRecord(update); fail("Should not be able to update a certificate that does not exist."); } catch (InvalidUserCertificateException e) { if (!e.getMessage().equals( UserCertificateManager.CANNOT_UPDATE_CERT_DOES_NOT_EXIST_ERROR)) { fail("Should not be able to update a certificate that does not exist."); } } } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } public void testUpdateCompromisedCertificate() { try { String uid = "jdoe"; X509Certificate cert = getAndValidateCertificate(uid, DEFAULT_SECONDS); man.addUserCertifcate(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName()), cert); UserCertificateRecord r = getAndValidateCertificateRecord(cert); checkCRL(man.getCompromisedCertificates(), 0); Map<Long, UserCertificateRecord> expected = new HashMap<Long, UserCertificateRecord>(); UserCertificateFilter sn = new UserCertificateFilter(); sn.setSerialNumber(new Long(r.getSerialNumber())); sn.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(sn, expected); expected.clear(); sn.setSerialNumber(new Long(0)); validateFind(sn, expected); // Test update UserCertificateUpdate u = new UserCertificateUpdate(); u.setSerialNumber(cert.getSerialNumber().longValue()); u.setStatus(UserCertificateStatus.COMPROMISED); man.updateUserCertificateRecord(u); r.setStatus(UserCertificateStatus.COMPROMISED); // Test Update Results UserCertificateFilter update = new UserCertificateFilter(); update.setStatus(UserCertificateStatus.OK); expected.clear(); validateFind(update, expected); expected.clear(); update.setStatus(UserCertificateStatus.COMPROMISED); expected.put(new Long(r.getSerialNumber()), r); validateFind(update, expected); checkCRL(man.getCompromisedCertificates(), 1); UserCertificateUpdate u2 = new UserCertificateUpdate(); u2.setSerialNumber(cert.getSerialNumber().longValue()); u2.setStatus(UserCertificateStatus.OK); try { man.updateUserCertificateRecord(u2); fail("Should not be able to change the status of a compromised certificate."); } catch (InvalidUserCertificateException e) { if (!e.getMessage().equals( UserCertificateManager.CANNOT_UPDATE_STATUS_IF_COMPROMISED_ERROR)) { fail("Should not be able to change the status of a compromised certificate."); } } checkCRL(man.getCompromisedCertificates(), 1); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } public void testActiveCertificates() { try { String uid = "jdoe"; Map<Long, UserCertificateRecord> expected = new HashMap<Long, UserCertificateRecord>(); GregorianCalendar now = new GregorianCalendar(); Calendar end = new GregorianCalendar(); end.add(Calendar.YEAR, 5); DateRange range = new DateRange(); range.setStartDate(now); range.setEndDate(end); // Create expired certificate X509Certificate expiredCert = getAndValidateCertificate(uid, DEFAULT_SECONDS, (DEFAULT_SECONDS * -2)); man.addUserCertifcate(CommonUtils.subjectToIdentity(expiredCert.getSubjectDN().getName()), expiredCert); UserCertificateRecord expired = getAndValidateCertificateRecord(expiredCert); UserCertificateFilter expiredFilter = new UserCertificateFilter(); expiredFilter.setSerialNumber(expired.getSerialNumber()); expiredFilter.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(expired.getSerialNumber()), expired); validateFind(expiredFilter, expected); expiredFilter.setDateRange(range); expected.clear(); validateFind(expiredFilter, expected); checkCRL(man.getCompromisedCertificates(), 0); // Create expired compromised certificate X509Certificate expiredCompromisedCert = getAndValidateCertificate(uid, DEFAULT_SECONDS, (DEFAULT_SECONDS * -2)); man.addUserCertifcate(CommonUtils.subjectToIdentity(expiredCompromisedCert.getSubjectDN().getName()), expiredCompromisedCert); UserCertificateRecord expiredCompromised = getAndValidateCertificateRecord(expiredCompromisedCert); UserCertificateFilter expiredCompromisedFilter = new UserCertificateFilter(); expiredCompromisedFilter.setSerialNumber(expiredCompromised.getSerialNumber()); expiredCompromisedFilter.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(expiredCompromised.getSerialNumber()), expiredCompromised); validateFind(expiredCompromisedFilter, expected); expiredCompromisedFilter.setDateRange(range); expected.clear(); validateFind(expiredCompromisedFilter, expected); UserCertificateUpdate expiredCompromisedUpdate = new UserCertificateUpdate(); expiredCompromisedUpdate.setSerialNumber(expiredCompromised.getSerialNumber()); expiredCompromisedUpdate.setStatus(UserCertificateStatus.COMPROMISED); man.updateUserCertificateRecord(expiredCompromisedUpdate); expiredCompromised.setStatus(UserCertificateStatus.COMPROMISED); expiredCompromisedFilter.setStatus(UserCertificateStatus.COMPROMISED); expiredCompromisedFilter.setDateRange(null); expected.clear(); expected.put(new Long(expiredCompromised.getSerialNumber()), expiredCompromised); validateFind(expiredCompromisedFilter, expected); checkCRL(man.getCompromisedCertificates(), 1); // Create Active certificate X509Certificate activeCert = getAndValidateCertificate(uid, DEFAULT_SECONDS); man.addUserCertifcate(CommonUtils.subjectToIdentity(activeCert.getSubjectDN().getName()), activeCert); UserCertificateRecord active = getAndValidateCertificateRecord(activeCert); UserCertificateFilter activeFilter = new UserCertificateFilter(); activeFilter.setSerialNumber(active.getSerialNumber()); activeFilter.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(active.getSerialNumber()), active); validateFind(activeFilter, expected); activeFilter.setDateRange(range); expected.clear(); expected.put(new Long(active.getSerialNumber()), active); validateFind(activeFilter, expected); checkCRL(man.getCompromisedCertificates(), 1); // Create Active certificate of a different user String uid2 = "jane"; X509Certificate activeCert2 = getAndValidateCertificate(uid2, DEFAULT_SECONDS); man.addUserCertifcate(CommonUtils.subjectToIdentity(activeCert2.getSubjectDN().getName()), activeCert2); UserCertificateRecord active2 = getAndValidateCertificateRecord(activeCert2); UserCertificateFilter activeFilter2 = new UserCertificateFilter(); activeFilter2.setSerialNumber(active2.getSerialNumber()); activeFilter2.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(active2.getSerialNumber()), active2); validateFind(activeFilter2, expected); activeFilter2.setDateRange(range); expected.clear(); expected.put(new Long(active2.getSerialNumber()), active2); validateFind(activeFilter2, expected); checkCRL(man.getCompromisedCertificates(), 1); // Create Active Compromised Certificate X509Certificate activeCompromisedCert = getAndValidateCertificate(uid, DEFAULT_SECONDS); man.addUserCertifcate(CommonUtils.subjectToIdentity(activeCompromisedCert.getSubjectDN().getName()), activeCompromisedCert); UserCertificateRecord activeCompromised = getAndValidateCertificateRecord(activeCompromisedCert); UserCertificateFilter activeCompromisedFilter = new UserCertificateFilter(); activeCompromisedFilter.setSerialNumber(activeCompromised.getSerialNumber()); activeCompromisedFilter.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(activeCompromised.getSerialNumber()), activeCompromised); validateFind(activeCompromisedFilter, expected); activeCompromisedFilter.setDateRange(range); expected.clear(); expected.put(new Long(activeCompromised.getSerialNumber()), activeCompromised); validateFind(activeCompromisedFilter, expected); UserCertificateUpdate update = new UserCertificateUpdate(); update.setSerialNumber(activeCompromised.getSerialNumber()); update.setStatus(UserCertificateStatus.COMPROMISED); man.updateUserCertificateRecord(update); activeCompromised.setStatus(UserCertificateStatus.COMPROMISED); activeCompromisedFilter.setStatus(UserCertificateStatus.COMPROMISED); expected.clear(); expected.put(new Long(activeCompromised.getSerialNumber()), activeCompromised); validateFind(activeCompromisedFilter, expected); checkCRL(man.getCompromisedCertificates(), 2); List<BigInteger> activeResults = man.getActiveCertificates(CommonUtils .subjectToIdentity(expiredCompromisedCert.getSubjectDN().getName())); List<BigInteger> expectedResults = new ArrayList<BigInteger>(); expectedResults.add(activeCert.getSerialNumber()); validateExpectedSerialNumbers(expectedResults, activeResults); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } public void testCompromisedCertificates() { try { String uid = "john"; Map<Long, UserCertificateRecord> expected = new HashMap<Long, UserCertificateRecord>(); GregorianCalendar now = new GregorianCalendar(); Calendar end = new GregorianCalendar(); end.add(Calendar.YEAR, 5); DateRange range = new DateRange(); range.setStartDate(now); range.setEndDate(end); // Create expired certificate X509Certificate expiredCert = getAndValidateCertificate(uid, DEFAULT_SECONDS, (DEFAULT_SECONDS * -2)); man.addUserCertifcate(CommonUtils.subjectToIdentity(expiredCert.getSubjectDN().getName()), expiredCert); UserCertificateRecord expired = getAndValidateCertificateRecord(expiredCert); UserCertificateFilter expiredFilter = new UserCertificateFilter(); expiredFilter.setSerialNumber(expired.getSerialNumber()); expiredFilter.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(expired.getSerialNumber()), expired); validateFind(expiredFilter, expected); expiredFilter.setDateRange(range); expected.clear(); validateFind(expiredFilter, expected); checkCRL(man.getCompromisedCertificates(), 0); // Create expired compromised certificate X509Certificate expiredCompromisedCert = getAndValidateCertificate(uid, DEFAULT_SECONDS, (DEFAULT_SECONDS * -2)); man.addUserCertifcate(CommonUtils.subjectToIdentity(expiredCompromisedCert.getSubjectDN().getName()), expiredCompromisedCert); UserCertificateRecord expiredCompromised = getAndValidateCertificateRecord(expiredCompromisedCert); UserCertificateFilter expiredCompromisedFilter = new UserCertificateFilter(); expiredCompromisedFilter.setSerialNumber(expiredCompromised.getSerialNumber()); expiredCompromisedFilter.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(expiredCompromised.getSerialNumber()), expiredCompromised); validateFind(expiredCompromisedFilter, expected); expiredCompromisedFilter.setDateRange(range); expected.clear(); validateFind(expiredCompromisedFilter, expected); UserCertificateUpdate expiredCompromisedUpdate = new UserCertificateUpdate(); expiredCompromisedUpdate.setSerialNumber(expiredCompromised.getSerialNumber()); expiredCompromisedUpdate.setStatus(UserCertificateStatus.COMPROMISED); man.updateUserCertificateRecord(expiredCompromisedUpdate); expiredCompromised.setStatus(UserCertificateStatus.COMPROMISED); expiredCompromisedFilter.setStatus(UserCertificateStatus.COMPROMISED); expiredCompromisedFilter.setDateRange(null); expected.clear(); expected.put(new Long(expiredCompromised.getSerialNumber()), expiredCompromised); validateFind(expiredCompromisedFilter, expected); checkCRL(man.getCompromisedCertificates(), 1); String uid2 = "jane"; // Create Active certificate X509Certificate activeCert = getAndValidateCertificate(uid2, DEFAULT_SECONDS); man.addUserCertifcate(CommonUtils.subjectToIdentity(activeCert.getSubjectDN().getName()), activeCert); UserCertificateRecord active = getAndValidateCertificateRecord(activeCert); UserCertificateFilter activeFilter = new UserCertificateFilter(); activeFilter.setSerialNumber(active.getSerialNumber()); activeFilter.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(active.getSerialNumber()), active); validateFind(activeFilter, expected); activeFilter.setDateRange(range); expected.clear(); expected.put(new Long(active.getSerialNumber()), active); validateFind(activeFilter, expected); checkCRL(man.getCompromisedCertificates(), 1); // Create Active Compromised Certificate X509Certificate activeCompromisedCert = getAndValidateCertificate(uid2, DEFAULT_SECONDS); man.addUserCertifcate(CommonUtils.subjectToIdentity(activeCompromisedCert.getSubjectDN().getName()), activeCompromisedCert); UserCertificateRecord activeCompromised = getAndValidateCertificateRecord(activeCompromisedCert); UserCertificateFilter activeCompromisedFilter = new UserCertificateFilter(); activeCompromisedFilter.setSerialNumber(activeCompromised.getSerialNumber()); activeCompromisedFilter.setStatus(UserCertificateStatus.OK); expected.clear(); expected.put(new Long(activeCompromised.getSerialNumber()), activeCompromised); validateFind(activeCompromisedFilter, expected); activeCompromisedFilter.setDateRange(range); expected.clear(); expected.put(new Long(activeCompromised.getSerialNumber()), activeCompromised); validateFind(activeCompromisedFilter, expected); UserCertificateUpdate update = new UserCertificateUpdate(); update.setSerialNumber(activeCompromised.getSerialNumber()); update.setStatus(UserCertificateStatus.COMPROMISED); man.updateUserCertificateRecord(update); activeCompromised.setStatus(UserCertificateStatus.COMPROMISED); activeCompromisedFilter.setStatus(UserCertificateStatus.COMPROMISED); expected.clear(); expected.put(new Long(activeCompromised.getSerialNumber()), activeCompromised); validateFind(activeCompromisedFilter, expected); checkCRL(man.getCompromisedCertificates(), 2); List<BigInteger> compromisedResults = man.getCompromisedCertificates(); List<BigInteger> expectedResults = new ArrayList<BigInteger>(); expectedResults.add(activeCompromisedCert.getSerialNumber()); expectedResults.add(expiredCompromisedCert.getSerialNumber()); validateExpectedSerialNumbers(expectedResults, compromisedResults); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } public void testFindUserCertificatesInvalidRange() { try { String uid = "jdoe"; X509Certificate cert = getAndValidateCertificate(uid, DEFAULT_SECONDS); man.addUserCertifcate(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName()), cert); UserCertificateRecord r = getAndValidateCertificateRecord(cert); Map<Long, UserCertificateRecord> expected = new HashMap<Long, UserCertificateRecord>(); // Test Serial Number UserCertificateFilter sn = new UserCertificateFilter(); sn.setSerialNumber(new Long(r.getSerialNumber())); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(sn, expected); expected.clear(); sn.setSerialNumber(new Long(0)); validateFind(sn, expected); // Test exact date range UserCertificateFilter exactDates = new UserCertificateFilter(); DateRange range = new DateRange(); exactDates.setDateRange(range); GregorianCalendar start = new GregorianCalendar(); start.setTime(cert.getNotBefore()); GregorianCalendar end = new GregorianCalendar(); end.setTime(cert.getNotAfter()); try { man.findUserCertificateRecords(exactDates); fail("Should not be able to find user certificate records with an invalid range."); } catch (InvalidUserCertificateException e) { if (!e.getMessage().equals( UserCertificateManager.FIND_INVALID_RANGE_NO_START_ERROR)) { fail("Should not be able to find user certificate records with an invalid range."); } } range.setStartDate(start); range.setEndDate(null); try { man.findUserCertificateRecords(exactDates); fail("Should not be able to find user certificate records with an invalid range."); } catch (InvalidUserCertificateException e) { if (!e.getMessage().equals( UserCertificateManager.FIND_INVALID_RANGE_NO_END_ERROR)) { fail("Should not be able to find user certificate records with an invalid range."); } } range.setStartDate(null); range.setEndDate(end); try { man.findUserCertificateRecords(exactDates); fail("Should not be able to find user certificate records with an invalid range."); } catch (InvalidUserCertificateException e) { if (!e.getMessage().equals( UserCertificateManager.FIND_INVALID_RANGE_NO_START_ERROR)) { fail("Should not be able to find user certificate records with an invalid range."); } } range.setStartDate(end); range.setEndDate(start); try { man.findUserCertificateRecords(exactDates); fail("Should not be able to find user certificate records with an invalid range."); } catch (InvalidUserCertificateException e) { if (!e.getMessage().equals( UserCertificateManager.FIND_INVALID_RANGE_ERROR)) { fail("Should not be able to find user certificate records with an invalid range."); } } range.setStartDate(start); range.setEndDate(end); expected.clear(); expected.put(new Long(r.getSerialNumber()), r); validateFind(exactDates, expected); // Test all } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } public void testSingleUserCertificateDuplicateEntries() { try { String uid = "jdoe"; X509Certificate cert = getAndValidateCertificate(uid, DEFAULT_SECONDS); man.addUserCertifcate(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName()), cert); getAndValidateCertificateRecord(cert); try { man.addUserCertifcate(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName()), cert); fail("Should not be able to add existing user certificate!!!"); } catch (InvalidUserCertificateException e) { if (!e.getMessage().equals( UserCertificateManager.USER_CERTIFICATE_ALREADY_EXISTS_ERROR)) { fail("Should not be able to add existing user certificate!!!"); } } } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } private void validateExpectedSerialNumbers(List<BigInteger> expected, List<BigInteger> actual) throws Exception { assertEquals(expected.size(), actual.size()); for (int i = 0; i < expected.size(); i++) { boolean found = false; for (int j = 0; j < actual.size(); j++) { if (expected.get(i).equals(actual.get(j))) { found = true; break; } } if (!found) { fail("The user certificate record " + expected.get(i) + " was expected but was not found."); } } } private void validateFind(UserCertificateFilter f, Map<Long, UserCertificateRecord> expected) throws Exception { List<UserCertificateRecord> results = man.findUserCertificateRecords(f); assertEquals(expected.size(), results.size()); for (int i = 0; i < results.size(); i++) { Long sn = new Long(results.get(i).getSerialNumber()); if (expected.containsKey(sn)) { assertEquals(expected.get(sn), results.remove(i)); } else { fail("The user certificate record " + sn + " but was not expected."); } } } private UserCertificateRecord getAndValidateCertificateRecord(X509Certificate cert) throws Exception { assertTrue(man.determineIfRecordExistBySerialNumber(cert.getSerialNumber().longValue())); UserCertificateRecord record = man.getUserCertificateRecord(cert.getSerialNumber().longValue()); assertNotNull(record); assertEquals(CommonUtils.subjectToIdentity(cert.getSubjectDN().getName()), record.getGridIdentity()); assertEquals("", record.getNotes()); assertEquals(cert.getSerialNumber().longValue(), record.getSerialNumber()); assertEquals(UserCertificateStatus.OK, record.getStatus()); X509Certificate cert2 = CertUtil.loadCertificate(record.getCertificate().getCertificateAsString()); assertEquals(cert, cert2); return record; } private X509Certificate getAndValidateCertificate(String uid, int seconds) throws Exception { return getAndValidateCertificate(uid, seconds, 0); } private X509Certificate getAndValidateCertificate(String uid, int seconds, int timeOffset) throws Exception { String subject = getUserSubject(uid); Calendar c = new GregorianCalendar(); c.add(Calendar.SECOND, timeOffset); Date start = c.getTime(); c.add(Calendar.SECOND, seconds); Date end = c.getTime(); X509Certificate cert = getCertificate(subject, start, end); assertEquals(subject, cert.getSubjectDN().getName()); return cert; } private String getUserSubject(String uid) { int caindex = caSubject.lastIndexOf(","); String caPreSub = caSubject.substring(0, caindex); return caPreSub + ",OU=" + 123 + ",CN=" + uid; } private X509Certificate getCertificate(String subject, Date start, Date end) throws Exception { KeyPair pair = KeyUtil.generateRSAKeyPair1024(); return ca.signCertificate(subject, pair.getPublic(), start, end, CertificateSignatureAlgorithm.SHA2); } public void checkCRL(List<BigInteger> expected, int expectedCount) { assertEquals(expectedCount, this.crlPublishCount); assertEquals(expected, this.crl); } public void publishCRL() { try { this.crlPublishCount = this.crlPublishCount + 1; this.crl = man.getCompromisedCertificates(); } catch (Exception e) { e.printStackTrace(); } } protected void setUp() throws Exception { super.setUp(); try { db = Utils.getDB(); assertEquals(0, db.getUsedConnectionCount()); ca = Utils.getCA(); caSubject = ca.getCACertificate().getSubjectDN().getName(); blackList = new CertificateBlacklistManager(db); blackList.clearDatabase(); man = new UserCertificateManager(db, this, blackList); man.clearDatabase(); this.crlPublishCount = 0; this.crl = new ArrayList<BigInteger>(); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } protected void tearDown() throws Exception { super.setUp(); try { ca.clearCertificateAuthority(); blackList.clearDatabase(); man.clearDatabase(); this.crlPublishCount = 0; this.crl = null; assertEquals(0, db.getUsedConnectionCount()); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } }