}
- public static final int CURRENT_SCHEMA_VERSION = 29;
+ public static final int CURRENT_SCHEMA_VERSION = 30;
public static final int CONNECTION_TIMEOUT = 24 * 60 * 60;
DROP TABLE IF EXISTS "certsRevoked";
DROP TYPE IF EXISTS "revocationType";
-CREATE TYPE "revocationType" AS ENUM('user', 'support', 'ping_timeout');
+CREATE TYPE "revocationType" AS ENUM('user', 'support', 'ping_timeout', 'key_compromise');
CREATE TABLE "certsRevoked" (
"id" int NOT NULL,
-- the time when the certificate was revoked by cassiopeia (and that is stored in the CRL)
-- NULL indicated the revocation is pending
"revoked" timestamp NULL,
"type" "revocationType" NOT NULL,
+ "challenge" varchar(16) NULL DEFAULT NULL,
+ "signature" text NULL DEFAULT NULL,
+ "message" text NULL DEFAULT NULL,
PRIMARY KEY ("id")
);
"version" smallint NOT NULL,
PRIMARY KEY ("version")
);
-INSERT INTO "schemeVersion" (version) VALUES(29);
+INSERT INTO "schemeVersion" (version) VALUES(30);
DROP TABLE IF EXISTS `passwordResetTickets`;
CREATE TABLE `passwordResetTickets` (
--- /dev/null
+ALTER TABLE "certsRevoked" ADD COLUMN "challenge" varchar(16) NULL DEFAULT NULL;
+ALTER TABLE "certsRevoked" ADD COLUMN "signature" text NULL DEFAULT NULL;
+ALTER TABLE "certsRevoked" ADD COLUMN "message" text NULL DEFAULT NULL;
+
+ALTER TYPE "revocationType" ADD VALUE 'key_compromise' AFTER 'ping_timeout';
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Locale;
import java.util.Map.Entry;
import club.wpia.gigi.GigiApiException;
public class Certificate implements IdCachable {
public enum RevocationType implements DBEnum {
- USER("user"), SUPPORT("support"), PING_TIMEOUT("ping_timeout");
+ USER("user"), SUPPORT("support"), PING_TIMEOUT("ping_timeout"), KEY_COMPROMISE("key_compromise");
private final String dbName;
public String getDBName() {
return dbName;
}
+
+ public static RevocationType fromString(String s) {
+ return valueOf(s.toUpperCase(Locale.ENGLISH));
+ }
}
public enum SANType implements DBEnum {
throw new IllegalStateException();
}
return Job.revoke(this, type);
+ }
+ public Job revoke(String challenge, String signature, String message) {
+ if (getStatus() != CertificateStatus.ISSUED) {
+ throw new IllegalStateException();
+ }
+ return Job.revoke(this, challenge, signature, message);
}
public CACertificate getParent() {
}
protected synchronized static Job revoke(Certificate targetId, RevocationType type) {
- try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `certsRevoked` SET id=?, type=?::`revocationType`")) {
+ return revoke(targetId, type, null, null, null);
+ }
+
+ protected synchronized static Job revoke(Certificate targetId, String challenge, String signature, String message) {
+ return revoke(targetId, RevocationType.KEY_COMPROMISE, challenge, signature, message);
+ }
+
+ private synchronized static Job revoke(Certificate targetId, RevocationType type, String challenge, String signature, String message) {
+ try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `certsRevoked` SET id=?, type=?::`revocationType`, challenge=?, signature=?, message=?")) {
ps.setInt(1, targetId.getId());
ps.setEnum(2, type);
+ ps.setString(3, challenge);
+ ps.setString(4, signature);
+ ps.setString(5, message);
ps.execute();
}