[openssl-users] Authentication over ECDHE
Christian
c.wehrmeyer at freshlions.de
Fri Dec 28 10:22:23 UTC 2018
Thank you for the suggestions thus far. I've been working on a simple
SSL client/server system in the last couple days. Unfortunately the SSL
documentation is a right mess, so I don't know what is allowed and what
is not, which leads to some problems that I don't know exactly how to
tackle on.
First of all, I opted out for the cipher "ECDHE-PSK-AES128-CBC-SHA256".
As Matt suggested, using PSKs does reduce a lot of complexity in this
scenario - if I've been understanding him correctly, this cipher should
give us forward secrecy while still relying on a pre-shared key, which
also authenticates both sides to each other. When I run my server, and
then run my client, it receives the data the server sends without any
problems.
However, things start to get messy once the keys mismatch, as would in
any attacker scenario. The client initiates the handshake, but on the
server side SSL_accept() returns -1, the client receives no data (as
should). Then I start the client *again*. On the server side
SSL_accept() returns -1 again, but this time the client blocks in
SSL_read() (I haven't not implemented timeout handling yet, as this
still all runs on my testing environments). It's almost as if
SSL_shutdown on the server side does not notify the client that the
connection is to be closed.
For the BIO object on the server side I'm using a permanent BIO object
which I just call BIO_set_fd() upon to set the socket I receive from
accept(). The call chain looks like this:
===================
First connection, client closes connection as excepted.
===================
BIO_set_fd with 4|1 #Socket 4, BIO_CLOSE
SSL_set_accept_state
SSL_accept
SSL_accept returned with -1
SSL_shutdown
SSL_clear
===================
Second connection, client suddenly blocks, has to be interrupted
with CTRL + C.
===================
BIO_set_fd with 5|1 #Socket 5, BIO_CLOSE
SSL_set_accept_state
SSL_accept
SSL_accept returned with -1
SSL_shutdown
SSL_clear
===================
Third connection, client blocks again, has to be interrupted again.
===================
BIO_set_fd with 4|1
SSL_set_accept_state
SSL_accept
SSL_accept returned with -1
SSL_shutdown
SSL_clear
What am I doing wrong on the server side? I assume it's the server; the
client process ends right after the connection attempt, and it's the
server that keeps running. And once I reset the server the first
connection closes properly again. Am I supposed to use a new BIO object
for each incoming connection? If so, that's pretty dumb. You usually
want to have your accept() loop to be free of as much code as possible,
and setting up everything in advance during server startup. The current
server code for setting up the SSL object and using it looks like this:
> if(NULL == (bio = BIO_new_socket(0,BIO_NOCLOSE))) /*Socket doesn't
really matter, we're gonna reset this soon enough.*/
> {
> goto LABEL_END_NO_BIO;
> }
>
> if(NULL == (ssl = SSL_new(ssl_ctx)))
> {
> BIO_free(bio);
> goto LABEL_END_NO_SSL;
> }
>
> SSL_clear(ssl);
> SSL_set_bio(ssl,bio,bio);
>
> tmp = 1;
> setsockopt
> (
> socket_server,
> SOL_SOCKET,
> SO_REUSEADDR,
> &tmp,
> sizeof(tmp)
> );
>
> if(-1 == bind
> (
> socket_server,
> (struct sockaddr*)&sin_server,
> sizeof(sin_server)
> ))
> {
> fprintf(stderr,"Can't bind socket.\n");
> goto LABEL_END;
> }
>
> if(-1 == listen(socket_server,1))
> goto LABEL_END;
>
> while(0 <= (socket_client = accept
> (
> socket_server,
> (struct sockaddr*)&sin_client,
> &sin_client_length
> )))
> {
> fprintf(stderr,"BIO_set_fd with
%u|%u\n",socket_client,BIO_CLOSE);
> BIO_set_fd(bio,socket_client,BIO_CLOSE);
> fprintf(stderr,"SSL_set_accept_state\n");
> SSL_set_accept_state(ssl);
> fprintf(stderr,"SSL_accept\n");
> tmp = SSL_accept(ssl);
> if(tmp != 1)
> {
> fprintf(stderr,"SSL_accept returned with %i\n",tmp);
> goto LABEL_NEXT_CLIENT;
> }
>
> fprintf(stderr,"SSL_write\n");
> SSL_write(ssl,"That is my string",sizeof("That is my string")
- 1);
>
> LABEL_NEXT_CLIENT:
> fprintf(stderr,"SSL_shutdown\n");
> SSL_shutdown(ssl);
> fprintf(stderr,"SSL_clear\n");
> SSL_clear(ssl);
> }
>
> /*Rest of cleanup, doesn't matter, this is hopefully never reached.*/
Thank you for your continued help.
More information about the openssl-users
mailing list