44996558c4cab6203546dfba757717f68b7bd01f
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) 
Bernd Wurst Updated copyright notice (2...

Bernd Wurst authored 11 years ago

5) Written 2008-2013 by schokokeks.org Hosting, namely
Bernd Wurst Added license tags for CC0,...

Bernd Wurst authored 12 years ago

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'];
Bernd Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

27)   $result = db_query("SELECT id, valid_from, valid_until, subject, cn FROM vhosts.certs WHERE uid=? ORDER BY cn", array($uid));
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

28)   $ret = array();
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

29)   while ($i = $result->fetch())
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

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'];
Bernd Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

38)   $result = db_query("SELECT id, created, hostname, bits FROM vhosts.csr WHERE uid=? ORDER BY hostname", array($uid));
bernd CSR-Erstellung

bernd authored 15 years ago

39)   $ret = array();
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

40)   while ($i = $result->fetch())
bernd CSR-Erstellung

bernd authored 15 years ago

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 Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 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", array(":uid" => $uid, ":id" => $id));
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

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

bernd authored 15 years ago

53)     system_failure("Ungültiges Zertifikat #{$id}");
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

54)   return $result->fetch();
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

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)   
Bernd Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

63)   $result = db_query("SELECT id, created, hostname, bits, `replace`, csr, `key` FROM vhosts.csr WHERE uid=:uid AND id=:id", array(":uid" => $uid, ":id" => $id));
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

64)   if ($result->rowCount() != 1)
bernd CSR-Erstellung

bernd authored 15 years ago

65)     system_failure("Ungültiger CSR");
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

66)   return $result->fetch();
bernd CSR-Erstellung

bernd authored 15 years ago

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 Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

90)   $result = db_query("SELECT id FROM vhosts.certchain WHERE cn=?", array($certdata['issuer']['CN']));
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

91)   if ($result->rowCount() > 0)
bernd Cert-Chain erkennen und ben...

bernd authored 14 years ago

92)   {
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

93)     $c = $result->fetch();
bernd Cert-Chain erkennen und ben...

bernd authored 14 years ago

94)     //$chainfile = '/etc/apache2/certs/chains/'.$c['id'].'.pem';
95)     DEBUG("identified fitting certificate chain #".$c['id']);
96)     return $c['id'];
97)   }
98) }
99) 
100) 
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

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

bernd authored 13 years ago

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

bernd authored 13 years ago

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

bernd authored 13 years ago

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

bernd authored 13 years ago

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

bernd authored 13 years ago

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

bernd authored 13 years ago

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

bernd authored 13 years ago

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

bernd authored 15 years ago

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

bernd authored 14 years ago

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

Bernd Wurst authored 12 years ago

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

bernd authored 14 years ago

139)   if ($chain)
140)   {
Bernd Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

141)     $result = db_query("SELECT content FROM vhosts.certchain WHERE id=?", array($chain));
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

142)     $tmp = $result->fetch();
Bernd Wurst use temporary file for vali...

Bernd Wurst authored 12 years ago

143)     $chaincert = $tmp['content'];
144)     $chainfile = tempnam(sys_get_temp_dir(), 'webinterface');
145)     $f = fopen($chainfile, "w");
146)     fwrite($f, $chaincert);
147)     fclose($f);
148)     $cacerts[] = $chainfile;
bernd Cert-Chain erkennen und ben...

bernd authored 14 years ago

149)   }
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

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

Bernd Wurst authored 12 years ago

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

bernd authored 15 years ago

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

bernd authored 13 years ago

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

bernd authored 14 years ago

176)   //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

177)   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

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

hanno authored 15 years ago

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

bernd authored 15 years ago

185)   $uid = (int) $_SESSION['userinfo']['uid'];
186) 
Bernd Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

187)   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)", 
188)         array(":uid" => $uid, ":subject" => filter_input_general($info['subject']), ":cn" => filter_input_general($info['cn']), ":valid_from" => $info['valid_from'], 
189)               ":valid_until" => $info['valid_until'], ":chain" => get_chain($cert), ":cert" => $cert, ":key" => $key));
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

190) }
191) 
bernd Cert-Refresh

bernd authored 15 years ago

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

bernd authored 15 years ago

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

bernd authored 15 years ago

194) {
hanno zertifikate und keys export...

hanno authored 15 years ago

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

bernd authored 13 years ago

196)   $chain = maybe_null( get_chain($cert) );
197) 
bernd Cert-Refresh

bernd authored 15 years ago

198)   $id = (int) $id;
199)   $oldcert = cert_details($id);
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

200)   $cert = db_escape_string($cert);
201)   $subject = db_escape_string(filter_input_general($info['subject']));
202)   $cn = db_escape_string(filter_input_general($info['cn']));
bernd Cert-Refresh

bernd authored 15 years ago

203)   
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

204)   $valid_from = db_escape_string($info['valid_from']);
205)   $valid_until = db_escape_string($info['valid_until']);
bernd Cert-Refresh

bernd authored 15 years ago

206) 
Bernd Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

207)   $args = array(":subject" => filter_input_general($info['subject']),
208)                 ":cn" => filter_input_general($info['cn']),
209)                 ":cert" => $cert,
210)                 ":valid_from" => $info['valid_from'],
211)                 ":valid_until" => $info['valid_until'],
212)                 ":chain" => get_chain($cert),
213)                 ":id" => $id);
214) 
bernd neue Bilder, mehr SSL-Zerti...

