From b9b6e3eb8dbe4e498f65be3992791104c3f4291a Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Sun, 1 Aug 2021 11:36:01 +0200 Subject: [PATCH] System / Trust - split between generic server use in cert_get_purpose() and id-kp-serverAuth according to rfc3280, for https://github.com/opnsense/core/issues/5128 --- src/etc/inc/certs.inc | 27 +++++++++++++------- src/etc/inc/plugins.inc.d/openvpn/wizard.inc | 2 +- src/www/vpn_openvpn_server.php | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc index b6cd87c1e..92e5f547d 100644 --- a/src/etc/inc/certs.inc +++ b/src/etc/inc/certs.inc @@ -440,18 +440,27 @@ function cert_get_purpose($str_crt, $decode = true) $crt_details = openssl_x509_parse($str_crt); $purpose = array(); - $purpose['ca'] = (stristr($crt_details['extensions']['basicConstraints'], 'CA:TRUE') === false) ? 'No' : 'Yes'; + foreach (['basicConstraints', 'extendedKeyUsage', 'keyUsage'] as $ext) { + $purpose[$ext] = []; + if (!empty($crt_details['extensions'][$ext])) { + foreach (explode(",", $crt_details['extensions'][$ext]) as $item) { + $purpose[$ext][] = trim($item); + } + } + } + $purpose['ca'] = in_array('CA:TRUE', $purpose['basicConstraints']) ? 'Yes' : 'No'; + $purpose['server'] = in_array('TLS Web Server Authentication', $purpose['extendedKeyUsage']) ? 'Yes' : 'No'; + // rfc3280 extended key usage if ( - isset($crt_details['extensions']['extendedKeyUsage']) && - strstr($crt_details['extensions']['extendedKeyUsage'], 'TLS Web Server Authentication') !== false && - isset($crt_details['extensions']['keyUsage']) && - strpos($crt_details['extensions']['keyUsage'], 'Digital Signature') !== false && - (strpos($crt_details['extensions']['keyUsage'], 'Key Encipherment') !== false || - strpos($crt_details['extensions']['keyUsage'], 'Key Agreement') !== false) + in_array('TLS Web Server Authentication', $purpose['extendedKeyUsage']) && + in_array('Digital Signature', $purpose['keyUsage']) && ( + in_array('Key Encipherment', $purpose['keyUsage']) || + in_array('Key Agreement', $purpose['keyUsage']) + ) ) { - $purpose['server'] = 'Yes'; + $purpose['id-kp-serverAuth'] = 'Yes'; } else { - $purpose['server'] = 'No'; + $purpose['id-kp-serverAuth'] = 'No'; } return $purpose; } diff --git a/src/etc/inc/plugins.inc.d/openvpn/wizard.inc b/src/etc/inc/plugins.inc.d/openvpn/wizard.inc index 2ebe7b405..e19411280 100644 --- a/src/etc/inc/plugins.inc.d/openvpn/wizard.inc +++ b/src/etc/inc/plugins.inc.d/openvpn/wizard.inc @@ -276,7 +276,7 @@ function step8_stepbeforeformdisplay() $stepid++; } else { foreach ($config['cert'] as $cert) { - if (cert_get_purpose($cert['crt'])['server'] == 'Yes') { + if (cert_get_purpose($cert['crt'])['id-kp-serverAuth'] == 'Yes') { $no_server_cert = false; break; } diff --git a/src/www/vpn_openvpn_server.php b/src/www/vpn_openvpn_server.php index 7f088c2ff..23ecce647 100644 --- a/src/www/vpn_openvpn_server.php +++ b/src/www/vpn_openvpn_server.php @@ -337,7 +337,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { if (!empty($pconfig['certref'])) { foreach ($config['cert'] as $cert) { if ($cert['refid'] == $pconfig['certref']) { - if (cert_get_purpose($cert['crt'])['server'] == 'No') { + if (cert_get_purpose($cert['crt'])['id-kp-serverAuth'] == 'No') { $input_errors[] = gettext( sprintf('Certificate %s is not intended for server use.', $cert['descr']) );