Project

General

Profile

Download (15.8 KB) Statistics
| Branch: | Tag: | Revision:
1 64cc39d3 Matthew Grooms
<?php
2
/*
3 ce77a9c4 Phil Davis
	system_camanager.php
4
5
	Copyright (C) 2008 Shrew Soft Inc.
6
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
7
	All rights reserved.
8
9
	Redistribution and use in source and binary forms, with or without
10
	modification, are permitted provided that the following conditions are met:
11
12
	1. Redistributions of source code must retain the above copyright notice,
13
	   this list of conditions and the following disclaimer.
14
15
	2. Redistributions in binary form must reproduce the above copyright
16
	   notice, this list of conditions and the following disclaimer in the
17
	   documentation and/or other materials provided with the distribution.
18
19
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
	POSSIBILITY OF SUCH DAMAGE.
29 64cc39d3 Matthew Grooms
*/
30 1d333258 Scott Ullrich
/*
31 ce77a9c4 Phil Davis
	pfSense_MODULE:	certificate_manager
32 1d333258 Scott Ullrich
*/
33 64cc39d3 Matthew Grooms
34
##|+PRIV
35
##|*IDENT=page-system-camanager
36
##|*NAME=System: CA Manager
37
##|*DESCR=Allow access to the 'System: CA Manager' page.
38
##|*MATCH=system_camanager.php*
39
##|-PRIV
40
41
require("guiconfig.inc");
42 742d9c2d Ermal Lu?i
require_once("certs.inc");
43 64cc39d3 Matthew Grooms
44
$ca_methods = array(
45 a37753d7 Vinicius Coque
	"existing" => gettext("Import an existing Certificate Authority"),
46 95c8cf48 Evgeny Yurchenko
	"internal" => gettext("Create an internal Certificate Authority"),
47
	"intermediate" => gettext("Create an intermediate Certificate Authority"));
48 64cc39d3 Matthew Grooms
49
$ca_keylens = array( "512", "1024", "2048", "4096");
50 84197cec jim-p
$openssl_digest_algs = array("sha1", "sha224", "sha256", "sha384", "sha512");
51 64cc39d3 Matthew Grooms
52 a37753d7 Vinicius Coque
$pgtitle = array(gettext("System"), gettext("Certificate Authority Manager"));
53 64cc39d3 Matthew Grooms
54 e41ec584 Renato Botelho
if (is_numericint($_GET['id']))
55
	$id = $_GET['id'];
56
if (isset($_POST['id']) && is_numericint($_POST['id']))
57 64cc39d3 Matthew Grooms
	$id = $_POST['id'];
58
59 b4e6524c jim-p
if (!is_array($config['ca']))
60
	$config['ca'] = array();
61 64cc39d3 Matthew Grooms
62 b4e6524c jim-p
$a_ca =& $config['ca'];
63 64cc39d3 Matthew Grooms
64 b4e6524c jim-p
if (!is_array($config['cert']))
65
	$config['cert'] = array();
66 64cc39d3 Matthew Grooms
67 b4e6524c jim-p
$a_cert =& $config['cert'];
68 64cc39d3 Matthew Grooms
69 461aa9d0 jim-p
if (!is_array($config['crl']))
70
	$config['crl'] = array();
71
72
$a_crl =& $config['crl'];
73
74 64cc39d3 Matthew Grooms
$act = $_GET['act'];
75
if ($_POST['act'])
76
	$act = $_POST['act'];
