101aced04f2e6adc53eb61ae6ab79b0fb415496e
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

1) <?php
2) 
3) require_once('inc/base.php');
bernd CSR-Erstellung

bernd authored 14 years ago

4) require_once('inc/security.php');
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

5) 
6) define("CERT_OK", 0);
7) define("CERT_INVALID", 1);
8) define("CERT_NOCHAIN", 2);
9) 
10) function user_certs()
11) {
12)   $uid = (int) $_SESSION['userinfo']['uid'];
13)   $result = db_query("SELECT id, valid_from, valid_until, subject, cn FROM vhosts.certs WHERE uid=${uid}");
14)   $ret = array();
15)   while ($i = mysql_fetch_assoc($result))
16)     $ret[] = $i;
17)   DEBUG($ret);
18)   return $ret;
19) }
20) 
bernd CSR-Erstellung

bernd authored 14 years ago

21) function user_csr()
22) {
23)   $uid = (int) $_SESSION['userinfo']['uid'];
24)   $result = db_query("SELECT id, created, hostname, bits FROM vhosts.csr WHERE uid=${uid}");
25)   $ret = array();
26)   while ($i = mysql_fetch_assoc($result))
27)     $ret[] = $i;
28)   DEBUG($ret);
29)   return $ret;
30) }
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

31) 
32) function cert_details($id)
33) {
34)   $id = (int) $id;
35)   $uid = (int) $_SESSION['userinfo']['uid'];
36)   
bernd CSR-Erstellung

bernd authored 14 years ago

37)   $result = db_query("SELECT id, lastchange, valid_from, valid_until, subject, cn, cert, `key` FROM vhosts.certs WHERE uid={$uid} AND id={$id}");
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

38)   if (mysql_num_rows($result) != 1)
bernd Cert-Refresh

bernd authored 14 years ago

39)     system_failure("Ungültiges Zertifikat #{$id}");
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

40)   return mysql_fetch_assoc($result);
41) }
42) 
43) 
bernd CSR-Erstellung

bernd authored 14 years ago

44) function csr_details($id)
45) {
46)   $id = (int) $id;
47)   $uid = (int) $_SESSION['userinfo']['uid'];
48)   
49)   $result = db_query("SELECT id, created, hostname, bits, csr, `key` FROM vhosts.csr WHERE uid={$uid} AND id={$id}");
50)   if (mysql_num_rows($result) != 1)
51)     system_failure("Ungültiger CSR");
52)   return mysql_fetch_assoc($result);
53) }
54) 
55) 
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

56) function get_available_CAs()
57) {
58)   $path = '/etc/apache2/certs/cabundle/';
59)   $ret = glob($path.'*.pem');
60)   if (! $ret)
61)     system_failure("Konnte die CA-Zertifikate nicht laden");
62)   DEBUG($ret);
63)   return $ret;
64) }
65) 
66) 
bernd Cert-Chain erkennen und ben...

bernd authored 13 years ago

67) function get_chain($cert)
68) {
69)   $certdata = openssl_x509_parse($cert, true);
bernd Mehr Fehlerbehandlung für S...

bernd authored 13 years ago

70)   if ($certdata === FALSE) {
71)     system_failure("Das Zertifikat konnte nicht gelesen werden");
72)   }
73)   if (! isset($certdata['issuer']['CN'])) {
74)     return NULL;
75)   }
bernd Cert-Chain erkennen und ben...

bernd authored 13 years ago

76)   $issuer = mysql_real_escape_string($certdata['issuer']['CN']);
77)   $result = db_query("SELECT id FROM vhosts.certchain WHERE cn='{$issuer}'");
78)   if (mysql_num_rows($result) > 0)
79)   {
80)     $c = mysql_fetch_assoc($result);
81)     //$chainfile = '/etc/apache2/certs/chains/'.$c['id'].'.pem';
82)     DEBUG("identified fitting certificate chain #".$c['id']);
83)     return $c['id'];
84)   }
85) }
86) 
87) 
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

88) function validate_certificate($cert, $key)
bernd Mehr Fehlerbehandlung für S...

bernd authored 13 years ago

