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"); - +