77
78
if ($act == "del") {
79
80 40e6086a jim-p
	if (!isset($a_ca[$id])) {
81 64cc39d3 Matthew Grooms
		pfSenseHeader("system_camanager.php");
82
		exit;
83
	}
84
85
	$index = count($a_cert) - 1;
86
	for (;$index >=0; $index--)
87
		if ($a_cert[$index]['caref'] == $a_ca[$id]['refid'])
88
			unset($a_cert[$index]);
89
90 461aa9d0 jim-p
	$index = count($a_crl) - 1;
91
	for (;$index >=0; $index--)
92
		if ($a_crl[$index]['caref'] == $a_ca[$id]['refid'])
93
			unset($a_crl[$index]);
94
95 f2a86ca9 jim-p
	$name = $a_ca[$id]['descr'];
96 64cc39d3 Matthew Grooms
	unset($a_ca[$id]);
97
	write_config();
98 8cd558b6 ayvis
	$savemsg = sprintf(gettext("Certificate Authority %s and its CRLs (if any) successfully deleted"), $name) . "<br />";
99 2f51259b jim-p
	pfSenseHeader("system_camanager.php");
100
	exit;
101 64cc39d3 Matthew Grooms
}
102
103 bfa992bc jim-p
if ($act == "edit") {
104
	if (!$a_ca[$id]) {
105
		pfSenseHeader("system_camanager.php");
106
		exit;
107
	}
108
	$pconfig['descr']  = $a_ca[$id]['descr'];
109
	$pconfig['refid']  = $a_ca[$id]['refid'];
110
	$pconfig['cert']   = base64_decode($a_ca[$id]['crt']);
111
	$pconfig['serial'] = $a_ca[$id]['serial'];
112
	if (!empty($a_ca[$id]['prv']))
113
		$pconfig['key'] = base64_decode($a_ca[$id]['prv']);
114
}
115
116 64cc39d3 Matthew Grooms
if ($act == "new") {
117
	$pconfig['method'] = $_GET['method'];
118
	$pconfig['keylen'] = "2048";
119 28a20fdb jim-p
	$pconfig['digest_alg'] = "sha256";
120 cf360495 Chris Buechler
	$pconfig['lifetime'] = "3650";
121 64cc39d3 Matthew Grooms
	$pconfig['dn_commonname'] = "internal-ca";
122
}
123
124 93823b10 Matthew Grooms
if ($act == "exp") {
125
126
	if (!$a_ca[$id]) {
127
		pfSenseHeader("system_camanager.php");
128
		exit;
129
	}
130
131 f2a86ca9 jim-p
	$exp_name = urlencode("{$a_ca[$id]['descr']}.crt");
132 93823b10 Matthew Grooms
	$exp_data = base64_decode($a_ca[$id]['crt']);
133
	$exp_size = strlen($exp_data);
134
135
	header("Content-Type: application/octet-stream");
136
	header("Content-Disposition: attachment; filename={$exp_name}");
137
	header("Content-Length: $exp_size");
138
	echo $exp_data;
139
	exit;
140
}
141
142 ecefc738 jim-p
if ($act == "expkey") {
143
144
	if (!$a_ca[$id]) {
145
		pfSenseHeader("system_camanager.php");
146
		exit;
147
	}
148
149 f2a86ca9 jim-p
	$exp_name = urlencode("{$a_ca[$id]['descr']}.key");
150 ecefc738 jim-p
	$exp_data = base64_decode($a_ca[$id]['prv']);
151
	$exp_size = strlen($exp_data);
152
153
	header("Content-Type: application/octet-stream");
154
	header("Content-Disposition: attachment; filename={$exp_name}");
155
	header("Content-Length: $exp_size");
156
	echo $exp_data;
157
	exit;
158
}
159
160 64cc39d3 Matthew Grooms
if ($_POST) {
161
162 95c8cf48 Evgeny Yurchenko
	unset($input_errors);
163 2b8bfda4 Phil Davis
	$input_errors = array();
164 64cc39d3 Matthew Grooms
	$pconfig = $_POST;
165
166
	/* input validation */
167
	if ($pconfig['method'] == "existing") {
168 5293bfec jim-p
		$reqdfields = explode(" ", "descr cert");
169 38fb1109 Vinicius Coque
		$reqdfieldsn = array(
170
				gettext("Descriptive name"),
171
				gettext("Certificate data"));
172 396cfe2e jim-p
		if ($_POST['cert'] && (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE")))
173
			$input_errors[] = gettext("This certificate does not appear to be valid.");
174 46698c3f jim-p
		if ($_POST['key'] && strstr($_POST['key'], "ENCRYPTED"))
175
			$input_errors[] = gettext("Encrypted private keys are not yet supported.");
176 64cc39d3 Matthew Grooms
	}
177
	if ($pconfig['method'] == "internal") {
178
		$reqdfields = explode(" ",
179 5293bfec jim-p
				"descr keylen lifetime dn_country dn_state dn_city ".
180 64cc39d3 Matthew Grooms
				"dn_organization dn_email dn_commonname");
181 38fb1109 Vinicius Coque
		$reqdfieldsn = array(
182
				gettext("Descriptive name"),
183
				gettext("Key length"),
184
				gettext("Lifetime"),
185
				gettext("Distinguished name Country Code"),
186
				gettext("Distinguished name State or Province"),
187
				gettext("Distinguished name City"),
188
				gettext("Distinguished name Organization"),
189
				gettext("Distinguished name Email Address"),
190 a37753d7 Vinicius Coque
				gettext("Distinguished name Common Name"));
191 64cc39d3 Matthew Grooms
	}
192 95c8cf48 Evgeny Yurchenko
	if ($pconfig['method'] == "intermediate") {
193
		$reqdfields = explode(" ",
194
				"descr caref keylen lifetime dn_country dn_state dn_city ".
195
				"dn_organization dn_email dn_commonname");
196
		$reqdfieldsn = array(
197
				gettext("Descriptive name"),
198
				gettext("Signing Certificate Authority"),
199
				gettext("Key length"),
200
				gettext("Lifetime"),
201
				gettext("Distinguished name Country Code"),
202
				gettext("Distinguished name State or Province"),
203
				gettext("Distinguished name City"),
204
				gettext("Distinguished name Organization"),
205
				gettext("Distinguished name Email Address"),
206
				gettext("Distinguished name Common Name"));
207
	}
208 64cc39d3 Matthew Grooms
209 1e9b4611 Renato Botelho
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
210 ca621902 jim-p
	if ($pconfig['method'] != "existing") {
211 21cc2faa Evgeny Yurchenko
		/* Make sure we do not have invalid characters in the fields for the certificate */
212
		for ($i = 0; $i < count($reqdfields); $i++) {
213
			if ($reqdfields[$i] == 'dn_email'){
214
				if (preg_match("/[\!\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST["dn_email"]))
215
					array_push($input_errors, "The field 'Distinguished name Email Address' contains invalid characters.");
216
			}else if ($reqdfields[$i] == 'dn_commonname'){
217
				if (preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST["dn_commonname"]))
218
					array_push($input_errors, "The field 'Distinguished name Common Name' contains invalid characters.");
219 00a695c8 jim-p
			}else if (($reqdfields[$i] != "descr") && preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\.\"\']/", $_POST["$reqdfields[$i]"]))
220 21cc2faa Evgeny Yurchenko
				array_push($input_errors, "The field '" . $reqdfieldsn[$i] . "' contains invalid characters.");
221
		}
222 ca621902 jim-p
		if (!in_array($_POST["keylen"], $ca_keylens))
223
			array_push($input_errors, gettext("Please select a valid Key Length."));
224
		if (!in_array($_POST["digest_alg"], $openssl_digest_algs))
225
			array_push($input_errors, gettext("Please select a valid Digest Algorithm."));
226
	}
227 64cc39d3 Matthew Grooms
228
	/* if this is an AJAX caller then handle via JSON */
229
	if (isAjax() && is_array($input_errors)) {
230
		input_errors2Ajax($input_errors);
231
		exit;
232
	}
233
234
	/* save modifications */
235
	if (!$input_errors) {
236
237
		$ca = array();
238 bfa992bc jim-p
		if (!isset($pconfig['refid']) || empty($pconfig['refid']))
239
			$ca['refid'] = uniqid();
240
		else
241
			$ca['refid'] = $pconfig['refid'];
242
243 64cc39d3 Matthew Grooms
		if (isset($id) && $a_ca[$id])
244
			$ca = $a_ca[$id];
245
246 bfa992bc jim-p
		$ca['descr'] = $pconfig['descr'];
247
248 5d2edeca Sjon Hortensius
		if ($act == "edit") {
249 bfa992bc jim-p
			$ca['descr']  = $pconfig['descr'];
250
			$ca['refid']  = $pconfig['refid'];
251
			$ca['serial'] = $pconfig['serial'];
252 5d2edeca Sjon Hortensius
			$ca['crt'] = base64_encode($pconfig['cert']);
253 bfa992bc jim-p
			if (!empty($pconfig['key']))
254 5d2edeca Sjon Hortensius
				$ca['prv'] = base64_encode($pconfig['key']);
255 bfa992bc jim-p
		} else {
256 f416763b Phil Davis
			$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
257 bfa992bc jim-p
			if ($pconfig['method'] == "existing")
258
				ca_import($ca, $pconfig['cert'], $pconfig['key'], $pconfig['serial']);
259
260 95c8cf48 Evgeny Yurchenko
			else if ($pconfig['method'] == "internal") {
261 bfa992bc jim-p
				$dn = array(
262
					'countryName' => $pconfig['dn_country'],
263
					'stateOrProvinceName' => $pconfig['dn_state'],
264
					'localityName' => $pconfig['dn_city'],
265
					'organizationName' => $pconfig['dn_organization'],
266
					'emailAddress' => $pconfig['dn_email'],
267
					'commonName' => $pconfig['dn_commonname']);
268 ca621902 jim-p
				if (!ca_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['digest_alg'])){
269 1b6d9fa5 Evgeny Yurchenko
					while($ssl_err = openssl_error_string()){
270
						$input_errors = array();
271
						array_push($input_errors, "openssl library returns: " . $ssl_err);
272
					}
273
				}
274 bfa992bc jim-p
			}
275 95c8cf48 Evgeny Yurchenko
			else if ($pconfig['method'] == "intermediate") {
276
				$dn = array(
277
					'countryName' => $pconfig['dn_country'],
278
					'stateOrProvinceName' => $pconfig['dn_state'],
279
					'localityName' => $pconfig['dn_city'],
280
					'organizationName' => $pconfig['dn_organization'],
281
					'emailAddress' => $pconfig['dn_email'],
282
					'commonName' => $pconfig['dn_commonname']);
283 ca621902 jim-p
				if (!ca_inter_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['caref'], $pconfig['digest_alg'])){
284 95c8cf48 Evgeny Yurchenko
					while($ssl_err = openssl_error_string()){
285
						$input_errors = array();
286
						array_push($input_errors, "openssl library returns: " . $ssl_err);
287
					}
288
				}
289
			}
290 1b6d9fa5 Evgeny Yurchenko
			error_reporting($old_err_level);
291 64cc39d3 Matthew Grooms
		}
292
293
		if (isset($id) && $a_ca[$id])
294
			$a_ca[$id] = $ca;
295
		else
296
			$a_ca[] = $ca;
297
298 95c8cf48 Evgeny Yurchenko
		if (!$input_errors)
299
			write_config();
300 64cc39d3 Matthew Grooms
301
//		pfSenseHeader("system_camanager.php");
302
	}
303
}
304
305
include("head.inc");
306
307 5d2edeca Sjon Hortensius
if ($input_errors)
308
	print_input_errors($input_errors);
