Project

General

Profile

Download (21.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * system_camanager.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2019 Rubicon Communications, LLC (Netgate)
9
 * Copyright (c) 2008 Shrew Soft Inc
10
 * All rights reserved.
11
 *
12
 * Licensed under the Apache License, Version 2.0 (the "License");
13
 * you may not use this file except in compliance with the License.
14
 * You may obtain a copy of the License at
15
 *
16
 * http://www.apache.org/licenses/LICENSE-2.0
17
 *
18
 * Unless required by applicable law or agreed to in writing, software
19
 * distributed under the License is distributed on an "AS IS" BASIS,
20
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
 * See the License for the specific language governing permissions and
22
 * limitations under the License.
23
 */
24

    
25
##|+PRIV
26
##|*IDENT=page-system-camanager
27
##|*NAME=System: CA Manager
28
##|*DESCR=Allow access to the 'System: CA Manager' page.
29
##|*MATCH=system_camanager.php*
30
##|-PRIV
31

    
32
require_once("guiconfig.inc");
33
require_once("certs.inc");
34
require_once("pfsense-utils.inc");
35

    
36
$ca_methods = array(
37
	"internal" => gettext("Create an internal Certificate Authority"),
38
	"existing" => gettext("Import an existing Certificate Authority"),
39
	"intermediate" => gettext("Create an intermediate Certificate Authority"));
40

    
41
$ca_keylens = array("1024", "2048", "3072", "4096", "6144", "7680", "8192", "15360", "16384");
42
$ca_keytypes = array("RSA", "ECDSA");
43
global $openssl_digest_algs;
44
$openssl_ecnames = openssl_get_curve_names();
45

    
46
if (isset($_REQUEST['id']) && is_numericint($_REQUEST['id'])) {
47
	$id = $_REQUEST['id'];
48
}
49

    
50
init_config_arr(array('ca'));
51
$a_ca = &$config['ca'];
52

    
53
init_config_arr(array('cert'));
54
$a_cert = &$config['cert'];
55

    
56
init_config_arr(array('crl'));
57
$a_crl = &$config['crl'];
58

    
59
if ($_REQUEST['act']) {
60
	$act = $_REQUEST['act'];
61
}
62

    
63
if ($_POST['act'] == "del") {
64

    
65
	if (!isset($a_ca[$id])) {
66
		pfSenseHeader("system_camanager.php");
67
		exit;
68
	}
69

    
70
	/* Only remove CA reference when deleting. It can be reconnected if a new matching CA is imported */
71
	$index = count($a_cert) - 1;
72
	for (;$index >= 0; $index--) {
73
		if ($a_cert[$index]['caref'] == $a_ca[$id]['refid']) {
74
			unset($a_cert[$index]['caref']);
75
		}
76
	}
77

    
78
	/* Remove any CRLs for this CA, there is no way to recover the connection once the CA has been removed. */
79
	$index = count($a_crl) - 1;
80
	for (;$index >= 0; $index--) {
81
		if ($a_crl[$index]['caref'] == $a_ca[$id]['refid']) {
82
			unset($a_crl[$index]);
83
		}
84
	}
85

    
86
	$name = $a_ca[$id]['descr'];
87
	unset($a_ca[$id]);
88
	write_config();
89
	$savemsg = sprintf(gettext("Certificate Authority %s and its CRLs (if any) successfully deleted."), htmlspecialchars($name));
90
	pfSenseHeader("system_camanager.php");
91
	exit;
92
}
93

    
94
if ($act == "edit") {
95
	if (!$a_ca[$id]) {
96
		pfSenseHeader("system_camanager.php");
97
		exit;
98
	}
99
	$pconfig['method'] = 'existing';
100
	$pconfig['descr']  = $a_ca[$id]['descr'];
101
	$pconfig['refid']  = $a_ca[$id]['refid'];
102
	$pconfig['cert']   = base64_decode($a_ca[$id]['crt']);
103
	$pconfig['serial'] = $a_ca[$id]['serial'];
104
	if (!empty($a_ca[$id]['prv'])) {
105
		$pconfig['key'] = base64_decode($a_ca[$id]['prv']);
106
	}
107
}
108

    
109
if ($act == "new") {
110
	$pconfig['method'] = $_POST['method'];
111
	$pconfig['keytype'] = "RSA";
112
	$pconfig['keylen'] = "2048";
113
	$pconfig['ecname'] = "brainpoolP256r1";
114
	$pconfig['digest_alg'] = "sha256";
115
	$pconfig['lifetime'] = "3650";
116
	$pconfig['dn_commonname'] = "internal-ca";
117
}
118

    
119
if ($act == "exp") {
120

    
121
	if (!$a_ca[$id]) {
122
		pfSenseHeader("system_camanager.php");
123
		exit;
124
	}
125

    
126
	$exp_name = urlencode("{$a_ca[$id]['descr']}.crt");
127
	$exp_data = base64_decode($a_ca[$id]['crt']);
128
	$exp_size = strlen($exp_data);
129

    
130
	header("Content-Type: application/octet-stream");
131
	header("Content-Disposition: attachment; filename={$exp_name}");
132
	header("Content-Length: $exp_size");
133
	echo $exp_data;
134
	exit;
135
}
136

    
137
if ($act == "expkey") {
138

    
139
	if (!$a_ca[$id]) {
140
		pfSenseHeader("system_camanager.php");
141
		exit;
142
	}
143

    
144
	$exp_name = urlencode("{$a_ca[$id]['descr']}.key");
145
	$exp_data = base64_decode($a_ca[$id]['prv']);
146
	$exp_size = strlen($exp_data);
147

    
148
	header("Content-Type: application/octet-stream");
149
	header("Content-Disposition: attachment; filename={$exp_name}");
150
	header("Content-Length: $exp_size");
151
	echo $exp_data;
152
	exit;
153
}
154

    
155
if ($_POST['save']) {
156

    
157
	unset($input_errors);
158
	$input_errors = array();
159
	$pconfig = $_POST;
160

    
161
	/* input validation */
162
	if ($pconfig['method'] == "existing") {
163
		$reqdfields = explode(" ", "descr cert");
164
		$reqdfieldsn = array(
165
			gettext("Descriptive name"),
166
			gettext("Certificate data"));
167
		if ($_POST['cert'] && (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE"))) {
168
			$input_errors[] = gettext("This certificate does not appear to be valid.");
169
		}
170
		if ($_POST['key'] && strstr($_POST['key'], "ENCRYPTED")) {
171
			$input_errors[] = gettext("Encrypted private keys are not yet supported.");
172
		}
173
		if (!$input_errors && !empty($_POST['key']) && cert_get_publickey($_POST['cert'], false) != cert_get_publickey($_POST['key'], false, 'prv')) {
174
			$input_errors[] = gettext("The submitted private key does not match the submitted certificate data.");
175
		}
176
		/* we must ensure the certificate is capable of acting as a CA
177
		 * https://redmine.pfsense.org/issues/7885
178
		 */
179
		if (!$input_errors) {
180
			$purpose = cert_get_purpose($_POST['cert'], false);
181
			if ($purpose['ca'] != 'Yes') {
182
				$input_errors[] = gettext("The submitted certificate does not appear to be a Certificate Authority, import it on the Certificates tab instead.");
183
			}
184
		}
185
	}
186
	if ($pconfig['method'] == "internal") {
187
		$reqdfields = explode(" ",
188
			"descr keylen ecname keytype lifetime dn_commonname");
189
		$reqdfieldsn = array(
190
			gettext("Descriptive name"),
191
			gettext("Key length"),
192
			gettext("Elliptic Curve Name"),
193
			gettext("Key type"),
194
			gettext("Lifetime"),
195
			gettext("Common Name"));
196
	}
197
	if ($pconfig['method'] == "intermediate") {
198
		$reqdfields = explode(" ",
199
			"descr caref keylen ecname keytype lifetime dn_commonname");
200
		$reqdfieldsn = array(
201
			gettext("Descriptive name"),
202
			gettext("Signing Certificate Authority"),
203
			gettext("Key length"),
204
			gettext("Elliptic Curve Name"),
205
			gettext("Key type"),
206
			gettext("Lifetime"),
207
			gettext("Common Name"));
208
	}
209

    
210
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
211
	if ($pconfig['method'] != "existing") {
212
		/* Make sure we do not have invalid characters in the fields for the certificate */
213
		if (preg_match("/[\?\>\<\&\/\\\"\']/", $_POST['descr'])) {
214
			array_push($input_errors, gettext("The field 'Descriptive Name' contains invalid characters."));
215
		}
216
		if (!in_array($_POST["keytype"], $ca_keytypes)) {
217
			array_push($input_errors, gettext("Please select a valid Key Type."));
218
		}
219
		if (!in_array($_POST["keylen"], $ca_keylens)) {
220
			array_push($input_errors, gettext("Please select a valid Key Length."));
221
		}
222
		if (!in_array($_POST["ecname"], $openssl_ecnames)) {
223
			array_push($input_errors, gettext("Please select a valid Elliptic Curve Name."));
224
		}
225
		if (!in_array($_POST["digest_alg"], $openssl_digest_algs)) {
226
			array_push($input_errors, gettext("Please select a valid Digest Algorithm."));
227
		}
228
	}
229

    
230
	/* save modifications */
231
	if (!$input_errors) {
232
		$ca = array();
233
		if (!isset($pconfig['refid']) || empty($pconfig['refid'])) {
234
			$ca['refid'] = uniqid();
235
		} else {
236
			$ca['refid'] = $pconfig['refid'];
237
		}
238

    
239
		if (isset($id) && $a_ca[$id]) {
240
			$ca = $a_ca[$id];
241
		}
242

    
243
		$ca['descr'] = $pconfig['descr'];
244

    
245
		if ($act == "edit") {
246
			$ca['descr']  = $pconfig['descr'];
247
			$ca['refid']  = $pconfig['refid'];
248
			$ca['serial'] = $pconfig['serial'];
249
			$ca['crt']	  = base64_encode($pconfig['cert']);
250
			if (!empty($pconfig['key'])) {
251
				$ca['prv']	  = base64_encode($pconfig['key']);
252
			}
253
		} else {
254
			$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
255
			if ($pconfig['method'] == "existing") {
256
				ca_import($ca, $pconfig['cert'], $pconfig['key'], $pconfig['serial']);
257
			} else if ($pconfig['method'] == "internal") {
258
				$dn = array('commonName' => cert_escape_x509_chars($pconfig['dn_commonname']));
259
				if (!empty($pconfig['dn_country'])) {
260
					$dn['countryName'] = $pconfig['dn_country'];
261
				}
262
				if (!empty($pconfig['dn_state'])) {
263
					$dn['stateOrProvinceName'] = cert_escape_x509_chars($pconfig['dn_state']);
264
				}
265
				if (!empty($pconfig['dn_city'])) {
266
					$dn['localityName'] = cert_escape_x509_chars($pconfig['dn_city']);
267
				}
268
				if (!empty($pconfig['dn_organization'])) {
269
					$dn['organizationName'] = cert_escape_x509_chars($pconfig['dn_organization']);
270
				}
271
				if (!empty($pconfig['dn_organizationalunit'])) {
272
					$dn['organizationalUnitName'] = cert_escape_x509_chars($pconfig['dn_organizationalunit']);
273
				}
274
				if (!ca_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['digest_alg'], $pconfig['keytype'], $pconfig['ecname'])) {
275
					$input_errors = array();
276
					while ($ssl_err = openssl_error_string()) {
277
						if (strpos($ssl_err, 'NCONF_get_string:no value') === false) {
278
							array_push($input_errors, "openssl library returns: " . $ssl_err);
279
						}
280
					}
281
				}
282
			} else if ($pconfig['method'] == "intermediate") {
283
				$dn = array('commonName' => cert_escape_x509_chars($pconfig['dn_commonname']));
284
				if (!empty($pconfig['dn_country'])) {
285
					$dn['countryName'] = $pconfig['dn_country'];
286
				}
287
				if (!empty($pconfig['dn_state'])) {
288
					$dn['stateOrProvinceName'] = cert_escape_x509_chars($pconfig['dn_state']);
289
				}
290
				if (!empty($pconfig['dn_city'])) {
291
					$dn['localityName'] = cert_escape_x509_chars($pconfig['dn_city']);
292
				}
293
				if (!empty($pconfig['dn_organization'])) {
294
					$dn['organizationName'] = cert_escape_x509_chars($pconfig['dn_organization']);
295
				}
296
				if (!empty($pconfig['dn_organizationalunit'])) {
297
					$dn['organizationalUnitName'] = cert_escape_x509_chars($pconfig['dn_organizationalunit']);
298
				}
299
				if (!ca_inter_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['caref'], $pconfig['digest_alg'], $pconfig['keytype'], $pconfig['ecname'])) {
300
					$input_errors = array();
301
					while ($ssl_err = openssl_error_string()) {
302
						if (strpos($ssl_err, 'NCONF_get_string:no value') === false) {
303
							array_push($input_errors, "openssl library returns: " . $ssl_err);
304
						}
305
					}
306
				}
307
			}
308
			error_reporting($old_err_level);
309
		}
310

    
311
		if (isset($id) && $a_ca[$id]) {
312
			$a_ca[$id] = $ca;
313
		} else {
314
			$a_ca[] = $ca;
315
		}
316

    
317
		if (!$input_errors) {
318
			write_config();
319
			pfSenseHeader("system_camanager.php");
320
		}
321
	}
322
}
323

    
324
$pgtitle = array(gettext("System"), gettext("Certificate Manager"), gettext("CAs"));
325
$pglinks = array("", "system_camanager.php", "system_camanager.php");
326

    
327
if ($act == "new" || $act == "edit" || $act == gettext("Save") || $input_errors) {
328
	$pgtitle[] = gettext('Edit');
329
	$pglinks[] = "@self";
330
}
331
include("head.inc");
332

    
333
if ($input_errors) {
334
	print_input_errors($input_errors);
335
}
336

    
337
if ($savemsg) {
338
	print_info_box($savemsg, 'success');
339
}
340

    
341
$tab_array = array();
342
$tab_array[] = array(gettext("CAs"), true, "system_camanager.php");
343
$tab_array[] = array(gettext("Certificates"), false, "system_certmanager.php");
344
$tab_array[] = array(gettext("Certificate Revocation"), false, "system_crlmanager.php");
345
display_top_tabs($tab_array);
346

    
347
if (!($act == "new" || $act == "edit" || $act == gettext("Save") || $input_errors)) {
348
?>
349
<div class="panel panel-default" id="search-panel">
350
	<div class="panel-heading">
351
		<h2 class="panel-title">
352
			<?=gettext('Search')?>
353
			<span class="widget-heading-icon pull-right">
354
				<a data-toggle="collapse" href="#search-panel_panel-body">
355
					<i class="fa fa-plus-circle"></i>
356
				</a>
357
			</span>
358
		</h2>
359
	</div>
360
	<div id="search-panel_panel-body" class="panel-body collapse in">
361
		<div class="form-group">
362
			<label class="col-sm-2 control-label">
363
				<?=gettext("Search term")?>
364
			</label>
365
			<div class="col-sm-5"><input class="form-control" name="searchstr" id="searchstr" type="text"/></div>
366
			<div class="col-sm-2">
367
				<select id="where" class="form-control">
368
					<option value="0"><?=gettext("Name")?></option>
369
					<option value="1"><?=gettext("Distinguished Name")?></option>
370
					<option value="2" selected><?=gettext("Both")?></option>
371
				</select>
372
			</div>
373
			<div class="col-sm-3">
374
				<a id="btnsearch" title="<?=gettext("Search")?>" class="btn btn-primary btn-sm"><i class="fa fa-search icon-embed-btn"></i><?=gettext("Search")?></a>
375
				<a id="btnclear" title="<?=gettext("Clear")?>" class="btn btn-info btn-sm"><i class="fa fa-undo icon-embed-btn"></i><?=gettext("Clear")?></a>
376
			</div>
377
			<div class="col-sm-10 col-sm-offset-2">
378
				<span class="help-block"><?=gettext('Enter a search string or *nix regular expression to search certificate names and distinguished names.')?></span>
379
			</div>
380
		</div>
381
	</div>
382
</div>
383

    
384
<div class="panel panel-default">
385
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Certificate Authorities')?></h2></div>
386
	<div class="panel-body">
387
		<div class="table-responsive">
388
		<table id="catable" class="table table-striped table-hover table-rowdblclickedit sortable-theme-bootstrap" data-sortable>
389
			<thead>
390
				<tr>
391
					<th><?=gettext("Name")?></th>
392
					<th><?=gettext("Internal")?></th>
393
					<th><?=gettext("Issuer")?></th>
394
					<th><?=gettext("Certificates")?></th>
395
					<th><?=gettext("Distinguished Name")?></th>
396
					<th><?=gettext("In Use")?></th>
397
					<th><?=gettext("Actions")?></th>
398
				</tr>
399
			</thead>
400
			<tbody>
401
<?php
402
$pluginparams = array();
403
$pluginparams['type'] = 'certificates';
404
$pluginparams['event'] = 'used_ca';
405
$certificates_used_by_packages = pkg_call_plugins('plugin_certificates', $pluginparams);
406

    
407
foreach ($a_ca as $i => $ca):
408
	$name = htmlspecialchars($ca['descr']);
409
	$subj = cert_get_subject($ca['crt']);
410
	$issuer = cert_get_issuer($ca['crt']);
411
	if ($subj == $issuer) {
412
		$issuer_name = gettext("self-signed");
413
	} else {
414
		$issuer_name = gettext("external");
415
	}
416
	$subj = htmlspecialchars(cert_escape_x509_chars($subj, true));
417
	$issuer = htmlspecialchars($issuer);
418
	$certcount = 0;
419

    
420
	$issuer_ca = lookup_ca($ca['caref']);
421
	if ($issuer_ca) {
422
		$issuer_name = $issuer_ca['descr'];
423
	}
424

    
425
	foreach ($a_cert as $cert) {
426
		if ($cert['caref'] == $ca['refid']) {
427
			$certcount++;
428
		}
429
	}
430

    
431
	foreach ($a_ca as $cert) {
432
		if ($cert['caref'] == $ca['refid']) {
433
			$certcount++;
434
		}
435
	}
436
?>
437
				<tr>
438
					<td><?=$name?></td>
439
					<td><i class="fa fa-<?= (!empty($ca['prv'])) ? "check" : "times" ; ?>"></i></td>
440
					<td><i><?=$issuer_name?></i></td>
441
					<td><?=$certcount?></td>
442
					<td>
443
						<?=$subj?>
444
						<?php cert_print_infoblock($ca); ?>
445
						<?php cert_print_dates($ca);?>
446
					</td>
447
					<td class="text-nowrap">
448
						<?php if (is_openvpn_server_ca($ca['refid'])): ?>
449
							<?=gettext("OpenVPN Server")?><br/>
450
						<?php endif?>
451
						<?php if (is_openvpn_client_ca($ca['refid'])): ?>
452
							<?=gettext("OpenVPN Client")?><br/>
453
						<?php endif?>
454
						<?php if (is_ipsec_peer_ca($ca['refid'])): ?>
455
							<?=gettext("IPsec Tunnel")?><br/>
456
						<?php endif?>
457
						<?php if (is_ldap_peer_ca($ca['refid'])): ?>
458
							<?=gettext("LDAP Server")?>
459
						<?php endif?>
460
						<?php echo cert_usedby_description($ca['refid'], $certificates_used_by_packages); ?>
461
					</td>
462
					<td class="text-nowrap">
463
						<a class="fa fa-pencil"	title="<?=gettext("Edit CA")?>"	href="system_camanager.php?act=edit&amp;id=<?=$i?>"></a>
464
						<a class="fa fa-certificate"	title="<?=gettext("Export CA")?>"	href="system_camanager.php?act=exp&amp;id=<?=$i?>"></a>
465
					<?php if ($ca['prv']): ?>
466
						<a class="fa fa-key"	title="<?=gettext("Export key")?>"	href="system_camanager.php?act=expkey&amp;id=<?=$i?>"></a>
467
					<?php endif?>
468
					<?php if (is_cert_locally_renewable($ca)): ?>
469
						<a href="system_certmanager_renew.php?type=ca&amp;refid=<?=$ca['refid']?>" class="fa fa-repeat" title="<?=gettext("Reissue/Renew")?>"></a>
470
					<?php endif ?>
471
					<?php if (!ca_in_use($ca['refid'])): ?>
472
						<a class="fa fa-trash" 	title="<?=gettext("Delete CA and its CRLs")?>"	href="system_camanager.php?act=del&amp;id=<?=$i?>" usepost ></a>
473
					<?php endif?>
474
					</td>
475
				</tr>
476
<?php endforeach; ?>
477
			</tbody>
478
		</table>
479
		</div>
480
	</div>
481
</div>
482

    
483
<nav class="action-buttons">
484
	<a href="?act=new" class="btn btn-success btn-sm">
485
		<i class="fa fa-plus icon-embed-btn"></i>
486
		<?=gettext("Add")?>
487
	</a>
488
</nav>
489
<script type="text/javascript">
490
//<![CDATA[
491

    
492
events.push(function() {
493

    
494
	// Make these controls plain buttons
495
	$("#btnsearch").prop('type', 'button');
496
	$("#btnclear").prop('type', 'button');
497

    
498
	// Search for a term in the entry name and/or dn
499
	$("#btnsearch").click(function() {
500
		var searchstr = $('#searchstr').val().toLowerCase();
501
		var table = $("table tbody");
502
		var where = $('#where').val();
503

    
504
		table.find('tr').each(function (i) {
505
			var $tds = $(this).find('td'),
506
				shortname = $tds.eq(0).text().trim().toLowerCase(),
507
				dn = $tds.eq(4).text().trim().toLowerCase();
508

    
509
			regexp = new RegExp(searchstr);
510
			if (searchstr.length > 0) {
511
				if (!(regexp.test(shortname) && (where != 1)) && !(regexp.test(dn) && (where != 0))) {
512
					$(this).hide();
513
				} else {
514
					$(this).show();
515
				}
516
			} else {
517
				$(this).show();	// A blank search string shows all
518
			}
519
		});
520
	});
521

    
522
	// Clear the search term and unhide all rows (that were hidden during a previous search)
523
	$("#btnclear").click(function() {
524
		var table = $("table tbody");
525

    
526
		$('#searchstr').val("");
527

    
528
		table.find('tr').each(function (i) {
529
			$(this).show();
530
		});
531
	});
532

    
533
	// Hitting the enter key will do the same as clicking the search button
534
	$("#searchstr").on("keyup", function (event) {
535
		if (event.keyCode == 13) {
536
			$("#btnsearch").get(0).click();
537
		}
538
	});
539
});
540
//]]>
541
</script>
542

    
543
<?php
544
	include("foot.inc");
545
	exit;
546
}
547

    
548
$form = new Form;
549
//$form->setAction('system_camanager.php?act=edit');
550
if (isset($id) && $a_ca[$id]) {
551
	$form->addGlobal(new Form_Input(
552
		'id',
553
		null,
554
		'hidden',
555
		$id
556
	));
557
}
558

    
559
if ($act == "edit") {
560
	$form->addGlobal(new Form_Input(
561
		'refid',
562
		null,
563
		'hidden',
564
		$pconfig['refid']
565
	));
566
}
567

    
568
$section = new Form_Section('Create / Edit CA');
569

    
570
$section->addInput(new Form_Input(
571
	'descr',
572
	'*Descriptive name',
573
	'text',
574
	$pconfig['descr']
575
));
576

    
577
if (!isset($id) || $act == "edit") {
578
	$section->addInput(new Form_Select(
579
		'method',
580
		'*Method',
581
		$pconfig['method'],
582
		$ca_methods
583
	))->toggles();
584
}
585

    
586
$form->add($section);
587

    
588
$section = new Form_Section('Existing Certificate Authority');
589
$section->addClass('toggle-existing collapse');
590

    
591
$section->addInput(new Form_Textarea(
592
	'cert',
593
	'*Certificate data',
594
	$pconfig['cert']
595
))->setHelp('Paste a certificate in X.509 PEM format here.');
596

    
597
$section->addInput(new Form_Textarea(
598
	'key',
599
	'Certificate Private Key (optional)',
600
	$pconfig['key']
601
))->setHelp('Paste the private key for the above certificate here. This is '.
602
	'optional in most cases, but is required when generating a '.
603
	'Certificate Revocation List (CRL).');
