in reply to Dynamic SNI certificates while upgrading to SSL

There is no explicit support in IO::Socket::SSL to do this, that is it can only deal with fixed certificates for SNI and has no way to create a certificate on demand for SNI. The way SNI on the server side works is by supplying an tls_ext_servername_callback and set the relevant context there.

I suggest you have a look at the code for IO::Socket::SSL and look how it uses Net::SSLeay::CTX_set_tlsext_servername_callback. Your code must work in a similar way, but instead of using an already created SSL context you have to create a new context with your own certifcates in this callback.

  • Comment on Re: Dynamic SNI certificates while upgrading to SSL

Replies are listed 'Best First'.
Re^2: Dynamic SNI certificates while upgrading to SSL
by gr3m1in (Novice) on Jan 03, 2015 at 17:01 UTC

    thanks for this!

    according to CPAN

    http://search.cpan.org/~mikem/Net-SSLeay-1.66/lib/Net/SSLeay.pod#Low_level_API:_Server_side_Server_Name_Indication_%28SNI%29_support

    the goal can be reached with code like this:

    # create default context my $ctx = Net::SSLeay::CTX_new or die; Net::SSLeay::CTX_set_cipher_list($ctx, 'ALL'); Net::SSLeay::set_cert_and_key($ctx, 'cert.pem','key.pem') or die; # create new context for each new hostname my %hostnames = (); Net::SSLeay::CTX_set_tlsext_servername_callback( $ctx, sub { my $ssl = shift; my $h = Net::SSLeay::get_servername($ssl); unless (exists $hostnames{$h}) { $hostnames{$h}->{ctx} = Net::SSLeay::CTX_new or die; Net::SSLeay::CTX_set_cipher_list($hostnames{$h}->{ctx}, 'A +LL'); $hostnames{$h}->{cert} = ... # generate certificate and $hostnames{$h}->{key} = ... # key based on hostname in $h # and re-use them in future f +rom hash as below Net::SSLeay::set_cert_and_key( $hostnames{$h}->{ctx}, $hostnames{$h}->{cert}, $hostnames{$h}->{key} ) or die; } Net::SSLeay::set_SSL_CTX($ssl, $hostnames{$h}->{ctx}); } );

    but every new cert/key pair generation will use some time.
    in my case, the script is a multiplexing server based on IO::Select, so it reads and writes with short parts of data to prevent any long/heavy transfer to block the others.
    and each time the new pair is generated the script will block for this time.

    is there a way to solve this in non-blocking manner?

    thanks!

      > is there a way to solve this in non-blocking manner?

      I don't think so. To do this in a sensible non-blocking way you would need to have control about the SSL state machine. But OpenSSL only exposes some hooks into this machine with callbacks and I don't think you can have multiple servername callbacks on the same context run in parallel.

        and what if i detach (maybe fork) this process from the main one?
        in such case, the problem is how to return the upgraded socket object from child to main one?

        i know, it sounds somewhat insane (in case of fork)...

        i'm not familiar with threads, however maybe it could help...
        i don't know.
        could it?

        thanks!