309
if ($savemsg)
310
	print_info_box($savemsg);
311
312
// Load valid country codes
313
$dn_cc = array();
314
if (file_exists("/etc/ca_countries")){
315
	$dn_cc_file=file("/etc/ca_countries");
316
	foreach($dn_cc_file as $line)
317
		if (preg_match('/^(\S*)\s(.*)$/', $line, $matches))
318
			array_push($dn_cc, $matches[1]);
319 64cc39d3 Matthew Grooms
}
320
321 5d2edeca Sjon Hortensius
$tab_array = array();
322
$tab_array[] = array(gettext("CAs"), true, "system_camanager.php");
323
$tab_array[] = array(gettext("Certificates"), false, "system_certmanager.php");
324
$tab_array[] = array(gettext("Certificate Revocation"), false, "system_crlmanager.php");
325
display_top_tabs($tab_array);
326
327
if (!($act == "new" || $act == "edit" || $act == gettext("Save") || $input_errors))
328
{
329
?>
330
<div class="table-responsive">
331
<table class="table table-striped table-hover">
332
	<thead>
333
		<tr>
334
			<th><?=gettext("Name")?></th>
335
			<th><?=gettext("Internal")?></th>
336
			<th><?=gettext("Issuer")?></th>
337
			<th><?=gettext("Certificates")?></th>
338
			<th><?=gettext("Distinguished Name")?></th>
339
			<th></th>
340
		</tr>
341
	</thead>
342
	<tbody>
343 64cc39d3 Matthew Grooms
<?php
344 5d2edeca Sjon Hortensius
foreach ($a_ca as $i => $ca):
345
	$name = htmlspecialchars($ca['descr']);
346
	$subj = cert_get_subject($ca['crt']);
347
	$issuer = cert_get_issuer($ca['crt']);
348
	list($startdate, $enddate) = cert_get_dates($ca['crt']);
349 a2a10102 Sjon Hortensius
	if ($subj == $issuer)
350
		$issuer_name = gettext("self-signed");
351 5d2edeca Sjon Hortensius
	else
352 a2a10102 Sjon Hortensius
		$issuer_name = gettext("external");
353 5d2edeca Sjon Hortensius
	$subj = htmlspecialchars($subj);
354
	$issuer = htmlspecialchars($issuer);
355
	$certcount = 0;
356
357
	$issuer_ca = lookup_ca($ca['caref']);
358
	if ($issuer_ca)
359
		$issuer_name = $issuer_ca['descr'];
360
361
	// TODO : Need gray certificate icon
362
	$internal = (!!$ca['prv']);
363
364
	foreach ($a_cert as $cert)
365
		if ($cert['caref'] == $ca['refid'])
366
			$certcount++;
367
368
	foreach ($a_ca as $cert)
369
		if ($cert['caref'] == $ca['refid'])
370
			$certcount++;
371 64cc39d3 Matthew Grooms
?>
372 5d2edeca Sjon Hortensius
		<tr>
373
			<td><?=$name?></td>
374
			<td><?=$internal?></td>
375 a2a10102 Sjon Hortensius
			<td><i><?=$issuer_name?></i></td>
376 5d2edeca Sjon Hortensius
			<td><?=$certcount?></td>
377 a2a10102 Sjon Hortensius
			<td>
378
				<?=$subj?>
379
				<br />
380
				<small>
381
					<?=gettext("Valid From")?>: <b><?=$startdate ?></b>, <?=gettext("Valid Until")?>: <b><?=$enddate ?></b>
382
				</small>
383 5d2edeca Sjon Hortensius
			</td>
384
			<td>
385
				<a href="system_camanager.php?act=edit&amp;id=<?=$i?>" class="btn btn-xs btn-primary">
386
					<?=gettext("edit")?>
387
				</a>
388
				<a href="system_camanager.php?act=exp&amp;id=<?=$i?>" class="btn btn-xs btn-default">
389
					<?=gettext("export cert")?>
390
				</a>
391
				<?php if ($ca['prv']): ?>
392
					<a href="system_camanager.php?act=expkey&amp;id=<?=$i?>" class="btn btn-xs btn-default">
393
						<?=gettext("export private key")?>
394
					</a>
395
				<?php endif?>
396
				<a href="system_camanager.php?act=del&amp;id=<?=$i?>" class="btn btn-xs btn-danger">
397
					<?=gettext("delete")?>
398
				</a>
399
			</td>
400
		</tr>
401
<?php endforeach; ?>
402
	</tbody>
403
</table>
404 64cc39d3 Matthew Grooms
405 5d2edeca Sjon Hortensius
<nav class="action-buttons">
406
	<a href="?act=new" class="btn btn-success">add new</a>
407
</nav>
408
<?
409
	include("foot.inc");
410
	exit;
411
}
412 96c7a492 Matthew Grooms
413 5d2edeca Sjon Hortensius
require('classes/Form.class.php');
414
$form = new Form;
415
$form->setAction('system_camanager.php?act=edit');
416
if (isset($id) && $a_ca[$id])
417
{
418
	$form->addGlobal(new Form_Input(
419
		'id',
420
		null,
421
		'hidden',
422
		$id
423
	));
424
}
425 64cc39d3 Matthew Grooms
426 5d2edeca Sjon Hortensius
if ($act == "edit")
427
{
428
	$form->addGlobal(new Form_Input(
429
		'refid',
430
		null,
431
		'hidden',
432
		$pconfig['refid']
433
	));
434
}
435
436
$section = new Form_Section('Create / edit CA');
437
438
$section->addInput(new Form_Input(
439
	'descr',
440
	'Descriptive name',
441
	'text',
442
	$pconfig['descr']
443
));
444
445
if (!isset($id) || $act == "edit")
446
{
447
	$section->addInput(new Form_Select(
448
		'method',
449
		'Method',
450
		$pconfig['method'],
451
		$ca_methods
452
	))->toggles(null);
453
}
454 64cc39d3 Matthew Grooms
455 5d2edeca Sjon Hortensius
$form->add($section);
456
457
$section = new Form_Section('Existing Certificate Authority');
458
$section->addClass('toggle-existing collapse');
459
460
$section->addInput(new Form_Textarea(
461
	'cert',
462
	'Certificate data',
463
	$pconfig['cert']
464
))->setHelp('Paste a certificate in X.509 PEM format here.');
465
466
$section->addInput(new Form_Textarea(
467
	'key',
468
	'Certificate Private Key (optional)',
469
	$pconfig['key']
470
))->setHelp('Paste the private key for the above certificate here. This is '.
471
	'optional in most cases, but required if you need to generate a '.
472
	'Certificate Revocation List (CRL).');
