42747c76095bd1345463e4e0fa5b00dc9d133f97
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

1) <?php
Bernd Wurst Added license tags for CC0,...

Bernd Wurst authored 12 years ago

2) /*
3) This file belongs to the Webinterface of schokokeks.org Hosting
4) 
5) Written 2008-2012 by schokokeks.org Hosting, namely
6)   Bernd Wurst <bernd@schokokeks.org>
7)   Hanno Böck <hanno@schokokeks.org>
8) 
9) To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
10) 
11) You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see 
12) http://creativecommons.org/publicdomain/zero/1.0/
13) 
14) Nevertheless, in case you use a significant part of this code, we ask (but not require, see the license) that you keep the authors' names in place and return your changes to the public. We would be especially happy if you tell us what you're going to do with this code.
15) */
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

16) 
17) require_once('inc/base.php');
bernd CSR-Erstellung

bernd authored 15 years ago

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

bernd authored 15 years ago

19) 
20) define("CERT_OK", 0);
21) define("CERT_INVALID", 1);
22) define("CERT_NOCHAIN", 2);
23) 
24) function user_certs()
25) {
26)   $uid = (int) $_SESSION['userinfo']['uid'];
27)   $result = db_query("SELECT id, valid_from, valid_until, subject, cn FROM vhosts.certs WHERE uid=${uid}");
28)   $ret = array();
29)   while ($i = mysql_fetch_assoc($result))
30)     $ret[] = $i;
31)   DEBUG($ret);
32)   return $ret;
33) }
34) 
bernd CSR-Erstellung

bernd authored 15 years ago

35) function user_csr()
36) {
37)   $uid = (int) $_SESSION['userinfo']['uid'];
38)   $result = db_query("SELECT id, created, hostname, bits FROM vhosts.csr WHERE uid=${uid}");
39)   $ret = array();
40)   while ($i = mysql_fetch_assoc($result))
41)     $ret[] = $i;
42)   DEBUG($ret);
43)   return $ret;
44) }
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

45) 
46) function cert_details($id)
47) {
48)   $id = (int) $id;
49)   $uid = (int) $_SESSION['userinfo']['uid'];
50)   
bernd CSR-Erstellung

bernd authored 15 years ago

51)   $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 15 years ago

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

bernd authored 15 years ago

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

bernd authored 15 years ago

54)   return mysql_fetch_assoc($result);
55) }
56) 
57) 
bernd CSR-Erstellung

bernd authored 15 years ago

58) function csr_details($id)
59) {
60)   $id = (int) $id;
61)   $uid = (int) $_SESSION['userinfo']['uid'];
62)   
63)   $result = db_query("SELECT id, created, hostname, bits, csr, `key` FROM vhosts.csr WHERE uid={$uid} AND id={$id}");
64)   if (mysql_num_rows($result) != 1)
65)     system_failure("Ungültiger CSR");
66)   return mysql_fetch_assoc($result);
67) }
68) 
69) 
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

70) function get_available_CAs()
71) {
72)   $path = '/etc/apache2/certs/cabundle/';
73)   $ret = glob($path.'*.pem');
74)   if (! $ret)
75)     system_failure("Konnte die CA-Zertifikate nicht laden");
76)   DEBUG($ret);
77)   return $ret;
78) }
79) 
80) 
bernd Cert-Chain erkennen und ben...

bernd authored 14 years ago

81) function get_chain($cert)
82) {
83)   $certdata = openssl_x509_parse($cert, true);
bernd Mehr Fehlerbehandlung für S...

bernd authored 13 years ago

84)   if ($certdata === FALSE) {
85)     system_failure("Das Zertifikat konnte nicht gelesen werden");
86)   }
87)   if (! isset($certdata['issuer']['CN'])) {
88)     return NULL;
89)   }
bernd Cert-Chain erkennen und ben...

bernd authored 14 years ago

90)   $issuer = mysql_real_escape_string($certdata['issuer']['CN']);
91)   $result = db_query("SELECT id FROM vhosts.certchain WHERE cn='{$issuer}'");
92)   if (mysql_num_rows($result) > 0)
93)   {
94)     $c = mysql_fetch_assoc($result);
95)     //$chainfile = '/etc/apache2/certs/chains/'.$c['id'].'.pem';
96)     DEBUG("identified fitting certificate chain #".$c['id']);
97)     return $c['id'];
98)   }
99) }
100) 
101) 
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

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

bernd authored 13 years ago

103) { 
104)   // Lade private key 
105)   $seckey = openssl_get_privatekey($key);
106)   if ($seckey === FALSE) {
107)     system_failure("Der private Schlüssel konnte (ohne Passwort) nicht gelesen werden.");
108)   }
109)   // Lade public key
110)   $pubkey = openssl_get_publickey($cert);
111)   if ($pubkey === FALSE) {
112)     system_failure("In dem eingetragenen Zertifikat wurde kein öffentlicher Schlüssel gefunden.");
113)   }
114)   // Parse Details über den pubkey
115)   $certinfo = openssl_pkey_get_details($pubkey);
bernd Erlaube nur RSA- und DSA-Ze...

