Project

General

Profile

Download (19.3 KB) Statistics
| Branch: | Tag: | Revision:
1 d43ad788 Scott Ullrich
<?php
2
/* $Id$ */
3
/*
4 c5f010aa jim-p
	Copyright (C) 2008 Shrew Soft Inc
5
	Copyright (C) 2010 Jim Pingle <jimp@pfsense.org>
6
	All rights reserved.
7 d43ad788 Scott Ullrich
8
        Redistribution and use in source and binary forms, with or without
9
        modification, are permitted provided that the following conditions are met:
10
11
        1. Redistributions of source code must retain the above copyright notice,
12
           this list of conditions and the following disclaimer.
13
14
        2. Redistributions in binary form must reproduce the above copyright
15
           notice, this list of conditions and the following disclaimer in the
16
           documentation and/or other materials provided with the distribution.
17
18
        THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19
        INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20
        AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21
        AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
22
        OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
        SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
        INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
        CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
        ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
        POSSIBILITY OF SUCH DAMAGE.
28
29
		DISABLE_PHP_LINT_CHECKING
30 523855b0 Scott Ullrich
		pfSense_MODULE:	certificate_managaer
31 d43ad788 Scott Ullrich
*/
32
33 87b4deb2 jim-p
define("OPEN_SSL_CONF_PATH", "/etc/ssl/openssl.cnf");
34
35 d43ad788 Scott Ullrich
require_once("functions.inc");
36
37 e09b941d jim-p
global $openssl_digest_algs;
38 ca621902 jim-p
$openssl_digest_algs = array("sha1", "sha224", "sha256", "sha384", "sha512");
39
40 e09b941d jim-p
global $openssl_crl_status;
41
$openssl_crl_status = array(
42
	OCSP_REVOKED_STATUS_NOSTATUS              => "No Status (default)",
43
	OCSP_REVOKED_STATUS_UNSPECIFIED           => "Unspecified",
44
	OCSP_REVOKED_STATUS_KEYCOMPROMISE         => "Key Compromise",
45
	OCSP_REVOKED_STATUS_CACOMPROMISE          => "CA Compromise",
46
	OCSP_REVOKED_STATUS_AFFILIATIONCHANGED    => "Affiliation Changed",
47
	OCSP_REVOKED_STATUS_SUPERSEDED            => "Superseded",
48
	OCSP_REVOKED_STATUS_CESSATIONOFOPERATION  => "Cessation of Operation",
49
	OCSP_REVOKED_STATUS_CERTIFICATEHOLD       => "Certificate Hold"
50
);
51
52 d43ad788 Scott Ullrich
function & lookup_ca($refid) {
53
	global $config;
54
55 1e332e98 jim-p
	if (is_array($config['ca']))
56
		foreach ($config['ca'] as & $ca)
57 d43ad788 Scott Ullrich
			if ($ca['refid'] == $refid)
58
				return $ca;
59
60
	return false;
61
}
62
63
function & lookup_ca_by_subject($subject) {
64
	global $config;
65
66 1e332e98 jim-p
	if (is_array($config['ca']))
67
		foreach ($config['ca'] as & $ca)
68 d43ad788 Scott Ullrich
		{
69
			$ca_subject = cert_get_subject($ca['crt']);
70
			if ($ca_subject == $subject)
71
				return $ca;
72
		}
73
74
	return false;
75
}
76
77
function & lookup_cert($refid) {
78
	global $config;
79
80 1e332e98 jim-p
	if (is_array($config['cert']))
81
		foreach ($config['cert'] as & $cert)
82 d43ad788 Scott Ullrich
			if ($cert['refid'] == $refid)
83
				return $cert;
84
85
	return false;
86
}
87
88 c5f010aa jim-p
function & lookup_cert_by_name($name) {
89
	global $config;
90
	if (is_array($config['cert']))
91
		foreach ($config['cert'] as & $cert)
92 f2a86ca9 jim-p
			if ($cert['descr'] == $name)
93 c5f010aa jim-p
				return $cert;
94
}
95
96
function & lookup_crl($refid) {
97
	global $config;
98
99
	if (is_array($config['crl']))
100
		foreach ($config['crl'] as & $crl)
101
			if ($crl['refid'] == $refid)
102
				return $crl;
103
104
	return false;
105
}
106
107 d43ad788 Scott Ullrich
function ca_chain_array(& $cert) {
108
	if($cert['caref']) {
109
		$chain = array();
110 5289dc57 jim-p
		$crt = lookup_ca($cert['caref']);
111 d43ad788 Scott Ullrich
		$chain[] = $crt;
112
		while ($crt) {
113
			$caref = $crt['caref'];
114
			if($caref)
115 5289dc57 jim-p
				$crt = lookup_ca($caref);
116 d43ad788 Scott Ullrich
			else
117
				$crt = false;
118
			if($crt)
119
				$chain[] = $crt;
120
		}
121
		return $chain;
122
	}
123
	return false;
124
}
125
126
function ca_chain(& $cert) {
127
	if($cert['caref']) {
128
		$ca = "";
129
		$cas = ca_chain_array($cert);
130
		if (is_array($cas))
131
			foreach ($cas as & $ca_cert)
132
			{
133
				$ca .= base64_decode($ca_cert['crt']);
134
				$ca .= "\n";
135
			}
136
		return $ca;
137
	}
138
	return "";
139
}
140
141 bfa992bc jim-p
function ca_import(& $ca, $str, $key="", $serial=0) {
142 d43ad788 Scott Ullrich
	global $config;
143
144
	$ca['crt'] = base64_encode($str);
145 ecefc738 jim-p
	if (!empty($key))
146
		$ca['prv'] = base64_encode($key);
147 bfa992bc jim-p
	if (!empty($serial))
148
		$ca['serial'] = $serial;
149 d43ad788 Scott Ullrich
	$subject = cert_get_subject($str, false);
150
	$issuer = cert_get_issuer($str, false);
151
	
152
	// Find my issuer unless self-signed
153
	if($issuer <> $subject) {
154
		$issuer_crt =& lookup_ca_by_subject($issuer);
155
		if($issuer_crt)
156
			$ca['caref'] = $issuer_crt['refid'];
157
	}
158
159
	/* Correct if child certificate was loaded first */
160 1e332e98 jim-p
	if (is_array($config['ca']))
161
		foreach ($config['ca'] as & $oca)
162 d43ad788 Scott Ullrich
		{
163
			$issuer = cert_get_issuer($oca['crt']);
164
			if($ca['refid']<>$oca['refid'] && $issuer==$subject)
165
				$oca['caref'] = $ca['refid'];
166
		}
167 1e332e98 jim-p
	if (is_array($config['cert']))
168
		foreach ($config['cert'] as & $cert)
169 d43ad788 Scott Ullrich
		{
170
			$issuer = cert_get_issuer($cert['crt']);
171
			if($issuer==$subject)
172
				$cert['caref'] = $ca['refid'];
173
		}
174
	return true;
175
}
176
177 ca621902 jim-p
function ca_create(& $ca, $keylen, $lifetime, $dn, $digest_alg = "sha256") {
178 d43ad788 Scott Ullrich
179
	$args = array(
180 87b4deb2 jim-p
		"x509_extensions" => "v3_ca",
181 ca621902 jim-p
		"digest_alg" => $digest_alg,
182 51dbdcde Ermal Lu?i
		"private_key_bits" => (int)$keylen,
183 d43ad788 Scott Ullrich
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
184
		"encrypt_key" => false);
185
186
	// generate a new key pair
187 838e27bf jim-p
	$res_key = openssl_pkey_new($args);
188 1b6d9fa5 Evgeny Yurchenko
	if (!$res_key) return false;
189 d43ad788 Scott Ullrich
190
	// generate a certificate signing request
191
	$res_csr = openssl_csr_new($dn, $res_key, $args);
192 1b6d9fa5 Evgeny Yurchenko
	if (!$res_csr) return false;
193 d43ad788 Scott Ullrich
194
	// self sign the certificate
195
	$res_crt = openssl_csr_sign($res_csr, null, $res_key, $lifetime, $args);
196 1b6d9fa5 Evgeny Yurchenko
	if (!$res_crt) return false;
197 d43ad788 Scott Ullrich
198
	// export our certificate data
199 1b6d9fa5 Evgeny Yurchenko
	if (!openssl_pkey_export($res_key, $str_key) ||
200
	    !openssl_x509_export($res_crt, $str_crt))
201
		return false;
202 d43ad788 Scott Ullrich
203
	// return our ca information
204
	$ca['crt'] = base64_encode($str_crt);
205
	$ca['prv'] = base64_encode($str_key);
206
	$ca['serial'] = 0;
207
208
	return true;
209
}
210
211 ca621902 jim-p
function ca_inter_create(& $ca, $keylen, $lifetime, $dn, $caref, $digest_alg = "sha256") {
212 95c8cf48 Evgeny Yurchenko
	// Create Intermediate Certificate Authority
213
	$signing_ca =& lookup_ca($caref);
214
	if (!$signing_ca)
215
		return false;
216
217
	$signing_ca_res_crt = openssl_x509_read(base64_decode($signing_ca['crt']));
218
	$signing_ca_res_key = openssl_pkey_get_private(array(0 => base64_decode($signing_ca['prv']) , 1 => ""));
219
	if (!$signing_ca_res_crt || !$signing_ca_res_key) return false;
220
	$signing_ca_serial = ++$signing_ca['serial'];
221
222
	$args = array(
223 87b4deb2 jim-p
		"x509_extensions" => "v3_ca",
224 ca621902 jim-p
		"digest_alg" => $digest_alg,
225 95c8cf48 Evgeny Yurchenko
		"private_key_bits" => (int)$keylen,
226
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
227
		"encrypt_key" => false);
228
229
	// generate a new key pair
230
	$res_key = openssl_pkey_new($args);
231
	if (!$res_key) return false;
232
233
	// generate a certificate signing request
234
	$res_csr = openssl_csr_new($dn, $res_key, $args);
235
	if (!$res_csr) return false;
236
237
	// Sign the certificate
238
	$res_crt = openssl_csr_sign($res_csr, $signing_ca_res_crt, $signing_ca_res_key, $lifetime, $args, $signing_ca_serial);
239
	if (!$res_crt) return false;
240
241
	// export our certificate data
242
	if (!openssl_pkey_export($res_key, $str_key) ||
243
	    !openssl_x509_export($res_crt, $str_crt))
244
		return false;
245
246
	// return our ca information
247
	$ca['crt'] = base64_encode($str_crt);
248
	$ca['prv'] = base64_encode($str_key);
249
	$ca['serial'] = 0;
250
251
	return true;
252
}
253
254 d43ad788 Scott Ullrich
function cert_import(& $cert, $crt_str, $key_str) {
255
256
	$cert['crt'] = base64_encode($crt_str);
257
	$cert['prv'] = base64_encode($key_str);
258
259
	$subject = cert_get_subject($crt_str, false);
260
	$issuer = cert_get_issuer($crt_str, false);
261
	
262
	// Find my issuer unless self-signed
263
	if($issuer <> $subject) {
264
		$issuer_crt =& lookup_ca_by_subject($issuer);
265
		if($issuer_crt)
266
			$cert['caref'] = $issuer_crt['refid'];
267
	}
268
	return true;
269
}
270
271 ca621902 jim-p
function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type="user", $digest_alg = "sha256") {
272 d43ad788 Scott Ullrich
273
	$ca =& lookup_ca($caref);
274
	if (!$ca)
275
		return false;
276
277
	$ca_str_crt = base64_decode($ca['crt']);
278
	$ca_str_key = base64_decode($ca['prv']);
279
	$ca_res_crt = openssl_x509_read($ca_str_crt);
280 ae4dbded Ermal
	$ca_res_key = openssl_pkey_get_private(array(0 => $ca_str_key, 1 => ""));
281 22b380aa Evgeny Yurchenko
	if(!$ca_res_key) return false;
282 ae4dbded Ermal
	$ca_serial = ++$ca['serial'];
283 d43ad788 Scott Ullrich
284 7aaabd69 jim-p
	switch ($type) {
285
		case "ca":
286
			$cert_type = "v3_ca";
287
			break;
288
		case "server":
289
			$cert_type = "server";
290
			break;
291
		default:
292
			$cert_type = "usr_cert";
293
			break;
294
	}
295
296 d43ad788 Scott Ullrich
	$args = array(
297 7aaabd69 jim-p
		"x509_extensions" => $cert_type,
298 ca621902 jim-p
		"digest_alg" => $digest_alg,
299 51dbdcde Ermal Lu?i
		"private_key_bits" => (int)$keylen,
300 d43ad788 Scott Ullrich
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
301
		"encrypt_key" => false);
302
303
	// generate a new key pair
304 838e27bf jim-p
	$res_key = openssl_pkey_new($args);
305 22b380aa Evgeny Yurchenko
	if(!$res_key) return false;
306 d43ad788 Scott Ullrich
307
	// generate a certificate signing request
308
	$res_csr = openssl_csr_new($dn, $res_key, $args);
309 22b380aa Evgeny Yurchenko
	if(!$res_csr) return false;
310 d43ad788 Scott Ullrich
311
	// self sign the certificate
312
	$res_crt = openssl_csr_sign($res_csr, $ca_res_crt, $ca_res_key, $lifetime,
313
				 $args, $ca_serial);
314 22b380aa Evgeny Yurchenko
	if(!$res_crt) return false;
315 d43ad788 Scott Ullrich
316
	// export our certificate data
317 22b380aa Evgeny Yurchenko
	if (!openssl_pkey_export($res_key, $str_key) ||
318
	    !openssl_x509_export($res_crt, $str_crt))
319
		return false;
320 d43ad788 Scott Ullrich
321
	// return our certificate information
322
	$cert['caref'] = $caref;
323
	$cert['crt'] = base64_encode($str_crt);
324
	$cert['prv'] = base64_encode($str_key);
325 7aaabd69 jim-p
	$cert['type'] = $type;
326 d43ad788 Scott Ullrich
327
	return true;
328
}
329
330 ca621902 jim-p
function csr_generate(& $cert, $keylen, $dn, $digest_alg = "sha256") {
331 d43ad788 Scott Ullrich
332
	$args = array(
333 87b4deb2 jim-p
		"x509_extensions" => "v3_req",
334 ca621902 jim-p
		"digest_alg" => $digest_alg,
335 3198b8d3 Ermal Lu?i
		"private_key_bits" => (int)$keylen,
336 d43ad788 Scott Ullrich
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
337
		"encrypt_key" => false);
338
339
	// generate a new key pair
340 838e27bf jim-p
	$res_key = openssl_pkey_new($args);
341 22b380aa Evgeny Yurchenko
	if(!$res_key) return false;
342 d43ad788 Scott Ullrich
343
	// generate a certificate signing request
344
	$res_csr = openssl_csr_new($dn, $res_key, $args);
345 22b380aa Evgeny Yurchenko
	if(!$res_csr) return false;
346 d43ad788 Scott Ullrich
347
	// export our request data
348 22b380aa Evgeny Yurchenko
	if (!openssl_pkey_export($res_key, $str_key) ||
349
	    !openssl_csr_export($res_csr, $str_csr))
350
		return false;
351 d43ad788 Scott Ullrich
352
	// return our request information
353
	$cert['csr'] = base64_encode($str_csr);
354
	$cert['prv'] = base64_encode($str_key);
355
356
	return true;
357
}
358
359
function csr_complete(& $cert, $str_crt) {
360
361
	// return our request information
362
	$cert['crt'] = base64_encode($str_crt);
363
	unset($cert['csr']);
364
365
	return true;
366
}
367
368
function csr_get_subject($str_crt, $decode = true) {
369
370
	if ($decode)
371
		$str_crt = base64_decode($str_crt);
372
373
	$components = openssl_csr_get_subject($str_crt);
374
375 5ca13f69 Ermal
	if (empty($components) || !is_array($components))
376 d43ad788 Scott Ullrich
		return "unknown";
377
378 311f93cd Ermal
	ksort($components);
379 d43ad788 Scott Ullrich
	foreach ($components as $a => $v) {
380
		if (!strlen($subject))
381
			$subject = "{$a}={$v}";
382
		else
383
			$subject = "{$a}={$v}, {$subject}";
384
	}
385
386
	return $subject;
387
}
388
389
function cert_get_subject($str_crt, $decode = true) {
390
391
	if ($decode)
392
		$str_crt = base64_decode($str_crt);
393
394
	$inf_crt = openssl_x509_parse($str_crt);
395
	$components = $inf_crt['subject'];
396
397 5ca13f69 Ermal
	if (empty($components) || !is_array($components))
398 d43ad788 Scott Ullrich
		return "unknown";
399
400 b89c34aa Ermal
	ksort($components);
401 d43ad788 Scott Ullrich
	foreach ($components as $a => $v) {
402 b89c34aa Ermal
		if (is_array($v)) {
403
			ksort($v);
404 5479df47 jim-p
			foreach ($v as $w) {
405
				$asubject = "{$a}={$w}";
406
				$subject = (strlen($subject)) ? "{$asubject}, {$subject}" : $asubject;
407
			}
408 b89c34aa Ermal
		} else {
409 5479df47 jim-p
			$asubject = "{$a}={$v}";
410
			$subject = (strlen($subject)) ? "{$asubject}, {$subject}" : $asubject;
411
		}
412 d43ad788 Scott Ullrich
	}
413
414
	return $subject;
415
}
416
417
function cert_get_subject_array($crt) {
418
	$str_crt = base64_decode($crt);
419
	$inf_crt = openssl_x509_parse($str_crt);
420
	$components = $inf_crt['subject'];
421 e4d7a064 jim-p
422
	if (!is_array($components))
423
		return;
424
425 d43ad788 Scott Ullrich
	$subject_array = array();
426
427
	foreach($components as $a => $v)
428
		$subject_array[] = array('a' => $a, 'v' => $v);
429
430
	return $subject_array;
431
}
432
433 a84eb838 jim-p
function cert_get_subject_hash($crt) {
434
	$str_crt = base64_decode($crt);
435
	$inf_crt = openssl_x509_parse($str_crt);
436
	return $inf_crt['subject'];
437
}
438
439 d43ad788 Scott Ullrich
function cert_get_issuer($str_crt, $decode = true) {
440
441
	if ($decode)
442
		$str_crt = base64_decode($str_crt);
443
444
	$inf_crt = openssl_x509_parse($str_crt);
445
	$components = $inf_crt['issuer'];
446
	
447 5ca13f69 Ermal
	if (empty($components) || !is_array($components))
448 d43ad788 Scott Ullrich
		return "unknown";
449 5ca13f69 Ermal
450
	ksort($components);
451 d43ad788 Scott Ullrich
	foreach ($components as $a => $v) {
452
		if (!strlen($issuer))
453
			$issuer = "{$a}={$v}";
454
		else
455
			$issuer = "{$a}={$v}, {$issuer}";
456
	}
457
458
	return $issuer;
459
}
460
461 a828210b yakatz
/* this function works on x509 (crt), rsa key (prv), and req(csr) */
462
function cert_get_modulus($str_crt, $decode = true, $type = "crt"){
463
	if ($decode)
464
		$str_crt = base64_decode($str_crt);
465
466
	$modulus = "";
467
	if ( in_array($type, array("crt", "prv", "csr")) ) {
468
			$type = str_replace( array("crt","prv","csr"), array("x509","rsa","req"), $type);
469
			$modulus = exec("echo \"{$str_crt}\" | openssl {$type} -noout -modulus");
470
	}
471
	return $modulus;
472
}
473
function csr_get_modulus($str_crt, $decode = true){
474
	return cert_get_modulus($str_crt, $decode, "csr");
475
}
476 1379d66f jim-p
477
function cert_get_purpose($str_crt, $decode = true) {
478
	if ($decode)
479
		$str_crt = base64_decode($str_crt);
480
	$crt_details = openssl_x509_parse($str_crt);
481
	$purpose = array();
482
	$purpose['ca'] = (stristr($crt_details['extensions']['basicConstraints'], 'CA:TRUE') === false) ? 'No': 'Yes';
483
	$purpose['server'] = ($crt_details['extensions']['nsCertType'] == "SSL Server") ? 'Yes': 'No';
484
	return $purpose;
485
}
486
487 2b333210 jim-p
function cert_get_dates($str_crt, $decode = true) {
488
	if ($decode)
489
		$str_crt = base64_decode($str_crt);
490
	$crt_details = openssl_x509_parse($str_crt);
491
	if ($crt_details['validFrom_time_t'] > 0)
492
		$start = date('r', $crt_details['validFrom_time_t']);
493
	if ($crt_details['validTo_time_t'] > 0)
494
		$end = date('r', $crt_details['validTo_time_t']);
495
	return array($start, $end);
496
}
497
498 04761344 jim-p
function cert_get_serial($str_crt, $decode = true) {
499
	if ($decode)
500
		$str_crt = base64_decode($str_crt);
501
	$crt_details = openssl_x509_parse($str_crt);
502
	if (isset($crt_details['serialNumber']) && !empty($crt_details['serialNumber']))
503
		return $crt_details['serialNumber'];
504
	else
505
		return NULL;
506
}
507
508 a828210b yakatz
function prv_get_modulus($str_crt, $decode = true){
509
	return cert_get_modulus($str_crt, $decode, "prv");
510
}
511
512 dea98903 jim-p
function is_user_cert($certref) {
513 dab2e769 jim-p
	global $config;
514
	if (!is_array($config['system']['user']))
515
		return;
516
	foreach ($config['system']['user'] as $user) {
517
		if (!is_array($user['cert']))
518
			continue;
519
		foreach ($user['cert'] as $cert) {
520 dea98903 jim-p
			if ($certref == $cert)
521
				return true;
522 dab2e769 jim-p
		}
523
	}
524 dea98903 jim-p
	return false;
525 dab2e769 jim-p
}
526
527 dea98903 jim-p
function is_openvpn_server_cert($certref) {
528 dab2e769 jim-p
	global $config;
529 dea98903 jim-p
	if (!is_array($config['openvpn']['openvpn-server']))
530
		return;
531
	foreach ($config['openvpn']['openvpn-server'] as $ovpns) {
532
		if ($ovpns['certref'] == $certref)
533
			return true;
534
	}
535
	return false;
536
}
537
538
function is_openvpn_client_cert($certref) {
539
	global $config;
540
	if (!is_array($config['openvpn']['openvpn-client']))
541
		return;
542
	foreach ($config['openvpn']['openvpn-client'] as $ovpnc) {
543
		if ($ovpnc['certref'] == $certref)
544
			return true;
545
	}
546
	return false;
547
}
548
549
function is_ipsec_cert($certref) {
550
	global $config;
551
	if (!is_array($config['ipsec']['phase1']))
552
		return;
553
	foreach ($config['ipsec']['phase1'] as $ipsec) {
554
		if ($ipsec['certref'] == $certref)
555
			return true;
556
	}
557
	return false;
558
}
559
560
function is_webgui_cert($certref) {
561
	global $config;
562 8364184a jim-p
	if (($config['system']['webgui']['ssl-certref'] == $certref)
563
		&& ($config['system']['webgui']['protocol'] != "http"))
564 dea98903 jim-p
		return true;
565
}
566
567 36f6ed35 bcyrill
function is_captiveportal_cert($certref) {
568
	global $config;
569
	if (!is_array($config['captiveportal']))
570
		return;
571
	foreach ($config['captiveportal'] as $portal) {
572 adca02c4 bcyrill
		if (isset($portal['enable']) && isset($portal['httpslogin']) && ($portal['certref'] == $certref))
573 36f6ed35 bcyrill
			return true;
574
	}
575
	return false;
576
}
577
578 dea98903 jim-p
function cert_in_use($certref) {
579
	return (is_webgui_cert($certref) ||
580
		is_user_cert($certref) ||
581
		is_openvpn_server_cert($certref) ||
582
		is_openvpn_client_cert($certref) ||
583 36f6ed35 bcyrill
		is_ipsec_cert($certref) ||
584
		is_captiveportal_cert($certref));
585 dab2e769 jim-p
}
586
587 c5f010aa jim-p
function crl_create(& $crl, $caref, $name, $serial=0, $lifetime=9999) {
588
	global $config;
589
	$ca =& lookup_ca($caref);
590
	if (!$ca)
591
		return false;
592 f2a86ca9 jim-p
	$crl['descr'] = $name;
593 c5f010aa jim-p
	$crl['caref'] = $caref;
594
	$crl['serial'] = $serial;
595
	$crl['lifetime'] = $lifetime;
596
	$crl['cert'] = array();
597
	$crl_res = crl_update($crl);
598
	$config['crl'][] = $crl;
599
	return $crl_res;
600
}
601
602
function crl_update(& $crl) {
603
	global $config;
604
	$ca =& lookup_ca($crl['caref']);
605
	if (!$ca)
606
		return false;
607 7b757d1b jim-p
	// If we have text but no certs, it was imported and cannot be updated.
608 728003c8 jim-p
	if (($crl["method"] != "internal") && (!empty($crl['text']) && empty($crl['cert'])))
609 7b757d1b jim-p
		return false;
610 c5f010aa jim-p
	$crl['serial']++;
611
	$ca_str_crt = base64_decode($ca['crt']);
612
	$ca_str_key = base64_decode($ca['prv']);
613
	$crl_res = openssl_crl_new($ca_str_crt, $crl['serial'], $crl['lifetime']);
614 4bc2c676 jim-p
	if (is_array($crl['cert']) && (count($crl['cert']) > 0)) {
615
		foreach ($crl['cert'] as $cert) {
616
			openssl_crl_revoke_cert($crl_res, base64_decode($cert["crt"]), $cert["revoke_time"], $cert["reason"]);
617
		}
618 c5f010aa jim-p
	}
619
	openssl_crl_export($crl_res, $crl_text, $ca_str_key);
620
	$crl['text'] = base64_encode($crl_text);
621
	return $crl_res;
622
}
623
624
function cert_revoke($cert, & $crl, $reason=OCSP_REVOKED_STATUS_UNSPECIFIED) {
625
	global $config;
626 fb3f1993 jim-p
	if (is_cert_revoked($cert, $crl['refid']))
627 c5f010aa jim-p
		return true;
628 7b757d1b jim-p
	// If we have text but no certs, it was imported and cannot be updated.
629 fb3f1993 jim-p
	if (!is_crl_internal($crl))
630 7b757d1b jim-p
		return false;
631 c5f010aa jim-p
	$cert["reason"] = $reason;
632
	$cert["revoke_time"] = time();
633
	$crl["cert"][] = $cert;
634
	crl_update($crl);
635 fb3f1993 jim-p
	return true;
636 c5f010aa jim-p
}
637
638
function cert_unrevoke($cert, & $crl) {
639
	global $config;
640 fb3f1993 jim-p
	if (!is_crl_internal($crl))
641 7b757d1b jim-p
		return false;
642 c5f010aa jim-p
	foreach ($crl['cert'] as $id => $rcert) {
643 f2a86ca9 jim-p
		if (($rcert['refid'] == $cert['refid']) || ($rcert['descr'] == $cert['descr'])) {
644 c5f010aa jim-p
			unset($crl['cert'][$id]);
645 728003c8 jim-p
			if (count($crl['cert']) == 0) {
646
				// Protect against accidentally switching the type to imported, for older CRLs
647
				if (!isset($crl['method']))
648
					$crl['method'] = "internal";
649
				crl_update($crl);
650
			} else
651 a59831e7 jim-p
				crl_update($crl);
652 c5f010aa jim-p
			return true;
653
		}
654
	}
655
	return false;
656
}
657
658 04761344 jim-p
/* Compare two certificates to see if they match. */
659
function cert_compare($cert1, $cert2) {
660
	/* Ensure two certs are identical by first checking that their issuers match, then
661
		subjects, then serial numbers, and finally the moduli. Anything less strict
662
		could accidentally count two similar, but different, certificates as
663
		being identical. */
664
	$c1 = base64_decode($cert1['crt']);
665
	$c2 = base64_decode($cert2['crt']);
666
	if ((cert_get_issuer($c1, false) == cert_get_issuer($c2, false))
667
		&& (cert_get_subject($c1, false) == cert_get_subject($c2, false))
668
		&& (cert_get_serial($c1, false) == cert_get_serial($c2, false))
669
		&& (cert_get_modulus($c1, false) == cert_get_modulus($c2, false)))
670
		return true;
671
	return false;
672
}
673
674 fb3f1993 jim-p
function is_cert_revoked($cert, $crlref = "") {
675 c5f010aa jim-p
	global $config;
676 088ce869 jim-p
	if (!is_array($config['crl']))
677 c5f010aa jim-p
		return false;
678
679 fb3f1993 jim-p
	if (!empty($crlref)) {
680 28ff7ace jim-p
		$crl = lookup_crl($crlref);
681 088ce869 jim-p
		if (!is_array($crl['cert']))
682 fb3f1993 jim-p
			return false;
683 088ce869 jim-p
		foreach ($crl['cert'] as $rcert) {
684 04761344 jim-p
			if (cert_compare($rcert, $cert))
685 c5f010aa jim-p
				return true;
686
		}
687 fb3f1993 jim-p
	} else {
688
		foreach ($config['crl'] as $crl) {
689
			if (!is_array($crl['cert']))
690
				continue;
691
			foreach ($crl['cert'] as $rcert) {
692 04761344 jim-p
				if (cert_compare($rcert, $cert))
693 fb3f1993 jim-p
					return true;
694
			}
695
		}
696
	}
697
	return false;
698
}
699
700
function is_openvpn_server_crl($crlref) {
701
	global $config;
702
	if (!is_array($config['openvpn']['openvpn-server']))
703
		return;
704
	foreach ($config['openvpn']['openvpn-server'] as $ovpns) {
705 cd9f13e0 jim-p
		if (!empty($ovpns['crlref']) && ($ovpns['crlref'] == $crlref))
706 fb3f1993 jim-p
			return true;
707 c5f010aa jim-p
	}
708
	return false;
709
}
710
711 fb3f1993 jim-p
// Keep this general to allow for future expansion. See cert_in_use() above.
712
function crl_in_use($crlref) {
713
	return (is_openvpn_server_crl($crlref));
714
}
715
716
function is_crl_internal($crl) {
717 728003c8 jim-p
	return (!(!empty($crl['text']) && empty($crl['cert'])) || ($crl["method"] == "internal"));
718 fb3f1993 jim-p
}
719
720 b34b2b7d jim-p
function cert_get_cn($crt, $isref = false) {
721
	/* If this is a certref, not an actual cert, look up the cert first */
722
	if ($isref) {
723
		$cert = lookup_cert($crt);
724
		/* If it's not a valid cert, bail. */
725
		if (!(is_array($cert) && !empty($cert['crt'])))
726
			return "";
727
		$cert = $cert['crt'];
728
	} else {
729
		$cert = $crt;
730
	}
731
	$sub = cert_get_subject_array($cert);
732
	if (is_array($sub)) {
733
		foreach ($sub as $s) {
734
			if (strtoupper($s['a']) == "CN")
735
				return $s['v'];
736
		}
737
	}
738
	return "";
739
}
740
741 b89c34aa Ermal
?>