How OpenSSL connections work

Corey Minyard minyard at acm.org
Sun Mar 6 13:40:01 UTC 2022


On Sun, Mar 06, 2022 at 02:39:55AM +0000, loic nicolas wrote:
> Hello,
> 
> I can't figure out how OpenSSL connections work.
> 
> I would like to use 2 bios (rbio, wbio) which will be shared for all my connections.

I'm not sure why you would want to do this.  Why would you allocate one
BIO and share it between connections?

> The problem is that I really don't understand the error messages.
> I never get an SSL_ERROR_WANT_WRITE error code, I only get SSL_ERROR_WANT_READ.

Your example doesn't show this.  It has several issues, in fact.  Can
you give an example where you are actually handling the want write
error?

I haven't announced this here, but I guess I should have.  I have a
library that has stackable stream and packet I/O modules, and it has an
SSL module.  If all you want is a simple SSL connection, it's probably
easier to use than the raw openssl library.  It's at
https://github.com/cminyard/gensio

-corey

> 
> For example, for the handshake, whether I have to send or receive data, I only receive the error SSL_ERROR_WANT_READ.
> (calls are blocking for simplicity)
> 
> int main()
> {
>        struct addrinfo hints, *result;
>        memset(&hints, 0, sizeof(struct addrinfo));
>        hints.ai_family = AF_UNSPEC;
>        hints.ai_socktype = SOCK_STREAM;
> 
>        if (getaddrinfo("google.com", "443", &hints, &result) != 0) {
>               printf("getaddrinfo error");
>               exit(1);
>        }
> 
>        int fd = -1;
>        for (; result != nullptr; result = result->ai_next) {
>               fd = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
>               if (fd < 0)
>                      continue;
>               int res = connect(fd, result->ai_addr, result->ai_addrlen);
>               if (res == -1) {
>                      continue;
>               } break;
>        }
>        if (fd < 0) {
>               printf("Connection error");
>               exit(1);
>        }
>        freeaddrinfo(result);
> 
>        SSL_library_init();
>        OpenSSL_add_all_algorithms();
>        SSL_load_error_strings();
>        ERR_load_BIO_strings();
>        ERR_load_crypto_strings();
>        SSL_CTX *ctx = SSL_CTX_new(SSLv23_method());
> 
>        BIO *rbio = BIO_new(BIO_s_mem());
>        BIO *wbio = BIO_new(BIO_s_mem());
>        SSL *ssl = SSL_new(ctx);
>        SSL_set_bio(ssl, rbio, wbio);
>        SSL_set_connect_state(ssl);
> 
>        int n;
>        do {
>               n = SSL_do_handshake(ssl);
>               n = SSL_get_error(ssl, n);
>               if (n == SSL_ERROR_WANT_READ) {
>                      char buffer[4096];
>                      int r = BIO_read(wbio, buffer, sizeof(buffer));
>                      int error = SSL_get_error(ssl, r);
>                      if (error == SSL_ERROR_WANT_READ) {
>                             r = read(fd, buffer, sizeof(buffer));
>                             BIO_write(rbio, buffer, r);
>                      } else {
>                             send(fd, buffer, r, 0);
>                      }
>               }
>        } while (n != SSL_ERROR_NONE);
>        printf("Connected");
> }
> 
> 
> 
> How to manage the connection (with several sockets on the same bios) if I don't know if I have to send data or receive it according to the error message?
> 
> Thank you


More information about the openssl-users mailing list