tl;dr: I've been looking into an issue in my product (uses DTLS) for the last couple of days. Tracked it down to a CHANGE_CIPHER_SPEC being processed too early causing the handshake to never complete.
Details: - OpenSSL version 1.0.1c - Brackets indicate a single datagram packet. (1) Client: send [SSL3_MT_CLIENT_HELLO] (2) Server: send [SSL3_MT_SERVER_HELLO, SSL3_MT_CERTIFICATE, SSL3_MT_CERTIFICATE_REQUEST, SSL3_MT_SERVER_DONE] (3) Client: send [SSL3_MT_CERTIFICATE, SSL3_MT_CLIENT_KEY_EXCHANGE, SSL3_MT_CERTIFICATE_VERIFY, *CHANGE_CIPHER*, SSL3_MT_FINISHED] Client packet (3) is lost. Oh noes! Other stuff happens, but Client eventually resends each message in its own datagram this time: (4) Client: send [SSL3_MT_CERTIFICATE] (5) Client: send [SSL3_MT_CLIENT_KEY_EXCHANGE] (6) Client: send [SSL3_MT_CERTIFICATE_VERIFY] (7) Client: send [*CHANGE_CIPHER*] (8) Client: send [SSL3_MT_FINISHED] Now, one of the following thing happens: a) packet (6) is lost or, in my case, packet (7) arrives before (6). Unfortunately, when Server processes packet (7) it changes the cypher spec before the handshake is over. When (6) finally arrives, it's dropped by dtls1_read_bytes. Subsequent re-sends from Client are also ignored. Without having read any spec, and with my limited knowledge of the OpenSSL codebase, my naive interpretation is that the problem is caused by dtls1_accept setting change_cipher_spec_ok on SSL3_ST_SR_CERT_VRFY_* states. Commenting out that line definitely seems to fix the problem for me. Is this really the bug, or does that line plays a role in a different scenario? Cheers, -dan