Project

General

Profile

Download (33 KB) Statistics
| Branch: | Tag: | Revision:
1 64cc39d3 Matthew Grooms
<?php
2
/*
3 aaec5634 Renato Botelho
 * system_certmanager.php
4 98402844 Stephen Beaver
 *
5 aaec5634 Renato Botelho
 * part of pfSense (https://www.pfsense.org)
6 2a2396a6 Renato Botelho
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7 aaec5634 Renato Botelho
 * Copyright (c) 2008 Shrew Soft Inc
8
 * All rights reserved.
9 98402844 Stephen Beaver
 *
10 aaec5634 Renato Botelho
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions are met:
12 98402844 Stephen Beaver
 *
13 aaec5634 Renato Botelho
 * 1. Redistributions of source code must retain the above copyright notice,
14
 *    this list of conditions and the following disclaimer.
15 98402844 Stephen Beaver
 *
16 aaec5634 Renato Botelho
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in
18
 *    the documentation and/or other materials provided with the
19
 *    distribution.
20 98402844 Stephen Beaver
 *
21 aaec5634 Renato Botelho
 * 3. All advertising materials mentioning features or use of this software
22
 *    must display the following acknowledgment:
23
 *    "This product includes software developed by the pfSense Project
24
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
25 98402844 Stephen Beaver
 *
26 aaec5634 Renato Botelho
 * 4. The names "pfSense" and "pfSense Project" must not be used to
27
 *    endorse or promote products derived from this software without
28
 *    prior written permission. For written permission, please contact
29
 *    coreteam@pfsense.org.
30 98402844 Stephen Beaver
 *
31 aaec5634 Renato Botelho
 * 5. Products derived from this software may not be called "pfSense"
32
 *    nor may "pfSense" appear in their names without prior written
33
 *    permission of the Electric Sheep Fencing, LLC.
34 98402844 Stephen Beaver
 *
35 aaec5634 Renato Botelho
 * 6. Redistributions of any form whatsoever must retain the following
36
 *    acknowledgment:
37 98402844 Stephen Beaver
 *
38 aaec5634 Renato Botelho
 * "This product includes software developed by the pfSense Project
39
 * for use in the pfSense software distribution (http://www.pfsense.org/).
40 98402844 Stephen Beaver
 *
41 aaec5634 Renato Botelho
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
42
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
45
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52
 * OF THE POSSIBILITY OF SUCH DAMAGE.
53 98402844 Stephen Beaver
 */
54 64cc39d3 Matthew Grooms
55
##|+PRIV
56
##|*IDENT=page-system-certmanager
57
##|*NAME=System: Certificate Manager
58
##|*DESCR=Allow access to the 'System: Certificate Manager' page.
59
##|*MATCH=system_certmanager.php*
60
##|-PRIV
61
62 aceaf18c Phil Davis
require_once("guiconfig.inc");
63 14f5ae08 Ermal Lu?i
require_once("certs.inc");
64 64cc39d3 Matthew Grooms
65
$cert_methods = array(
66 ad9b5c67 jim-p
	"import" => gettext("Import an existing Certificate"),
67 a37753d7 Vinicius Coque
	"internal" => gettext("Create an internal Certificate"),
68 ad9b5c67 jim-p
	"external" => gettext("Create a Certificate Signing Request"),
69
);
70 64cc39d3 Matthew Grooms
71 dbcc45d1 Phil Davis
$cert_keylens = array("512", "1024", "2048", "3072", "4096", "7680", "8192", "15360", "16384");
72 56b1ed39 Phil Davis
$cert_types = array(
73
	"server" => "Server Certificate",
74
	"user" => "User Certificate");
