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 813c6673 NOYB
							array_push($input_errors, "An e-mail address must be provided 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 813c6673 NOYB
			gettext('No internal Certificate Authorities have been defined. ').
655
			gettext('An internal CA must be defined in order to create an internal certificate. ').
656
			'<a href="system_camanager.php?act=new&amp;method=internal"> '. gettext("Create") .'</a>'.
657
			gettext(' an internal CA.')
658 b35250d9 NewEraCracker
		));
659
	} else {
660
		$allCas = array();
661
		foreach ($a_ca as $ca) {
662
			if (!$ca['prv']) {
663
				continue;
664
			}
665 b49f31d0 Sjon Hortensius
666 b35250d9 NewEraCracker
			$allCas[ $ca['refid'] ] = $ca['descr'];
667
		}
668 64cc39d3 Matthew Grooms
669 b35250d9 NewEraCracker
		$section->addInput(new Form_Select(
670
			'caref',
671
			'Certificate authority',
672
			$pconfig['caref'],
673
			$allCas
674
		));
675
	}
676 64cc39d3 Matthew Grooms
677 b35250d9 NewEraCracker
	$section->addInput(new Form_Select(
678
		'keylen',
679
		'Key length',
680
		$pconfig['keylen'],
681
		array_combine($cert_keylens, $cert_keylens)
682 b49f31d0 Sjon Hortensius
	));
683 64cc39d3 Matthew Grooms
684 b35250d9 NewEraCracker
	$section->addInput(new Form_Select(
685
		'digest_alg',
686
		'Digest Algorithm',
687
		$pconfig['digest_alg'],
688
		array_combine($openssl_digest_algs, $openssl_digest_algs)
689
	))->setHelp('NOTE: It is recommended to use an algorithm stronger than '.
690
		'SHA1 when possible.');
691 b49f31d0 Sjon Hortensius
692
	$section->addInput(new Form_Select(
693 b35250d9 NewEraCracker
		'type',
694
		'Certificate Type',
695
		$pconfig['type'],
696
		$cert_types
697
	))->setHelp('Type of certificate to generate. Used for placing '.
698
		'restrictions on the usage of the generated certificate.');
699 b49f31d0 Sjon Hortensius
700 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
701
		'lifetime',
702
		'Lifetime (days)',
703
		'number',
704
		$pconfig['lifetime']
705
	));
706 b49f31d0 Sjon Hortensius
707
	$section->addInput(new Form_Select(
708 b35250d9 NewEraCracker
		'dn_country',
709
		'Country Code',
710
		$pconfig['dn_country'],
711
		$dn_cc
712 b49f31d0 Sjon Hortensius
	));
713
714 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
715
		'dn_state',
716
		'State or Province',
717
		'text',
718
		$pconfig['dn_state'],
719
		['placeholder' => 'e.g. Texas']
720 b49f31d0 Sjon Hortensius
	));
721
722 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
723
		'dn_city',
724
		'City',
725
		'text',
726
		$pconfig['dn_city'],
727
		['placeholder' => 'e.g. Austin']
728
	));
729
730
	$section->addInput(new Form_Input(
731
		'dn_organization',
732
		'Organization',
733
		'text',
734
		$pconfig['dn_organization'],
735
		['placeholder' => 'e.g. My Company Inc.']
736
	));
737
738
	$section->addInput(new Form_Input(
739
		'dn_email',
740
		'Email Address',
741
		'text',
742
		$pconfig['dn_email'],
743
		['placeholder' => 'e.g. admin@mycompany.com']
744
	));
745
746
	$section->addInput(new Form_Input(
747
		'dn_commonname',
748
		'Common Name',
749
		'text',
750
		$pconfig['dn_commonname'],
751
		['placeholder' => 'e.g. www.example.com']
752
	));
753
754
	if (empty($pconfig['altnames']['item'])) {
755
		$pconfig['altnames']['item'] = array(
756
			array('type' => null, 'value' => null)
757
		);
758 64cc39d3 Matthew Grooms
	}
759 b49f31d0 Sjon Hortensius
760 b35250d9 NewEraCracker
	$counter = 0;
761
	$numrows = count($pconfig['altnames']['item']) - 1;