bernd authored 13 years ago

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

bernd authored 13 years ago

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

bernd authored 13 years ago

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

bernd authored 13 years ago

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

bernd authored 13 years ago

123)     system_failure("Dieser Schlüssel nutzt einen nicht unterstützten Algorithmus.");
124)   }
125)     
bernd Mehr Fehlerbehandlung für S...

bernd authored 13 years ago

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

bernd authored 15 years ago

132)   if (openssl_x509_check_private_key($cert, $key) !== true)
133)   {
134)     DEBUG("Zertifikat und Key passen nicht zusammen");
135)     return CERT_INVALID;
136)   }
137) 
bernd Cert-Chain erkennen und ben...

bernd authored 14 years ago

138)   $cacerts = array('/etc/ssl/certs');
Bernd Wurst use temporary file for vali...

Bernd Wurst authored 12 years ago

139)   $chain = (int) get_chain($cert);
bernd Cert-Chain erkennen und ben...

bernd authored 14 years ago

140)   if ($chain)
141)   {
Bernd Wurst use temporary file for vali...

Bernd Wurst authored 12 years ago

142)     $result = db_query("SELECT content FROM vhosts.certchain WHERE id={$chain}");
143)     $tmp = mysql_fetch_assoc($result);
144)     $chaincert = $tmp['content'];
145)     $chainfile = tempnam(sys_get_temp_dir(), 'webinterface');
146)     $f = fopen($chainfile, "w");
147)     fwrite($f, $chaincert);
148)     fclose($f);
149)     $cacerts[] = $chainfile;
bernd Cert-Chain erkennen und ben...

bernd authored 14 years ago

150)   }
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

151) 
Bernd Wurst use temporary file for vali...

Bernd Wurst authored 12 years ago

152)   $valid = openssl_x509_checkpurpose($cert, X509_PURPOSE_SSL_SERVER, $cacerts);
153)   if ($chain) {
154)     unlink($chainfile);
155)   }
156)   if ($valid !== true)
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

157)   { 
158)     DEBUG('certificate was not validated as a server certificate with the available chain');
159)     return CERT_NOCHAIN;
160)   }
161) 
162)   return CERT_OK;
163) }
164) 
165) 
166) function parse_cert_details($cert)
167) {
168)   $certdata = openssl_x509_parse($cert, true);
169)   /* 
170) name => /CN=*.bwurst.org
171) validFrom_time_t => 1204118790
172) validTo_time_t => 1267190790
173) 
174) 
175)   */
bernd Erlaube nur RSA- und DSA-Ze...

bernd authored 13 years ago

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

bernd authored 14 years ago

177)   //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 14 years ago

178)   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 15 years ago

179) }
180) 
181) 
182) function save_cert($info, $cert, $key)
183) {
hanno zertifikate und keys export...

hanno authored 15 years ago

184)   openssl_pkey_export($key, $key);
185)   openssl_x509_export($cert, $cert);
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

186)   $subject = mysql_real_escape_string(filter_input_general($info['subject']));
187)   $cn = mysql_real_escape_string(filter_input_general($info['cn']));
188)   $valid_from = mysql_real_escape_string($info['valid_from']);
189)   $valid_until = mysql_real_escape_string($info['valid_until']);
bernd Cert-Chain erkennen und ben...

bernd authored 14 years ago

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

bernd authored 15 years ago

191)   $cert = mysql_real_escape_string($cert);
192)   $key = mysql_real_escape_string($key);
193)   $uid = (int) $_SESSION['userinfo']['uid'];
194) 
bernd Cert-Chain erkennen und ben...

bernd authored 14 years ago

195)   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 15 years ago

196) }
197) 
bernd Cert-Refresh

bernd authored 15 years ago

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

bernd authored 15 years ago

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

bernd authored 15 years ago

200) {
hanno zertifikate und keys export...

hanno authored 15 years ago

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

bernd authored 13 years ago

202)   $chain = maybe_null( get_chain($cert) );
203) 
bernd Cert-Refresh

bernd authored 15 years ago

204)   $id = (int) $id;
205)   $oldcert = cert_details($id);
206)   $cert = mysql_real_escape_string($cert);
207)   
208)   $valid_from = mysql_real_escape_string($info['valid_from']);
209)   $valid_until = mysql_real_escape_string($info['valid_until']);
210) 
bernd neue Bilder, mehr SSL-Zerti...

bernd authored 15 years ago

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

hanno authored 15 years ago

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

bernd authored 15 years ago

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

hanno authored 15 years ago

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

bernd authored 14 years ago

216)   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 15 years ago

217) }
218) 
219) 
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

220) function delete_cert($id)
221) {
222)   $uid = (int) $_SESSION['userinfo']['uid'];
223)   $id = (int) $id;
224)   
225)   db_query("DELETE FROM vhosts.certs WHERE uid={$uid} AND id={$id} LIMIT 1");
226) }
227) 
bernd CSR-Erstellung