75 64cc39d3 Matthew Grooms
76 2f65de89 jim-p
$altname_types = array("DNS", "IP", "email", "URI");
77 cfc0d396 jim-p
global $openssl_digest_algs;
78 2f65de89 jim-p
79 56b1ed39 Phil Davis
if (is_numericint($_GET['userid'])) {
80 e41ec584 Renato Botelho
	$userid = $_GET['userid'];
81 56b1ed39 Phil Davis
}
82
if (isset($_POST['userid']) && is_numericint($_POST['userid'])) {
83 ad9b5c67 jim-p
	$userid = $_POST['userid'];
84 56b1ed39 Phil Davis
}
85 e41ec584 Renato Botelho
86
if (isset($userid)) {
87 ad9b5c67 jim-p
	$cert_methods["existing"] = gettext("Choose an existing certificate");
88 56b1ed39 Phil Davis
	if (!is_array($config['system']['user'])) {
89 ad9b5c67 jim-p
		$config['system']['user'] = array();
90 56b1ed39 Phil Davis
	}
91 ad9b5c67 jim-p
	$a_user =& $config['system']['user'];
92
}
93
94 56b1ed39 Phil Davis
if (is_numericint($_GET['id'])) {
95 e41ec584 Renato Botelho
	$id = $_GET['id'];
96 56b1ed39 Phil Davis
}
97
if (isset($_POST['id']) && is_numericint($_POST['id'])) {
98 64cc39d3 Matthew Grooms
	$id = $_POST['id'];
99 56b1ed39 Phil Davis
}
100 64cc39d3 Matthew Grooms
101 56b1ed39 Phil Davis
if (!is_array($config['ca'])) {
102 b4e6524c jim-p
	$config['ca'] = array();
103 56b1ed39 Phil Davis
}
104 64cc39d3 Matthew Grooms
105 b4e6524c jim-p
$a_ca =& $config['ca'];
106 64cc39d3 Matthew Grooms
107 56b1ed39 Phil Davis
if (!is_array($config['cert'])) {
108 b4e6524c jim-p
	$config['cert'] = array();
109 56b1ed39 Phil Davis
}
110 64cc39d3 Matthew Grooms
111 b4e6524c jim-p
$a_cert =& $config['cert'];
112 64cc39d3 Matthew Grooms
113
$internal_ca_count = 0;
114 56b1ed39 Phil Davis
foreach ($a_ca as $ca) {
115
	if ($ca['prv']) {
116 64cc39d3 Matthew Grooms
		$internal_ca_count++;
117 56b1ed39 Phil Davis
	}
118
}
119 64cc39d3 Matthew Grooms
120
$act = $_GET['act'];
121 8b35eae5 Stephen Beaver
122 56b1ed39 Phil Davis
if ($_POST['act']) {
123 64cc39d3 Matthew Grooms
	$act = $_POST['act'];
124 56b1ed39 Phil Davis
}
125 64cc39d3 Matthew Grooms
126
if ($act == "del") {
127
128 40e6086a jim-p
	if (!isset($a_cert[$id])) {
129 64cc39d3 Matthew Grooms
		pfSenseHeader("system_certmanager.php");
130
		exit;
131
	}
132
133
	unset($a_cert[$id]);
134
	write_config();
135 8545adde k-paulius
	$savemsg = sprintf(gettext("Certificate %s successfully deleted."), htmlspecialchars($a_cert[$id]['descr']));
136 2f51259b jim-p
	pfSenseHeader("system_certmanager.php");
137
	exit;
138 64cc39d3 Matthew Grooms
}
139
140 8b35eae5 Stephen Beaver
141 64cc39d3 Matthew Grooms
if ($act == "new") {
142
	$pconfig['method'] = $_GET['method'];
143
	$pconfig['keylen'] = "2048";
144 28a20fdb jim-p
	$pconfig['digest_alg'] = "sha256";
145 8f07b51c PiBa-NL
	$pconfig['csr_keylen'] = "2048";
146
	$pconfig['csr_digest_alg'] = "sha256";
147 7aaabd69 jim-p
	$pconfig['type'] = "user";
148 cf360495 Chris Buechler
	$pconfig['lifetime'] = "3650";
149 64cc39d3 Matthew Grooms
}
150
151 93823b10 Matthew Grooms
if ($act == "exp") {
152
153
	if (!$a_cert[$id]) {
154
		pfSenseHeader("system_certmanager.php");
155
		exit;
156
	}
157
158 f2a86ca9 jim-p
	$exp_name = urlencode("{$a_cert[$id]['descr']}.crt");
159 93823b10 Matthew Grooms
	$exp_data = base64_decode($a_cert[$id]['crt']);
160
	$exp_size = strlen($exp_data);
161
162
	header("Content-Type: application/octet-stream");
163
	header("Content-Disposition: attachment; filename={$exp_name}");
164
	header("Content-Length: $exp_size");
165
	echo $exp_data;
166
	exit;
167
}
168
169 53f5b15f jim-p
if ($act == "req") {
170
171
	if (!$a_cert[$id]) {
172
		pfSenseHeader("system_certmanager.php");
173
		exit;
174
	}
175
176
	$exp_name = urlencode("{$a_cert[$id]['descr']}.req");
177
	$exp_data = base64_decode($a_cert[$id]['csr']);
178
	$exp_size = strlen($exp_data);
179
180
	header("Content-Type: application/octet-stream");
181
	header("Content-Disposition: attachment; filename={$exp_name}");
182
	header("Content-Length: $exp_size");
183
	echo $exp_data;
184
	exit;
185
}
186
187 73fbece8 mgrooms
if ($act == "key") {
188
189
	if (!$a_cert[$id]) {
190
		pfSenseHeader("system_certmanager.php");
191
		exit;
192
	}
193
194 f2a86ca9 jim-p
	$exp_name = urlencode("{$a_cert[$id]['descr']}.key");
195 73fbece8 mgrooms
	$exp_data = base64_decode($a_cert[$id]['prv']);
196
	$exp_size = strlen($exp_data);
197
198
	header("Content-Type: application/octet-stream");
199
	header("Content-Disposition: attachment; filename={$exp_name}");
200
	header("Content-Length: $exp_size");
201
	echo $exp_data;
202
	exit;
203
}
204
205 eaf23c17 jim-p
if ($act == "p12") {
206
	if (!$a_cert[$id]) {
207
		pfSenseHeader("system_certmanager.php");
208
		exit;
209
	}
210
211
	$exp_name = urlencode("{$a_cert[$id]['descr']}.p12");
212 eed5b507 jim-p
	$args = array();
213
	$args['friendly_name'] = $a_cert[$id]['descr'];
214
215
	$ca = lookup_ca($a_cert[$id]['caref']);
216 56b1ed39 Phil Davis
	if ($ca) {
217 eed5b507 jim-p
		$args['extracerts'] = openssl_x509_read(base64_decode($ca['crt']));
218 56b1ed39 Phil Davis
	}
219 eaf23c17 jim-p
220
	$res_crt = openssl_x509_read(base64_decode($a_cert[$id]['crt']));
221
	$res_key = openssl_pkey_get_private(array(0 => base64_decode($a_cert[$id]['prv']) , 1 => ""));
222
223
	$exp_data = "";
224 eed5b507 jim-p
	openssl_pkcs12_export($res_crt, $exp_data, $res_key, null, $args);
225 eaf23c17 jim-p
	$exp_size = strlen($exp_data);
226
227
	header("Content-Type: application/octet-stream");
228
	header("Content-Disposition: attachment; filename={$exp_name}");
229
	header("Content-Length: $exp_size");
230
	echo $exp_data;
231
	exit;
232
}
233
234 64cc39d3 Matthew Grooms
if ($act == "csr") {
235
	if (!$a_cert[$id]) {
236
		pfSenseHeader("system_certmanager.php");
237
		exit;
238
	}
239
240 f2a86ca9 jim-p
	$pconfig['descr'] = $a_cert[$id]['descr'];
241 64cc39d3 Matthew Grooms
	$pconfig['csr'] = base64_decode($a_cert[$id]['csr']);
242
}
243
244
if ($_POST) {
245 762faef5 Phil Davis
	// This is just the blank alternate name that is added for display purposes. We don't want to validate/save it
246 78863416 Phil Davis
	if ($_POST['altname_value0'] == "") {
247 3f0efd58 Stephen Beaver
		unset($_POST['altname_type0']);
248
		unset($_POST['altname_value0']);
249
	}
250 0edcccc3 Daniel Seebald
251 e64aa6f8 Carlos Eduardo Ramos
	if ($_POST['save'] == gettext("Save")) {
252 21cc2faa Evgeny Yurchenko
		$input_errors = array();
253 64cc39d3 Matthew Grooms
		$pconfig = $_POST;
254
255
		/* input validation */
256 ad9b5c67 jim-p
		if ($pconfig['method'] == "import") {
257 64cc39d3 Matthew Grooms
			$reqdfields = explode(" ",
258 56b1ed39 Phil Davis
				"descr cert key");
259 38fb1109 Vinicius Coque
			$reqdfieldsn = array(
260 56b1ed39 Phil Davis
				gettext("Descriptive name"),
261
				gettext("Certificate data"),
262
				gettext("Key data"));
263
			if ($_POST['cert'] && (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE"))) {
264 396cfe2e jim-p
				$input_errors[] = gettext("This certificate does not appear to be valid.");
265 56b1ed39 Phil Davis
			}
266 64cc39d3 Matthew Grooms
		}
267
268
		if ($pconfig['method'] == "internal") {
269
			$reqdfields = explode(" ",
270 56b1ed39 Phil Davis
				"descr caref keylen type lifetime dn_country dn_state dn_city ".
271
				"dn_organization dn_email dn_commonname");
272 38fb1109 Vinicius Coque
			$reqdfieldsn = array(
273 56b1ed39 Phil Davis
				gettext("Descriptive name"),
274
				gettext("Certificate authority"),
275
				gettext("Key length"),
276
				gettext("Certificate Type"),
277
				gettext("Lifetime"),
278
				gettext("Distinguished name Country Code"),
279
				gettext("Distinguished name State or Province"),
280
				gettext("Distinguished name City"),
281
				gettext("Distinguished name Organization"),
282
				gettext("Distinguished name Email Address"),
283
				gettext("Distinguished name Common Name"));
284 64cc39d3 Matthew Grooms
		}
285
286
		if ($pconfig['method'] == "external") {
287
			$reqdfields = explode(" ",
288 56b1ed39 Phil Davis
				"descr csr_keylen csr_dn_country csr_dn_state csr_dn_city ".
289
				"csr_dn_organization csr_dn_email csr_dn_commonname");
290 38fb1109 Vinicius Coque
			$reqdfieldsn = array(
291 56b1ed39 Phil Davis
				gettext("Descriptive name"),
292
				gettext("Key length"),
293
				gettext("Distinguished name Country Code"),
294
				gettext("Distinguished name State or Province"),
295
				gettext("Distinguished name City"),
296
				gettext("Distinguished name Organization"),
297
				gettext("Distinguished name Email Address"),
298
				gettext("Distinguished name Common Name"));
299 64cc39d3 Matthew Grooms
		}
300
301 ad9b5c67 jim-p
		if ($pconfig['method'] == "existing") {
302
			$reqdfields = array("certref");
303
			$reqdfieldsn = array(gettext("Existing Certificate Choice"));
304
		}
305
306 547c56c4 jim-p
		$altnames = array();
307 1e9b4611 Renato Botelho
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
308 eecbeec4 Renato Botelho
		if ($pconfig['method'] != "import" && $pconfig['method'] != "existing") {
309 2f65de89 jim-p
			/* subjectAltNames */
310 bf9d50e8 Stephen Beaver
			foreach ($_POST as $key => $value) {
311
				$entry = '';
312
				if (!substr_compare('altname_type', $key, 0, 12)) {
313
					$entry = substr($key, 12);
314
					$field = 'type';
315 78863416 Phil Davis
				} elseif (!substr_compare('altname_value', $key, 0, 13)) {
316 bf9d50e8 Stephen Beaver
					$entry = substr($key, 13);
317
					$field = 'value';
318
				}
319
320
				if (ctype_digit($entry)) {
321 3f0efd58 Stephen Beaver
					$entry++;	// Pre-bootstrap code is one-indexed, but the bootstrap code is 0-indexed
322 bf9d50e8 Stephen Beaver
					$altnames[$entry][$field] = $value;
323
				}
324 2f65de89 jim-p
			}
325 bf9d50e8 Stephen Beaver
326 edf37d56 Renato Botelho
			$pconfig['altnames']['item'] = $altnames;
327 2f65de89 jim-p
328
			/* Input validation for subjectAltNames */
329
			foreach ($altnames as $idx => $altname) {
330
				switch ($altname['type']) {
331
					case "DNS":
332 0edcccc3 Daniel Seebald
						if (!is_hostname($altname['value'], true)) {
333
							array_push($input_errors, "DNS subjectAltName values must be valid hostnames, FQDNs or wildcard domains.");
334 56b1ed39 Phil Davis
						}
335 2f65de89 jim-p
						break;
336
					case "IP":
337 56b1ed39 Phil Davis
						if (!is_ipaddr($altname['value'])) {
338 2f65de89 jim-p
							array_push($input_errors, "IP subjectAltName values must be valid IP Addresses");
339 56b1ed39 Phil Davis
						}
340 2f65de89 jim-p
						break;
341
					case "email":
342 56b1ed39 Phil Davis
						if (empty($altname['value'])) {
343 73ff9530 Stephen Beaver
							array_push($input_errors, "An e-mail address must be provided for this type of subjectAltName");
344 56b1ed39 Phil Davis
						}
345
						if (preg_match("/[\!\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $altname['value'])) {
346 2f65de89 jim-p
							array_push($input_errors, "The e-mail provided in a subjectAltName contains invalid characters.");
347 56b1ed39 Phil Davis
						}
348 2f65de89 jim-p
						break;
349
					case "URI":
350
						/* Close enough? */
351 56b1ed39 Phil Davis
						if (!is_URL($altname['value'])) {
352 2f65de89 jim-p
							$input_errors[] = "URI subjectAltName types must be a valid URI";
353 56b1ed39 Phil Davis
						}
354 2f65de89 jim-p
						break;
355
					default:
356
						$input_errors[] = "Unrecognized subjectAltName type.";
357
				}
358
			}
359
360 21cc2faa Evgeny Yurchenko
			/* Make sure we do not have invalid characters in the fields for the certificate */
361 b741d2ef jim-p
362
			if (preg_match("/[\?\>\<\&\/\\\"\']/", $_POST['descr'])) {
363
				array_push($input_errors, "The field 'Descriptive Name' contains invalid characters.");
364
			}
365
366 21cc2faa Evgeny Yurchenko
			for ($i = 0; $i < count($reqdfields); $i++) {
367 56b1ed39 Phil Davis
				if (preg_match('/email/', $reqdfields[$i])) { /* dn_email or csr_dn_name */
368
					if (preg_match("/[\!\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST[$reqdfields[$i]])) {
369 762faef5 Phil Davis
						array_push($input_errors, gettext("The field 'Distinguished name Email Address' contains invalid characters."));
370 56b1ed39 Phil Davis
					}
371
				} else if (preg_match('/commonname/', $reqdfields[$i])) { /* dn_commonname or csr_dn_commonname */
372
					if (preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST[$reqdfields[$i]])) {
373 762faef5 Phil Davis
						array_push($input_errors, gettext("The field 'Distinguished name Common Name' contains invalid characters."));
374 56b1ed39 Phil Davis
					}
375
				} else if (($reqdfields[$i] != "descr") && preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\.\"\']/", $_POST[$reqdfields[$i]])) {
376 762faef5 Phil Davis
					array_push($input_errors, sprintf(gettext("The field '%s' contains invalid characters."), $reqdfieldsn[$i]));
377 56b1ed39 Phil Davis
				}
378 21cc2faa Evgeny Yurchenko
			}
379 738fab3d jim-p
380 56b1ed39 Phil Davis
			if (($pconfig['method'] != "external") && isset($_POST["keylen"]) && !in_array($_POST["keylen"], $cert_keylens)) {
381 741d748d jim-p
				array_push($input_errors, gettext("Please select a valid Key Length."));
382 56b1ed39 Phil Davis
			}
383
			if (($pconfig['method'] != "external") && !in_array($_POST["digest_alg"], $openssl_digest_algs)) {
384 8f07b51c PiBa-NL
				array_push($input_errors, gettext("Please select a valid Digest Algorithm."));
385 56b1ed39 Phil Davis
			}
386 b49f31d0 Sjon Hortensius
387 56b1ed39 Phil Davis
			if (($pconfig['method'] == "external") && isset($_POST["csr_keylen"]) && !in_array($_POST["csr_keylen"], $cert_keylens)) {
388 ca621902 jim-p
				array_push($input_errors, gettext("Please select a valid Key Length."));
389 56b1ed39 Phil Davis
			}
390
			if (($pconfig['method'] == "external") && !in_array($_POST["csr_digest_alg"], $openssl_digest_algs)) {
391 ca621902 jim-p
				array_push($input_errors, gettext("Please select a valid Digest Algorithm."));
392 56b1ed39 Phil Davis
			}
393 547c56c4 jim-p
		}
394 64cc39d3 Matthew Grooms
395
		/* save modifications */
396
		if (!$input_errors) {
397
398 ad9b5c67 jim-p
			if ($pconfig['method'] == "existing") {
399
				$cert = lookup_cert($pconfig['certref']);
400 56b1ed39 Phil Davis
				if ($cert && $a_user) {
401 ad9b5c67 jim-p
					$a_user[$userid]['cert'][] = $cert['refid'];
402 56b1ed39 Phil Davis
				}
403 ad9b5c67 jim-p
			} else {
404
				$cert = array();
405
				$cert['refid'] = uniqid();
406 56b1ed39 Phil Davis
				if (isset($id) && $a_cert[$id]) {
407 ad9b5c67 jim-p
					$cert = $a_cert[$id];
408 56b1ed39 Phil Davis
				}
409 ad9b5c67 jim-p
410 f2a86ca9 jim-p
				$cert['descr'] = $pconfig['descr'];
411 ad9b5c67 jim-p
412 f416763b Phil Davis
				$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
413 22b380aa Evgeny Yurchenko
414 56b1ed39 Phil Davis
				if ($pconfig['method'] == "import") {
415 ad9b5c67 jim-p
					cert_import($cert, $pconfig['cert'], $pconfig['key']);
416 56b1ed39 Phil Davis
				}
417 ad9b5c67 jim-p
418
				if ($pconfig['method'] == "internal") {
419
					$dn = array(
420
						'countryName' => $pconfig['dn_country'],
421
						'stateOrProvinceName' => $pconfig['dn_state'],
422
						'localityName' => $pconfig['dn_city'],
423
						'organizationName' => $pconfig['dn_organization'],
424
						'emailAddress' => $pconfig['dn_email'],
425
						'commonName' => $pconfig['dn_commonname']);
426 b8332deb jim-p
					if (!empty($pconfig['dn_organizationalunit'])) {
427
						$dn['organizationalUnitName'] = $pconfig['dn_organizationalunit'];
428
					}
429 2f65de89 jim-p
					if (count($altnames)) {
430
						$altnames_tmp = "";
431
						foreach ($altnames as $altname) {
432
							$altnames_tmp[] = "{$altname['type']}:{$altname['value']}";
433
						}
434 bf9d50e8 Stephen Beaver
435 2f65de89 jim-p
						$dn['subjectAltName'] = implode(",", $altnames_tmp);
436
					}
437 bf9d50e8 Stephen Beaver
438
					if (!cert_create($cert, $pconfig['caref'], $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['type'], $pconfig['digest_alg'])) {
439 ddfa8daa jim-p
						$input_errors = array();
440 56b1ed39 Phil Davis
						while ($ssl_err = openssl_error_string()) {
441 ddfa8daa jim-p
							if (strpos($ssl_err, 'NCONF_get_string:no value') === false) {
442
								array_push($input_errors, "openssl library returns: " . $ssl_err);
443
							}
444 22b380aa Evgeny Yurchenko
						}
445
					}
446 ad9b5c67 jim-p
				}
447
448
				if ($pconfig['method'] == "external") {
449
					$dn = array(
450
						'countryName' => $pconfig['csr_dn_country'],
451
						'stateOrProvinceName' => $pconfig['csr_dn_state'],
452
						'localityName' => $pconfig['csr_dn_city'],
453
						'organizationName' => $pconfig['csr_dn_organization'],
454
						'emailAddress' => $pconfig['csr_dn_email'],
455
						'commonName' => $pconfig['csr_dn_commonname']);
456 b8332deb jim-p
					if (!empty($pconfig['csr_dn_organizationalunit'])) {
457
						$dn['organizationalUnitName'] = $pconfig['csr_dn_organizationalunit'];
458
					}
459 2f65de89 jim-p
					if (count($altnames)) {
460
						$altnames_tmp = "";
461
						foreach ($altnames as $altname) {
462
							$altnames_tmp[] = "{$altname['type']}:{$altname['value']}";
463
						}
464
						$dn['subjectAltName'] = implode(",", $altnames_tmp);
465
					}
466 b29c322c Stephen Beaver
467 56b1ed39 Phil Davis
					if (!csr_generate($cert, $pconfig['csr_keylen'], $dn, $pconfig['csr_digest_alg'])) {
468 ddfa8daa jim-p
						$input_errors = array();
469 56b1ed39 Phil Davis
						while ($ssl_err = openssl_error_string()) {
470 ddfa8daa jim-p
							if (strpos($ssl_err, 'NCONF_get_string:no value') === false) {
471
								array_push($input_errors, "openssl library returns: " . $ssl_err);
472
							}
473 22b380aa Evgeny Yurchenko
						}
474
					}
475 ad9b5c67 jim-p
				}
476 22b380aa Evgeny Yurchenko
				error_reporting($old_err_level);
477
478 56b1ed39 Phil Davis
				if (isset($id) && $a_cert[$id]) {
479 ad9b5c67 jim-p
					$a_cert[$id] = $cert;
480 56b1ed39 Phil Davis
				} else {
481 ad9b5c67 jim-p
					$a_cert[] = $cert;
482 56b1ed39 Phil Davis
				}
483 bf9d50e8 Stephen Beaver
484 56b1ed39 Phil Davis
				if (isset($a_user) && isset($userid)) {
485 ad9b5c67 jim-p
					$a_user[$userid]['cert'][] = $cert['refid'];
486 56b1ed39 Phil Davis
				}
487 64cc39d3 Matthew Grooms
			}
488
489 56b1ed39 Phil Davis
			if (!$input_errors) {
490 22b380aa Evgeny Yurchenko
				write_config();
491 56b1ed39 Phil Davis
			}
492 64cc39d3 Matthew Grooms
493 1a6769a6 Renato Botelho
			if ($userid) {
494
				post_redirect("system_usermanager.php", array('act' => 'edit', 'userid' => $userid));
495
				exit;
496
			}
497 64cc39d3 Matthew Grooms
		}
498
	}
499
500 a37753d7 Vinicius Coque
	if ($_POST['save'] == gettext("Update")) {
501 64cc39d3 Matthew Grooms
		unset($input_errors);
502
		$pconfig = $_POST;
503
504
		/* input validation */
505 5293bfec jim-p
		$reqdfields = explode(" ", "descr cert");
506 76d49f20 Renato Botelho
		$reqdfieldsn = array(
507 78863416 Phil Davis
			gettext("Descriptive name"),
508
			gettext("Final Certificate data"));
509 64cc39d3 Matthew Grooms
510 1e9b4611 Renato Botelho
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
511 64cc39d3 Matthew Grooms
512 b741d2ef jim-p
		if (preg_match("/[\?\>\<\&\/\\\"\']/", $_POST['descr'])) {
513
			array_push($input_errors, "The field 'Descriptive Name' contains invalid characters.");
514
		}
515
516 a828210b yakatz
//		old way
517 64cc39d3 Matthew Grooms
		/* make sure this csr and certificate subjects match */
518 a828210b yakatz
//		$subj_csr = csr_get_subject($pconfig['csr'], false);
519
//		$subj_cert = cert_get_subject($pconfig['cert'], false);
520
//
521 56b1ed39 Phil Davis
//		if (!isset($_POST['ignoresubjectmismatch']) && !($_POST['ignoresubjectmismatch'] == "yes")) {
522
//			if (strcmp($subj_csr, $subj_cert)) {
523
//				$input_errors[] = sprintf(gettext("The certificate subject '%s' does not match the signing request subject."), $subj_cert);
524 a828210b yakatz
//				$subject_mismatch = true;
525
//			}
526
//		}
527 6c07db48 Phil Davis
		$mod_csr = csr_get_modulus($pconfig['csr'], false);
528 2594f401 yakatz
		$mod_cert = cert_get_modulus($pconfig['cert'], false);
529 b49f31d0 Sjon Hortensius
530 56b1ed39 Phil Davis
		if (strcmp($mod_csr, $mod_cert)) {
531 a828210b yakatz
			// simply: if the moduli don't match, then the private key and public key won't match
532 56b1ed39 Phil Davis
			$input_errors[] = sprintf(gettext("The certificate modulus does not match the signing request modulus."), $subj_cert);
533 a828210b yakatz
			$subject_mismatch = true;
534
		}
535 64cc39d3 Matthew Grooms
536
		/* save modifications */
537
		if (!$input_errors) {
538
539
			$cert = $a_cert[$id];
540
541 f2a86ca9 jim-p
			$cert['descr'] = $pconfig['descr'];
542 64cc39d3 Matthew Grooms
543
			csr_complete($cert, $pconfig['cert']);
544
545
			$a_cert[$id] = $cert;
546
547
			write_config();
548
549
			pfSenseHeader("system_certmanager.php");
550
		}
551
	}
552
}
553
554 56c6b1cb k-paulius
$pgtitle = array(gettext("System"), gettext("Certificate Manager"), gettext("Certificates"));
555 de02dc29 Phil Davis
$pglinks = array("", "system_camanager.php", "system_certmanager.php");
556 56c6b1cb k-paulius
557
if (($act == "new" || ($_POST['save'] == gettext("Save") && $input_errors)) || ($act == "csr" || ($_POST['save'] == gettext("Update") && $input_errors))) {
558
	$pgtitle[] = gettext('Edit');
559 de02dc29 Phil Davis
	$pglinks[] = "@self";
560 56c6b1cb k-paulius
}
561 64cc39d3 Matthew Grooms
include("head.inc");
562 b49f31d0 Sjon Hortensius
563 78863416 Phil Davis
if ($input_errors) {
564 b49f31d0 Sjon Hortensius
	print_input_errors($input_errors);
565 78863416 Phil Davis
}
566 0edcccc3 Daniel Seebald
567 78863416 Phil Davis
if ($savemsg) {
568 3f0efd58 Stephen Beaver
	print_info_box($savemsg, 'success');
569 78863416 Phil Davis
}
570 b49f31d0 Sjon Hortensius
571
$tab_array = array();
572
$tab_array[] = array(gettext("CAs"), false, "system_camanager.php");
573
$tab_array[] = array(gettext("Certificates"), true, "system_certmanager.php");
574
$tab_array[] = array(gettext("Certificate Revocation"), false, "system_crlmanager.php");
575
display_top_tabs($tab_array);
576
577
// Load valid country codes
578
$dn_cc = array();
579 78863416 Phil Davis
if (file_exists("/etc/ca_countries")) {
580 b49f31d0 Sjon Hortensius
	$dn_cc_file=file("/etc/ca_countries");
581 78863416 Phil Davis
	foreach ($dn_cc_file as $line) {
582 b8f22f61 Stephen Beaver
		if (preg_match('/^(\S*)\s(.*)$/', $line, $matches)) {
583
			$dn_cc[$matches[1]] = $matches[1];
584
		}
585
	}
586 b49f31d0 Sjon Hortensius
}
587
588 b29c322c Stephen Beaver
if ($act == "new" || (($_POST['save'] == gettext("Save")) && $input_errors)) {
589 b35250d9 NewEraCracker
	$form = new Form();
590
	$form->setAction('system_certmanager.php?act=edit');
591 b49f31d0 Sjon Hortensius
592 b35250d9 NewEraCracker
	if (isset($userid) && $a_user) {
593
		$form->addGlobal(new Form_Input(
594
			'userid',
595
			null,
596
			'hidden',
597
			$userid
598
		));
599
	}
600 b49f31d0 Sjon Hortensius
601 78863416 Phil Davis
	if (isset($id) && $a_cert[$id]) {
602 b49f31d0 Sjon Hortensius
		$form->addGlobal(new Form_Input(
603
			'id',
604
			null,
605
			'hidden',
606
			$id
607
		));
608 64cc39d3 Matthew Grooms
	}
609 b49f31d0 Sjon Hortensius
610 b35250d9 NewEraCracker
	$section = new Form_Section('Add a New Certificate');
611
612
	if (!isset($id)) {
613
		$section->addInput(new Form_Select(
614
			'method',
615 51685157 Phil Davis
			'*Method',
616 b35250d9 NewEraCracker
			$pconfig['method'],
617
			$cert_methods
618
		))->toggles();
619
	}
620
621 b49f31d0 Sjon Hortensius
	$section->addInput(new Form_Input(
622
		'descr',
623 51685157 Phil Davis
		'*Descriptive name',
624 b49f31d0 Sjon Hortensius
		'text',
625 b35250d9 NewEraCracker
		($a_user && empty($pconfig['descr'])) ? $a_user[$userid]['name'] : $pconfig['descr']
626
	))->addClass('toggle-existing');
627 b49f31d0 Sjon Hortensius
628 b35250d9 NewEraCracker
	$form->add($section);
629
	$section = new Form_Section('Import Certificate');
630
	$section->addClass('toggle-import collapse');
631 b49f31d0 Sjon Hortensius
632
	$section->addInput(new Form_Textarea(
633
		'cert',
634 51685157 Phil Davis
		'*Certificate data',
635 78863416 Phil Davis
		$pconfig['cert']
636 b35250d9 NewEraCracker
	))->setHelp('Paste a certificate in X.509 PEM format here.');
637
638
	$section->addInput(new Form_Textarea(
639
		'key',
640 51685157 Phil Davis
		'*Private key data',
641 b35250d9 NewEraCracker
		$pconfig['key']
642
	))->setHelp('Paste a private key in X.509 PEM format here.');
643 b49f31d0 Sjon Hortensius
644
	$form->add($section);
645 b35250d9 NewEraCracker
	$section = new Form_Section('Internal Certificate');
646
	$section->addClass('toggle-internal collapse');
647
648
	if (!$internal_ca_count) {
649
		$section->addInput(new Form_StaticText(
650 51685157 Phil Davis
			'*Certificate authority',
651 73ff9530 Stephen Beaver
			gettext('No internal Certificate Authorities have been defined. ').
652
			gettext('An internal CA must be defined in order to create an internal certificate. ').
653
			'<a href="system_camanager.php?act=new&amp;method=internal"> '. gettext("Create") .'</a>'.
654
			gettext(' an internal CA.')
655 b35250d9 NewEraCracker
		));
656
	} else {
657
		$allCas = array();
658
		foreach ($a_ca as $ca) {
659
			if (!$ca['prv']) {
660
				continue;
661
			}
662 b49f31d0 Sjon Hortensius
663 b35250d9 NewEraCracker
			$allCas[ $ca['refid'] ] = $ca['descr'];
664
		}
665 64cc39d3 Matthew Grooms
666 b35250d9 NewEraCracker
		$section->addInput(new Form_Select(
667
			'caref',
668 51685157 Phil Davis
			'*Certificate authority',
669 b35250d9 NewEraCracker
			$pconfig['caref'],
670
			$allCas
671
		));
672
	}
673 64cc39d3 Matthew Grooms
674 b35250d9 NewEraCracker
	$section->addInput(new Form_Select(
675
		'keylen',
676 51685157 Phil Davis
		'*Key length',
677 b35250d9 NewEraCracker
		$pconfig['keylen'],
678
		array_combine($cert_keylens, $cert_keylens)
679 b49f31d0 Sjon Hortensius
	));
680 64cc39d3 Matthew Grooms
681 b35250d9 NewEraCracker
	$section->addInput(new Form_Select(
682
		'digest_alg',
683 51685157 Phil Davis
		'*Digest Algorithm',
684 b35250d9 NewEraCracker
		$pconfig['digest_alg'],
685
		array_combine($openssl_digest_algs, $openssl_digest_algs)
686
	))->setHelp('NOTE: It is recommended to use an algorithm stronger than '.
687
		'SHA1 when possible.');
688 b49f31d0 Sjon Hortensius
689
	$section->addInput(new Form_Select(
690 b35250d9 NewEraCracker
		'type',
691 51685157 Phil Davis
		'*Certificate Type',
692 b35250d9 NewEraCracker
		$pconfig['type'],
693
		$cert_types
694
	))->setHelp('Type of certificate to generate. Used for placing '.
695
		'restrictions on the usage of the generated certificate.');
696 b49f31d0 Sjon Hortensius
697 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
698
		'lifetime',
699 51685157 Phil Davis
		'*Lifetime (days)',
700 b35250d9 NewEraCracker
		'number',
701
		$pconfig['lifetime']
702
	));
