Improve CRL/OCSP status checks
Currently the code used to check the CRL status is quite heavy and uses a rather large memory footprint depending on the SSL provider. In future versions it may be beneficial to abstract the CRL testing out of the SSL class and into the downloader.
It'd be nice if the SSL class itself was more of a getter of protected attributes than a getter of raw data and processing of meta data. Right now having the CRL code all within the SSL Cert class makes things feel dense. I think there may be some mixed concerns as well that might benefit from a refactor.
I ran into some issues today where a list took up to 356M of ram...this is no bueno.
Maybe I could consider processing CRL lists as data streams instead of processing the complete data chunk?
It might be usefull to have openssl do the revocation check to save on the memory (optionally).
A thing I have been experimenting with (nowhere near perfect):
private static function isCertificateRevoked(array $info)
{
$ocsp_url = str_replace('OCSP - URI:', '', collect(explode("\n", array_get($info, 'extensions.authorityInfoAccess')))->first(function ($value) {
return starts_with($value, 'OCSP - URI:');
}));
if (!empty($ocsp_url)) {
$temp_path = storage_path("app/{$info['fingerprint']}");
file_put_contents("{$temp_path}.pem", $info['certificate']);
file_put_contents("{$temp_path}.chain.pem", $info['certificate_chain']);
$output = shell_exec("openssl ocsp -issuer {$temp_path}.chain.pem -cert {$temp_path}.pem -url {$ocsp_url}");
@unlink($temp_path);
if (!empty($output) && str_contains($output, 'Revocation Time')) {
preg_match('/\sRevocation Time: (.*? [a-zA-Z]+)\s/', $output, $matches);
if (!empty($matches[1])) {
return Carbon::createFromFormat('M n H:i:s Y T', $matches[1]);
}
}
}
return false;
}
I think this seems like a fair wait to approach things. I'll have to review the impact that this could have to see how it fits into the whole picture of things. Thanks for contributing this! I'll update this issue once I've had time to examine the change further!
Yeah ofcourse, this is using OCSP instead of the revocation list so a whole other approuch but more "light", might be an good idea to keep the current option next to this since the revocation list with some smart caching can probably be sped up a lot using streaming and caching.
This does make an request per certificate instead of a single revocation list (per issuer) and OCSP can be down causing this to fail (this is why the default is false to make sure failures don;t mess with anything).