Project

General

Profile

Download (37.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * system_certmanager.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
 * Copyright (c) 2008 Shrew Soft Inc
8
 * All rights reserved.
9
 *
10
 * 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
 *
14
 * http://www.apache.org/licenses/LICENSE-2.0
15
 *
16
 * 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
 */
22

    
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
require_once("guiconfig.inc");
31
require_once("certs.inc");
32
require_once("pfsense-utils.inc");
33

    
34
$cert_methods = array(
35
	"import" => gettext("Import an existing Certificate"),
36
	"internal" => gettext("Create an internal Certificate"),
37
	"external" => gettext("Create a Certificate Signing Request"),
38
	"sign" => gettext("Sign a Certificate Signing Request")
39
);
40

    
41
$cert_keylens = array("512", "1024", "2048", "3072", "4096", "7680", "8192", "15360", "16384");
42
$cert_types = array(
43
	"server" => "Server Certificate",
44
	"user" => "User Certificate");
45

    
46
global $cert_altname_types;
47
global $openssl_digest_algs;
48

    
49
if (isset($_REQUEST['userid']) && is_numericint($_REQUEST['userid'])) {
50
	$userid = $_REQUEST['userid'];
51
}
52

    
53
if (isset($userid)) {
54
	$cert_methods["existing"] = gettext("Choose an existing certificate");
55
	if (!is_array($config['system']['user'])) {
56
		$config['system']['user'] = array();
57
	}
58
	$a_user =& $config['system']['user'];
59
}
60

    
61
if (isset($_REQUEST['id']) && is_numericint($_REQUEST['id'])) {
62
	$id = $_REQUEST['id'];
63
}
64

    
65
if (!is_array($config['ca'])) {
66
	$config['ca'] = array();
67
}
68

    
69
$a_ca =& $config['ca'];
70

    
71
if (!is_array($config['cert'])) {
72
	$config['cert'] = array();
73
}
74

    
75
$a_cert =& $config['cert'];
76

    
77
$internal_ca_count = 0;
78
foreach ($a_ca as $ca) {
79
	if ($ca['prv']) {
80
		$internal_ca_count++;
81
	}
82
}
83

    
84
$act = $_REQUEST['act'];
85

    
86
if ($_POST['act'] == "del") {
87

    
88
	if (!isset($a_cert[$id])) {
89
		pfSenseHeader("system_certmanager.php");
90
		exit;
91
	}
92

    
93
	unset($a_cert[$id]);
94
	write_config();
95
	$savemsg = sprintf(gettext("Certificate %s successfully deleted."), htmlspecialchars($a_cert[$id]['descr']));
96
	pfSenseHeader("system_certmanager.php");
97
	exit;
98
}
99

    
100
if ($act == "new") {
101
	$pconfig['method'] = $_POST['method'];
102
	$pconfig['keylen'] = "2048";
103
	$pconfig['digest_alg'] = "sha256";
104
	$pconfig['csr_keylen'] = "2048";
105
	$pconfig['csr_digest_alg'] = "sha256";
106
	$pconfig['type'] = "user";
107
	$pconfig['lifetime'] = "3650";
108
}
109

    
110
if ($act == "exp") {
111

    
112
	if (!$a_cert[$id]) {
113
		pfSenseHeader("system_certmanager.php");
114
		exit;
115
	}
116

    
117
	$exp_name = urlencode("{$a_cert[$id]['descr']}.crt");
118
	$exp_data = base64_decode($a_cert[$id]['crt']);
119
	$exp_size = strlen($exp_data);
120

    
121
	header("Content-Type: application/octet-stream");
122
	header("Content-Disposition: attachment; filename={$exp_name}");
123
	header("Content-Length: $exp_size");
124
	echo $exp_data;
125
	exit;
126
}
127

    
128
if ($act == "req") {
129

    
130
	if (!$a_cert[$id]) {
131
		pfSenseHeader("system_certmanager.php");
132
		exit;
133
	}
134

    
135
	$exp_name = urlencode("{$a_cert[$id]['descr']}.req");
136
	$exp_data = base64_decode($a_cert[$id]['csr']);
137
	$exp_size = strlen($exp_data);
138

    
139
	header("Content-Type: application/octet-stream");
140
	header("Content-Disposition: attachment; filename={$exp_name}");
141
	header("Content-Length: $exp_size");
142
	echo $exp_data;
143
	exit;
144
}
145

    
146
if ($act == "key") {
147

    
148
	if (!$a_cert[$id]) {
149
		pfSenseHeader("system_certmanager.php");
150
		exit;
151
	}
152

    
153
	$exp_name = urlencode("{$a_cert[$id]['descr']}.key");
154
	$exp_data = base64_decode($a_cert[$id]['prv']);
155
	$exp_size = strlen($exp_data);
156

    
157
	header("Content-Type: application/octet-stream");
158
	header("Content-Disposition: attachment; filename={$exp_name}");
159
	header("Content-Length: $exp_size");
160
	echo $exp_data;
161
	exit;
162
}
163

    
164
if ($act == "p12") {
165
	if (!$a_cert[$id]) {
166
		pfSenseHeader("system_certmanager.php");
167
		exit;
168
	}
169

    
170
	$exp_name = urlencode("{$a_cert[$id]['descr']}.p12");
171
	$args = array();
172
	$args['friendly_name'] = $a_cert[$id]['descr'];
173

    
174
	$ca = lookup_ca($a_cert[$id]['caref']);
175

    
176
	if ($ca) {
177
		$args['extracerts'] = openssl_x509_read(base64_decode($ca['crt']));
178
	}
179

    
180
	$res_crt = openssl_x509_read(base64_decode($a_cert[$id]['crt']));
181
	$res_key = openssl_pkey_get_private(array(0 => base64_decode($a_cert[$id]['prv']) , 1 => ""));
182

    
183
	$exp_data = "";
184
	openssl_pkcs12_export($res_crt, $exp_data, $res_key, null, $args);
185
	$exp_size = strlen($exp_data);
186

    
187
	header("Content-Type: application/octet-stream");
188
	header("Content-Disposition: attachment; filename={$exp_name}");
189
	header("Content-Length: $exp_size");
190
	echo $exp_data;
191
	exit;
192
}
193

    
194
if ($act == "csr") {
195
	if (!$a_cert[$id]) {
196
		pfSenseHeader("system_certmanager.php");
197
		exit;
198
	}
199

    
200
	$pconfig['descr'] = $a_cert[$id]['descr'];
201
	$pconfig['csr'] = base64_decode($a_cert[$id]['csr']);
202
}
203

    
204
if ($_POST['save']) {
205

    
206
	if ($_POST['save'] == gettext("Save")) {
207
		$input_errors = array();
208
		$pconfig = $_POST;
209

    
210
		/* input validation */
211
		if ($pconfig['method'] == "sign") {
212
			$reqdfields = explode(" ",
213
				"descr catosignwith");
214
			$reqdfieldsn = array(
215
				gettext("Descriptive name"),
216
				gettext("CA to sign with"));
217

    
218
			if (($_POST['csrtosign'] === "new") &&
219
			    ((!strstr($_POST['csrpaste'], "BEGIN CERTIFICATE REQUEST") || !strstr($_POST['csrpaste'], "END CERTIFICATE REQUEST")) &&
220
			    (!strstr($_POST['csrpaste'], "BEGIN NEW CERTIFICATE REQUEST") || !strstr($_POST['csrpaste'], "END NEW CERTIFICATE REQUEST")))) {
221
				$input_errors[] = gettext("This signing request does not appear to be valid.");
222
			}
223

    
224
			if ( (($_POST['csrtosign'] === "new") && (strlen($_POST['keypaste']) > 0)) && (!strstr($_POST['keypaste'], "BEGIN PRIVATE KEY") || !strstr($_POST['keypaste'], "END PRIVATE KEY"))) {
225
				$input_errors[] = gettext("This private does not appear to be valid.");
226
				$input_errors[] = gettext("Key data field should be blank, or a valid x509 private key");
227
			}
228

    
229
		}
230

    
231
		if ($pconfig['method'] == "import") {
232
			$reqdfields = explode(" ",
233
				"descr cert key");
234
			$reqdfieldsn = array(
235
				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
				$input_errors[] = gettext("This certificate does not appear to be valid.");
240
			}
241

    
242
			if (cert_get_publickey($_POST['cert'], false) != cert_get_publickey($_POST['key'], false, 'prv')) {
243
				$input_errors[] = gettext("The submitted private key does not match the submitted certificate data.");
244
			}
245
		}
246

    
247
		if ($pconfig['method'] == "internal") {
248
			$reqdfields = explode(" ",
249
				"descr caref keylen type lifetime dn_country dn_state dn_city ".
250
				"dn_organization dn_email dn_commonname");
251
			$reqdfieldsn = array(
252
				gettext("Descriptive name"),
253
				gettext("Certificate authority"),
254
				gettext("Key length"),
255
				gettext("Certificate Type"),
256
				gettext("Lifetime"),
257
				gettext("Distinguished name Country Code"),
258
				gettext("Distinguished name State or Province"),
259
				gettext("Distinguished name City"),
260
				gettext("Distinguished name Organization"),
261
				gettext("Distinguished name Email Address"),
262
				gettext("Distinguished name Common Name"));
263
		}
264

    
265
		if ($pconfig['method'] == "external") {
266
			$reqdfields = explode(" ",
267
				"descr csr_keylen csr_dn_country csr_dn_state csr_dn_city ".
268
				"csr_dn_organization csr_dn_email csr_dn_commonname");
269
			$reqdfieldsn = array(
270
				gettext("Descriptive name"),
271
				gettext("Key length"),
272
				gettext("Distinguished name Country Code"),
273
				gettext("Distinguished name State or Province"),
274
				gettext("Distinguished name City"),
275
				gettext("Distinguished name Organization"),
276
				gettext("Distinguished name Email Address"),
277
				gettext("Distinguished name Common Name"));
278
		}
279

    
280
		if ($pconfig['method'] == "existing") {
281
			$reqdfields = array("certref");
282
			$reqdfieldsn = array(gettext("Existing Certificate Choice"));
283
		}
284

    
285
		$altnames = array();
286
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
287

    
288
		if ($pconfig['method'] != "import" && $pconfig['method'] != "existing") {
289
			/* subjectAltNames */
290
			$san_typevar = 'altname_type';
291
			$san_valuevar = 'altname_value';
292
			// This is just the blank alternate name that is added for display purposes. We don't want to validate/save it
293
			if ($_POST["{$san_valuevar}0"] == "") {
294
				unset($_POST["{$san_typevar}0"]);
295
				unset($_POST["{$san_valuevar}0"]);
296
			}
297
			foreach ($_POST as $key => $value) {
298
				$entry = '';
299
				if (!substr_compare($san_typevar, $key, 0, strlen($san_typevar))) {
300
					$entry = substr($key, strlen($san_typevar));
301
					$field = 'type';
302
				} elseif (!substr_compare($san_valuevar, $key, 0, strlen($san_valuevar))) {
303
					$entry = substr($key, strlen($san_valuevar));
304
					$field = 'value';
305
				}
306

    
307
				if (ctype_digit($entry)) {
308
					$entry++;	// Pre-bootstrap code is one-indexed, but the bootstrap code is 0-indexed
309
					$altnames[$entry][$field] = $value;
310
				}
311
			}
312

    
313
			$pconfig['altnames']['item'] = $altnames;
314

    
315
			/* Input validation for subjectAltNames */
316
			foreach ($altnames as $idx => $altname) {
317
				switch ($altname['type']) {
318
					case "DNS":
319
						if (!is_hostname($altname['value'], true)) {
320
							array_push($input_errors, "DNS subjectAltName values must be valid hostnames, FQDNs or wildcard domains.");
321
						}
322
						break;
323
					case "IP":
324
						if (!is_ipaddr($altname['value'])) {
325
							array_push($input_errors, "IP subjectAltName values must be valid IP Addresses");
326
						}
327
						break;
328
					case "email":
329
						if (empty($altname['value'])) {
330
							array_push($input_errors, "An e-mail address must be provided for this type of subjectAltName");
331
						}
332
						if (preg_match("/[\!\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $altname['value'])) {
333
							array_push($input_errors, "The e-mail provided in a subjectAltName contains invalid characters.");
334
						}
335
						break;
336
					case "URI":
337
						/* Close enough? */
338
						if (!is_URL($altname['value'])) {
339
							$input_errors[] = "URI subjectAltName types must be a valid URI";
340
						}
341
						break;
342
					default:
343
						$input_errors[] = "Unrecognized subjectAltName type.";
344
				}
345
			}
346

    
347
			/* Make sure we do not have invalid characters in the fields for the certificate */
348

    
349
			if (preg_match("/[\?\>\<\&\/\\\"\']/", $_POST['descr'])) {
350
				array_push($input_errors, "The field 'Descriptive Name' contains invalid characters.");
351
			}
352

    
353
			for ($i = 0; $i < count($reqdfields); $i++) {
354
				if (preg_match('/email/', $reqdfields[$i])) { /* dn_email or csr_dn_name */
355
					if (preg_match("/[\!\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST[$reqdfields[$i]])) {
356
						array_push($input_errors, gettext("The field 'Distinguished name Email Address' contains invalid characters."));
357
					}
358
				}
359
			}
360

    
361
			if (($pconfig['method'] != "external") && isset($_POST["keylen"]) && !in_array($_POST["keylen"], $cert_keylens)) {
362
				array_push($input_errors, gettext("Please select a valid Key Length."));
363
			}
364
			if (($pconfig['method'] != "external") && !in_array($_POST["digest_alg"], $openssl_digest_algs)) {
365
				array_push($input_errors, gettext("Please select a valid Digest Algorithm."));
366
			}
367

    
368
			if (($pconfig['method'] == "external") && isset($_POST["csr_keylen"]) && !in_array($_POST["csr_keylen"], $cert_keylens)) {
369
				array_push($input_errors, gettext("Please select a valid Key Length."));
370
			}
371
			if (($pconfig['method'] == "external") && !in_array($_POST["csr_digest_alg"], $openssl_digest_algs)) {
372
				array_push($input_errors, gettext("Please select a valid Digest Algorithm."));
373
			}
374
		}
375

    
376
		/* save modifications */
377
		if (!$input_errors) {
378

    
379
			if ($pconfig['method'] == "existing") {
380
				$cert = lookup_cert($pconfig['certref']);
381
				if ($cert && $a_user) {
382
					$a_user[$userid]['cert'][] = $cert['refid'];
383
				}
384
			} else if ($pconfig['method'] == "sign") { // Sign a CSR
385
				$csrid = lookup_cert($pconfig['csrtosign']);
386
				$ca = & lookup_ca($pconfig['catosignwith']);
387

    
388
				// Read the CSR from $config, or if a new one, from the textarea
389
				if ($pconfig['csrtosign'] === "new") {
390
					$csr = $pconfig['csrpaste'];
391
				} else {
392
					$csr = base64_decode($csrid['csr']);
393
				}
394
				if (count($altnames)) {
395
					foreach ($altnames as $altname) {
396
						$altnames_tmp[] = "{$altname['type']}:" . cert_escape_x509_chars($altname['value']);
397
					}
398
					$altname_str = implode(",", $altnames_tmp);
399
				}
400

    
401
				$n509 = csr_sign($csr, $ca, $pconfig['csrsign_lifetime'], $pconfig['type'], $altname_str);
402

    
403
				if ($n509) {
404
					// Gather the details required to save the new cert
405
					$newcert = array();
406
					$newcert['refid'] = uniqid();
407
					$newcert['caref'] = $pconfig['catosignwith'];
408
					$newcert['descr'] = $pconfig['descr'];
409
					$newcert['type'] = $pconfig['type'];
410
					$newcert['crt'] = base64_encode($n509);
411

    
412
					if ($pconfig['csrtosign'] === "new") {
413
						$newcert['prv'] = base64_encode($pconfig['keypaste']);
414
					} else {
415
						$newcert['prv'] = $csrid['prv'];
416
					}
417

    
418
					// Add it to the config file
419
					$config['cert'][] = $newcert;
420
				}
421

    
422
			} else {
423
				$cert = array();
424
				$cert['refid'] = uniqid();
425
				if (isset($id) && $a_cert[$id]) {
426
					$cert = $a_cert[$id];
427
				}
428

    
429
				$cert['descr'] = $pconfig['descr'];
430

    
431
				$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
432

    
433
				if ($pconfig['method'] == "import") {
434
					cert_import($cert, $pconfig['cert'], $pconfig['key']);
435
				}
436

    
437
				if ($pconfig['method'] == "internal") {
438
					$dn = array(
439
						'countryName' => $pconfig['dn_country'],
440
						'stateOrProvinceName' => cert_escape_x509_chars($pconfig['dn_state']),
441
						'localityName' => cert_escape_x509_chars($pconfig['dn_city']),
442
						'organizationName' => cert_escape_x509_chars($pconfig['dn_organization']),
443
						'emailAddress' => cert_escape_x509_chars($pconfig['dn_email']),
444
						'commonName' => cert_escape_x509_chars($pconfig['dn_commonname']));
445
					if (!empty($pconfig['dn_organizationalunit'])) {
446
						$dn['organizationalUnitName'] = cert_escape_x509_chars($pconfig['dn_organizationalunit']);
447
					}
448
					$altnames_tmp = array(cert_add_altname_type($pconfig['dn_commonname']));
449
					if (count($altnames)) {
450
						foreach ($altnames as $altname) {
451
							// The CN is added as a SAN automatically, do not add it again.
452
							if ($altname['value'] != $pconfig['dn_commonname']) {
453
								$altnames_tmp[] = "{$altname['type']}:" . cert_escape_x509_chars($altname['value']);
454
							}
455
						}
456
					}
457
					if (!empty($altnames_tmp)) {
458
						$dn['subjectAltName'] = implode(",", $altnames_tmp);
459
					}
460

    
461
					if (!cert_create($cert, $pconfig['caref'], $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['type'], $pconfig['digest_alg'])) {
462
						$input_errors = array();
463
						while ($ssl_err = openssl_error_string()) {
464
							if (strpos($ssl_err, 'NCONF_get_string:no value') === false) {
465
								array_push($input_errors, "openssl library returns: " . $ssl_err);
466
							}
467
						}
468
					}
469
				}
470

    
471
				if ($pconfig['method'] == "external") {
472
					$dn = array(
473
						'countryName' => $pconfig['csr_dn_country'],
474
						'stateOrProvinceName' => cert_escape_x509_chars($pconfig['csr_dn_state']),
475
						'localityName' => cert_escape_x509_chars($pconfig['csr_dn_city']),
476
						'organizationName' => cert_escape_x509_chars($pconfig['csr_dn_organization']),
477
						'emailAddress' => cert_escape_x509_chars($pconfig['csr_dn_email']),
478
						'commonName' => cert_escape_x509_chars($pconfig['csr_dn_commonname']));
479
					if (!empty($pconfig['csr_dn_organizationalunit'])) {
480
						$dn['organizationalUnitName'] = cert_escape_x509_chars($pconfig['csr_dn_organizationalunit']);
481
					}
482

    
483
					$altnames_tmp = array(cert_add_altname_type($pconfig['csr_dn_commonname']));
484
					if (count($altnames)) {
485
						foreach ($altnames as $altname) {
486
							// The CN is added as a SAN automatically, do not add it again.
487
							if ($altname['value'] != $pconfig['csr_dn_commonname']) {
488
								$altnames_tmp[] = "{$altname['type']}:" . cert_escape_x509_chars($altname['value']);
489
							}
490
						}
491
					}
492
					if (!empty($altnames_tmp)) {
493
						$dn['subjectAltName'] = implode(",", $altnames_tmp);
494
					}
495

    
496
					if (!csr_generate($cert, $pconfig['csr_keylen'], $dn, $pconfig['type'], $pconfig['csr_digest_alg'])) {
497
						$input_errors = array();
498
						while ($ssl_err = openssl_error_string()) {
499
							if (strpos($ssl_err, 'NCONF_get_string:no value') === false) {
500
								array_push($input_errors, "openssl library returns: " . $ssl_err);
501
							}
502
						}
503
					}
504
				}
505

    
506
				error_reporting($old_err_level);
507

    
508
				if (isset($id) && $a_cert[$id]) {
509
					$a_cert[$id] = $cert;
510
				} else {
511
					$a_cert[] = $cert;
512
				}
513

    
514
				if (isset($a_user) && isset($userid)) {
515
					$a_user[$userid]['cert'][] = $cert['refid'];
516
				}
517
			}
518

    
519
			if (!$input_errors) {
520
				write_config();
521
			}
522

    
523
			if ($userid && !$input_errors) {
524
				post_redirect("system_usermanager.php", array('act' => 'edit', 'userid' => $userid));
525
				exit;
526
			}
527
		}
528
	}
529

    
530
	if ($_POST['save'] == gettext("Update")) {
531
		unset($input_errors);
532
		$pconfig = $_POST;
533

    
534
		/* input validation */
535
		$reqdfields = explode(" ", "descr cert");
536
		$reqdfieldsn = array(
537
			gettext("Descriptive name"),
538
			gettext("Final Certificate data"));
539

    
540
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
541

    
542
		if (preg_match("/[\?\>\<\&\/\\\"\']/", $_POST['descr'])) {
543
			array_push($input_errors, "The field 'Descriptive Name' contains invalid characters.");
544
		}
545

    
546
//		old way
547
		/* make sure this csr and certificate subjects match */
548
//		$subj_csr = csr_get_subject($pconfig['csr'], false);
549
//		$subj_cert = cert_get_subject($pconfig['cert'], false);
550
//
551
//		if (!isset($_POST['ignoresubjectmismatch']) && !($_POST['ignoresubjectmismatch'] == "yes")) {
552
//			if (strcmp($subj_csr, $subj_cert)) {
553
//				$input_errors[] = sprintf(gettext("The certificate subject '%s' does not match the signing request subject."), $subj_cert);
554
//				$subject_mismatch = true;
555
//			}
556
//		}
557
		$mod_csr = cert_get_publickey($pconfig['csr'], false, 'csr');
558
		$mod_cert = cert_get_publickey($pconfig['cert'], false);
559

    
560
		if (strcmp($mod_csr, $mod_cert)) {
561
			// simply: if the moduli don't match, then the private key and public key won't match
562
			$input_errors[] = sprintf(gettext("The certificate public key does not match the signing request public key."), $subj_cert);
563
			$subject_mismatch = true;
564
		}
565

    
566
		/* save modifications */
567
		if (!$input_errors) {
568

    
569
			$cert = $a_cert[$id];
570

    
571
			$cert['descr'] = $pconfig['descr'];
572

    
573
			csr_complete($cert, $pconfig['cert']);
574

    
575
			$a_cert[$id] = $cert;
576

    
577
			write_config();
578

    
579
			pfSenseHeader("system_certmanager.php");
580
		}
581
	}
582
}
583

    
584
$pgtitle = array(gettext("System"), gettext("Certificate Manager"), gettext("Certificates"));
585
$pglinks = array("", "system_camanager.php", "system_certmanager.php");
586

    
587
if (($act == "new" || ($_POST['save'] == gettext("Save") && $input_errors)) || ($act == "csr" || ($_POST['save'] == gettext("Update") && $input_errors))) {
588
	$pgtitle[] = gettext('Edit');
589
	$pglinks[] = "@self";
590
}
591
include("head.inc");
592

    
593
if ($input_errors) {
594
	print_input_errors($input_errors);
595
}
596

    
597
if ($savemsg) {
598
	print_info_box($savemsg, 'success');
599
}
600

    
601
$tab_array = array();
602
$tab_array[] = array(gettext("CAs"), false, "system_camanager.php");
603
$tab_array[] = array(gettext("Certificates"), true, "system_certmanager.php");
604
$tab_array[] = array(gettext("Certificate Revocation"), false, "system_crlmanager.php");
605
display_top_tabs($tab_array);
606

    
607
// Load valid country codes
608
$dn_cc = array();
609
if (file_exists("/etc/ca_countries")) {
610
	$dn_cc_file=file("/etc/ca_countries");
611
	foreach ($dn_cc_file as $line) {
612
		if (preg_match('/^(\S*)\s(.*)$/', $line, $matches)) {
613
			$dn_cc[$matches[1]] = $matches[1];
614
		}
615
	}
616
}
617

    
618
if ($act == "new" || (($_POST['save'] == gettext("Save")) && $input_errors)) {
619
	$form = new Form();
620
	$form->setAction('system_certmanager.php?act=edit');
621

    
622
	if (isset($userid) && $a_user) {
623
		$form->addGlobal(new Form_Input(
624
			'userid',
625
			null,
626
			'hidden',
627
			$userid
628
		));
629
	}
630

    
631
	if (isset($id) && $a_cert[$id]) {
632
		$form->addGlobal(new Form_Input(
633
			'id',
634
			null,
635
			'hidden',
636
			$id
637
		));
638
	}
639

    
640
	$section = new Form_Section('Add/Sign a New Certificate');
641

    
642
	if (!isset($id)) {
643
		$section->addInput(new Form_Select(
644
			'method',
645
			'*Method',
646
			$pconfig['method'],
647
			$cert_methods
648
		))->toggles();
649
	}
650

    
651
	$section->addInput(new Form_Input(
652
		'descr',
653
		'*Descriptive name',
654
		'text',
655
		($a_user && empty($pconfig['descr'])) ? $a_user[$userid]['name'] : $pconfig['descr']
656
	))->addClass('toggle-existing');
657

    
658
	$form->add($section);
659

    
660
	// Return an array containing the IDs od all CAs
661
	function list_cas() {
662
		global $a_ca;
663
		$allCas = array();
664

    
665
		foreach ($a_ca as $ca) {
666
			if ($ca['prv']) {
667
				$allCas[$ca['refid']] = $ca['descr'];
668
			}
669
		}
670

    
671
		return $allCas;
672
	}
673

    
674
	// Return an array containing the IDs od all CSRs
675
	function list_csrs() {
676
		global $config;
677
		$allCsrs = array();
678

    
679
		foreach ($config['cert'] as $cert) {
680
			if ($cert['csr']) {
681
				$allCsrs[$cert['refid']] = $cert['descr'];
682
			}
683
		}
684

    
685
		return ['new' => gettext('New CSR (Paste below)')] + $allCsrs;
686
	}
687

    
688
	$section = new Form_Section('Sign CSR');
689
	$section->addClass('toggle-sign collapse');
690

    
691
	$section->AddInput(new Form_Select(
692
		'catosignwith',
693
		'*CA to sign with',
694
		$pconfig['catosignwith'],
695
		list_cas()
696
	));
697

    
698
	$section->AddInput(new Form_Select(
699
		'csrtosign',
700
		'*CSR to sign',
701
		isset($pconfig['csrtosign']) ? $pconfig['csrtosign'] : 'new',
702
		list_csrs()
703
	));
704

    
705
	$section->addInput(new Form_Textarea(
706
		'csrpaste',
707
		'CSR data',
708
		$pconfig['csrpaste']
709
	))->setHelp('Paste a Certificate Signing Request in X.509 PEM format here.');
710

    
711
	$section->addInput(new Form_Textarea(
712
		'keypaste',
713
		'Key data',
714
		$pconfig['keypaste']
715
	))->setHelp('Optionally paste a private key here. The key will be associated with the newly signed certificate in pfSense');
716

    
717
	$section->addInput(new Form_Input(
718
		'csrsign_lifetime',
719
		'*Certificate Lifetime (days)',
720
		'number',
721
		$pconfig['duration'] ? $pconfig['duration']:'3650'
722
	));
723

    
724
	$form->add($section);
725

    
726
	$section = new Form_Section('Import Certificate');
727
	$section->addClass('toggle-import collapse');
728

    
729
	$section->addInput(new Form_Textarea(
730
		'cert',
731
		'*Certificate data',
732
		$pconfig['cert']
733
	))->setHelp('Paste a certificate in X.509 PEM format here.');
734

    
735
	$section->addInput(new Form_Textarea(
736
		'key',
737
		'*Private key data',
738
		$pconfig['key']
739
	))->setHelp('Paste a private key in X.509 PEM format here.');
740

    
741
	$form->add($section);
742
	$section = new Form_Section('Internal Certificate');
743
	$section->addClass('toggle-internal collapse');
744

    
745
	if (!$internal_ca_count) {
746
		$section->addInput(new Form_StaticText(
747
			'*Certificate authority',
748
			gettext('No internal Certificate Authorities have been defined. ') .
749
			gettext('An internal CA must be defined in order to create an internal certificate. ') .
750
			sprintf(gettext('%1$sCreate%2$s an internal CA.'), '<a href="system_camanager.php?act=new&amp;method=internal"> ', '</a>')
751
		));
752
	} else {
753
		$allCas = array();
754
		foreach ($a_ca as $ca) {
755
			if (!$ca['prv']) {
756
				continue;
757
			}
758

    
759
			$allCas[ $ca['refid'] ] = $ca['descr'];
760
		}
761

    
762
		$section->addInput(new Form_Select(
763
			'caref',
764
			'*Certificate authority',
765
			$pconfig['caref'],
766
			$allCas
767
		));
768
	}
769

    
770
	$section->addInput(new Form_Select(
771
		'keylen',
772
		'*Key length',
773
		$pconfig['keylen'],
774
		array_combine($cert_keylens, $cert_keylens)
775
	));
776

    
777
	$section->addInput(new Form_Select(
778
		'digest_alg',
779
		'*Digest Algorithm',
780
		$pconfig['digest_alg'],
781
		array_combine($openssl_digest_algs, $openssl_digest_algs)
782
	))->setHelp('NOTE: It is recommended to use an algorithm stronger than '.
783
		'SHA1 when possible.');
784

    
785
	$section->addInput(new Form_Input(
786
		'lifetime',
787
		'*Lifetime (days)',
788
		'number',
789
		$pconfig['lifetime']
790
	));
791

    
792
	$section->addInput(new Form_Select(
793
		'dn_country',
794
		'*Country Code',
795
		$pconfig['dn_country'],
796
		$dn_cc
797
	));
798

    
799
	$section->addInput(new Form_Input(
800
		'dn_state',
801
		'*State or Province',
802
		'text',
803
		$pconfig['dn_state'],
804
		['placeholder' => 'e.g. Texas']
805
	));
806

    
807
	$section->addInput(new Form_Input(
808
		'dn_city',
809
		'*City',
810
		'text',
811
		$pconfig['dn_city'],
812
		['placeholder' => 'e.g. Austin']
813
	));
814

    
815
	$section->addInput(new Form_Input(
816
		'dn_organization',
817
		'*Organization',
818
		'text',
819
		$pconfig['dn_organization'],
820
		['placeholder' => 'e.g. My Company Inc']
821
	));
822

    
823
	$section->addInput(new Form_Input(
824
		'dn_organizationalunit',
825
		'Organizational Unit',
826
		'text',
827
		$pconfig['dn_organizationalunit'],
828
		['placeholder' => 'e.g. My Department Name (optional)']
829
	));
830

    
831
	$section->addInput(new Form_Input(
832
		'dn_email',
833
		'*Email Address',
834
		'text',
835
		$pconfig['dn_email'],
836
		['placeholder' => 'e.g. admin@mycompany.com']
837
	));
838

    
839
	$section->addInput(new Form_Input(
840
		'dn_commonname',
841
		'*Common Name',
842
		'text',
843
		$pconfig['dn_commonname'],
844
		['placeholder' => 'e.g. www.example.com']
845
	));
846

    
847
	$form->add($section);
848
	$section = new Form_Section('External Signing Request');
849
	$section->addClass('toggle-external collapse');
850

    
851
	$section->addInput(new Form_Select(
852
		'csr_keylen',
853
		'*Key length',
854
		$pconfig['csr_keylen'],
855
		array_combine($cert_keylens, $cert_keylens)
856
	));
857

    
858
	$section->addInput(new Form_Select(
859
		'csr_digest_alg',
860
		'*Digest Algorithm',
861
		$pconfig['csr_digest_alg'],
862
		array_combine($openssl_digest_algs, $openssl_digest_algs)
863
	))->setHelp('NOTE: It is recommended to use an algorithm stronger than '.
864
		'SHA1 when possible');
865

    
866
	$section->addInput(new Form_Select(
867
		'csr_dn_country',
868
		'*Country Code',
869
		$pconfig['csr_dn_country'],
870
		$dn_cc
871
	));
872

    
873
	$section->addInput(new Form_Input(
874
		'csr_dn_state',
875
		'*State or Province',
876
		'text',
877
		$pconfig['csr_dn_state'],
878
		['placeholder' => 'e.g. Texas']
879
	));
880

    
881
	$section->addInput(new Form_Input(
882
		'csr_dn_city',
883
		'*City',
884
		'text',
885
		$pconfig['csr_dn_city'],
886
		['placeholder' => 'e.g. Austin']
887
	));
888

    
889
	$section->addInput(new Form_Input(
890
		'csr_dn_organization',
891
		'*Organization',
892
		'text',
893
		$pconfig['csr_dn_organization'],
894
		['placeholder' => 'e.g. My Company Inc']
895
	));
896

    
897
	$section->addInput(new Form_Input(
898
		'csr_dn_organizationalunit',
899
		'Organizational Unit',
900
		'text',
901
		$pconfig['csr_dn_organizationalunit'],
902
		['placeholder' => 'e.g. My Department Name (optional)']
903
	));
904

    
905
	$section->addInput(new Form_Input(
906
		'csr_dn_email',
907
		'*Email Address',
908
		'text',
909
		$pconfig['csr_dn_email'],
910
		['placeholder' => 'e.g. admin@mycompany.com']
911
	));
912

    
913
	$section->addInput(new Form_Input(
914
		'csr_dn_commonname',
915
		'*Common Name',
916
		'text',
917
		$pconfig['csr_dn_commonname'],
918
		['placeholder' => 'e.g. internal-ca']
919
	));
920

    
921
	$form->add($section);
922
	$section = new Form_Section('Choose an Existing Certificate');
923
	$section->addClass('toggle-existing collapse');
924

    
925
	$existCerts = array();
926

    
927
	foreach ($config['cert'] as $cert)	{
928
		if (is_array($config['system']['user'][$userid]['cert'])) { // Could be MIA!
929
			if (isset($userid) && in_array($cert['refid'], $config['system']['user'][$userid]['cert'])) {
930
				continue;
931
			}
932
		}
933

    
934
		$ca = lookup_ca($cert['caref']);
935
		if ($ca) {
936
			$cert['descr'] .= " (CA: {$ca['descr']})";
937
		}
938

    
939
		if (cert_in_use($cert['refid'])) {
940
			$cert['descr'] .= " (In Use)";
941
		}
942
		if (is_cert_revoked($cert)) {
943
			$cert['descr'] .= " (Revoked)";
944
		}
945

    
946
		$existCerts[ $cert['refid'] ] = $cert['descr'];
947
	}
948

    
949
	$section->addInput(new Form_Select(
950
		'certref',
951
		'*Existing Certificates',
952
		$pconfig['certref'],
953
		$existCerts
954
	));
955

    
956
	$form->add($section);
957

    
958
	$section = new Form_Section('Certificate Attributes');
959
	$section->addClass('toggle-external toggle-internal toggle-sign collapse');
960

    
961
	$section->addInput(new Form_StaticText(
962
		gettext('Attribute Notes'),
963
		'<span class="help-block">'.
964
		gettext('The following attributes are added to certificates and ' .
965
		'requests when they are created or signed. These attributes behave ' .
966
		'differently depending on the selected mode.') .
967
		'<br/><br/>' .
968
		'<span class="toggle-internal collapse">' . gettext('For Internal Certificates, these attributes are added directly to the certificate as shown.') . '</span>' .
969
		'<span class="toggle-external collapse">' .
970
		gettext('For Certificate Signing Requests, These attributes are added to the request but they may be ignored or changed by the CA that signs the request. ') .
971
		'<br/><br/>' .
972
		gettext('If this CSR will be signed using the Certificate Manager on this firewall, set the attributes when signing instead as they cannot be carried over.') . '</span>' .
973
		'<span class="toggle-sign collapse">' . gettext('When Signing a Certificate Request, existing attributes in the request cannot be copied. The attributes below will be applied to the resulting certificate.') . '</span>' .
974
		'</span>'
975
	));
976

    
977
	$section->addInput(new Form_Select(
978
		'type',
979
		'*Certificate Type',
980
		$pconfig['type'],
981
		$cert_types
982
	))->setHelp('Add type-specific usage attributes to the signed certificate.' .
983
		' Used for placing usage restrictions on, or granting abilities to, ' .
984
		'the signed certificate.');
985

    
986
	if (empty($pconfig['altnames']['item'])) {
987
		$pconfig['altnames']['item'] = array(
988
			array('type' => null, 'value' => null)
989
		);
990
	}
991

    
992
	$counter = 0;
993
	$numrows = count($pconfig['altnames']['item']) - 1;
994

    
995
	foreach ($pconfig['altnames']['item'] as $item) {
996

    
997
		$group = new Form_Group($counter == 0 ? 'Alternative Names':'');
998

    
999
		$group->add(new Form_Select(
1000
			'altname_type' . $counter,
1001
			'Type',
1002
			$item['type'],
1003
			$cert_altname_types
1004
		))->setHelp(($counter == $numrows) ? 'Type':null);
1005

    
1006
		$group->add(new Form_Input(
1007
			'altname_value' . $counter,
1008
			null,
1009
			'text',
1010
			$item['value']
1011
		))->setHelp(($counter == $numrows) ? 'Value':null);
1012

    
1013
		$group->add(new Form_Button(
1014
			'deleterow' . $counter,
1015
			'Delete',
1016
			null,
1017
			'fa-trash'
1018
		))->addClass('btn-warning');
1019

    
1020
		$group->addClass('repeatable');
1021

    
1022
		$group->setHelp('Enter additional identifiers for the certificate ' .
1023
			'in this list. The Common Name field is automatically ' .
1024
			'added to the certificate as an Alternative Name. ' .
1025
			'The signing CA may ignore or change these values.');
1026

    
1027
		$section->add($group);
1028

    
1029
		$counter++;
1030
	}
1031

    
1032
	$section->addInput(new Form_Button(
1033
		'addrow',
1034
		'Add',
1035
		null,
1036
		'fa-plus'
1037
	))->addClass('btn-success');
1038

    
1039
	$form->add($section);
1040

    
1041

    
1042
	print $form;
1043

    
1044
} else if ($act == "csr" || (($_POST['save'] == gettext("Update")) && $input_errors)) {
1045
	$form = new Form(false);
1046
	$form->setAction('system_certmanager.php?act=csr');
1047

    
1048
	$section = new Form_Section("Complete Signing Request for " . $pconfig['descr']);
1049

    
1050
	$section->addInput(new Form_Input(
1051
		'descr',
1052
		'*Descriptive name',
1053
		'text',
1054
		$pconfig['descr']
1055
	));
1056

    
1057
	$section->addInput(new Form_Textarea(
1058
		'csr',
1059
		'Signing request data',
1060
		$pconfig['csr']
1061
	))->setReadonly()
1062
	  ->setWidth(7)
1063
	  ->setHelp('Copy the certificate signing data from here and forward it to a certificate authority for signing.');
1064

    
1065
	$section->addInput(new Form_Textarea(
1066
		'cert',
1067
		'*Final certificate data',
1068
		$pconfig['cert']
1069
	))->setWidth(7)
1070
	  ->setHelp('Paste the certificate received from the certificate authority here.');
1071

    
1072
	 if (isset($id) && $a_cert[$id]) {
1073
		 $section->addInput(new Form_Input(
1074
			'id',
1075
			null,
1076
			'hidden',
1077
			$id
1078
		 ));
1079

    
1080
		 $section->addInput(new Form_Input(
1081
			'act',
1082
			null,
1083
			'hidden',
1084
			'csr'
1085
		 ));
1086
	 }
1087

    
1088
	$form->add($section);
1089

    
1090
	$form->addGlobal(new Form_Button(
1091
		'save',
1092
		'Update',
1093
		null,
1094
		'fa-save'
1095
	))->addClass('btn-primary');
1096

    
1097
	print($form);
1098
} else {
1099
?>
1100
<div class="panel panel-default">
1101
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Certificates')?></h2></div>
1102
	<div class="panel-body">
1103
		<div class="table-responsive">
1104
		<table class="table table-striped table-hover">
1105
			<thead>
1106
				<tr>
1107
					<th><?=gettext("Name")?></th>
1108
					<th><?=gettext("Issuer")?></th>
1109
					<th><?=gettext("Distinguished Name")?></th>
1110
					<th><?=gettext("In Use")?></th>
1111

    
1112
					<th class="col-sm-2"><?=gettext("Actions")?></th>
1113
				</tr>
1114
			</thead>
1115
			<tbody>
1116
<?php
1117

    
1118
$pluginparams = array();
1119
$pluginparams['type'] = 'certificates';
1120
$pluginparams['event'] = 'used_certificates';
1121
$certificates_used_by_packages = pkg_call_plugins('plugin_certificates', $pluginparams);
1122
$i = 0;
1123
foreach ($a_cert as $i => $cert):
1124
	$name = htmlspecialchars($cert['descr']);
1125

    
1126
	if ($cert['crt']) {
1127
		$subj = cert_get_subject($cert['crt']);
1128
		$issuer = cert_get_issuer($cert['crt']);
1129
		$purpose = cert_get_purpose($cert['crt']);
1130
		$sans = cert_get_sans($cert['crt']);
1131
		list($startdate, $enddate) = cert_get_dates($cert['crt']);
1132

    
1133
		if ($subj == $issuer) {
1134
			$caname = '<i>'. gettext("self-signed") .'</i>';
1135
		} else {
1136
			$caname = '<i>'. gettext("external").'</i>';
1137
		}
1138

    
1139
		$subj = htmlspecialchars(cert_escape_x509_chars($subj, true));
1140
	} else {
1141
		$subj = "";
1142
		$issuer = "";
1143
		$purpose = "";
1144
		$startdate = "";
1145
		$enddate = "";
1146
		$caname = "<em>" . gettext("private key only") . "</em>";
1147
	}
1148

    
1149
	if ($cert['csr']) {
1150
		$subj = htmlspecialchars(cert_escape_x509_chars(csr_get_subject($cert['csr']), true));
1151
		$sans = cert_get_sans($cert['crt']);
1152
		$caname = "<em>" . gettext("external - signature pending") . "</em>";
1153
	}
1154

    
1155
	$ca = lookup_ca($cert['caref']);
1156
	if ($ca) {
1157
		$caname = $ca['descr'];
1158
	}
1159
?>
1160
				<tr>
1161
					<td>
1162
						<?=$name?><br />
1163
						<?php if ($cert['type']): ?>
1164
							<i><?=$cert_types[$cert['type']]?></i><br />
1165
						<?php endif?>
1166
						<?php if (is_array($purpose)): ?>
1167
							CA: <b><?=$purpose['ca']?></b><br/>
1168
							<?=gettext("Server")?>: <b><?=$purpose['server']?></b><br/>
1169
						<?php endif?>
1170
					</td>
1171
					<td><?=$caname?></td>
1172
					<td>
1173
						<?=$subj?>
1174
						<?php
1175
						$certextinfo = "";
1176
						if (is_array($sans) && !empty($sans)) {
1177
							$certextinfo .= '<b>' . gettext("SAN: ") . '</b> ';
1178
							$certextinfo .= htmlspecialchars(implode(', ', cert_escape_x509_chars($sans, true)));
1179
							$certextinfo .= '<br/>';
1180
						}
1181
						if (is_array($purpose) && !empty($purpose['ku'])) {
1182
							$certextinfo .= '<b>' . gettext("KU: ") . '</b> ';
1183
							$certextinfo .= htmlspecialchars(implode(', ', $purpose['ku']));
1184
							$certextinfo .= '<br/>';
1185
						}
1186
						if (is_array($purpose) && !empty($purpose['eku'])) {
1187
							$certextinfo .= '<b>' . gettext("EKU: ") . '</b> ';
1188
							$certextinfo .= htmlspecialchars(implode(', ', $purpose['eku']));
1189
						}
1190
						?>
1191
						<?php if (!empty($certextinfo)): ?>
1192
							<div class="infoblock">
1193
							<? print_info_box($certextinfo, 'info', false); ?>
1194
							</div>
1195
						<?php endif?>
1196

    
1197
						<?php if (!empty($startdate) || !empty($enddate)): ?>
1198
						<br />
1199
						<small>
1200
							<?=gettext("Valid From")?>: <b><?=$startdate ?></b><br /><?=gettext("Valid Until")?>: <b><?=$enddate ?></b>
1201
						</small>
1202
						<?php endif?>
1203
					</td>
1204
					<td>
1205
						<?php if (is_cert_revoked($cert)): ?>
1206
							<i><?=gettext("Revoked")?></i>
1207
						<?php endif?>
1208
						<?php if (is_webgui_cert($cert['refid'])): ?>
1209
							<?=gettext("webConfigurator")?>
1210
						<?php endif?>
1211
						<?php if (is_user_cert($cert['refid'])): ?>
1212
							<?=gettext("User Cert")?>
1213
						<?php endif?>
1214
						<?php if (is_openvpn_server_cert($cert['refid'])): ?>
1215
							<?=gettext("OpenVPN Server")?>
1216
						<?php endif?>
1217
						<?php if (is_openvpn_client_cert($cert['refid'])): ?>
1218
							<?=gettext("OpenVPN Client")?>
1219
						<?php endif?>
1220
						<?php if (is_ipsec_cert($cert['refid'])): ?>
1221
							<?=gettext("IPsec Tunnel")?>
1222
						<?php endif?>
1223
						<?php if (is_captiveportal_cert($cert['refid'])): ?>
1224
							<?=gettext("Captive Portal")?>
1225
						<?php endif?>
1226
						<?php echo cert_usedby_description($cert['refid'], $certificates_used_by_packages); ?>
1227
					</td>
1228
					<td>
1229
						<?php if (!$cert['csr']): ?>
1230
							<a href="system_certmanager.php?act=exp&amp;id=<?=$i?>" class="fa fa-certificate" title="<?=gettext("Export Certificate")?>"></a>
1231
							<?php if ($cert['prv']): ?>
1232
								<a href="system_certmanager.php?act=key&amp;id=<?=$i?>" class="fa fa-key" title="<?=gettext("Export Key")?>"></a>
1233
							<?php endif?>
1234
							<a href="system_certmanager.php?act=p12&amp;id=<?=$i?>" class="fa fa-archive" title="<?=gettext("Export P12")?>"></a>
1235
						<?php else: ?>
1236
							<a href="system_certmanager.php?act=csr&amp;id=<?=$i?>" class="fa fa-pencil" title="<?=gettext("Update CSR")?>"></a>
1237
							<a href="system_certmanager.php?act=req&amp;id=<?=$i?>" class="fa fa-sign-in" title="<?=gettext("Export Request")?>"></a>
1238
							<a href="system_certmanager.php?act=key&amp;id=<?=$i?>" class="fa fa-key" title="<?=gettext("Export Key")?>"></a>
1239
						<?php endif?>
1240
						<?php if (!cert_in_use($cert['refid'])): ?>
1241
							<a href="system_certmanager.php?act=del&amp;id=<?=$i?>" class="fa fa-trash" title="<?=gettext("Delete Certificate")?>" usepost></a>
1242
						<?php endif?>
1243
					</td>
1244
				</tr>
1245
<?php
1246
	$i++;
1247
	endforeach; ?>
1248
			</tbody>
1249
		</table>
1250
		</div>
1251
	</div>
1252
</div>
1253

    
1254
<nav class="action-buttons">
1255
	<a href="?act=new" class="btn btn-success btn-sm">
1256
		<i class="fa fa-plus icon-embed-btn"></i>
1257
		<?=gettext("Add/Sign")?>
1258
	</a>
1259
</nav>
1260
<?php
1261
	include("foot.inc");
1262
	exit;
1263
}
1264

    
1265

    
1266
?>
1267
<script type="text/javascript">
1268
//<![CDATA[
1269
events.push(function() {
1270

    
1271
<?php if ($internal_ca_count): ?>
1272
	function internalca_change() {
1273

    
1274
		caref = $('#caref').val();
1275

    
1276
		switch (caref) {
1277
<?php
1278
			foreach ($a_ca as $ca):
1279
				if (!$ca['prv']) {
1280
					continue;
1281
				}
1282

    
1283
				$subject = cert_get_subject_array($ca['crt']);
1284
?>
1285
				case "<?=$ca['refid'];?>":
1286
					$('#dn_country').val(<?=json_encode(cert_escape_x509_chars($subject[0]['v'], true));?>);
1287
					$('#dn_state').val(<?=json_encode(cert_escape_x509_chars($subject[1]['v'], true));?>);
1288
					$('#dn_city').val(<?=json_encode(cert_escape_x509_chars($subject[2]['v'], true));?>);
1289
					$('#dn_organization').val(<?=json_encode(cert_escape_x509_chars($subject[3]['v'], true));?>);
1290
					$('#dn_email').val(<?=json_encode(cert_escape_x509_chars($subject[4]['v'], true));?>);
1291
					$('#dn_organizationalunit').val(<?=json_encode(cert_escape_x509_chars($subject[6]['v'], true));?>);
1292
					break;
1293
<?php
1294
			endforeach;
1295
?>
1296
		}
1297
	}
1298

    
1299
	function set_csr_ro() {
1300
		var newcsr = ($('#csrtosign').val() == "new");
1301

    
1302
		$('#csrpaste').attr('readonly', !newcsr);
1303
		$('#keypaste').attr('readonly', !newcsr);
1304
		setRequired('csrpaste', newcsr);
1305
	}
1306

    
1307
	// ---------- Click checkbox handlers ---------------------------------------------------------
1308

    
1309
	$('#caref').on('change', function() {
1310
		internalca_change();
1311
	});
1312

    
1313
	$('#csrtosign').change(function () {
1314
		set_csr_ro();
1315
	});
1316

    
1317
	// ---------- On initial page load ------------------------------------------------------------
1318

    
1319
	internalca_change();
1320
	set_csr_ro();
1321

    
1322
	// Suppress "Delete row" button if there are fewer than two rows
1323
	checkLastRow();
1324

    
1325
<?php endif; ?>
1326

    
1327

    
1328
});
1329
//]]>
1330
</script>
1331
<?php
1332
include('foot.inc');
(196-196/228)