703 b49f31d0 Sjon Hortensius
704
	$section->addInput(new Form_Select(
705 b35250d9 NewEraCracker
		'dn_country',
706 51685157 Phil Davis
		'*Country Code',
707 b35250d9 NewEraCracker
		$pconfig['dn_country'],
708
		$dn_cc
709 b49f31d0 Sjon Hortensius
	));
710
711 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
712
		'dn_state',
713 51685157 Phil Davis
		'*State or Province',
714 b35250d9 NewEraCracker
		'text',
715
		$pconfig['dn_state'],
716
		['placeholder' => 'e.g. Texas']
717 b49f31d0 Sjon Hortensius
	));
718
719 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
720
		'dn_city',
721 51685157 Phil Davis
		'*City',
722 b35250d9 NewEraCracker
		'text',
723
		$pconfig['dn_city'],
724
		['placeholder' => 'e.g. Austin']
725
	));
726
727
	$section->addInput(new Form_Input(
728
		'dn_organization',
729 51685157 Phil Davis
		'*Organization',
730 b35250d9 NewEraCracker
		'text',
731
		$pconfig['dn_organization'],
732 b8332deb jim-p
		['placeholder' => 'e.g. My Company Inc']
733
	));
734
735
	$section->addInput(new Form_Input(
736
		'dn_organizationalunit',
737
		'Organizational Unit',
738
		'text',
739
		$pconfig['dn_organizationalunit'],
740
		['placeholder' => 'e.g. My Department Name (optional)']
741 b35250d9 NewEraCracker
	));
