summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorJean-Paul Calderone <exarkun@boson>2008-02-18 20:50:23 -0500
committerJean-Paul Calderone <exarkun@boson>2008-02-18 20:50:23 -0500
commit897bc2556fed43b76f6d1b14470c3e806df15af8 (patch)
treebdd09f33c3fadb7efecca918e06e3dbef0a82bb9 /examples
downloadpyopenssl-897bc2556fed43b76f6d1b14470c3e806df15af8.tar.gz
initial source import
Diffstat (limited to 'examples')
-rw-r--r--examples/README48
-rw-r--r--examples/SecureXMLRPCServer.py102
-rw-r--r--examples/certgen.py80
-rw-r--r--examples/mk_simple_certs.py17
-rw-r--r--examples/proxy.py70
-rw-r--r--examples/simple/CA.cert12
-rw-r--r--examples/simple/CA.pkey15
-rw-r--r--examples/simple/client.cert11
-rw-r--r--examples/simple/client.pkey15
-rw-r--r--examples/simple/client.py53
-rw-r--r--examples/simple/server.cert11
-rw-r--r--examples/simple/server.pkey15
-rw-r--r--examples/simple/server.py101
13 files changed, 550 insertions, 0 deletions
diff --git a/examples/README b/examples/README
new file mode 100644
index 0000000..ecf95e5
--- /dev/null
+++ b/examples/README
@@ -0,0 +1,48 @@
+I've finally gotten around to writing some examples :-)
+
+They aren't many, but at least it's something. If you write any, feel free to
+send them to me and I will add themn.
+
+
+certgen.py - Certificate generation module
+==========================================
+
+Example module with three functions:
+ createKeyPair - Create a public/private key pair
+ createCertRequest - Create a certificate request
+ createCertificate - Create a certificate given a cert request
+In fact, I created the certificates and keys in the 'simple' directory with
+the script mk_simple_certs.py
+
+
+simple - Simple client/server example
+=====================================
+
+Start the server with
+ python server.py PORT
+and start clients with
+ python client.py HOST PORT
+
+The server is a simple echo server, anything a client sends, it sends back.
+
+
+proxy.py - Example of an SSL-enabled proxy
+==========================================
+
+The proxy example demonstrate how to use set_connect_state to start
+talking SSL over an already connected socket.
+
+Usage: python proxy.py server[:port] proxy[:port]
+
+Contributed by Mihai Ibanescu
+
+
+SecureXMLRPCServer.py - SSL-enabled version of SimpleXMLRPCServer
+=================================================================
+
+This acts exactly like SimpleXMLRPCServer from the standard python library,
+but uses secure connections. The technique and classes should work for any
+SocketServer style server. However, the code has not been extensively tested.
+
+Contributed by Michal Wallace
+
diff --git a/examples/SecureXMLRPCServer.py b/examples/SecureXMLRPCServer.py
new file mode 100644
index 0000000..757b49c
--- /dev/null
+++ b/examples/SecureXMLRPCServer.py
@@ -0,0 +1,102 @@
+"""
+SecureXMLRPCServer module using pyOpenSSL 0.5
+Written 0907.2002
+by Michal Wallace
+http://www.sabren.net/
+
+This acts exactly like SimpleXMLRPCServer
+from the standard python library, but
+uses secure connections. The technique
+and classes should work for any SocketServer
+style server. However, the code has not
+been extensively tested.
+
+This code is in the public domain.
+It is provided AS-IS WITH NO WARRANTY WHATSOEVER.
+"""
+import SocketServer
+import os, socket
+import SimpleXMLRPCServer
+from OpenSSL import SSL
+
+class SSLWrapper:
+ """
+ This whole class exists just to filter out a parameter
+ passed in to the shutdown() method in SimpleXMLRPC.doPOST()
+ """
+ def __init__(self, conn):
+ """
+ Connection is not yet a new-style class,
+ so I'm making a proxy instead of subclassing.
+ """
+ self.__dict__["conn"] = conn
+ def __getattr__(self,name):
+ return getattr(self.__dict__["conn"], name)
+ def __setattr__(self,name, value):
+ setattr(self.__dict__["conn"], name, value)
+ def shutdown(self, how=1):
+ """
+ SimpleXMLRpcServer.doPOST calls shutdown(1),
+ and Connection.shutdown() doesn't take
+ an argument. So we just discard the argument.
+ """
+ self.__dict__["conn"].shutdown()
+ def accept(self):
+ """
+ This is the other part of the shutdown() workaround.
+ Since servers create new sockets, we have to infect
+ them with our magic. :)
+ """
+ c, a = self.__dict__["conn"].accept()
+ return (SSLWrapper(c), a)
+
+
+
+class SecureTCPServer(SocketServer.TCPServer):
+ """
+ Just like TCPServer, but use a socket.
+ This really ought to let you specify the key and certificate files.
+ """
+ def __init__(self, server_address, RequestHandlerClass):
+ SocketServer.BaseServer.__init__(self, server_address, RequestHandlerClass)
+
+ ## Same as normal, but make it secure:
+ ctx = SSL.Context(SSL.SSLv23_METHOD)
+ ctx.set_options(SSL.OP_NO_SSLv2)
+
+ dir = os.curdir
+ ctx.use_privatekey_file (os.path.join(dir, 'server.pkey'))
+ ctx.use_certificate_file(os.path.join(dir, 'server.cert'))
+
+ self.socket = SSLWrapper(SSL.Connection(ctx, socket.socket(self.address_family,
+ self.socket_type)))
+ self.server_bind()
+ self.server_activate()
+
+
+class SecureXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
+ def setup(self):
+ """
+ We need to use socket._fileobject Because SSL.Connection
+ doesn't have a 'dup'. Not exactly sure WHY this is, but
+ this is backed up by comments in socket.py and SSL/connection.c
+ """
+ self.connection = self.request # for doPOST
+ self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
+ self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
+
+
+class SecureXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer, SecureTCPServer):
+ def __init__(self, addr,
+ requestHandler=SecureXMLRPCRequestHandler,
+ logRequests=1):
+ """
+ This is the exact same code as SimpleXMLRPCServer.__init__
+ except it calls SecureTCPServer.__init__ instead of plain
+ old TCPServer.__init__
+ """
+ self.funcs = {}
+ self.logRequests = logRequests
+ self.instance = None
+ SecureTCPServer.__init__(self, addr, requestHandler)
+
diff --git a/examples/certgen.py b/examples/certgen.py
new file mode 100644
index 0000000..e37d0c7
--- /dev/null
+++ b/examples/certgen.py
@@ -0,0 +1,80 @@
+#
+# certgen.py
+#
+# Copyright (C) Martin Sjögren and AB Strakt 2001, All rights reserved
+#
+# $Id: certgen.py,v 1.2 2004/07/22 12:01:25 martin Exp $
+#
+"""
+Certificate generation module.
+"""
+
+from OpenSSL import crypto
+
+TYPE_RSA = crypto.TYPE_RSA
+TYPE_DSA = crypto.TYPE_DSA
+
+def createKeyPair(type, bits):
+ """
+ Create a public/private key pair.
+
+ Arguments: type - Key type, must be one of TYPE_RSA and TYPE_DSA
+ bits - Number of bits to use in the key
+ Returns: The public/private key pair in a PKey object
+ """
+ pkey = crypto.PKey()
+ pkey.generate_key(type, bits)
+ return pkey
+
+def createCertRequest(pkey, digest="md5", **name):
+ """
+ Create a certificate request.
+
+ Arguments: pkey - The key to associate with the request
+ digest - Digestion method to use for signing, default is md5
+ **name - The name of the subject of the request, possible
+ arguments are:
+ C - Country name
+ ST - State or province name
+ L - Locality name
+ O - Organization name
+ OU - Organizational unit name
+ CN - Common name
+ emailAddress - E-mail address
+ Returns: The certificate request in an X509Req object
+ """
+ req = crypto.X509Req()
+ subj = req.get_subject()
+
+ for (key,value) in name.items():
+ setattr(subj, key, value)
+
+ req.set_pubkey(pkey)
+ req.sign(pkey, digest)
+ return req
+
+def createCertificate(req, (issuerCert, issuerKey), serial, (notBefore, notAfter), digest="md5"):
+ """
+ Generate a certificate given a certificate request.
+
+ Arguments: req - Certificate reqeust to use
+ issuerCert - The certificate of the issuer
+ issuerKey - The private key of the issuer
+ serial - Serial number for the certificate
+ notBefore - Timestamp (relative to now) when the certificate
+ starts being valid
+ notAfter - Timestamp (relative to now) when the certificate
+ stops being valid
+ digest - Digest method to use for signing, default is md5
+ Returns: The signed certificate in an X509 object
+ """
+ cert = crypto.X509()
+ cert.set_serial_number(serial)
+ cert.gmtime_adj_notBefore(notBefore)
+ cert.gmtime_adj_notAfter(notAfter)
+ cert.set_issuer(issuerCert.get_subject())
+ cert.set_subject(req.get_subject())
+ cert.set_pubkey(req.get_pubkey())
+ cert.sign(issuerKey, digest)
+ return cert
+
diff --git a/examples/mk_simple_certs.py b/examples/mk_simple_certs.py
new file mode 100644
index 0000000..9dfdd2e
--- /dev/null
+++ b/examples/mk_simple_certs.py
@@ -0,0 +1,17 @@
+"""
+Create certificates and private keys for the 'simple' example.
+"""
+
+from OpenSSL import crypto
+from certgen import * # yes yes, I know, I'm lazy
+cakey = createKeyPair(TYPE_RSA, 1024)
+careq = createCertRequest(cakey, CN='Certificate Authority')
+cacert = createCertificate(careq, (careq, cakey), 0, (0, 60*60*24*365*5)) # five years
+open('simple/CA.pkey', 'w').write(crypto.dump_privatekey(crypto.FILETYPE_PEM, cakey))
+open('simple/CA.cert', 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, cacert))
+for (fname, cname) in [('client', 'Simple Client'), ('server', 'Simple Server')]:
+ pkey = createKeyPair(TYPE_RSA, 1024)
+ req = createCertRequest(pkey, CN=cname)
+ cert = createCertificate(req, (cacert, cakey), 1, (0, 60*60*24*365*5)) # five years
+ open('simple/%s.pkey' % (fname,), 'w').write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey))
+ open('simple/%s.cert' % (fname,), 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
diff --git a/examples/proxy.py b/examples/proxy.py
new file mode 100644
index 0000000..b094864
--- /dev/null
+++ b/examples/proxy.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+#
+# This script demostrates how one can use pyOpenSSL to speak SSL over an HTTP
+# proxy
+# The challenge here is to start talking SSL over an already connected socket
+#
+# Author: Mihai Ibanescu <misa@redhat.com>
+#
+# $Id: proxy.py,v 1.2 2004/07/22 12:01:25 martin Exp $
+
+import sys, socket, string
+from OpenSSL import SSL
+
+def usage(exit_code=0):
+ print "Usage: %s server[:port] proxy[:port]" % sys.argv[0]
+ print " Connects SSL to the specified server (port 443 by default)"
+ print " using the specified proxy (port 8080 by default)"
+ sys.exit(exit_code)
+
+def main():
+ # Command-line processing
+ if len(sys.argv) != 3:
+ usage(-1)
+
+ server, proxy = sys.argv[1:3]
+
+ run(split_host(server, 443), split_host(proxy, 8080))
+
+def split_host(hostname, default_port=80):
+ a = string.split(hostname, ':', 1)
+ if len(a) == 1:
+ a.append(default_port)
+ return a[0], int(a[1])
+
+
+# Connects to the server, through the proxy
+def run(server, proxy):
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ s.connect(proxy)
+ except socket.error, e:
+ print "Unable to connect to %s:%s %s" % (proxy[0], proxy[1], str(e))
+ sys.exit(-1)
+
+ # Use the CONNECT method to get a connection to the actual server
+ s.send("CONNECT %s:%s HTTP/1.0\n\n" % (server[0], server[1]))
+ print "Proxy response: %s" % string.strip(s.recv(1024))
+
+ ctx = SSL.Context(SSL.SSLv23_METHOD)
+ conn = SSL.Connection(ctx, s)
+
+ # Go to client mode
+ conn.set_connect_state()
+
+ # start using HTTP
+
+ conn.send("HEAD / HTTP/1.0\n\n")
+ print "Sever response:"
+ print "-" * 40
+ while 1:
+ try:
+ buff = conn.recv(4096)
+ except SSL.ZeroReturnError:
+ # we're done
+ break
+
+ print buff,
+
+if __name__ == '__main__':
+ main()
diff --git a/examples/simple/CA.cert b/examples/simple/CA.cert
new file mode 100644
index 0000000..1e6162d
--- /dev/null
+++ b/examples/simple/CA.cert
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIBrzCCARgCAQAwDQYJKoZIhvcNAQEEBQAwIDEeMBwGA1UEAxMVQ2VydGlmaWNh
+dGUgQXV0aG9yaXR5MB4XDTAyMDgxNTEyMjQzN1oXDTA3MDgxNDEyMjQzN1owIDEe
+MBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
+A4GNADCBiQKBgQC9PNfAFlRkjw4SPLm8VV4/UFVkFJRKzpFgyi0UxN1W5HqSxMtH
+ivYPiUhhtfdGlLlzcMTeE+bcDxYjdrKh1bH3OmJN60fdpCiu2YMGucrNbLvuD8+f
+E1uoqYhheKTW0p2V+MkGMb/cbTmKk1rHr5dWHVXOrXTus/U8fmt/1wckNwIDAQAB
+MA0GCSqGSIb3DQEBBAUAA4GBAFt0RHXJbFPWHVnx9/vyCQlI3VluEBJquUlJFsqd
+VctFvzQyPypYRXYqxjD8JTxO0DmDyvlPNEu4nv6RVyca8FKDF0x8ro5G/hkCkVrN
+6AvC1ZIccHb3LzlfSv8bNB0iPkQPvnH4ZxDE+KJcOe80S7ttSRdDnjxm4NZFmUsI
+NtBS
+-----END CERTIFICATE-----
diff --git a/examples/simple/CA.pkey b/examples/simple/CA.pkey
new file mode 100644
index 0000000..6747a99
--- /dev/null
+++ b/examples/simple/CA.pkey
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQC9PNfAFlRkjw4SPLm8VV4/UFVkFJRKzpFgyi0UxN1W5HqSxMtH
+ivYPiUhhtfdGlLlzcMTeE+bcDxYjdrKh1bH3OmJN60fdpCiu2YMGucrNbLvuD8+f
+E1uoqYhheKTW0p2V+MkGMb/cbTmKk1rHr5dWHVXOrXTus/U8fmt/1wckNwIDAQAB
+AoGBAIwZ54GHBqQMZVaLLteIPGaTiyS1N7TKikcmZ4ng1h3mufi/SeCFuPZ3pOby
+WUggA8y7yITCJ0D0ymcnEclO9JnUP8XF8q7YBNVjjSQKr7xa4k+R1yzkqOwLnGFI
+X5OWQpHnGDzVZX14CGQMk8p1jIl6jz9LrNJ/spB4VrTkB9+BAkEA+jt3CjU3x4Dl
+DOxDfwNjwq2mw43SdyF03vdobLHvQhxoLbuglmSSe3V9mteD3h9NwgosK7QkApwr
+gJ2EHAWJvwJBAMGZeCxfO5B9ghVYNd8JupDdIkIiJh28wJPx8bgoncBsB/b7JEd5
+aUbfCwuMzy/FHLTRWCkiQ02qMSPBVcp404kCQGRw7g1Y4zTfVhFj3IvlDmwcS+3+
+xVYwRbshz/ahTYpZ4K9KuuDjKbEIrgwzKalFI28ZqjU4r6OkkAmmMFsXFf0CQHVO
+JnDMa20Lf2yrfEjevjrUotNrmajfG9kI+qvZgGx9iP3wAnWEbXPR5gFjmo6ZYuF1
+D3QtHJbMjuXZWcBLIfECQQDP6ywjwMAAB2285GwyI8Aqvo9U05QtGby6O/UQ2XoM
+XsrjM42qlPI+S+s72o47wkRhRayhnE5MJMpKJGgbTN8f
+-----END RSA PRIVATE KEY-----
diff --git a/examples/simple/client.cert b/examples/simple/client.cert
new file mode 100644
index 0000000..97ee35e
--- /dev/null
+++ b/examples/simple/client.cert
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBpzCCARACAQEwDQYJKoZIhvcNAQEEBQAwIDEeMBwGA1UEAxMVQ2VydGlmaWNh
+dGUgQXV0aG9yaXR5MB4XDTAyMDgxNTEyMjQzN1oXDTA3MDgxNDEyMjQzN1owGDEW
+MBQGA1UEAxMNU2ltcGxlIENsaWVudDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
+gYEAynARaDhd5I/BhLGlcqOqOoEsOEF4KH9+5SfwQX1zBaaI8bVTq8GB1/J5UFXt
+3ugLAb4QHtUVBrks9wi+IGENS1IeUgZZMsETQqXgzdK3SXt7IPnggo4GUl3dWIJG
+UYsOjea37ejV1TbtD5MrEWNSF4F9OP1H8oWUFJOFR/7sdHECAwEAATANBgkqhkiG
+9w0BAQQFAAOBgQAzvsH7fD0GKKZo2uL/5gBc/ZE1hSx/KfRIZ78CZGsgHI8oi3Y+
+Km91PX2H4xx/2dv/ZaAPslDjvvyVTl6KQoN+HMmhcjY8XAs1lVqckcNbhVEw2kgc
+Admy5yPZmuIC0nTC1jzZo1dDD4PNrFcRho6fHDk2aaxpS+DnzAO2/cTCTg==
+-----END CERTIFICATE-----
diff --git a/examples/simple/client.pkey b/examples/simple/client.pkey
new file mode 100644
index 0000000..a4ffec1
--- /dev/null
+++ b/examples/simple/client.pkey
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDKcBFoOF3kj8GEsaVyo6o6gSw4QXgof37lJ/BBfXMFpojxtVOr
+wYHX8nlQVe3e6AsBvhAe1RUGuSz3CL4gYQ1LUh5SBlkywRNCpeDN0rdJe3sg+eCC
+jgZSXd1YgkZRiw6N5rft6NXVNu0PkysRY1IXgX04/UfyhZQUk4VH/ux0cQIDAQAB
+AoGBAIwv314U6rCE/LYvbytcO14YZc7vR46D/BQk/DPd8/FNyjfYIgEnGAu7VldT
+qk5a0oR6Yh933/+v7HuGCmPR0anCdBX+0fuZakMetvM1PN0Nvv8PqEXfILW/ikT6
+rCcFWXff4og41HVmLcap6wo4KeCGLyXEynZWCXNRnedGnHQhAkEA+1tOa03oc9HJ
+RbBC87teSLCVVa8CiXWhpttXAbBPBRpzrBCdIiv9cpVQ1iRRbmKUgPRNX1MQI5Lw
+6mzQNkRPnwJBAM4tazLZJD3KIqNTUuQgxhcPmzerQ5jylhbPcHB4N5U/nS1feWpm
+QQf4AWQp4TJUOqoqW+nbdfEwyOUPqc2Zge8CQQDupnJ+Tyo1TSnckM4AvBV4zq/6
++n9eI+GnmvmxEMT2A3dwFxYaK8on0L0/lJv8QnzdMxeDOkpIfGthKI9H9vPhAkAJ
+8CiFp+/WRqMKyl5pfqbtv6PUuB2nBrJzYQZjdXgAarOR11NL7Kff0XWHtXkUavj0
+8NvDVv/FY3ubhvjBX0/jAkEAtjbwbIcRVjMQ9FuZk6SdJBSMfsX7iTDhgA7Hgn3U
+YsHo3E094lIi/66gnApVUOqr+brdglP6uAG2qP+ZgqWPiw==
+-----END RSA PRIVATE KEY-----
diff --git a/examples/simple/client.py b/examples/simple/client.py
new file mode 100644
index 0000000..6358b20
--- /dev/null
+++ b/examples/simple/client.py
@@ -0,0 +1,53 @@
+#
+# client.py
+#
+# Copyright (C) 2001 Martin Sjögren and AB Strakt, All rights reserved
+#
+# $Id: client.py,v 1.7 2002/08/15 12:20:46 martin Exp $
+#
+"""
+Simple SSL client, using blocking I/O
+"""
+
+from OpenSSL import SSL
+import sys, os, select, socket
+
+def verify_cb(conn, cert, errnum, depth, ok):
+ # This obviously has to be updated
+ print 'Got certificate: %s' % cert.get_subject()
+ return ok
+
+if len(sys.argv) < 3:
+ print 'Usage: python[2] client.py HOST PORT'
+ sys.exit(1)
+
+dir = os.path.dirname(sys.argv[0])
+if dir == '':
+ dir = os.curdir
+
+# Initialize context
+ctx = SSL.Context(SSL.SSLv23_METHOD)
+ctx.set_verify(SSL.VERIFY_PEER, verify_cb) # Demand a certificate
+ctx.use_privatekey_file (os.path.join(dir, 'client.pkey'))
+ctx.use_certificate_file(os.path.join(dir, 'client.cert'))
+ctx.load_verify_locations(os.path.join(dir, 'CA.cert'))
+
+# Set up client
+sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
+sock.connect((sys.argv[1], int(sys.argv[2])))
+
+while 1:
+ line = sys.stdin.readline()
+ if line == '':
+ break
+ try:
+ sock.send(line)
+ sys.stdout.write(sock.recv(1024))
+ sys.stdout.flush()
+ except SSL.Error:
+ print 'Connection died unexpectedly'
+ break
+
+
+sock.shutdown()
+sock.close()
diff --git a/examples/simple/server.cert b/examples/simple/server.cert
new file mode 100644
index 0000000..adc84e8
--- /dev/null
+++ b/examples/simple/server.cert
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBpzCCARACAQEwDQYJKoZIhvcNAQEEBQAwIDEeMBwGA1UEAxMVQ2VydGlmaWNh
+dGUgQXV0aG9yaXR5MB4XDTAyMDgxNTEyMjQzOFoXDTA3MDgxNDEyMjQzOFowGDEW
+MBQGA1UEAxMNU2ltcGxlIFNlcnZlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
+gYEA6IUeEF7IA5onMYj1nxbNRshtEMtJoNKmVhkhv+izihSmFBZp2X+s5ijCVtx4
+RlSbUh9HN3yQJnL0lpiv6MuivXiYElMcla8x3nryBG5ZNE6dpZI9NqGCuMzyiuhH
+2AhyJPQ2xDOAly5T/jnILNUmPbPBmpUX5hYjAaTyXM9hUIkCAwEAATANBgkqhkiG
+9w0BAQQFAAOBgQAo6u+V9CU9tLJI6iD3X+oxC6Z5XCL7iz5ROf+G8Jbke21uWbWS
+JHvmk1jENrfHZ8z1vm5XN25TWNDXPmNb1c4n3Rn9CcoVnmG+IThAaqQZuwSryj2B
+TmvyzKqNqLbdofF1O5hyqgDUFG09323Hny4+TwaUq2yMaj63jpLyUkZc/Q==
+-----END CERTIFICATE-----
diff --git a/examples/simple/server.pkey b/examples/simple/server.pkey
new file mode 100644
index 0000000..dbcfafb
--- /dev/null
+++ b/examples/simple/server.pkey
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDohR4QXsgDmicxiPWfFs1GyG0Qy0mg0qZWGSG/6LOKFKYUFmnZ
+f6zmKMJW3HhGVJtSH0c3fJAmcvSWmK/oy6K9eJgSUxyVrzHeevIEblk0Tp2lkj02
+oYK4zPKK6EfYCHIk9DbEM4CXLlP+Ocgs1SY9s8GalRfmFiMBpPJcz2FQiQIDAQAB
+AoGAMnyk+Hz8BPw1wmWwn2h+Df564Aij5g2XHF68m0TVpwewv+/V7+nvCtKSz/Vz
+ECJSz1QHTJ75Vb/kJ8bjezKsFPncBRUBBPNlbvOD02DhDQAmzdJPul6gQ2TvtuLu
+07KtfjnQcH4/2gqMknW7GB3SroCDZbw72QRuridFvfJlTlkCQQD6TOy7a5WZOn+Q
+luYLyWzOaB7uzLfoHY3tWLd1hJBLbY+WvuXFzfjgLteM7vxHpitz+xjiFw6ktK6o
+mhmt/QGTAkEA7dCLgaI2lqk3GqndEWsU33PYJlgNWAVjMnGRMmYwEnxYf7WkPGYC
+07qhlBoZ1SiiHOmMCD+IY6frChdU8C8m8wJBAIk6gZQj4OoYi3XfdZLCxVfI+CSe
+srmc8oJNYJAatO3VzKKuWNWBHtDyfZU0NbamoS4+XZ8fWxTsRtIDYs7kZucCQQCH
+h1MJ5M0hXXw26NlAxPrXQajMaV/pauCWbdxmkZAR6OVymqzncudnjLPquFlCfm6s
+9XhFdxeeW6L6VEOmweh7AkEAsvcEcce8CAauroQ4ST5dw9dQlxuohHY37lEtWuFL
+A7/k1kCtLitZKvAWDfaz34NQUtgr5/lOQ6h+jGfIafpHpQ==
+-----END RSA PRIVATE KEY-----
diff --git a/examples/simple/server.py b/examples/simple/server.py
new file mode 100644
index 0000000..a592ec3
--- /dev/null
+++ b/examples/simple/server.py
@@ -0,0 +1,101 @@
+#
+# server.py
+#
+# Copyright (C) 2001 Martin Sjögren and AB Strakt, All rights reserved
+#
+# $Id: server.py,v 1.2 2002/07/25 08:26:34 martin Exp $
+#
+"""
+Simple echo server, using nonblocking I/O
+"""
+
+from OpenSSL import SSL
+import sys, os, select, socket
+
+
+def verify_cb(conn, cert, errnum, depth, ok):
+ # This obviously has to be updated
+ print 'Got certificate: %s' % cert.get_subject()
+ return ok
+
+if len(sys.argv) < 2:
+ print 'Usage: python[2] server.py PORT'
+ sys.exit(1)
+
+dir = os.path.dirname(sys.argv[0])
+if dir == '':
+ dir = os.curdir
+
+# Initialize context
+ctx = SSL.Context(SSL.SSLv23_METHOD)
+ctx.set_options(SSL.OP_NO_SSLv2)
+ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb) # Demand a certificate
+ctx.use_privatekey_file (os.path.join(dir, 'server.pkey'))
+ctx.use_certificate_file(os.path.join(dir, 'server.cert'))
+ctx.load_verify_locations(os.path.join(dir, 'CA.cert'))
+
+# Set up server
+server = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
+server.bind(('', int(sys.argv[1])))
+server.listen(3)
+server.setblocking(0)
+
+clients = {}
+writers = {}
+
+def dropClient(cli, errors=None):
+ if errors:
+ print 'Client %s left unexpectedly:' % (clients[cli],)
+ print ' ', errors
+ else:
+ print 'Client %s left politely' % (clients[cli],)
+ del clients[cli]
+ if writers.has_key(cli):
+ del writers[cli]
+ if not errors:
+ cli.shutdown()
+ cli.close()
+
+while 1:
+ try:
+ r,w,_ = select.select([server]+clients.keys(), writers.keys(), [])
+ except:
+ break
+
+ for cli in r:
+ if cli == server:
+ cli,addr = server.accept()
+ print 'Connection from %s' % (addr,)
+ clients[cli] = addr
+
+ else:
+ try:
+ ret = cli.recv(1024)
+ except (SSL.WantReadError, SSL.WantWriteError, SSL.WantX509LookupError):
+ pass
+ except SSL.ZeroReturnError:
+ dropClient(cli)
+ except SSL.Error, errors:
+ dropClient(cli, errors)
+ else:
+ if not writers.has_key(cli):
+ writers[cli] = ''
+ writers[cli] = writers[cli] + ret
+
+ for cli in w:
+ try:
+ ret = cli.send(writers[cli])
+ except (SSL.WantReadError, SSL.WantWriteError, SSL.WantX509LookupError):
+ pass
+ except SSL.ZeroReturnError:
+ dropClient(cli)
+ except SSL.Error, errors:
+ dropClient(cli, errors)
+ else:
+ writers[cli] = writers[cli][ret:]
+ if writers[cli] == '':
+ del writers[cli]
+
+for cli in clients.keys():
+ cli.close()
+server.close()