1 package org.cacert.gigi;
4 import java.io.FileInputStream;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.security.GeneralSecurityException;
9 import java.security.cert.CertificateFactory;
10 import java.security.cert.X509Certificate;
11 import java.sql.PreparedStatement;
12 import java.sql.ResultSet;
13 import java.sql.SQLException;
15 import org.cacert.gigi.database.DatabaseConnection;
16 import org.cacert.gigi.util.Job;
17 import org.cacert.gigi.util.Job.JobType;
18 import org.cacert.gigi.util.KeyStorage;
19 import org.cacert.gigi.util.Notary;
21 public class Certificate {
24 private String serial;
27 private String csrName;
28 private String crtName;
29 private String csr = null;
31 public Certificate(int ownerId, String dn, String md, String csr) {
32 this.ownerId = ownerId;
38 private Certificate(String serial) {
40 PreparedStatement ps = DatabaseConnection.getInstance().prepare(
41 "SELECT id,subject, md, csr_name, crt_name,memid FROM `emailcerts` WHERE serial=?");
42 ps.setString(1, serial);
43 ResultSet rs = ps.executeQuery();
45 throw new IllegalArgumentException("Invalid mid " + serial);
47 this.id = rs.getInt(1);
50 csrName = rs.getString(4);
51 crtName = rs.getString(5);
52 ownerId = rs.getInt(6);
55 } catch (SQLException e) {
60 public enum CertificateStatus {
62 * This certificate is not in the database, has no id and only exists as
67 * The certificate has been signed. It is stored in the database.
68 * {@link Certificate#cert()} is valid.
73 * The certificate has been revoked.
78 * If this certificate cannot be updated because an error happened in
83 private CertificateStatus() {
88 public CertificateStatus getStatus() throws SQLException {
90 return CertificateStatus.DRAFT;
92 PreparedStatement searcher = DatabaseConnection.getInstance().prepare(
93 "SELECT crt_name, created, revoked, serial FROM emailcerts WHERE id=?");
94 searcher.setInt(1, id);
95 ResultSet rs = searcher.executeQuery();
97 throw new IllegalStateException("Certificate not in Database");
100 crtName = rs.getString(1);
101 serial = rs.getString(4);
102 if (rs.getTime(2) == null) {
103 return CertificateStatus.DRAFT;
105 if (rs.getTime(2) != null && rs.getTime(3) == null) {
106 return CertificateStatus.ISSUED;
108 return CertificateStatus.REVOKED;
111 public Job issue() throws IOException, SQLException {
112 if (getStatus() != CertificateStatus.DRAFT) {
113 throw new IllegalStateException();
115 Notary.writeUserAgreement(ownerId, "CCA", "issue certificate", "", true, 0);
117 PreparedStatement inserter = DatabaseConnection.getInstance().prepare(
118 "INSERT INTO emailcerts SET md=?, subject=?, crt_name='', memid=?");
119 inserter.setString(1, md);
120 inserter.setString(2, dn);
121 inserter.setInt(3, ownerId);
123 id = DatabaseConnection.lastInsertId(inserter);
124 File csrFile = KeyStorage.locateCsr(id);
125 csrName = csrFile.getPath();
126 FileOutputStream fos = new FileOutputStream(csrFile);
127 fos.write(csr.getBytes());
130 PreparedStatement updater = DatabaseConnection.getInstance().prepare(
131 "UPDATE emailcerts SET csr_name=? WHERE id=?");
132 updater.setString(1, csrName);
133 updater.setInt(2, id);
135 return Job.submit(this, JobType.SIGN);
139 public Job revoke() throws SQLException {
140 if (getStatus() != CertificateStatus.ISSUED) {
141 throw new IllegalStateException();
143 return Job.submit(this, JobType.REVOKE);
147 public X509Certificate cert() throws IOException, GeneralSecurityException, SQLException {
148 CertificateStatus status = getStatus();
149 if (status != CertificateStatus.ISSUED) {
150 throw new IllegalStateException(status + " is not wanted here.");
152 InputStream is = null;
153 X509Certificate crt = null;
155 is = new FileInputStream(crtName);
156 CertificateFactory cf = CertificateFactory.getInstance("X.509");
157 crt = (X509Certificate) cf.generateCertificate(is);
166 public Certificate renew() {
174 public String getSerial() {
178 public String getDistinguishedName() {
182 public String getMessageDigest() {
186 public int getOwnerId() {
190 public static Certificate getBySerial(String serial) {
193 return new Certificate(serial);
194 } catch (IllegalArgumentException e) {