Project

General

Profile

« Previous | Next » 

Revision 04761344

Added by Jim Pingle over 11 years ago

Perform a much more accurate comparison between two certificates to determine if they are identical when checking their revocation status. Fixes #3237

View differences:

etc/inc/certs.inc
495 495
	return array($start, $end);
496 496
}
497 497

  
498
function cert_get_serial($str_crt, $decode = true) {
499
	if ($decode)
500
		$str_crt = base64_decode($str_crt);
501
	$crt_details = openssl_x509_parse($str_crt);
502
	if (isset($crt_details['serialNumber']) && !empty($crt_details['serialNumber']))
503
		return $crt_details['serialNumber'];
504
	else
505
		return NULL;
506
}
507

  
498 508
function prv_get_modulus($str_crt, $decode = true){
499 509
	return cert_get_modulus($str_crt, $decode, "prv");
500 510
}
......
645 655
	return false;
646 656
}
647 657

  
658
/* Compare two certificates to see if they match. */
659
function cert_compare($cert1, $cert2) {
660
	/* Ensure two certs are identical by first checking that their issuers match, then
661
		subjects, then serial numbers, and finally the moduli. Anything less strict
662
		could accidentally count two similar, but different, certificates as
663
		being identical. */
664
	$c1 = base64_decode($cert1['crt']);
665
	$c2 = base64_decode($cert2['crt']);
666
	if ((cert_get_issuer($c1, false) == cert_get_issuer($c2, false))
667
		&& (cert_get_subject($c1, false) == cert_get_subject($c2, false))
668
		&& (cert_get_serial($c1, false) == cert_get_serial($c2, false))
669
		&& (cert_get_modulus($c1, false) == cert_get_modulus($c2, false)))
670
		return true;
671
	return false;
672
}
673

  
648 674
function is_cert_revoked($cert, $crlref = "") {
649 675
	global $config;
650 676
	if (!is_array($config['crl']))
......
655 681
		if (!is_array($crl['cert']))
656 682
			return false;
657 683
		foreach ($crl['cert'] as $rcert) {
658
			if (($rcert['refid'] == $cert['refid']) || ($rcert['descr'] == $cert['descr']))
684
			if (cert_compare($rcert, $cert))
659 685
				return true;
660 686
		}
661 687
	} else {
......
663 689
			if (!is_array($crl['cert']))
664 690
				continue;
665 691
			foreach ($crl['cert'] as $rcert) {
666
				if (($rcert['refid'] == $cert['refid']) || ($rcert['descr'] == $cert['descr']))
692
				if (cert_compare($rcert, $cert))
667 693
					return true;
668 694
			}
669 695
		}

Also available in: Unified diff