Project

General

Profile

Download (18.2 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-2016 Electric Sheep Fencing, LLC
7
 * Copyright (c) 2008 Shrew Soft Inc
8
 * All rights reserved.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions are met:
12
 *
13
 * 1. Redistributions of source code must retain the above copyright notice,
14
 *    this list of conditions and the following disclaimer.
15
 *
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in
18
 *    the documentation and/or other materials provided with the
19
 *    distribution.
20
 *
21
 * 3. All advertising materials mentioning features or use of this software
22
 *    must display the following acknowledgment:
23
 *    "This product includes software developed by the pfSense Project
24
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
25
 *
26
 * 4. The names "pfSense" and "pfSense Project" must not be used to
27
 *    endorse or promote products derived from this software without
28
 *    prior written permission. For written permission, please contact
29
 *    coreteam@pfsense.org.
30
 *
31
 * 5. Products derived from this software may not be called "pfSense"
32
 *    nor may "pfSense" appear in their names without prior written
33
 *    permission of the Electric Sheep Fencing, LLC.
34
 *
35
 * 6. Redistributions of any form whatsoever must retain the following
36
 *    acknowledgment:
37
 *
38
 * "This product includes software developed by the pfSense Project
39
 * for use in the pfSense software distribution (http://www.pfsense.org/).
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
42
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
45
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52
 * OF THE POSSIBILITY OF SUCH DAMAGE.
53
 */
54

    
55
##|+PRIV
56
##|*IDENT=page-system-camanager
57
##|*NAME=System: CA Manager
58
##|*DESCR=Allow access to the 'System: CA Manager' page.
59
##|*MATCH=system_camanager.php*
60
##|-PRIV
61

    
62
require_once("guiconfig.inc");
63
require_once("certs.inc");
64

    
65
$ca_methods = array(
66
	"existing" => gettext("Import an existing Certificate Authority"),
67
	"internal" => gettext("Create an internal Certificate Authority"),
68
	"intermediate" => gettext("Create an intermediate Certificate Authority"));
69

    
70
$ca_keylens = array("512", "1024", "2048", "4096");
71
$openssl_digest_algs = array("sha1", "sha224", "sha256", "sha384", "sha512");
72

    
73
if (is_numericint($_GET['id'])) {
74
	$id = $_GET['id'];
75
}
76
if (isset($_POST['id']) && is_numericint($_POST['id'])) {
77
	$id = $_POST['id'];
78
}
79

    
80
if (!is_array($config['ca'])) {
81
	$config['ca'] = array();
82
}
83

    
84
$a_ca =& $config['ca'];
85

    
86
if (!is_array($config['cert'])) {
87
	$config['cert'] = array();
88
}
89

    
90
$a_cert =& $config['cert'];
91

    
92
if (!is_array($config['crl'])) {
93
	$config['crl'] = array();
94
}
95

    
96
$a_crl =& $config['crl'];
97

    
98
$act = $_GET['act'];
99
if ($_POST['act']) {
100
	$act = $_POST['act'];
101
}
102

    
103
if ($act == "del") {
104

    
105
	if (!isset($a_ca[$id])) {
106
		pfSenseHeader("system_camanager.php");
107
		exit;
108
	}
109

    
110
	$index = count($a_cert) - 1;
111
	for (;$index >= 0; $index--) {
112
		if ($a_cert[$index]['caref'] == $a_ca[$id]['refid']) {
113
			unset($a_cert[$index]);
114
		}
115
	}
116

    
117
	$index = count($a_crl) - 1;
118
	for (;$index >= 0; $index--) {
119
		if ($a_crl[$index]['caref'] == $a_ca[$id]['refid']) {
120
			unset($a_crl[$index]);
121
		}
122
	}
123

    
124
	$name = $a_ca[$id]['descr'];
125
	unset($a_ca[$id]);
126
	write_config();
127
	$savemsg = sprintf(gettext("Certificate Authority %s and its CRLs (if any) successfully deleted."), htmlspecialchars($name));
128
	pfSenseHeader("system_camanager.php");
129
	exit;
130
}
131

    
132
if ($act == "edit") {
133
	if (!$a_ca[$id]) {
134
		pfSenseHeader("system_camanager.php");
135
		exit;
136
	}
137
	$pconfig['descr']  = $a_ca[$id]['descr'];
138
	$pconfig['refid']  = $a_ca[$id]['refid'];
139
	$pconfig['cert']   = base64_decode($a_ca[$id]['crt']);
140
	$pconfig['serial'] = $a_ca[$id]['serial'];
141
	if (!empty($a_ca[$id]['prv'])) {
142
		$pconfig['key'] = base64_decode($a_ca[$id]['prv']);
143
	}
144
}
145

    
146
if ($act == "new") {
147
	$pconfig['method'] = $_GET['method'];
148
	$pconfig['keylen'] = "2048";
149
	$pconfig['digest_alg'] = "sha256";
150
	$pconfig['lifetime'] = "3650";
151
	$pconfig['dn_commonname'] = "internal-ca";
152
}
153

    
154
if ($act == "exp") {
155

    
156
	if (!$a_ca[$id]) {
157
		pfSenseHeader("system_camanager.php");
158
		exit;
159
	}
160

    
161
	$exp_name = urlencode("{$a_ca[$id]['descr']}.crt");
162
	$exp_data = base64_decode($a_ca[$id]['crt']);
163
	$exp_size = strlen($exp_data);
164

    
165
	header("Content-Type: application/octet-stream");
166
	header("Content-Disposition: attachment; filename={$exp_name}");
167
	header("Content-Length: $exp_size");
168
	echo $exp_data;
169
	exit;
170
}
171

    
172
if ($act == "expkey") {
173

    
174
	if (!$a_ca[$id]) {
175
		pfSenseHeader("system_camanager.php");
176
		exit;
177
	}
178

    
179
	$exp_name = urlencode("{$a_ca[$id]['descr']}.key");
180
	$exp_data = base64_decode($a_ca[$id]['prv']);
181
	$exp_size = strlen($exp_data);
182

    
183
	header("Content-Type: application/octet-stream");
184
	header("Content-Disposition: attachment; filename={$exp_name}");
185
	header("Content-Length: $exp_size");
186
	echo $exp_data;
187
	exit;
188
}
189

    
190
if ($_POST) {
191

    
192
	unset($input_errors);
193
	$input_errors = array();
194
	$pconfig = $_POST;
195

    
196
	/* input validation */
197
	if ($pconfig['method'] == "existing") {
198
		$reqdfields = explode(" ", "descr cert");
199
		$reqdfieldsn = array(
200
			gettext("Descriptive name"),
201
			gettext("Certificate data"));
202
		if ($_POST['cert'] && (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE"))) {
203
			$input_errors[] = gettext("This certificate does not appear to be valid.");
204
		}
205
		if ($_POST['key'] && strstr($_POST['key'], "ENCRYPTED")) {
206
			$input_errors[] = gettext("Encrypted private keys are not yet supported.");
207
		}
208
	}
209
	if ($pconfig['method'] == "internal") {
210
		$reqdfields = explode(" ",
211
			"descr keylen lifetime dn_country dn_state dn_city ".
212
			"dn_organization dn_email dn_commonname");
213
		$reqdfieldsn = array(
214
			gettext("Descriptive name"),
215
			gettext("Key length"),
216
			gettext("Lifetime"),
217
			gettext("Distinguished name Country Code"),
218
			gettext("Distinguished name State or Province"),
219
			gettext("Distinguished name City"),
220
			gettext("Distinguished name Organization"),
221
			gettext("Distinguished name Email Address"),
222
			gettext("Distinguished name Common Name"));
223
	}
224
	if ($pconfig['method'] == "intermediate") {
225
		$reqdfields = explode(" ",
226
			"descr caref keylen lifetime dn_country dn_state dn_city ".
227
			"dn_organization dn_email dn_commonname");
228
		$reqdfieldsn = array(
229
			gettext("Descriptive name"),
230
			gettext("Signing Certificate Authority"),
231
			gettext("Key length"),
232
			gettext("Lifetime"),
233
			gettext("Distinguished name Country Code"),
234
			gettext("Distinguished name State or Province"),
235
			gettext("Distinguished name City"),
236
			gettext("Distinguished name Organization"),
237
			gettext("Distinguished name Email Address"),
238
			gettext("Distinguished name Common Name"));
239
	}
240

    
241
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
242
	if ($pconfig['method'] != "existing") {
243
		/* Make sure we do not have invalid characters in the fields for the certificate */
244
		if (preg_match("/[\?\>\<\&\/\\\"\']/", $_POST['descr'])) {
245
			array_push($input_errors, gettext("The field 'Descriptive Name' contains invalid characters."));
246
		}
247

    
248
		for ($i = 0; $i < count($reqdfields); $i++) {
249
			if ($reqdfields[$i] == 'dn_email') {
250
				if (preg_match("/[\!\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST["dn_email"])) {
251
					array_push($input_errors, gettext("The field 'Distinguished name Email Address' contains invalid characters."));
252
				}
253
			} else if ($reqdfields[$i] == 'dn_commonname') {
254
				if (preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST["dn_commonname"])) {
255
					array_push($input_errors, gettext("The field 'Distinguished name Common Name' contains invalid characters."));
256
				}
257
			} else if (($reqdfields[$i] != "descr") && preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\.\"\']/", $_POST["$reqdfields[$i]"])) {
258
				array_push($input_errors, sprintf(gettext("The field '%s' contains invalid characters."), $reqdfieldsn[$i]));
259
			}
260
		}
261
		if (!in_array($_POST["keylen"], $ca_keylens)) {
262
			array_push($input_errors, gettext("Please select a valid Key Length."));
263
		}
264
		if (!in_array($_POST["digest_alg"], $openssl_digest_algs)) {
265
			array_push($input_errors, gettext("Please select a valid Digest Algorithm."));
266
		}
267
	}
268

    
269
	/* if this is an AJAX caller then handle via JSON */
270
	if (isAjax() && is_array($input_errors)) {
271
		input_errors2Ajax($input_errors);
272
		exit;
273
	}
274

    
275
	/* save modifications */
276
	if (!$input_errors) {
277
		$ca = array();
278
		if (!isset($pconfig['refid']) || empty($pconfig['refid'])) {
279
			$ca['refid'] = uniqid();
280
		} else {
281
			$ca['refid'] = $pconfig['refid'];
282
		}
283

    
284
		if (isset($id) && $a_ca[$id]) {
285
			$ca = $a_ca[$id];
286
		}
287

    
288
		$ca['descr'] = $pconfig['descr'];
289

    
290
		if ($act == "edit") {
291
			$ca['descr']  = $pconfig['descr'];
292
			$ca['refid']  = $pconfig['refid'];
293
			$ca['serial'] = $pconfig['serial'];
294
			$ca['crt']	  = base64_encode($pconfig['cert']);
295
			if (!empty($pconfig['key'])) {
296
				$ca['prv']	  = base64_encode($pconfig['key']);
297
			}
298
		} else {
299
			$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
300
			if ($pconfig['method'] == "existing") {
301
				ca_import($ca, $pconfig['cert'], $pconfig['key'], $pconfig['serial']);
302
			} else if ($pconfig['method'] == "internal") {
303
				$dn = array(
304
					'countryName' => $pconfig['dn_country'],
305
					'stateOrProvinceName' => $pconfig['dn_state'],
306
					'localityName' => $pconfig['dn_city'],
307
					'organizationName' => $pconfig['dn_organization'],
308
					'emailAddress' => $pconfig['dn_email'],
309
					'commonName' => $pconfig['dn_commonname']);
310
				if (!empty($pconfig['dn_organizationalunit'])) {
311
					$dn['organizationalUnitName'] = $pconfig['dn_organizationalunit'];
312
				}
313
				if (!ca_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['digest_alg'])) {
314
					while ($ssl_err = openssl_error_string()) {
315
						$input_errors = array();
316
						array_push($input_errors, "openssl library returns: " . $ssl_err);
317
					}
318
				}
319
			} else if ($pconfig['method'] == "intermediate") {
320
				$dn = array(
321
					'countryName' => $pconfig['dn_country'],
322
					'stateOrProvinceName' => $pconfig['dn_state'],
323
					'localityName' => $pconfig['dn_city'],
324
					'organizationName' => $pconfig['dn_organization'],
325
					'emailAddress' => $pconfig['dn_email'],
326
					'commonName' => $pconfig['dn_commonname']);
327
				if (!empty($pconfig['dn_organizationalunit'])) {
328
					$dn['organizationalUnitName'] = $pconfig['dn_organizationalunit'];
329
				}
330
				if (!ca_inter_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['caref'], $pconfig['digest_alg'])) {
331
					while ($ssl_err = openssl_error_string()) {
332
						$input_errors = array();
333
						array_push($input_errors, "openssl library returns: " . $ssl_err);
334
					}
335
				}
336
			}
337
			error_reporting($old_err_level);
338
		}
339

    
340
		if (isset($id) && $a_ca[$id]) {
341
			$a_ca[$id] = $ca;
342
		} else {
343
			$a_ca[] = $ca;
344
		}
345

    
346
		if (!$input_errors) {
347
			write_config();
348
		}
349

    
350
		pfSenseHeader("system_camanager.php");
351
	}
352
}
353

    
354
$pgtitle = array(gettext("System"), gettext("Certificate Manager"), gettext("CAs"));
355

    
356
if ($act == "new" || $act == "edit" || $act == gettext("Save") || $input_errors) {
357
	$pgtitle[] = gettext('Edit');
358
}
359
include("head.inc");
360

    
361
if ($input_errors) {
362
	print_input_errors($input_errors);
363
}
364

    
365
if ($savemsg) {
366
	print_info_box($savemsg, 'success');
367
}
368

    
369
// Load valid country codes
370
$dn_cc = array();
371
if (file_exists("/etc/ca_countries")) {
372
	$dn_cc_file=file("/etc/ca_countries");
373
	foreach ($dn_cc_file as $line) {
374
		if (preg_match('/^(\S*)\s(.*)$/', $line, $matches)) {
375
			$dn_cc[$matches[1]] = $matches[1];
376
		}
377
	}
378
}
379

    
380
$tab_array = array();
381
$tab_array[] = array(gettext("CAs"), true, "system_camanager.php");
382
$tab_array[] = array(gettext("Certificates"), false, "system_certmanager.php");
383
$tab_array[] = array(gettext("Certificate Revocation"), false, "system_crlmanager.php");
384
display_top_tabs($tab_array);
385

    
386
if (!($act == "new" || $act == "edit" || $act == gettext("Save") || $input_errors)) {
387
?>
388
<div class="panel panel-default">
389
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Certificate Authorities')?></h2></div>
390
	<div class="panel-body">
391
		<div class="table-responsive">
392
		<table class="table table-striped table-hover table-rowdblclickedit">
393
			<thead>
394
				<tr>
395
					<th><?=gettext("Name")?></th>
396
					<th><?=gettext("Internal")?></th>
397
					<th><?=gettext("Issuer")?></th>
398
					<th><?=gettext("Certificates")?></th>
399
					<th><?=gettext("Distinguished Name")?></th>
400
					<th><?=gettext("Actions")?></th>
401
				</tr>
402
			</thead>
403
			<tbody>
404
<?php
405
foreach ($a_ca as $i => $ca):
406
	$name = htmlspecialchars($ca['descr']);
407
	$subj = cert_get_subject($ca['crt']);
408
	$issuer = cert_get_issuer($ca['crt']);
409
	list($startdate, $enddate) = cert_get_dates($ca['crt']);
410
	if ($subj == $issuer) {
411
		$issuer_name = gettext("self-signed");
412
	} else {
413
		$issuer_name = gettext("external");
414
	}
415
	$subj = htmlspecialchars($subj);
416
	$issuer = htmlspecialchars($issuer);
417
	$certcount = 0;
418

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

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

    
430
	foreach ($a_ca as $cert) {
431
		if ($cert['caref'] == $ca['refid']) {
432
			$certcount++;
433
		}
434
	}
435
?>
436
				<tr>
437
					<td><?=$name?></td>
438
					<td><i class="fa fa-<?= (!empty($ca['prv'])) ? "check" : "times" ; ?>"></i></td>
439
					<td><i><?=$issuer_name?></i></td>
440
					<td><?=$certcount?></td>
441
					<td>
442
						<?=$subj?>
443
						<br />
444
						<small>
445
							<?=gettext("Valid From")?>: <b><?=$startdate ?></b><br /><?=gettext("Valid Until")?>: <b><?=$enddate ?></b>
446
						</small>
447
					</td>
448
					<td>
449
						<a class="fa fa-pencil"	title="<?=gettext("Edit CA")?>"	href="system_camanager.php?act=edit&amp;id=<?=$i?>"></a>
450
						<a class="fa fa-certificate"	title="<?=gettext("Export CA")?>"	href="system_camanager.php?act=exp&amp;id=<?=$i?>"></a>
451
					<?php if ($ca['prv']): ?>
452
						<a class="fa fa-key"	title="<?=gettext("Export key")?>"	href="system_camanager.php?act=expkey&amp;id=<?=$i?>"></a>
453
					<?php endif?>
454
						<a class="fa fa-trash" 	title="<?=gettext("Delete CA")?>"	href="system_camanager.php?act=del&amp;id=<?=$i?>"></a>
455
					</td>
456
				</tr>
457
<?php endforeach; ?>
458
			</tbody>
459
		</table>
460
		</div>
461
	</div>
462
</div>
463

    
464
<nav class="action-buttons">
465
	<a href="?act=new" class="btn btn-success btn-sm">
466
		<i class="fa fa-plus icon-embed-btn"></i>
467
		<?=gettext("Add")?>
468
	</a>
469
</nav>
470
<?php
471
	include("foot.inc");
472
	exit;
473
}
474

    
475
$form = new Form;
476
//$form->setAction('system_camanager.php?act=edit');
477
if (isset($id) && $a_ca[$id]) {
478
	$form->addGlobal(new Form_Input(
479
		'id',
480
		null,
481
		'hidden',
482
		$id
483
	));
484
}
485

    
486
if ($act == "edit") {
487
	$form->addGlobal(new Form_Input(
488
		'refid',
489
		null,
490
		'hidden',
491
		$pconfig['refid']
492
	));
493
}
494

    
495
$section = new Form_Section('Create / Edit CA');
496

    
497
$section->addInput(new Form_Input(
498
	'descr',
499
	'Descriptive name',
500
	'text',
501
	$pconfig['descr']
502
));
503

    
504
if (!isset($id) || $act == "edit") {
505
	$section->addInput(new Form_Select(
506
		'method',
507
		'Method',
508
		$pconfig['method'],
509
		$ca_methods
510
	))->toggles();
511
}
512

    
513
$form->add($section);
514

    
515
$section = new Form_Section('Existing Certificate Authority');
516
$section->addClass('toggle-existing collapse');
517

    
518
$section->addInput(new Form_Textarea(
519
	'cert',
520
	'Certificate data',
521
	$pconfig['cert']
522
))->setHelp('Paste a certificate in X.509 PEM format here.');
523

    
524
$section->addInput(new Form_Textarea(
525
	'key',
526
	'Certificate Private Key (optional)',
527
	$pconfig['key']
528
))->setHelp('Paste the private key for the above certificate here. This is '.
529
	'optional in most cases, but is required when generating a '.
530
	'Certificate Revocation List (CRL).');
