Integrating SSL into a program using BSD sockets

I have a TCP network library that implements a bunch of protocol (redis, http, etc.) and they are implemented using BSD sockets.

A lot of code uses select () functions and other functions designed for BSD sockets. Do I believe that this will not work on SSL sockets? Or will they work as they are?

I'm just curious how SSL and BSD sockets are so different that they need a completely different approach to implementation.

+6
source share
3 answers

Assuming you mean OpenSSL, it sits on top of the socket, it does not replace it. So all direct connect operations like select() still work. However, the difference is that OpenSSL handles reading and writing for you, so you replace recv() with ssl_read() and send() with ssl_write() , but you can (and in some cases need to) use select() directly. However, you cannot just call him whenever you want, you need to wait until OpenSSL prompts you to call. For example, if you have a read loop that first calls select() and then calls recv() only when select() reports readability, you have to change this logic. Call ssl_read() , and then call select () only if ssl_read() returns either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE (note that ssl_read() can perform write operations inside, and ssl_write() can perform read operations inside),

+6
source

One thing that comes to mind is that you should not make a choice on fd, through which the ssl connection is started. This is because it can, for example, say that you can read from it, while ssl_read will be blocked. This, in turn, is caused, for example, by the fact that SSL does key switching, and not the application data, to become available. This is one of the holes.

+2
source

This may be belated, but may serve as a good reference to future users. There is a good stream when using the select () function on the url http://developerweb.net/viewtopic.php?id=6824 . One example is given below:

 int sslsock_handle_nbio (ssl, ret, totv) void *ssl; /* -> the SSL info */ int ret; /* the SSL I/O function return value */ struct timeval *totv; /* -> timeout info, or NULL */ { int sfd, i; fd_set rset, wset; sfd = SSL_get_fd (ssl); i = SSL_get_error (ssl, ret); if (i == SSL_ERROR_WANT_READ) { do { FD_ZERO (&rset); FD_SET (sfd, &rset); i = select (sfd + 1, &rset, NULL, NULL, totv); } while ((i < 0) && (errno == EINTR)); if (i == 0) { /* the select() timed out */ ret = -2; errno = ETIMEDOUT; } else { /* either an error, or it readable */ ret = i; } } else if (i == SSL_ERROR_WANT_WRITE) { do { FD_ZERO (&wset); FD_SET (sfd, &wset); i = select (sfd + 1, NULL, &wset, NULL, totv); } while ((i < 0) && (errno == EINTR)); if (i == 0) { /* the select() timed out */ ret = -2; errno = ETIMEDOUT; } else { /* either an error, or it writable */ ret = i; } } /* else, leave "ret" alone, and return it as-is */ return (ret); } 

This is only done after SSL_read() or SSL_write() .

0
source

Source: https://habr.com/ru/post/914009/


All Articles