89) { 
90)   // Lade private key 
91)   $seckey = openssl_get_privatekey($key);
92)   if ($seckey === FALSE) {
93)     system_failure("Der private Schlüssel konnte (ohne Passwort) nicht gelesen werden.");
94)   }
95)   // Lade public key
96)   $pubkey = openssl_get_publickey($cert);
97)   if ($pubkey === FALSE) {
98)     system_failure("In dem eingetragenen Zertifikat wurde kein öffentlicher Schlüssel gefunden.");
99)   }
100)   // Parse Details über den pubkey
101)   $certinfo = openssl_pkey_get_details($pubkey);
bernd Erlaube nur RSA- und DSA-Ze...

bernd authored 13 years ago

102)   DEBUG($certinfo);
bernd Mehr Fehlerbehandlung für S...

bernd authored 13 years ago

103)   if ($certinfo === FALSE) {
104)     system_failure("Der öffentliche Schlüssel des Zertifikats konnte nicht gelesen werden");
bernd Erlaube nur RSA- und DSA-Ze...

bernd authored 13 years ago

105)   }
bernd Mehr Fehlerbehandlung für S...

bernd authored 13 years ago

106) 
107)   // Apache unterstützt nur Schlüssel vom Typ RSA oder DSA
108)   if (! in_array($certinfo['type'], array(OPENSSL_KEYTYPE_RSA, OPENSSL_KEYTYPE_DSA))) {
bernd Erlaube nur RSA- und DSA-Ze...

bernd authored 13 years ago

109)     system_failure("Dieser Schlüssel nutzt einen nicht unterstützten Algorithmus.");
110)   }
111)     
bernd Mehr Fehlerbehandlung für S...

bernd authored 13 years ago

112)   // Bei ECC-Keys treten kürzere Schlüssellängen auf, die können wir aktuell aber sowieso nicht unterstützen
113)   if ($certinfo['bits'] < 2048) {
114)     warning("Dieser Schlüssel hat eine sehr geringe Bitlänge und ist daher als nicht besonders sicher einzustufen!");
115)   }
116) 
117)   // Prüfe ob Key und Zertifikat zusammen passen
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

118)   if (openssl_x509_check_private_key($cert, $key) !== true)
119)   {
120)     DEBUG("Zertifikat und Key passen nicht zusammen");
121)     return CERT_INVALID;
122)   }
123) 
bernd Cert-Chain erkennen und ben...

bernd authored 13 years ago

124)   $cacerts = array('/etc/ssl/certs');
125)   $chain = get_chain($cert);
126)   if ($chain)
127)   {
128)     $cacerts[] = '/etc/apache2/certs/chains/'.$chain.'.pem';
129)   }
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

130) 
131)   if (openssl_x509_checkpurpose($cert, X509_PURPOSE_SSL_SERVER, $cacerts) !== true)
132)   { 
133)     DEBUG('certificate was not validated as a server certificate with the available chain');
134)     return CERT_NOCHAIN;
135)   }
136) 
137)   return CERT_OK;
138) }
139) 
140) 
141) function parse_cert_details($cert)
142) {
143)   $certdata = openssl_x509_parse($cert, true);
144)   /* 
145) name => /CN=*.bwurst.org
146) validFrom_time_t => 1204118790
147) validTo_time_t => 1267190790
148) 
149) 
150)   */
bernd Erlaube nur RSA- und DSA-Ze...

bernd authored 13 years ago

151)   DEBUG($certdata);
bernd Cert-Name ist Subject-CN un...

bernd authored 14 years ago

152)   //return array('subject' => $certdata['name'], 'cn' => $certdata['subject']['CN'], 'valid_from' => date('Y-m-d', $certdata['validFrom_time_t']), 'valid_until' => date('Y-m-d', $certdata['validTo_time_t']));
bernd Cert-Chain erkennen und ben...

bernd authored 13 years ago

153)   return array('subject' => $certdata['subject']['CN'].' / '.$certdata['issuer']['O'], 'cn' => $certdata['subject']['CN'], 'valid_from' => date('Y-m-d', $certdata['validFrom_time_t']), 'valid_until' => date('Y-m-d', $certdata['validTo_time_t']), 'issuer' => $certdata['issuer']['CN']);
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

154) }
155) 
156) 
157) function save_cert($info, $cert, $key)
158) {
hanno zertifikate und keys export...

hanno authored 14 years ago

159)   openssl_pkey_export($key, $key);
160)   openssl_x509_export($cert, $cert);
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

