[openssl-users] DTLS over UDP

Michael Richardson mcr at sandelman.ca
Mon Feb 19 18:43:08 UTC 2018

Nivedita <maddi.nivedita at gmail.com> wrote:
    >> Nivedita <maddi.nivedita at gmail.com> wrote:
    >>> I am trying to establish DTLS over UDP connection by using
    >>> DTLSv1_listen method .
    >>> I have followed the below steps - 1. Created a server socket
    >>> and using
    >>> this socket created bio and ssl object. bio =
    >>> BIO_new_dgram(VI_sock,BIO_NOCLOSE)) SSL_set_bio
    >>> (ssl,VP_bio,VP_bio);
    >>> 2. Enable cookie exchange on SSL object. SSL_set_options(ssl,
    >>> 3. Then started listening using dtlsv1_listen for the new
    >>> client
    >>> connections. Once dtlsv1_listen is successful and i got the
    >>> peer
    >>> address.
    mcr> okay.

    >> Nivedita- All the above mentioned steps i am doing on server
    >> side . On the
    >> client side i have already initiated ssl_connect.
    >> On the server side when i am listening using dtlsv1_listen
    >> method -
    >>> 4. Once i got the peer address , i am creating one more socket
    >>> 5. With the new socket i tried to connect to peer address.
    > Then once i got the client address from the dtlsv1_listen method,
    > i am creating one more socket and trying to connect to this client
    > address.

I think that I see what is wrong with your flow... you haven't taken the
packet off the original socket, so SSL_accept is still looking for it.

The flow is supposed to be:
    1) client sends ClientHello
    2) DTLSv1_listen() sees it, and sends a HelloVerifyRequest
       (I assume you have filled in the cookie callbacks. I think that
       perhaps there should be good cryptographic defaults available in
       the library.  Maybe there are, and I'm ignorant of them)
    3) Client sends ClientHello w/cookie.
       DTLSv1_listen() then sees that and tweaks the SSL* to indicate that
       the cookie has been accepted.  Note that the packet is *LEFT*
       on the incoming socket so that SSL_accept() can process it.
       This is one the places where the DTLSv1_listen() API is rather
       hard to use in my opinion.

    4) You make up new sockets, etc.
    5) But, you need to call SSL_accept() once with the **old socket** to
       process packet that listen() left on it, and then you can switch the
       FD over!  Of course, you probably want to make sure that SSL_accept()
       sends the reply correctly.

What I do in my proposed DTLSv1_accept() API is that I move the data
From the incoming socket to the new BIO's incoming queue:

    /* At this point, there is a real ClientHello in serv->init_buf */
    memcpy(rb->buf, serv->init_buf->data, serv->init_num);
    rb->offset = 0;
    rb->left   = serv->init_num;

and then remove the packet from the incoming socket.  The situation is
then returned like this so that the new sockets can be setup, but the
incoming SSL_accept() BIO is stuffed with the correct (cookie-full)
ClientHello, and replies will go to the right place with the right source
address.  I hope to get these patches accepted for the March 11 freeze,
but you might not want to depend upon it.

]               Never tell me the odds!                 | ipv6 mesh networks [ 
]   Michael Richardson, Sandelman Software Works        | network architect  [ 
]     mcr at sandelman.ca  http://www.sandelman.ca/        |   ruby on rails    [ 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 487 bytes
Desc: not available
URL: <http://mta.openssl.org/pipermail/openssl-users/attachments/20180219/f8a78d4d/attachment-0001.sig>

More information about the openssl-users mailing list