604

    
605
$section->addInput(new Form_Input(
606
	'serial',
607
	'Serial for next certificate',
608
	'number',
609
	$pconfig['serial']
610
))->setHelp('Enter a decimal number to be used as the serial number for the next '.
611
	'certificate to be created using this CA.');
612

    
613
$form->add($section);
614

    
615
$section = new Form_Section('Internal Certificate Authority');
616
$section->addClass('toggle-internal', 'toggle-intermediate', 'collapse');
617

    
618
$allCas = array();
619
foreach ($a_ca as $ca) {
620
	if (!$ca['prv']) {
621
			continue;
622
	}
623

    
624
	$allCas[ $ca['refid'] ] = $ca['descr'];
625
}
626

    
627
$group = new Form_Group('*Signing Certificate Authority');
628
$group->addClass('toggle-intermediate', 'collapse');
629
$group->add(new Form_Select(
630
	'caref',
631
	null,
632
	$pconfig['caref'],
633
	$allCas
634
));
635
$section->add($group);
636

    
637
$section->addInput(new Form_Select(
638
	'keytype',
639
	'*Key type',
640
	$pconfig['keytype'],
641
	array_combine($ca_keytypes, $ca_keytypes)
642
));
643

    
644
$group = new Form_Group($i == 0 ? '*Key length':'');
645
$group->addClass('rsakeys');
646
$group->add(new Form_Select(
647
	'keylen',
648
	null,
649
	$pconfig['keylen'],
650
	array_combine($ca_keylens, $ca_keylens)
651
));
652
$section->add($group);
653

    
654
$group = new Form_Group($i == 0 ? '*Elliptic Curve Name':'');
655
$group->addClass('ecnames');
656
$group->add(new Form_Select(
657
	'ecname',
658
	null,
659
	$pconfig['ecname'],
660
	array_combine($openssl_ecnames, $openssl_ecnames)
661
));
662
$section->add($group);
663

    
664
$section->addInput(new Form_Select(
665
	'digest_alg',
666
	'*Digest Algorithm',
667
	$pconfig['digest_alg'],
668
	array_combine($openssl_digest_algs, $openssl_digest_algs)
669
))->setHelp('NOTE: It is recommended to use an algorithm stronger than SHA1 '.
670
	'when possible.');