bernd authored 15 years ago

228) function delete_csr($id)
229) {
230)   $uid = (int) $_SESSION['userinfo']['uid'];
231)   $id = (int) $id;
232)   
233)   db_query("DELETE FROM vhosts.csr WHERE uid={$uid} AND id={$id} LIMIT 1");
234) }
235) 
236) function create_wildcard_csr($cn, $bits)
237) {
238)   $cn = filter_input_hostname($cn);
239)   $bits = (int) $bits;
240)   if ($bits == 0)
241)     $bits = 4096;
242) 
243)   $keyfile = tempnam(ini_get('upload_tmp_dir'), 'key');
244)   $csrfile = tempnam(ini_get('upload_tmp_dir'), 'csr');
245)   $config = tempnam(ini_get('upload_tmp_dir'), 'config');
246) 
247)   DEBUG("key: ".$keyfile." / csr: ".$csrfile." / config: ".$config);
248) 
249)   $c = fopen($config, "w");
250)   fwrite($c, "[req]
251) default_bits = {$bits}
252) default_keyfile = {$keyfile}
253) encrypt_key = no
254) distinguished_name      = req_distinguished_name
255) req_extensions = v3_req
256) 
257) [v3_req]
258) subjectAltName = DNS:{$cn}, DNS:*.{$cn}
259) 
260) [ req_distinguished_name ]
261) countryName                     = Country Name (2 letter code)
262) countryName_default             = DE
263) stateOrProvinceName             = State or Province Name (full name)
264) stateOrProvinceName_default     = Baden-Wuerttemberg
265) localityName                    = Locality Name (eg, city)
266) localityName_default            = Murrhardt
267) 0.organizationName              = Organization Name (eg, company)
268) 0.organizationName_default      = schokokeks.org
269) 
270) commonName = Common Name
271) commonName_default = *.{$cn}
272) ");
273)   fclose($c);
274) 
275)   $output = '';
hanno sha2 csrs

hanno authored 14 years ago

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

bernd authored 15 years ago

277)   $retval = 0;
278)   exec($cmdline, $output, $retval);
279)   DEBUG($output);
280)   DEBUG($retval);
281)   if ($retval != 0)
282)   {
bernd Bugfix: Beim Eintragen eine...

bernd authored 13 years ago

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

bernd authored 15 years ago

284)   }
285)   
286)   $csr = file_get_contents($csrfile);
287)   $key = file_get_contents($keyfile);
288) 
289)   unlink($csrfile);
290)   unlink($keyfile);
291)   unlink($config);
292) 
293)   return array($csr, $key);
294) }
295) 
296) 
297) 
298) function create_csr($cn, $bits)
299) {
300)   $cn = filter_input_hostname($cn);
301)   $bits = (int) $bits;
302)   if ($bits == 0)
303)     $bits = 4096;
304) 
305)   $keyfile = tempnam(ini_get('upload_tmp_dir'), 'key');
306)   $csrfile = tempnam(ini_get('upload_tmp_dir'), 'csr');
307)   $config = tempnam(ini_get('upload_tmp_dir'), 'config');
308) 
309)   DEBUG("key: ".$keyfile." / csr: ".$csrfile." / config: ".$config);
310) 
311)   $c = fopen($config, "w");
312)   fwrite($c, "[req]
313) default_bits = {$bits}
314) default_keyfile = {$keyfile}
315) encrypt_key = no
316) distinguished_name      = req_distinguished_name
317) 
318) [ req_distinguished_name ]
319) countryName                     = Country Name (2 letter code)
320) countryName_default             = DE
321) stateOrProvinceName             = State or Province Name (full name)
322) stateOrProvinceName_default     = Baden-Wuerttemberg
323) localityName                    = Locality Name (eg, city)
324) localityName_default            = Murrhardt
325) 0.organizationName              = Organization Name (eg, company)
326) 0.organizationName_default      = schokokeks.org
327) 
328) commonName = Common Name
329) commonName_default = {$cn}
330) ");
331)   fclose($c);
332) 
333)   $output = '';
hanno sha2 csrs

hanno authored 14 years ago

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

bernd authored 15 years ago

335)   $retval = 0;
336)   exec($cmdline, $output, $retval);
337)   DEBUG($output);
338)   DEBUG($retval);
339)   if ($retval != 0)
340)   {
bernd Bugfix: Beim Eintragen eine...

bernd authored 13 years ago

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

bernd authored 15 years ago

342)   }
343)   
344)   $csr = file_get_contents($csrfile);
345)   $key = file_get_contents($keyfile);
346) 
347)   unlink($csrfile);
348)   unlink($keyfile);
349)   unlink($config);
350) 
351)   return array($csr, $key);
352) }
353) 
354) 
355) 
356) function save_csr($cn, $bits, $wildcard=true)
357) {
bernd (Verständliche) Fehlermeldu...

bernd authored 13 years ago

358)   if (! $cn) {
359)     system_failure("Sie müssen einen Domainname eingeben!");
360)   }