From a78a9cf35509326c66e2b1879f98ce3bed0336cd Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Wed, 17 May 2023 14:33:08 +0200 Subject: [PATCH] MVC/Trust - add wrapper around trust module for reusable functions. --- .../mvc/app/library/OPNsense/Trust/Store.php | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 src/opnsense/mvc/app/library/OPNsense/Trust/Store.php diff --git a/src/opnsense/mvc/app/library/OPNsense/Trust/Store.php b/src/opnsense/mvc/app/library/OPNsense/Trust/Store.php new file mode 100644 index 000000000..081e0414f --- /dev/null +++ b/src/opnsense/mvc/app/library/OPNsense/Trust/Store.php @@ -0,0 +1,129 @@ +object()->ca)) { + foreach (Config::getInstance()->object()->ca as $cert) { + if (isset($cert->refid) && (string)$caref == $cert->refid) { + return $cert; + } + } + } + return null; + } + + /** + * @param string $text certificate text + * @return certificate with single unix line endings + */ + private static function cleanCert($text) + { + $response = []; + foreach (explode("\n", str_replace("\r", "", $text)) as $item) { + if (!empty($item)) { + $response[] = $item; + } + } + return implode("\n", $response) . "\n"; + } + + /** + * Extract certificate and its details from the store + * @param string $certref reference number + * @return array|bool structure or boolean false if not found + */ + public static function getCertificate($certref) + { + if (isset(Config::getInstance()->object()->cert)) { + foreach (Config::getInstance()->object()->cert as $cert) { + if (isset($cert->refid) && $certref == $cert->refid) { + $response = ['is_server' => false]; + // certificate CN + $str_crt = base64_decode((string)$cert->crt); + $inf_crt = openssl_x509_parse($str_crt); + if (is_array($inf_crt)) { + foreach ($inf_crt as $key => $val) { + $response[$key] = $val; + } + if ( + isset($inf_crt['extensions']['extendedKeyUsage']) && + strstr($inf_crt['extensions']['extendedKeyUsage'], 'TLS Web Server Authentication') !== false && + isset($inf_crt['extensions']['keyUsage']) && + strpos($inf_crt['extensions']['keyUsage'], 'Digital Signature') !== false && + (strpos($inf_crt['extensions']['keyUsage'], 'Key Encipherment') !== false || + strpos($inf_crt['extensions']['keyUsage'], 'Key Agreement') !== false) + ) { + $response['is_server'] = true; + } + } + $response['crt'] = self::cleanCert(base64_decode((string)$cert->crt)); + if (!empty((string)$cert->prv)) { + $response['prv'] = self::cleanCert(base64_decode((string)$cert->prv)); + } + if (!empty($chain = self::getCaChain((string)$cert->caref))) { + $response['ca'] = ['crt' => self::cleanCert($chain)]; + } + return $response; + } + } + } + return false; + } + + + /** + * Extract certificate chain + * @param string $caref reference number + * @return array|bool structure or boolean false if not found + */ + public static function getCaChain($caref) + { + $chain = []; + while (($item = self::getCA(!isset($item) ? $caref : $item->caref)) != null) { + $chain[] = base64_decode((string)$item->crt); + } + return implode("\n", $chain); + } + +} \ No newline at end of file