mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-14 00:24:40 +00:00
System: Trust: Revocation - work in progress for https://github.com/opnsense/core/issues/7248
* add raw dump button * generate CRL and store text * remove add/del footer buttons
This commit is contained in:
parent
ad5fed3c4d
commit
bed2e66cf0
@ -231,6 +231,27 @@ class CrlController extends ApiControllerBase
|
||||
}
|
||||
}
|
||||
}
|
||||
$x509_crl = new \phpseclib3\File\X509();
|
||||
if (empty($validations['crl.caref'])) {
|
||||
/*
|
||||
* create empty CRL. A quirk with phpseclib is that in order to correctly sign
|
||||
* a new CRL, a CA must be loaded using a separate X509 container, which is passed
|
||||
* to signCRL(). However, to validate the resulting signature, the original X509
|
||||
* CRL container must load the same CA using loadCA() with a direct reference
|
||||
* to the CA's public cert.
|
||||
*/
|
||||
$x509_crl->loadCA($ca_crt_str);
|
||||
$x509_crl->loadCRL($x509_crl->saveCRL($x509_crl->signCRL($ca_cert, $x509_crl)));
|
||||
|
||||
/* Now validate the CRL to see if everything went well */
|
||||
try {
|
||||
if (!$x509_crl->validateSignature(false)) {
|
||||
$validations['crl.caref'] = gettext('Cert revocation error: CRL signature invalid');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$validations['crl.caref'] = gettext('Cert revocation error: CRL signature invalid') . " " . $e;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($validations)) {
|
||||
Config::getInstance()->unlock();
|
||||
@ -279,12 +300,16 @@ class CrlController extends ApiControllerBase
|
||||
}
|
||||
$crl->caref = (string)$caref;
|
||||
$crl->descr = (string)$payload['descr'];
|
||||
$crl->serial = !empty($payload['serial']) ? $payload['serial'] : $crl->serial;
|
||||
$crl->serial = ((int)((string)$crl->serial)) + 1;
|
||||
$to_delete = [];
|
||||
$crl_certs = [];
|
||||
foreach ($crl->cert as $cert) {
|
||||
if (!isset($revoked_refs[(string)$cert->refid])) {
|
||||
$to_delete[] = $cert;
|
||||
} else {
|
||||
$cert->reason = $revoked_refs[(string)$cert->refid];
|
||||
$crl_certs[] = $cert;
|
||||
unset($revoked_refs[(string)$cert->refid]);
|
||||
}
|
||||
}
|
||||
@ -302,8 +327,31 @@ class CrlController extends ApiControllerBase
|
||||
$tmp->prv = (string)$cert->prv;
|
||||
$tmp->revoke_time = (string)time();
|
||||
$tmp->reason = $revoked_refs[(string)$cert->refid];
|
||||
$crl_certs[] = $tmp;
|
||||
}
|
||||
}
|
||||
if ($payload['crlmethod'] == 'internal') {
|
||||
/* add all cert serial numbers to crl */
|
||||
foreach ($crl_certs as $cert) {
|
||||
$tmp = @openssl_x509_parse(base64_decode((string)$cert->crt));
|
||||
if ($tmp !== false && isset($tmp['serialNumber'])) {
|
||||
$x509_crl->setRevokedCertificateExtension(
|
||||
(string)$tmp['serialNumber'],
|
||||
'id-ce-cRLReasons',
|
||||
self::$status_codes[(string)$cert->reason]
|
||||
);
|
||||
}
|
||||
}
|
||||
$x509_crl->setSerialNumber((string)$crl->serial, 10);
|
||||
/* consider dates after 2050 lifetime in GeneralizedTime format (rfc5280#section-4.1.2.5) */
|
||||
$date = new \DateTimeImmutable(
|
||||
'+' . (string)$crl->lifetime . ' days',
|
||||
new \DateTimeZone(@date_default_timezone_get())
|
||||
);
|
||||
$x509_crl->setEndDate((int)$date->format("Y") < 2050 ? $date : 'lifetime');
|
||||
$new_crl = $x509_crl->signCRL($ca_cert, $x509_crl);
|
||||
$crl->text = base64_encode($x509_crl->saveCRL($new_crl) . PHP_EOL);
|
||||
}
|
||||
|
||||
if ($last_crl) {
|
||||
/* insert new item after last crl */
|
||||
@ -321,4 +369,16 @@ class CrlController extends ApiControllerBase
|
||||
}
|
||||
return ['status' => 'failed'];
|
||||
}
|
||||
|
||||
|
||||
public function rawDumpAction($uuid)
|
||||
{
|
||||
$payload = $this->getAction($uuid);
|
||||
if (!empty($payload['crl'])) {
|
||||
if (!empty($payload['crl']['text'])) {
|
||||
return CertStore::dumpCRL($payload['crl']['text']);
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,6 +555,30 @@ class Store
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cert certificate
|
||||
* @return array [stdout|stderr]
|
||||
*/
|
||||
public static function dumpCRL($cert)
|
||||
{
|
||||
$result = [];
|
||||
$process = proc_open(
|
||||
'/usr/local/bin/openssl crl -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -32,7 +32,30 @@
|
||||
get:'/api/trust/crl/get/',
|
||||
set:'/api/trust/crl/set/',
|
||||
del:'/api/trust/crl/del/',
|
||||
datakey: 'refid'
|
||||
datakey: 'refid',
|
||||
commands: {
|
||||
raw_dump: {
|
||||
method: function(event){
|
||||
let refid = $(this).data("row-id") !== undefined ? $(this).data("row-id") : '';
|
||||
ajaxGet('/api/trust/crl/raw_dump/' + refid, {}, function(data, status){
|
||||
if (data.stdout) {
|
||||
BootstrapDialog.show({
|
||||
title: "{{ lang._('CRL info') }}",
|
||||
type:BootstrapDialog.TYPE_INFO,
|
||||
message: $("<div/>").text(data.stdout).html(),
|
||||
cssClass: 'monospace-dialog',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
classname: 'fa fa-fw fa-info-circle',
|
||||
title: "{{ lang._('show certificate info') }}",
|
||||
sequence: 10
|
||||
},
|
||||
copy: {
|
||||
classname: undefined
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("#DialogCrl").click(function(){
|
||||
@ -82,6 +105,22 @@
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.monospace-dialog {
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.monospace-dialog > .modal-dialog {
|
||||
width:70% !important;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
max-height: calc(100vh - 210px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
|
||||
<li class="active"><a data-toggle="tab" id="tab_crls" href="#cert">{{ lang._('Index') }}</a></li>
|
||||
<li><a data-toggle="tab" href="#edit_crl" id="DialogCrl" style="display: none;"> </a></li>
|
||||
@ -99,15 +138,6 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-primary"><span class="fa fa-fw fa-plus"></span></button>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-fw fa-trash-o"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div id="edit_crl" class="tab-pane fade in">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user