531

    
532
$section->addInput(new Form_Input(
533
	'serial',
534
	'Serial for next certificate',
535
	'number',
536
	$pconfig['serial']
537
))->setHelp('Enter a decimal number to be used as the serial number for the next '.
538
	'certificate to be created using this CA.');
539

    
540
$form->add($section);
541

    
542
$section = new Form_Section('Internal Certificate Authority');
543
$section->addClass('toggle-internal', 'toggle-intermediate', 'collapse');
544

    
545
$allCas = array();
546
foreach ($a_ca as $ca) {
547
	if (!$ca['prv']) {
548
			continue;
549
	}
550

    
551
	$allCas[ $ca['refid'] ] = $ca['descr'];
552
}
553

    
554
$group = new Form_Group('Signing Certificate Authority');
555
$group->addClass('toggle-intermediate', 'collapse');
556
$group->add(new Form_Select(
557
	'caref',
558
	null,
559
	$pconfig['caref'],
560
	$allCas
561
));
562
$section->add($group);
563

    
564
$section->addInput(new Form_Select(
565
	'keylen',
566
	'Key length (bits)',
567
	$pconfig['keylen'],
568
	array_combine($ca_keylens, $ca_keylens)
569
));
570

    
571
$section->addInput(new Form_Select(
572
	'digest_alg',
573
	'Digest Algorithm',
574
	$pconfig['digest_alg'],
575
	array_combine($openssl_digest_algs, $openssl_digest_algs)
576
))->setHelp('NOTE: It is recommended to use an algorithm stronger than SHA1 '.
577
	'when possible.');
