Project

General

Profile

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