RE: SSL_read() seems to close my connection

2013-05-26 Thread Jeremy Farrell
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

2013-05-26 Thread Mario

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

2013-05-26 Thread Salz, Rich
➢ 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

2013-05-26 Thread Xmly
 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

2013-05-26 Thread Xmly
 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