578

    
579
$section->addInput(new Form_Input(
580
	'lifetime',
581
	'Lifetime (days)',
582
	'number',
583
	$pconfig['lifetime']
584
));
585

    
586
$section->addInput(new Form_Select(
587
	'dn_country',
588
	'Country Code',
589
	$pconfig['dn_country'],
590
	$dn_cc
591
));
592

    
593
$section->addInput(new Form_Input(
594
	'dn_state',
595
	'State or Province',
596
	'text',
597
	$pconfig['dn_state'],
598
	['placeholder' => 'e.g. Texas']
599
));
600

    
601
$section->addInput(new Form_Input(
602
	'dn_city',
603
	'City',
604
	'text',
605
	$pconfig['dn_city'],
606
	['placeholder' => 'e.g. Austin']
607
));
608

    
609
$section->addInput(new Form_Input(
610
	'dn_organization',
611
	'Organization',
612
	'text',
613
	$pconfig['dn_organization'],
614
	['placeholder' => 'e.g. My Company Inc']
615
));
616

    
617
$section->addInput(new Form_Input(
618
	'dn_organizationalunit',
619
	'Organizational Unit',
620
	'text',
621
	$pconfig['dn_organizationalunit'],
622
	['placeholder' => 'e.g. My Department Name (optional)']
623
));
624

    
625
$section->addInput(new Form_Input(
626
	'dn_email',
627
	'Email Address',
628
	'email',
629
	$pconfig['dn_email'],
630
	['placeholder' => 'e.g. admin@mycompany.com']
631
));
632

    
633
$section->addInput(new Form_Input(
634
	'dn_commonname',
635
	'Common Name',
636
	'text',
637
	$pconfig['dn_commonname'],
638
	['placeholder' => 'e.g. internal-ca']
639
));
640

    
641
$form->add($section);
642

    
643
print $form;
644

    
645
$internal_ca_count = 0;
646
foreach ($a_ca as $ca) {
647
	if ($ca['prv']) {
648
		$internal_ca_count++;
649
	}
650
}
651

    
652
include('foot.inc');
653
?>
(192-192/225)