summaryrefslogtreecommitdiffstats
path: root/etc
diff options
context:
space:
mode:
authorjim-p <jimp@pfsense.org>2013-10-09 10:02:56 -0400
committerjim-p <jimp@pfsense.org>2013-10-09 10:03:59 -0400
commit6f4a2864ad0e83f152a0cdc9c157f5d95aa8a9c7 (patch)
tree701daa93ff63d0935b68bea7b3df0a55ab7a2914 /etc
parentfda96df060e5a813875496a3b9ad09b6708d02af (diff)
downloadpfsense-6f4a2864ad0e83f152a0cdc9c157f5d95aa8a9c7.zip
pfsense-6f4a2864ad0e83f152a0cdc9c157f5d95aa8a9c7.tar.gz
Perform a much more accurate comparison between two certificates to determine if they are identical when checking their revocation status. Fixes #3237
Diffstat (limited to 'etc')
-rw-r--r--etc/inc/certs.inc30
1 files changed, 28 insertions, 2 deletions
diff --git a/etc/inc/certs.inc b/etc/inc/certs.inc
index 3525660..518bc59 100644
--- a/etc/inc/certs.inc
+++ b/etc/inc/certs.inc
@@ -495,6 +495,16 @@ function cert_get_dates($str_crt, $decode = true) {
return array($start, $end);
}
+function cert_get_serial($str_crt, $decode = true) {
+ if ($decode)
+ $str_crt = base64_decode($str_crt);
+ $crt_details = openssl_x509_parse($str_crt);
+ if (isset($crt_details['serialNumber']) && !empty($crt_details['serialNumber']))
+ return $crt_details['serialNumber'];
+ else
+ return NULL;
+}
+
function prv_get_modulus($str_crt, $decode = true){
return cert_get_modulus($str_crt, $decode, "prv");
}
@@ -645,6 +655,22 @@ function cert_unrevoke($cert, & $crl) {
return false;
}
+/* Compare two certificates to see if they match. */
+function cert_compare($cert1, $cert2) {
+ /* Ensure two certs are identical by first checking that their issuers match, then
+ subjects, then serial numbers, and finally the moduli. Anything less strict
+ could accidentally count two similar, but different, certificates as
+ being identical. */
+ $c1 = base64_decode($cert1['crt']);
+ $c2 = base64_decode($cert2['crt']);
+ if ((cert_get_issuer($c1, false) == cert_get_issuer($c2, false))
+ && (cert_get_subject($c1, false) == cert_get_subject($c2, false))
+ && (cert_get_serial($c1, false) == cert_get_serial($c2, false))
+ && (cert_get_modulus($c1, false) == cert_get_modulus($c2, false)))
+ return true;
+ return false;
+}
+
function is_cert_revoked($cert, $crlref = "") {
global $config;
if (!is_array($config['crl']))
@@ -655,7 +681,7 @@ function is_cert_revoked($cert, $crlref = "") {
if (!is_array($crl['cert']))
return false;
foreach ($crl['cert'] as $rcert) {
- if (($rcert['refid'] == $cert['refid']) || ($rcert['descr'] == $cert['descr']))
+ if (cert_compare($rcert, $cert))
return true;
}
} else {
@@ -663,7 +689,7 @@ function is_cert_revoked($cert, $crlref = "") {
if (!is_array($crl['cert']))
continue;
foreach ($crl['cert'] as $rcert) {
- if (($rcert['refid'] == $cert['refid']) || ($rcert['descr'] == $cert['descr']))
+ if (cert_compare($rcert, $cert))
return true;
}
}
OpenPOWER on IntegriCloud