742
743
	$section->addInput(new Form_Input(
744
		'dn_email',
745 51685157 Phil Davis
		'*Email Address',
746 b35250d9 NewEraCracker
		'text',
747
		$pconfig['dn_email'],
748
		['placeholder' => 'e.g. admin@mycompany.com']
749
	));
750
751
	$section->addInput(new Form_Input(
752
		'dn_commonname',
753 51685157 Phil Davis
		'*Common Name',
754 b35250d9 NewEraCracker
		'text',
755
		$pconfig['dn_commonname'],
756
		['placeholder' => 'e.g. www.example.com']
757
	));
758
759
	if (empty($pconfig['altnames']['item'])) {
760
		$pconfig['altnames']['item'] = array(
761
			array('type' => null, 'value' => null)
762
		);
763 64cc39d3 Matthew Grooms
	}
764 b49f31d0 Sjon Hortensius
765 b35250d9 NewEraCracker
	$counter = 0;
766
	$numrows = count($pconfig['altnames']['item']) - 1;
767
768
	foreach ($pconfig['altnames']['item'] as $item) {
769
770
		$group = new Form_Group($counter == 0 ? 'Alternative Names':'');
771
772
		$group->add(new Form_Select(
773
			'altname_type' . $counter,
774
			'Type',
775
			$item['type'],
776
			array(
777
				'DNS' => gettext('FQDN or Hostname'),
778
				'IP' => gettext('IP address'),
779
				'URI' => gettext('URI'),
780
				'email' => gettext('email address'),
781
			)
782
		))->setHelp(($counter == $numrows) ? 'Type':null);
783
784
		$group->add(new Form_Input(
785
			'altname_value' . $counter,
786
			null,
787
			'text',
788
			$item['value']
789
		))->setHelp(($counter == $numrows) ? 'Value':null);
790
791
		$group->add(new Form_Button(
792
			'deleterow' . $counter,
793 faab522f Renato Botelho
			'Delete',
794 b35250d9 NewEraCracker
			null,
795
			'fa-trash'
796
		))->addClass('btn-warning');
797
798
		$group->addClass('repeatable');
799
800
		$section->add($group);
801
802
		$counter++;
803 64cc39d3 Matthew Grooms
	}
