candrebc
candrebc

Reputation: 41

SSLError: Python Server Failure (HTTP_REQUEST _ssl.c:777)

My application has a server wherein waiting for a connection is made as follow:

sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = ('', port_server)
sckt.bind(server)
sckt.listen(5)
try:
    while True:
        new_sckt, client = sckt.accept()
        conn = ssl.wrap_socket(new_sckt, server_side=True, ca_certs=certClient, cert_reqs=ssl.CERT_REQUIRED, certfile=certServer, keyfile=keyServer)
        _thread.start_new_thread(self.waitUserCommand, tuple([conn, client]))
finally:
    conn.close()

The client connects to server by:

sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn = ssl.wrap_socket(sckt, server_side=False, ca_certs=certServer, cert_reqs = ssl.CERT_REQUIRED, certfile=certClient, keyfile=keyClient)
conn.connect((ip_server, port_server))

The failure occurs after some client connections, appearing the followed message:

Traceback (most recent call last):
  File "server.py", line 260, in <module>
    server.startServer()
  File "server.py", line 90, in startServer
    keyfile=keyServer)
  File "/usr/local/lib/python3.6/ssl.py", line 1149, in wrap_socket
    ciphers=ciphers)
  File "/usr/local/lib/python3.6/ssl.py", line 814, in __init__
    self.do_handshake()
  File "/usr/local/lib/python3.6/ssl.py", line 1068, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/local/lib/python3.6/ssl.py", line 689, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: HTTP_REQUEST] http request (_ssl.c:777)

It is interesting to mention that this error occurs after the end of a connection and before the start of the next connection. i.e., the client is offline and the server is only waiting a new connection (without executing anything). Besides, my application uses another server that works in a similar manner but no failure with it occurred in my experiments.

Upvotes: 4

Views: 4780

Answers (1)

jmunsch
jmunsch

Reputation: 24089

Let's debug this.

do_handshake():

error :

SSL_R_HTTP_REQUEST :

lets look at the source of openssl:

git clone git://git.openssl.org/openssl.git
cd openssl

where is HTTP_REQUEST :

➜  openssl git:(master) grep -Rn 'HTTP_REQUEST' .
./crypto/err/openssl.txt:2454:SSL_R_HTTP_REQUEST:156:http request
./include/openssl/sslerr.h:530:# define SSL_R_HTTP_REQUEST                               156
./ssl/record/ssl3_record.c:316:                                     SSL_R_HTTP_REQUEST);
./ssl/ssl_err.c:845:    {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_HTTP_REQUEST), "http request"},
./test/ossl_shim/ossl_config.json:260:        ":HTTP_REQUEST:":"http request",

whats happening in openssl :

 ➜  openssl git:(master) grep -Rn 'SSL_R_HTTP_REQUEST' -A 20 -B 20 openssl/ssl/record/ssl3_record.c
openssl/ssl/record/ssl3_record.c-296-                        /*
openssl/ssl/record/ssl3_record.c-297-                         * Send back error using their minor version number :-)
openssl/ssl/record/ssl3_record.c-298-                         */
openssl/ssl/record/ssl3_record.c-299-                        s->version = (unsigned short)version;
openssl/ssl/record/ssl3_record.c-300-                    }
openssl/ssl/record/ssl3_record.c-301-                    SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_F_SSL3_GET_RECORD,
openssl/ssl/record/ssl3_record.c-302-                             SSL_R_WRONG_VERSION_NUMBER);
openssl/ssl/record/ssl3_record.c-303-                    return -1;
openssl/ssl/record/ssl3_record.c-304-                }
openssl/ssl/record/ssl3_record.c-305-
openssl/ssl/record/ssl3_record.c-306-                if ((version >> 8) != SSL3_VERSION_MAJOR) {
openssl/ssl/record/ssl3_record.c-307-                    if (RECORD_LAYER_is_first_record(&s->rlayer)) {
openssl/ssl/record/ssl3_record.c-308-                        /* Go back to start of packet, look at the five bytes
openssl/ssl/record/ssl3_record.c-309-                         * that we have. */
openssl/ssl/record/ssl3_record.c-310-                        p = RECORD_LAYER_get_packet(&s->rlayer);
openssl/ssl/record/ssl3_record.c-311-                        if (strncmp((char *)p, "GET ", 4) == 0 ||
openssl/ssl/record/ssl3_record.c-312-                            strncmp((char *)p, "POST ", 5) == 0 ||
openssl/ssl/record/ssl3_record.c-313-                            strncmp((char *)p, "HEAD ", 5) == 0 ||
openssl/ssl/record/ssl3_record.c-314-                            strncmp((char *)p, "PUT ", 4) == 0) {
openssl/ssl/record/ssl3_record.c-315-                            SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_GET_RECORD,
openssl/ssl/record/ssl3_record.c:316:                                     SSL_R_HTTP_REQUEST);
openssl/ssl/record/ssl3_record.c-317-                            return -1;
openssl/ssl/record/ssl3_record.c-318-                        } else if (strncmp((char *)p, "CONNE", 5) == 0) {
openssl/ssl/record/ssl3_record.c-319-                            SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_GET_RECORD,
openssl/ssl/record/ssl3_record.c-320-                                     SSL_R_HTTPS_PROXY_REQUEST);
openssl/ssl/record/ssl3_record.c-321-                            return -1;
openssl/ssl/record/ssl3_record.c-322-                        }
openssl/ssl/record/ssl3_record.c-323-
openssl/ssl/record/ssl3_record.c-324-                        /* Doesn't look like TLS - don't send an alert */
openssl/ssl/record/ssl3_record.c-325-                        SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_GET_RECORD,
openssl/ssl/record/ssl3_record.c-326-                                 SSL_R_WRONG_VERSION_NUMBER);
openssl/ssl/record/ssl3_record.c-327-                        return -1;
openssl/ssl/record/ssl3_record.c-328-                    } else {
openssl/ssl/record/ssl3_record.c-329-                        SSLfatal(s, SSL_AD_PROTOCOL_VERSION,
openssl/ssl/record/ssl3_record.c-330-                                 SSL_F_SSL3_GET_RECORD,
openssl/ssl/record/ssl3_record.c-331-                                 SSL_R_WRONG_VERSION_NUMBER);
openssl/ssl/record/ssl3_record.c-332-                        return -1;
openssl/ssl/record/ssl3_record.c-333-                    }
openssl/ssl/record/ssl3_record.c-334-                }

tentative answer

The ssl server is expecting a HTTP response, but is not receiving one, when the server responds? Other questions to be asked would be what version of OpenSSL? What version of Python3.6 exactly?

Why is it not seeing? :

strncmp((char *)p, "GET ", 4) == 0 ||
strncmp((char *)p, "POST ", 5) == 0 ||
strncmp((char *)p, "HEAD ", 5) == 0 ||
strncmp((char *)p, "PUT ", 4) == 0)

Perhaps, no clients are connecting, and the errors are not being handled on an empty socket request, or something like that?

Upvotes: 4

Related Questions