Projet

Général

Profil

Télécharger (20,1 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / certs.inc @ 340ce958

1
<?php
2
/* $Id$ */
3
/*
4
	Copyright (C) 2008 Shrew Soft Inc
5
	Copyright (C) 2010 Jim Pingle <jimp@pfsense.org>
6
	All rights reserved.
7

    
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
		pfSense_MODULE:	certificate_managaer
30
*/
31

    
32
define("OPEN_SSL_CONF_PATH", "/etc/ssl/openssl.cnf");
33

    
34
require_once("functions.inc");
35

    
36
global $openssl_digest_algs;
37
$openssl_digest_algs = array("sha1", "sha224", "sha256", "sha384", "sha512");
38

    
39
global $openssl_crl_status;
40
$openssl_crl_status = array(
41
	OCSP_REVOKED_STATUS_NOSTATUS              => "No Status (default)",
42
	OCSP_REVOKED_STATUS_UNSPECIFIED           => "Unspecified",
43
	OCSP_REVOKED_STATUS_KEYCOMPROMISE         => "Key Compromise",
44
	OCSP_REVOKED_STATUS_CACOMPROMISE          => "CA Compromise",
45
	OCSP_REVOKED_STATUS_AFFILIATIONCHANGED    => "Affiliation Changed",
46
	OCSP_REVOKED_STATUS_SUPERSEDED            => "Superseded",
47
	OCSP_REVOKED_STATUS_CESSATIONOFOPERATION  => "Cessation of Operation",
48
	OCSP_REVOKED_STATUS_CERTIFICATEHOLD       => "Certificate Hold"
49
);
50

    
51
function & lookup_ca($refid) {
52
	global $config;
53

    
54
	if (is_array($config['ca']))
55
		foreach ($config['ca'] as & $ca)
56
			if ($ca['refid'] == $refid)
57
				return $ca;
58

    
59
	return false;
60
}
61

    
62
function & lookup_ca_by_subject($subject) {
63
	global $config;
64

    
65
	if (is_array($config['ca']))
66
		foreach ($config['ca'] as & $ca)
67
		{
68
			$ca_subject = cert_get_subject($ca['crt']);
69
			if ($ca_subject == $subject)
70
				return $ca;
71
		}
72

    
73
	return false;
74
}
75

    
76
function & lookup_cert($refid) {
77
	global $config;
78

    
79
	if (is_array($config['cert']))
80
		foreach ($config['cert'] as & $cert)
81
			if ($cert['refid'] == $refid)
82
				return $cert;
83

    
84
	return false;
85
}
86

    
87
function & lookup_cert_by_name($name) {
88
	global $config;
89
	if (is_array($config['cert']))
90
		foreach ($config['cert'] as & $cert)
91
			if ($cert['descr'] == $name)
92
				return $cert;
93
}
94

    
95
function & lookup_crl($refid) {
96
	global $config;
97

    
98
	if (is_array($config['crl']))
99
		foreach ($config['crl'] as & $crl)
100
			if ($crl['refid'] == $refid)
101
				return $crl;
102

    
103
	return false;
104
}
105

    
106
function ca_chain_array(& $cert) {
107
	if($cert['caref']) {
108
		$chain = array();
109
		$crt = lookup_ca($cert['caref']);
110
		$chain[] = $crt;
111
		while ($crt) {
112
			$caref = $crt['caref'];
113
			if($caref)
114
				$crt = lookup_ca($caref);
115
			else
116
				$crt = false;
117
			if($crt)
118
				$chain[] = $crt;
119
		}
120
		return $chain;
121
	}
122
	return false;
123
}
124

    
125
function ca_chain(& $cert) {
126
	if($cert['caref']) {
127
		$ca = "";
128
		$cas = ca_chain_array($cert);
129
		if (is_array($cas))
130
			foreach ($cas as & $ca_cert)
131
			{
132
				$ca .= base64_decode($ca_cert['crt']);
133
				$ca .= "\n";
134
			}
135
		return $ca;
136
	}
137
	return "";
138
}
139

    
140
function ca_import(& $ca, $str, $key="", $serial=0) {
141
	global $config;
142

    
143
	$ca['crt'] = base64_encode($str);
144
	if (!empty($key))
145
		$ca['prv'] = base64_encode($key);
146
	if (!empty($serial))
147
		$ca['serial'] = $serial;
148
	$subject = cert_get_subject($str, false);
149
	$issuer = cert_get_issuer($str, false);
150
	
151
	// Find my issuer unless self-signed
152
	if($issuer <> $subject) {
153
		$issuer_crt =& lookup_ca_by_subject($issuer);
154
		if($issuer_crt)
155
			$ca['caref'] = $issuer_crt['refid'];
156
	}
157

    
158
	/* Correct if child certificate was loaded first */
159
	if (is_array($config['ca']))
160
		foreach ($config['ca'] as & $oca)
161
		{
162
			$issuer = cert_get_issuer($oca['crt']);
163
			if($ca['refid']<>$oca['refid'] && $issuer==$subject)
164
				$oca['caref'] = $ca['refid'];
165
		}
166
	if (is_array($config['cert']))
167
		foreach ($config['cert'] as & $cert)
168
		{
169
			$issuer = cert_get_issuer($cert['crt']);
170
			if($issuer==$subject)
171
				$cert['caref'] = $ca['refid'];
172
		}
173
	return true;
174
}
175

    
176
function ca_create(& $ca, $keylen, $lifetime, $dn, $digest_alg = "sha256") {
177

    
178
	$args = array(
179
		"x509_extensions" => "v3_ca",
180
		"digest_alg" => $digest_alg,
181
		"private_key_bits" => (int)$keylen,
182
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
183
		"encrypt_key" => false);
184

    
185
	// generate a new key pair
186
	$res_key = openssl_pkey_new($args);
187
	if (!$res_key) return false;
188

    
189
	// generate a certificate signing request
190
	$res_csr = openssl_csr_new($dn, $res_key, $args);
191
	if (!$res_csr) return false;
192

    
193
	// self sign the certificate
194
	$res_crt = openssl_csr_sign($res_csr, null, $res_key, $lifetime, $args);
195
	if (!$res_crt) return false;
196

    
197
	// export our certificate data
198
	if (!openssl_pkey_export($res_key, $str_key) ||
199
	    !openssl_x509_export($res_crt, $str_crt))
200
		return false;
201

    
202
	// return our ca information
203
	$ca['crt'] = base64_encode($str_crt);
204
	$ca['prv'] = base64_encode($str_key);
205
	$ca['serial'] = 0;
206

    
207
	return true;
208
}
209

    
210
function ca_inter_create(& $ca, $keylen, $lifetime, $dn, $caref, $digest_alg = "sha256") {
211
	// Create Intermediate Certificate Authority
212
	$signing_ca =& lookup_ca($caref);
213
	if (!$signing_ca)
214
		return false;
215

    
216
	$signing_ca_res_crt = openssl_x509_read(base64_decode($signing_ca['crt']));
217
	$signing_ca_res_key = openssl_pkey_get_private(array(0 => base64_decode($signing_ca['prv']) , 1 => ""));
218
	if (!$signing_ca_res_crt || !$signing_ca_res_key) return false;
219
	$signing_ca_serial = ++$signing_ca['serial'];
220

    
221
	$args = array(
222
		"x509_extensions" => "v3_ca",
223
		"digest_alg" => $digest_alg,
224
		"private_key_bits" => (int)$keylen,
225
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
226
		"encrypt_key" => false);
227

    
228
	// generate a new key pair
229
	$res_key = openssl_pkey_new($args);
230
	if (!$res_key) return false;
231

    
232
	// generate a certificate signing request
233
	$res_csr = openssl_csr_new($dn, $res_key, $args);
234
	if (!$res_csr) return false;
235

    
236
	// Sign the certificate
237
	$res_crt = openssl_csr_sign($res_csr, $signing_ca_res_crt, $signing_ca_res_key, $lifetime, $args, $signing_ca_serial);
238
	if (!$res_crt) return false;
239

    
240
	// export our certificate data
241
	if (!openssl_pkey_export($res_key, $str_key) ||
242
	    !openssl_x509_export($res_crt, $str_crt))
243
		return false;
244

    
245
	// return our ca information
246
	$ca['crt'] = base64_encode($str_crt);
247
	$ca['prv'] = base64_encode($str_key);
248
	$ca['serial'] = 0;
249

    
250
	return true;
251
}
252

    
253
function cert_import(& $cert, $crt_str, $key_str) {
254

    
255
	$cert['crt'] = base64_encode($crt_str);
256
	$cert['prv'] = base64_encode($key_str);
257

    
258
	$subject = cert_get_subject($crt_str, false);
259
	$issuer = cert_get_issuer($crt_str, false);
260
	
261
	// Find my issuer unless self-signed
262
	if($issuer <> $subject) {
263
		$issuer_crt =& lookup_ca_by_subject($issuer);
264
		if($issuer_crt)
265
			$cert['caref'] = $issuer_crt['refid'];
266
	}
267
	return true;
268
}
269

    
270
function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type="user", $digest_alg = "sha256") {
271

    
272
	$cert['type'] = $type;
273

    
274
	if ($type != "self-signed") {
275
		$cert['caref'] = $caref;
276
		$ca =& lookup_ca($caref);
277
		if (!$ca)
278
			return false;
279

    
280
		$ca_str_crt = base64_decode($ca['crt']);
281
		$ca_str_key = base64_decode($ca['prv']);
282
		$ca_res_crt = openssl_x509_read($ca_str_crt);
283
		$ca_res_key = openssl_pkey_get_private(array(0 => $ca_str_key, 1 => ""));
284
		if(!$ca_res_key) return false;
285
		$ca_serial = ++$ca['serial'];
286
	}
287

    
288
	switch ($type) {
289
		case "ca":
290
			$cert_type = "v3_ca";
291
			break;
292
		case "server":
293
		case "self-signed":
294
			$cert_type = "server";
295
			break;
296
		default:
297
			$cert_type = "usr_cert";
298
			break;
299
	}
300

    
301
	// in case of using Subject Alternative Names use other sections (with postfix '_san')
302
	// pass subjectAltName over environment variable 'SAN'
303
	if ($dn['subjectAltName']) {
304
		putenv("SAN={$dn['subjectAltName']}"); // subjectAltName can be set _only_ via configuration file
305
		$cert_type .= '_san';
306
		unset($dn['subjectAltName']);
307
	}
308

    
309
	$args = array(
310
		"x509_extensions" => $cert_type,
311
		"digest_alg" => $digest_alg,
312
		"private_key_bits" => (int)$keylen,
313
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
314
		"encrypt_key" => false);
315

    
316
	// generate a new key pair
317
	$res_key = openssl_pkey_new($args);
318
	if(!$res_key) return false;
319

    
320
	// If this is a self-signed cert, blank out the CA and sign with the cert's key
321
	if ($type == "self-signed") {
322
		$ca           = null;
323
		$ca_res_crt   = null;
324
		$ca_res_key   = $res_key;
325
		$ca_serial    = 0;
326
		$cert['type'] = "server";
327
	}
328

    
329
	// generate a certificate signing request
330
	$res_csr = openssl_csr_new($dn, $res_key, $args);
331
	if(!$res_csr) return false;
332

    
333
	// sign the certificate using an internal CA
334
	$res_crt = openssl_csr_sign($res_csr, $ca_res_crt, $ca_res_key, $lifetime,
335
				 $args, $ca_serial);
336
	if(!$res_crt) return false;
337

    
338
	// export our certificate data
339
	if (!openssl_pkey_export($res_key, $str_key) ||
340
	    !openssl_x509_export($res_crt, $str_crt))
341
		return false;
342

    
343
	// return our certificate information
344
	$cert['crt'] = base64_encode($str_crt);
345
	$cert['prv'] = base64_encode($str_key);
346

    
347
	return true;
348
}
349

    
350
function csr_generate(& $cert, $keylen, $dn, $digest_alg = "sha256") {
351

    
352
	$args = array(
353
		"x509_extensions" => "v3_req",
354
		"digest_alg" => $digest_alg,
355
		"private_key_bits" => (int)$keylen,
356
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
357
		"encrypt_key" => false);
358

    
359
	// generate a new key pair
360
	$res_key = openssl_pkey_new($args);
361
	if(!$res_key) return false;
362

    
363
	// generate a certificate signing request
364
	$res_csr = openssl_csr_new($dn, $res_key, $args);
365
	if(!$res_csr) return false;
366

    
367
	// export our request data
368
	if (!openssl_pkey_export($res_key, $str_key) ||
369
	    !openssl_csr_export($res_csr, $str_csr))
370
		return false;
371

    
372
	// return our request information
373
	$cert['csr'] = base64_encode($str_csr);
374
	$cert['prv'] = base64_encode($str_key);
375

    
376
	return true;
377
}
378

    
379
function csr_complete(& $cert, $str_crt) {
380

    
381
	// return our request information
382
	$cert['crt'] = base64_encode($str_crt);
383
	unset($cert['csr']);
384

    
385
	return true;
386
}
387

    
388
function csr_get_subject($str_crt, $decode = true) {
389

    
390
	if ($decode)
391
		$str_crt = base64_decode($str_crt);
392

    
393
	$components = openssl_csr_get_subject($str_crt);
394

    
395
	if (empty($components) || !is_array($components))
396
		return "unknown";
397

    
398
	ksort($components);
399
	foreach ($components as $a => $v) {
400
		if (!strlen($subject))
401
			$subject = "{$a}={$v}";
402
		else
403
			$subject = "{$a}={$v}, {$subject}";
404
	}
405

    
406
	return $subject;
407
}
408

    
409
function cert_get_subject($str_crt, $decode = true) {
410

    
411
	if ($decode)
412
		$str_crt = base64_decode($str_crt);
413

    
414
	$inf_crt = openssl_x509_parse($str_crt);
415
	$components = $inf_crt['subject'];
416

    
417
	if (empty($components) || !is_array($components))
418
		return "unknown";
419

    
420
	ksort($components);
421
	foreach ($components as $a => $v) {
422
		if (is_array($v)) {
423
			ksort($v);
424
			foreach ($v as $w) {
425
				$asubject = "{$a}={$w}";
426
				$subject = (strlen($subject)) ? "{$asubject}, {$subject}" : $asubject;
427
			}
428
		} else {
429
			$asubject = "{$a}={$v}";
430
			$subject = (strlen($subject)) ? "{$asubject}, {$subject}" : $asubject;
431
		}
432
	}
433

    
434
	return $subject;
435
}
436

    
437
function cert_get_subject_array($crt) {
438
	$str_crt = base64_decode($crt);
439
	$inf_crt = openssl_x509_parse($str_crt);
440
	$components = $inf_crt['subject'];
441

    
442
	if (!is_array($components))
443
		return;
444

    
445
	$subject_array = array();
446

    
447
	foreach($components as $a => $v)
448
		$subject_array[] = array('a' => $a, 'v' => $v);
449

    
450
	return $subject_array;
451
}
452

    
453
function cert_get_subject_hash($crt) {
454
	$str_crt = base64_decode($crt);
455
	$inf_crt = openssl_x509_parse($str_crt);
456
	return $inf_crt['subject'];
457
}
458

    
459
function cert_get_issuer($str_crt, $decode = true) {
460

    
461
	if ($decode)
462
		$str_crt = base64_decode($str_crt);
463

    
464
	$inf_crt = openssl_x509_parse($str_crt);
465
	$components = $inf_crt['issuer'];
466
	
467
	if (empty($components) || !is_array($components))
468
		return "unknown";
469

    
470
	ksort($components);
471
	foreach ($components as $a => $v) {
472
		if (is_array($v)) {
473
			ksort($v);
474
			foreach ($v as $w) {
475
				$aissuer = "{$a}={$w}";
476
				$issuer = (strlen($issuer)) ? "{$aissuer}, {$issuer}" : $aissuer;
477
			}
478
		} else {
479
			$aissuer = "{$a}={$v}";
480
			$issuer = (strlen($issuer)) ? "{$aissuer}, {$issuer}" : $aissuer;
481
		}
482
	}
483

    
484
	return $issuer;
485
}
486

    
487
/* this function works on x509 (crt), rsa key (prv), and req(csr) */
488
function cert_get_modulus($str_crt, $decode = true, $type = "crt"){
489
	if ($decode)
490
		$str_crt = base64_decode($str_crt);
491

    
492
	$modulus = "";
493
	if ( in_array($type, array("crt", "prv", "csr")) ) {
494
			$type = str_replace( array("crt","prv","csr"), array("x509","rsa","req"), $type);
495
			$modulus = exec("echo \"{$str_crt}\" | openssl {$type} -noout -modulus");
496
	}
497
	return $modulus;
498
}
499
function csr_get_modulus($str_crt, $decode = true){
500
	return cert_get_modulus($str_crt, $decode, "csr");
501
}
502

    
503
function cert_get_purpose($str_crt, $decode = true) {
504
	if ($decode)
505
		$str_crt = base64_decode($str_crt);
506
	$crt_details = openssl_x509_parse($str_crt);
507
	$purpose = array();
508
	$purpose['ca'] = (stristr($crt_details['extensions']['basicConstraints'], 'CA:TRUE') === false) ? 'No': 'Yes';
509
	$purpose['server'] = ($crt_details['extensions']['nsCertType'] == "SSL Server") ? 'Yes': 'No';
510
	return $purpose;
511
}
512

    
513
function cert_get_dates($str_crt, $decode = true) {
514
	if ($decode)
515
		$str_crt = base64_decode($str_crt);
516
	$crt_details = openssl_x509_parse($str_crt);
517
	if ($crt_details['validFrom_time_t'] > 0)
518
		$start = date('r', $crt_details['validFrom_time_t']);
519
	if ($crt_details['validTo_time_t'] > 0)
520
		$end = date('r', $crt_details['validTo_time_t']);
521
	return array($start, $end);
522
}
523

    
524
function cert_get_serial($str_crt, $decode = true) {
525
	if ($decode)
526
		$str_crt = base64_decode($str_crt);
527
	$crt_details = openssl_x509_parse($str_crt);
528
	if (isset($crt_details['serialNumber']) && !empty($crt_details['serialNumber']))
529
		return $crt_details['serialNumber'];
530
	else
531
		return NULL;
532
}
533

    
534
function prv_get_modulus($str_crt, $decode = true){
535
	return cert_get_modulus($str_crt, $decode, "prv");
536
}
537

    
538
function is_user_cert($certref) {
539
	global $config;
540
	if (!is_array($config['system']['user']))
541
		return;
542
	foreach ($config['system']['user'] as $user) {
543
		if (!is_array($user['cert']))
544
			continue;
545
		foreach ($user['cert'] as $cert) {
546
			if ($certref == $cert)
547
				return true;
548
		}
549
	}
550
	return false;
551
}
552

    
553
function is_openvpn_server_cert($certref) {
554
	global $config;
555
	if (!is_array($config['openvpn']['openvpn-server']))
556
		return;
557
	foreach ($config['openvpn']['openvpn-server'] as $ovpns) {
558
		if ($ovpns['certref'] == $certref)
559
			return true;
560
	}
561
	return false;
562
}
563

    
564
function is_openvpn_client_cert($certref) {
565
	global $config;
566
	if (!is_array($config['openvpn']['openvpn-client']))
567
		return;
568
	foreach ($config['openvpn']['openvpn-client'] as $ovpnc) {
569
		if ($ovpnc['certref'] == $certref)
570
			return true;
571
	}
572
	return false;
573
}
574

    
575
function is_ipsec_cert($certref) {
576
	global $config;
577
	if (!is_array($config['ipsec']['phase1']))
578
		return;
579
	foreach ($config['ipsec']['phase1'] as $ipsec) {
580
		if ($ipsec['certref'] == $certref)
581
			return true;
582
	}
583
	return false;
584
}
585

    
586
function is_webgui_cert($certref) {
587
	global $config;
588
	if (($config['system']['webgui']['ssl-certref'] == $certref)
589
		&& ($config['system']['webgui']['protocol'] != "http"))
590
		return true;
591
}
592

    
593
function is_captiveportal_cert($certref) {
594
	global $config;
595
	if (!is_array($config['captiveportal']))
596
		return;
597
	foreach ($config['captiveportal'] as $portal) {
598
		if (isset($portal['enable']) && isset($portal['httpslogin']) && ($portal['certref'] == $certref))
599
			return true;
600
	}
601
	return false;
602
}
603

    
604
function cert_in_use($certref) {
605
	return (is_webgui_cert($certref) ||
606
		is_user_cert($certref) ||
607
		is_openvpn_server_cert($certref) ||
608
		is_openvpn_client_cert($certref) ||
609
		is_ipsec_cert($certref) ||
610
		is_captiveportal_cert($certref));
611
}
612

    
613
function crl_create(& $crl, $caref, $name, $serial=0, $lifetime=9999) {
614
	global $config;
615
	$ca =& lookup_ca($caref);
616
	if (!$ca)
617
		return false;
618
	$crl['descr'] = $name;
619
	$crl['caref'] = $caref;
620
	$crl['serial'] = $serial;
621
	$crl['lifetime'] = $lifetime;
622
	$crl['cert'] = array();
623
	$crl_res = crl_update($crl);
624
	$config['crl'][] = $crl;
625
	return $crl_res;
626
}
627

    
628
function crl_update(& $crl) {
629
	global $config;
630
	$ca =& lookup_ca($crl['caref']);
631
	if (!$ca)
632
		return false;
633
	// If we have text but no certs, it was imported and cannot be updated.
634
	if (($crl["method"] != "internal") && (!empty($crl['text']) && empty($crl['cert'])))
635
		return false;
636
	$crl['serial']++;
637
	$ca_str_crt = base64_decode($ca['crt']);
638
	$ca_str_key = base64_decode($ca['prv']);
639
	$crl_res = openssl_crl_new($ca_str_crt, $crl['serial'], $crl['lifetime']);
640
	if (is_array($crl['cert']) && (count($crl['cert']) > 0)) {
641
		foreach ($crl['cert'] as $cert) {
642
			openssl_crl_revoke_cert($crl_res, base64_decode($cert["crt"]), $cert["revoke_time"], $cert["reason"]);
643
		}
644
	}
645
	openssl_crl_export($crl_res, $crl_text, $ca_str_key);
646
	$crl['text'] = base64_encode($crl_text);
647
	return $crl_res;
648
}
649

    
650
function cert_revoke($cert, & $crl, $reason=OCSP_REVOKED_STATUS_UNSPECIFIED) {
651
	global $config;
652
	if (is_cert_revoked($cert, $crl['refid']))
653
		return true;
654
	// If we have text but no certs, it was imported and cannot be updated.
655
	if (!is_crl_internal($crl))
656
		return false;
657
	$cert["reason"] = $reason;
658
	$cert["revoke_time"] = time();
659
	$crl["cert"][] = $cert;
660
	crl_update($crl);
661
	return true;
662
}
663

    
664
function cert_unrevoke($cert, & $crl) {
665
	global $config;
666
	if (!is_crl_internal($crl))
667
		return false;
668
	foreach ($crl['cert'] as $id => $rcert) {
669
		if (($rcert['refid'] == $cert['refid']) || ($rcert['descr'] == $cert['descr'])) {
670
			unset($crl['cert'][$id]);
671
			if (count($crl['cert']) == 0) {
672
				// Protect against accidentally switching the type to imported, for older CRLs
673
				if (!isset($crl['method']))
674
					$crl['method'] = "internal";
675
				crl_update($crl);
676
			} else
677
				crl_update($crl);
678
			return true;
679
		}
680
	}
681
	return false;
682
}
683

    
684
/* Compare two certificates to see if they match. */
685
function cert_compare($cert1, $cert2) {
686
	/* Ensure two certs are identical by first checking that their issuers match, then
687
		subjects, then serial numbers, and finally the moduli. Anything less strict
688
		could accidentally count two similar, but different, certificates as
689
		being identical. */
690
	$c1 = base64_decode($cert1['crt']);
691
	$c2 = base64_decode($cert2['crt']);
692
	if ((cert_get_issuer($c1, false) == cert_get_issuer($c2, false))
693
		&& (cert_get_subject($c1, false) == cert_get_subject($c2, false))
694
		&& (cert_get_serial($c1, false) == cert_get_serial($c2, false))
695
		&& (cert_get_modulus($c1, false) == cert_get_modulus($c2, false)))
696
		return true;
697
	return false;
698
}
699

    
700
function is_cert_revoked($cert, $crlref = "") {
701
	global $config;
702
	if (!is_array($config['crl']))
703
		return false;
704

    
705
	if (!empty($crlref)) {
706
		$crl = lookup_crl($crlref);
707
		if (!is_array($crl['cert']))
708
			return false;
709
		foreach ($crl['cert'] as $rcert) {
710
			if (cert_compare($rcert, $cert))
711
				return true;
712
		}
713
	} else {
714
		foreach ($config['crl'] as $crl) {
715
			if (!is_array($crl['cert']))
716
				continue;
717
			foreach ($crl['cert'] as $rcert) {
718
				if (cert_compare($rcert, $cert))
719
					return true;
720
			}
721
		}
722
	}
723
	return false;
724
}
725

    
726
function is_openvpn_server_crl($crlref) {
727
	global $config;
728
	if (!is_array($config['openvpn']['openvpn-server']))
729
		return;
730
	foreach ($config['openvpn']['openvpn-server'] as $ovpns) {
731
		if (!empty($ovpns['crlref']) && ($ovpns['crlref'] == $crlref))
732
			return true;
733
	}
734
	return false;
735
}
736

    
737
// Keep this general to allow for future expansion. See cert_in_use() above.
738
function crl_in_use($crlref) {
739
	return (is_openvpn_server_crl($crlref));
740
}
741

    
742
function is_crl_internal($crl) {
743
	return (!(!empty($crl['text']) && empty($crl['cert'])) || ($crl["method"] == "internal"));
744
}
745

    
746
function cert_get_cn($crt, $isref = false) {
747
	/* If this is a certref, not an actual cert, look up the cert first */
748
	if ($isref) {
749
		$cert = lookup_cert($crt);
750
		/* If it's not a valid cert, bail. */
751
		if (!(is_array($cert) && !empty($cert['crt'])))
752
			return "";
753
		$cert = $cert['crt'];
754
	} else {
755
		$cert = $crt;
756
	}
757
	$sub = cert_get_subject_array($cert);
758
	if (is_array($sub)) {
759
		foreach ($sub as $s) {
760
			if (strtoupper($s['a']) == "CN")
761
				return $s['v'];
762
		}
763
	}
764
	return "";
765
}
766

    
767
?>
(9-9/68)