Projet

Général

Profil

Télécharger (19,8 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / certs.inc @ 3cb773da

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

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

    
35
require_once("functions.inc");
36

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

    
40
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
function & lookup_ca($refid) {
53
	global $config;
54

    
55
	if (is_array($config['ca']))
56
		foreach ($config['ca'] as & $ca)
57
			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
	if (is_array($config['ca']))
67
		foreach ($config['ca'] as & $ca)
68
		{
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
	if (is_array($config['cert']))
81
		foreach ($config['cert'] as & $cert)
82
			if ($cert['refid'] == $refid)
83
				return $cert;
84

    
85
	return false;
86
}
87

    
88
function & lookup_cert_by_name($name) {
89
	global $config;
90
	if (is_array($config['cert']))
91
		foreach ($config['cert'] as & $cert)
92
			if ($cert['descr'] == $name)
93
				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
function ca_chain_array(& $cert) {
108
	if($cert['caref']) {
109
		$chain = array();
110
		$crt = lookup_ca($cert['caref']);
111
		$chain[] = $crt;
112
		while ($crt) {
113
			$caref = $crt['caref'];
114
			if($caref)
115
				$crt = lookup_ca($caref);
116
			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
function ca_import(& $ca, $str, $key="", $serial=0) {
142
	global $config;
143

    
144
	$ca['crt'] = base64_encode($str);
145
	if (!empty($key))
146
		$ca['prv'] = base64_encode($key);
147
	if (!empty($serial))
148
		$ca['serial'] = $serial;
149
	$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
	if (is_array($config['ca']))
161
		foreach ($config['ca'] as & $oca)
162
		{
163
			$issuer = cert_get_issuer($oca['crt']);
164
			if($ca['refid']<>$oca['refid'] && $issuer==$subject)
165
				$oca['caref'] = $ca['refid'];
166
		}
167
	if (is_array($config['cert']))
168
		foreach ($config['cert'] as & $cert)
169
		{
170
			$issuer = cert_get_issuer($cert['crt']);
171
			if($issuer==$subject)
172
				$cert['caref'] = $ca['refid'];
173
		}
174
	return true;
175
}
176

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

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

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

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

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

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

    
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
function ca_inter_create(& $ca, $keylen, $lifetime, $dn, $caref, $digest_alg = "sha256") {
212
	// 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
		"x509_extensions" => "v3_ca",
224
		"digest_alg" => $digest_alg,
225
		"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
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
function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type="user", $digest_alg = "sha256") {
272

    
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
	$ca_res_key = openssl_pkey_get_private(array(0 => $ca_str_key, 1 => ""));
281
	if(!$ca_res_key) return false;
282
	$ca_serial = ++$ca['serial'];
283

    
284
	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
	// in case of using Subject Alternative Names use other sections (with postfix '_san')
297
	// pass subjectAltName over environment variable 'SAN'
298
	if ($dn['subjectAltName']) {
299
		putenv("SAN={$dn['subjectAltName']}"); // subjectAltName can be set _only_ via configuration file
300
		$cert_type .= '_san';
301
		unset($dn['subjectAltName']);
302
	}
303

    
304
	$args = array(
305
		"x509_extensions" => $cert_type,
306
		"digest_alg" => $digest_alg,
307
		"private_key_bits" => (int)$keylen,
308
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
309
		"encrypt_key" => false);
310

    
311
	// generate a new key pair
312
	$res_key = openssl_pkey_new($args);
313
	if(!$res_key) return false;
314

    
315
	// generate a certificate signing request
316
	$res_csr = openssl_csr_new($dn, $res_key, $args);
317
	if(!$res_csr) return false;
318

    
319
	// self sign the certificate
320
	$res_crt = openssl_csr_sign($res_csr, $ca_res_crt, $ca_res_key, $lifetime,
321
				 $args, $ca_serial);
322
	if(!$res_crt) return false;
323

    
324
	// export our certificate data
325
	if (!openssl_pkey_export($res_key, $str_key) ||
326
	    !openssl_x509_export($res_crt, $str_crt))
327
		return false;
328

    
329
	// return our certificate information
330
	$cert['caref'] = $caref;
331
	$cert['crt'] = base64_encode($str_crt);
332
	$cert['prv'] = base64_encode($str_key);
333
	$cert['type'] = $type;
334

    
335
	return true;
336
}
337

    
338
function csr_generate(& $cert, $keylen, $dn, $digest_alg = "sha256") {
339

    
340
	$args = array(
341
		"x509_extensions" => "v3_req",
342
		"digest_alg" => $digest_alg,
343
		"private_key_bits" => (int)$keylen,
344
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
345
		"encrypt_key" => false);
346

    
347
	// generate a new key pair
348
	$res_key = openssl_pkey_new($args);
349
	if(!$res_key) return false;
350

    
351
	// generate a certificate signing request
352
	$res_csr = openssl_csr_new($dn, $res_key, $args);
353
	if(!$res_csr) return false;
354

    
355
	// export our request data
356
	if (!openssl_pkey_export($res_key, $str_key) ||
357
	    !openssl_csr_export($res_csr, $str_csr))
358
		return false;
359

    
360
	// return our request information
361
	$cert['csr'] = base64_encode($str_csr);
362
	$cert['prv'] = base64_encode($str_key);
363

    
364
	return true;
365
}
366

    
367
function csr_complete(& $cert, $str_crt) {
368

    
369
	// return our request information
370
	$cert['crt'] = base64_encode($str_crt);
371
	unset($cert['csr']);
372

    
373
	return true;
374
}
375

    
376
function csr_get_subject($str_crt, $decode = true) {
377

    
378
	if ($decode)
379
		$str_crt = base64_decode($str_crt);
380

    
381
	$components = openssl_csr_get_subject($str_crt);
382

    
383
	if (empty($components) || !is_array($components))
384
		return "unknown";
385

    
386
	ksort($components);
387
	foreach ($components as $a => $v) {
388
		if (!strlen($subject))
389
			$subject = "{$a}={$v}";
390
		else
391
			$subject = "{$a}={$v}, {$subject}";
392
	}
393

    
394
	return $subject;
395
}
396

    
397
function cert_get_subject($str_crt, $decode = true) {
398

    
399
	if ($decode)
400
		$str_crt = base64_decode($str_crt);
401

    
402
	$inf_crt = openssl_x509_parse($str_crt);
403
	$components = $inf_crt['subject'];
404

    
405
	if (empty($components) || !is_array($components))
406
		return "unknown";
407

    
408
	ksort($components);
409
	foreach ($components as $a => $v) {
410
		if (is_array($v)) {
411
			ksort($v);
412
			foreach ($v as $w) {
413
				$asubject = "{$a}={$w}";
414
				$subject = (strlen($subject)) ? "{$asubject}, {$subject}" : $asubject;
415
			}
416
		} else {
417
			$asubject = "{$a}={$v}";
418
			$subject = (strlen($subject)) ? "{$asubject}, {$subject}" : $asubject;
419
		}
420
	}
421

    
422
	return $subject;
423
}
424

    
425
function cert_get_subject_array($crt) {
426
	$str_crt = base64_decode($crt);
427
	$inf_crt = openssl_x509_parse($str_crt);
428
	$components = $inf_crt['subject'];
429

    
430
	if (!is_array($components))
431
		return;
432

    
433
	$subject_array = array();
434

    
435
	foreach($components as $a => $v)
436
		$subject_array[] = array('a' => $a, 'v' => $v);
437

    
438
	return $subject_array;
439
}
440

    
441
function cert_get_subject_hash($crt) {
442
	$str_crt = base64_decode($crt);
443
	$inf_crt = openssl_x509_parse($str_crt);
444
	return $inf_crt['subject'];
445
}
446

    
447
function cert_get_issuer($str_crt, $decode = true) {
448

    
449
	if ($decode)
450
		$str_crt = base64_decode($str_crt);
451

    
452
	$inf_crt = openssl_x509_parse($str_crt);
453
	$components = $inf_crt['issuer'];
454
	
455
	if (empty($components) || !is_array($components))
456
		return "unknown";
457

    
458
	ksort($components);
459
	foreach ($components as $a => $v) {
460
		if (is_array($v)) {
461
			ksort($v);
462
			foreach ($v as $w) {
463
				$aissuer = "{$a}={$w}";
464
				$issuer = (strlen($issuer)) ? "{$aissuer}, {$issuer}" : $aissuer;
465
			}
466
		} else {
467
			$aissuer = "{$a}={$v}";
468
			$issuer = (strlen($issuer)) ? "{$aissuer}, {$issuer}" : $aissuer;
469
		}
470
	}
471

    
472
	return $issuer;
473
}
474

    
475
/* this function works on x509 (crt), rsa key (prv), and req(csr) */
476
function cert_get_modulus($str_crt, $decode = true, $type = "crt"){
477
	if ($decode)
478
		$str_crt = base64_decode($str_crt);
479

    
480
	$modulus = "";
481
	if ( in_array($type, array("crt", "prv", "csr")) ) {
482
			$type = str_replace( array("crt","prv","csr"), array("x509","rsa","req"), $type);
483
			$modulus = exec("echo \"{$str_crt}\" | openssl {$type} -noout -modulus");
484
	}
485
	return $modulus;
486
}
487
function csr_get_modulus($str_crt, $decode = true){
488
	return cert_get_modulus($str_crt, $decode, "csr");
489
}
490

    
491
function cert_get_purpose($str_crt, $decode = true) {
492
	if ($decode)
493
		$str_crt = base64_decode($str_crt);
494
	$crt_details = openssl_x509_parse($str_crt);
495
	$purpose = array();
496
	$purpose['ca'] = (stristr($crt_details['extensions']['basicConstraints'], 'CA:TRUE') === false) ? 'No': 'Yes';
497
	$purpose['server'] = ($crt_details['extensions']['nsCertType'] == "SSL Server") ? 'Yes': 'No';
498
	return $purpose;
499
}
500

    
501
function cert_get_dates($str_crt, $decode = true) {
502
	if ($decode)
503
		$str_crt = base64_decode($str_crt);
504
	$crt_details = openssl_x509_parse($str_crt);
505
	if ($crt_details['validFrom_time_t'] > 0)
506
		$start = date('r', $crt_details['validFrom_time_t']);
507
	if ($crt_details['validTo_time_t'] > 0)
508
		$end = date('r', $crt_details['validTo_time_t']);
509
	return array($start, $end);
510
}
511

    
512
function cert_get_serial($str_crt, $decode = true) {
513
	if ($decode)
514
		$str_crt = base64_decode($str_crt);
515
	$crt_details = openssl_x509_parse($str_crt);
516
	if (isset($crt_details['serialNumber']) && !empty($crt_details['serialNumber']))
517
		return $crt_details['serialNumber'];
518
	else
519
		return NULL;
520
}
521

    
522
function prv_get_modulus($str_crt, $decode = true){
523
	return cert_get_modulus($str_crt, $decode, "prv");
524
}
525

    
526
function is_user_cert($certref) {
527
	global $config;
528
	if (!is_array($config['system']['user']))
529
		return;
530
	foreach ($config['system']['user'] as $user) {
531
		if (!is_array($user['cert']))
532
			continue;
533
		foreach ($user['cert'] as $cert) {
534
			if ($certref == $cert)
535
				return true;
536
		}
537
	}
538
	return false;
539
}
540

    
541
function is_openvpn_server_cert($certref) {
542
	global $config;
543
	if (!is_array($config['openvpn']['openvpn-server']))
544
		return;
545
	foreach ($config['openvpn']['openvpn-server'] as $ovpns) {
546
		if ($ovpns['certref'] == $certref)
547
			return true;
548
	}
549
	return false;
550
}
551

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

    
563
function is_ipsec_cert($certref) {
564
	global $config;
565
	if (!is_array($config['ipsec']['phase1']))
566
		return;
567
	foreach ($config['ipsec']['phase1'] as $ipsec) {
568
		if ($ipsec['certref'] == $certref)
569
			return true;
570
	}
571
	return false;
572
}
573

    
574
function is_webgui_cert($certref) {
575
	global $config;
576
	if (($config['system']['webgui']['ssl-certref'] == $certref)
577
		&& ($config['system']['webgui']['protocol'] != "http"))
578
		return true;
579
}
580

    
581
function is_captiveportal_cert($certref) {
582
	global $config;
583
	if (!is_array($config['captiveportal']))
584
		return;
585
	foreach ($config['captiveportal'] as $portal) {
586
		if (isset($portal['enable']) && isset($portal['httpslogin']) && ($portal['certref'] == $certref))
587
			return true;
588
	}
589
	return false;
590
}
591

    
592
function cert_in_use($certref) {
593
	return (is_webgui_cert($certref) ||
594
		is_user_cert($certref) ||
595
		is_openvpn_server_cert($certref) ||
596
		is_openvpn_client_cert($certref) ||
597
		is_ipsec_cert($certref) ||
598
		is_captiveportal_cert($certref));
599
}
600

    
601
function crl_create(& $crl, $caref, $name, $serial=0, $lifetime=9999) {
602
	global $config;
603
	$ca =& lookup_ca($caref);
604
	if (!$ca)
605
		return false;
606
	$crl['descr'] = $name;
607
	$crl['caref'] = $caref;
608
	$crl['serial'] = $serial;
609
	$crl['lifetime'] = $lifetime;
610
	$crl['cert'] = array();
611
	$crl_res = crl_update($crl);
612
	$config['crl'][] = $crl;
613
	return $crl_res;
614
}
615

    
616
function crl_update(& $crl) {
617
	global $config;
618
	$ca =& lookup_ca($crl['caref']);
619
	if (!$ca)
620
		return false;
621
	// If we have text but no certs, it was imported and cannot be updated.
622
	if (($crl["method"] != "internal") && (!empty($crl['text']) && empty($crl['cert'])))
623
		return false;
624
	$crl['serial']++;
625
	$ca_str_crt = base64_decode($ca['crt']);
626
	$ca_str_key = base64_decode($ca['prv']);
627
	$crl_res = openssl_crl_new($ca_str_crt, $crl['serial'], $crl['lifetime']);
628
	if (is_array($crl['cert']) && (count($crl['cert']) > 0)) {
629
		foreach ($crl['cert'] as $cert) {
630
			openssl_crl_revoke_cert($crl_res, base64_decode($cert["crt"]), $cert["revoke_time"], $cert["reason"]);
631
		}
632
	}
633
	openssl_crl_export($crl_res, $crl_text, $ca_str_key);
634
	$crl['text'] = base64_encode($crl_text);
635
	return $crl_res;
636
}
637

    
638
function cert_revoke($cert, & $crl, $reason=OCSP_REVOKED_STATUS_UNSPECIFIED) {
639
	global $config;
640
	if (is_cert_revoked($cert, $crl['refid']))
641
		return true;
642
	// If we have text but no certs, it was imported and cannot be updated.
643
	if (!is_crl_internal($crl))
644
		return false;
645
	$cert["reason"] = $reason;
646
	$cert["revoke_time"] = time();
647
	$crl["cert"][] = $cert;
648
	crl_update($crl);
649
	return true;
650
}
651

    
652
function cert_unrevoke($cert, & $crl) {
653
	global $config;
654
	if (!is_crl_internal($crl))
655
		return false;
656
	foreach ($crl['cert'] as $id => $rcert) {
657
		if (($rcert['refid'] == $cert['refid']) || ($rcert['descr'] == $cert['descr'])) {
658
			unset($crl['cert'][$id]);
659
			if (count($crl['cert']) == 0) {
660
				// Protect against accidentally switching the type to imported, for older CRLs
661
				if (!isset($crl['method']))
662
					$crl['method'] = "internal";
663
				crl_update($crl);
664
			} else
665
				crl_update($crl);
666
			return true;
667
		}
668
	}
669
	return false;
670
}
671

    
672
/* Compare two certificates to see if they match. */
673
function cert_compare($cert1, $cert2) {
674
	/* Ensure two certs are identical by first checking that their issuers match, then
675
		subjects, then serial numbers, and finally the moduli. Anything less strict
676
		could accidentally count two similar, but different, certificates as
677
		being identical. */
678
	$c1 = base64_decode($cert1['crt']);
679
	$c2 = base64_decode($cert2['crt']);
680
	if ((cert_get_issuer($c1, false) == cert_get_issuer($c2, false))
681
		&& (cert_get_subject($c1, false) == cert_get_subject($c2, false))
682
		&& (cert_get_serial($c1, false) == cert_get_serial($c2, false))
683
		&& (cert_get_modulus($c1, false) == cert_get_modulus($c2, false)))
684
		return true;
685
	return false;
686
}
687

    
688
function is_cert_revoked($cert, $crlref = "") {
689
	global $config;
690
	if (!is_array($config['crl']))
691
		return false;
692

    
693
	if (!empty($crlref)) {
694
		$crl = lookup_crl($crlref);
695
		if (!is_array($crl['cert']))
696
			return false;
697
		foreach ($crl['cert'] as $rcert) {
698
			if (cert_compare($rcert, $cert))
699
				return true;
700
		}
701
	} else {
702
		foreach ($config['crl'] as $crl) {
703
			if (!is_array($crl['cert']))
704
				continue;
705
			foreach ($crl['cert'] as $rcert) {
706
				if (cert_compare($rcert, $cert))
707
					return true;
708
			}
709
		}
710
	}
711
	return false;
712
}
713

    
714
function is_openvpn_server_crl($crlref) {
715
	global $config;
716
	if (!is_array($config['openvpn']['openvpn-server']))
717
		return;
718
	foreach ($config['openvpn']['openvpn-server'] as $ovpns) {
719
		if (!empty($ovpns['crlref']) && ($ovpns['crlref'] == $crlref))
720
			return true;
721
	}
722
	return false;
723
}
724

    
725
// Keep this general to allow for future expansion. See cert_in_use() above.
726
function crl_in_use($crlref) {
727
	return (is_openvpn_server_crl($crlref));
728
}
729

    
730
function is_crl_internal($crl) {
731
	return (!(!empty($crl['text']) && empty($crl['cert'])) || ($crl["method"] == "internal"));
732
}
733

    
734
function cert_get_cn($crt, $isref = false) {
735
	/* If this is a certref, not an actual cert, look up the cert first */
736
	if ($isref) {
737
		$cert = lookup_cert($crt);
738
		/* If it's not a valid cert, bail. */
739
		if (!(is_array($cert) && !empty($cert['crt'])))
740
			return "";
741
		$cert = $cert['crt'];
742
	} else {
743
		$cert = $crt;
744
	}
745
	$sub = cert_get_subject_array($cert);
746
	if (is_array($sub)) {
747
		foreach ($sub as $s) {
748
			if (strtoupper($s['a']) == "CN")
749
				return $s['v'];
750
		}
751
	}
752
	return "";
753
}
754

    
755
?>
(9-9/68)