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 {
28 private String serial;
31 private String csrName;
32 private String crtName;
33 private String csr = null;
34 private CSRType csrType;
36 public Certificate(int ownerId, String dn, String md, String csr, CSRType csrType) {
37 this.ownerId = ownerId;
41 this.csrType = csrType;
44 private Certificate(String serial) {
46 PreparedStatement ps = DatabaseConnection.getInstance().prepare(
47 "SELECT id,subject, md, csr_name, crt_name,memid FROM `emailcerts` WHERE serial=?");
48 ps.setString(1, serial);
49 ResultSet rs = ps.executeQuery();
51 throw new IllegalArgumentException("Invalid mid " + serial);
53 this.id = rs.getInt(1);
56 csrName = rs.getString(4);
57 crtName = rs.getString(5);
58 ownerId = rs.getInt(6);
61 } catch (SQLException e) {
66 public enum CertificateStatus {
68 * This certificate is not in the database, has no id and only exists as
73 * The certificate has been signed. It is stored in the database.
74 * {@link Certificate#cert()} is valid.
79 * The certificate has been revoked.
84 * If this certificate cannot be updated because an error happened in
89 private CertificateStatus() {
94 public CertificateStatus getStatus() throws SQLException {
96 return CertificateStatus.DRAFT;
98 PreparedStatement searcher = DatabaseConnection.getInstance().prepare(
99 "SELECT crt_name, created, revoked, serial FROM emailcerts WHERE id=?");
100 searcher.setInt(1, id);
101 ResultSet rs = searcher.executeQuery();
103 throw new IllegalStateException("Certificate not in Database");
106 crtName = rs.getString(1);
107 serial = rs.getString(4);
108 if (rs.getTime(2) == null) {
109 return CertificateStatus.DRAFT;
111 if (rs.getTime(2) != null && rs.getTime(3) == null) {
112 return CertificateStatus.ISSUED;
114 return CertificateStatus.REVOKED;
117 public Job issue() throws IOException, SQLException {
118 if (getStatus() != CertificateStatus.DRAFT) {
119 throw new IllegalStateException();
121 Notary.writeUserAgreement(ownerId, "CCA", "issue certificate", "", true, 0);
123 PreparedStatement inserter = DatabaseConnection.getInstance().prepare(
124 "INSERT INTO emailcerts SET md=?, subject=?, csr_type=?, crt_name='', memid=?");
125 inserter.setString(1, md);
126 System.out.println(csrType.toString());
127 inserter.setString(2, dn);
128 inserter.setString(3, csrType.toString());
129 inserter.setInt(4, ownerId);
131 id = DatabaseConnection.lastInsertId(inserter);
132 File csrFile = KeyStorage.locateCsr(id);
133 csrName = csrFile.getPath();
134 FileOutputStream fos = new FileOutputStream(csrFile);
135 fos.write(csr.getBytes());
138 PreparedStatement updater = DatabaseConnection.getInstance().prepare(
139 "UPDATE emailcerts SET csr_name=? WHERE id=?");
140 updater.setString(1, csrName);
141 updater.setInt(2, id);
143 return Job.submit(this, JobType.SIGN);
147 public Job revoke() throws SQLException {
148 if (getStatus() != CertificateStatus.ISSUED) {
149 throw new IllegalStateException();
151 return Job.submit(this, JobType.REVOKE);
155 public X509Certificate cert() throws IOException, GeneralSecurityException, SQLException {
156 CertificateStatus status = getStatus();
157 if (status != CertificateStatus.ISSUED) {
158 throw new IllegalStateException(status + " is not wanted here.");
160 InputStream is = null;
161 X509Certificate crt = null;
163 is = new FileInputStream(crtName);
164 CertificateFactory cf = CertificateFactory.getInstance("X.509");
165 crt = (X509Certificate) cf.generateCertificate(is);
174 public Certificate renew() {
182 public String getSerial() {
185 } catch (SQLException e) {
191 public String getDistinguishedName() {
195 public String getMessageDigest() {
199 public int getOwnerId() {
203 public static Certificate getBySerial(String serial) {
206 return new Certificate(serial);
207 } catch (IllegalArgumentException e) {