804 b49f31d0 Sjon Hortensius
805 b35250d9 NewEraCracker
	$section->addInput(new Form_Button(
806
		'addrow',
807 faab522f Renato Botelho
		'Add',
808 b35250d9 NewEraCracker
		null,
809
		'fa-plus'
810
	))->addClass('btn-success');
811
812
	$form->add($section);
813
	$section = new Form_Section('External Signing Request');
814
	$section->addClass('toggle-external collapse');
815
816 b49f31d0 Sjon Hortensius
	$section->addInput(new Form_Select(
817 b35250d9 NewEraCracker
		'csr_keylen',
818 51685157 Phil Davis
		'*Key length',
819 b35250d9 NewEraCracker
		$pconfig['csr_keylen'],
820
		array_combine($cert_keylens, $cert_keylens)
821 b49f31d0 Sjon Hortensius
	));
822 64cc39d3 Matthew Grooms
823 b35250d9 NewEraCracker
	$section->addInput(new Form_Select(
824
		'csr_digest_alg',
825 51685157 Phil Davis
		'*Digest Algorithm',
826 b35250d9 NewEraCracker
		$pconfig['csr_digest_alg'],
827
		array_combine($openssl_digest_algs, $openssl_digest_algs)
828
	))->setHelp('NOTE: It is recommended to use an algorithm stronger than '.
829
		'SHA1 when possible');
