Project

General

Profile

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