]> WPIA git - gigi.git/blob - util/org/cacert/gigi/util/SimpleSigner.java
Merge branch 'spkac'
[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.Certificate.CSRType;
21 import org.cacert.gigi.database.DatabaseConnection;
22
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;
32
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);
37
38                 runSigner();
39         }
40
41         public synchronized static void stopSigner() throws InterruptedException {
42                 if (runner == null) {
43                         throw new IllegalStateException("already stopped");
44                 }
45                 running = false;
46                 runner.interrupt();
47                 runner.join();
48                 runner = null;
49         }
50
51         public synchronized static void runSigner() throws SQLException, IOException, InterruptedException {
52                 if (runner != null) {
53                         throw new IllegalStateException("already running");
54                 }
55                 running = true;
56                 readyMail = DatabaseConnection
57                         .getInstance()
58                         .prepare(
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'");
62
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=?");
67
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=?");
72
73                 finishJob = DatabaseConnection.getInstance().prepare("UPDATE jobs SET state='done' WHERE id=?");
74
75                 runner = new Thread() {
76                         @Override
77                         public void run() {
78                                 work();
79                         }
80
81                 };
82                 runner.start();
83         }
84
85         private static void work() {
86                 try {
87                         gencrl();
88                 } catch (IOException e2) {
89                         e2.printStackTrace();
90                 } catch (InterruptedException e2) {
91                         e2.printStackTrace();
92                 }
93                 while (running) {
94                         try {
95                                 signCertificates();
96                                 revokeCertificates();
97                                 Thread.sleep(5000);
98                         } catch (IOException e) {
99                                 e.printStackTrace();
100                         } catch (SQLException e) {
101                                 e.printStackTrace();
102                         } catch (InterruptedException e1) {
103                         }
104                 }
105         }
106
107         private static void revokeCertificates() throws SQLException, IOException, InterruptedException {
108                 ResultSet rs = revoke.executeQuery();
109                 boolean worked = false;
110                 while (rs.next()) {
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(),//
117                                         "-batch",//
118                                         "-config", "selfsign.config"
119
120                         };
121                         Process p1 = Runtime.getRuntime().exec(call, null, new File("keys"));
122                         System.out.println("revoking: " + crt.getPath());
123                         if (p1.waitFor() == 0) {
124                                 worked = true;
125                                 revokeCompleted.setInt(1, id);
126                                 revokeCompleted.execute();
127                                 finishJob.setInt(1, rs.getInt(3));
128                                 finishJob.execute();
129                         } else {
130                                 System.out.println("Failed");
131                         }
132                 }
133                 if (worked) {
134                         gencrl();
135                 }
136         }
137
138         private static void gencrl() throws IOException, InterruptedException {
139                 String[] call = new String[] { "openssl", "ca",//
140                                 "-cert", "testca.crt",//
141                                 "-keyfile", "testca.key",//
142                                 "-gencrl",//
143                                 "-crlhours",//
144                                 "12",//
145                                 "-out", "testca.crl",//
146                                 "-config", "selfsign.config"
147
148                 };
149                 Process p1 = Runtime.getRuntime().exec(call, null, new File("keys"));
150                 if (p1.waitFor() != 0) {
151                         System.out.println("Error while generating crl.");
152                 }
153         }
154
155         private static void signCertificates() throws SQLException, IOException, InterruptedException {
156                 ResultSet rs = readyMail.executeQuery();
157                 while (rs.next()) {
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(),//
169                                         "-days", "356",//
170                                         "-batch",//
171                                         "-subj", rs.getString(3),//
172                                         "-config", "selfsign.config"//
173
174                         };
175                         if (ct == CSRType.SPKAC) {
176                                 call[2] = "-spkac";
177                         }
178                         Process p1 = Runtime.getRuntime().exec(call, null, new File("keys"));
179
180                         int waitFor = p1.waitFor();
181                         if (waitFor == 0) {
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();
190
191                                         finishJob.setInt(1, rs.getInt(4));
192                                         finishJob.execute();
193                                         System.out.println("signed: " + id);
194                                         continue;
195                                 } catch (GeneralSecurityException e) {
196                                         e.printStackTrace();
197                                 }
198                                 System.out.println("ERROR Afterwards: " + id);
199                                 warnMail.setInt(1, rs.getInt(4));
200                                 warnMail.execute();
201                         } else {
202                                 BufferedReader br = new BufferedReader(new InputStreamReader(p1.getErrorStream()));
203                                 String s;
204                                 while ((s = br.readLine()) != null) {
205                                         System.out.println(s);
206                                 }
207                                 System.out.println(Arrays.toString(call));
208                                 System.out.println("ERROR: " + id);
209                                 warnMail.setInt(1, rs.getInt(4));
210                                 warnMail.execute();
211                         }
212
213                 }
214                 rs.close();
215         }
216 }