671

    
672
$section->addInput(new Form_Input(
673
	'lifetime',
674
	'*Lifetime (days)',
675
	'number',
676
	$pconfig['lifetime']
677
));
678

    
679
$section->addInput(new Form_Input(
680
	'dn_commonname',
681
	'*Common Name',
682
	'text',
683
	$pconfig['dn_commonname'],
684
	['placeholder' => 'e.g. internal-ca']
685
));
686

    
687
$section->addInput(new Form_StaticText(
688
	null,
689
	gettext('The following certificate authority subject components are optional and may be left blank.')
690
));
691

    
692
$section->addInput(new Form_Select(
693
	'dn_country',
694
	'Country Code',
695
	$pconfig['dn_country'],
696
	get_cert_country_codes()
697
));
698

    
699
$section->addInput(new Form_Input(
700
	'dn_state',
701
	'State or Province',
702
	'text',
703
	$pconfig['dn_state'],
704
	['placeholder' => 'e.g. Texas']
705
));
706

    
707
$section->addInput(new Form_Input(
708
	'dn_city',
709
	'City',
710
	'text',
711
	$pconfig['dn_city'],
712
	['placeholder' => 'e.g. Austin']
713
));
714

    
715
$section->addInput(new Form_Input(
716
	'dn_organization',
717
	'Organization',
718
	'text',
719
	$pconfig['dn_organization'],
720
	['placeholder' => 'e.g. My Company Inc']
721
));
722

    
723
$section->addInput(new Form_Input(
724
	'dn_organizationalunit',
725
	'Organizational Unit',
726
	'text',
727
	$pconfig['dn_organizationalunit'],
728
	['placeholder' => 'e.g. My Department Name (optional)']
729
));
730

    
731
$form->add($section);
732

    
733
print $form;
734

    
735
$internal_ca_count = 0;
736
foreach ($a_ca as $ca) {
737
	if ($ca['prv']) {
738
		$internal_ca_count++;
739
	}
740
}
741

    
742
?>
743
<script type="text/javascript">
744
//<![CDATA[
745
events.push(function() {
746
	function change_keytype() {
747
	hideClass('rsakeys', ($('#keytype').val() != 'RSA'));
748
		hideClass('ecnames', ($('#keytype').val() != 'ECDSA'));
749
	}
750

    
751
	$('#keytype').change(function () {
752
		change_keytype();
753
	});
754

    
755
	// ---------- On initial page load ------------------------------------------------------------
756
	change_keytype();
757
});
758
//]]>
759
</script>
760
<?php
761
include('foot.inc');
(192-192/227)