~stepankk/pyopenssl/bug-845445

« back to all changes in this revision

Viewing changes to examples/sni/server.py

  • Committer: Jean-Paul Calderone
  • Date: 2011-06-06 12:33:31 UTC
  • mfrom: (153.1.4 sni)
  • Revision ID: exarkun@divmod.com-20110606123331-vm00hkfitja61m7c
Add client and server support for SNI.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) Jean-Paul Calderone
 
2
# See LICENSE for details.
 
3
 
 
4
if __name__ == '__main__':
 
5
    import server
 
6
    raise SystemExit(server.main())
 
7
 
 
8
from sys import stdout
 
9
from socket import SOL_SOCKET, SO_REUSEADDR, socket
 
10
 
 
11
from OpenSSL.crypto import FILETYPE_PEM, load_privatekey, load_certificate
 
12
from OpenSSL.SSL import TLSv1_METHOD, Context, Connection
 
13
 
 
14
def 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
 
 
25
def 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
 
 
49
certificates = {
 
50
    "example.invalid": load("example.invalid"),
 
51
    "another.invalid": load("another.invalid"),
 
52
    }
 
53
 
 
54
 
 
55
def 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)