Deleted client certificate trust expectations

Dan Freed dfreed at epic.com
Wed Nov 11 16:41:50 UTC 2020


Sorry I realized I didn't include the OpenSSL version I was using.

This is with OpenSSL 1.1.1d  10 Sep 2019.

-Dan

From: openssl-users <openssl-users-bounces at openssl.org>
Date: Wednesday, November 11, 2020 at 10:29 AM
To: openssl-users at openssl.org <openssl-users at openssl.org>
Subject: Deleted client certificate trust expectations
External Mail. Careful of links / attachments. Submit Helpdesk if unsure.

Hello,

I have a question/issue about how OpenSSL should handle a deleted client certificate. It appears that once a trusted certificate is read from the filesystem, it remains trusted throughout the lifespan of the server process.

I wrote a small SSL web service that reproduces the issue I'm having with my application.

Pardon the Perl syntax - I've not rewritten this in C but I think the intent is clear.  This code reproduces the scenario:

use Socket;
use Net::SSLeay qw(die_now die_if_ssl_error);
Net::SSLeay::load_error_strings();
Net::SSLeay::SSLeay_add_ssl_algorithms();
Net::SSLeay::randomize();
$our_ip = "\0\0\0\0";
$port = 1235;
$sockaddr_template = 'S n a4 x8';
$our_serv_params = pack ($sockaddr_template, &AF_INET, $port, $our_ip);
socket (S, &AF_INET, &SOCK_STREAM, 0)  or die "socket: $!";
bind (S, $our_serv_params)             or die "bind:   $!";
listen (S, 5);
$ctx = Net::SSLeay::CTX_new ();
$key = "client.key";
$cert = "client.crt";
$trust_dir = "/client_trusted_certificates";
Net::SSLeay::CTX_use_RSAPrivateKey_file($ctx, $key, Net::SSLeay::FILETYPE_PEM());
Net::SSLeay::CTX_use_certificate_file($ctx, $cert, Net::SSLeay::FILETYPE_PEM());
Net::SSLeay::CTX_set_session_id_context($ctx,'sessiontest',length('sessiontest'));
Net::SSLeay::CTX_load_verify_locations($ctx,"",$trust_dir);
Net::SSLeay::CTX_set_verify($ctx,&Net::SSLeay::VERIFY_PEER, \&verify_client_cert);
while (1)
{
   $addr = accept (NS, S);
   select (NS);
   $| = 1;
   select (STDOUT);
   $ssl = Net::SSLeay::new($ctx);
   Net::SSLeay::set_fd($ssl, fileno(NS));
   $err = Net::SSLeay::accept($ssl);
   $got = Net::SSLeay::read($ssl);
   print $got."\n";
   Net::SSLeay::write ($ssl, uc ($got));
   Net::SSLeay::free ($ssl);
   close NS;
}

sub verify_client_cert
{
    my ($pre_verify,$x509_store) = @_;

    print "Pre-verify: $pre_verify\n";
    print "ctx error: ".Net::SSLeay::X509_STORE_CTX_get_error($x509_store)."\n";
    return $pre_verify;
}

This all works as it should, and verify_client_cert() is called appropriately when the client cert is provided.

The issue I'm having is how the verify process works when a certificate is removed from the trusted directory while this service is running.  If a client connects with a client cert and the service verifies that certificate, then the trusted client cert is removed from /trusted_clients, then the client connects again - the client cert will still verify.  The client cert will continue to  verify until I restart the server.

An strace of the process confirms that it only opens the trusted directory once, subsequent connections using this client cert do not re-open or look for the file in the trust directory.

My understanding of how this should work was that it should read the contents of that directory at the time the verify takes place, not when CTX_set_verify() is called, but that doesn't seem to be what is happening.

Another interesting bit is that the inverse is not true.  If I add a cert to the trusted directory, it immediately uses it without having to restart the process.

I assume that if I used a certificate revocation list and revoked the client cert this wouldn't be an issue, but why are the directory contents cached? Is this for performance reasons?

Thanks
Dan Freed


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mta.openssl.org/pipermail/openssl-users/attachments/20201111/9b85b370/attachment-0001.html>


More information about the openssl-users mailing list