SSL3_READ_BYTES:tlsv1 alert internal error, secure sockets, OpenSSL, C++, getting HTTPS page

17,177

Solution 1

... SSL routines:SSL3_READ_BYTES:tlsv1 alert internal error when trying result = SSL_connect(ssl);

This means that the server sends a TLSv1 alert back probably because it does not like the information send by the client in the handshake (ClientHello). This might be because the client only offers ciphers which the server does not supports, that the client uses a protocol version not supported or very often also because the server requires the TLS SNI extension to determine which certificate to provide to the client. Testing with other tools indicates that this is actually the case. The problem thus can be solved in your code by using the SNI extension:

SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);

// ADD THIS
SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, (void*)servername.c_str());

result = SSL_connect(ssl);

Solution 2

In case it is ever useful to anyone, I had the same error (irregularly ) in my C++ program and it was driving me mad:

error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version I tried all combinations of OpenSSL, different TLS versions etc, etc.

In the end, I found the Ping I had implemented ( to check the socket was still up ) was being called while another thread's SSL_read / SSL_write() was active on the same SSL object.

Share:
17,177
Katie
Author by

Katie

A girl who just loves programming :)) (but still learns ^^)

Updated on June 16, 2022

Comments

  • Katie
    Katie almost 2 years

    I want to write a simple application, which grabs the content of the HTTPS page: https://httpbin.org/html.

    I know how to access its insecure (HTTP) version (http://httpbin.org/html), I just need to send a request using sockets:

    std::stringstream ss;
    ss << "GET /html HTTP/1.1" << "\r\n"
    << "Host: httpbin.org\r\n"
    << "Connection: close"
    << "\r\n\r\n";
    std::string request = ss.str();
    
    // socket creation, connect
    
    send(sock, request.c_str(), request.size(), 0);
    

    And it works. However, when using secure sockets (#include <openssl/ssl.h>) I got the following error: error:14094438:SSL routines:SSL3_READ_BYTES:tlsv1 alert internal error when trying result = SSL_connect(ssl);

    Here's the code:

    #include <sys/stat.h>
    #include <netdb.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <openssl/ssl.h>
    #include <openssl/err.h>
    #include <string>
    #include <iostream>
    #include <sstream>
    
    int main(int argc, char **argv)
    {
        int    sock;
        char   buff[1024];
    
        struct sockaddr_in  address;
        struct hostent     *host = NULL;
    
        std::string servername = "httpbin.org";
    
        if (!inet_aton(servername.c_str(), &address.sin_addr))
            if (host = gethostbyname(servername.c_str()))
                address.sin_addr = *(struct in_addr*)host->h_addr;
            else
                return -1;
    
        address.sin_port   = htons(443);
        address.sin_family = AF_INET;
    
        std::stringstream ss;
        ss << "GET /html HTTP/1.1" << "\r\n"
        << "Host: httpbin.org\r\n"
        << "Connection: close"
        << "\r\n\r\n";
        std::string request = ss.str();
    
    
        if ((sock = socket(AF_INET, SOCK_STREAM, 0)) != -1)
        {
            if (connect(sock, (struct sockaddr *)&address, sizeof(struct sockaddr_in)) != -1)
            {
                SSL_library_init();
                OpenSSL_add_all_algorithms();
                SSL_load_error_strings();
                SSL_CTX *ctx = SSL_CTX_new(TLSv1_2_method());
                if (!ctx)
                    return -1;
    
                int result = -1;
                SSL *ssl = SSL_new(ctx);
                SSL_set_fd(ssl, sock);
                result = SSL_connect(ssl);
    
                if (result == 0)
                {
                    long error = ERR_get_error();
                    const char* error_str = ERR_error_string(error, NULL);
                    printf("%s\n", error_str);
                    return 0;
                }
    
                SSL_write(ssl, request.c_str(), request.size());
                SSL_read(ssl, buff, 1024);
                printf("%s\n", buff);
                memset(buff, 0, 1024);
    
                SSL_free(ssl);
                SSL_CTX_free(ctx);
                close(sock);
            }
        }
    
        return 0;
    }