473
474
$section->addInput(new Form_Input(
475
	'serial',
476
	'Serial for next certificate',
477
	'number',
478
	$pconfig['serial']
479
))->setHelp('Enter a decimal number to be used as the serial number for the next '.
480
	'certificate to be created using this CA.');
481
482
$form->add($section);
483
484
$section = new Form_Section('Internal Certificate Authority');
485
$section->addClass('toggle-internal', 'toggle-intermediate', 'collapse');
486
487
$allCas = array();
488
foreach ($a_ca as $ca)
489
{
490
	if (!$ca['prv'])
491
			continue;
492
493
	$allCas[ $ca['refid'] ] = $ca['descr'];
494
}
495 64cc39d3 Matthew Grooms
496 5d2edeca Sjon Hortensius
$group = new Form_Group('Signing Certificate Authority');
497
$group->addClass('toggle-intermediate');
498
$group->add(new Form_Select(
499
	'caref',
500
	null,
501
	$pconfig['caref'],
502
	$allCas
503
));
504
$section->add($group);
505
506
$section->addInput(new Form_Select(
507
	'keylen',
508
	'Key length (bits)',
509
	$pconfig['keylen'],
510
	$ca_keylens
511
));
512
513
$section->addInput(new Form_Select(
514
	'digest_alg',
515
	'Digest Algorithm',
516
	$pconfig['digest_alg'],
517
	$openssl_digest_algs
518
))->setHelp('NOTE: It is recommended to use an algorithm stronger than SHA1 '.
519
	'when possible.');
