-
Notifications
You must be signed in to change notification settings - Fork 425
Expand file tree
/
Copy pathsimple-http-example.py
More file actions
executable file
·67 lines (50 loc) · 1.95 KB
/
simple-http-example.py
File metadata and controls
executable file
·67 lines (50 loc) · 1.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/env python3
"""A simple Python program to show the use of the pyOpenSSL
library. We connect to a HTTPS server and retrieve its home page. (Of
course, for this specific task, pyCurl would be a better solution but
the goal is to demonstrate pyOpenSSL.)"""
PORT = 443 # Hardwired
PATH = "/" # Hardwired
# https://www.pyopenssl.org/
# https://pyopenssl.readthedocs.io/
import OpenSSL
import socket
import sys
if len(sys.argv) != 2:
raise Exception("Usage: %s hostname" % sys.argv[0])
host = sys.argv[1]
addrinfo = socket.getaddrinfo(host, PORT, 0)
# We should loop over the IP addresses instead of taking only the first one…
sock = socket.socket(addrinfo[0][0], socket.SOCK_STREAM)
addr = addrinfo[0][4]
print("Connecting to %s ..." % str(addr))
context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_2_METHOD)
# Use the OS' default CAs
context.set_default_verify_paths()
# Ask for a certificate check. Warning, this does not check the host
# name, just the path from the CA, the expiration, may be the CRLs…
context.set_verify(OpenSSL.SSL.VERIFY_PEER | OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT | \
OpenSSL.SSL.VERIFY_CLIENT_ONCE,
lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
session = OpenSSL.SSL.Connection(context, sock)
session.set_tlsext_host_name(host.encode()) # Server Name Indication (SNI)
# TCP
session.connect((addr))
# TLS
session.do_handshake()
cert = session.get_peer_certificate()
print("Connected, its certificate is for \"%s\", delivered by \"%s\"" % \
(cert.get_subject().commonName,
cert.get_issuer().commonName))
# HTTP
request = """GET %s HTTP/1.1
Host: %s
Connection: close
""" % (PATH, host)
session.write(request.replace("\n","\r\n"))
# A real program must loop to read all the data
data = session.read(4096)
print("Got %i bytes, the first ones are: \"%s...\"" % (len(data),
data[:256].decode()))
session.close()
sock.close()