blob: 87384168166a855d41d9128876157ff2fdcffec6 [file] [log] [blame]
Jean-Paul Calderone7fb6b212011-06-06 08:31:28 -04001# Copyright (C) Jean-Paul Calderone
2# See LICENSE for details.
3
4if __name__ == '__main__':
5 import server
6 raise SystemExit(server.main())
7
8from sys import stdout
9from socket import SOL_SOCKET, SO_REUSEADDR, socket
10
11from OpenSSL.crypto import FILETYPE_PEM, load_privatekey, load_certificate
12from OpenSSL.SSL import TLSv1_METHOD, Context, Connection
13
14def load(domain):
15 crt = open(domain + ".crt")
16 key = open(domain + ".key")
17 result = (
18 load_privatekey(FILETYPE_PEM, key.read()),
19 load_certificate(FILETYPE_PEM, crt.read()))
20 crt.close()
21 key.close()
22 return result
23
24
25def main():
26 """
27 Run an SNI-enabled server which selects between a few certificates in a
28 C{dict} based on the handshake request it receives from a client.
29 """
30 port = socket()
31 port.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
32 port.bind(('', 8443))
33 port.listen(3)
34
35 print 'Accepting...',
36 stdout.flush()
37 server, addr = port.accept()
38 print 'accepted', addr
39
40 server_context = Context(TLSv1_METHOD)
41 server_context.set_tlsext_servername_callback(pick_certificate)
42
43 server_ssl = Connection(server_context, server)
44 server_ssl.set_accept_state()
45 server_ssl.do_handshake()
46 server.close()
47
48
49certificates = {
50 "example.invalid": load("example.invalid"),
51 "another.invalid": load("another.invalid"),
52 }
53
54
55def pick_certificate(connection):
56 try:
57 key, cert = certificates[connection.get_servername()]
58 except KeyError:
59 pass
60 else:
61 new_context = Context(TLSv1_METHOD)
62 new_context.use_privatekey(key)
63 new_context.use_certificate(cert)
64 connection.set_context(new_context)