1 package org.cacert.gigi.util;
3 import java.io.BufferedReader;
5 import java.io.FileInputStream;
6 import java.io.FileReader;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.InputStreamReader;
10 import java.math.BigInteger;
11 import java.security.GeneralSecurityException;
12 import java.security.cert.CertificateFactory;
13 import java.security.cert.X509Certificate;
14 import java.sql.PreparedStatement;
15 import java.sql.ResultSet;
16 import java.sql.SQLException;
17 import java.util.Arrays;
18 import java.util.Properties;
20 import org.cacert.gigi.Certificate.CSRType;
21 import org.cacert.gigi.database.DatabaseConnection;
23 public class SimpleSigner {
24 private static PreparedStatement warnMail;
25 private static PreparedStatement updateMail;
26 private static PreparedStatement readyMail;
27 private static PreparedStatement revoke;
28 private static PreparedStatement revokeCompleted;
29 private static PreparedStatement finishJob;
30 private static boolean running = true;
31 private static Thread runner;
33 public static void main(String[] args) throws IOException, SQLException, InterruptedException {
34 Properties p = new Properties();
35 p.load(new FileReader("config/gigi.properties"));
36 DatabaseConnection.init(p);
41 public synchronized static void stopSigner() throws InterruptedException {
43 throw new IllegalStateException("already stopped");
51 public synchronized static void runSigner() throws SQLException, IOException, InterruptedException {
53 throw new IllegalStateException("already running");
56 readyMail = DatabaseConnection
59 "SELECT emailcerts.id,emailcerts.csr_name,emailcerts.subject, jobs.id,csr_type FROM jobs INNER JOIN emailcerts ON emailcerts.id=jobs.targetId"
60 + " WHERE jobs.state='open'"//
61 + " AND task='sign'");
63 updateMail = DatabaseConnection.getInstance().prepare(
64 "UPDATE emailcerts SET crt_name=?," + " created=NOW(), serial=? WHERE id=?");
65 warnMail = DatabaseConnection.getInstance().prepare(
66 "UPDATE jobs SET warning=warning+1, state=IF(warning<3, 'open','error') WHERE id=?");
68 revoke = DatabaseConnection.getInstance().prepare(
69 "SELECT emailcerts.id, emailcerts.csr_name,jobs.id FROM jobs INNER JOIN emailcerts ON jobs.targetId=emailcerts.id"
70 + " WHERE jobs.state='open' AND task='revoke'");
71 revokeCompleted = DatabaseConnection.getInstance().prepare("UPDATE emailcerts SET revoked=NOW() WHERE id=?");
73 finishJob = DatabaseConnection.getInstance().prepare("UPDATE jobs SET state='done' WHERE id=?");
75 runner = new Thread() {
85 private static void work() {
88 } catch (IOException e2) {
90 } catch (InterruptedException e2) {
98 } catch (IOException e) {
100 } catch (SQLException e) {
102 } catch (InterruptedException e1) {
107 private static void revokeCertificates() throws SQLException, IOException, InterruptedException {
108 ResultSet rs = revoke.executeQuery();
109 boolean worked = false;
111 int id = rs.getInt(1);
112 File crt = KeyStorage.locateCrt(id);
113 String[] call = new String[] { "openssl", "ca",//
114 "-cert", "testca.crt",//
115 "-keyfile", "testca.key",//
116 "-revoke", "../" + crt.getPath(),//
118 "-config", "selfsign.config"
121 Process p1 = Runtime.getRuntime().exec(call, null, new File("keys"));
122 System.out.println("revoking: " + crt.getPath());
123 if (p1.waitFor() == 0) {
125 revokeCompleted.setInt(1, id);
126 revokeCompleted.execute();
127 finishJob.setInt(1, rs.getInt(3));
130 System.out.println("Failed");
138 private static void gencrl() throws IOException, InterruptedException {
139 String[] call = new String[] { "openssl", "ca",//
140 "-cert", "testca.crt",//
141 "-keyfile", "testca.key",//
145 "-out", "testca.crl",//
146 "-config", "selfsign.config"
149 Process p1 = Runtime.getRuntime().exec(call, null, new File("keys"));
150 if (p1.waitFor() != 0) {
151 System.out.println("Error while generating crl.");
155 private static void signCertificates() throws SQLException, IOException, InterruptedException {
156 ResultSet rs = readyMail.executeQuery();
158 String csrname = rs.getString(2);
159 System.out.println("sign: " + csrname);
160 int id = rs.getInt(1);
161 String csrType = rs.getString(5);
162 CSRType ct = CSRType.valueOf(csrType);
163 File crt = KeyStorage.locateCrt(id);
164 String[] call = new String[] { "openssl", "ca",//
165 "-in", "../" + csrname,//
166 "-cert", "testca.crt",//
167 "-keyfile", "testca.key",//
168 "-out", "../" + crt.getPath(),//
171 "-subj", rs.getString(3),//
172 "-config", "selfsign.config"//
175 if (ct == CSRType.SPKAC) {
178 Process p1 = Runtime.getRuntime().exec(call, null, new File("keys"));
180 int waitFor = p1.waitFor();
182 try (InputStream is = new FileInputStream(crt)) {
183 CertificateFactory cf = CertificateFactory.getInstance("X.509");
184 X509Certificate crtp = (X509Certificate) cf.generateCertificate(is);
185 BigInteger serial = crtp.getSerialNumber();
186 updateMail.setString(1, crt.getPath());
187 updateMail.setString(2, serial.toString(16));
188 updateMail.setInt(3, id);
189 updateMail.execute();
191 finishJob.setInt(1, rs.getInt(4));
193 System.out.println("signed: " + id);
195 } catch (GeneralSecurityException e) {
198 System.out.println("ERROR Afterwards: " + id);
199 warnMail.setInt(1, rs.getInt(4));
202 BufferedReader br = new BufferedReader(new InputStreamReader(p1.getErrorStream()));
204 while ((s = br.readLine()) != null) {
205 System.out.println(s);
207 System.out.println(Arrays.toString(call));
208 System.out.println("ERROR: " + id);
209 warnMail.setInt(1, rs.getInt(4));