Project

General

Profile

Download (25.5 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	system_certmanager.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
*/
30
/*
31
	pfSense_MODULE:	certificate_manager
32
*/
33

    
34
##|+PRIV
35
##|*IDENT=page-system-certmanager
36
##|*NAME=System: Certificate Manager
37
##|*DESCR=Allow access to the 'System: Certificate Manager' page.
38
##|*MATCH=system_certmanager.php*
39
##|-PRIV
40

    
41
require("guiconfig.inc");
42
require_once("certs.inc");
43

    
44
$cert_methods = array(
45
	"import" => gettext("Import an existing Certificate"),
46
	"internal" => gettext("Create an internal Certificate"),
47
	"external" => gettext("Create a Certificate Signing Request"),
48
);
49

    
50
$cert_keylens = array( "512", "1024", "2048", "4096");
51
$cert_types = array(	"ca" => "Certificate Authority",
52
			"server" => "Server Certificate",
53
			"user" => "User Certificate");
54

    
55
$altname_types = array("DNS", "IP", "email", "URI");
56
$openssl_digest_algs = array("sha1", "sha224", "sha256", "sha384", "sha512");
57

    
58
$pgtitle = array(gettext("System"), gettext("Certificate Manager"));
59

    
60
if (is_numericint($_GET['userid']))
61
	$userid = $_GET['userid'];
62
if (isset($_POST['userid']) && is_numericint($_POST['userid']))
63
	$userid = $_POST['userid'];
64

    
65
if (isset($userid)) {
66
	$cert_methods["existing"] = gettext("Choose an existing certificate");
67
	if (!is_array($config['system']['user']))
68
		$config['system']['user'] = array();
69
	$a_user =& $config['system']['user'];
70
}
71

    
72
if (is_numericint($_GET['id']))
73
	$id = $_GET['id'];
74
if (isset($_POST['id']) && is_numericint($_POST['id']))
75
	$id = $_POST['id'];
76

    
77
if (!is_array($config['ca']))
78
	$config['ca'] = array();
79

    
80
$a_ca =& $config['ca'];
81

    
82
if (!is_array($config['cert']))
83
	$config['cert'] = array();
84

    
85
$a_cert =& $config['cert'];
86

    
87
$internal_ca_count = 0;
88
foreach ($a_ca as $ca)
89
	if ($ca['prv'])
90
		$internal_ca_count++;
91

    
92
$act = $_GET['act'];
93
if ($_POST['act'])
94
	$act = $_POST['act'];
95

    
96
if ($act == "del") {
97

    
98
	if (!isset($a_cert[$id])) {
99
		pfSenseHeader("system_certmanager.php");
100
		exit;
101
	}
102

    
103
	$name = $a_cert[$id]['descr'];
104
	unset($a_cert[$id]);
105
	write_config();
106
	$savemsg = sprintf(gettext("Certificate %s successfully deleted"), $name) . "<br />";
107
	pfSenseHeader("system_certmanager.php");
108
	exit;
109
}
110

    
111
if ($act == "new") {
112
	$pconfig['method'] = $_GET['method'];
113
	$pconfig['keylen'] = "2048";
114
	$pconfig['digest_alg'] = "sha256";
115
	$pconfig['csr_keylen'] = "2048";
116
	$pconfig['csr_digest_alg'] = "sha256";
117
	$pconfig['type'] = "user";
118
	$pconfig['lifetime'] = "3650";
119
}
120

    
121
if ($act == "exp") {
122

    
123
	if (!$a_cert[$id]) {
124
		pfSenseHeader("system_certmanager.php");
125
		exit;
126
	}
127

    
128
	$exp_name = urlencode("{$a_cert[$id]['descr']}.crt");
129
	$exp_data = base64_decode($a_cert[$id]['crt']);
130
	$exp_size = strlen($exp_data);
131

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

    
139
if ($act == "key") {
140

    
141
	if (!$a_cert[$id]) {
142
		pfSenseHeader("system_certmanager.php");
143
		exit;
144
	}
145

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

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

    
157
if ($act == "p12") {
158
	if (!$a_cert[$id]) {
159
		pfSenseHeader("system_certmanager.php");
160
		exit;
161
	}
162

    
163
	$exp_name = urlencode("{$a_cert[$id]['descr']}.p12");
164
	$args = array();
165
	$args['friendly_name'] = $a_cert[$id]['descr'];
166

    
167
	$ca = lookup_ca($a_cert[$id]['caref']);
168
	if ($ca)
169
		$args['extracerts'] = openssl_x509_read(base64_decode($ca['crt']));
170

    
171
	$res_crt = openssl_x509_read(base64_decode($a_cert[$id]['crt']));
172
	$res_key = openssl_pkey_get_private(array(0 => base64_decode($a_cert[$id]['prv']) , 1 => ""));
173

    
174
	$exp_data = "";
175
	openssl_pkcs12_export($res_crt, $exp_data, $res_key, null, $args);
176
	$exp_size = strlen($exp_data);
177

    
178
	header("Content-Type: application/octet-stream");
179
	header("Content-Disposition: attachment; filename={$exp_name}");
180
	header("Content-Length: $exp_size");
181
	echo $exp_data;
182
	exit;
183
}
184

    
185
if ($act == "csr") {
186

    
187
	if (!$a_cert[$id]) {
188
		pfSenseHeader("system_certmanager.php");
189
		exit;
190
	}
191

    
192
	$pconfig['descr'] = $a_cert[$id]['descr'];
193
	$pconfig['csr'] = base64_decode($a_cert[$id]['csr']);
194
}
195

    
196
if ($_POST) {
197
	if ($_POST['save'] == gettext("Save")) {
198
		$input_errors = array();
199
		$pconfig = $_POST;
200

    
201
		/* input validation */
202
		if ($pconfig['method'] == "import") {
203
			$reqdfields = explode(" ",
204
					"descr cert key");
205
			$reqdfieldsn = array(
206
					gettext("Descriptive name"),
207
					gettext("Certificate data"),
208
					gettext("Key data"));
209
			if ($_POST['cert'] && (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE")))
210
				$input_errors[] = gettext("This certificate does not appear to be valid.");
211
		}
212

    
213
		if ($pconfig['method'] == "internal") {
214
			$reqdfields = explode(" ",
215
					"descr caref keylen type lifetime dn_country dn_state dn_city ".
216
					"dn_organization dn_email dn_commonname");
217
			$reqdfieldsn = array(
218
					gettext("Descriptive name"),
219
					gettext("Certificate authority"),
220
					gettext("Key length"),
221
					gettext("Certificate Type"),
222
					gettext("Lifetime"),
223
					gettext("Distinguished name Country Code"),
224
					gettext("Distinguished name State or Province"),
225
					gettext("Distinguished name City"),
226
					gettext("Distinguished name Organization"),
227
					gettext("Distinguished name Email Address"),
228
					gettext("Distinguished name Common Name"));
229
		}
230

    
231
		if ($pconfig['method'] == "external") {
232
			$reqdfields = explode(" ",
233
					"descr csr_keylen csr_dn_country csr_dn_state csr_dn_city ".
234
					"csr_dn_organization csr_dn_email csr_dn_commonname");
235
			$reqdfieldsn = array(
236
					gettext("Descriptive name"),
237
					gettext("Key length"),
238
					gettext("Distinguished name Country Code"),
239
					gettext("Distinguished name State or Province"),
240
					gettext("Distinguished name City"),
241
					gettext("Distinguished name Organization"),
242
					gettext("Distinguished name Email Address"),
243
					gettext("Distinguished name Common Name"));
244
		}
245

    
246
		if ($pconfig['method'] == "existing") {
247
			$reqdfields = array("certref");
248
			$reqdfieldsn = array(gettext("Existing Certificate Choice"));
249
		}
250

    
251
		$altnames = array();
252
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
253
		if ($pconfig['method'] != "import" && $pconfig['method'] != "existing") {
254
			/* subjectAltNames */
255
			foreach ($_POST['altname_value'] as $idx => $value) {
256
				if (empty($value))
257
					continue;
258

    
259
				$altnames[$idx] = array(
260
					'type' => $_POST['altname_type'][$idx],
261
					'value' => $value
262
				);
263
			}
264
			$pconfig['altnames']['item'] = $altnames;
265

    
266
			/* Input validation for subjectAltNames */
267
			foreach ($altnames as $idx => $altname) {
268
				switch ($altname['type']) {
269
					case "DNS":
270
						if (!is_hostname($altname['value']))
271
							array_push($input_errors, "DNS subjectAltName values must be valid hostnames or FQDNs");
272
						break;
273
					case "IP":
274
						if (!is_ipaddr($altname['value']))
275
							array_push($input_errors, "IP subjectAltName values must be valid IP Addresses");
276
						break;
277
					case "email":
278
						if (empty($altname['value']))
279
							array_push($input_errors, "You must provide an e-mail address for this type of subjectAltName");
280
						if (preg_match("/[\!\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $altname['value']))
281
							array_push($input_errors, "The e-mail provided in a subjectAltName contains invalid characters.");
282
						break;
283
					case "URI":
284
						/* Close enough? */
285
						if (!is_URL($altname['value']))
286
							$input_errors[] = "URI subjectAltName types must be a valid URI";
287
						break;
288
					default:
289
						$input_errors[] = "Unrecognized subjectAltName type.";
290
				}
291
			}
292

    
293
			/* Make sure we do not have invalid characters in the fields for the certificate */
294
			for ($i = 0; $i < count($reqdfields); $i++) {
295
				if (preg_match('/email/', $reqdfields[$i])){ /* dn_email or csr_dn_name */
296
					if (preg_match("/[\!\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST[$reqdfields[$i]]))
297
						array_push($input_errors, "The field 'Distinguished name Email Address' contains invalid characters.");
298
				}else if (preg_match('/commonname/', $reqdfields[$i])){ /* dn_commonname or csr_dn_commonname */
299
					if (preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST[$reqdfields[$i]]))
300
						array_push($input_errors, "The field 'Distinguished name Common Name' contains invalid characters.");
301
				}else if (($reqdfields[$i] != "descr") && preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\.\"\']/", $_POST[$reqdfields[$i]]))
302
					array_push($input_errors, "The field '" . $reqdfieldsn[$i] . "' contains invalid characters.");
303
			}
304

    
305
			if (($pconfig['method'] != "external") && isset($_POST["keylen"]) && !in_array($_POST["keylen"], $cert_keylens))
306
				array_push($input_errors, gettext("Please select a valid Key Length."));
307
			if (($pconfig['method'] != "external") && !in_array($_POST["digest_alg"], $openssl_digest_algs))
308
				array_push($input_errors, gettext("Please select a valid Digest Algorithm."));
309

    
310
			if (($pconfig['method'] == "external") && isset($_POST["csr_keylen"]) && !in_array($_POST["csr_keylen"], $cert_keylens))
311
				array_push($input_errors, gettext("Please select a valid Key Length."));
312
			if (($pconfig['method'] == "external") && !in_array($_POST["csr_digest_alg"], $openssl_digest_algs))
313
				array_push($input_errors, gettext("Please select a valid Digest Algorithm."));
314
		}
315

    
316
		/* if this is an AJAX caller then handle via JSON */
317
		if (isAjax() && is_array($input_errors)) {
318
			input_errors2Ajax($input_errors);
319
			exit;
320
		}
321

    
322
		/* save modifications */
323
		if (!$input_errors) {
324

    
325
			if ($pconfig['method'] == "existing") {
326
				$cert = lookup_cert($pconfig['certref']);
327
				if ($cert && $a_user)
328
					$a_user[$userid]['cert'][] = $cert['refid'];
329
			} else {
330
				$cert = array();
331
				$cert['refid'] = uniqid();
332
				if (isset($id) && $a_cert[$id])
333
					$cert = $a_cert[$id];
334

    
335
				$cert['descr'] = $pconfig['descr'];
336

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

    
339
				if ($pconfig['method'] == "import")
340
					cert_import($cert, $pconfig['cert'], $pconfig['key']);
341

    
342
				if ($pconfig['method'] == "internal") {
343
					$dn = array(
344
						'countryName' => $pconfig['dn_country'],
345
						'stateOrProvinceName' => $pconfig['dn_state'],
346
						'localityName' => $pconfig['dn_city'],
347
						'organizationName' => $pconfig['dn_organization'],
348
						'emailAddress' => $pconfig['dn_email'],
349
						'commonName' => $pconfig['dn_commonname']);
350
					if (count($altnames)) {
351
						$altnames_tmp = "";
352
						foreach ($altnames as $altname) {
353
							$altnames_tmp[] = "{$altname['type']}:{$altname['value']}";
354
						}
355
						$dn['subjectAltName'] = implode(",", $altnames_tmp);
356
					}
357
					if (!cert_create($cert, $pconfig['caref'], $pconfig['keylen'],
358
						$pconfig['lifetime'], $dn, $pconfig['type'], $pconfig['digest_alg'])){
359
						while($ssl_err = openssl_error_string()){
360
							$input_errors = array();
361
							array_push($input_errors, "openssl library returns: " . $ssl_err);
362
						}
363
					}
364
				}
365

    
366
				if ($pconfig['method'] == "external") {
367
					$dn = array(
368
						'countryName' => $pconfig['csr_dn_country'],
369
						'stateOrProvinceName' => $pconfig['csr_dn_state'],
370
						'localityName' => $pconfig['csr_dn_city'],
371
						'organizationName' => $pconfig['csr_dn_organization'],
372
						'emailAddress' => $pconfig['csr_dn_email'],
373
						'commonName' => $pconfig['csr_dn_commonname']);
374
					if (count($altnames)) {
375
						$altnames_tmp = "";
376
						foreach ($altnames as $altname) {
377
							$altnames_tmp[] = "{$altname['type']}:{$altname['value']}";
378
						}
379
						$dn['subjectAltName'] = implode(",", $altnames_tmp);
380
					}
381
					if(!csr_generate($cert, $pconfig['csr_keylen'], $dn, $pconfig['csr_digest_alg'])){
382
						while($ssl_err = openssl_error_string()){
383
							$input_errors = array();
384
							array_push($input_errors, "openssl library returns: " . $ssl_err);
385
						}
386
					}
387
				}
388
				error_reporting($old_err_level);
389

    
390
				if (isset($id) && $a_cert[$id])
391
					$a_cert[$id] = $cert;
392
				else
393
					$a_cert[] = $cert;
394
				if (isset($a_user) && isset($userid))
395
					$a_user[$userid]['cert'][] = $cert['refid'];
396
			}
397

    
398
			if (!$input_errors)
399
				write_config();
400

    
401
			if ($userid) {
402
				post_redirect("system_usermanager.php", array('act' => 'edit', 'userid' => $userid));
403
				exit;
404
			}
405
		}
406
	}
407

    
408
	if ($_POST['save'] == gettext("Update")) {
409
		unset($input_errors);
410
		$pconfig = $_POST;
411

    
412
		/* input validation */
413
		$reqdfields = explode(" ", "descr cert");
414
		$reqdfieldsn = array(
415
			gettext("Descriptive name"),
416
			gettext("Final Certificate data"));
417

    
418
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
419

    
420
//		old way
421
		/* make sure this csr and certificate subjects match */
422
//		$subj_csr = csr_get_subject($pconfig['csr'], false);
423
//		$subj_cert = cert_get_subject($pconfig['cert'], false);
424
//
425
//		if ( !isset($_POST['ignoresubjectmismatch']) && !($_POST['ignoresubjectmismatch'] == "yes") ) {
426
//			if (strcmp($subj_csr,$subj_cert)) {
427
//				$input_errors[] = sprintf(gettext("The certificate subject '%s' does not match the signing request subject."),$subj_cert);
428
//				$subject_mismatch = true;
429
//			}
430
//		}
431
		$mod_csr  =  csr_get_modulus($pconfig['csr'], false);
432
		$mod_cert = cert_get_modulus($pconfig['cert'], false);
433

    
434
		if (strcmp($mod_csr,$mod_cert)) {
435
			// simply: if the moduli don't match, then the private key and public key won't match
436
			$input_errors[] = sprintf(gettext("The certificate modulus does not match the signing request modulus."),$subj_cert);
437
			$subject_mismatch = true;
438
		}
439

    
440
		/* if this is an AJAX caller then handle via JSON */
441
		if (isAjax() && is_array($input_errors)) {
442
			input_errors2Ajax($input_errors);
443
			exit;
444
		}
445

    
446
		/* save modifications */
447
		if (!$input_errors) {
448

    
449
			$cert = $a_cert[$id];
450

    
451
			$cert['descr'] = $pconfig['descr'];
452

    
453
			csr_complete($cert, $pconfig['cert']);
454

    
455
			$a_cert[$id] = $cert;
456

    
457
			write_config();
458

    
459
			pfSenseHeader("system_certmanager.php");
460
		}
461
	}
462
}
463

    
464
include("head.inc");
465

    
466
if ($input_errors)
467
	print_input_errors($input_errors);
468
if ($savemsg)
469
	print_info_box($savemsg);
470

    
471
$tab_array = array();
472
$tab_array[] = array(gettext("CAs"), false, "system_camanager.php");
473
$tab_array[] = array(gettext("Certificates"), true, "system_certmanager.php");
474
$tab_array[] = array(gettext("Certificate Revocation"), false, "system_crlmanager.php");
475
display_top_tabs($tab_array);
476

    
477
// Load valid country codes
478
$dn_cc = array();
479
if (file_exists("/etc/ca_countries")){
480
	$dn_cc_file=file("/etc/ca_countries");
481
	foreach($dn_cc_file as $line)
482
		if (preg_match('/^(\S*)\s(.*)$/', $line, $matches))
483
			array_push($dn_cc, $matches[1]);
484
}
485

    
486
if (!($act == "new" || (($_POST['save'] == gettext("Save")) && $input_errors)))
487
{
488
?>
489
<div class="table-responsive">
490
<table class="table table-striped table-hover">
491
	<thead>
492
		<tr>
493
			<th><?=gettext("Name")?></th>
494
			<th><?=gettext("Issuer")?></th>
495
			<th><?=gettext("Distinguished Name")?></th>
496
			<th><?=gettext("In Use")?></th>
497
			<th></th>
498
		</tr>
499
	</thead>
500
	<tbody>
501
<?php
502
foreach($a_cert as $i => $cert):
503
	$name = htmlspecialchars($cert['descr']);
504

    
505
	if ($cert['crt']) {
506
		$subj = cert_get_subject($cert['crt']);
507
		$issuer = cert_get_issuer($cert['crt']);
508
		$purpose = cert_get_purpose($cert['crt']);
509
		list($startdate, $enddate) = cert_get_dates($cert['crt']);
510

    
511
		if ($subj==$issuer)
512
			$caname = '<i>'. gettext("self-signed") .'</i>';
513
		else
514
			$caname = '<i>'. gettext("external").'</i>';
515

    
516
		$subj = htmlspecialchars($subj);
517
	}
518

    
519
	if ($cert['csr']) {
520
		$subj = htmlspecialchars(csr_get_subject($cert['csr']));
521
		$caname = "<em>" . gettext("external - signature pending") . "</em>";
522
	}
523

    
524
	$ca = lookup_ca($cert['caref']);
525
	if ($ca)
526
		$caname = $ca['descr'];
527
?>
528
		<tr>
529
			<td>
530
				<?=$name?>
531
				<?php if ($cert['type']): ?>
532
					<i><?=$cert_types[$cert['type']]?></i>
533
				<?php endif?>
534
				<?php if (is_array($purpose)): ?>
535
					CA: <b><?=$purpose['ca']?></b>, Server: <b><?=$purpose['server']?></b>
536
				<?php endif?>
537
			</td>
538
			<td><?=$caname?></td>
539
			<td>
540
				<?=$subj?>
541
				<br />
542
				<small>
543
					<?=gettext("Valid From")?>: <b><?=$startdate ?></b>, <?=gettext("Valid Until")?>: <b><?=$enddate ?></b>
544
				</small>
545
			</td>
546
			<td>
547
				<?php if (is_cert_revoked($cert)): ?>
548
					<i>Revoked </i>
549
				<?php endif?>
550
				<?php if (is_webgui_cert($cert['refid'])): ?>
551
					webConfigurator
552
				<?php endif?>
553
				<?php if (is_user_cert($cert['refid'])): ?>
554
					User Cert
555
				<?php endif?>
556
				<?php if (is_openvpn_server_cert($cert['refid'])): ?>
557
					OpenVPN Server
558
				<?php endif?>
559
				<?php if (is_openvpn_client_cert($cert['refid'])): ?>
560
					OpenVPN Client
561
				<?php endif?>
562
				<?php if (is_ipsec_cert($cert['refid'])): ?>
563
					IPsec Tunnel
564
				<?php endif?>
565
				<?php if (is_captiveportal_cert($cert['refid'])): ?>
566
					Captive Portal
567
				<?php endif?>
568
			</td>
569
			<td>
570
				<a href="system_certmanager.php?act=exp&amp;id=<?=$i?>" class="btn btn-xs btn-default">
571
					<?=gettext("export")?>
572
				</a>
573
				<a href="system_certmanager.php?act=key&amp;id=<?=$i?>" class="btn btn-xs btn-default">
574
					<?=gettext("export key")?>
575
				</a>
576
				<a href="system_certmanager.php?act=p12&amp;id=<?=$i?>" class="btn btn-xs btn-default">
577
					<?=gettext("export p12")?>
578
				</a>
579
				<?php if (!cert_in_use($cert['refid'])): ?>
580
					<a href="system_certmanager.php?act=del&amp;id=<?=$i?>" class="btn btn-xs btn-danger">
581
						<?=gettext("delete")?>
582
					</a>
583
				<?php endif?>
584
				<?php if ($cert['csr']): ?>
585
					<a href="system_certmanager.php?act=csr&amp;id=<?=$i?>" class="btn btn-xs btn-default">
586
						<?=gettext("update csr")?>
587
					</a>
588
				<?php endif?>
589
			</td>
590
		</tr>
591
<?php endforeach; ?>
592
	</tbody>
593
</table>
594
</div>
595

    
596
<nav class="action-buttons">
597
	<a href="?act=new" class="btn btn-success">add new</a>
598
</nav>
599
<?
600
	include("foot.inc");
601
	exit;
602
}
603

    
604
require('classes/Form.class.php');
605
$form = new Form;
606

    
607
if ($act == "csr" || (($_POST['save'] == gettext("Update")) && $input_errors))
608
{
609
	$form->setAction('system_certmanager.php?act=csr');
610

    
611
	$section = new Form_Section('Complete Signing Request');
612

    
613
	if (isset($id) && $a_cert[$id])
614
	{
615
		$form->addGlobal(new Form_Input(
616
			'id',
617
			null,
618
			'hidden',
619
			$id
620
		));
621
	}
622

    
623
	$section->addInput(new Form_Input(
624
		'descr',
625
		'Descriptive name',
626
		'text',
627
		$pconfig['descr']
628
	));
629

    
630
	$section->addInput(new Form_Textarea(
631
		'csr',
632
		'Signing request data',
633
		$pconfig['csr']
634
	))->setReadonly()->setHelp('Copy the certificate signing data from here and '.
635
		'forward it to your certificate authority for signing.');
636

    
637
	$section->addInput(new Form_Textarea(
638
		'cert',
639
		'Final certificate data',
640
		$pconfig["cert"]
641
	))->setHelp('Paste the certificate received from your certificate authority here.');
642

    
643
	$form->add($section);
644
	print $form;
645

    
646
	include("foot.inc");
647
	exit;
648
}
649

    
650
$form->setAction('system_certmanager.php?act=edit');
651

    
652
if (isset($userid) && $a_user)
653
{
654
	$form->addGlobal(new Form_Input(
655
		'userid',
656
		null,
657
		'hidden',
658
		$userid
659
	));
660
}
661

    
662
if (isset($id) && $a_cert[$id])
663
{
664
	$form->addGlobal(new Form_Input(
665
		'id',
666
		null,
667
		'hidden',
668
		$id
669
	));
670
}
671

    
672
$section = new Form_Section('Add a new certificate');
673

    
674
if (!isset($id))
675
{
676
	$section->addInput(new Form_Select(
677
		'method',
678
		'Method',
679
		$pconfig['method'],
680
		$cert_methods
681
	))->toggles();
682
}
683

    
684
$section->addInput(new Form_Input(
685
	'descr',
686
	'Descriptive name',
687
	'text',
688
	($a_user && empty($pconfig['descr'])) ? $a_user[$userid]['name'] : $pconfig['descr']
689
))->addClass('toggle-existing');
690

    
691
$form->add($section);
692
$section = new Form_Section('Import Certificate');
693
$section->addClass('toggle-import collapse');
694

    
695
$section->addInput(new Form_Textarea(
696
	'cert',
697
	'Certificate data',
698
	$pconfig['cert']
699
))->setHelp('Paste a certificate in X.509 PEM format here.');
700

    
701
$section->addInput(new Form_Textarea(
702
	'key',
703
	'Private key data',
704
	$pconfig['key']
705
))->setHelp('Paste a private key in X.509 PEM format here.');
706

    
707
$form->add($section);
708
$section = new Form_Section('Internal Certificate');
709
$section->addClass('toggle-internal collapse');
710

    
711
if (!$internal_ca_count)
712
{
713
	$section->addInput(new Form_StaticText(
714
		'Certificate authority',
715
		gettext('No internal Certificate Authorities have been defined. You must').
716
		'<a href="system_camanager.php?act=new&amp;method=internal">'. gettext("create") .'</a>'.
717
		gettext('an internal CA before creating an internal certificate.')
718
	));
719
}
720
else
721
{
722
	$allCas = array();
723
	foreach ($a_ca as $ca)
724
	{
725
		if (!$ca['prv'])
726
				continue;
727

    
728
		$allCas[ $ca['refid'] ] = $ca['descr'];
729
	}
730

    
731
	$section->addInput(new Form_Select(
732
		'caref',
733
		'Certificate authority',
734
		$pconfig['caref'],
735
		$allCas
736
	));
737
}
738

    
739
$section->addInput(new Form_Select(
740
	'keylen',
741
	'Key length',
742
	$pconfig['keylen'],
743
	$cert_keylens
744
));
745

    
746
$section->addInput(new Form_Select(
747
	'digest_alg',
748
	'Digest Algorithm',
749
	$pconfig['digest_alg'],
750
	$openssl_digest_algs
751
))->setHelp('NOTE: It is recommended to use an algorithm stronger than '.
752
	'SHA1 when possible.") ?>');
753

    
754
$section->addInput(new Form_Select(
755
	'type',
756
	'Certificate Type',
757
	$pconfig['type'],
758
	$cert_types
759
))->setHelp('Type of certificate to generate. Used for placing '.
760
	'restrictions on the usage of the generated certificate.');
761

    
762
$section->addInput(new Form_Input(
763
	'lifetime',
764
	'Lifetime (days)',
765
	'number',
766
	$pconfig['lifetime']
767
));
768

    
769
$section->addInput(new Form_Select(
770
	'dn_country',
771
	'Country Code',
772
	$pconfig['dn_country'],
773
	$dn_cc
774
));
775

    
776
$section->addInput(new Form_Input(
777
	'dn_state',
778
	'State or Province',
779
	'text',
780
	$pconfig['dn_state'],
781
	['placeholder' => 'e.g. Texas']
782
));
783

    
784
$section->addInput(new Form_Input(
785
	'dn_city',
786
	'City',
787
	'text',
788
	$pconfig['dn_city'],
789
	['placeholder' => 'e.g. Austin']
790
));
791

    
792
$section->addInput(new Form_Input(
793
	'dn_organization',
794
	'Organization',
795
	'text',
796
	$pconfig['dn_organization'],
797
	['placeholder' => 'e.g. My Company Inc.']
798
));
799

    
800
$section->addInput(new Form_Input(
801
	'dn_email',
802
	'Email Address',
803
	'email',
804
	$pconfig['dn_email'],
805
	['placeholder' => 'e.g. admin@mycompany.com']
806
));
807

    
808
$section->addInput(new Form_Input(
809
	'dn_commonname',
810
	'Common Name',
811
	'text',
812
	$pconfig['dn_commonname'],
813
	['placeholder' => 'e.g. internal-ca']
814
));
815

    
816
$group = new Form_Group('Alternative Names');
817

    
818
if (empty($pconfig['altnames']['item']))
819
{
820
	$pconfig['altnames']['item'] = array(
821
		array('type' => null, 'value' => null)
822
	);
823
}
824

    
825
foreach ($pconfig['altnames']['item'] as $item)
826
{
827
	$group->add(new Form_Select(
828
		'altname_type',
829
		'Type',
830
		$item['type'],
831
		array(
832
			'DNS' => 'FQDN or Hostname',
833
			'IP' => 'IP address',
834
			'URI' => 'URI',
835
			'email' => 'email address',
836
		)
837
	));
838

    
839
	$group->add(new Form_Input(
840
		'altname_value',
841
		'Type',
842
		'text',
843
		$item['value']
844
	));
845

    
846
	$group->enableDuplication();
847
}
848

    
849
$section->add($group);
850

    
851
$form->add($section);
852
$section = new Form_Section('External Signing Request');
853
$section->addClass('toggle-external collapse');
854

    
855
$section->addInput(new Form_Select(
856
	'csr_keylen',
857
	'Key length',
858
	$pconfig['csr_keylen'],
859
	$cert_keylens
860
));
861

    
862
$section->addInput(new Form_Select(
863
	'csr_digest_alg',
864
	'Digest Algorithm',
865
	$pconfig['csr_digest_alg'],
866
	$openssl_digest_algs
867
))->setHelp('NOTE: It is recommended to use an algorithm stronger than '.
868
	'SHA1 when possible');
869

    
870
$section->addInput(new Form_Select(
871
	'dn_country',
872
	'Country Code',
873
	$pconfig['dn_country'],
874
	$dn_cc
875
));
876

    
877
$section->addInput(new Form_Input(
878
	'csr_dn_state',
879
	'State or Province',
880
	'text',
881
	$pconfig['csr_dn_state'],
882
	['placeholder' => 'e.g. Texas']
883
));
884

    
885
$section->addInput(new Form_Input(
886
	'csr_dn_city',
887
	'City',
888
	'text',
889
	$pconfig['csr_dn_city'],
890
	['placeholder' => 'e.g. Austin']
891
));
892

    
893
$section->addInput(new Form_Input(
894
	'csr_dn_organization',
895
	'Organization',
896
	'text',
897
	$pconfig['csr_dn_organization'],
898
	['placeholder' => 'e.g. My Company Inc.']
899
));
900

    
901
$section->addInput(new Form_Input(
902
	'csr_dn_email',
903
	'Email Address',
904
	'email',
905
	$pconfig['csr_dn_email'],
906
	['placeholder' => 'e.g. admin@mycompany.com']
907
));
908

    
909
$section->addInput(new Form_Input(
910
	'csr_dn_commonname',
911
	'Common Name',
912
	'text',
913
	$pconfig['csr_dn_commonname'],
914
	['placeholder' => 'e.g. internal-ca']
915
));
916

    
917
$form->add($section);
918
$section = new Form_Section('Choose an Existing Certificate');
919
$section->addClass('toggle-existing collapse');
920

    
921
$existCerts = array();
922
foreach ($config['cert'] as $cert)
923
{
924
	if (isset($userid) && in_array($cert['refid'], $config['system']['user'][$userid]['cert']))
925
		continue;
926

    
927
	$ca = lookup_ca($cert['caref']);
928
	if ($ca)
929
		$cert['descr'] .= " (CA: {$ca['descr']})";
930

    
931
	if (cert_in_use($cert['refid']))
932
		$cert['descr'] .= " <i>In Use</i>";
933
	if (is_cert_revoked($cert))
934
		$cert['descr'] .= " <b>Revoked</b>";
935

    
936
	$existCerts[ $cert['refid'] ] = $cert['descr'];
937
}
938

    
939
$section->addInput(new Form_Select(
940
	'certref',
941
	'Existing Certificates',
942
	$pconfig['certref'],
943
	$existCerts
944
));
945

    
946
$form->add($section);
947
print $form;
948

    
949
?>
950
<nav class="action-buttons">
951
	<a href="system_certmanager.php?act=new">
952
		<?=gettext("add or import certificate")?>
953
	</a>
954
</nav>
955

    
956
<?php include('foot.inc');
(199-199/241)