830 b49f31d0 Sjon Hortensius
831 b35250d9 NewEraCracker
	$section->addInput(new Form_Select(
832
		'csr_dn_country',
833 51685157 Phil Davis
		'*Country Code',
834 b35250d9 NewEraCracker
		$pconfig['csr_dn_country'],
835
		$dn_cc
836
	));
837 bf9d50e8 Stephen Beaver
838 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
839
		'csr_dn_state',
840 51685157 Phil Davis
		'*State or Province',
841 b35250d9 NewEraCracker
		'text',
842
		$pconfig['csr_dn_state'],
843
		['placeholder' => 'e.g. Texas']
844
	));
845 bf9d50e8 Stephen Beaver
846 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
847
		'csr_dn_city',
848 51685157 Phil Davis
		'*City',
849 b35250d9 NewEraCracker
		'text',
850
		$pconfig['csr_dn_city'],
851
		['placeholder' => 'e.g. Austin']
852
	));
853 bf9d50e8 Stephen Beaver
854 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
855
		'csr_dn_organization',
856 51685157 Phil Davis
		'*Organization',
857 b35250d9 NewEraCracker
		'text',
858
		$pconfig['csr_dn_organization'],
859 b8332deb jim-p
		['placeholder' => 'e.g. My Company Inc']
860
	));
861
862
	$section->addInput(new Form_Input(
863
		'csr_dn_organizationalunit',
864
		'Organizational Unit',
865
		'text',
866
		$pconfig['csr_dn_organizationalunit'],
867
		['placeholder' => 'e.g. My Department Name (optional)']
868 b35250d9 NewEraCracker
	));
869 b49f31d0 Sjon Hortensius
870 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
871
		'csr_dn_email',
872 51685157 Phil Davis
		'*Email Address',
873 b49f31d0 Sjon Hortensius
		'text',
874 b35250d9 NewEraCracker
		$pconfig['csr_dn_email'],
875
		['placeholder' => 'e.g. admin@mycompany.com']
876
	));
877 bf9d50e8 Stephen Beaver
878 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
879
		'csr_dn_commonname',
880 51685157 Phil Davis
		'*Common Name',
881 b35250d9 NewEraCracker
		'text',
882
		$pconfig['csr_dn_commonname'],
883
		['placeholder' => 'e.g. internal-ca']
884
	));
885 bf9d50e8 Stephen Beaver
886 b35250d9 NewEraCracker
	$form->add($section);
887
	$section = new Form_Section('Choose an Existing Certificate');
888
	$section->addClass('toggle-existing collapse');
889 b49f31d0 Sjon Hortensius
890 b35250d9 NewEraCracker
	$existCerts = array();
