On Wed, May 08, 2019 at 04:40:07PM -0400, Michael Richardson wrote: > > Viktor Dukhovni <openssl-users@xxxxxxxxxxxx> wrote: > >> Diversionary issue: > >> https://www.openssl.org/docs/manmaster/man3/SSL_set_tlsext_host_name.html > >> and: > >> https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_client_hello_cb.html > >> > >> are pretty vague. I think that SSL_set_tlsext_host_name() is probably > >> intended to be used on the client to set the SNI, but I'm not sure. > > > Yes, e.g. in the Postfix TLS client: > > > https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_client.c#L1035-L1045 > > So, okay. > Either this URL can go into the man page, or some short code extract could go in. Probably better to have a code snippet (filing a github issue or sending a pull request would probably be good). > >> The legacy cb function returns int, but it's values are not > >> documented. > > > On the server side I'm using SSL_CTX_set_tlsext_servername_callback(): > > > https://github.com/vdukhovni/postfix/blob/2399e9e179ee025d03155fa3637cccab0a23ddce/postfix/src/tls/tls_misc.c#L1040-L1043 > > https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_misc.c#L668 > > >> I guess the point is that CB can set the server certificate to > >> something appropriate, or I think, it could just decide to ignore the > >> SNI value completely and force the certificate regardless. > > > Yes. > > I can see that the CB provides comprehensive functionality, but I worry about > applications trying to parse ClientHello extensions themselves and getting it wrong. It turns out that the server_name TLS extension is something of an unfortunate exception in terms of the unneeded complexity in its encoding. When I wrote the client_hello_cb functionality (at the time, know as the early_cb), I thought about whether I wanted to add a dedicated API just for the SNI value, due to the level of complexity involved. I ended up not doing so in the initial submission, both because I figured it could safely be added later as an incremental change, and because I was worried (IIRC) about being tempted to expose some of the PACKET_* APIs in the process, which is not really the right architectural choice for OpenSSL. There is, however, an existing implementation for extracting the SNI value in the test code at https://github.com/openssl/openssl/blob/master/test/handshake_helper.c#L150-L187 that has been successfully extracted and used in a couple places I know of. > >> What is the SNI functionality otherwise on the server? > > > You can interpose a secondary "virtual-host-specific" SSL_CTX for for > > the rest of the handshake. This carries the server certificate, but > > also the trust store settings for validating client certificates, the > > settings to request (or not) client certificates, the verification > > callbacks, ... It is a rather heavyweight object, best cached and > > re-used for multiple connections. > > So, it's okay to change the SSL_CTX for an SSL* after creation. > That is rather surprising to me, but I guess it's okay. > I suppose I feel that there ought to be reference counts, but this is C, not Rust. There *are* reference counts. > > In Postfix, it is configured with the same settings as the initial > > SSL_CTX, *but* no server certificates. During the SNI callback I > > interpose the certificate-less context, and then set the certificate > > chain on the connection handle (SSL *) instead. > > okay, I'll use Postfix as my reference :-) For "how to use and switch SSL_CTXs" I'm sure it's admirable, but my understanding is that it's still using the legacy server_name callback (as opposed to the new client_hello_cb), and the new callback has a lot of advantages for architectural cleanliness and avoiding some surprising behavior with respect to the ordering of certain processing in the server. So for a greenfield application I'd still suggest using the client_hello_cb (not that I'm entirely unbiased...). -Ben > >> Is there any support for picking a certificate based upon the SNI > >> name? > > > The application does the "picking"... The application sets one or more > > certificate chains (one per supported public key algorithm) that best > > match the SNI name, and then OpenSSL chooses one of these based on the > > client's advertised supported signature algorithms, ... > > What I was observing (wrongly) was that maybe the server was doing something > itself if there was no callback, and it was failing. This was from looking > at the code around the error code that came out. > This (see other email) proved to wildly incorrect. > > -- > ] Never tell me the odds! | ipv6 mesh networks [ > ] Michael Richardson, Sandelman Software Works | IoT architect [ > ] mcr@xxxxxxxxxxxx http://www.sandelman.ca/ | ruby on rails [ > >