Add CRUD for root CA certificates

refs #3016
This commit is contained in:
Alexander A. Klimov 2017-11-17 18:02:03 +01:00
parent 1b30682adc
commit 4bd1a35dd2
4 changed files with 292 additions and 4 deletions

View File

@ -6,8 +6,10 @@ namespace Icinga\Controllers;
use Exception;
use Icinga\Application\Icinga;
use Icinga\File\Storage\LocalFileStorage;
use Icinga\Forms\Config\Tls\RootCaCollection\AddCaForm;
use Icinga\Forms\Config\Tls\RootCaCollection\CreateForm;
use Icinga\Forms\Config\Tls\RootCaCollection\EditForm;
use Icinga\Forms\Config\Tls\RootCaCollection\RemoveCaForm;
use Icinga\Forms\ConfirmRemovalForm;
use Icinga\Web\Controller;
use Icinga\Web\Notification;
@ -40,18 +42,58 @@ class TlsrootcacollectionController extends Controller
public function editAction()
{
$this->view->form = $form = new EditForm();
$this->view->editForm = $editForm = new EditForm();
$name = $this->params->getRequired('name');
$form->setOldName($name)
$editForm->setOldName($name)
->setRedirectUrl('tlsrootcacollection/edit')
->handleRequest();
$this->view->addCaForm = $addCaForm = new AddCaForm();
$addCaForm->setCollectionName($name)
->setRedirectUrl('tlsrootcacollection/edit')
->handleRequest();
preg_match_all(
'/-+BEGIN CERTIFICATE-+.+?-+END CERTIFICATE-+/s',
LocalFileStorage::common('tls/rootcacollections')->read(bin2hex($name) . '.pem'),
$certs
);
$certs = $certs[0];
foreach ($certs as & $cert) {
$sha256 = openssl_x509_fingerprint($cert, 'sha256');
$cert = array(
'info' => openssl_x509_parse($cert),
'sha1' => openssl_x509_fingerprint($cert, 'sha1'),
'sha256' => $sha256,
'removalForm' => new RemoveCaForm(array(
'collectionName' => $name,
'certBySha256' => $sha256,
'redirectUrl' => 'tlsrootcacollection/edit'
))
);
$cert['removalForm']->handleRequest();
}
usort($certs, function($a, $b) {
$a = $a['info']['name'];
$b = $b['info']['name'];
if ($a < $b) {
return -1;
}
return $a > $b ? 1 : 0;
});
$this->view->certs = $certs;
$this->addTitleTab(
$this->translate('Edit Certificate Collection'),
sprintf($this->translate('Edit TLS Root CA Certificate Collection "%s"'), $name)
);
$this->render('form');
}
public function removeAction()

View File

@ -0,0 +1,80 @@
<?php
/* Icinga Web 2 | (c) 2017 Icinga Development Team | GPLv2+ */
namespace Icinga\Forms\Config\Tls\RootCaCollection;
use Exception;
use Icinga\File\Storage\LocalFileStorage;
use Icinga\Web\Form;
use Icinga\Web\Form\Validator\TlsCertFileValidator;
/**
* Configuration form for adding TLS root CA certificates
*/
class AddCaForm extends Form
{
/**
* The TLS root CA certificate collection's name
*
* @var string
*/
protected $collectionName;
public function init()
{
$this->setName('form_config_tlsrootca_add');
$this->setSubmitLabel($this->translate('Add'));
}
public function createElements(array $formData)
{
$this->addElement(
'file',
'cert',
array(
'label' => $this->translate('Certificate (PEM)'),
'description' => $this->translate('The new TLS root CA certificate'),
'required' => true,
'validators' => array(new TlsCertFileValidator())
)
);
}
public function onSuccess()
{
try {
$rootCaCollections = LocalFileStorage::common('tls/rootcacollections');
/** @var \Zend_Form_Element_File $cert */
$cert = $this->getElement('cert');
if ($cert->isUploaded()) {
$cert->getValue();
}
openssl_x509_export('file://' . $cert->getFileName(), $newCert);
$collectionFileName = bin2hex($this->collectionName) . '.pem';
$rootCaCollections->update($collectionFileName, $newCert . $rootCaCollections->read($collectionFileName));
} catch (Exception $e) {
$this->error($e->getMessage());
return false;
}
$this->getRedirectUrl()->setParam('name', $this->collectionName);
}
/**
* Set the TLS root CA certificate collection's name
*
* @param string $collectionName
*
* @return $this
*/
public function setCollectionName($collectionName)
{
$this->collectionName = $collectionName;
return $this;
}
}

View File

