Am 08.02.2016 um 13:34 schrieb Matt Caswell:
On 08/02/16 12:11, Rainer Jung wrote:
I'm adding support for OpenSSL 1.1.0 to the Apache web server.

I struggle to migrate the renegotiation code in the case wehere we want
the client to send a client cert. The current code works like explained in

   http://www.linuxjournal.com/node/5487/print

After using SSL_set_verify() it calls

   SSL_renegotiate(ssl);
   SSL_do_handshake(ssl);
   SSL_set_state(ssl, SSL_ST_ACCEPT);
   SSL_do_handshake(ssl);

for reasons given in the article.

The new 1.1.0 API no longer allows to set the state using
SSL_set_state(). The old article states, that calling
SSL_set_accept_state() is not the right thing to do. Looking at
s_server.c doesn't give a hint what to do instead, because it looks like
it reads the client certs just raw from the socket.

Any hint what would replace the above sequence or at least the
SSL_set_state(ssl, SSL_ST_ACCEPT)?

Thanks a bunch and regards,

Renegotiation isn't entirely within the control of the server. A server
can request that a renegotiation takes place. It is up to the client
whether it honours that request immediately; or perhaps its finishes off
sending some application data before it gets around to honouring it; or
perhaps it doesn't honour it at all.

   SSL_renegotiate(ssl);
   SSL_do_handshake(ssl);

This sequence makes the server send the HelloVerifyRequest. It is then
back in a state where it can continue to receive application data from
the client. At some later point the client may or may not initiate a reneg.

   SSL_set_state(ssl, SSL_ST_ACCEPT);
   SSL_do_handshake(ssl);

This is really not a good idea, and I suspect is a hack that was
originally copied from s_server :-). Doing this will make the connection
fail if the client sends application data next (which it is allowed to do).

We don't know what we're going to get next from the client it could be
more application data. It could be an immediate start of a new
handshake. The correct thing for the server to do is to attempt to read
application data. If we happen to get a handshake instead then it will
be automatically handled.

OK, tried it and it partially works. More precisely: when the cipher is AES128-SHA it works, bur for ECDHE-RSA-AES128-SHA256 I run into an error in tls_construct_server_key_exchange() (file statem/statem_srvr.c).

The following conditions triggers the jump to err:

   1773     if (type & (SSL_kECDHE | SSL_kECDHEPSK)) {
   1774         int nid;
   1775
   1776         if (s->s3->tmp.pkey != NULL) {
   1777             SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
   1778                    ERR_R_INTERNAL_ERROR);
   1779             goto err;
   1780         }

By comparing the communication for the two ciphers I see the following flow:

write 69/69 bytes
SSLv3/TLS write hello request
- try to read app data -> I/O error, 5 bytes expected to read
read 5/5 bytes
read 576/576
Handshake: start
before SSL initialization
before SSL initialization
SSLv3/TLS read client hello
write 149/149
SSLv3/TLS write server hello
write 2021/2021
SSLv3/TLS write certificate

And here for the ECDHE case the error triggered by the above check.

In the AES case we proceed

write 1173/1173
SSLv3/TLS write certificate request
write 69/69 bytes
write 3412/3412 bytes
SSLv3/TLS write server done
error in SSLv3/TLS write server done
read 5/5 bytes
read 1952/1952
SSLv3/TLS write server done
Successful client certificate verification

Any idea how to clear s->s3->tmp.pkey so that the check doesn't trigger?

I see SSL_clear() but from its description I doubt that is should be used here.

Regards,

Rainer
--
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

Reply via email to