repetitive ssl send

Viktor Dukhovni openssl-users at dukhovni.org
Mon Jun 22 17:27:13 UTC 2020


On Mon, Jun 22, 2020 at 03:17:41PM +0200, Attila Csosz wrote:

> char HEADERS[] = "GET /search?q=arduino HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n";
> char HOST_NAME_PORT[] = "www.google.com:443";

Note the "Connection: close" in the HTTP request header!

> void init_openssl()
> {
>     SSL_load_error_strings();
>     SSL_library_init();
> }
> 
> void CreateSSL()
> {
>  // Create SSL context
>  meth = SSLv23_client_method();
>  if (!meth) throw Exception("SSL: method");
> 
>  ctx = SSL_CTX_new(meth);
>  if (!ctx) throw Exception("SSL: SSL_CTX_new");
>  old_opts = SSL_CTX_set_options(ctx, SSL_OP_ALL);

The SSL_CTX need only be created once, not once per connection.
You've made no provision for verifying the server certificate.
Typically you would load trusted CA certificate locations into
the SSL_CTX.

>  web = BIO_new_ssl_connect(ctx);
>  if (!web) throw Exception("SSL: BIO_new_ssl_connect");
> }

This code belows in the ConnectSSL function.

> 
> void ConnectSSL()
> {
>  // Connect
>  res = BIO_set_conn_hostname(web, HOST_NAME_PORT);
>  if (!res) throw Exception("SSL: BIO_ctrl");
> 
>  res = BIO_get_ssl(web, &ssl);
>  if (!res) throw Exception("SSL: BIO_ctrl");
> 
>  res = SSL_set_cipher_list(ssl, PREFERRED_CIPHERS);
>  if (!res) throw Exception("SSL: SSL_set_cipher_list");
> 
>  res = BIO_do_connect(web);
>  if (res <= 0) throw Exception("SSL: BIO_do_connect");
> 
>  res = BIO_do_handshake(web);
>  if (res <= 0) throw Exception("SSL: BIO_do_handshake");

This connection is unauthenticated.  Perhaps that's OK, but often it is
not.

> }
> 
> void SendSSL()
> {
>  // Send
>  err = BIO_puts(web, HEADERS);
>  if (err <= 0) throw Exception("SSL: BIO_puts");
> }
> 
> void ReceiveSSL()
> {
>  // Read
>  sResult = "";
>  for (;;) {
>   len = BIO_read(web, buf, sizeof(buf));
>   sResult += buf;
>   if (len <= 0)
>    break;
>  }

The server closes the connection after returning its reply.
You need to close the SSL BIO to avoid a memory leak.

> ---------
> It is ok for one request.
> 
> My problem when I trying to send a new search request to google it works
> only when I call
>  CreateSSL();
>  ConnectSSL();
> again

Naturally, you're not doing HTTP/1.1 connection keep-alive, and in any
case would need to be prepared for the server to close the connection
now and then.  You need an actual HTTPS library, naive open-coding of an
HTTP client over SSL is unlikely to be correct.  Something like libcurl
or similar is the way to go.

> What may the problem?

You're writing a naïve HTTPS client from scratch.  A correct
implementation would understand "Content-Length" and chunked
trasfer encoding, handle server-initiated disconnects, be
prepared to receive multi-record responses, ...

-- 
    Viktor.


More information about the openssl-users mailing list