Thread: [asio-users] ssl server supporting multiple certificates and multiple private keys...
Brought to you by:
chris_kohlhoff
|
From: leon z. <leo...@gm...> - 2010-05-27 08:43:23
|
I have a distributed app (server client) with self-signed certificate used to validate communication between server and, multiple, client instances (i.e. 1 server box and many client boxes -- each client running the same client app). I would like to automatically update/renew this self-signed cert in the context of the distributed app. The client side has the capacity to self-update any of the client-side files automatically (over the SSL connection with the server)... including own executable, etc. etc. etc. -- inclusive of being able to download the updated cert. for the client. The client side also has the capability to auto-restart after the update of relevant files has been completed. There is a temporal problem however -- there are many clients (some could be online or offline with a few days frequency)... so some clients may be connecting with an already-updated cert. whilst others may be connecting, after a long offline period, still with the older certificate (and if the server is migrated to use the new cert, then the late-comers will not be able to connect with still-old cert and self-update, etc...) I would, ideally, like to have a server which would support, concurrently, 2 different certs (each signed with a different private key of course) -- this way any previously-connected and already-updated clients can continue working via the new cert.; and the currently-connecting clients which need updating will be able to update themselves via the old cert. The idea being that there will be a transition time-window over which both of the certs will be supported... with the older one being eventually phased out. Would this be possible (in boost::asio::ssl) ? I know that there may be other ways such as starting another instance of the server (on diff address) thus having 2 servers running: one with the old and another with the new cert... ... but it would include issues (e.g. being clanky admin-wise and due to having to prevent non-atomic writes w.r.t. contents of the cert file and the new client's config file (new ip/port address to connect to the server) on the client side: so as to prevent cases when updating client updates the new cert but crashes/restarts (e.g. due to power loss) before updating the new ip address... or the other way around... and this would involve more work etc... ... and so I'd like to see if it is at all possible to achieve the aforementioned solution with the 2 certs being supported by the same server at the same time... Or of course, if there are other ideas -- I'd welcome them all at this early stage of development. Kind regards Leon. |
|
From: leon z. <leo...@gm...> - 2010-05-27 08:57:33
|
On 5/27/10, leon zadorin <leo...@gm...> wrote: > I would, ideally, like to have a server which would support, > concurrently, 2 different certs (each signed with a different [...] > Would this be possible (in boost::asio::ssl) ? For instance, given something like: http://www.madboa.com/geek/openssl/ " This example will produce a file called mycert.pem which will contain both the private key and the public certificate based on it. [...] openssl req \ -x509 -nodes -days 365 \ -newkey rsa:1024 -keyout mycert.pem -out mycert.pem " Would it be possible to use a call such as (or similar): ssl.use_certificate_chain_file(xyz.pem); with the xyz.pem file having 2 tuples of the private key and the cert? ... and then discard the need to call ssl.use_private_key_file ...? :-) I am a noob w.r.t. asio/ssl |
|
From: Juraj I. <jur...@gm...> - 2010-05-27 13:58:53
|
On 27.5.2010 10:57, leon zadorin wrote: > On 5/27/10, leon zadorin<leo...@gm...> wrote: > >> I would, ideally, like to have a server which would support, >> concurrently, 2 different certs (each signed with a different > [...] >> Would this be possible (in boost::asio::ssl) ? OpenSSL which ASIO uses is very flexible with certificates. E.g. it is possible to configure your SSL server to use certificate signed by CA1 and allows only client certificates from CA2 and CA3. By default - client certificate is not needed for establishing SSL - only server certificate and private key are needed. These are set in ASIO using boost::asio::ssl::context::use_certificate_file and boost::asio::ssl::context::use_private_key_file. In case you want to verify client certificates you should call boost::asio::ssl::context::set_verify_mode with appropriate parameters (e.g. boost::asio::ssl::context::verify_peer | boost::asio::ssl::context::verify_fail_if_no_peer_cert ) To set which certificates are allowed by the server you should use either boost::asio::ssl::context::load_verify_file() or boost::asio::ssl::context::add_verify_path(). These are actually simple wrappers for OpenSSL function: SSL_CTX_load_verify_locations(). This function allows you to set any number of CA certificates which are trusted(allowed) by your server. More detailed description can be found here: http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html HTH |
|
From: leon z. <leo...@gm...> - 2010-05-28 04:17:06
|
On 5/27/10, Juraj Ivančić <jur...@gm...> wrote: > On 27.5.2010 10:57, leon zadorin wrote: >> On 5/27/10, leon zadorin<leo...@gm...> wrote: >> >>> I would, ideally, like to have a server which would support, >>> concurrently, 2 different certs (each signed with a different >> [...] >>> Would this be possible (in boost::asio::ssl) ? > > OpenSSL which ASIO uses is very flexible with certificates. E.g. it is > possible to configure your SSL server to use certificate signed by CA1 > and allows only client certificates from CA2 and CA3. > > By default - client certificate is not needed for establishing SSL - > only server certificate and private key are needed. These are set in > ASIO using > boost::asio::ssl::context::use_certificate_file and > boost::asio::ssl::context::use_private_key_file. Yes -- but I wasn't really asking about client certificates (I'm sorry if this was not 100% clear in my previous explanations), I was rather asking about a server having *multiple* *server* self-signed certificates (i.e. 2, each signed with a different private key) and clients connecting to server using any of the multiple "server" certificates (to validate the target server)... for the reasons outlined in the 1st post. So, for example, there are 2 clients -- each has stored a server's certificate (to connect to server and to validate that it is indeed connecting to the valid server)... The problem is that the server wants to update *it's* self-signed certificate (and clients have the capacity to automatically download the server's updated/new self-signed certificate to the client-side securely and then restart/reconnect with the newly downloaded server certificate)... but some clients may not come online for a while (let's say 3 days), whilst other clients are online now (so they will connect and upgrade to use the new server certificate) but may go offline later on. Then in a couple of days time we have a situation where some clients will be validating their connection to the server using server's new certificate and some clients will be trying to validate their connection to server using server's old certificate... So, essentially, I'd like to have a server which will support 2 certificates to allow for older clients to connect and upgrade (like a transition time-window) in a sense of the server being able to be *validated by clients* via 2 different certificates. I'd like to see if this (as opposed to other alternatives such as running a second instance of the server or using a paid-for certificate as opposed to self-signed ones thusly delegating the issue elsewhere) is possible in boost::asio for the reasons outlined in my 1st post. Kind regards Leon. > In case you want to verify client certificates you should call > boost::asio::ssl::context::set_verify_mode > with appropriate parameters (e.g. > boost::asio::ssl::context::verify_peer | > boost::asio::ssl::context::verify_fail_if_no_peer_cert ) I think it's the other way around -- there is 1 entity (server) which is *being verified* and many entities (clients) which *are doing the verifying* but via different self-signed certificates (each certificate nevertheless relating to the same *being verified* entity -- the server)... > More detailed description can be found here: > > http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html I'll dig around there... hopefully it is of relevance to the subject at hand... thanks for the pointers. Kind regards Leon. |
|
From: Juraj I. <jur...@gm...> - 2010-05-28 07:37:34
|
On 28.5.2010 6:16, leon zadorin wrote: > Yes -- but I wasn't really asking about client certificates (I'm sorry > if this was not 100% clear in my previous explanations), I was rather > asking about a server having *multiple* *server* self-signed > certificates (i.e. 2, each signed with a different private key) and > clients connecting to server using any of the multiple "server" > certificates (to validate the target server)... for the reasons > outlined in the 1st post. Sorry, after reading your initial post again - you were clear enough. OpenSSL mailing list would definitely be a better place to ask this question. I did however look around OpenSSL API and failed to find anything to allow multiple server certificates. I'm pretty sure that only one server certificate/private key is allowed per SSL handshake. In case it cannot be done - you can alway try multiple SSL handshakes with the client using different certificates and private keys until one of them succeeds. Or you could try implementing some sort of pre-handshake on plain TCP where you could negotiate CA certificate for the SSL. This is, of course, under assumption that you are designing this protocol. |
|
From: Christopher K. <ch...@ko...> - 2010-05-31 10:23:59
|
leon zadorin wrote: > I'd like to see if this (as opposed to other alternatives such as > running a second instance of the server or using a paid-for > certificate as opposed to self-signed ones thusly delegating the issue > elsewhere) is possible in boost::asio for the reasons outlined in my > 1st post. Asio lets you access the undlerying openssl data structures (SSL*, SSL_CTX*) via the impl() member functions. If you can find a way to do it with openssl directly then it should (in theory) be possible with Asio too. Cheers, Chris |