Project

General

Profile

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