Project

General

Profile

Download (27 KB) Statistics
| Branch: | Tag: | Revision:
1 d43ad788 Scott Ullrich
<?php
2
/*
3 ac24dc24 Renato Botelho
 * certs.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6 b8f91b7c Luiz Souza
 * Copyright (c) 2008-2018 Rubicon Communications, LLC (Netgate)
7 ac24dc24 Renato Botelho
 * Copyright (c) 2008 Shrew Soft Inc. All rights reserved.
8
 * All rights reserved.
9
 *
10 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
11
 * you may not use this file except in compliance with the License.
12
 * You may obtain a copy of the License at
13 ac24dc24 Renato Botelho
 *
14 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
15 ac24dc24 Renato Botelho
 *
16 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
17
 * distributed under the License is distributed on an "AS IS" BASIS,
18
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
 * See the License for the specific language governing permissions and
20
 * limitations under the License.
21 ac24dc24 Renato Botelho
 */
22 d43ad788 Scott Ullrich
23 87b4deb2 jim-p
define("OPEN_SSL_CONF_PATH", "/etc/ssl/openssl.cnf");
24
25 d43ad788 Scott Ullrich
require_once("functions.inc");
26
27 e09b941d jim-p
global $openssl_digest_algs;
28 84141846 jim-p
$openssl_digest_algs = array("sha1", "sha224", "sha256", "sha384", "sha512");
29 ca621902 jim-p
30 e09b941d jim-p
global $openssl_crl_status;
31
$openssl_crl_status = array(
32
	OCSP_REVOKED_STATUS_NOSTATUS              => "No Status (default)",
33
	OCSP_REVOKED_STATUS_UNSPECIFIED           => "Unspecified",
34
	OCSP_REVOKED_STATUS_KEYCOMPROMISE         => "Key Compromise",
35
	OCSP_REVOKED_STATUS_CACOMPROMISE          => "CA Compromise",
36
	OCSP_REVOKED_STATUS_AFFILIATIONCHANGED    => "Affiliation Changed",
37
	OCSP_REVOKED_STATUS_SUPERSEDED            => "Superseded",
38
	OCSP_REVOKED_STATUS_CESSATIONOFOPERATION  => "Cessation of Operation",
39
	OCSP_REVOKED_STATUS_CERTIFICATEHOLD       => "Certificate Hold"
40
);
41
42 2e1809dd jim-p
global $cert_altname_types;
43
$cert_altname_types = array(
44
	'DNS' => gettext('FQDN or Hostname'),
45
	'IP' => gettext('IP address'),
46
	'URI' => gettext('URI'),
47
	'email' => gettext('email address'),
48
);
49
50
51 d43ad788 Scott Ullrich
function & lookup_ca($refid) {
52
	global $config;
53
54 1e0b1727 Phil Davis
	if (is_array($config['ca'])) {
55
		foreach ($config['ca'] as & $ca) {
56
			if ($ca['refid'] == $refid) {
57 d43ad788 Scott Ullrich
				return $ca;
58 1e0b1727 Phil Davis
			}
59
		}
60
	}
61 d43ad788 Scott Ullrich
62
	return false;
63
}
64
65
function & lookup_ca_by_subject($subject) {
66
	global $config;
67
68 1e0b1727 Phil Davis
	if (is_array($config['ca'])) {
69
		foreach ($config['ca'] as & $ca) {
70 d43ad788 Scott Ullrich
			$ca_subject = cert_get_subject($ca['crt']);
71 1e0b1727 Phil Davis
			if ($ca_subject == $subject) {
72 d43ad788 Scott Ullrich
				return $ca;
73 1e0b1727 Phil Davis
			}
74 d43ad788 Scott Ullrich
		}
75 1e0b1727 Phil Davis
	}
76 d43ad788 Scott Ullrich
77
	return false;
78
}
79
80
function & lookup_cert($refid) {
81
	global $config;
82
83 1e0b1727 Phil Davis
	if (is_array($config['cert'])) {
84
		foreach ($config['cert'] as & $cert) {
85
			if ($cert['refid'] == $refid) {
86 d43ad788 Scott Ullrich
				return $cert;
87 1e0b1727 Phil Davis
			}
88
		}
89
	}
90 d43ad788 Scott Ullrich
91
	return false;
92
}
93
94 c5f010aa jim-p
function & lookup_cert_by_name($name) {
95
	global $config;
96 1e0b1727 Phil Davis
	if (is_array($config['cert'])) {
97
		foreach ($config['cert'] as & $cert) {
98
			if ($cert['descr'] == $name) {
99 c5f010aa jim-p
				return $cert;
100 1e0b1727 Phil Davis
			}
101
		}
102
	}
103 c5f010aa jim-p
}
104
105
function & lookup_crl($refid) {
106
	global $config;
107
108 1e0b1727 Phil Davis
	if (is_array($config['crl'])) {
109
		foreach ($config['crl'] as & $crl) {
110
			if ($crl['refid'] == $refid) {
111 c5f010aa jim-p
				return $crl;
112 1e0b1727 Phil Davis
			}
113
		}
114
	}
115 c5f010aa jim-p
116
	return false;
117
}
118
119 d43ad788 Scott Ullrich
function ca_chain_array(& $cert) {
120 1e0b1727 Phil Davis
	if ($cert['caref']) {
121 d43ad788 Scott Ullrich
		$chain = array();
122 5289dc57 jim-p
		$crt = lookup_ca($cert['caref']);
123 d43ad788 Scott Ullrich
		$chain[] = $crt;
124
		while ($crt) {
125
			$caref = $crt['caref'];
126 1e0b1727 Phil Davis
			if ($caref) {
127 5289dc57 jim-p
				$crt = lookup_ca($caref);
128 1e0b1727 Phil Davis
			} else {
129 d43ad788 Scott Ullrich
				$crt = false;
130 1e0b1727 Phil Davis
			}
131
			if ($crt) {
132 d43ad788 Scott Ullrich
				$chain[] = $crt;
133 1e0b1727 Phil Davis
			}
134 d43ad788 Scott Ullrich
		}
135
		return $chain;
136
	}
137
	return false;
138
}
139
140
function ca_chain(& $cert) {
141 1e0b1727 Phil Davis
	if ($cert['caref']) {
142 d43ad788 Scott Ullrich
		$ca = "";
143
		$cas = ca_chain_array($cert);
144 1e0b1727 Phil Davis
		if (is_array($cas)) {
145
			foreach ($cas as & $ca_cert) {
146 d43ad788 Scott Ullrich
				$ca .= base64_decode($ca_cert['crt']);
147
				$ca .= "\n";
148
			}
149 1e0b1727 Phil Davis
		}
150 d43ad788 Scott Ullrich
		return $ca;
151
	}
152
	return "";
153
}
154
155 ab63443a jim-p
function ca_import(& $ca, $str, $key = "", $serial = "") {
156 d43ad788 Scott Ullrich
	global $config;
157
158
	$ca['crt'] = base64_encode($str);
159 1e0b1727 Phil Davis
	if (!empty($key)) {
160 ecefc738 jim-p
		$ca['prv'] = base64_encode($key);
161 1e0b1727 Phil Davis
	}
162 ab63443a jim-p
	if (empty($serial)) {
163
		$ca['serial'] = 0;
164
	} else {
165 bfa992bc jim-p
		$ca['serial'] = $serial;
166 1e0b1727 Phil Davis
	}
167 d43ad788 Scott Ullrich
	$subject = cert_get_subject($str, false);
168
	$issuer = cert_get_issuer($str, false);
169 1e0b1727 Phil Davis
170 d43ad788 Scott Ullrich
	// Find my issuer unless self-signed
171 1e0b1727 Phil Davis
	if ($issuer <> $subject) {
172 d43ad788 Scott Ullrich
		$issuer_crt =& lookup_ca_by_subject($issuer);
173 1e0b1727 Phil Davis
		if ($issuer_crt) {
174 d43ad788 Scott Ullrich
			$ca['caref'] = $issuer_crt['refid'];
175 1e0b1727 Phil Davis
		}
176 d43ad788 Scott Ullrich
	}
177
178
	/* Correct if child certificate was loaded first */
179 1e0b1727 Phil Davis
	if (is_array($config['ca'])) {
180
		foreach ($config['ca'] as & $oca) {
181 d43ad788 Scott Ullrich
			$issuer = cert_get_issuer($oca['crt']);
182 086cf944 Phil Davis
			if ($ca['refid'] <> $oca['refid'] && $issuer == $subject) {
183 d43ad788 Scott Ullrich
				$oca['caref'] = $ca['refid'];
184 1e0b1727 Phil Davis
			}
185 d43ad788 Scott Ullrich
		}
186 1e0b1727 Phil Davis
	}
187
	if (is_array($config['cert'])) {
188
		foreach ($config['cert'] as & $cert) {
189 d43ad788 Scott Ullrich
			$issuer = cert_get_issuer($cert['crt']);
190 086cf944 Phil Davis
			if ($issuer == $subject) {
191 d43ad788 Scott Ullrich
				$cert['caref'] = $ca['refid'];
192 1e0b1727 Phil Davis
			}
193 d43ad788 Scott Ullrich
		}
194 1e0b1727 Phil Davis
	}
195 d43ad788 Scott Ullrich
	return true;
196
}
197
198 ca621902 jim-p
function ca_create(& $ca, $keylen, $lifetime, $dn, $digest_alg = "sha256") {
199 d43ad788 Scott Ullrich
200
	$args = array(
201 87b4deb2 jim-p
		"x509_extensions" => "v3_ca",
202 ca621902 jim-p
		"digest_alg" => $digest_alg,
203 51dbdcde Ermal Lu?i
		"private_key_bits" => (int)$keylen,
204 d43ad788 Scott Ullrich
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
205
		"encrypt_key" => false);
206
207
	// generate a new key pair
208 838e27bf jim-p
	$res_key = openssl_pkey_new($args);
209 1e0b1727 Phil Davis
	if (!$res_key) {
210
		return false;
211
	}
212 d43ad788 Scott Ullrich
213
	// generate a certificate signing request
214
	$res_csr = openssl_csr_new($dn, $res_key, $args);
215 1e0b1727 Phil Davis
	if (!$res_csr) {
216
		return false;
217
	}
218 d43ad788 Scott Ullrich
219
	// self sign the certificate
220
	$res_crt = openssl_csr_sign($res_csr, null, $res_key, $lifetime, $args);
221 1e0b1727 Phil Davis
	if (!$res_crt) {
222
		return false;
223
	}
224 d43ad788 Scott Ullrich
225
	// export our certificate data
226 1b6d9fa5 Evgeny Yurchenko
	if (!openssl_pkey_export($res_key, $str_key) ||
227 ae52d165 Renato Botelho
	    !openssl_x509_export($res_crt, $str_crt)) {
228 1b6d9fa5 Evgeny Yurchenko
		return false;
229 1e0b1727 Phil Davis
	}
230 d43ad788 Scott Ullrich
231
	// return our ca information
232
	$ca['crt'] = base64_encode($str_crt);
233
	$ca['prv'] = base64_encode($str_key);
234
	$ca['serial'] = 0;
235
236
	return true;
237
}
238
239 ca621902 jim-p
function ca_inter_create(& $ca, $keylen, $lifetime, $dn, $caref, $digest_alg = "sha256") {
240 95c8cf48 Evgeny Yurchenko
	// Create Intermediate Certificate Authority
241
	$signing_ca =& lookup_ca($caref);
242 1e0b1727 Phil Davis
	if (!$signing_ca) {
243 95c8cf48 Evgeny Yurchenko
		return false;
244 1e0b1727 Phil Davis
	}
245 95c8cf48 Evgeny Yurchenko
246
	$signing_ca_res_crt = openssl_x509_read(base64_decode($signing_ca['crt']));
247
	$signing_ca_res_key = openssl_pkey_get_private(array(0 => base64_decode($signing_ca['prv']) , 1 => ""));
248 1e0b1727 Phil Davis
	if (!$signing_ca_res_crt || !$signing_ca_res_key) {
249
		return false;
250
	}
251 95c8cf48 Evgeny Yurchenko
	$signing_ca_serial = ++$signing_ca['serial'];
252
253
	$args = array(
254 87b4deb2 jim-p
		"x509_extensions" => "v3_ca",
255 ca621902 jim-p
		"digest_alg" => $digest_alg,
256 95c8cf48 Evgeny Yurchenko
		"private_key_bits" => (int)$keylen,
257
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
258
		"encrypt_key" => false);
259
260
	// generate a new key pair
261
	$res_key = openssl_pkey_new($args);
262 1e0b1727 Phil Davis
	if (!$res_key) {
263
		return false;
264
	}
265 95c8cf48 Evgeny Yurchenko
266
	// generate a certificate signing request
267
	$res_csr = openssl_csr_new($dn, $res_key, $args);
268 1e0b1727 Phil Davis
	if (!$res_csr) {
269
		return false;
270
	}
271 95c8cf48 Evgeny Yurchenko
272
	// Sign the certificate
273
	$res_crt = openssl_csr_sign($res_csr, $signing_ca_res_crt, $signing_ca_res_key, $lifetime, $args, $signing_ca_serial);
274 1e0b1727 Phil Davis
	if (!$res_crt) {
275
		return false;
276
	}
277 95c8cf48 Evgeny Yurchenko
278
	// export our certificate data
279
	if (!openssl_pkey_export($res_key, $str_key) ||
280 ae52d165 Renato Botelho
	    !openssl_x509_export($res_crt, $str_crt)) {
281 95c8cf48 Evgeny Yurchenko
		return false;
282 1e0b1727 Phil Davis
	}
283 95c8cf48 Evgeny Yurchenko
284
	// return our ca information
285
	$ca['crt'] = base64_encode($str_crt);
286
	$ca['prv'] = base64_encode($str_key);
287
	$ca['serial'] = 0;
288 dd76084d Matt Smith
	$ca['caref'] = $caref;
289 95c8cf48 Evgeny Yurchenko
290
	return true;
291
}
292
293 d43ad788 Scott Ullrich
function cert_import(& $cert, $crt_str, $key_str) {
294
295
	$cert['crt'] = base64_encode($crt_str);
296
	$cert['prv'] = base64_encode($key_str);
297
298
	$subject = cert_get_subject($crt_str, false);
299
	$issuer = cert_get_issuer($crt_str, false);
300 1e0b1727 Phil Davis
301 d43ad788 Scott Ullrich
	// Find my issuer unless self-signed
302 1e0b1727 Phil Davis
	if ($issuer <> $subject) {
303 d43ad788 Scott Ullrich
		$issuer_crt =& lookup_ca_by_subject($issuer);
304 1e0b1727 Phil Davis
		if ($issuer_crt) {
305 d43ad788 Scott Ullrich
			$cert['caref'] = $issuer_crt['refid'];
306 1e0b1727 Phil Davis
		}
307 d43ad788 Scott Ullrich
	}
308
	return true;
309
}
310
311 6c07db48 Phil Davis
function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type = "user", $digest_alg = "sha256") {
312 d43ad788 Scott Ullrich
313 7c4c77ee jim-p
	$cert['type'] = $type;
314 d43ad788 Scott Ullrich
315 7c4c77ee jim-p
	if ($type != "self-signed") {
316
		$cert['caref'] = $caref;
317
		$ca =& lookup_ca($caref);
318 1e0b1727 Phil Davis
		if (!$ca) {
319 7c4c77ee jim-p
			return false;
320 1e0b1727 Phil Davis
		}
321 7c4c77ee jim-p
322
		$ca_str_crt = base64_decode($ca['crt']);
323
		$ca_str_key = base64_decode($ca['prv']);
324
		$ca_res_crt = openssl_x509_read($ca_str_crt);
325
		$ca_res_key = openssl_pkey_get_private(array(0 => $ca_str_key, 1 => ""));
326 1e0b1727 Phil Davis
		if (!$ca_res_key) {
327
			return false;
328
		}
329 ab63443a jim-p
		if (empty($ca['serial'])) {
330
			$ca['serial'] = 0;
331
		}
332 7c4c77ee jim-p
		$ca_serial = ++$ca['serial'];
333
	}
334 d43ad788 Scott Ullrich
335 0c82b8c2 jim-p
	$cert_type = cert_type_config_section($type);
336 7aaabd69 jim-p
337 3cb773da yarick123
	// in case of using Subject Alternative Names use other sections (with postfix '_san')
338
	// pass subjectAltName over environment variable 'SAN'
339
	if ($dn['subjectAltName']) {
340
		putenv("SAN={$dn['subjectAltName']}"); // subjectAltName can be set _only_ via configuration file
341
		$cert_type .= '_san';
342
		unset($dn['subjectAltName']);
343
	}
344
345 d43ad788 Scott Ullrich
	$args = array(
346 7aaabd69 jim-p
		"x509_extensions" => $cert_type,
347 ca621902 jim-p
		"digest_alg" => $digest_alg,
348 51dbdcde Ermal Lu?i
		"private_key_bits" => (int)$keylen,
349 d43ad788 Scott Ullrich
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
350
		"encrypt_key" => false);
351
352
	// generate a new key pair
353 838e27bf jim-p
	$res_key = openssl_pkey_new($args);
354 1e0b1727 Phil Davis
	if (!$res_key) {
355
		return false;
356
	}
357 d43ad788 Scott Ullrich
358 7c4c77ee jim-p
	// If this is a self-signed cert, blank out the CA and sign with the cert's key
359
	if ($type == "self-signed") {
360
		$ca           = null;
361
		$ca_res_crt   = null;
362
		$ca_res_key   = $res_key;
363
		$ca_serial    = 0;
364
		$cert['type'] = "server";
365
	}
366
367 d43ad788 Scott Ullrich
	// generate a certificate signing request
368
	$res_csr = openssl_csr_new($dn, $res_key, $args);
369 1e0b1727 Phil Davis
	if (!$res_csr) {
370
		return false;
371
	}
372 d43ad788 Scott Ullrich
373 7c4c77ee jim-p
	// sign the certificate using an internal CA
374 d43ad788 Scott Ullrich
	$res_crt = openssl_csr_sign($res_csr, $ca_res_crt, $ca_res_key, $lifetime,
375
				 $args, $ca_serial);
376 1e0b1727 Phil Davis
	if (!$res_crt) {
377
		return false;
378
	}
379 d43ad788 Scott Ullrich
380
	// export our certificate data
381 22b380aa Evgeny Yurchenko
	if (!openssl_pkey_export($res_key, $str_key) ||
382 ae52d165 Renato Botelho
	    !openssl_x509_export($res_crt, $str_crt)) {
383 22b380aa Evgeny Yurchenko
		return false;
384 1e0b1727 Phil Davis
	}
385 d43ad788 Scott Ullrich
386
	// return our certificate information
387
	$cert['crt'] = base64_encode($str_crt);
388
	$cert['prv'] = base64_encode($str_key);
389
390
	return true;
391
}
392
393 282b6c66 jim-p
function csr_generate(& $cert, $keylen, $dn, $type = "user", $digest_alg = "sha256") {
394
395 0c82b8c2 jim-p
	$cert_type = cert_type_config_section($type);
396 282b6c66 jim-p
397
	// in case of using Subject Alternative Names use other sections (with postfix '_san')
398
	// pass subjectAltName over environment variable 'SAN'
399
	if ($dn['subjectAltName']) {
400
		putenv("SAN={$dn['subjectAltName']}"); // subjectAltName can be set _only_ via configuration file
401
		$cert_type .= '_san';
402
		unset($dn['subjectAltName']);
403
	}
404 d43ad788 Scott Ullrich
405
	$args = array(
406 282b6c66 jim-p
		"x509_extensions" => $cert_type,
407
		"req_extensions" => "req_{$cert_type}",
408 ca621902 jim-p
		"digest_alg" => $digest_alg,
409 3198b8d3 Ermal Lu?i
		"private_key_bits" => (int)$keylen,
410 d43ad788 Scott Ullrich
		"private_key_type" => OPENSSL_KEYTYPE_RSA,
411
		"encrypt_key" => false);
412
413
	// generate a new key pair
414 838e27bf jim-p
	$res_key = openssl_pkey_new($args);
415 1e0b1727 Phil Davis
	if (!$res_key) {
416
		return false;
417
	}
418 d43ad788 Scott Ullrich
419
	// generate a certificate signing request
420
	$res_csr = openssl_csr_new($dn, $res_key, $args);
421 1e0b1727 Phil Davis
	if (!$res_csr) {
422
		return false;
423
	}
424 d43ad788 Scott Ullrich
425
	// export our request data
426 22b380aa Evgeny Yurchenko
	if (!openssl_pkey_export($res_key, $str_key) ||
427 ae52d165 Renato Botelho
	    !openssl_csr_export($res_csr, $str_csr)) {
428 22b380aa Evgeny Yurchenko
		return false;
429 1e0b1727 Phil Davis
	}
430 d43ad788 Scott Ullrich
431
	// return our request information
432
	$cert['csr'] = base64_encode($str_csr);
433
	$cert['prv'] = base64_encode($str_key);
434
435
	return true;
436
}
437
438 aec3a259 jim-p
function csr_sign($csr, & $ca, $duration, $type = "user", $altnames, $digest_alg = "sha256") {
439 0c82b8c2 jim-p
	global $config;
440
	$old_err_level = error_reporting(0);
441
442
	// Gather the information required for signed cert
443
	$ca_str_crt = base64_decode($ca['crt']);
444
	$ca_str_key = base64_decode($ca['prv']);
445
	$ca_res_key = openssl_pkey_get_private(array(0 => $ca_str_key, 1 => ""));
446
	if (!$ca_res_key) {
447
		return false;
448
	}
449
	if (empty($ca['serial'])) {
450
		$ca['serial'] = 0;
451
	}
452
	$ca_serial = ++$ca['serial'];
453
454
	$cert_type = cert_type_config_section($type);
455
456
	if (!empty($altnames)) {
457
		putenv("SAN={$altnames}"); // subjectAltName can be set _only_ via configuration file
458
		$cert_type .= '_san';
459
	}
460
461
	$args = array(
462
		"x509_extensions" => $cert_type,
463 aec3a259 jim-p
		"digest_alg" => $digest_alg,
464 0c82b8c2 jim-p
		"req_extensions" => "req_{$cert_type}"
465
	);
466
467
	// Sign the new cert and export it in x509 format
468
	openssl_x509_export(openssl_csr_sign($csr, $ca_str_crt, $ca_str_key, $duration, $args, $ca_serial), $n509);
469
	error_reporting($old_err_level);
470
471
	return $n509;
472
}
473
474 d43ad788 Scott Ullrich
function csr_complete(& $cert, $str_crt) {
475 7fd7fbcf PiBa-NL
	$str_key = base64_decode($cert['prv']);
476
	cert_import($cert, $str_crt, $str_key);
477 d43ad788 Scott Ullrich
	unset($cert['csr']);
478
	return true;
479
}
480
481
function csr_get_subject($str_crt, $decode = true) {
482
483 1e0b1727 Phil Davis
	if ($decode) {
484 d43ad788 Scott Ullrich
		$str_crt = base64_decode($str_crt);
485 1e0b1727 Phil Davis
	}
486 d43ad788 Scott Ullrich
487
	$components = openssl_csr_get_subject($str_crt);
488
489 1e0b1727 Phil Davis
	if (empty($components) || !is_array($components)) {
490 d43ad788 Scott Ullrich
		return "unknown";
491 1e0b1727 Phil Davis
	}
492 d43ad788 Scott Ullrich
493 311f93cd Ermal
	ksort($components);
494 d43ad788 Scott Ullrich
	foreach ($components as $a => $v) {
495 1e0b1727 Phil Davis
		if (!strlen($subject)) {
496 d43ad788 Scott Ullrich
			$subject = "{$a}={$v}";
497 1e0b1727 Phil Davis
		} else {
498 d43ad788 Scott Ullrich
			$subject = "{$a}={$v}, {$subject}";
499 1e0b1727 Phil Davis
		}
500 d43ad788 Scott Ullrich
	}
501
502
	return $subject;
503
}
504
505
function cert_get_subject($str_crt, $decode = true) {
506
507 1e0b1727 Phil Davis
	if ($decode) {
508 d43ad788 Scott Ullrich
		$str_crt = base64_decode($str_crt);
509 1e0b1727 Phil Davis
	}
510 d43ad788 Scott Ullrich
511
	$inf_crt = openssl_x509_parse($str_crt);
512
	$components = $inf_crt['subject'];
513
514 1e0b1727 Phil Davis
	if (empty($components) || !is_array($components)) {
515 d43ad788 Scott Ullrich
		return "unknown";
516 1e0b1727 Phil Davis
	}
517 d43ad788 Scott Ullrich
518 b89c34aa Ermal
	ksort($components);
519 d43ad788 Scott Ullrich
	foreach ($components as $a => $v) {
520 b89c34aa Ermal
		if (is_array($v)) {
521
			ksort($v);
522 5479df47 jim-p
			foreach ($v as $w) {
523
				$asubject = "{$a}={$w}";
524
				$subject = (strlen($subject)) ? "{$asubject}, {$subject}" : $asubject;
525
			}
526 b89c34aa Ermal
		} else {
527 5479df47 jim-p
			$asubject = "{$a}={$v}";
528
			$subject = (strlen($subject)) ? "{$asubject}, {$subject}" : $asubject;
529
		}
530 d43ad788 Scott Ullrich
	}
531
532
	return $subject;
533
}
534
535
function cert_get_subject_array($crt) {
536
	$str_crt = base64_decode($crt);
537
	$inf_crt = openssl_x509_parse($str_crt);
538
	$components = $inf_crt['subject'];
539 e4d7a064 jim-p
540 1e0b1727 Phil Davis
	if (!is_array($components)) {
541 e4d7a064 jim-p
		return;
542 1e0b1727 Phil Davis
	}
543 e4d7a064 jim-p
544 d43ad788 Scott Ullrich
	$subject_array = array();
545
546 1e0b1727 Phil Davis
	foreach ($components as $a => $v) {
547 d43ad788 Scott Ullrich
		$subject_array[] = array('a' => $a, 'v' => $v);
548 1e0b1727 Phil Davis
	}
549 d43ad788 Scott Ullrich
550
	return $subject_array;
551
}
552
553 a84eb838 jim-p
function cert_get_subject_hash($crt) {
554
	$str_crt = base64_decode($crt);
555
	$inf_crt = openssl_x509_parse($str_crt);
556
	return $inf_crt['subject'];
557
}
558
559 4906f4ee jim-p
function cert_get_sans($str_crt, $decode = true) {
560
	if ($decode) {
561
		$str_crt = base64_decode($str_crt);
562
	}
563
	$sans = array();
564
	$crt_details = openssl_x509_parse($str_crt);
565
	if (!empty($crt_details['extensions']['subjectAltName'])) {
566
		$sans = explode(',', $crt_details['extensions']['subjectAltName']);
567
	}
568
	return $sans;
569
}
570
571 d43ad788 Scott Ullrich
function cert_get_issuer($str_crt, $decode = true) {
572
573 1e0b1727 Phil Davis
	if ($decode) {
574 d43ad788 Scott Ullrich
		$str_crt = base64_decode($str_crt);
575 1e0b1727 Phil Davis
	}
576 d43ad788 Scott Ullrich
577
	$inf_crt = openssl_x509_parse($str_crt);
578
	$components = $inf_crt['issuer'];
579 1e0b1727 Phil Davis
580
	if (empty($components) || !is_array($components)) {
581 d43ad788 Scott Ullrich
		return "unknown";
582 1e0b1727 Phil Davis
	}
583 5ca13f69 Ermal
584
	ksort($components);
585 d43ad788 Scott Ullrich
	foreach ($components as $a => $v) {
586 2a08b814 vsquared56
		if (is_array($v)) {
587
			ksort($v);
588
			foreach ($v as $w) {
589
				$aissuer = "{$a}={$w}";
590
				$issuer = (strlen($issuer)) ? "{$aissuer}, {$issuer}" : $aissuer;
591
			}
592
		} else {
593
			$aissuer = "{$a}={$v}";
594
			$issuer = (strlen($issuer)) ? "{$aissuer}, {$issuer}" : $aissuer;
595
		}
596 d43ad788 Scott Ullrich
	}
597
598
	return $issuer;
599
}
600
601 1746c5ce PiBa-NL
/* Works for both RSA and ECC (crt) and key (prv) */
602
function cert_get_publickey($str_crt, $decode = true, $type = "crt") {
603 1e0b1727 Phil Davis
	if ($decode) {
604 9038f44c Steve Beaver
		$str_crt = base64_decode($str_crt);
605 1e0b1727 Phil Davis
	}
606 b6dcbd64 jim-p
	$certfn = tempnam('/tmp', 'CGPK');
607
	file_put_contents($certfn, $str_crt);
608 6d6ba660 PiBa-NL
	switch ($type) {
609
		case 'prv':
610 b6dcbd64 jim-p
			exec("/usr/bin/openssl pkey -in {$certfn} -pubout", $out);
611 6d6ba660 PiBa-NL
			break;
612
		case 'crt':
613 b6dcbd64 jim-p
			exec("/usr/bin/openssl x509 -in {$certfn} -inform pem -noout -pubkey", $out);
614 6d6ba660 PiBa-NL
			break;
615
		case 'csr':
616 b6dcbd64 jim-p
			exec("/usr/bin/openssl req -in {$certfn} -inform pem -noout -pubkey", $out);
617 6d6ba660 PiBa-NL
			break;
618
		default:
619
			$out = array();
620
			break;
621 1746c5ce PiBa-NL
	}
622 b6dcbd64 jim-p
	unlink($certfn);
623 6d6ba660 PiBa-NL
	return implode("\n", $out);
624 a828210b yakatz
}
625 1379d66f jim-p
626
function cert_get_purpose($str_crt, $decode = true) {
627 4906f4ee jim-p
	$extended_oids = array(
628
		"1.3.6.1.5.5.8.2.2" => "IP Security IKE Intermediate",
629
	);
630 1e0b1727 Phil Davis
	if ($decode) {
631 1379d66f jim-p
		$str_crt = base64_decode($str_crt);
632 1e0b1727 Phil Davis
	}
633 1379d66f jim-p
	$crt_details = openssl_x509_parse($str_crt);
634
	$purpose = array();
635 4906f4ee jim-p
	if (!empty($crt_details['extensions']['keyUsage'])) {
636
		$purpose['ku'] = explode(',', $crt_details['extensions']['keyUsage']);
637
		foreach ($purpose['ku'] as & $ku) {
638
			$ku = trim($ku);
639
			if (array_key_exists($ku, $extended_oids)) {
640
				$ku = $extended_oids[$ku];
641
			}
642
		}
643
	} else {
644
		$purpose['ku'] = array();
645
	}
646
	if (!empty($crt_details['extensions']['extendedKeyUsage'])) {
647
		$purpose['eku'] = explode(',', $crt_details['extensions']['extendedKeyUsage']);
648
		foreach ($purpose['eku'] as & $eku) {
649
			$eku = trim($eku);
650
			if (array_key_exists($eku, $extended_oids)) {
651
				$eku = $extended_oids[$eku];
652
			}
653
		}
654
	} else {
655
		$purpose['eku'] = array();
656
	}
657 1379d66f jim-p
	$purpose['ca'] = (stristr($crt_details['extensions']['basicConstraints'], 'CA:TRUE') === false) ? 'No': 'Yes';
658 4906f4ee jim-p
	$purpose['server'] = (in_array('TLS Web Server Authentication', $purpose['eku'])) ? 'Yes': 'No';
659
660 1379d66f jim-p
	return $purpose;
661
}
662
663 2b333210 jim-p
function cert_get_dates($str_crt, $decode = true) {
664 1e0b1727 Phil Davis
	if ($decode) {
665 2b333210 jim-p
		$str_crt = base64_decode($str_crt);
666 1e0b1727 Phil Davis
	}
667 2b333210 jim-p
	$crt_details = openssl_x509_parse($str_crt);
668 1e0b1727 Phil Davis
	if ($crt_details['validFrom_time_t'] > 0) {
669 2b333210 jim-p
		$start = date('r', $crt_details['validFrom_time_t']);
670 1e0b1727 Phil Davis
	}
671
	if ($crt_details['validTo_time_t'] > 0) {
672 2b333210 jim-p
		$end = date('r', $crt_details['validTo_time_t']);
673 1e0b1727 Phil Davis
	}
674 2b333210 jim-p
	return array($start, $end);
675
}
676
677 04761344 jim-p
function cert_get_serial($str_crt, $decode = true) {
678 1e0b1727 Phil Davis
	if ($decode) {
679 04761344 jim-p
		$str_crt = base64_decode($str_crt);
680 1e0b1727 Phil Davis
	}
681 04761344 jim-p
	$crt_details = openssl_x509_parse($str_crt);
682 1e0b1727 Phil Davis
	if (isset($crt_details['serialNumber']) && !empty($crt_details['serialNumber'])) {
683 04761344 jim-p
		return $crt_details['serialNumber'];
684 1e0b1727 Phil Davis
	} else {
685 04761344 jim-p
		return NULL;
686 1e0b1727 Phil Davis
	}
687 04761344 jim-p
}
688
689 aec3a259 jim-p
function cert_get_sigtype($str_crt, $decode = true) {
690
	if ($decode) {
691
		$str_crt = base64_decode($str_crt);
692
	}
693
	$crt_details = openssl_x509_parse($str_crt);
694
695
	$signature = array();
696
	if (isset($crt_details['signatureTypeSN']) && !empty($crt_details['signatureTypeSN'])) {
697
		$signature['shortname'] = $crt_details['signatureTypeSN'];
698
	}
699
	if (isset($crt_details['signatureTypeLN']) && !empty($crt_details['signatureTypeLN'])) {
700
		$signature['longname'] = $crt_details['signatureTypeLN'];
701
	}
702
	if (isset($crt_details['signatureTypeNID']) && !empty($crt_details['signatureTypeNID'])) {
703
		$signature['nid'] = $crt_details['signatureTypeNID'];
704
	}
705
706
	return $signature;
707
}
708
709 e2c718c8 jim-p
function is_openvpn_server_ca($caref) {
710
	global $config;
711
	if (!is_array($config['openvpn']['openvpn-server'])) {
712
		return;
713
	}
714
	foreach ($config['openvpn']['openvpn-server'] as $ovpns) {
715
		if ($ovpns['caref'] == $caref) {
716
			return true;
717
		}
718
	}
719
	return false;
720
}
721
722
function is_openvpn_client_ca($caref) {
723
	global $config;
724
	if (!is_array($config['openvpn']['openvpn-client'])) {
725
		return;
726
	}
727
	foreach ($config['openvpn']['openvpn-client'] as $ovpnc) {
728
		if ($ovpnc['caref'] == $caref) {
729
			return true;
730
		}
731
	}
732
	return false;
733
}
734
735
function is_ipsec_peer_ca($caref) {
736
	global $config;
737
	if (!is_array($config['ipsec']['phase1'])) {
738
		return;
739
	}
740
	foreach ($config['ipsec']['phase1'] as $ipsec) {
741
		if ($ipsec['caref'] == $caref) {
742
			return true;
743
		}
744
	}
745
	return false;
746
}
747
748
function is_ldap_peer_ca($caref) {
749
	global $config;
750
	if (!is_array($config['system']['authserver'])) {
751
		return;
752
	}
753
	foreach ($config['system']['authserver'] as $authserver) {
754
		if ($authserver['ldap_caref'] == $caref) {
755
			return true;
756
		}
757
	}
758
	return false;
759
}
760
761
function ca_in_use($caref) {
762
	return (is_openvpn_server_ca($caref) ||
763
		is_openvpn_client_ca($caref) ||
764
		is_ipsec_peer_ca($caref) ||
765
		is_ldap_peer_ca($caref));
766
}
767
768 dea98903 jim-p
function is_user_cert($certref) {
769 dab2e769 jim-p
	global $config;
770 1e0b1727 Phil Davis
	if (!is_array($config['system']['user'])) {
771 dab2e769 jim-p
		return;
772 1e0b1727 Phil Davis
	}
773 dab2e769 jim-p
	foreach ($config['system']['user'] as $user) {
774 1e0b1727 Phil Davis
		if (!is_array($user['cert'])) {
775 dab2e769 jim-p
			continue;
776 1e0b1727 Phil Davis
		}
777 dab2e769 jim-p
		foreach ($user['cert'] as $cert) {
778 1e0b1727 Phil Davis
			if ($certref == $cert) {
779 dea98903 jim-p
				return true;
780 1e0b1727 Phil Davis
			}
781 dab2e769 jim-p
		}
782
	}
783 dea98903 jim-p
	return false;
784 dab2e769 jim-p
}
785
786 dea98903 jim-p
function is_openvpn_server_cert($certref) {
787 dab2e769 jim-p
	global $config;
788 1e0b1727 Phil Davis
	if (!is_array($config['openvpn']['openvpn-server'])) {
789 dea98903 jim-p
		return;
790 1e0b1727 Phil Davis
	}
791 dea98903 jim-p
	foreach ($config['openvpn']['openvpn-server'] as $ovpns) {
792 1e0b1727 Phil Davis
		if ($ovpns['certref'] == $certref) {
793 dea98903 jim-p
			return true;
794 1e0b1727 Phil Davis
		}
795 dea98903 jim-p
	}
796
	return false;
797
}
798
799
function is_openvpn_client_cert($certref) {
800
	global $config;
801 1e0b1727 Phil Davis
	if (!is_array($config['openvpn']['openvpn-client'])) {
802 dea98903 jim-p
		return;
803 1e0b1727 Phil Davis
	}
804 dea98903 jim-p
	foreach ($config['openvpn']['openvpn-client'] as $ovpnc) {
805 1e0b1727 Phil Davis
		if ($ovpnc['certref'] == $certref) {
806 dea98903 jim-p
			return true;
807 1e0b1727 Phil Davis
		}
808 dea98903 jim-p
	}
809
	return false;
810
}
811
812
function is_ipsec_cert($certref) {
813
	global $config;
814 1e0b1727 Phil Davis
	if (!is_array($config['ipsec']['phase1'])) {
815 dea98903 jim-p
		return;
816 1e0b1727 Phil Davis
	}
817 dea98903 jim-p
	foreach ($config['ipsec']['phase1'] as $ipsec) {
818 1e0b1727 Phil Davis
		if ($ipsec['certref'] == $certref) {
819 dea98903 jim-p
			return true;
820 1e0b1727 Phil Davis
		}
821 dea98903 jim-p
	}
822
	return false;
823
}
824
825
function is_webgui_cert($certref) {
826
	global $config;
827 ae52d165 Renato Botelho
	if (($config['system']['webgui']['ssl-certref'] == $certref) &&
828
	    ($config['system']['webgui']['protocol'] != "http")) {
829 dea98903 jim-p
		return true;
830 1e0b1727 Phil Davis
	}
831 dea98903 jim-p
}
832
833 29e6a815 Renato Botelho
function is_package_cert($certref) {
834
	$pluginparams = array();
835
	$pluginparams['type'] = 'certificates';
836
	$pluginparams['event'] = 'used_certificates';
837
838
	$certificates_used_by_packages = pkg_call_plugins('plugin_certificates', $pluginparams);
839
840
	/* Check if any package is using certificate */
841
	foreach ($certificates_used_by_packages as $name => $package) {
842
		if (is_array($package['certificatelist'][$certref]) &&
843
		    isset($package['certificatelist'][$certref]) > 0) {
844
			return true;
845
		}
846
	}
847
}
848
849 36f6ed35 bcyrill
function is_captiveportal_cert($certref) {
850
	global $config;
851 1e0b1727 Phil Davis
	if (!is_array($config['captiveportal'])) {
852 36f6ed35 bcyrill
		return;
853 1e0b1727 Phil Davis
	}
854 36f6ed35 bcyrill
	foreach ($config['captiveportal'] as $portal) {
855 1e0b1727 Phil Davis
		if (isset($portal['enable']) && isset($portal['httpslogin']) && ($portal['certref'] == $certref)) {
856 36f6ed35 bcyrill
			return true;
857 1e0b1727 Phil Davis
		}
858 36f6ed35 bcyrill
	}
859
	return false;
860
}
861
862 dea98903 jim-p
function cert_in_use($certref) {
863 29e6a815 Renato Botelho
864 dea98903 jim-p
	return (is_webgui_cert($certref) ||
865
		is_user_cert($certref) ||
866
		is_openvpn_server_cert($certref) ||
867
		is_openvpn_client_cert($certref) ||
868 36f6ed35 bcyrill
		is_ipsec_cert($certref) ||
869 29e6a815 Renato Botelho
		is_captiveportal_cert($certref) ||
870
		is_package_cert($certref));
871 dab2e769 jim-p
}
872
873 3bde5cdd PiBa-NL
function cert_usedby_description($refid, $certificates_used_by_packages) {
874
	$result = "";
875
	if (is_array($certificates_used_by_packages)) {
876
		foreach ($certificates_used_by_packages as $name => $package) {
877
			if (isset($package['certificatelist'][$refid])) {
878
				$hint = "" ;
879
				if (is_array($package['certificatelist'][$refid])) {
880
					foreach ($package['certificatelist'][$refid] as $cert_used) {
881
						$hint = $hint . $cert_used['usedby']."\n";
882
					}
883
				}
884
				$count = count($package['certificatelist'][$refid]);
885
				$result .= "<div title='".htmlspecialchars($hint)."'>";
886
				$result .= htmlspecialchars($package['pkgname'])." ($count)<br />";
887
				$result .= "</div>";
888
			}
889
		}
890
	}
891
	return $result;
892
}
893
894 6c07db48 Phil Davis
function crl_create(& $crl, $caref, $name, $serial = 0, $lifetime = 9999) {
895 c5f010aa jim-p
	global $config;
896
	$ca =& lookup_ca($caref);
897 1e0b1727 Phil Davis
	if (!$ca) {
898 c5f010aa jim-p
		return false;
899 1e0b1727 Phil Davis
	}
900 f2a86ca9 jim-p
	$crl['descr'] = $name;
901 c5f010aa jim-p
	$crl['caref'] = $caref;
902
	$crl['serial'] = $serial;
903
	$crl['lifetime'] = $lifetime;
904
	$crl['cert'] = array();
905
	$crl_res = crl_update($crl);
906
	$config['crl'][] = $crl;
907
	return $crl_res;
908
}
909
910
function crl_update(& $crl) {
911
	global $config;
912
	$ca =& lookup_ca($crl['caref']);
913 1e0b1727 Phil Davis
	if (!$ca) {
914 c5f010aa jim-p
		return false;
915 1e0b1727 Phil Davis
	}
916 7b757d1b jim-p
	// If we have text but no certs, it was imported and cannot be updated.
917 1e0b1727 Phil Davis
	if (($crl["method"] != "internal") && (!empty($crl['text']) && empty($crl['cert']))) {
918 7b757d1b jim-p
		return false;
919 1e0b1727 Phil Davis
	}
920 c5f010aa jim-p
	$crl['serial']++;
921
	$ca_str_crt = base64_decode($ca['crt']);
922
	$ca_str_key = base64_decode($ca['prv']);
923
	$crl_res = openssl_crl_new($ca_str_crt, $crl['serial'], $crl['lifetime']);
924 4bc2c676 jim-p
	if (is_array($crl['cert']) && (count($crl['cert']) > 0)) {
925
		foreach ($crl['cert'] as $cert) {
926
			openssl_crl_revoke_cert($crl_res, base64_decode($cert["crt"]), $cert["revoke_time"], $cert["reason"]);
927
		}
928 c5f010aa jim-p
	}
929
	openssl_crl_export($crl_res, $crl_text, $ca_str_key);
930
	$crl['text'] = base64_encode($crl_text);
931
	return $crl_res;
932
}
933
934 6c07db48 Phil Davis
function cert_revoke($cert, & $crl, $reason = OCSP_REVOKED_STATUS_UNSPECIFIED) {
935 c5f010aa jim-p
	global $config;
936 1e0b1727 Phil Davis
	if (is_cert_revoked($cert, $crl['refid'])) {
937 c5f010aa jim-p
		return true;
938 1e0b1727 Phil Davis
	}
939 7b757d1b jim-p
	// If we have text but no certs, it was imported and cannot be updated.
940 1e0b1727 Phil Davis
	if (!is_crl_internal($crl)) {
941 7b757d1b jim-p
		return false;
942 1e0b1727 Phil Davis
	}
943 c5f010aa jim-p
	$cert["reason"] = $reason;
944
	$cert["revoke_time"] = time();
945
	$crl["cert"][] = $cert;
946
	crl_update($crl);
947 fb3f1993 jim-p
	return true;
948 c5f010aa jim-p
}
949
950
function cert_unrevoke($cert, & $crl) {
951
	global $config;
952 1e0b1727 Phil Davis
	if (!is_crl_internal($crl)) {
953 7b757d1b jim-p
		return false;
954 1e0b1727 Phil Davis
	}
955 c5f010aa jim-p
	foreach ($crl['cert'] as $id => $rcert) {
956 f2a86ca9 jim-p
		if (($rcert['refid'] == $cert['refid']) || ($rcert['descr'] == $cert['descr'])) {
957 c5f010aa jim-p
			unset($crl['cert'][$id]);
958 728003c8 jim-p
			if (count($crl['cert']) == 0) {
959
				// Protect against accidentally switching the type to imported, for older CRLs
960 1e0b1727 Phil Davis
				if (!isset($crl['method'])) {
961 728003c8 jim-p
					$crl['method'] = "internal";
962 1e0b1727 Phil Davis
				}
963 728003c8 jim-p
				crl_update($crl);
964 1e0b1727 Phil Davis
			} else {
965 a59831e7 jim-p
				crl_update($crl);
966 1e0b1727 Phil Davis
			}
967 c5f010aa jim-p
			return true;
968
		}
969
	}
970
	return false;
971
}
972
973 04761344 jim-p
/* Compare two certificates to see if they match. */
974
function cert_compare($cert1, $cert2) {
975
	/* Ensure two certs are identical by first checking that their issuers match, then
976
		subjects, then serial numbers, and finally the moduli. Anything less strict
977
		could accidentally count two similar, but different, certificates as
978
		being identical. */
979
	$c1 = base64_decode($cert1['crt']);
980
	$c2 = base64_decode($cert2['crt']);
981 ae52d165 Renato Botelho
	if ((cert_get_issuer($c1, false) == cert_get_issuer($c2, false)) &&
982
	    (cert_get_subject($c1, false) == cert_get_subject($c2, false)) &&
983
	    (cert_get_serial($c1, false) == cert_get_serial($c2, false)) &&
984 1746c5ce PiBa-NL
	    (cert_get_publickey($c1, false) == cert_get_publickey($c2, false))) {
985 04761344 jim-p
		return true;
986 1e0b1727 Phil Davis
	}
987 04761344 jim-p
	return false;
988
}
989
990 fb3f1993 jim-p
function is_cert_revoked($cert, $crlref = "") {
991 c5f010aa jim-p
	global $config;
992 1e0b1727 Phil Davis
	if (!is_array($config['crl'])) {
993 c5f010aa jim-p
		return false;
994 1e0b1727 Phil Davis
	}
995 c5f010aa jim-p
996 fb3f1993 jim-p
	if (!empty($crlref)) {
997 28ff7ace jim-p
		$crl = lookup_crl($crlref);
998 1e0b1727 Phil Davis
		if (!is_array($crl['cert'])) {
999 fb3f1993 jim-p
			return false;
1000 1e0b1727 Phil Davis
		}
1001 088ce869 jim-p
		foreach ($crl['cert'] as $rcert) {
1002 1e0b1727 Phil Davis
			if (cert_compare($rcert, $cert)) {
1003 c5f010aa jim-p
				return true;
1004 1e0b1727 Phil Davis
			}
1005 c5f010aa jim-p
		}
1006 fb3f1993 jim-p
	} else {
1007
		foreach ($config['crl'] as $crl) {
1008 1e0b1727 Phil Davis
			if (!is_array($crl['cert'])) {
1009 fb3f1993 jim-p
				continue;
1010 1e0b1727 Phil Davis
			}
1011 fb3f1993 jim-p
			foreach ($crl['cert'] as $rcert) {
1012 1e0b1727 Phil Davis
				if (cert_compare($rcert, $cert)) {
1013 fb3f1993 jim-p
					return true;
1014 1e0b1727 Phil Davis
				}
1015 fb3f1993 jim-p
			}
1016
		}
1017
	}
1018
	return false;
1019
}
1020
1021
function is_openvpn_server_crl($crlref) {
1022
	global $config;
1023 1e0b1727 Phil Davis
	if (!is_array($config['openvpn']['openvpn-server'])) {
1024 fb3f1993 jim-p
		return;
1025 1e0b1727 Phil Davis
	}
1026 fb3f1993 jim-p
	foreach ($config['openvpn']['openvpn-server'] as $ovpns) {
1027 1e0b1727 Phil Davis
		if (!empty($ovpns['crlref']) && ($ovpns['crlref'] == $crlref)) {
1028 fb3f1993 jim-p
			return true;
1029 1e0b1727 Phil Davis
		}
1030 c5f010aa jim-p
	}
1031
	return false;
1032
}
1033
1034 fb3f1993 jim-p
// Keep this general to allow for future expansion. See cert_in_use() above.
1035
function crl_in_use($crlref) {
1036
	return (is_openvpn_server_crl($crlref));
1037
}
1038
1039
function is_crl_internal($crl) {
1040 728003c8 jim-p
	return (!(!empty($crl['text']) && empty($crl['cert'])) || ($crl["method"] == "internal"));
1041 fb3f1993 jim-p
}
1042
1043 b34b2b7d jim-p
function cert_get_cn($crt, $isref = false) {
1044
	/* If this is a certref, not an actual cert, look up the cert first */
1045
	if ($isref) {
1046
		$cert = lookup_cert($crt);
1047
		/* If it's not a valid cert, bail. */
1048 1e0b1727 Phil Davis
		if (!(is_array($cert) && !empty($cert['crt']))) {
1049 b34b2b7d jim-p
			return "";
1050 1e0b1727 Phil Davis
		}
1051 b34b2b7d jim-p
		$cert = $cert['crt'];
1052
	} else {
1053
		$cert = $crt;
1054
	}
1055
	$sub = cert_get_subject_array($cert);
1056
	if (is_array($sub)) {
1057
		foreach ($sub as $s) {
1058 1e0b1727 Phil Davis
			if (strtoupper($s['a']) == "CN") {
1059 b34b2b7d jim-p
				return $s['v'];
1060 1e0b1727 Phil Davis
			}
1061 b34b2b7d jim-p
		}
1062
	}
1063
	return "";
1064
}
1065
1066 83d2b83a jim-p
function cert_escape_x509_chars($str, $reverse = false) {
1067
	/* Characters which need escaped when present in x.509 fields.
1068
	 * See https://www.ietf.org/rfc/rfc4514.txt
1069
	 *
1070
	 * The backslash (\) must be listed first in these arrays!
1071
	 */
1072
	$cert_directory_string_special_chars = array('\\', '"', '#', '+', ',', ';', '<', '=', '>');
1073
	$cert_directory_string_special_chars_esc = array('\\\\', '\"', '\#', '\+', '\,', '\;', '\<', '\=', '\>');
1074
	if ($reverse) {
1075
		return str_replace($cert_directory_string_special_chars_esc, $cert_directory_string_special_chars, $str);
1076
	} else {
1077
		/* First unescape and then escape again, to prevent possible double escaping. */
1078
		return str_replace($cert_directory_string_special_chars, $cert_directory_string_special_chars_esc, cert_escape_x509_chars($str, true));
1079
	}
1080
}
1081
1082 2e1809dd jim-p
function cert_add_altname_type($str) {
1083
	$type = "";
1084
	if (is_ipaddr($str)) {
1085
		$type = "IP";
1086 70b70f9d jim-p
	} elseif (is_hostname($str, true)) {
1087 2e1809dd jim-p
		$type = "DNS";
1088
	} elseif (is_URL($str)) {
1089
		$type = "URI";
1090
	} elseif (filter_var($str, FILTER_VALIDATE_EMAIL)) {
1091
		$type = "email";
1092
	}
1093
	if (!empty($type)) {
1094
		return "{$type}:" . cert_escape_x509_chars($str);
1095
	} else {
1096 e562fca2 jim-p
		return null;
1097 2e1809dd jim-p
	}
1098
}
1099
1100 0c82b8c2 jim-p
function cert_type_config_section($type) {
1101
	switch ($type) {
1102
		case "ca":
1103
			$cert_type = "v3_ca";
1104
			break;
1105
		case "server":
1106
		case "self-signed":
1107
			$cert_type = "server";
1108
			break;
1109
		default:
1110
			$cert_type = "usr_cert";
1111
			break;
1112
	}
1113
	return $cert_type;
1114
}
1115
1116 b89c34aa Ermal
?>