891 bf9d50e8 Stephen Beaver
892 b35250d9 NewEraCracker
	foreach ($config['cert'] as $cert)	{
893
		if (is_array($config['system']['user'][$userid]['cert'])) { // Could be MIA!
894
			if (isset($userid) && in_array($cert['refid'], $config['system']['user'][$userid]['cert'])) {
895
				continue;
896
			}
897
		}
898 b49f31d0 Sjon Hortensius
899 b35250d9 NewEraCracker
		$ca = lookup_ca($cert['caref']);
900
		if ($ca) {
901
			$cert['descr'] .= " (CA: {$ca['descr']})";
902 78863416 Phil Davis
		}
903 b49f31d0 Sjon Hortensius
904 b35250d9 NewEraCracker
		if (cert_in_use($cert['refid'])) {
905 8dbde62f Steve Beaver
			$cert['descr'] .= " (In Use)";
906 b35250d9 NewEraCracker
		}
907
		if (is_cert_revoked($cert)) {
908 8dbde62f Steve Beaver
			$cert['descr'] .= " (Revoked)";
909 b35250d9 NewEraCracker
		}
910 b49f31d0 Sjon Hortensius
911 b35250d9 NewEraCracker
		$existCerts[ $cert['refid'] ] = $cert['descr'];
912 78863416 Phil Davis
	}
913 b49f31d0 Sjon Hortensius
914 b35250d9 NewEraCracker
	$section->addInput(new Form_Select(
915
		'certref',
916 51685157 Phil Davis
		'*Existing Certificates',
917 b35250d9 NewEraCracker
		$pconfig['certref'],
918
		$existCerts
919
	));
920 b49f31d0 Sjon Hortensius
921 b35250d9 NewEraCracker
	$form->add($section);
922
	print $form;
