ShubhadeepB
ShubhadeepB

Reputation: 13

Receive raw TLS packet in Python

I am writing a simple SSL socket server and client in Python 2.7. I am trying to send a byte array from the client and read the same byte array from the server. Here's the code :

server

import socket
import ssl
import threading

class SocketServer(object):
    def __init__(self, host, port):
        self.context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
        self.context.load_cert_chain(certfile="D:\plugnplay\openssl\cert.pem")
        self.host = host
        self.port = port
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind((self.host, self.port))

    def listen(self):
        self.sock.listen(5)
        while True:
            sslsoc = None
            try:
                client, address = self.sock.accept()
                sslsoc = self.context.wrap_socket(client, server_side=True)
                threading.Thread(target = self.listenToClient,args = (client,address)).start()
            except Exception,ex:
                print (('Connection error : client - {0}, error - {1}').format(address, ex))
                try:
                    if sslsoc != None:
                        sslsoc.close()
                    else:
                        client.close()
                except:
                    pass


    def listenToClient(self, sslsoc, address):
        sslsoc.settimeout(60)
        size = 1024
        full_data = []
        while True:
            try:
                data = sslsoc.recv(size)
                byte_data = bytearray()
                byte_data.extend(data)
                if data:
                    for d in byte_data:
                        full_data.append(int(d))
                else:
                    raise Exception('Client disconnected')
            except Exception,ex:
                sslsoc.close()
                print full_data
                return

if __name__ == "__main__":
    port_num = 7656
    SocketServer('',port_num).listen()

client

import socket, ssl
import time

port = 7656
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain(certfile="D:\plugnplay\openssl\cert.pem")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = context.wrap_socket(s, server_side = False)
ssl_sock.connect(('127.0.0.1', port))

data = bytearray()
data.append(1)
data.append(2)
data.append(3)
data.append(4)
ssl_sock.write(data)

ssl_sock.close()

The problem is, I am getting the following array as the output from the server -

[23, 3, 3, 0, 28, 83, 69, 220, 108, 217, 65, 85, 25, 96, 230, 134, 63, 153, 137, 21, 226, 71, 162, 89, 86, 203, 141, 178, 171, 103, 72, 216, 79]

but I am suppose to get [1,2,3,4] as the output. These values are changing every time I run the client, except the first 5 bytes - 23, 3, 3, 0, 28.

I am using Win 10 and Python 2.7.14. And I am generating the SSL certificate using Openssl with the following command -

openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem

What I am doing wrong?

Upvotes: 1

Views: 1297

Answers (2)

halfer
halfer

Reputation: 20487

(Posted on behalf of the question author).

I changed the parameter of the function 'listenToClient' from 'client' to 'sslsoc' as Steffen suggested. Everything is working now.

Upvotes: 0

Steffen Ullrich
Steffen Ullrich

Reputation: 123639

[23, 3, 3, 0

This is the start of a TLS frame, i.e. ContentType 23 (application data) followed by the TLS version (3.3 which means TLS 1.2). This means you read from the plain socket instead from the SSL socket.

The reason for this is that you are calling listenToClient with the plain socket client but the functions actually expects the SSL socket sslsoc:

def listen(self):
    ...
            client, address = self.sock.accept()
            sslsoc = self.context.wrap_socket(client, server_side=True)
            threading.Thread(target = self.listenToClient,args = (client,address)).start()
            ...
def listenToClient(self, sslsoc, address):

Upvotes: 1

Related Questions