bernd authored 15 years ago

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

hanno authored 15 years ago

216)   if ($key) {
217)     openssl_pkey_export($key, $key);
Bernd Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

218)     $keyop = ", `key`=:key";
219)     $args[":key"] = $key;
hanno zertifikate und keys export...

hanno authored 15 years ago

220)   }
Bernd Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

221)   db_query("UPDATE vhosts.certs SET subject=:subject, cn=:cn, cert=:cert{$keyop}, valid_from=:valid_from, valid_until=:valid_until, chain=:chain WHERE id=:id", $args);
bernd Cert-Refresh

bernd authored 15 years ago

222) }
223) 
224) 
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

225) function delete_cert($id)
226) {
227)   $uid = (int) $_SESSION['userinfo']['uid'];
228)   $id = (int) $id;
229)   
Bernd Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

230)   db_query("DELETE FROM vhosts.certs WHERE uid=? AND id=?", array($uid, $id));
bernd Neue Zertifikatsverwaltung

bernd authored 15 years ago

231) }
232) 
bernd CSR-Erstellung

bernd authored 15 years ago

233) function delete_csr($id)
234) {
235)   $uid = (int) $_SESSION['userinfo']['uid'];
236)   $id = (int) $id;
237)   
Bernd Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

238)   db_query("DELETE FROM vhosts.csr WHERE uid=? AND id=?", array($uid, $id));
bernd CSR-Erstellung

bernd authored 15 years ago

239) }
240) 
241) 
242) function create_csr($cn, $bits)
243) {
Bernd Wurst Wildcard-CSRs können jetzt...

Bernd Wurst authored 11 years ago

244)   $cn = filter_input_hostname($cn, true);
bernd CSR-Erstellung

bernd authored 15 years ago

245)   $bits = (int) $bits;
246)   if ($bits == 0)
247)     $bits = 4096;
248) 
249)   $keyfile = tempnam(ini_get('upload_tmp_dir'), 'key');
250)   $csrfile = tempnam(ini_get('upload_tmp_dir'), 'csr');
251)   $config = tempnam(ini_get('upload_tmp_dir'), 'config');
252) 
253)   DEBUG("key: ".$keyfile." / csr: ".$csrfile." / config: ".$config);
254) 
255)   $c = fopen($config, "w");
256)   fwrite($c, "[req]
257) default_bits = {$bits}
258) default_keyfile = {$keyfile}
259) encrypt_key = no
260) distinguished_name      = req_distinguished_name
261) 
262) [ req_distinguished_name ]
263) countryName                     = Country Name (2 letter code)
264) countryName_default             = DE
265) stateOrProvinceName             = State or Province Name (full name)
266) stateOrProvinceName_default     = Baden-Wuerttemberg
267) localityName                    = Locality Name (eg, city)
268) localityName_default            = Murrhardt
269) 0.organizationName              = Organization Name (eg, company)
270) 0.organizationName_default      = schokokeks.org
271) 
272) commonName = Common Name
273) commonName_default = {$cn}
274) ");
275)   fclose($c);
276) 
277)   $output = '';
hanno sha2 csrs

hanno authored 14 years ago

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

bernd authored 15 years ago

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

bernd authored 13 years ago

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

bernd authored 15 years ago

286)   }
287)   
288)   $csr = file_get_contents($csrfile);
289)   $key = file_get_contents($keyfile);
290) 
291)   unlink($csrfile);
292)   unlink($keyfile);
293)   unlink($config);
294) 
295)   return array($csr, $key);
296) }
297) 
298) 
299) 
Bernd Wurst Wildcard-CSRs können jetzt...

Bernd Wurst authored 11 years ago

300) function save_csr($cn, $bits, $replace=NULL)
bernd CSR-Erstellung

bernd authored 15 years ago

301) {
bernd (Verständliche) Fehlermeldu...

bernd authored 13 years ago

302)   if (! $cn) {
303)     system_failure("Sie müssen einen Domainname eingeben!");
304)   }
bernd CSR-Erstellung

bernd authored 15 years ago

305)   $csr = NULL;
306)   $key = NULL;
Bernd Wurst Wildcard-CSRs können jetzt...

Bernd Wurst authored 11 years ago

307)   list($csr, $key) = create_csr($cn, $bits);
bernd CSR-Erstellung

bernd authored 15 years ago

308)   
309)   $uid = (int) $_SESSION['userinfo']['uid'];
Bernd Wurst Umstellung auf PDO-Datenban...

Bernd Wurst authored 10 years ago

310)   $cn = db_escape_string(filter_input_hostname($cn, true));
Bernd Wurst Einige Statements auf Prepa...

Bernd Wurst authored 10 years ago

311)   db_query("INSERT INTO vhosts.csr (uid, hostname, bits, `replace`, csr, `key`) VALUES (:uid, :cn, :bits, :replace, :csr, :key)",
312)            array(":uid" => $uid, ":cn" => filter_input_hostname($cn, true), ":bits" => $bits, 
313)                  ":replace" => $replace, ":csr" => $csr, ":key" => $key));
314)   $id = db_insert_id();