diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc
index ca0b5a0ce..ad67c7bcf 100644
--- a/src/etc/inc/certs.inc
+++ b/src/etc/inc/certs.inc
@@ -612,6 +612,10 @@ function crl_update(&$crl)
$crl['serial']++;
$ca_str_crt = base64_decode($ca['crt']);
$ca_str_key = base64_decode($ca['prv']);
+ if (!openssl_x509_check_private_key($ca_str_crt, $ca_str_key)) {
+ syslog(LOG_ERR, "Cert revocation error: CA keys mismatch");
+ return false;
+ }
/* Load in the CA's cert */
$ca_cert = new \phpseclib\File\X509();
@@ -632,10 +636,18 @@ function crl_update(&$crl)
* CRL container must load the same CA using loadCA() with a direct reference
* to the CA's public cert.
*/
+
$x509_crl->loadCRL($x509_crl->saveCRL($x509_crl->signCRL($ca_cert, $x509_crl)));
/* Now validate the CRL to see if everything went well */
if (!$x509_crl->validateSignature(false)) {
+ /* phpseclib2 not throws exceptions on validation fail. let's try to guess */
+ if (openssl_pkey_get_details(openssl_pkey_get_private($ca_str_key))['type'] === 0) {
+ syslog(LOG_ERR, "Cert revocation error: CRL validation failed at first step.");
+ } else {
+ /* phpseclib2 Crypt not supporting ECDSA / ECDH algorithms. May be the reason of sign/validateion fail */
+ syslog(LOG_ERR, "Cert revocation error: Only RSA key type currently supported for CRL signing.");
+ }
return false;
}
@@ -646,6 +658,7 @@ function crl_update(&$crl)
$x509_cert->loadCA($ca_str_crt);
$raw_cert = $x509_cert->loadX509(base64_decode($cert['crt']));
if (!$x509_cert->validateSignature(false)) {
+ syslog(LOG_ERR, "Cert revocation error: CA validation failed.");
return false;
}
/* Get serial number of cert */
@@ -672,10 +685,14 @@ function cert_revoke($cert, &$crl, $reason = CERT_CRL_STATUS_UNSPECIFIED)
if (!is_crl_internal($crl)) {
return false;
}
+ $crl_before = $crl;
$cert["reason"] = $reason;
$cert["revoke_time"] = time();
$crl["cert"][] = $cert;
- crl_update($crl);
+ if (!crl_update($crl)) {
+ $crl = $crl_before;
+ return false;
+ }
return true;
}
diff --git a/src/www/system_crlmanager.php b/src/www/system_crlmanager.php
index b84193194..61d5f0bbc 100644
--- a/src/www/system_crlmanager.php
+++ b/src/www/system_crlmanager.php
@@ -169,11 +169,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (!count($input_errors)) {
$reason = (empty($pconfig['crlreason'])) ? CERT_CRL_STATUS_UNSPECIFIED : $pconfig['crlreason'];
- cert_revoke($cert, $crl, $reason);
- plugins_configure('crl');
- write_config(sprintf('Revoked certificate %s in CRL %s', $cert['descr'], $crl['descr']));
- header(url_safe('Location: /system_crlmanager.php'));
- exit;
+ if (cert_revoke($cert, $crl, $reason)) {
+ plugins_configure('crl');
+ write_config(sprintf('Revoked certificate %s in CRL %s', $cert['descr'], $crl['descr']));
+ header(url_safe('Location: /system_crlmanager.php'));
+ exit;
+ } else {
+ $savemsg = gettext("Cannot revoke certificate. See general log for details.") . "
";
+ $act="edit";
+ }
}
} else {
$input_errors = array();
@@ -217,6 +221,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
}
if ($pconfig['crlmethod'] == "internal") {
+ /* check if new CRL CA have private key and it match public key so this CA can sign anything */
+ if (isset($pconfig['caref']) && !isset($id)) {
+ $cacert = lookup_ca($pconfig['caref']);
+ $ca_str_crt = base64_decode($cacert['crt']);
+ $ca_str_key = base64_decode($cacert['prv']);
+ if (!openssl_x509_check_private_key($ca_str_crt, $ca_str_key)) {
+ syslog(LOG_ERR, "CRL error: CA keys mismatch");
+ $savemsg = gettext("Cannot create CRL for this CA. CA keys mismatch or key missing.") . "
";
+ $act="edit";
+ }
+ }
+
$crl['serial'] = empty($pconfig['serial']) ? 9999 : $pconfig['serial'];
$crl['lifetime'] = empty($pconfig['lifetime']) ? 9999 : $pconfig['lifetime'];
$crl['cert'] = array();
@@ -226,10 +242,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$a_crl[] = $crl;
}
- write_config(sprintf('Saved CRL %s', $crl['descr']));
- plugins_configure('crl');
- header(url_safe('Location: /system_crlmanager.php'));
- exit;
+ if (!isset($savemsg)) {
+ write_config(sprintf('Saved CRL %s', $crl['descr']));
+ plugins_configure('crl');
+ header(url_safe('Location: /system_crlmanager.php'));
+ exit;
+ }
}
}
@@ -596,7 +614,7 @@ include("head.inc");
-
+