Project

General

Profile

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