Project

General

Profile

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