diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Trust/Api/CertController.php b/src/opnsense/mvc/app/controllers/OPNsense/Trust/Api/CertController.php
index 4588c3edd..e196e369f 100644
--- a/src/opnsense/mvc/app/controllers/OPNsense/Trust/Api/CertController.php
+++ b/src/opnsense/mvc/app/controllers/OPNsense/Trust/Api/CertController.php
@@ -141,7 +141,9 @@ class CertController extends ApiMutableModelControllerBase
$filter_funct = function ($record) use ($carefs) {
return empty($carefs) || array_intersect(explode(',', $record->caref), $carefs);
};
- return $this->searchBase('cert', ['descr', 'caref', 'name', 'valid_from', 'valid_to'], null, $filter_funct);
+ return $this->searchBase(
+ 'cert', ['descr', 'caref', 'rfc3280_purpose', 'name', 'valid_from', 'valid_to'], null, $filter_funct
+ );
}
public function getAction($uuid = null)
@@ -179,6 +181,19 @@ class CertController extends ApiMutableModelControllerBase
return [];
}
+ public function rawDumpAction($uuid)
+ {
+ $payload = $this->getBase('cert', 'cert', $uuid);
+ if (!empty($payload['cert'])) {
+ if (!empty($payload['cert']['crt_payload'])) {
+ return CertStore::dumpX509($payload['cert']['crt_payload']);
+ } elseif (!empty($payload['cert']['csr_payload'])) {
+ return CertStore::dumpCSR($payload['cert']['csr_payload']);
+ }
+ }
+ return [];
+ }
+
public function caListAction()
{
$result = [];
diff --git a/src/opnsense/mvc/app/library/OPNsense/Trust/Store.php b/src/opnsense/mvc/app/library/OPNsense/Trust/Store.php
index db610b48c..2a732e634 100644
--- a/src/opnsense/mvc/app/library/OPNsense/Trust/Store.php
+++ b/src/opnsense/mvc/app/library/OPNsense/Trust/Store.php
@@ -446,11 +446,97 @@ class Store
$result[$target] = implode('\n', $values);
}
}
+
+ /* Extract certificate purpose */
+ $purpose = [];
+ foreach (['basicConstraints', 'extendedKeyUsage', 'keyUsage', 'authorityInfoAccess'] as $ext) {
+ $purpose[$ext] = [];
+ if (!empty($crt['extensions'][$ext])) {
+ foreach (explode(",", $crt['extensions'][$ext]) as $item) {
+ $purpose[$ext][] = trim($item);
+ }
+ }
+ }
+
+ // rfc3280 purpose definitions
+ $result['rfc3280_purpose'] = '';
+ if (
+ 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'])
+ )
+ ) {
+ $result['rfc3280_purpose'] = 'id-kp-serverAuth';
+ } elseif (
+ in_array('TLS Web Client Authentication', $purpose['extendedKeyUsage']) &&
+ in_array('Digital Signature', $purpose['keyUsage'])
+ ) {
+ $result['rfc3280_purpose'] = 'id-kp-clientAuth';
+ } elseif (
+ in_array('OCSP Signing', $purpose['extendedKeyUsage']) &&
+ in_array('Digital Signature', $purpose['keyUsage'])
+ ) {
+ $result['rfc3280_purpose'] = 'id-kp-OCSPSigning';
+ }
+ //
return $result;
}
return false;
}
+ /**
+ * @param string $cert certificate
+ * @return array [stdout|stderr]
+ */
+ public static function dumpX509($cert)
+ {
+ $result = [];
+ $process = proc_open(
+ '/usr/local/bin/openssl x509 -fingerprint -sha256 -text',
+ [["pipe", "r"], ["pipe", "w"], ["pipe", "w"]],
+ $pipes
+ );
+ if (is_resource($process)) {
+ fwrite($pipes[0], $cert);
+ fclose($pipes[0]);
+ $result['stdout'] = stream_get_contents($pipes[1]);
+ fclose($pipes[1]);
+ $result['stderr'] = stream_get_contents($pipes[2]);
+ fclose($pipes[2]);
+ proc_close($process);
+
+ }
+ return $result;
+ }
+
+ /**
+ * @param string $csr CSR
+ * @return array [stdout|stderr]
+ */
+ public static function dumpCSR($csr)
+ {
+ $result = [];
+ $process = proc_open(
+ '/usr/local/bin/openssl req -text -noout',
+ [["pipe", "r"], ["pipe", "w"], ["pipe", "w"]],
+ $pipes
+ );
+ if (is_resource($process)) {
+ fwrite($pipes[0], $csr);
+ fclose($pipes[0]);
+ $result['stdout'] = stream_get_contents($pipes[1]);
+ fclose($pipes[1]);
+ $result['stderr'] = stream_get_contents($pipes[2]);
+ fclose($pipes[2]);
+ proc_close($process);
+
+ }
+ return $result;
+ }
+
+
+
/**
* Extract certificate chain
* @param string $caref reference number
diff --git a/src/opnsense/mvc/app/models/OPNsense/Trust/Cert.xml b/src/opnsense/mvc/app/models/OPNsense/Trust/Cert.xml
index 9afa01945..9a2ed1ae1 100644
--- a/src/opnsense/mvc/app/models/OPNsense/Trust/Cert.xml
+++ b/src/opnsense/mvc/app/models/OPNsense/Trust/Cert.xml
@@ -111,6 +111,7 @@