]> WPIA git - gigi.git/blob - util/org/cacert/gigi/util/SimpleSigner.java
New Signer Job Table.
[gigi.git] / util / org / cacert / gigi / util / SimpleSigner.java
1 package org.cacert.gigi.util;
2
3 import java.io.BufferedReader;
4 import java.io.File;
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;
19
20 import org.cacert.gigi.database.DatabaseConnection;
21
22 public class SimpleSigner {
23         private static PreparedStatement warnMail;
24         private static PreparedStatement updateMail;
25         private static PreparedStatement readyMail;
26         private static PreparedStatement revoke;
27         private static PreparedStatement revokeCompleted;
28         private static PreparedStatement finishJob;
29         private static boolean running = true;
30         private static Thread runner;
31
32         public static void main(String[] args) throws IOException, SQLException, InterruptedException {
33                 Properties p = new Properties();
34                 p.load(new FileReader("config/gigi.properties"));
35                 DatabaseConnection.init(p);
36
37                 runSigner();
38         }
39
40         public synchronized static void stopSigner() throws InterruptedException {
41                 if (runner == null) {
42                         throw new IllegalStateException("already stopped");
43                 }
44                 running = false;
45                 runner.interrupt();
46                 runner.join();
47                 runner = null;
48         }
49
50         public synchronized static void runSigner() throws SQLException, IOException, InterruptedException {
51                 if (runner != null) {
52                         throw new IllegalStateException("already running");
53                 }
54                 running = true;
55                 readyMail = DatabaseConnection
56                         .getInstance()
57                         .prepare(
58                                 "SELECT emailcerts.id,emailcerts.csr_name,emailcerts.subject, jobs.id FROM jobs INNER JOIN emailcerts ON emailcerts.id=jobs.targetId"
59                                         + " WHERE jobs.state='open'"//
60                                         + " AND task='sign'");
61
62                 updateMail = DatabaseConnection.getInstance().prepare(
63                         "UPDATE emailcerts SET crt_name=?," + " created=NOW(), serial=? WHERE id=?");
64                 warnMail = DatabaseConnection.getInstance().prepare(
65                         "UPDATE jobs SET warning=warning+1, state=IF(warning<3, 'open','error') WHERE id=?");
66
67                 revoke = DatabaseConnection.getInstance().prepare(
68                         "SELECT emailcerts.id, emailcerts.csr_name,jobs.id FROM jobs INNER JOIN emailcerts ON jobs.targetId=emailcerts.id"
69                                 + " WHERE jobs.state='open' AND task='revoke'");
70                 revokeCompleted = DatabaseConnection.getInstance().prepare("UPDATE emailcerts SET revoked=NOW() WHERE id=?");
71
72                 finishJob = DatabaseConnection.getInstance().prepare("UPDATE jobs SET state='done' WHERE id=?");
73
74                 runner = new Thread() {
75                         @Override
76                         public void run() {
77                                 work();
78                         }
79
80                 };
81                 runner.start();
82         }
83
84         private static void work() {
85                 try {
86                         gencrl();
87                 } catch (IOException e2) {
88                         e2.printStackTrace();
89                 } catch (InterruptedException e2) {
90                         e2.printStackTrace();
91                 }
92                 while (running) {
93                         try {
94                                 signCertificates();
95                                 revokeCertificates();
96                                 Thread.sleep(5000);
97                         } catch (IOException e) {
98                                 e.printStackTrace();
99                         } catch (SQLException e) {
100                                 e.printStackTrace();
101                         } catch (InterruptedException e1) {
102                         }
103                 }
104         }
105
106         private static void revokeCertificates() throws SQLException, IOException, InterruptedException {
107                 ResultSet rs = revoke.executeQuery();
108                 boolean worked = false;
109                 while (rs.next()) {
110                         int id = rs.getInt(1);
111                         File crt = KeyStorage.locateCrt(id);
112                         String[] call = new String[] { "openssl", "ca",//
113                                         "-cert", "testca.crt",//
114                                         "-keyfile", "testca.key",//
115                                         "-revoke", "../" + crt.getPath(),//
116                                         "-batch",//
117                                         "-config", "selfsign.config"
118
119                         };
120                         Process p1 = Runtime.getRuntime().exec(call, null, new File("keys"));
121                         System.out.println("revoking: " + crt.getPath());
122                         if (p1.waitFor() == 0) {
123                                 worked = true;
124                                 revokeCompleted.setInt(1, id);
125                                 revokeCompleted.execute();
126                                 finishJob.setInt(1, rs.getInt(3));
127                                 finishJob.execute();
128                         } else {
129                                 System.out.println("Failed");
130                         }
131                 }
132                 if (worked) {
133                         gencrl();
134                 }
135         }
136
137         private static void gencrl() throws IOException, InterruptedException {
138                 String[] call = new String[] { "openssl", "ca",//
139                                 "-cert", "testca.crt",//
140                                 "-keyfile", "testca.key",//
141                                 "-gencrl",//
142                                 "-crlhours",//
143                                 "12",//
144                                 "-out", "testca.crl",//
145                                 "-config", "selfsign.config"
146
147                 };
148                 Process p1 = Runtime.getRuntime().exec(call, null, new File("keys"));
149                 if (p1.waitFor() != 0) {
150                         System.out.println("Error while generating crl.");
151                 }
152         }
153
154         private static void signCertificates() throws SQLException, IOException, InterruptedException {
155                 ResultSet rs = readyMail.executeQuery();
156                 while (rs.next()) {
157                         String csrname = rs.getString(2);
158                         System.out.println("sign: " + csrname);
159                         int id = rs.getInt(1);
160                         File crt = KeyStorage.locateCrt(id);
161                         String[] call = new String[] { "openssl", "ca",//
162                                         "-cert", "testca.crt",//
163                                         "-keyfile", "testca.key",//
164                                         "-in", "../" + csrname,//
165                                         "-out", "../" + crt.getPath(),//
166                                         "-days", "356",//
167                                         "-batch",//
168                                         "-subj", rs.getString(3),//
169                                         "-config", "selfsign.config"
170
171                         };
172                         Process p1 = Runtime.getRuntime().exec(call, null, new File("keys"));
173
174                         int waitFor = p1.waitFor();
175                         if (waitFor == 0) {
176                                 try (InputStream is = new FileInputStream(crt)) {
177                                         CertificateFactory cf = CertificateFactory.getInstance("X.509");
178                                         X509Certificate crtp = (X509Certificate) cf.generateCertificate(is);
179                                         BigInteger serial = crtp.getSerialNumber();
180                                         updateMail.setString(1, crt.getPath());
181                                         updateMail.setString(2, serial.toString(16));
182                                         updateMail.setInt(3, id);
183                                         updateMail.execute();
184
185                                         finishJob.setInt(1, rs.getInt(4));
186                                         finishJob.execute();
187                                         System.out.println("signed: " + id);
188                                         continue;
189                                 } catch (GeneralSecurityException e) {
190                                         e.printStackTrace();
191                                 }
192                                 System.out.println("ERROR Afterwards: " + id);
193                                 warnMail.setInt(1, rs.getInt(4));
194                                 warnMail.execute();
195                         } else {
196                                 BufferedReader br = new BufferedReader(new InputStreamReader(p1.getErrorStream()));
197                                 String s;
198                                 while ((s = br.readLine()) != null) {
199                                         System.out.println(s);
200                                 }
201                                 System.out.println(Arrays.toString(call));
202                                 System.out.println("ERROR: " + id);
203                                 warnMail.setInt(1, rs.getInt(4));
204                                 warnMail.execute();
205                         }
206
207                 }
208                 rs.close();
209         }
210 }