Project

General

Profile

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