@ -0,0 +1,93 @@
<?php
/* Icinga Web 2 | (c) 2017 Icinga Development Team | GPLv2+ */
namespace Icinga\Forms\Config\Tls\RootCaCollection;
use Exception;
use Icinga\File\Storage\LocalFileStorage;
use Icinga\Web\Form;
use Icinga\Web\Form\Validator\TlsCertFileValidator;
/**
* Configuration form for removing TLS root CA certificates
*/
class RemoveCaForm extends Form
{
/**
* The TLS root CA certificate collection's name
*
* @var string
*/
protected $collectionName;
/**
* The TLS root CA certificate's SHA256 sum
*
* @var string
*/
protected $certBySha256;
public function init()
{
$this->setName('form_config_tlsrootca_remove_' . $this->certBySha256);
$this->setSubmitLabel($this->translate('Remove'));
}
public function onSuccess()
{
try {
$rootCaCollections = LocalFileStorage::common('tls/rootcacollections');
$collectionFileName = bin2hex($this->collectionName) . '.pem';
preg_match_all(
'/-+BEGIN CERTIFICATE-+.+?-+END CERTIFICATE-+/s',
$rootCaCollections->read($collectionFileName),
$certs
);
$certs = $certs[0];
foreach ($certs as $index => $cert) {
if (openssl_x509_fingerprint($cert, 'sha256') === $this->certBySha256) {
unset($certs[$index]);
$rootCaCollections->update($collectionFileName, implode(PHP_EOL, $certs));
break;
}
}
} catch (Exception $e) {
$this->error($e->getMessage());
return false;
}
$this->getRedirectUrl()->setParam('name', $this->collectionName);
}
/**
* Set the TLS root CA certificate collection's name
*
* @param string $collectionName
*
* @return $this
*/
public function setCollectionName($collectionName)
{
$this->collectionName = $collectionName;
return $this;
}
/**
* Set the TLS root CA certificate's SHA256 sum
*
* @param string $certBySha256
*
* @return $this
*/
public function setCertBySha256($certBySha256)
{
$this->certBySha256 = $certBySha256;
return $this;
}
}

View File

@ -0,0 +1,73 @@
<?php
use Icinga\Util\TimezoneDetect;
/** @var array[] $certs */
if (! empty($certs)) {
$timezoneDetect = new TimezoneDetect();
$timeZone = new DateTimeZone(
$timezoneDetect->success() ? $timezoneDetect->getTimezoneName() : date_default_timezone_get()
);
}
?>
<div class="controls">
<?= /** @var \Icinga\Web\Widget\Tabs $tabs */ $tabs ?>
</div>
<div class="content">
<?= /** @var \Icinga\Forms\Config\Tls\RootCaCollection\EditForm $editForm */ $editForm ?>
<h1><?= /** @var \Icinga\Web\View $this */ $this->translate('TLS Root CA Certificates') ?></h1>
<?= /** @var \Icinga\Forms\Config\Tls\RootCaCollection\AddCaForm $addCaForm */ $addCaForm ?>
<?php foreach ($certs as $cert):
$subject = array();
foreach ($cert['info']['subject'] as $key => $value) {
$subject[] = $this->escape("$key = " . var_export($value, true));
}
$issuer = array();
foreach ($cert['info']['issuer'] as $key => $value) {
$issuer[] = $this->escape("$key = " . var_export($value, true));
}
?>
<h2><?= $this->escape($cert['info']['name']) ?></h2>
<table class="name-value-list">
<tr>
<td><?= $this->escape($this->translate('Subject', 'x509.certificate')) ?></td>
<td><?= implode('<br>', $subject) ?></td>
</tr>
<tr>
<td><?= $this->escape($this->translate('Issuer', 'x509.certificate')) ?></td>
<td><?= implode('<br>', $issuer) ?></td>
</tr>
<tr>
<td><?= $this->escape($this->translate('Valid from', 'x509.certificate')) ?></td>
<td><?= $this->escape(
DateTime::createFromFormat('U', $cert['info']['validFrom_time_t'])
->setTimezone($timeZone)
->format(DateTime::ISO8601)
) ?></td>
</tr>
<tr>
<td><?= $this->escape($this->translate('Valid until', 'x509.certificate')) ?></td>
<td><?= $this->escape(
DateTime::createFromFormat('U', $cert['info']['validTo_time_t'])
->setTimezone($timeZone)
->format(DateTime::ISO8601)
) ?></td>
</tr>
<tr>
<td><?= $this->escape($this->translate('SHA256 fingerprint', 'x509.certificate')) ?></td>
<td><?= $this->escape(implode(' ', str_split(strtoupper($cert['sha256']), 2))) ?></td>
</tr>
<tr>
<td><?= $this->escape($this->translate('SHA1 fingerprint', 'x509.certificate')) ?></td>
<td><?= $this->escape(implode(' ', str_split(strtoupper($cert['sha1']), 2))) ?></td>
</tr>
</table>
<?= $cert['removalForm'] ?>
<?php endforeach; ?>
</div>