Hi, I recently tried to refactor the TLS related code of my server application and wanted to use a SSL-BIO instead of performing all SSL-read/-write-operations by hand. As cipher suite I use ADH-AES256-SHA, because no authentication of the peers is needed and a man-in-the-middle-attack is highly unlikely in my setup. My problem is know that with the new code the handshake fails most of the time (but works on like every 10th retry). For establishing a new TLS-connection my code looked like this:
SSL *ssl_handle = NULL; bool retry_accept = true; bool ssl_want_read = false; bool ssl_want_write = false; bool can_read = false; bool can_write = false; int ssl_return = 0; tls_handle_t *tls_handle = NULL; if (!global_ssl_context) { print_SSL_error("TLS accept: SSL context not initialized. SSL accept failed."); return TLS_EINIT; } if (!h->sfd) { print_SSL_error("TLS accept: Bad socket file descriptor."); return TLS_EINVAL; } if (!(socket_bio = BIO_new_socket((int) h->sfd, BIO_NOCLOSE))) { print_SSL_error("TLS accept: Failed to create socket-BIO object."); return TLS_EGENER; } ssl_handle = SSL_new(global_ssl_context); SSL_set_bio(ssl_handle, socket_bio, socket_bio); tls_handle = calloc(1, sizeof(tls_handle_t)); tls_handle->con_handle = ssl_handle; do { if (ssl_want_read) { rttTmsTLSSelect(tls_handle, &can_read, NULL, true); ssl_want_read = false; } else if (ssl_want_write) { rttTmsTLSSelect(tls_handle, NULL, &can_write, true); ssl_want_write = false; } ssl_return = SSL_accept(tls_handle->con_handle); switch (SSL_get_error(tls_handle->con_handle, ssl_return)) { case SSL_ERROR_WANT_READ: ssl_want_read = true; break; case SSL_ERROR_WANT_WRITE: ssl_want_write = true; break; default: retry_accept = false; } } while (ssl_return <= 0 && retry_accept); This worked reliably. My new code looks like this: BIO *socket_bio = NULL; BIO *ssl_bio = NULL; BIO *buffer_bio = NULL; tls_handle_t *tls_handle = NULL; if (!global_ssl_context) { print_SSL_error("TLS accept: SSL context not initialized. SSL accept failed."); return TLS_EINIT; } if (!h->sfd) { print_SSL_error("TLS accept: Bad socket file descriptor."); return TLS_EINVAL; } if (!(socket_bio = BIO_new_socket((int) h->sfd, BIO_NOCLOSE))) { print_SSL_error("TLS accept: Failed to create socket-BIO object."); return TLS_EGENER; } /* if (!(ssl_bio = BIO_new_ssl(global_ssl_context, 0))) { print_SSL_error("TLS_accept: Failed to create SSL-BIO object"); BIO_free_all(socket_bio); return TLS_EGENER; } // Append the socket-BIO to the SSL-BIO ssl_bio = BIO_push(ssl_bio, socket_bio); if (!(buffer_bio = BIO_new(BIO_f_buffer()))) { print_SSL_error("TLS_accept: Failed to create buffer-BIO object"); BIO_free_all(ssl_bio); return TLS_EGENER; } // Prepend the buffer-BIO to the SSL-BIO ssl_bio = BIO_push(buffer_bio, ssl_bio); if (BIO_do_handshake(ssl_bio) <= 0) { print_SSL_error("TLS accept: Handshake failed"); return TLS_EGENER; } tls_handle = calloc(1, sizeof(tls_handle_t)); tls_handle->ssl_bio = ssl_bio; BIO_get_ssl(tls_handle->ssl_bio, &(tls_handle->con_handle)); My global SSL-context object is initialized like if (!(tls_context = SSL_CTX_new(TLSv1_method()))) { print_SSL_error("TLS error while creating context object."); return TLS_EINIT; } SSL_CTX_set_mode(tls_context, SSL_MODE_AUTO_RETRY); if (!SSL_CTX_set_cipher_list(tls_context, "ADH-AES256-SHA")) { print_SSL_error("TLS error while setting cipher list"); return TLS_EGENER; } global_use_ssl = true; global_ssl_context = tls_context; The s_client test-application delivers the following output: > openssl s_client -cipher "ADH-AES256-SHA" -connect localhost:9111 -state -msg -tls1 CONNECTED(00000003) SSL_connect:before/connect initialization >>> TLS 1.0 Handshake [length 0036], ClientHello 01 00 00 32 03 01 4d 91 11 d5 4b 61 48 50 5b 27 b8 a2 3b d0 ea d9 53 3d 28 78 70 d7 fa 28 0e 96 d7 3a 5c eb 99 dc 00 00 04 00 3a 00 ff 02 01 00 00 04 00 23 00 00 SSL_connect:SSLv3 write client hello A <<< TLS 1.0 Handshake [length 0035], ServerHello 02 00 00 31 03 01 4d 91 11 d5 5e 5f c9 5c 08 05 27 44 8c 47 3d 44 36 fe cc a7 12 de e9 c2 e5 c3 31 91 61 bc 07 9a 00 00 3a 01 00 09 ff 01 00 01 00 00 23 00 00 SSL_connect:SSLv3 read server hello A <<< TLS 1.0 Handshake [length 002b], ServerKeyExchange 0c 00 00 27 00 10 f3 0a 17 a4 aa 28 63 71 4d 57 2b 0e 66 c3 99 23 00 01 05 00 10 46 e1 f7 72 24 39 22 11 1c f1 48 7c 04 f0 70 7d SSL_connect:SSLv3 read server key exchange A <<< TLS 1.0 Handshake [length 0004], ServerHelloDone 0e 00 00 00 SSL_connect:SSLv3 read server done A >>> TLS 1.0 Handshake [length 0016], ClientKeyExchange 10 00 00 12 00 10 b2 e7 1c e0 8c f9 49 67 2a eb 1a f2 ce de e0 9c SSL_connect:SSLv3 write client key exchange A >>> TLS 1.0 ChangeCipherSpec [length 0001] 01 SSL_connect:SSLv3 write change cipher spec A >>> TLS 1.0 Handshake [length 0010], Finished 14 00 00 0c d2 53 c4 44 4a 1d 11 9c ee d4 f1 6a SSL_connect:SSLv3 write finished A SSL_connect:SSLv3 flush data SSL_connect:failed in SSLv3 read server session ticket A 3074487944:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:590: --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 115 bytes and written 86 bytes --- New, TLSv1/SSLv3, Cipher is ADH-AES256-SHA Secure Renegotiation IS supported Compression: zlib compression Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : ADH-AES256-SHA Session-ID: Session-ID-ctx: Master-Key: A56F57324F1757E4FA5368610DA95D302BFFF94BE392850E8895D477D3C5E63C7AA947F6C613F599C4DDAC7390512A88 Key-Arg : None PSK identity: None PSK identity hint: None Compression: 1 (zlib compression) Start Time: 1301352917 Timeout : 7200 (sec) Verify return code: 0 (ok) One observation that I made is that with a correct handshake the number of sent/received data is SSL handshake has read 349 bytes and written 145 bytes whereas in the above output the transmitted data is much less. Does anyone have a suggestion how to fix the code using the SSL-BIO approach? Any hints would be appreciated. Regards, Martin ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org