762
763
	foreach ($pconfig['altnames']['item'] as $item) {
764
765
		$group = new Form_Group($counter == 0 ? 'Alternative Names':'');
766
767
		$group->add(new Form_Select(
768
			'altname_type' . $counter,
769
			'Type',
770
			$item['type'],
771
			array(
772
				'DNS' => gettext('FQDN or Hostname'),
773
				'IP' => gettext('IP address'),
774
				'URI' => gettext('URI'),
775
				'email' => gettext('email address'),
776
			)
777
		))->setHelp(($counter == $numrows) ? 'Type':null);
778
779
		$group->add(new Form_Input(
780
			'altname_value' . $counter,
781
			null,
782
			'text',
783
			$item['value']
784
		))->setHelp(($counter == $numrows) ? 'Value':null);
785
786
		$group->add(new Form_Button(
787
			'deleterow' . $counter,
788 faab522f Renato Botelho
			'Delete',
789 b35250d9 NewEraCracker
			null,
790
			'fa-trash'
791
		))->addClass('btn-warning');
792
793
		$group->addClass('repeatable');
794
795
		$section->add($group);
796
797
		$counter++;
798 64cc39d3 Matthew Grooms
	}
799 b49f31d0 Sjon Hortensius
800 b35250d9 NewEraCracker
	$section->addInput(new Form_Button(
801
		'addrow',
802 faab522f Renato Botelho
		'Add',
803 b35250d9 NewEraCracker
		null,
804
		'fa-plus'
805
	))->addClass('btn-success');
806
807
	$form->add($section);
808
	$section = new Form_Section('External Signing Request');
809
	$section->addClass('toggle-external collapse');
810
811 b49f31d0 Sjon Hortensius
	$section->addInput(new Form_Select(
812 b35250d9 NewEraCracker
		'csr_keylen',
813
		'Key length',
814
		$pconfig['csr_keylen'],
815
		array_combine($cert_keylens, $cert_keylens)
816 b49f31d0 Sjon Hortensius
	));
817 64cc39d3 Matthew Grooms
818 b35250d9 NewEraCracker
	$section->addInput(new Form_Select(
819
		'csr_digest_alg',
820
		'Digest Algorithm',
821
		$pconfig['csr_digest_alg'],
822
		array_combine($openssl_digest_algs, $openssl_digest_algs)
823
	))->setHelp('NOTE: It is recommended to use an algorithm stronger than '.
824
		'SHA1 when possible');
825 b49f31d0 Sjon Hortensius
826 b35250d9 NewEraCracker
	$section->addInput(new Form_Select(
827
		'csr_dn_country',
828
		'Country Code',
829
		$pconfig['csr_dn_country'],
830
		$dn_cc
831
	));
832 bf9d50e8 Stephen Beaver
833 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
834
		'csr_dn_state',
835
		'State or Province',
836
		'text',
837
		$pconfig['csr_dn_state'],
838
		['placeholder' => 'e.g. Texas']
839
	));
840 bf9d50e8 Stephen Beaver
841 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
842
		'csr_dn_city',
843
		'City',
844
		'text',
845
		$pconfig['csr_dn_city'],
846
		['placeholder' => 'e.g. Austin']
847
	));
848 bf9d50e8 Stephen Beaver
849 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
850
		'csr_dn_organization',
851
		'Organization',
852
		'text',
853
		$pconfig['csr_dn_organization'],
854
		['placeholder' => 'e.g. My Company Inc.']
855
	));
856 b49f31d0 Sjon Hortensius
857 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
858
		'csr_dn_email',
859
		'Email Address',
860 b49f31d0 Sjon Hortensius
		'text',
861 b35250d9 NewEraCracker
		$pconfig['csr_dn_email'],
862
		['placeholder' => 'e.g. admin@mycompany.com']
863
	));
864 bf9d50e8 Stephen Beaver
865 b35250d9 NewEraCracker
	$section->addInput(new Form_Input(
866
		'csr_dn_commonname',
867
		'Common Name',
868
		'text',
869
		$pconfig['csr_dn_commonname'],
870
		['placeholder' => 'e.g. internal-ca']
871
	));
872 bf9d50e8 Stephen Beaver
873 b35250d9 NewEraCracker
	$form->add($section);
874
	$section = new Form_Section('Choose an Existing Certificate');
875
	$section->addClass('toggle-existing collapse');
876 b49f31d0 Sjon Hortensius
877 b35250d9 NewEraCracker
	$existCerts = array();
