Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTPS server with Python

I have written a simple webserver & client with python, following is my code. I want to implement HTTPS, for that I am using standard SSL library. I am using Python 2.7.3. I generated certificate file and self signed it. So I have .crt and .key files which I use it to bind on the socket.

When I browse it from the browser, I get the exception error that certificate is self signed and I have to add it to the exceptions. Then it works.

Code of my sever :

import BaseHTTPServer
import urlparse
import urllib 
import SocketServer
import threading
import ssl

HOST_NAME = 'localhost'
PORT_NUMBER = 8089


class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_HEAD(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()

    def do_GET(self):

        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()

        if self.path == '/get/':
            self.wfile.write('On /get/')
            return
        self.wfile.write('On root')
        return    

    def do_POST(self):
        pass

class ThreadedHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
    pass


if __name__ == '__main__':
    httpd = BaseHTTPServer.HTTPServer((HOST_NAME, PORT_NUMBER), Handler)
    httpd.socket = ssl.wrap_socket (httpd.socket, keyfile='my_key.key', certfile='my_cert.crt', server_side=True)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        httpd.server_close()
    print "Server Stopped - %s:%s" % (HOST_NAME, PORT_NUMBER)

However I am trying to use requests module and when I provide the .crt file with the requests, I get the following error:

requests.get('https://localhost:8089', verify=True)
#requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

requests.get('https://localhost:8089', verify='my_cert.crt')
#requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

requests.get('https://localhost:8089', cert='my_crt.crt')
#requests.exceptions.SSLError: [Errno 336265225] _ssl.c:351: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib

requests.get('https://localhost:8089', cert=('my_crt.crt', 'my_key.key'))
# requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed    

requests.get('https://localhost:8089', verify=False)
#<Response [200]>

1) Why I am getting this error? I certainly don't want to use 'verify=False'. I want to validate the certificate at the client side.

2) (Assuming I get to make it work) If I enforce cert_reqs=CERT_REQUIRED by changing :

httpd.socket = ssl.wrap_socket (httpd.socket, keyfile='my_key.key', certfile='my_cert.crt', cert_reqs=CERT_REQUIRED, server_side=True)

then does it mean only people who have my cert file (my_cert.crt) will be able to send request and get the response and people who don't, will not be able to?

like image 212
avi Avatar asked Dec 09 '13 12:12

avi


1 Answers

An SSL certificate can only be validated by the client if it has the certificate used for signing the validating certificate. This is the main reason why self-signed certificate are not commonly used on the Internet. Usually you ask some organization (Certification Authority) to sign you certificate with its. Those CA are commonly trusted by people and other organization so that their certificates are already built-in in many clients.

So, if you want to make everybody able to validate your certificate, you should not self-sign it. There are many CA out there and some of them issues certificate for free. Unless you get a CA-signed certificate only people who already have your certificate would validate it.

EDIT:

As a side note: when you tell your browser to add an exception for a particular site you are telling him to not validate at all its certificate. So you will not be protected against MITM.

like image 72
smeso Avatar answered Nov 15 '22 00:11

smeso