The sslsocket class in Python

Overview:

  •  The SSLSocket class is derived from the socket class and represents a secure socket in TLS context.

  • The Python examples given here use SSLSocket instances in both server and client scenarios.

 

Example Server program that uses TLS:

  • The SSL server program creates a server socket and listens on port 15001 on localhost.
  • When a client connection is accepted, a client socket is created which is wrapped  into a SSLSocket.
  • The SSLSocket is supplied with the CA Certificate, the certificate of the server and the corresponding private key.
  • A call to the getpeercert() on the secure client connection(ie., the SSLSocket instance) gets the certificate of the client.
  • The server program validates the common Name, time validity  of the certificate before sending any information over the secure connection with the client.

# Example SSL server program that listens at port 15001
import ssl
import socket
import datetime
import time

ipAddress   = "127.0.0.1";
port        = 15001;

# Create a server socket 
serverSocket = socket.socket();
serverSocket.bind((ipAddress, port));

# Listen for incoming connections
serverSocket.listen();
print("Server listening:");

while(True):
    # Keep accepting connections from clients
    (clientConnection, clientAddress) = serverSocket.accept();
    
    # Make the socket connection to the clients secure through SSLSocket
    secureClientSocket = ssl.wrap_socket(clientConnection, 
                                        server_side=True, 
                                        ca_certs="./DemoCA.pem", 
                                        certfile="./DemoSvr.crt",
                                        keyfile="./DemoSvr.key", 
                                        cert_reqs=ssl.CERT_REQUIRED,
                                        ssl_version=ssl.PROTOCOL_TLSv1_2);

    # Get certificate from the client
    client_cert = secureClientSocket.getpeercert();
    
    clt_subject    = dict(item[0] for item in client_cert['subject']);
    clt_commonName = clt_subject['commonName'];

    # Check the client certificate bears the expected name as per server's policy
    if not client_cert:
        raise Exception("Unable to get the certificate from the client");
        
    if clt_commonName != 'DemoClt':
        raise Exception("Incorrect common name in client certificate");

    # Check time validity of the client certificate
    t1  = ssl.cert_time_to_seconds(client_cert['notBefore']);
    t2  = ssl.cert_time_to_seconds(client_cert['notAfter']);
    ts  = time.time();

    if ts < t1:
        raise Exception("Client certificate not yet active");
        
    if ts > t2:
        raise Exception("Expired client certificate");

    # Send current server time to the client
    serverTimeNow = "%s"%datetime.datetime.now();
    secureClientSocket.send(serverTimeNow.encode());
    print("Securely sent %s to %s"%(serverTimeNow, clientAddress));

    # Close the connection to the client
    secureClientSocket.close();

 

Example Client program that uses TLS:

  • The client program makes use of the SSLContext instance to load the CA certificate, client certificate and the corresponding private key.  
  • The client creates a stream based socket and wraps it around an SSLSocket instance.
  • Through the SSLSocket instance the security aspects of the communication: Privacy, Data Integrity and Authentication are taken care.
  • Once the SSLSocket instance makes a connection to the server listening on a specific IP address and Port it requests for the certificate of the server to which it is connected to.
  • The fields of the certificate like commonName, notBefore and notAfter are validated before any communication is received from the server.

import socket
import ssl
import os
import time

# IP address and the port number of the server
sslServerIP    = "127.0.0.1";
sslServerPort  = 15001;

# Create an SSL context
context                     = ssl.SSLContext();
context.verify_mode         = ssl.CERT_REQUIRED;

# Load CA certificate with which the client will validate the server certificate
context.load_verify_locations("./DemoCA.pem");

# Load client certificate
context.load_cert_chain(certfile="./DemoClt.crt", keyfile="./DemoClt.key");

# Create a client socket
clientSocket        = socket.socket();

# Make the client socket suitable for secure communication
secureClientSocket  = context.wrap_socket(clientSocket);
secureClientSocket.connect((sslServerIP, sslServerPort));

# Obtain the certificate from the server
server_cert = secureClientSocket.getpeercert();

# Validate whether the Certificate is indeed issued to the server
subject         = dict(item[0] for item in server_cert['subject']);
commonName      = subject['commonName'];

if not server_cert:
    raise Exception("Unable to retrieve server certificate");
    
if commonName != 'DemoSvr':
    raise Exception("Incorrect common name in server certificate");

notAfterTimestamp   = ssl.cert_time_to_seconds(server_cert['notAfter']);
notBeforeTimestamp  = ssl.cert_time_to_seconds(server_cert['notBefore']);
currentTimeStamp    = time.time();

if currentTimeStamp > notAfterTimestamp:
    raise Exception("Expired server certificate");
    
if currentTimeStamp < notBeforeTimestamp:
    raise Exception("Server certificate not yet active");

# Safe to proceed with the communication
msgReceived = secureClientSocket.recv(1024);
print("Secure communication received from server:%s"%msgReceived.decode());

# Close the sockets
secureClientSocket.close();
clientSocket.close();

 

Output - Server:

Server listening:

Securely sent 2020-04-03 00:59:13.419609 to ('127.0.0.1', 60047)

Securely sent 2020-04-03 00:59:15.225650 to ('127.0.0.1', 60048)

 

Output - Client:

Secure communication received from server:2020-04-03 00:59:15.225650

 


Copyright 2024 © pythontic.com