878 bf9d50e8 Stephen Beaver
879 b35250d9 NewEraCracker
	foreach ($config['cert'] as $cert)	{
880
		if (is_array($config['system']['user'][$userid]['cert'])) { // Could be MIA!
881
			if (isset($userid) && in_array($cert['refid'], $config['system']['user'][$userid]['cert'])) {
882
				continue;
883
			}
884
		}
885 b49f31d0 Sjon Hortensius
886 b35250d9 NewEraCracker
		$ca = lookup_ca($cert['caref']);
887
		if ($ca) {
888
			$cert['descr'] .= " (CA: {$ca['descr']})";
889 78863416 Phil Davis
		}
890 b49f31d0 Sjon Hortensius
891 b35250d9 NewEraCracker
		if (cert_in_use($cert['refid'])) {
892
			$cert['descr'] .= " <i>In Use</i>";
893
		}
894
		if (is_cert_revoked($cert)) {
895
			$cert['descr'] .= " <b>Revoked</b>";
896
		}
897 b49f31d0 Sjon Hortensius
898 b35250d9 NewEraCracker
		$existCerts[ $cert['refid'] ] = $cert['descr'];
899 78863416 Phil Davis
	}
900 b49f31d0 Sjon Hortensius
901 b35250d9 NewEraCracker
	$section->addInput(new Form_Select(
902
		'certref',
903
		'Existing Certificates',
904
		$pconfig['certref'],
905
		$existCerts
906
	));
907 b49f31d0 Sjon Hortensius
908 b35250d9 NewEraCracker
	$form->add($section);
909
	print $form;
