RE: SSL_read() seems to close my connection
I've not been through your code properly, but this line grabbed my eye as I skimmed over it: > len = SSL_read(ctx->ssl, buffer + buf_offset, sizeof(BUFFER_SIZE) - buf_offset); You don't show the definition of BUFFER_SIZE anywhere, but sizeof(BUFFER_SIZE) is likely to be 4 or 8 or similar; are you sure that's what you mean? Regards, jjf > From: Mario [mailto:m...@kernelobjects.org] > > I have an issue with a try of my implementation of a secure > communication software. > > I´m compiling everything on Debian 6.0.7 (openssl 0.9.8o-4squeeze14 and > its dev package). > > For the application I´m dealing with non-blocking IO for the socket. I > can communicate a few bytes between server and client. However when my > server answers too much, the conneciton will be closed for both sides > when I try to read (SSL_read() returns 0 and the SSL-Error is 5 but the > systems errno is 0 all the time). The last SSL_write will always return > the amount of bytes I have to send, but ins this setup only 4 Bytes are > transmitted to the client. I case I send more than those 4 Bytes the > connection will be closed as described. > > Here is my SSL relevant code of my server part: > --- SNIP > /* setup our crypto environment */ > SSL_load_error_strings(); > SSL_library_init(); > OpenSSL_add_all_ciphers(); > if((ctx->ssl_ctx = SSL_CTX_new(TLSv1_server_method())) == NULL) { >tproxy_error_die("unable to initialize SSLv3 methods", 1); > } > SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_ALL); > SSL_CTX_set_timeout(ctx->ssl_ctx, 300); > if(!SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, ctx->cert_bundle)) > { >tproxy_error_die("unable to read certificate bundle file", 1); > } > if(strlen(ctx->key_file_pw)) { >SSL_CTX_set_default_passwd_cb(ctx->ssl_ctx, > private_key_pass_callback); >SSL_CTX_set_default_passwd_cb_userdata(ctx->ssl_ctx, (void *)ctx); > } > if(!SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx, ctx->key_file, > SSL_FILETYPE_PEM)) { >tproxy_error_die("unable to read key file", 1); > } > SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_NONE, NULL); > SSL_CTX_set_info_callback(ctx->ssl_ctx, apps_ssl_info_callback); > [...] > con->sock = accept(ctx->socket[i], (struct sockaddr *)&in_socket, > &s_size); > /* make the accepted socket non-blocking */ > if(ioctl(con->sock, FIONBIO, (char *)&enable) < 0) { >tproxy_error_die("cannot set socket flags", 1); > } > /* create a new SSL context to handle the connection with the peer */ > con->ssl = SSL_new(ctx->ssl_ctx); > SSL_set_mode(con->ssl, SSL_MODE_AUTO_RETRY | > SSL_MODE_ENABLE_PARTIAL_WRITE); > > /* complete ssl connection */ > con->sbio = BIO_new_socket(con->sock, BIO_NOCLOSE); > SSL_set_bio(con->ssl, con->sbio, con->sbio); > /* set chipher */ > if (SSL_set_cipher_list(con->ssl,"AES128-SHA") <= 0) { >tproxy_error_die("unable to set chipher", 1); > } > /* do not require a valid client certificate */ > SSL_set_verify(con->ssl, SSL_VERIFY_NONE, NULL); > add_connection(ctx, con); > [...] > > /* later in the connection worker thread */ > > [...] > while(cur) { > switch(cur->state) { > case CSTATE_SSL_HANDSHAKE: >/* wait for the client to accept */ >if(1 != SSL_accept(cur->ssl)) { > if(SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_READ && > SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_WRITE) { >/* an SSL error occured */ >cur->state = CSTATE_TERMINATING; > } >} else { > cur->state = CSTATE_T_SETUP; >} >break; > case CSTATE_T_SETUP: >len = SSL_read(cur->ssl, cur->data + cur->data_offset, > TPROXY_BUFFER_SIZE - cur->data_offset); >if(len > 0) { > cur->data_offset += len; >} else if(len == 0){ > cur->state = CSTATE_TERMINATING; >} else { > if(SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_READ && > SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_WRITE) { >cur->state = CSTATE_TERMINATING; > } else { >if(cur->data_offset) { > [... do something with the data for application handshake...] > } >} >break; > case CSTATE_CONNECTED: >if(SSL_want(cur->ssl) == SSL_NOTHING) { > [...] check if something is in the pipe to send [...] > if(proto_data->len != SSL_write(cur->ssl, proto_data, > proto_data->len)) { >[...handle the partial send (never notices)...] > } >} >len = SSL_read(cur->ssl, cur->data + cur->data_offset, > TPROXY_BUFFER_SIZE - cur->data_offset); >if(len > 0) { > cur->data_offset += len; >} else if(len == 0){ > [...here is the actual error I´m talking about...] >} else { > if(SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_READ && > SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_WRITE) { >cur->state = CSTATE_TERMINATING; > } else { >if(cur->data_offset) { > [... do something with the data for application ...] > } >} >break; > [...] > SNIP > > I guess there was nothing special about it. The client is almo
SSL_read() seems to close my connection
Hi, I have an issue with a try of my implementation of a secure communication software. I´m compiling everything on Debian 6.0.7 (openssl 0.9.8o-4squeeze14 and its dev package). For the application I´m dealing with non-blocking IO for the socket. I can communicate a few bytes between server and client. However when my server answers too much, the conneciton will be closed for both sides when I try to read (SSL_read() returns 0 and the SSL-Error is 5 but the systems errno is 0 all the time). The last SSL_write will always return the amount of bytes I have to send, but ins this setup only 4 Bytes are transmitted to the client. I case I send more than those 4 Bytes the connection will be closed as described. Here is my SSL relevant code of my server part: --- SNIP /* setup our crypto environment */ SSL_load_error_strings(); SSL_library_init(); OpenSSL_add_all_ciphers(); if((ctx->ssl_ctx = SSL_CTX_new(TLSv1_server_method())) == NULL) { tproxy_error_die("unable to initialize SSLv3 methods", 1); } SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_ALL); SSL_CTX_set_timeout(ctx->ssl_ctx, 300); if(!SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, ctx->cert_bundle)) { tproxy_error_die("unable to read certificate bundle file", 1); } if(strlen(ctx->key_file_pw)) { SSL_CTX_set_default_passwd_cb(ctx->ssl_ctx, private_key_pass_callback); SSL_CTX_set_default_passwd_cb_userdata(ctx->ssl_ctx, (void *)ctx); } if(!SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx, ctx->key_file, SSL_FILETYPE_PEM)) { tproxy_error_die("unable to read key file", 1); } SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_NONE, NULL); SSL_CTX_set_info_callback(ctx->ssl_ctx, apps_ssl_info_callback); [...] con->sock = accept(ctx->socket[i], (struct sockaddr *)&in_socket, &s_size); /* make the accepted socket non-blocking */ if(ioctl(con->sock, FIONBIO, (char *)&enable) < 0) { tproxy_error_die("cannot set socket flags", 1); } /* create a new SSL context to handle the connection with the peer */ con->ssl = SSL_new(ctx->ssl_ctx); SSL_set_mode(con->ssl, SSL_MODE_AUTO_RETRY | SSL_MODE_ENABLE_PARTIAL_WRITE); /* complete ssl connection */ con->sbio = BIO_new_socket(con->sock, BIO_NOCLOSE); SSL_set_bio(con->ssl, con->sbio, con->sbio); /* set chipher */ if (SSL_set_cipher_list(con->ssl,"AES128-SHA") <= 0) { tproxy_error_die("unable to set chipher", 1); } /* do not require a valid client certificate */ SSL_set_verify(con->ssl, SSL_VERIFY_NONE, NULL); add_connection(ctx, con); [...] /* later in the connection worker thread */ [...] while(cur) { switch(cur->state) { case CSTATE_SSL_HANDSHAKE: /* wait for the client to accept */ if(1 != SSL_accept(cur->ssl)) { if(SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_READ && SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_WRITE) { /* an SSL error occured */ cur->state = CSTATE_TERMINATING; } } else { cur->state = CSTATE_T_SETUP; } break; case CSTATE_T_SETUP: len = SSL_read(cur->ssl, cur->data + cur->data_offset, TPROXY_BUFFER_SIZE - cur->data_offset); if(len > 0) { cur->data_offset += len; } else if(len == 0){ cur->state = CSTATE_TERMINATING; } else { if(SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_READ && SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_WRITE) { cur->state = CSTATE_TERMINATING; } else { if(cur->data_offset) { [... do something with the data for application handshake...] } } break; case CSTATE_CONNECTED: if(SSL_want(cur->ssl) == SSL_NOTHING) { [...] check if something is in the pipe to send [...] if(proto_data->len != SSL_write(cur->ssl, proto_data, proto_data->len)) { [...handle the partial send (never notices)...] } } len = SSL_read(cur->ssl, cur->data + cur->data_offset, TPROXY_BUFFER_SIZE - cur->data_offset); if(len > 0) { cur->data_offset += len; } else if(len == 0){ [...here is the actual error I´m talking about...] } else { if(SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_READ && SSL_get_error(cur->ssl, -1) != SSL_ERROR_WANT_WRITE) { cur->state = CSTATE_TERMINATING; } else { if(cur->data_offset) { [... do something with the data for application ...] } } break; [...] SNIP I guess there was nothing special about it. The client is almost equal - except that it do not handle multiple connections in a structure (cur) as it only has one ssl connection a time to the server: SNIP /* setup ssl stuff */ SSL_load_error_strings(); SSL_library_init(); OpenSSL_add_all_ciphers(); if(NULL == (ctx->ssl_ctx = SSL_CTX_new(TLSv1_client_method( { tproxy_error_die("unable to initialize ssl environment", 1); } SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_NONE, NULL); SSL_CTX_set_info_callback(ctx->ssl_ctx, apps_ssl_info_callback); [...] if(connect(ctx->proxy_socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { close(ctx->proxy_socket); tproxy_error_die("unable to connec
RE: OpenSSL compatibility between releases
➢ If there is compatibility issue, then it seems we have to recompile our application with latest openssl library. Please suggest if you have any other or better solutions. There is no other solution. 0.9.8 and 1.xxx aren’t binary compatible. For more details, see the FAQ, http://www.openssl.org/support/faq.html#MISC8 /r$ -- Principal Security Engineer Akamai Technology Cambridge, MA :��I"Ϯ��r�m (Z+�K�+1���x��h[�z�(Z+���f�y���f���h��)z{,���
OpenSSL compatibility between releases
Hi, How about the compatibility between different OpenSSL releases? Is it safe if we compile with openssl 0.9.8 library, then run our application with 1.0.0/1.0.1(by renaming the file name if needed) ? I have this question for two reasons, - we don't want to recompile our program - want to use latest openssl library(dynamic linked) I've learned some information that, libcrypto library in openssl is more stable(API compatible) than libssl. Currently we mainly use libcrypto library. If there is compatibility issue, then it seems we have to recompile our application with latest openssl library. Please suggest if you have any other or better solutions. Thanks and Best Regards, Xmly
OpenSSL compatibility between releases
Hi, How about the compatibility between different OpenSSL releases? Is it safe if we compile with openssl 0.9.8 library, then run our application with 1.0.0/1.0.1(by renaming the file name if needed) ? I have this question for two reasons, - we don't want to recompile our program - want to use latest openssl library(dynamic linked) I've learned some information that, libcrypto library in openssl is more stable(API compatible) than libssl. Currently we mainly use libcrypto library. If there is compatibility issue, then it seems we have to recompile our application with latest openssl library. Please suggest if you have any other or better solutions. Thanks and Best Regards, Xmly