161)   $subject = mysql_real_escape_string(filter_input_general($info['subject']));
162)   $cn = mysql_real_escape_string(filter_input_general($info['cn']));
163)   $valid_from = mysql_real_escape_string($info['valid_from']);
164)   $valid_until = mysql_real_escape_string($info['valid_until']);
bernd Cert-Chain erkennen und ben...

bernd authored 13 years ago

165)   $chain = maybe_null( get_chain($cert) );
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

166)   $cert = mysql_real_escape_string($cert);
167)   $key = mysql_real_escape_string($key);
168)   $uid = (int) $_SESSION['userinfo']['uid'];
169) 
bernd Cert-Chain erkennen und ben...

bernd authored 13 years ago

170)   db_query("INSERT INTO vhosts.certs (uid, subject, cn, valid_from, valid_until, chain, cert, `key`) VALUES ({$uid}, '{$subject}', '{$cn}', '{$valid_from}', '{$valid_until}', {$chain}, '{$cert}', '{$key}')");
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

171) }
172) 
bernd Cert-Refresh

bernd authored 14 years ago

173) 
bernd neue Bilder, mehr SSL-Zerti...

bernd authored 14 years ago

174) function refresh_cert($id, $info, $cert, $key = NULL)
bernd Cert-Refresh

bernd authored 14 years ago

175) {
hanno zertifikate und keys export...

hanno authored 14 years ago

176)   openssl_x509_export($cert, $cert);
bernd Bugfix: Beim Eintragen eine...

bernd authored 13 years ago

177)   $chain = maybe_null( get_chain($cert) );
178) 
bernd Cert-Refresh

bernd authored 14 years ago

179)   $id = (int) $id;
180)   $oldcert = cert_details($id);
181)   $cert = mysql_real_escape_string($cert);
182)   
183)   $valid_from = mysql_real_escape_string($info['valid_from']);
184)   $valid_until = mysql_real_escape_string($info['valid_until']);
185) 
bernd neue Bilder, mehr SSL-Zerti...

bernd authored 14 years ago

186)   $keyop = '';
hanno zertifikate und keys export...

hanno authored 14 years ago

187)   if ($key) {
188)     openssl_pkey_export($key, $key);
bernd neue Bilder, mehr SSL-Zerti...

bernd authored 14 years ago

189)     $keyop = ", `key`='".mysql_real_escape_string($key)."'";
hanno zertifikate und keys export...

hanno authored 14 years ago

190)   }
bernd chain auch beim refresh erm...

bernd authored 13 years ago

191)   db_query("UPDATE vhosts.certs SET cert='{$cert}'{$keyop}, valid_from='{$valid_from}', valid_until='{$valid_until}', chain={$chain} WHERE id={$id} LIMIT 1");
bernd Cert-Refresh

bernd authored 14 years ago

192) }
193) 
194) 
bernd Neue Zertifikatsverwaltung

bernd authored 14 years ago

195) function delete_cert($id)
196) {
197)   $uid = (int) $_SESSION['userinfo']['uid'];
198)   $id = (int) $id;
199)   
200)   db_query("DELETE FROM vhosts.certs WHERE uid={$uid} AND id={$id} LIMIT 1");
201) }
202) 
bernd CSR-Erstellung

bernd authored 14 years ago

203) function delete_csr($id)
204) {
205)   $uid = (int) $_SESSION['userinfo']['uid'];
206)   $id = (int) $id;
207)   
208)   db_query("DELETE FROM vhosts.csr WHERE uid={$uid} AND id={$id} LIMIT 1");
209) }
210) 
211) function create_wildcard_csr($cn, $bits)
212) {
213)   $cn = filter_input_hostname($cn);
214)   $bits = (int) $bits;
215)   if ($bits == 0)
216)     $bits = 4096;
217) 
218)   $keyfile = tempnam(ini_get('upload_tmp_dir'), 'key');
219)   $csrfile = tempnam(ini_get('upload_tmp_dir'), 'csr');
220)   $config = tempnam(ini_get('upload_tmp_dir'), 'config');
221) 
222)   DEBUG("key: ".$keyfile." / csr: ".$csrfile." / config: ".$config);
223) 
224)   $c = fopen($config, "w");
225)   fwrite($c, "[req]
226) default_bits = {$bits}
227) default_keyfile = {$keyfile}
228) encrypt_key = no
229) distinguished_name      = req_distinguished_name
230) req_extensions = v3_req
231) 
232) [v3_req]
233) subjectAltName = DNS:{$cn}, DNS:*.{$cn}
234) 
235) [ req_distinguished_name ]
236) countryName                     = Country Name (2 letter code)
237) countryName_default             = DE
238) stateOrProvinceName             = State or Province Name (full name)
239) stateOrProvinceName_default     = Baden-Wuerttemberg
240) localityName                    = Locality Name (eg, city)
241) localityName_default            = Murrhardt
242) 0.organizationName              = Organization Name (eg, company)
243) 0.organizationName_default      = schokokeks.org
244) 
245) commonName = Common Name
246) commonName_default = *.{$cn}
247) ");
248)   fclose($c);
249) 
250)   $output = '';
hanno sha2 csrs

