Project

General

Profile

Download (20.1 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-2019 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-camanager
25
##|*NAME=System: CA Manager
26
##|*DESCR=Allow access to the 'System: CA Manager' page.
27
##|*MATCH=system_camanager.php*
28
##|-PRIV
29

    
30
require_once("guiconfig.inc");
31
require_once("certs.inc");
32
require_once("pfsense-utils.inc");
33

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

    
39
$ca_keylens = array("1024", "2048", "3072", "4096", "6144", "7680", "8192", "15360", "16384");
40
global $openssl_digest_algs;
41

    
42
if (isset($_REQUEST['id']) && is_numericint($_REQUEST['id'])) {
43
	$id = $_REQUEST['id'];
44
}
45

    
46
init_config_arr(array('ca'));
47
$a_ca = &$config['ca'];
48

    
49
init_config_arr(array('cert'));
50
$a_cert = &$config['cert'];
51

    
52
init_config_arr(array('crl'));
53
$a_crl = &$config['crl'];
54

    
55
if ($_REQUEST['act']) {
56
	$act = $_REQUEST['act'];
57
}
58

    
59
if ($_POST['act'] == "del") {
60

    
61
	if (!isset($a_ca[$id])) {
62
		pfSenseHeader("system_camanager.php");
63
		exit;
64
	}
65

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

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

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

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

    
105
if ($act == "new") {
106
	$pconfig['method'] = $_POST['method'];
107
	$pconfig['keylen'] = "2048";
108
	$pconfig['digest_alg'] = "sha256";
109
	$pconfig['lifetime'] = "3650";
110
	$pconfig['dn_commonname'] = "internal-ca";
111
}
112

    
113
if ($act == "exp") {
114

    
115
	if (!$a_ca[$id]) {
116
		pfSenseHeader("system_camanager.php");
117
		exit;
118
	}
119

    
120
	$exp_name = urlencode("{$a_ca[$id]['descr']}.crt");
121
	$exp_data = base64_decode($a_ca[$id]['crt']);
122
	$exp_size = strlen($exp_data);
123

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

    
131
if ($act == "expkey") {
132

    
133
	if (!$a_ca[$id]) {
134
		pfSenseHeader("system_camanager.php");
135
		exit;
136
	}
137

    
138
	$exp_name = urlencode("{$a_ca[$id]['descr']}.key");
139
	$exp_data = base64_decode($a_ca[$id]['prv']);
140
	$exp_size = strlen($exp_data);
141

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

    
149
if ($_POST['save']) {
150

    
151
	unset($input_errors);
152
	$input_errors = array();
153
	$pconfig = $_POST;
154

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

    
200
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
201
	if ($pconfig['method'] != "existing") {
202
		/* Make sure we do not have invalid characters in the fields for the certificate */
203
		if (preg_match("/[\?\>\<\&\/\\\"\']/", $_POST['descr'])) {
204
			array_push($input_errors, gettext("The field 'Descriptive Name' contains invalid characters."));
205
		}
206
		if (!in_array($_POST["keylen"], $ca_keylens)) {
207
			array_push($input_errors, gettext("Please select a valid Key Length."));
208
		}
209
		if (!in_array($_POST["digest_alg"], $openssl_digest_algs)) {
210
			array_push($input_errors, gettext("Please select a valid Digest Algorithm."));
211
		}
212
	}
213

    
214
	/* save modifications */
215
	if (!$input_errors) {
216
		$ca = array();
217
		if (!isset($pconfig['refid']) || empty($pconfig['refid'])) {
218
			$ca['refid'] = uniqid();
219
		} else {
220
			$ca['refid'] = $pconfig['refid'];
221
		}
222

    
223
		if (isset($id) && $a_ca[$id]) {
224
			$ca = $a_ca[$id];
225
		}
226

    
227
		$ca['descr'] = $pconfig['descr'];
228

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

    
295
		if (isset($id) && $a_ca[$id]) {
296
			$a_ca[$id] = $ca;
297
		} else {
298
			$a_ca[] = $ca;
299
		}
300

    
301
		if (!$input_errors) {
302
			write_config();
303
			pfSenseHeader("system_camanager.php");
304
		}
305
	}
306
}
307

    
308
$pgtitle = array(gettext("System"), gettext("Certificate Manager"), gettext("CAs"));
309
$pglinks = array("", "system_camanager.php", "system_camanager.php");
310

    
311
if ($act == "new" || $act == "edit" || $act == gettext("Save") || $input_errors) {
312
	$pgtitle[] = gettext('Edit');
313
	$pglinks[] = "@self";
314
}
315
include("head.inc");
316

    
317
if ($input_errors) {
318
	print_input_errors($input_errors);
319
}
320

    
321
if ($savemsg) {
322
	print_info_box($savemsg, 'success');
323
}
324

    
325
$tab_array = array();
326
$tab_array[] = array(gettext("CAs"), true, "system_camanager.php");
327
$tab_array[] = array(gettext("Certificates"), false, "system_certmanager.php");
328
$tab_array[] = array(gettext("Certificate Revocation"), false, "system_crlmanager.php");
329
display_top_tabs($tab_array);
330

    
331
if (!($act == "new" || $act == "edit" || $act == gettext("Save") || $input_errors)) {
332
?>
333
<div class="panel panel-default" id="search-panel">
334
	<div class="panel-heading">
335
		<h2 class="panel-title">
336
			<?=gettext('Search')?>
337
			<span class="widget-heading-icon pull-right">
338
				<a data-toggle="collapse" href="#search-panel_panel-body">
339
					<i class="fa fa-plus-circle"></i>
340
				</a>
341
			</span>
342
		</h2>
343
	</div>
344
	<div id="search-panel_panel-body" class="panel-body collapse in">
345
		<div class="form-group">
346
			<label class="col-sm-2 control-label">
347
				<?=gettext("Search term")?>
348
			</label>
349
			<div class="col-sm-5"><input class="form-control" name="searchstr" id="searchstr" type="text"/></div>
350
			<div class="col-sm-2">
351
				<select id="where" class="form-control">
352
					<option value="0"><?=gettext("Name")?></option>
353
					<option value="1"><?=gettext("Distinguished Name")?></option>
354
					<option value="2" selected><?=gettext("Both")?></option>
355
				</select>
356
			</div>
357
			<div class="col-sm-3">
358
				<a id="btnsearch" title="<?=gettext("Search")?>" class="btn btn-primary btn-sm"><i class="fa fa-search icon-embed-btn"></i><?=gettext("Search")?></a>
359
				<a id="btnclear" title="<?=gettext("Clear")?>" class="btn btn-info btn-sm"><i class="fa fa-undo icon-embed-btn"></i><?=gettext("Clear")?></a>
360
			</div>
361
			<div class="col-sm-10 col-sm-offset-2">
362
				<span class="help-block"><?=gettext('Enter a search string or *nix regular expression to search certificate names and distinguished names.')?></span>
363
			</div>
364
		</div>
365
	</div>
366
</div>
367

    
368
<div class="panel panel-default">
369
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Certificate Authorities')?></h2></div>
370
	<div class="panel-body">
371
		<div class="table-responsive">
372
		<table id="catable" class="table table-striped table-hover table-rowdblclickedit sortable-theme-bootstrap" data-sortable>
373
			<thead>
374
				<tr>
375
					<th><?=gettext("Name")?></th>
376
					<th><?=gettext("Internal")?></th>
377
					<th><?=gettext("Issuer")?></th>
378
					<th><?=gettext("Certificates")?></th>
379
					<th><?=gettext("Distinguished Name")?></th>
380
					<th><?=gettext("In Use")?></th>
381
					<th><?=gettext("Actions")?></th>
382
				</tr>
383
			</thead>
384
			<tbody>
385
<?php
386
$pluginparams = array();
387
$pluginparams['type'] = 'certificates';
388
$pluginparams['event'] = 'used_ca';
389
$certificates_used_by_packages = pkg_call_plugins('plugin_certificates', $pluginparams);
390

    
391
foreach ($a_ca as $i => $ca):
392
	$name = htmlspecialchars($ca['descr']);
393
	$subj = cert_get_subject($ca['crt']);
394
	$issuer = cert_get_issuer($ca['crt']);
395
	list($startdate, $enddate) = cert_get_dates($ca['crt']);
396
	if ($subj == $issuer) {
397
		$issuer_name = gettext("self-signed");
398
	} else {
399
		$issuer_name = gettext("external");
400
	}
401
	$subj = htmlspecialchars(cert_escape_x509_chars($subj, true));
402
	$issuer = htmlspecialchars($issuer);
403
	$certcount = 0;
404

    
405
	$issuer_ca = lookup_ca($ca['caref']);
406
	if ($issuer_ca) {
407
		$issuer_name = $issuer_ca['descr'];
408
	}
409

    
410
	foreach ($a_cert as $cert) {
411
		if ($cert['caref'] == $ca['refid']) {
412
			$certcount++;
413
		}
414
	}
415

    
416
	foreach ($a_ca as $cert) {
417
		if ($cert['caref'] == $ca['refid']) {
418
			$certcount++;
419
		}
420
	}
421
?>
422
				<tr>
423
					<td><?=$name?></td>
424
					<td><i class="fa fa-<?= (!empty($ca['prv'])) ? "check" : "times" ; ?>"></i></td>
425
					<td><i><?=$issuer_name?></i></td>
426
					<td><?=$certcount?></td>
427
					<td>
428
						<?=$subj?>
429
						<br />
430
						<small>
431
							<?=gettext("Valid From")?>: <b><?=$startdate ?></b><br /><?=gettext("Valid Until")?>: <b><?=$enddate ?></b>
432
						</small>
433
					</td>
434
					<td class="text-nowrap">
435
						<?php if (is_openvpn_server_ca($ca['refid'])): ?>
436
							<?=gettext("OpenVPN Server")?><br/>
437
						<?php endif?>
438
						<?php if (is_openvpn_client_ca($ca['refid'])): ?>
439
							<?=gettext("OpenVPN Client")?><br/>
440
						<?php endif?>
441
						<?php if (is_ipsec_peer_ca($ca['refid'])): ?>
442
							<?=gettext("IPsec Tunnel")?><br/>
443
						<?php endif?>
444
						<?php if (is_ldap_peer_ca($ca['refid'])): ?>
445
							<?=gettext("LDAP Server")?>
446
						<?php endif?>
447
						<?php echo cert_usedby_description($ca['refid'], $certificates_used_by_packages); ?>
448
					</td>
449
					<td class="text-nowrap">
450
						<a class="fa fa-pencil"	title="<?=gettext("Edit CA")?>"	href="system_camanager.php?act=edit&amp;id=<?=$i?>"></a>
451
						<a class="fa fa-certificate"	title="<?=gettext("Export CA")?>"	href="system_camanager.php?act=exp&amp;id=<?=$i?>"></a>
452
					<?php if ($ca['prv']): ?>
453
						<a class="fa fa-key"	title="<?=gettext("Export key")?>"	href="system_camanager.php?act=expkey&amp;id=<?=$i?>"></a>
454
					<?php endif?>
455
					<?php if (!ca_in_use($ca['refid'])): ?>
456
						<a class="fa fa-trash" 	title="<?=gettext("Delete CA and its CRLs")?>"	href="system_camanager.php?act=del&amp;id=<?=$i?>" usepost ></a>
457
					<?php endif?>
458
					</td>
459
				</tr>
460
<?php endforeach; ?>
461
			</tbody>
462
		</table>
463
		</div>
464
	</div>
465
</div>
466

    
467
<nav class="action-buttons">
468
	<a href="?act=new" class="btn btn-success btn-sm">
469
		<i class="fa fa-plus icon-embed-btn"></i>
470
		<?=gettext("Add")?>
471
	</a>
472
</nav>
473
<script type="text/javascript">
474
//<![CDATA[
475

    
476
events.push(function() {
477

    
478
	// Make these controls plain buttons
479
	$("#btnsearch").prop('type', 'button');
480
	$("#btnclear").prop('type', 'button');
481

    
482
	// Search for a term in the entry name and/or dn
483
	$("#btnsearch").click(function() {
484
		var searchstr = $('#searchstr').val().toLowerCase();
485
		var table = $("table tbody");
486
		var where = $('#where').val();
487

    
488
		table.find('tr').each(function (i) {
489
			var $tds = $(this).find('td'),
490
				shortname = $tds.eq(0).text().trim().toLowerCase(),
491
				dn = $tds.eq(4).text().trim().toLowerCase();
492

    
493
			regexp = new RegExp(searchstr);
494
			if (searchstr.length > 0) {
495
				if (!(regexp.test(shortname) && (where != 1)) && !(regexp.test(dn) && (where != 0))) {
496
					$(this).hide();
497
				} else {
498
					$(this).show();
499
				}
500
			} else {
501
				$(this).show();	// A blank search string shows all
502
			}
503
		});
504
	});
505

    
506
	// Clear the search term and unhide all rows (that were hidden during a previous search)
507
	$("#btnclear").click(function() {
508
		var table = $("table tbody");
509

    
510
		$('#searchstr').val("");
511

    
512
		table.find('tr').each(function (i) {
513
			$(this).show();
514
		});
515
	});
516

    
517
	// Hitting the enter key will do the same as clicking the search button
518
	$("#searchstr").on("keyup", function (event) {
519
		if (event.keyCode == 13) {
520
			$("#btnsearch").get(0).click();
521
		}
522
	});
523
});
524
//]]>
525
</script>
526

    
527
<?php
528
	include("foot.inc");
529
	exit;
530
}
531

    
532
$form = new Form;
533
//$form->setAction('system_camanager.php?act=edit');
534
if (isset($id) && $a_ca[$id]) {
535
	$form->addGlobal(new Form_Input(
536
		'id',
537
		null,
538
		'hidden',
539
		$id
540
	));
541
}
542

    
543
if ($act == "edit") {
544
	$form->addGlobal(new Form_Input(
545
		'refid',
546
		null,
547
		'hidden',
548
		$pconfig['refid']
549
	));
550
}
551

    
552
$section = new Form_Section('Create / Edit CA');
553

    
554
$section->addInput(new Form_Input(
555
	'descr',
556
	'*Descriptive name',
557
	'text',
558
	$pconfig['descr']
559
));
560

    
561
if (!isset($id) || $act == "edit") {
562
	$section->addInput(new Form_Select(
563
		'method',
564
		'*Method',
565
		$pconfig['method'],
566
		$ca_methods
567
	))->toggles();
568
}
569

    
570
$form->add($section);
571

    
572
$section = new Form_Section('Existing Certificate Authority');
573
$section->addClass('toggle-existing collapse');
574

    
575
$section->addInput(new Form_Textarea(
576
	'cert',
577
	'*Certificate data',
578
	$pconfig['cert']
579
))->setHelp('Paste a certificate in X.509 PEM format here.');
580

    
581
$section->addInput(new Form_Textarea(
582
	'key',
583
	'Certificate Private Key (optional)',
584
	$pconfig['key']
585
))->setHelp('Paste the private key for the above certificate here. This is '.
586
	'optional in most cases, but is required when generating a '.
587
	'Certificate Revocation List (CRL).');
588

    
589
$section->addInput(new Form_Input(
590
	'serial',
591
	'Serial for next certificate',
592
	'number',
593
	$pconfig['serial']
594
))->setHelp('Enter a decimal number to be used as the serial number for the next '.
595
	'certificate to be created using this CA.');
596

    
597
$form->add($section);
598

    
599
$section = new Form_Section('Internal Certificate Authority');
600
$section->addClass('toggle-internal', 'toggle-intermediate', 'collapse');
601

    
602
$allCas = array();
603
foreach ($a_ca as $ca) {
604
	if (!$ca['prv']) {
605
			continue;
606
	}
607

    
608
	$allCas[ $ca['refid'] ] = $ca['descr'];
609
}
610

    
611
$group = new Form_Group('*Signing Certificate Authority');
612
$group->addClass('toggle-intermediate', 'collapse');
613
$group->add(new Form_Select(
614
	'caref',
615
	null,
616
	$pconfig['caref'],
617
	$allCas
618
));
619
$section->add($group);
620

    
621
$section->addInput(new Form_Select(
622
	'keylen',
623
	'*Key length (bits)',
624
	$pconfig['keylen'],
625
	array_combine($ca_keylens, $ca_keylens)
626
));
627

    
628
$section->addInput(new Form_Select(
629
	'digest_alg',
630
	'*Digest Algorithm',
631
	$pconfig['digest_alg'],
632
	array_combine($openssl_digest_algs, $openssl_digest_algs)
633
))->setHelp('NOTE: It is recommended to use an algorithm stronger than SHA1 '.
634
	'when possible.');
635

    
636
$section->addInput(new Form_Input(
637
	'lifetime',
638
	'*Lifetime (days)',
639
	'number',
640
	$pconfig['lifetime']
641
));
642

    
643
$section->addInput(new Form_Input(
644
	'dn_commonname',
645
	'*Common Name',
646
	'text',
647
	$pconfig['dn_commonname'],
648
	['placeholder' => 'e.g. internal-ca']
649
));
650

    
651
$section->addInput(new Form_StaticText(
652
	null,
653
	gettext('The following certificate authority subject components are optional and may be left blank.')
654
));
655

    
656
$section->addInput(new Form_Select(
657
	'dn_country',
658
	'Country Code',
659
	$pconfig['dn_country'],
660
	get_cert_country_codes()
661
));
662

    
663
$section->addInput(new Form_Input(
664
	'dn_state',
665
	'State or Province',
666
	'text',
667
	$pconfig['dn_state'],
668
	['placeholder' => 'e.g. Texas']
669
));
670

    
671
$section->addInput(new Form_Input(
672
	'dn_city',
673
	'City',
674
	'text',
675
	$pconfig['dn_city'],
676
	['placeholder' => 'e.g. Austin']
677
));
678

    
679
$section->addInput(new Form_Input(
680
	'dn_organization',
681
	'Organization',
682
	'text',
683
	$pconfig['dn_organization'],
684
	['placeholder' => 'e.g. My Company Inc']
685
));
686

    
687
$section->addInput(new Form_Input(
688
	'dn_organizationalunit',
689
	'Organizational Unit',
690
	'text',
691
	$pconfig['dn_organizationalunit'],
692
	['placeholder' => 'e.g. My Department Name (optional)']
693
));
694

    
695
$form->add($section);
696

    
697
print $form;
698

    
699
$internal_ca_count = 0;
700
foreach ($a_ca as $ca) {
701
	if ($ca['prv']) {
702
		$internal_ca_count++;
703
	}
704
}
705

    
706
include('foot.inc');
707
?>
(201-201/235)