910 64cc39d3 Matthew Grooms
911 b29c322c Stephen Beaver
} else if ($act == "csr" || (($_POST['save'] == gettext("Update")) && $input_errors)) {
912 8f58b51b jim-p
	$form = new Form(false);
913 308f0665 NewEraCracker
	$form->setAction('system_certmanager.php?act=csr');
914 b29c322c Stephen Beaver
915 5f88f964 k-paulius
	$section = new Form_Section("Complete Signing Request for " . $pconfig['descr']);
916 b29c322c Stephen Beaver
917 ba5c55e9 Stephen Beaver
	$section->addInput(new Form_Input(
918
		'descr',
919
		'Descriptive name',
920
		'text',
921
		$pconfig['descr']
922
	));
923
924 b29c322c Stephen Beaver
	$section->addInput(new Form_Textarea(
925
		'csr',
926
		'Signing request data',
927
		$pconfig['csr']
928
	))->setReadonly()
929 af28e231 Stephen Beaver
	  ->setWidth(7)
930 813c6673 NOYB
	  ->setHelp('Copy the certificate signing data from here and forward it to a certificate authority for signing.');
931 b29c322c Stephen Beaver
932
	$section->addInput(new Form_Textarea(
933
		'cert',
934
		'Final certificate data',
935
		$pconfig['cert']
936 af28e231 Stephen Beaver
	))->setWidth(7)
937 813c6673 NOYB
	  ->setHelp('Paste the certificate received from the certificate authority here.');
938 b29c322c Stephen Beaver
939
	 if (isset($id) && $a_cert[$id]) {
940
		 $section->addInput(new Form_Input(
941
			'id',
942
			null,
943
			'hidden',
944
			$id
945
		 ));
946
947
		 $section->addInput(new Form_Input(
948
			'act',
949
			null,
950
			'hidden',
951
			'csr'
952
		 ));
953
	 }
954
955
	$form->add($section);
956 8f58b51b jim-p
957
	$form->addGlobal(new Form_Button(
958 141d8913 jim-p
		'save',
959 faab522f Renato Botelho
		'Update',
960 8f58b51b jim-p
		null,
961
		'fa-save'
962
	))->addClass('btn-primary');
963
964 b29c322c Stephen Beaver
	print($form);
965
} else {
966
?>
967 060ed238 Stephen Beaver
<div class="panel panel-default">
968
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Certificates')?></h2></div>
969
	<div class="panel-body">
970
		<div class="table-responsive">
971
		<table class="table table-striped table-hover">
972
			<thead>
973
				<tr>
974
					<th><?=gettext("Name")?></th>
975
					<th><?=gettext("Issuer")?></th>
976
					<th><?=gettext("Distinguished Name")?></th>
977
					<th><?=gettext("In Use")?></th>
978 4db1f211 Stephen Beaver
979 060ed238 Stephen Beaver
					<th class="col-sm-2"><?=gettext("Actions")?></th>
980
				</tr>
981
			</thead>
982
			<tbody>
983 b29c322c Stephen Beaver
<?php
984 4db1f211 Stephen Beaver
985
$pluginparams = array();
986
$pluginparams['type'] = 'certificates';
987
$pluginparams['event'] = 'used_certificates';
988
$certificates_used_by_packages = pkg_call_plugins('plugin_certificates', $pluginparams);
989
$i = 0;
990 78863416 Phil Davis
foreach ($a_cert as $i => $cert):
991 b29c322c Stephen Beaver
	$name = htmlspecialchars($cert['descr']);
992
993
	if ($cert['crt']) {
994
		$subj = cert_get_subject($cert['crt']);
995
		$issuer = cert_get_issuer($cert['crt']);
996
		$purpose = cert_get_purpose($cert['crt']);
997
		list($startdate, $enddate) = cert_get_dates($cert['crt']);
998
999 78863416 Phil Davis
		if ($subj == $issuer) {
1000 b29c322c Stephen Beaver
			$caname = '<i>'. gettext("self-signed") .'</i>';
1001 78863416 Phil Davis
		} else {
1002 b29c322c Stephen Beaver
			$caname = '<i>'. gettext("external").'</i>';
1003 78863416 Phil Davis
		}
1004 b29c322c Stephen Beaver
1005
		$subj = htmlspecialchars($subj);
1006
	}
1007
1008
	if ($cert['csr']) {
1009
		$subj = htmlspecialchars(csr_get_subject($cert['csr']));
1010
		$caname = "<em>" . gettext("external - signature pending") . "</em>";
1011
	}
1012
1013
	$ca = lookup_ca($cert['caref']);
1014 78863416 Phil Davis
	if ($ca) {
1015 b29c322c Stephen Beaver
		$caname = $ca['descr'];
1016 78863416 Phil Davis
	}
1017 b29c322c Stephen Beaver
?>
1018 060ed238 Stephen Beaver
				<tr>
1019
					<td>
1020
						<?=$name?><br />
1021
						<?php if ($cert['type']): ?>
1022
							<i><?=$cert_types[$cert['type']]?></i><br />
1023
						<?php endif?>
1024
						<?php if (is_array($purpose)): ?>
1025 762faef5 Phil Davis
							CA: <b><?=$purpose['ca']?></b>, <?=gettext("Server")?>: <b><?=$purpose['server']?></b>
1026 060ed238 Stephen Beaver
						<?php endif?>
1027
					</td>
1028
					<td><?=$caname?></td>
1029
					<td>
1030
						<?=$subj?>
1031
						<?php if (!$cert['csr']): ?>
1032
						<br />
1033
						<small>
1034
							<?=gettext("Valid From")?>: <b><?=$startdate ?></b><br /><?=gettext("Valid Until")?>: <b><?=$enddate ?></b>
1035
						</small>
1036
						<?php endif?>
1037
					</td>
1038
					<td>
1039
						<?php if (is_cert_revoked($cert)): ?>
1040 762faef5 Phil Davis
							<i><?=gettext("Revoked")?></i>
1041 060ed238 Stephen Beaver
						<?php endif?>
1042
						<?php if (is_webgui_cert($cert['refid'])): ?>
1043 762faef5 Phil Davis
							<?=gettext("webConfigurator")?>
1044 060ed238 Stephen Beaver
						<?php endif?>
1045
						<?php if (is_user_cert($cert['refid'])): ?>
1046 762faef5 Phil Davis
							<?=gettext("User Cert")?>
1047 060ed238 Stephen Beaver
						<?php endif?>
1048
						<?php if (is_openvpn_server_cert($cert['refid'])): ?>
1049 762faef5 Phil Davis
							<?=gettext("OpenVPN Server")?>
1050 060ed238 Stephen Beaver
						<?php endif?>
1051
						<?php if (is_openvpn_client_cert($cert['refid'])): ?>
1052 762faef5 Phil Davis
							<?=gettext("OpenVPN Client")?>
1053 060ed238 Stephen Beaver
						<?php endif?>
1054
						<?php if (is_ipsec_cert($cert['refid'])): ?>
1055 762faef5 Phil Davis
							<?=gettext("IPsec Tunnel")?>
1056 060ed238 Stephen Beaver
						<?php endif?>
1057
						<?php if (is_captiveportal_cert($cert['refid'])): ?>
1058 762faef5 Phil Davis
							<?=gettext("Captive Portal")?>
1059 060ed238 Stephen Beaver
						<?php endif?>
1060 4db1f211 Stephen Beaver
<?php
1061
							$refid = $cert['refid'];
1062
							if (is_array($certificates_used_by_packages)) {
1063
								foreach ($certificates_used_by_packages as $name => $package) {
1064
									if (isset($package['certificatelist'][$refid])) {
1065
										$hint = "" ;
1066
										if (is_array($package['certificatelist'][$refid])) {
1067
											foreach ($package['certificatelist'][$refid] as $cert_used) {
1068
												$hint = $hint . $cert_used['usedby']."\n";
1069
											}
1070
										}
1071
										$count = count($package['certificatelist'][$refid]);
1072
										echo "<div title='".htmlspecialchars($hint)."'>";
1073
										echo htmlspecialchars($package['pkgname'])." ($count)<br />";
1074
										echo "</div>";
1075
									}
1076
								}
1077
							}
1078
?>
1079 060ed238 Stephen Beaver
					</td>
1080
					<td>
1081
						<?php if (!$cert['csr']): ?>
1082 c2dbd6d7 derelict-pf
							<a href="system_certmanager.php?act=exp&amp;id=<?=$i?>" class="fa fa-certificate" title="<?=gettext("Export Certificate")?>"></a>
1083 060ed238 Stephen Beaver
							<a href="system_certmanager.php?act=key&amp;id=<?=$i?>" class="fa fa-key" title="<?=gettext("Export Key")?>"></a>
1084 c2dbd6d7 derelict-pf
							<a href="system_certmanager.php?act=p12&amp;id=<?=$i?>" class="fa fa-archive" title="<?=gettext("Export P12")?>"></a>
1085 060ed238 Stephen Beaver
						<?php else: ?>
1086
							<a href="system_certmanager.php?act=csr&amp;id=<?=$i?>" class="fa fa-pencil" title="<?=gettext("Update CSR")?>"></a>
1087
							<a href="system_certmanager.php?act=req&amp;id=<?=$i?>" class="fa fa-sign-in" title="<?=gettext("Export Request")?>"></a>
1088
							<a href="system_certmanager.php?act=key&amp;id=<?=$i?>" class="fa fa-key" title="<?=gettext("Export Key")?>"></a>
1089
						<?php endif?>
1090
						<?php if (!cert_in_use($cert['refid'])): ?>
1091 b94f1830 Phil Davis
							<a href="system_certmanager.php?act=del&amp;id=<?=$i?>" class="fa fa-trash" title="<?=gettext("Delete Certificate")?>"></a>
1092 060ed238 Stephen Beaver
						<?php endif?>
1093
					</td>
1094
				</tr>
1095 4db1f211 Stephen Beaver
<?php
1096
	$i++; 
1097
	endforeach; ?>
1098 060ed238 Stephen Beaver
			</tbody>
1099
		</table>
1100
		</div>
1101
	</div>
1102 b29c322c Stephen Beaver
</div>
1103
1104
<nav class="action-buttons">
1105
	<a href="?act=new" class="btn btn-success btn-sm">
1106
		<i class="fa fa-plus icon-embed-btn"></i>
1107
		<?=gettext("Add")?>
1108
	</a>
1109
</nav>
1110 e9258698 NewEraCracker
<?php
1111 b29c322c Stephen Beaver
	include("foot.inc");
1112
	exit;
1113
}
1114
1115
1116 51583438 Stephen Beaver
?>
1117 8fd9052f Colin Fleming
<script type="text/javascript">
1118 51583438 Stephen Beaver
//<![CDATA[
1119 78863416 Phil Davis
events.push(function() {
1120 bf9d50e8 Stephen Beaver
1121 51583438 Stephen Beaver
<?php if ($internal_ca_count): ?>
1122
	function internalca_change() {
1123
1124
		caref = $('#caref').val();
1125
1126
		switch (caref) {
1127
<?php
1128
			foreach ($a_ca as $ca):
1129
				if (!$ca['prv']) {
1130
					continue;
1131
				}
1132
1133
				$subject = cert_get_subject_array($ca['crt']);
1134
1135
?>
1136
				case "<?=$ca['refid'];?>":
1137
					$('#dn_country').val("<?=$subject[0]['v'];?>");
1138
					$('#dn_state').val("<?=$subject[1]['v'];?>");
1139
					$('#dn_city').val("<?=$subject[2]['v'];?>");
1140
					$('#dn_organization').val("<?=$subject[3]['v'];?>");
1141
					$('#dn_email').val("<?=$subject[4]['v'];?>");
1142
					break;
1143
<?php
1144
			endforeach;
1145
?>
1146
		}
1147
	}
1148
1149 eef93144 Jared Dillard
	// ---------- Click checkbox handlers ---------------------------------------------------------
1150 f74457df Stephen Beaver
1151 51583438 Stephen Beaver
	$('#caref').on('change', function() {
1152
		internalca_change();
1153
	});
1154
1155 eef93144 Jared Dillard
	// ---------- On initial page load ------------------------------------------------------------
1156
1157 51583438 Stephen Beaver
	internalca_change();
1158
1159 0bc61baa Stephen Beaver
	// Suppress "Delete row" button if there are fewer than two rows
1160
	checkLastRow();
1161
1162 51583438 Stephen Beaver
<?php endif; ?>
1163
1164
1165
});
1166
//]]>
1167
</script>
1168
<?php
1169 0edcccc3 Daniel Seebald
include('foot.inc');