hanno authored 14 years ago

251)   $cmdline = "openssl req -sha256 -new -batch -config {$config} -out {$csrfile}";
bernd CSR-Erstellung

bernd authored 14 years ago

252)   $retval = 0;
253)   exec($cmdline, $output, $retval);
254)   DEBUG($output);
255)   DEBUG($retval);
256)   if ($retval != 0)
257)   {
bernd Bugfix: Beim Eintragen eine...

bernd authored 13 years ago

258)     system_failure("Die Erzeugung des CSR ist fehlgeschlagen. Ausgabe des OpenSSL-Befehls: ".print_r($output, true));
bernd CSR-Erstellung

bernd authored 14 years ago

259)   }
260)   
261)   $csr = file_get_contents($csrfile);
262)   $key = file_get_contents($keyfile);
263) 
264)   unlink($csrfile);
265)   unlink($keyfile);
266)   unlink($config);
267) 
268)   return array($csr, $key);
269) }
270) 
271) 
272) 
273) function create_csr($cn, $bits)
274) {
275)   $cn = filter_input_hostname($cn);
276)   $bits = (int) $bits;
277)   if ($bits == 0)
278)     $bits = 4096;
279) 
280)   $keyfile = tempnam(ini_get('upload_tmp_dir'), 'key');
281)   $csrfile = tempnam(ini_get('upload_tmp_dir'), 'csr');
282)   $config = tempnam(ini_get('upload_tmp_dir'), 'config');
283) 
284)   DEBUG("key: ".$keyfile." / csr: ".$csrfile." / config: ".$config);
285) 
286)   $c = fopen($config, "w");
287)   fwrite($c, "[req]
288) default_bits = {$bits}
289) default_keyfile = {$keyfile}
290) encrypt_key = no
291) distinguished_name      = req_distinguished_name
292) 
293) [ req_distinguished_name ]
294) countryName                     = Country Name (2 letter code)
295) countryName_default             = DE
296) stateOrProvinceName             = State or Province Name (full name)
297) stateOrProvinceName_default     = Baden-Wuerttemberg
298) localityName                    = Locality Name (eg, city)
299) localityName_default            = Murrhardt
300) 0.organizationName              = Organization Name (eg, company)
301) 0.organizationName_default      = schokokeks.org
302) 
303) commonName = Common Name
304) commonName_default = {$cn}
305) ");
306)   fclose($c);
307) 
308)   $output = '';
hanno sha2 csrs

hanno authored 14 years ago

309)   $cmdline = "openssl req -sha256 -new -batch -config {$config} -out {$csrfile}";
bernd CSR-Erstellung

bernd authored 14 years ago

310)   $retval = 0;
311)   exec($cmdline, $output, $retval);
312)   DEBUG($output);
313)   DEBUG($retval);
314)   if ($retval != 0)
315)   {
bernd Bugfix: Beim Eintragen eine...

bernd authored 13 years ago

316)     system_failure("Die Erzeugung des CSR ist fehlgeschlagen. Ausgabe des OpenSSL-Befehls: ".print_r($output, true));
bernd CSR-Erstellung

bernd authored 14 years ago

317)   }
318)   
319)   $csr = file_get_contents($csrfile);
320)   $key = file_get_contents($keyfile);
321) 
322)   unlink($csrfile);
323)   unlink($keyfile);
324)   unlink($config);
325) 
326)   return array($csr, $key);
327) }
328) 
329) 
330) 
331) function save_csr($cn, $bits, $wildcard=true)
332) {
bernd (Verständliche) Fehlermeldu...

bernd authored 13 years ago

333)   if (! $cn) {
334)     system_failure("Sie müssen einen Domainname eingeben!");
335)   }