923 64cc39d3 Matthew Grooms
924 b29c322c Stephen Beaver
} else if ($act == "csr" || (($_POST['save'] == gettext("Update")) && $input_errors)) {
925 8f58b51b jim-p
	$form = new Form(false);
926 308f0665 NewEraCracker
	$form->setAction('system_certmanager.php?act=csr');
927 b29c322c Stephen Beaver
928 5f88f964 k-paulius
	$section = new Form_Section("Complete Signing Request for " . $pconfig['descr']);
929 b29c322c Stephen Beaver
930 ba5c55e9 Stephen Beaver
	$section->addInput(new Form_Input(
931
		'descr',
932 51685157 Phil Davis
		'*Descriptive name',
933 ba5c55e9 Stephen Beaver
		'text',
934
		$pconfig['descr']
935
	));
936
937 b29c322c Stephen Beaver
	$section->addInput(new Form_Textarea(
938
		'csr',
939
		'Signing request data',
940
		$pconfig['csr']
941
	))->setReadonly()
942 af28e231 Stephen Beaver
	  ->setWidth(7)
943 73ff9530 Stephen Beaver
	  ->setHelp('Copy the certificate signing data from here and forward it to a certificate authority for signing.');
944 b29c322c Stephen Beaver
945
	$section->addInput(new Form_Textarea(
946
		'cert',
947 51685157 Phil Davis
		'*Final certificate data',
948 b29c322c Stephen Beaver
		$pconfig['cert']
949 af28e231 Stephen Beaver
	))->setWidth(7)
950 73ff9530 Stephen Beaver
	  ->setHelp('Paste the certificate received from the certificate authority here.');
951 b29c322c Stephen Beaver
952
	 if (isset($id) && $a_cert[$id]) {
953
		 $section->addInput(new Form_Input(
954
			'id',
955
			null,
956
			'hidden',
957
			$id
958
		 ));
959
960
		 $section->addInput(new Form_Input(
961
			'act',
962
			null,
963
			'hidden',
964
			'csr'
965
		 ));
966
	 }
967
968
	$form->add($section);
969 8f58b51b jim-p
970
	$form->addGlobal(new Form_Button(
971 141d8913 jim-p
		'save',
972 faab522f Renato Botelho
		'Update',
973 8f58b51b jim-p
		null,
974
		'fa-save'
975
	))->addClass('btn-primary');
976
977 b29c322c Stephen Beaver
	print($form);
978
} else {
979
?>
980 060ed238 Stephen Beaver
<div class="panel panel-default">
981
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Certificates')?></h2></div>
982
	<div class="panel-body">
983
		<div class="table-responsive">
984
		<table class="table table-striped table-hover">
985
			<thead>
986
				<tr>
987
					<th><?=gettext("Name")?></th>
988
					<th><?=gettext("Issuer")?></th>
989
					<th><?=gettext("Distinguished Name")?></th>
990
					<th><?=gettext("In Use")?></th>
991 4db1f211 Stephen Beaver
992 060ed238 Stephen Beaver
					<th class="col-sm-2"><?=gettext("Actions")?></th>
993
				</tr>
994
			</thead>
995
			<tbody>
996 b29c322c Stephen Beaver
<?php
997 4db1f211 Stephen Beaver
998
$pluginparams = array();
999
$pluginparams['type'] = 'certificates';
1000
$pluginparams['event'] = 'used_certificates';
1001
$certificates_used_by_packages = pkg_call_plugins('plugin_certificates', $pluginparams);
1002
$i = 0;
1003 78863416 Phil Davis
foreach ($a_cert as $i => $cert):
1004 b29c322c Stephen Beaver
	$name = htmlspecialchars($cert['descr']);
1005
1006
	if ($cert['crt']) {
1007
		$subj = cert_get_subject($cert['crt']);
1008
		$issuer = cert_get_issuer($cert['crt']);
1009
		$purpose = cert_get_purpose($cert['crt']);
1010
		list($startdate, $enddate) = cert_get_dates($cert['crt']);
1011
1012 78863416 Phil Davis
		if ($subj == $issuer) {
1013 b29c322c Stephen Beaver
			$caname = '<i>'. gettext("self-signed") .'</i>';
1014 78863416 Phil Davis
		} else {
1015 b29c322c Stephen Beaver
			$caname = '<i>'. gettext("external").'</i>';
1016 78863416 Phil Davis
		}
1017 b29c322c Stephen Beaver
1018
		$subj = htmlspecialchars($subj);
1019 d414b7eb PiBa-NL
	} else {
1020
		$subj = "";
1021
		$issuer = "";
1022
		$purpose = "";
1023
		$startdate = "";
1024
		$enddate = "";
1025
		$caname = "<em>" . gettext("private key only") . "</em>";
1026 b29c322c Stephen Beaver
	}
1027
1028
	if ($cert['csr']) {
1029
		$subj = htmlspecialchars(csr_get_subject($cert['csr']));
1030
		$caname = "<em>" . gettext("external - signature pending") . "</em>";
1031
	}
1032
1033
	$ca = lookup_ca($cert['caref']);
1034 78863416 Phil Davis
	if ($ca) {
1035 b29c322c Stephen Beaver
		$caname = $ca['descr'];
1036 78863416 Phil Davis
	}
1037 b29c322c Stephen Beaver
?>
1038 060ed238 Stephen Beaver
				<tr>
1039
					<td>
1040
						<?=$name?><br />
1041
						<?php if ($cert['type']): ?>
1042
							<i><?=$cert_types[$cert['type']]?></i><br />
1043
						<?php endif?>
1044
						<?php if (is_array($purpose)): ?>
1045 762faef5 Phil Davis
							CA: <b><?=$purpose['ca']?></b>, <?=gettext("Server")?>: <b><?=$purpose['server']?></b>
1046 060ed238 Stephen Beaver
						<?php endif?>
1047
					</td>
1048
					<td><?=$caname?></td>
1049
					<td>
1050
						<?=$subj?>
1051 d414b7eb PiBa-NL
						<?php if (!empty($startdate) || !empty($enddate)): ?>
1052 060ed238 Stephen Beaver
						<br />
1053
						<small>
1054
							<?=gettext("Valid From")?>: <b><?=$startdate ?></b><br /><?=gettext("Valid Until")?>: <b><?=$enddate ?></b>
1055
						</small>
1056
						<?php endif?>
1057
					</td>
1058
					<td>
1059
						<?php if (is_cert_revoked($cert)): ?>
1060 762faef5 Phil Davis
							<i><?=gettext("Revoked")?></i>
1061 060ed238 Stephen Beaver
						<?php endif?>
1062
						<?php if (is_webgui_cert($cert['refid'])): ?>
1063 762faef5 Phil Davis
							<?=gettext("webConfigurator")?>
1064 060ed238 Stephen Beaver
						<?php endif?>
1065
						<?php if (is_user_cert($cert['refid'])): ?>
1066 762faef5 Phil Davis
							<?=gettext("User Cert")?>
1067 060ed238 Stephen Beaver
						<?php endif?>
1068
						<?php if (is_openvpn_server_cert($cert['refid'])): ?>
1069 762faef5 Phil Davis
							<?=gettext("OpenVPN Server")?>
1070 060ed238 Stephen Beaver
						<?php endif?>
1071
						<?php if (is_openvpn_client_cert($cert['refid'])): ?>
1072 762faef5 Phil Davis
							<?=gettext("OpenVPN Client")?>
1073 060ed238 Stephen Beaver
						<?php endif?>
1074
						<?php if (is_ipsec_cert($cert['refid'])): ?>
1075 762faef5 Phil Davis
							<?=gettext("IPsec Tunnel")?>
1076 060ed238 Stephen Beaver
						<?php endif?>
1077
						<?php if (is_captiveportal_cert($cert['refid'])): ?>
1078 762faef5 Phil Davis
							<?=gettext("Captive Portal")?>
1079 060ed238 Stephen Beaver
						<?php endif?>
1080 4db1f211 Stephen Beaver
<?php
1081
							$refid = $cert['refid'];
1082
							if (is_array($certificates_used_by_packages)) {
1083
								foreach ($certificates_used_by_packages as $name => $package) {
1084
									if (isset($package['certificatelist'][$refid])) {
1085
										$hint = "" ;
1086
										if (is_array($package['certificatelist'][$refid])) {
1087
											foreach ($package['certificatelist'][$refid] as $cert_used) {
1088
												$hint = $hint . $cert_used['usedby']."\n";
1089
											}
1090
										}
1091
										$count = count($package['certificatelist'][$refid]);
1092
										echo "<div title='".htmlspecialchars($hint)."'>";
1093
										echo htmlspecialchars($package['pkgname'])." ($count)<br />";
1094
										echo "</div>";
1095
									}
1096
								}
1097
							}
1098
?>
1099 060ed238 Stephen Beaver
					</td>
1100
					<td>
1101
						<?php if (!$cert['csr']): ?>
1102 c2dbd6d7 derelict-pf
							<a href="system_certmanager.php?act=exp&amp;id=<?=$i?>" class="fa fa-certificate" title="<?=gettext("Export Certificate")?>"></a>
1103 060ed238 Stephen Beaver
							<a href="system_certmanager.php?act=key&amp;id=<?=$i?>" class="fa fa-key" title="<?=gettext("Export Key")?>"></a>
1104 c2dbd6d7 derelict-pf
							<a href="system_certmanager.php?act=p12&amp;id=<?=$i?>" class="fa fa-archive" title="<?=gettext("Export P12")?>"></a>
1105 060ed238 Stephen Beaver
						<?php else: ?>
1106
							<a href="system_certmanager.php?act=csr&amp;id=<?=$i?>" class="fa fa-pencil" title="<?=gettext("Update CSR")?>"></a>
1107
							<a href="system_certmanager.php?act=req&amp;id=<?=$i?>" class="fa fa-sign-in" title="<?=gettext("Export Request")?>"></a>
1108
							<a href="system_certmanager.php?act=key&amp;id=<?=$i?>" class="fa fa-key" title="<?=gettext("Export Key")?>"></a>
1109
						<?php endif?>
1110
						<?php if (!cert_in_use($cert['refid'])): ?>
1111 b94f1830 Phil Davis
							<a href="system_certmanager.php?act=del&amp;id=<?=$i?>" class="fa fa-trash" title="<?=gettext("Delete Certificate")?>"></a>
1112 060ed238 Stephen Beaver
						<?php endif?>
1113
					</td>
1114
				</tr>
1115 4db1f211 Stephen Beaver
<?php
1116
	$i++; 
1117
	endforeach; ?>
1118 060ed238 Stephen Beaver
			</tbody>
1119
		</table>
1120
		</div>
1121
	</div>
1122 b29c322c Stephen Beaver
</div>
1123
1124
<nav class="action-buttons">
1125
	<a href="?act=new" class="btn btn-success btn-sm">
1126
		<i class="fa fa-plus icon-embed-btn"></i>
1127
		<?=gettext("Add")?>
1128
	</a>
1129
</nav>
1130 e9258698 NewEraCracker
<?php
1131 b29c322c Stephen Beaver
	include("foot.inc");
1132
	exit;
1133
}
1134
1135
1136 51583438 Stephen Beaver
?>
1137 8fd9052f Colin Fleming
<script type="text/javascript">
1138 51583438 Stephen Beaver
//<![CDATA[
1139 78863416 Phil Davis
events.push(function() {
1140 bf9d50e8 Stephen Beaver
1141 51583438 Stephen Beaver
<?php if ($internal_ca_count): ?>
1142
	function internalca_change() {
1143
1144
		caref = $('#caref').val();
1145
1146
		switch (caref) {
1147
<?php
1148
			foreach ($a_ca as $ca):
1149
				if (!$ca['prv']) {
1150
					continue;
1151
				}
1152
1153
				$subject = cert_get_subject_array($ca['crt']);
1154
1155
?>
1156
				case "<?=$ca['refid'];?>":
1157
					$('#dn_country').val("<?=$subject[0]['v'];?>");
1158
					$('#dn_state').val("<?=$subject[1]['v'];?>");
1159
					$('#dn_city').val("<?=$subject[2]['v'];?>");
1160
					$('#dn_organization').val("<?=$subject[3]['v'];?>");
1161
					$('#dn_email').val("<?=$subject[4]['v'];?>");
1162 b8332deb jim-p
					$('#dn_organizationalunit').val("<?=$subject[6]['v'];?>");
1163 51583438 Stephen Beaver
					break;
1164
<?php
1165
			endforeach;
1166
?>
1167
		}
1168
	}
1169
1170 eef93144 Jared Dillard
	// ---------- Click checkbox handlers ---------------------------------------------------------
1171 f74457df Stephen Beaver
1172 51583438 Stephen Beaver
	$('#caref').on('change', function() {
1173
		internalca_change();
1174
	});
1175
1176 eef93144 Jared Dillard
	// ---------- On initial page load ------------------------------------------------------------
1177
1178 51583438 Stephen Beaver
	internalca_change();
1179
1180 0bc61baa Stephen Beaver
	// Suppress "Delete row" button if there are fewer than two rows
1181
	checkLastRow();
1182
1183 51583438 Stephen Beaver
<?php endif; ?>
1184
1185
1186
});
1187
//]]>
1188
</script>
1189
<?php
1190 0edcccc3 Daniel Seebald
include('foot.inc');