520
521
$section->addInput(new Form_Input(
522
	'lifetime',
523
	'Lifetime (days)',
524
	'number',
525
	$pconfig['lifetime']
526
));
527
528
$section->addInput(new Form_Select(
529
	'dn_country',
530
	'Country Code',
531
	$pconfig['dn_country'],
532
	$dn_cc
533
));
534
535
$section->addInput(new Form_Input(
536
	'dn_state',
537
	'State or Province',
538
	'text',
539
	$pconfig['dn_state'],
540
	['placeholder' => 'e.g. Texas']
541
));
542
543
$section->addInput(new Form_Input(
544
	'dn_city',
545
	'City',
546
	'text',
547
	$pconfig['dn_city'],
548
	['placeholder' => 'e.g. Austin']
549
));
550
551
$section->addInput(new Form_Input(
552
	'dn_organization',
553
	'Organization',
554
	'text',
555
	$pconfig['dn_organization'],
556
	['placeholder' => 'e.g. My Company Inc.']
557
));
558
559
$section->addInput(new Form_Input(
560
	'dn_email',
561
	'Email Address',
562
	'email',
563
	$pconfig['dn_email'],
564
	['placeholder' => 'e.g. admin@mycompany.com']
565
));
566
567
$section->addInput(new Form_Input(
568
	'dn_commonname',
569
	'Common Name',
570
	'text',
571
	$pconfig['dn_commonname'],
572
	['placeholder' => 'e.g. internal-ca']
573
));
574
575
$form->add($section);
576
577
print $form;
578
579
include('foot.inc');