Change-Id: Ie2a51a16eed420b284f9fd5660e057da1069b740
13 files changed:
import javax.servlet.http.HttpServletResponse;
import club.wpia.gigi.dbObjects.Certificate;
import javax.servlet.http.HttpServletResponse;
import club.wpia.gigi.dbObjects.Certificate;
+import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
+import club.wpia.gigi.dbObjects.Certificate.RevocationType;
import club.wpia.gigi.dbObjects.Job;
import club.wpia.gigi.dbObjects.User;
import club.wpia.gigi.dbObjects.Job;
import club.wpia.gigi.dbObjects.User;
-import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
public class RevokeCertificate extends APIPoint {
public class RevokeCertificate extends APIPoint {
+ Job job = c.revoke(RevocationType.USER);
job.waitFor(60000);
if (c.getStatus() != CertificateStatus.REVOKED) {
resp.sendError(510, "Error, issuing timed out");
job.waitFor(60000);
if (c.getStatus() != CertificateStatus.REVOKED) {
resp.sendError(510, "Error, issuing timed out");
- public static final int CURRENT_SCHEMA_VERSION = 28;
+ public static final int CURRENT_SCHEMA_VERSION = 29;
public static final int CONNECTION_TIMEOUT = 24 * 60 * 60;
public static final int CONNECTION_TIMEOUT = 24 * 60 * 60;
);
DROP TABLE IF EXISTS "certs";
);
DROP TABLE IF EXISTS "certs";
+DROP TYPE IF EXISTS "revocationType";
+CREATE TYPE "revocationType" AS ENUM('user', 'support', 'ping_timeout');
DROP TYPE IF EXISTS "mdType";
CREATE TYPE "mdType" AS ENUM('md5','sha1','sha256','sha384','sha512');
DROP TYPE IF EXISTS "mdType";
CREATE TYPE "mdType" AS ENUM('md5','sha1','sha256','sha384','sha512');
"crt_name" varchar(255) NOT NULL DEFAULT '',
"created" timestamp NULL DEFAULT NULL,
"modified" timestamp NULL DEFAULT NULL,
"crt_name" varchar(255) NOT NULL DEFAULT '',
"created" timestamp NULL DEFAULT NULL,
"modified" timestamp NULL DEFAULT NULL,
- "revoked" timestamp NULL DEFAULT NULL,
+ "revoked" timestamp NULL,
+ "revocationType" "revocationType" NULL,
"expire" timestamp NULL DEFAULT NULL,
"renewed" boolean NOT NULL DEFAULT 'false',
"pkhash" char(40) DEFAULT NULL,
"expire" timestamp NULL DEFAULT NULL,
"renewed" boolean NOT NULL DEFAULT 'false',
"pkhash" char(40) DEFAULT NULL,
CREATE INDEX ON "certs" ("crt_name");
CREATE INDEX ON "certs" ("crt_name");
DROP TABLE IF EXISTS "certAvas";
CREATE TABLE "certAvas" (
"certId" int NOT NULL,
DROP TABLE IF EXISTS "certAvas";
CREATE TABLE "certAvas" (
"certId" int NOT NULL,
"version" smallint NOT NULL,
PRIMARY KEY ("version")
);
"version" smallint NOT NULL,
PRIMARY KEY ("version")
);
-INSERT INTO "schemeVersion" (version) VALUES(28);
+INSERT INTO "schemeVersion" (version) VALUES(29);
DROP TABLE IF EXISTS `passwordResetTickets`;
CREATE TABLE `passwordResetTickets` (
DROP TABLE IF EXISTS `passwordResetTickets`;
CREATE TABLE `passwordResetTickets` (
--- /dev/null
+CREATE TYPE "revocationType" AS ENUM('user', 'support', 'ping_timeout');
+ALTER TABLE "certs" ADD COLUMN "revocationType" "revocationType" NULL;
public class Certificate implements IdCachable {
public class Certificate implements IdCachable {
+ public enum RevocationType implements DBEnum {
+ USER("user"), SUPPORT("support"), PING_TIMEOUT("ping_timeout");
+
+ private final String dbName;
+
+ private RevocationType(String dbName) {
+ this.dbName = dbName;
+ }
+
+ @Override
+ public String getDBName() {
+ return dbName;
+ }
+ }
+
public enum SANType implements DBEnum {
EMAIL("email"), DNS("DNS");
public enum SANType implements DBEnum {
EMAIL("email"), DNS("DNS");
+ public Job revoke(RevocationType type) {
if (getStatus() != CertificateStatus.ISSUED) {
throw new IllegalStateException();
}
if (getStatus() != CertificateStatus.ISSUED) {
throw new IllegalStateException();
}
- return Job.revoke(this);
+ return Job.revoke(this, type);
}
public Certificate[] getCertificates(boolean includeRevoked) {
}
public Certificate[] getCertificates(boolean includeRevoked) {
- try (GigiPreparedStatement ps = new GigiPreparedStatement(includeRevoked ? "SELECT id FROM certs WHERE memid=? ORDER BY id DESC" : "SELECT id FROM certs WHERE memid=? AND revoked IS NULL ORDER BY id DESC")) {
+ try (GigiPreparedStatement ps = new GigiPreparedStatement(includeRevoked ? "SELECT id FROM certs WHERE memid=? ORDER BY id DESC" : "SELECT id FROM certs WHERE memid=? AND `revoked` IS NULL ORDER BY id DESC")) {
ps.setInt(1, getId());
GigiResultSet rs = ps.executeQuery();
ps.setInt(1, getId());
GigiResultSet rs = ps.executeQuery();
import club.wpia.gigi.database.DBEnum;
import club.wpia.gigi.database.GigiPreparedStatement;
import club.wpia.gigi.database.GigiResultSet;
import club.wpia.gigi.database.DBEnum;
import club.wpia.gigi.database.GigiPreparedStatement;
import club.wpia.gigi.database.GigiResultSet;
+import club.wpia.gigi.dbObjects.Certificate.RevocationType;
import club.wpia.gigi.output.CertificateValiditySelector;
public class Job implements IdCachable {
import club.wpia.gigi.output.CertificateValiditySelector;
public class Job implements IdCachable {
- public synchronized static Job sign(Certificate targetId, Date start, String period) throws GigiApiException {
+ protected synchronized static Job sign(Certificate targetId, Date start, String period) throws GigiApiException {
CertificateValiditySelector.checkValidityLength(period);
try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `jobs` SET targetId=?, task=?::`jobType`, executeFrom=?, executeTo=?")) {
ps.setInt(1, targetId.getId());
CertificateValiditySelector.checkValidityLength(period);
try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `jobs` SET targetId=?, task=?::`jobType`, executeFrom=?, executeTo=?")) {
ps.setInt(1, targetId.getId());
- public synchronized static Job revoke(Certificate targetId) {
+ protected synchronized static Job revoke(Certificate targetId, RevocationType type) {
+ try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE `certs` SET `revocationType`=?::`revocationType` WHERE id=?")) {
+ ps.setEnum(1, type);
+ ps.setInt(2, targetId.getId());
+ ps.execute();
+ }
try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `jobs` SET targetId=?, task=?::`jobType`")) {
ps.setInt(1, targetId.getId());
try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `jobs` SET targetId=?, task=?::`jobType`")) {
ps.setInt(1, targetId.getId());
import club.wpia.gigi.database.GigiPreparedStatement;
import club.wpia.gigi.database.GigiResultSet;
import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
import club.wpia.gigi.database.GigiPreparedStatement;
import club.wpia.gigi.database.GigiResultSet;
import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
+import club.wpia.gigi.dbObjects.Certificate.RevocationType;
import club.wpia.gigi.dbObjects.Country.CountryCodeType;
import club.wpia.gigi.dbObjects.wrappers.DataContainer;
import club.wpia.gigi.dbObjects.Country.CountryCodeType;
import club.wpia.gigi.dbObjects.wrappers.DataContainer;
}
for (Certificate cert : getCertificates(false)) {
if (cert.getStatus() == CertificateStatus.ISSUED) {
}
for (Certificate cert : getCertificates(false)) {
if (cert.getStatus() == CertificateStatus.ISSUED) {
+ cert.revoke(RevocationType.USER);
}
}
try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE `organisations` SET `name`=?, `country`=?, `province`=?, `city`=? WHERE `id`=?")) {
}
}
try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE `organisations` SET `name`=?, `country`=?, `province`=?, `city`=? WHERE `id`=?")) {
import club.wpia.gigi.GigiApiException;
import club.wpia.gigi.database.GigiPreparedStatement;
import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
import club.wpia.gigi.GigiApiException;
import club.wpia.gigi.database.GigiPreparedStatement;
import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
+import club.wpia.gigi.dbObjects.Certificate.RevocationType;
import club.wpia.gigi.localisation.Language;
import club.wpia.gigi.output.template.MailTemplate;
import club.wpia.gigi.output.template.Outputable;
import club.wpia.gigi.localisation.Language;
import club.wpia.gigi.output.template.MailTemplate;
import club.wpia.gigi.output.template.Outputable;
// TODO Check for open jobs!
for (int i = 0; i < certs.length; i++) {
if (certs[i].getStatus() == CertificateStatus.ISSUED) {
// TODO Check for open jobs!
for (int i = 0; i < certs.length; i++) {
if (certs[i].getStatus() == CertificateStatus.ISSUED) {
+ certs[i].revoke(RevocationType.SUPPORT);
}
}
// send notification to support
}
}
// send notification to support
// TODO Check for open jobs!
if (cert.getStatus() == CertificateStatus.ISSUED) {
writeSELog("SE Revoke certificate");
// TODO Check for open jobs!
if (cert.getStatus() == CertificateStatus.ISSUED) {
writeSELog("SE Revoke certificate");
- cert.revoke().waitFor(60000);
+ cert.revoke(RevocationType.SUPPORT).waitFor(60000);
// send notification to support
String subject = "Revoke certificate";
Outputable message = SprintfCommand.createSimple("Certificate with serial number {0} for {1} <{2}> has been revoked.", cert.getSerial(), target.getPreferredName().toString(), target.getEmail());
// send notification to support
String subject = "Revoke certificate";
Outputable message = SprintfCommand.createSimple("Certificate with serial number {0} for {1} <{2}> has been revoked.", cert.getSerial(), target.getPreferredName().toString(), target.getEmail());
import club.wpia.gigi.GigiApiException;
import club.wpia.gigi.dbObjects.Certificate;
import club.wpia.gigi.GigiApiException;
import club.wpia.gigi.dbObjects.Certificate;
+import club.wpia.gigi.dbObjects.Certificate.RevocationType;
import club.wpia.gigi.dbObjects.CertificateOwner;
import club.wpia.gigi.dbObjects.Job;
import club.wpia.gigi.localisation.Language;
import club.wpia.gigi.dbObjects.CertificateOwner;
import club.wpia.gigi.dbObjects.Job;
import club.wpia.gigi.localisation.Language;
if (c == null || c.getOwner() != target) {
continue;
}
if (c == null || c.getOwner() != target) {
continue;
}
- revokes.add(c.revoke());
+ revokes.add(c.revoke(RevocationType.SUPPORT));
}
long start = System.currentTimeMillis();
for (Job job : revokes) {
}
long start = System.currentTimeMillis();
for (Job job : revokes) {
import club.wpia.gigi.GigiApiException;
import club.wpia.gigi.dbObjects.Certificate;
import club.wpia.gigi.GigiApiException;
import club.wpia.gigi.dbObjects.Certificate;
+import club.wpia.gigi.dbObjects.Certificate.RevocationType;
import club.wpia.gigi.dbObjects.SupportedUser;
import club.wpia.gigi.localisation.Language;
import club.wpia.gigi.output.template.Form;
import club.wpia.gigi.dbObjects.SupportedUser;
import club.wpia.gigi.localisation.Language;
import club.wpia.gigi.output.template.Form;
if (target != null) {
target.revokeCertificate(c);
} else {
if (target != null) {
target.revokeCertificate(c);
} else {
- c.revoke().waitFor(60000);
+ c.revoke(RevocationType.USER).waitFor(60000);
}
return new RedirectResult(req.getPathInfo());
}
}
return new RedirectResult(req.getPathInfo());
}
import club.wpia.gigi.dbObjects.Certificate;
import club.wpia.gigi.dbObjects.Certificate.CSRType;
import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
import club.wpia.gigi.dbObjects.Certificate;
import club.wpia.gigi.dbObjects.Certificate.CSRType;
import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
+import club.wpia.gigi.dbObjects.Certificate.RevocationType;
import club.wpia.gigi.dbObjects.Certificate.SANType;
import club.wpia.gigi.dbObjects.Certificate.SubjectAlternateName;
import club.wpia.gigi.dbObjects.Digest;
import club.wpia.gigi.dbObjects.Certificate.SANType;
import club.wpia.gigi.dbObjects.Certificate.SubjectAlternateName;
import club.wpia.gigi.dbObjects.Digest;
assertNotNull(login(pk, cert));
assertEquals(1, countRegex(IOUtils.readURL(get(cookie, Certificates.PATH)), "<td>(?:REVOKED|ISSUED)</td>"));
assertEquals(1, countRegex(IOUtils.readURL(get(cookie, Certificates.PATH + "?withRevoked")), "<td>(?:REVOKED|ISSUED)</td>"));
assertNotNull(login(pk, cert));
assertEquals(1, countRegex(IOUtils.readURL(get(cookie, Certificates.PATH)), "<td>(?:REVOKED|ISSUED)</td>"));
assertEquals(1, countRegex(IOUtils.readURL(get(cookie, Certificates.PATH + "?withRevoked")), "<td>(?:REVOKED|ISSUED)</td>"));
+ await(c.revoke(RevocationType.USER));
testFails(CertificateStatus.REVOKED, c);
assertNull(login(pk, cert));
testFails(CertificateStatus.REVOKED, c);
assertNull(login(pk, cert));
assertEquals(status, c.getStatus());
if (status != CertificateStatus.ISSUED) {
try {
assertEquals(status, c.getStatus());
if (status != CertificateStatus.ISSUED) {
try {
+ c.revoke(RevocationType.USER);
fail(status + " is in invalid state");
} catch (IllegalStateException ise) {
fail(status + " is in invalid state");
} catch (IllegalStateException ise) {
warnMail = new GigiPreparedStatement("UPDATE jobs SET warning=warning+1, state=CASE WHEN warning<3 THEN 'open'::`jobState` ELSE 'error'::`jobState` END WHERE id=?");
revoke = new GigiPreparedStatement("SELECT certs.id, certs.csr_name,jobs.id FROM jobs INNER JOIN certs ON jobs.`targetId`=certs.id" + " WHERE jobs.state='open' AND task='revoke'");
warnMail = new GigiPreparedStatement("UPDATE jobs SET warning=warning+1, state=CASE WHEN warning<3 THEN 'open'::`jobState` ELSE 'error'::`jobState` END WHERE id=?");
revoke = new GigiPreparedStatement("SELECT certs.id, certs.csr_name,jobs.id FROM jobs INNER JOIN certs ON jobs.`targetId`=certs.id" + " WHERE jobs.state='open' AND task='revoke'");
- revokeCompleted = new GigiPreparedStatement("UPDATE certs SET revoked=NOW() WHERE id=?");
+ revokeCompleted = new GigiPreparedStatement("UPDATE `certs` SET revoked=NOW() WHERE id=?");
finishJob = new GigiPreparedStatement("UPDATE jobs SET state='done' WHERE id=?");
finishJob = new GigiPreparedStatement("UPDATE jobs SET state='done' WHERE id=?");
worked = true;
System.out.println("Revoke faked: " + id);
revokeCompleted.setInt(1, id);
worked = true;
System.out.println("Revoke faked: " + id);
revokeCompleted.setInt(1, id);
- revokeCompleted.execute();
+ revokeCompleted.executeUpdate();
finishJob.setInt(1, rs.getInt(3));
finishJob.setInt(1, rs.getInt(3));
+ finishJob.executeUpdate();
}
if (worked) {
gencrl();
}
if (worked) {
gencrl();
updateMail.setInt(3, caRs.getInt("id"));
updateMail.setTimestamp(4, new Timestamp(toDate.getTime()));
updateMail.setInt(5, id);
updateMail.setInt(3, caRs.getInt("id"));
updateMail.setTimestamp(4, new Timestamp(toDate.getTime()));
updateMail.setInt(5, id);
+ updateMail.executeUpdate();
finishJob.setInt(1, rs.getInt("jobid"));
finishJob.setInt(1, rs.getInt("jobid"));
+ finishJob.executeUpdate();
System.out.println("signed: " + id);
continue;
}
System.out.println("signed: " + id);
continue;
}
}
System.out.println("Error with: " + id);
warnMail.setInt(1, rs.getInt("jobid"));
}
System.out.println("Error with: " + id);
warnMail.setInt(1, rs.getInt("jobid"));
+ warnMail.executeUpdate();