summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarayan Desai <desai@mcs.anl.gov>2009-05-06 01:26:53 +0000
committerNarayan Desai <desai@mcs.anl.gov>2009-05-06 01:26:53 +0000
commit9590d0bb421cb7fdf7dd04d4b1d0d77e3f06f13b (patch)
tree768763aa48be1a5a2c8dae7cba81859510f1146e
parent13f6d1554dd24d08d44662906fa9f3f008a23058 (diff)
downloadbcfg2-9590d0bb421cb7fdf7dd04d4b1d0d77e3f06f13b.tar.gz
bcfg2-9590d0bb421cb7fdf7dd04d4b1d0d77e3f06f13b.tar.bz2
bcfg2-9590d0bb421cb7fdf7dd04d4b1d0d77e3f06f13b.zip
more to python 2.6 ssl
git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@5187 ce84e21b-d406-0410-9b95-82705330c041
-rw-r--r--src/lib/Component.py584
-rw-r--r--src/lib/SSLServer.py326
-rwxr-xr-xsrc/lib/tlslite/BaseDB.py120
-rwxr-xr-xsrc/lib/tlslite/Checker.py146
-rwxr-xr-xsrc/lib/tlslite/FileObject.py220
-rwxr-xr-xsrc/lib/tlslite/HandshakeSettings.py159
-rwxr-xr-xsrc/lib/tlslite/Session.py131
-rwxr-xr-xsrc/lib/tlslite/SessionCache.py103
-rwxr-xr-xsrc/lib/tlslite/SharedKeyDB.py58
-rwxr-xr-xsrc/lib/tlslite/TLSConnection.py1600
-rwxr-xr-xsrc/lib/tlslite/TLSRecordLayer.py1131
-rwxr-xr-xsrc/lib/tlslite/VerifierDB.py90
-rwxr-xr-xsrc/lib/tlslite/X509.py133
-rwxr-xr-xsrc/lib/tlslite/X509CertChain.py181
-rwxr-xr-xsrc/lib/tlslite/__init__.py39
-rwxr-xr-xsrc/lib/tlslite/api.py75
-rwxr-xr-xsrc/lib/tlslite/constants.py225
-rwxr-xr-xsrc/lib/tlslite/errors.py149
-rwxr-xr-xsrc/lib/tlslite/integration/AsyncStateMachine.py235
-rwxr-xr-xsrc/lib/tlslite/integration/ClientHelper.py163
-rwxr-xr-xsrc/lib/tlslite/integration/HTTPTLSConnection.py169
-rwxr-xr-xsrc/lib/tlslite/integration/IMAP4_TLS.py132
-rwxr-xr-xsrc/lib/tlslite/integration/IntegrationHelper.py52
-rwxr-xr-xsrc/lib/tlslite/integration/POP3_TLS.py142
-rwxr-xr-xsrc/lib/tlslite/integration/SMTP_TLS.py114
-rwxr-xr-xsrc/lib/tlslite/integration/TLSAsyncDispatcherMixIn.py139
-rwxr-xr-xsrc/lib/tlslite/integration/TLSSocketServerMixIn.py59
-rwxr-xr-xsrc/lib/tlslite/integration/TLSTwistedProtocolWrapper.py196
-rwxr-xr-xsrc/lib/tlslite/integration/XMLRPCTransport.py137
-rwxr-xr-xsrc/lib/tlslite/integration/__init__.py17
-rwxr-xr-xsrc/lib/tlslite/mathtls.py170
-rwxr-xr-xsrc/lib/tlslite/messages.py561
-rwxr-xr-xsrc/lib/tlslite/utils/AES.py31
-rwxr-xr-xsrc/lib/tlslite/utils/ASN1Parser.py34
-rwxr-xr-xsrc/lib/tlslite/utils/Cryptlib_AES.py34
-rwxr-xr-xsrc/lib/tlslite/utils/Cryptlib_RC4.py28
-rwxr-xr-xsrc/lib/tlslite/utils/Cryptlib_TripleDES.py35
-rwxr-xr-xsrc/lib/tlslite/utils/OpenSSL_AES.py49
-rwxr-xr-xsrc/lib/tlslite/utils/OpenSSL_RC4.py25
-rwxr-xr-xsrc/lib/tlslite/utils/OpenSSL_RSAKey.py148
-rwxr-xr-xsrc/lib/tlslite/utils/OpenSSL_TripleDES.py44
-rwxr-xr-xsrc/lib/tlslite/utils/PyCrypto_AES.py22
-rwxr-xr-xsrc/lib/tlslite/utils/PyCrypto_RC4.py22
-rwxr-xr-xsrc/lib/tlslite/utils/PyCrypto_RSAKey.py61
-rwxr-xr-xsrc/lib/tlslite/utils/PyCrypto_TripleDES.py22
-rwxr-xr-xsrc/lib/tlslite/utils/Python_AES.py68
-rwxr-xr-xsrc/lib/tlslite/utils/Python_RC4.py39
-rwxr-xr-xsrc/lib/tlslite/utils/Python_RSAKey.py209
-rwxr-xr-xsrc/lib/tlslite/utils/RC4.py17
-rwxr-xr-xsrc/lib/tlslite/utils/RSAKey.py264
-rwxr-xr-xsrc/lib/tlslite/utils/TripleDES.py26
-rwxr-xr-xsrc/lib/tlslite/utils/__init__.py32
-rwxr-xr-xsrc/lib/tlslite/utils/cipherfactory.py111
-rwxr-xr-xsrc/lib/tlslite/utils/codec.py94
-rwxr-xr-xsrc/lib/tlslite/utils/compat.py140
-rwxr-xr-xsrc/lib/tlslite/utils/cryptomath.py411
-rwxr-xr-xsrc/lib/tlslite/utils/dateFuncs.py75
-rwxr-xr-xsrc/lib/tlslite/utils/entropy.c173
-rwxr-xr-xsrc/lib/tlslite/utils/hmac.py104
-rwxr-xr-xsrc/lib/tlslite/utils/jython_compat.py195
-rwxr-xr-xsrc/lib/tlslite/utils/keyfactory.py243
-rw-r--r--src/lib/tlslite/utils/prngd.py62
-rwxr-xr-xsrc/lib/tlslite/utils/rijndael.py392
-rwxr-xr-xsrc/lib/tlslite/utils/win32prng.c63
-rwxr-xr-xsrc/lib/tlslite/utils/xmltools.py201
65 files changed, 606 insertions, 10624 deletions
diff --git a/src/lib/Component.py b/src/lib/Component.py
index 7cfd3b8c8..d35759603 100644
--- a/src/lib/Component.py
+++ b/src/lib/Component.py
@@ -1,330 +1,306 @@
-'''Cobalt component base classes'''
-__revision__ = '$Revision$'
+"""Cobalt component base."""
-import logging, select, signal, socket, sys, urlparse, xmlrpclib, cPickle, os, traceback
-from base64 import decodestring
+__revision__ = '$Revision$'
-import BaseHTTPServer, SimpleXMLRPCServer
-import Bcfg2.tlslite.errors
-import Bcfg2.tlslite.api
-from Bcfg2.tlslite.TLSConnection import TLSConnection
+__all__ = ["Component", "exposed", "automatic", "run_component"]
-log = logging.getLogger('Component')
+import inspect
+import os
+import cPickle
+import pydoc
+import sys
+import getopt
+import logging
+import time
+import threading
+import xmlrpclib
-class ComponentInitError(Exception):
- '''Raised in case of component initialization failure'''
- pass
+import Bcfg2.Logger
+from Bcfg2.SSLServer import XMLRPCServer
-class ComponentKeyError(Exception):
- '''raised in case of key parse fails'''
- pass
+def run_component (component_cls, argv=None, register=True, state_name=False,
+ cls_kwargs={}, extra_getopt='', time_out=10):
+ if argv is None:
+ argv = sys.argv
+ try:
+ (opts, arg) = getopt.getopt(argv[1:], 'C:D:d' + extra_getopt)
+ except getopt.GetoptError, e:
+ print >> sys.stderr, e
+ print >> sys.stderr, "Usage:"
+ print >> sys.stderr, "%s [-d] [-D pidfile] [-C config file]" % (os.path.basename(argv[0]))
+ sys.exit(1)
+
+ # default settings
+ daemon = False
+ pidfile = ""
+ level = logging.INFO
+ # get user input
+ for item in opts:
+ if item[0] == '-C':
+ #FIXME
+ cf = (item[1], )
+ elif item[0] == '-D':
+ daemon = True
+ pidfile_name = item[1]
+ elif item[0] == '-d':
+ level = logging.DEBUG
+
+ logging.getLogger().setLevel(level)
+ Bcfg2.Logger.log_to_stderr(logging.getLogger())
+ Bcfg2.Logger.setup_logging(component_cls.implementation, True, True)
-class ForkedChild(Exception):
- '''raised after child has been forked'''
- pass
+ if daemon:
+ child_pid = os.fork()
+ if child_pid != 0:
+ return
+
+ os.setsid()
+
+ child_pid = os.fork()
+ if child_pid != 0:
+ os._exit(0)
+
+ redirect_file = open("/dev/null", "w+")
+ os.dup2(redirect_file.fileno(), sys.__stdin__.fileno())
+ os.dup2(redirect_file.fileno(), sys.__stdout__.fileno())
+ os.dup2(redirect_file.fileno(), sys.__stderr__.fileno())
+
+ os.chdir(os.sep)
+ os.umask(0)
+
+ pidfile = open(pidfile_name or "/dev/null", "w")
+ print >> pidfile, os.getpid()
+ pidfile.close()
-class CobaltXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
- '''CobaltXMLRPCRequestHandler takes care of ssl xmlrpc requests'''
- masterpid = os.getpid()
+ component = component_cls(**cls_kwargs)
+
+ location = ('', 6789)
+ keypath = '/etc/bcfg2.key'
+ certfile = '/etc/bcfg2.key'
- def __init__(self, request, client_address, server):
- self.cleanup = True
- SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.__init__(self, request,
- client_address,
- server)
+ server = XMLRPCServer(location, keyfile=keypath, certfile=keypath,
+ register=register, timeout=time_out)
+ server.register_instance(component)
+
+ try:
+ server.serve_forever()
+ finally:
+ server.server_close()
- def do_POST(self):
- '''Overload do_POST to pass through client address information'''
- try:
- # get arguments
- data = self.rfile.read(int(self.headers["content-length"]))
+def exposed (func):
+ """Mark a method to be exposed publically.
+
+ Examples:
+ class MyComponent (Component):
+ @expose
+ def my_method (self, param1, param2):
+ do_stuff()
+
+ class MyComponent (Component):
+ def my_method (self, param1, param2):
+ do_stuff()
+ my_method = expose(my_method)
+ """
+ func.exposed = True
+ return func
- authenticated = False
- #try x509 cert auth (will have been completed, just checking status)
- authenticated = self.request.authenticated
- #TLSConnection can be accessed by self.request?
-
- #try httpauth
- if not authenticated and "Authorization" in self.headers:
- binauth = self.headers['Authorization'].replace("Basic ", "")
- namepass = decodestring(binauth).split(':')
- if self.server._authenticate_connection("bogus-method",
- namepass[0],
- namepass[1],
- self.client_address):
- authenticated = True
+def automatic (func, period=10):
+ """Mark a method to be run periodically."""
+ func.automatic = True
+ func.automatic_period = period
+ func.automatic_ts = -1
+ return func
- response = self.server._cobalt_marshalled_dispatch(data, self.client_address, authenticated)
- except ForkedChild:
- self.cleanup = False
- return
- except: # This should only happen if the module is buggy
- # internal error, report as HTTP server error
- log.error("Unexcepted handler failure in do_POST", exc_info=1)
- self.send_response(500)
- self.end_headers()
- else:
- # got a valid XML RPC response
- if os.getpid() != self.masterpid:
- pid = os.fork()
- if pid:
- self.cleanup = False
- return
- try:
- self.send_response(200)
- self.send_header("Content-type", "text/xml")
- self.send_header("Content-length", str(len(response)))
- self.end_headers()
- self.wfile.write(response)
-
- # shut down the connection
- self.wfile.flush()
- self.rfile.close()
- self.wfile.close()
- self.connection.sock.shutdown(2)
- #self.wfile.close()
- except socket.error:
- pass
+def locking (func):
+ """Mark a function as being internally thread safe"""
+ func.locking = True
+ return func
- def setup(self):
- '''Setup a working connection'''
- self.cleanup = True
- self.connection = self.request
- self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
- self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
+def readonly (func):
+ """Mark a function as read-only -- no data effects in component inst"""
+ func.readonly = True
+ return func
-class TLSServer(Bcfg2.tlslite.api.TLSSocketServerMixIn,
- BaseHTTPServer.HTTPServer):
- '''This class is an tlslite-using SSLServer'''
- def __init__(self, address, keyfile, certfile, handler, checker=None,
- reqCert=False):
- print keyfile, certfile
- self.sc = Bcfg2.tlslite.api.SessionCache()
- self.rc = reqCert
- self.master = os.getpid()
- x509 = Bcfg2.tlslite.api.X509()
- cdata = open(certfile).read()
- x509.parse(cdata)
- self.checker = checker
- kdata = open(keyfile).read()
- try:
- self.key = Bcfg2.tlslite.api.parsePEMKey(kdata, private=True)
- except:
- raise ComponentKeyError
- self.chain = Bcfg2.tlslite.api.X509CertChain([x509])
- BaseHTTPServer.HTTPServer.__init__(self, address, handler)
+def query (func=None, **kwargs):
+ """Mark a method to be marshalled as a query."""
+ def _query (func):
+ if kwargs.get("all_fields", True):
+ func.query_all_fields = True
+ func.query = True
+ return func
+ if func is not None:
+ return _query(func)
+ return _query
- def finish_request(self, sock, address):
- sock.settimeout(90)
- tlsConnection = TLSConnection(sock)
- if self.handshake(tlsConnection) == True:
- req = self.RequestHandlerClass(tlsConnection, address, self)
- if req.cleanup:
- tlsConnection.close()
- if os.getpid() != self.master:
- os._exit(0)
- else:
- log.error("Handshake failed")
+def marshal_query_result (items, specs=None):
+ if specs is not None:
+ fields = get_spec_fields(specs)
+ else:
+ fields = None
+ return [item.to_rx(fields) for item in items]
- def handshake(self, tlsConnection):
- try:
- tlsConnection.handshakeServer(certChain=self.chain,
- privateKey=self.key,
- sessionCache=self.sc,
- checker=self.checker,
- reqCert=self.rc)
- tlsConnection.ignoreAbruptClose = True
- #Connection authenticated during TLS handshake, no need for passwords
- if not self.checker == None:
- tlsConnection.authenticated = True
+class Component (object):
+
+ """Base component.
+
+ Intended to be served as an instance by Cobalt.Component.XMLRPCServer
+ >>> server = Cobalt.Component.XMLRPCServer(location, keyfile)
+ >>> component = Cobalt.Component.Component()
+ >>> server.serve_instance(component)
+
+ Class attributes:
+ name -- logical component name (e.g., "queue-manager", "process-manager")
+ implementation -- implementation identifier (e.g., "BlueGene/L", "BlueGene/P")
+
+ Methods:
+ save -- pickle the component to a file
+ do_tasks -- perform automatic tasks for the component
+ """
+
+ name = "component"
+ implementation = "generic"
+
+ def __init__ (self, **kwargs):
+ """Initialize a new component.
+
+ Keyword arguments:
+ statefile -- file in which to save state automatically
+ """
+ self.statefile = kwargs.get("statefile", None)
+ self.logger = logging.getLogger("%s %s" % (self.implementation, self.name))
+ self.lock = threading.Lock()
+
+ def save (self, statefile=None):
+ """Pickle the component.
+
+ Arguments:
+ statefile -- use this file, rather than component.statefile
+ """
+ statefile = statefile or self.statefile
+ if statefile:
+ temp_statefile = statefile + ".temp"
+ data = cPickle.dumps(self)
+ try:
+ fd = file(temp_statefile, "wb")
+ fd.write(data)
+ fd.close()
+ except IOError, e:
+ self.logger.error("statefile failure : %s" % e)
+ return str(e)
else:
- tlsConnection.authenticated = False
- return True
- except Bcfg2.tlslite.errors.TLSError, error:
- return False
- except socket.error:
- return False
-
-class Component(TLSServer,
- SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
- """Cobalt component providing XML-RPC access"""
- __name__ = 'Component'
- __implementation__ = 'Generic'
- __statefields__ = []
- async_funcs = []
- fork_funcs = []
- child_limit = 32
-
- def __init__(self, keyfile, certfile, password, location):
- # need to get addr
- self.shut = False
- signal.signal(signal.SIGINT, self.start_shutdown)
- signal.signal(signal.SIGTERM, self.start_shutdown)
- self.logger = logging.getLogger('Component')
- self.children = []
- self.static = True
- uparsed = urlparse.urlparse(location)[1].split(':')
- sock_loc = (uparsed[0], int(uparsed[1]))
+ os.rename(temp_statefile, statefile)
+ return "state saved to file: %s" % statefile
+ save = exposed(save)
+
+ def do_tasks (self):
+ """Perform automatic tasks for the component.
+
+ Automatic tasks are member callables with an attribute
+ automatic == True.
+ """
+ for name, func in inspect.getmembers(self, callable):
+ if getattr(func, "automatic", False):
+ need_to_lock = not getattr(func, 'locking', False)
+ if (time.time() - func.automatic_ts) > \
+ func.automatic_period:
+ if need_to_lock:
+ self.lock.acquire()
+ try:
+ mt1 = time.time()
+ func()
+ except:
+ self.logger.error("Automatic method %s failed" \
+ % (name), exc_info=1)
+ finally:
+ mt2 = time.time()
- self.password = password
+ if need_to_lock:
+ self.lock.release()
+ func.__dict__['automatic_ts'] = time.time()
+ def _resolve_exposed_method (self, method_name):
+ """Resolve an exposed method.
+
+ Arguments:
+ method_name -- name of the method to resolve
+ """
try:
- TLSServer.__init__(self, sock_loc, keyfile, certfile,
- CobaltXMLRPCRequestHandler)
- except socket.error:
- self.logger.error("Failed to bind to socket")
- raise ComponentInitError
- except ComponentKeyError:
- self.logger.error("Failed to parse key" % (keyfile))
- raise ComponentInitError
- except:
- self.logger.error("Failed to load ssl key '%s'" % (keyfile), exc_info=1)
- raise ComponentInitError
- try:
- SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self)
- except TypeError:
- SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self, False, None)
- self.logRequests = 0
- self.port = self.socket.getsockname()[1]
- self.url = "https://%s:%s" % (socket.gethostname(), self.port)
- self.logger.info("Bound to port %s" % self.port)
- self.funcs.update({'system.listMethods':self.addr_system_listMethods})
- self.atime = 0
+ func = getattr(self, method_name)
+ except AttributeError:
+ raise NoExposedMethod(method_name)
+ if not getattr(func, "exposed", False):
+ raise NoExposedMethod(method_name)
+ return func
- def _cobalt_marshalled_dispatch(self, data, address, authenticated=False):
- """Decode and dispatch XMLRPC requests. Overloaded to pass through
- client address information
+ def _dispatch (self, method, args, dispatch_dict):
+ """Custom XML-RPC dispatcher for components.
+
+ method -- XML-RPC method name
+ args -- tuple of paramaters to method
"""
- try:
- rawparams, method = xmlrpclib.loads(data)
- except:
- self.logger.error("Failed to parse request from %s" \
- % (address[0]))
- #open('/tmp/badreq', 'w').write(data)
- return xmlrpclib.dumps(xmlrpclib.Fault(4, "Bad Request"))
- if not authenticated:
- if len(rawparams) < 2:
- self.logger.error("No authentication included with request from %s" % address[0])
- return xmlrpclib.dumps(xmlrpclib.Fault(2, "No Authentication Info"))
- user = rawparams[0]
- password = rawparams[1]
- params = rawparams[2:]
- # check authentication
- if not self._authenticate_connection(method, user, password, address):
- return xmlrpclib.dumps(xmlrpclib.Fault(3, "Authentication Failure"))
+ need_to_lock = True
+ if method in dispatch_dict:
+ method_func = dispatch_dict[method]
else:
- #there is no prefixed auth info in this case
- params = rawparams[0:]
- # generate response
- try:
- # need to add waitpid code here to enforce maxchild
- if method in self.fork_funcs:
- self.clean_up_children()
- self.check_for_free_slot()
- pid = os.fork()
- if pid:
- self.children.append(pid)
- raise ForkedChild
- # all handlers must take address as the first argument
- response = self._dispatch(method, (address, ) + params)
- # wrap response in a singleton tuple
- response = (response,)
- response = xmlrpclib.dumps(response, methodresponse=1)
- except xmlrpclib.Fault, fault:
- response = xmlrpclib.dumps(fault)
- except TypeError, terror:
- self.logger.error("Client %s called function %s with wrong argument count" %
- (address[0], method), exc_info=1)
- response = xmlrpclib.dumps(xmlrpclib.Fault(4, terror.args[0]))
- except ForkedChild:
- raise
- except:
- self.logger.error("Unexpected handler failure")
- trace = sys.exc_info()
- self.logger.error("%s : %s" % (str(trace[0]), str(trace[1])))
- for line in traceback.format_exc().splitlines():
- self.logger.error(line)
- del trace
- # report exception back to server
- response = xmlrpclib.dumps(xmlrpclib.Fault(1,
- "%s:%s" % (sys.exc_type, sys.exc_value)))
- return response
-
- def clean_up_children(self):
- while True:
try:
- pid = os.waitpid(0, os.WNOHANG)[0]
- if pid:
- if pid in self.children:
- self.children.remove(pid)
- else:
- break
- except OSError:
- break
-
- def check_for_free_slot(self):
- if len(self.children) >= self.child_limit:
- self.logger.info("Reached child_limit; waiting for child exit")
- pid = os.waitpid(0, 0)[0]
- self.children.remove(pid)
-
- def _authenticate_connection(self, method, user, password, address):
- '''Authenticate new connection'''
- (user, address, method)
- return password == self.password
-
- def save_state(self):
- '''Save fields defined in __statefields__ in /var/spool/cobalt/__implementation__'''
- if self.__statefields__:
- savedata = tuple([getattr(self, field) for field in self.__statefields__])
+ method_func = self._resolve_exposed_method(method)
+ except Exception, e:
+ if getattr(e, "log", True):
+ self.logger.error(e, exc_info=True)
+ raise xmlrpclib.Fault(getattr(e, "fault_code", 1), str(e))
+
+ if getattr(method_func, 'locking', False):
+ need_to_lock = False
+ if need_to_lock:
+ lock_start = time.time()
+ self.lock.acquire()
+ lock_done = time.time()
try:
- statefile = open("/var/spool/cobalt/%s" % self.__implementation__, 'w')
- # need to flock here
- statefile.write(cPickle.dumps(savedata))
- except:
- self.logger.info("Statefile save failed; data persistence disabled")
- self.__statefields__ = []
-
- def load_state(self):
- '''Load fields defined in __statefields__ from /var/spool/cobalt/__implementation__'''
- if self.__statefields__:
- try:
- loaddata = cPickle.loads(open("/var/spool/cobalt/%s" % self.__implementation__).read())
- except:
- self.logger.info("Statefile load failed")
- return
- for field in self.__statefields__:
- setattr(self, field, loaddata[self.__statefields__.index(field)])
-
- def addr_system_listMethods(self, address):
- """get rid of the address argument and call the underlying dispatcher method"""
- return SimpleXMLRPCServer.SimpleXMLRPCDispatcher.system_listMethods(self)
-
- def get_request(self):
- '''We need to do work between requests, so select with timeout instead of blocking in accept'''
- rsockinfo = []
- while self.socket not in rsockinfo:
- if self.shut:
- raise socket.error
- for funcname in self.async_funcs:
- func = getattr(self, funcname, False)
- if callable(func):
- func()
- else:
- self.logger.error("Cannot call uncallable method %s" % (funcname))
- try:
- rsockinfo = select.select([self.socket], [], [], 10)[0]
- except select.error:
- continue
- if self.socket in rsockinfo:
- return self.socket.accept()
-
- def serve_forever(self):
- """Handle one request at a time until doomsday."""
- while not self.shut:
- self.handle_request()
+ method_start = time.time()
+ result = method_func(*args)
+ method_done = time.time()
+ except Exception, e:
+ if getattr(e, "log", True):
+ self.logger.error(e, exc_info=True)
+ raise xmlrpclib.Fault(getattr(e, "fault_code", 1), str(e))
+ finally:
+ if need_to_lock:
+ self.lock.release()
+ if getattr(method_func, "query", False):
+ if not getattr(method_func, "query_all_methods", False):
+ margs = args[:1]
+ else:
+ margs = []
+ result = marshal_query_result(result, *margs)
+ return result
- def start_shutdown(self, signum, frame):
- '''Shutdown on unexpected signals'''
- self.shut = True
+ @exposed
+ def listMethods (self):
+ """Custom XML-RPC introspective method list."""
+ return [
+ name for name, func in inspect.getmembers(self, callable)
+ if getattr(func, "exposed", False)
+ ]
+ @exposed
+ def methodHelp (self, method_name):
+ """Custom XML-RPC introspective method help.
+
+ Arguments:
+ method_name -- name of method to get help on
+ """
+ try:
+ func = self._resolve_exposed_method(method_name)
+ except NoExposedMethod:
+ return ""
+ return pydoc.getdoc(func)
+
+ def get_name (self):
+ """The name of the component."""
+ return self.name
+ get_name = exposed(get_name)
+
+ def get_implementation (self):
+ """The implementation of the component."""
+ return self.implementation
+ get_implementation = exposed(get_implementation)
diff --git a/src/lib/SSLServer.py b/src/lib/SSLServer.py
new file mode 100644
index 000000000..1ee642ce9
--- /dev/null
+++ b/src/lib/SSLServer.py
@@ -0,0 +1,326 @@
+"""Bcfg2 SSL server."""
+
+__revision__ = '$Revision$'
+
+__all__ = [
+ "SSLServer", "XMLRPCRequestHandler", "XMLRPCServer",
+ "find_intended_location",
+]
+
+import sys
+import xmlrpclib
+import socket
+import SocketServer
+import SimpleXMLRPCServer
+import base64
+import signal
+import logging
+import ssl
+import threading
+import time
+
+class ForkedChild(Exception):
+ pass
+
+class XMLRPCDispatcher (SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
+ logger = logging.getLogger("Cobalt.Server.XMLRPCDispatcher")
+ def __init__ (self, allow_none, encoding):
+ SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self,
+ allow_none,
+ encoding)
+ self.allow_none = allow_none
+ self.encoding = encoding
+
+ def _marshaled_dispatch (self, data):
+ method_func = None
+ params, method = xmlrpclib.loads(data)
+ try:
+ response = self.instance._dispatch(method, params, self.funcs)
+ response = (response,)
+ raw_response = xmlrpclib.dumps(response, methodresponse=1,
+ allow_none=self.allow_none,
+ encoding=self.encoding)
+ except xmlrpclib.Fault, fault:
+ raw_response = xmlrpclib.dumps(fault,
+ allow_none=self.allow_none,
+ encoding=self.encoding)
+ except:
+ # report exception back to server
+ raw_response = xmlrpclib.dumps(
+ xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value)),
+ allow_none=self.allow_none, encoding=self.encoding)
+ return raw_response
+
+class SSLServer (SocketServer.TCPServer, object):
+
+ """TCP server supporting SSL encryption.
+
+ Methods:
+ handshake -- perform a SSL/TLS handshake
+
+ Properties:
+ url -- A url pointing to this server.
+ """
+
+ allow_reuse_address = True
+ logger = logging.getLogger("Cobalt.Server.TCPServer")
+
+ def __init__ (self, server_address, RequestHandlerClass, keyfile=None,
+ certfile=None, reqCert=False, ca=None, timeout=None):
+
+ """Initialize the SSL-TCP server.
+
+ Arguments:
+ server_address -- address to bind to the server
+ RequestHandlerClass -- class to handle requests
+
+ Keyword arguments:
+ keyfile -- private encryption key filename (enables ssl encryption)
+ certfile -- certificate file (enables ssl encryption)
+ reqCert -- client must present certificate
+ timeout -- timeout for non-blocking request handling
+ """
+
+ all_iface_address = ('', server_address[1])
+ SocketServer.TCPServer.__init__(self, all_iface_address,
+ RequestHandlerClass)
+
+ self.socket.settimeout(timeout)
+ self.keyfile = keyfile
+ self.certfile = certfile
+ self.ca = ca
+ self.reqCert = reqCert
+
+ def get_request(self):
+ (sock, sockinfo) = self.socket.accept()
+ sslsock = ssl.wrap_socket(sock, server_side=True, certfile=self.certfile,
+ keyfile=self.keyfile)
+ return sslsock, sockinfo
+
+ def _get_url (self):
+ port = self.socket.getsockname()[1]
+ hostname = socket.gethostname()
+ protocol = "https"
+ return "%s://%s:%i" % (protocol, hostname, port)
+ url = property(_get_url)
+
+
+class XMLRPCRequestHandler (SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
+
+ """Component XML-RPC request handler.
+
+ Adds support for HTTP authentication.
+
+ Exceptions:
+ CouldNotAuthenticate -- client did not present acceptable authentication information
+
+ Methods:
+ authenticate -- prompt a check of a client's provided username and password
+ handle_one_request -- handle a single rpc (optionally authenticating)
+ """
+ logger = logging.getLogger("Cobalt.Server.XMLRPCRequestHandler")
+
+ class CouldNotAuthenticate (Exception):
+ """Client did not present acceptible authentication information."""
+
+ require_auth = True
+ credentials = {'root':'default'}
+
+ def authenticate (self):
+ """Authenticate the credentials of the latest client."""
+ try:
+ header = self.headers['Authorization']
+ except KeyError:
+ self.logger.error("No authentication data presented")
+ raise self.CouldNotAuthenticate("client did not present credentials")
+ auth_type, auth_content = header.split()
+ auth_content = base64.standard_b64decode(auth_content)
+ try:
+ username, password = auth_content.split(":")
+ except ValueError:
+ username = auth_content
+ password = ""
+ try:
+ valid_password = self.credentials[username]
+ except KeyError:
+ raise self.CouldNotAuthenticate("unknown user: %s" % username)
+ if password != valid_password:
+ raise self.CouldNotAuthenticate("invalid password for %s" % username)
+
+ def parse_request (self):
+ """Extends parse_request.
+
+ Optionally check HTTP authentication when parsing."""
+ if not SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.parse_request(self):
+ return False
+ if self.require_auth:
+ try:
+ self.authenticate()
+ except self.CouldNotAuthenticate, e:
+ self.logger.error("Authentication failed: %s" % e.args[0])
+ code = 401
+ message, _ = self.responses[401]
+ self.send_error(code, message)
+ return False
+ return True
+
+ ### FIXME need to override do_POST here
+ def do_POST(self):
+ try:
+ max_chunk_size = 10*1024*1024
+ size_remaining = int(self.headers["content-length"])
+ L = []
+ while size_remaining:
+ chunk_size = min(size_remaining, max_chunk_size)
+ L.append(self.rfile.read(chunk_size))
+ size_remaining -= len(L[-1])
+ data = ''.join(L)
+
+ response = self.server._marshaled_dispatch(data)
+ except:
+ raise
+ self.send_response(500)
+ self.end_headers()
+ else:
+ # got a valid XML RPC response
+ self.send_response(200)
+ self.send_header("Content-type", "text/xml")
+ self.send_header("Content-length", str(len(response)))
+ self.end_headers()
+ self.wfile.write(response)
+
+ # shut down the connection
+ self.wfile.flush()
+ self.connection.shutdown(1)
+
+
+class XMLRPCServer (SocketServer.ThreadingMixIn, SSLServer,
+ XMLRPCDispatcher, object):
+
+ """Component XMLRPCServer.
+
+ Methods:
+ serve_daemon -- serve_forever in a daemonized process
+ serve_forever -- handle_one_request until not self.serve
+ shutdown -- stop serve_forever (by setting self.serve = False)
+ ping -- return all arguments received
+
+ RPC methods:
+ ping
+
+ (additional system.* methods are inherited from base dispatcher)
+
+ Properties:
+ require_auth -- the request handler is requiring authorization
+ credentials -- valid credentials being used for authentication
+ """
+
+ def __init__ (self, server_address, RequestHandlerClass=None,
+ keyfile=None, certfile=None,
+ timeout=10,
+ logRequests=False,
+ register=True, allow_none=True, encoding=None):
+
+ """Initialize the XML-RPC server.
+
+ Arguments:
+ server_address -- address to bind to the server
+ RequestHandlerClass -- request handler used by TCP server (optional)
+
+ Keyword arguments:
+ keyfile -- private encryption key filename
+ certfile -- certificate file
+ logRequests -- log all requests (default False)
+ register -- presence should be reported to service-location (default True)
+ allow_none -- allow None values in xml-rpc
+ encoding -- encoding to use for xml-rpc (default UTF-8)
+ """
+
+ XMLRPCDispatcher.__init__(self, allow_none, encoding)
+
+ if not RequestHandlerClass:
+ class RequestHandlerClass (XMLRPCRequestHandler):
+ """A subclassed request handler to prevent class-attribute conflicts."""
+
+ SSLServer.__init__(self,
+ server_address, RequestHandlerClass,
+ timeout=timeout, keyfile=keyfile, certfile=certfile)
+ self.logRequests = logRequests
+ self.serve = False
+ self.register = register
+ self.register_introspection_functions()
+ self.register_function(self.ping)
+ self.task_thread = threading.Thread(target=self._tasks_thread)
+ self.logger.info("service available at %s" % self.url)
+ self.timeout = timeout
+
+ def _tasks_thread (self):
+ try:
+ while self.serve:
+ try:
+ if self.instance and hasattr(self.instance, 'do_tasks'):
+ self.instance.do_tasks()
+ except:
+ self.logger.error("Unexpected task failure", exc_info=1)
+ time.sleep(self.timeout)
+ except:
+ self.logger.error("tasks_thread failed", exc_info=1)
+
+ def server_close (self):
+ SSLServer.server_close(self)
+ self.logger.info("server_close()")
+
+ def _get_require_auth (self):
+ return getattr(self.RequestHandlerClass, "require_auth", False)
+ def _set_require_auth (self, value):
+ self.RequestHandlerClass.require_auth = value
+ require_auth = property(_get_require_auth, _set_require_auth)
+
+ def _get_credentials (self):
+ try:
+ return self.RequestHandlerClass.credentials
+ except AttributeError:
+ return dict()
+ def _set_credentials (self, value):
+ self.RequestHandlerClass.credentials = value
+ credentials = property(_get_credentials, _set_credentials)
+
+ def register_instance (self, instance, *args, **kwargs):
+ XMLRPCDispatcher.register_instance(self, instance, *args, **kwargs)
+ try:
+ name = instance.name
+ except AttributeError:
+ name = "unknown"
+ self.logger.info("serving %s at %s" % (name, self.url))
+
+ def serve_forever (self):
+ """Serve single requests until (self.serve == False)."""
+ self.serve = True
+ self.task_thread.start()
+ self.logger.info("serve_forever() [start]")
+ signal.signal(signal.SIGINT, self._handle_shutdown_signal)
+ signal.signal(signal.SIGTERM, self._handle_shutdown_signal)
+
+ try:
+ while self.serve:
+ try:
+ self.handle_request()
+ except socket.timeout:
+ pass
+ except:
+ self.logger.error("Got unexpected error in handle_request",
+ exc_info=1)
+ finally:
+ self.logger.info("serve_forever() [stop]")
+
+ def shutdown (self):
+ """Signal that automatic service should stop."""
+ self.serve = False
+
+ def _handle_shutdown_signal (self, *_):
+ self.shutdown()
+
+ def ping (self, *args):
+ """Echo response."""
+ self.logger.info("ping(%s)" % (", ".join([repr(arg) for arg in args])))
+ return args
diff --git a/src/lib/tlslite/BaseDB.py b/src/lib/tlslite/BaseDB.py
deleted file mode 100755
index f4914fb7e..000000000
--- a/src/lib/tlslite/BaseDB.py
+++ /dev/null
@@ -1,120 +0,0 @@
-"""Base class for SharedKeyDB and VerifierDB."""
-
-import anydbm
-import thread
-
-class BaseDB:
- def __init__(self, filename, type):
- self.type = type
- self.filename = filename
- if self.filename:
- self.db = None
- else:
- self.db = {}
- self.lock = thread.allocate_lock()
-
- def create(self):
- """Create a new on-disk database.
-
- @raise anydbm.error: If there's a problem creating the database.
- """
- if self.filename:
- self.db = anydbm.open(self.filename, "n") #raises anydbm.error
- self.db["--Reserved--type"] = self.type
- self.db.sync()
- else:
- self.db = {}
-
- def open(self):
- """Open a pre-existing on-disk database.
-
- @raise anydbm.error: If there's a problem opening the database.
- @raise ValueError: If the database is not of the right type.
- """
- if not self.filename:
- raise ValueError("Can only open on-disk databases")
- self.db = anydbm.open(self.filename, "w") #raises anydbm.error
- try:
- if self.db["--Reserved--type"] != self.type:
- raise ValueError("Not a %s database" % self.type)
- except KeyError:
- raise ValueError("Not a recognized database")
-
- def __getitem__(self, username):
- if self.db == None:
- raise AssertionError("DB not open")
-
- self.lock.acquire()
- try:
- valueStr = self.db[username]
- finally:
- self.lock.release()
-
- return self._getItem(username, valueStr)
-
- def __setitem__(self, username, value):
- if self.db == None:
- raise AssertionError("DB not open")
-
- valueStr = self._setItem(username, value)
-
- self.lock.acquire()
- try:
- self.db[username] = valueStr
- if self.filename:
- self.db.sync()
- finally:
- self.lock.release()
-
- def __delitem__(self, username):
- if self.db == None:
- raise AssertionError("DB not open")
-
- self.lock.acquire()
- try:
- del(self.db[username])
- if self.filename:
- self.db.sync()
- finally:
- self.lock.release()
-
- def __contains__(self, username):
- """Check if the database contains the specified username.
-
- @type username: str
- @param username: The username to check for.
-
- @rtype: bool
- @return: True if the database contains the username, False
- otherwise.
-
- """
- if self.db == None:
- raise AssertionError("DB not open")
-
- self.lock.acquire()
- try:
- return username in self.db
- finally:
- self.lock.release()
-
- def check(self, username, param):
- value = self.__getitem__(username)
- return self._checkItem(value, username, param)
-
- def keys(self):
- """Return a list of usernames in the database.
-
- @rtype: list
- @return: The usernames in the database.
- """
- if self.db == None:
- raise AssertionError("DB not open")
-
- self.lock.acquire()
- try:
- usernames = self.db.keys()
- finally:
- self.lock.release()
- usernames = [u for u in usernames if not u.startswith("--Reserved--")]
- return usernames
diff --git a/src/lib/tlslite/Checker.py b/src/lib/tlslite/Checker.py
deleted file mode 100755
index f97869762..000000000
--- a/src/lib/tlslite/Checker.py
+++ /dev/null
@@ -1,146 +0,0 @@
-"""Class for post-handshake certificate checking."""
-
-from utils.cryptomath import hashAndBase64
-from X509 import X509
-from X509CertChain import X509CertChain
-from errors import *
-
-
-class Checker:
- """This class is passed to a handshake function to check the other
- party's certificate chain.
-
- If a handshake function completes successfully, but the Checker
- judges the other party's certificate chain to be missing or
- inadequate, a subclass of
- L{tlslite.errors.TLSAuthenticationError} will be raised.
-
- Currently, the Checker can check either an X.509 or a cryptoID
- chain (for the latter, cryptoIDlib must be installed).
- """
-
- def __init__(self, cryptoID=None, protocol=None,
- x509Fingerprint=None,
- x509TrustList=None, x509CommonName=None,
- checkResumedSession=False):
- """Create a new Checker instance.
-
- You must pass in one of these argument combinations:
- - cryptoID[, protocol] (requires cryptoIDlib)
- - x509Fingerprint
- - x509TrustList[, x509CommonName] (requires cryptlib_py)
-
- @type cryptoID: str
- @param cryptoID: A cryptoID which the other party's certificate
- chain must match. The cryptoIDlib module must be installed.
- Mutually exclusive with all of the 'x509...' arguments.
-
- @type protocol: str
- @param protocol: A cryptoID protocol URI which the other
- party's certificate chain must match. Requires the 'cryptoID'
- argument.
-
- @type x509Fingerprint: str
- @param x509Fingerprint: A hex-encoded X.509 end-entity
- fingerprint which the other party's end-entity certificate must
- match. Mutually exclusive with the 'cryptoID' and
- 'x509TrustList' arguments.
-
- @type x509TrustList: list of L{tlslite.X509.X509}
- @param x509TrustList: A list of trusted root certificates. The
- other party must present a certificate chain which extends to
- one of these root certificates. The cryptlib_py module must be
- installed. Mutually exclusive with the 'cryptoID' and
- 'x509Fingerprint' arguments.
-
- @type x509CommonName: str
- @param x509CommonName: The end-entity certificate's 'CN' field
- must match this value. For a web server, this is typically a
- server name such as 'www.amazon.com'. Mutually exclusive with
- the 'cryptoID' and 'x509Fingerprint' arguments. Requires the
- 'x509TrustList' argument.
-
- @type checkResumedSession: bool
- @param checkResumedSession: If resumed sessions should be
- checked. This defaults to False, on the theory that if the
- session was checked once, we don't need to bother
- re-checking it.
- """
-
- if cryptoID and (x509Fingerprint or x509TrustList):
- raise ValueError()
- if x509Fingerprint and x509TrustList:
- raise ValueError()
- if x509CommonName and not x509TrustList:
- raise ValueError()
- if protocol and not cryptoID:
- raise ValueError()
- if cryptoID:
- import cryptoIDlib #So we raise an error here
- if x509TrustList:
- import cryptlib_py #So we raise an error here
- self.cryptoID = cryptoID
- self.protocol = protocol
- self.x509Fingerprint = x509Fingerprint
- self.x509TrustList = x509TrustList
- self.x509CommonName = x509CommonName
- self.checkResumedSession = checkResumedSession
-
- def __call__(self, connection):
- """Check a TLSConnection.
-
- When a Checker is passed to a handshake function, this will
- be called at the end of the function.
-
- @type connection: L{tlslite.TLSConnection.TLSConnection}
- @param connection: The TLSConnection to examine.
-
- @raise tlslite.errors.TLSAuthenticationError: If the other
- party's certificate chain is missing or bad.
- """
- if not self.checkResumedSession and connection.resumed:
- return
-
- if self.cryptoID or self.x509Fingerprint or self.x509TrustList:
- if connection._client:
- chain = connection.session.serverCertChain
- else:
- chain = connection.session.clientCertChain
-
- if self.x509Fingerprint or self.x509TrustList:
- if isinstance(chain, X509CertChain):
- if self.x509Fingerprint:
- if chain.getFingerprint() != self.x509Fingerprint:
- raise TLSFingerprintError(\
- "X.509 fingerprint mismatch: %s, %s" % \
- (chain.getFingerprint(), self.x509Fingerprint))
- else: #self.x509TrustList
- if not chain.validate(self.x509TrustList):
- raise TLSValidationError("X.509 validation failure")
- if self.x509CommonName and \
- (chain.getCommonName() != self.x509CommonName):
- raise TLSAuthorizationError(\
- "X.509 Common Name mismatch: %s, %s" % \
- (chain.getCommonName(), self.x509CommonName))
- elif chain:
- raise TLSAuthenticationTypeError()
- else:
- raise TLSNoAuthenticationError()
- elif self.cryptoID:
- import cryptoIDlib.CertChain
- if isinstance(chain, cryptoIDlib.CertChain.CertChain):
- if chain.cryptoID != self.cryptoID:
- raise TLSFingerprintError(\
- "cryptoID mismatch: %s, %s" % \
- (chain.cryptoID, self.cryptoID))
- if self.protocol:
- if not chain.checkProtocol(self.protocol):
- raise TLSAuthorizationError(\
- "cryptoID protocol mismatch")
- if not chain.validate():
- raise TLSValidationError("cryptoID validation failure")
- elif chain:
- raise TLSAuthenticationTypeError()
- else:
- raise TLSNoAuthenticationError()
-
diff --git a/src/lib/tlslite/FileObject.py b/src/lib/tlslite/FileObject.py
deleted file mode 100755
index 6ee02b243..000000000
--- a/src/lib/tlslite/FileObject.py
+++ /dev/null
@@ -1,220 +0,0 @@
-"""Class returned by TLSConnection.makefile()."""
-
-class FileObject:
- """This class provides a file object interface to a
- L{tlslite.TLSConnection.TLSConnection}.
-
- Call makefile() on a TLSConnection to create a FileObject instance.
-
- This class was copied, with minor modifications, from the
- _fileobject class in socket.py. Note that fileno() is not
- implemented."""
-
- default_bufsize = 16384 #TREV: changed from 8192
-
- def __init__(self, sock, mode='rb', bufsize=-1):
- self._sock = sock
- self.mode = mode # Not actually used in this version
- if bufsize < 0:
- bufsize = self.default_bufsize
- self.bufsize = bufsize
- self.softspace = False
- if bufsize == 0:
- self._rbufsize = 1
- elif bufsize == 1:
- self._rbufsize = self.default_bufsize
- else:
- self._rbufsize = bufsize
- self._wbufsize = bufsize
- self._rbuf = "" # A string
- self._wbuf = [] # A list of strings
-
- def _getclosed(self):
- return self._sock is not None
- closed = property(_getclosed, doc="True if the file is closed")
-
- def close(self):
- try:
- if self._sock:
- for result in self._sock._decrefAsync(): #TREV
- pass
- finally:
- self._sock = None
-
- def __del__(self):
- try:
- self.close()
- except:
- # close() may fail if __init__ didn't complete
- pass
-
- def flush(self):
- if self._wbuf:
- buffer = "".join(self._wbuf)
- self._wbuf = []
- self._sock.sendall(buffer)
-
- #def fileno(self):
- # raise NotImplementedError() #TREV
-
- def write(self, data):
- data = str(data) # XXX Should really reject non-string non-buffers
- if not data:
- return
- self._wbuf.append(data)
- if (self._wbufsize == 0 or
- self._wbufsize == 1 and '\n' in data or
- self._get_wbuf_len() >= self._wbufsize):
- self.flush()
-
- def writelines(self, list):
- # XXX We could do better here for very long lists
- # XXX Should really reject non-string non-buffers
- self._wbuf.extend(filter(None, map(str, list)))
- if (self._wbufsize <= 1 or
- self._get_wbuf_len() >= self._wbufsize):
- self.flush()
-
- def _get_wbuf_len(self):
- buf_len = 0
- for x in self._wbuf:
- buf_len += len(x)
- return buf_len
-
- def read(self, size=-1):
- data = self._rbuf
- if size < 0:
- # Read until EOF
- buffers = []
- if data:
- buffers.append(data)
- self._rbuf = ""
- if self._rbufsize <= 1:
- recv_size = self.default_bufsize
- else:
- recv_size = self._rbufsize
- while True:
- data = self._sock.recv(recv_size)
- if not data:
- break
- buffers.append(data)
- return "".join(buffers)
- else:
- # Read until size bytes or EOF seen, whichever comes first
- buf_len = len(data)
- if buf_len >= size:
- self._rbuf = data[size:]
- return data[:size]
- buffers = []
- if data:
- buffers.append(data)
- self._rbuf = ""
- while True:
- left = size - buf_len
- recv_size = max(self._rbufsize, left)
- data = self._sock.recv(recv_size)
- if not data:
- break
- buffers.append(data)
- n = len(data)
- if n >= left:
- self._rbuf = data[left:]
- buffers[-1] = data[:left]
- break
- buf_len += n
- return "".join(buffers)
-
- def readline(self, size=-1):
- data = self._rbuf
- if size < 0:
- # Read until \n or EOF, whichever comes first
- if self._rbufsize <= 1:
- # Speed up unbuffered case
- assert data == ""
- buffers = []
- recv = self._sock.recv
- while data != "\n":
- data = recv(1)
- if not data:
- break
- buffers.append(data)
- return "".join(buffers)
- nl = data.find('\n')
- if nl >= 0:
- nl += 1
- self._rbuf = data[nl:]
- return data[:nl]
- buffers = []
- if data:
- buffers.append(data)
- self._rbuf = ""
- while True:
- data = self._sock.recv(self._rbufsize)
- if not data:
- break
- buffers.append(data)
- nl = data.find('\n')
- if nl >= 0:
- nl += 1
- self._rbuf = data[nl:]
- buffers[-1] = data[:nl]
- break
- return "".join(buffers)
- else:
- # Read until size bytes or \n or EOF seen, whichever comes first
- nl = data.find('\n', 0, size)
- if nl >= 0:
- nl += 1
- self._rbuf = data[nl:]
- return data[:nl]
- buf_len = len(data)
- if buf_len >= size:
- self._rbuf = data[size:]
- return data[:size]
- buffers = []
- if data:
- buffers.append(data)
- self._rbuf = ""
- while True:
- data = self._sock.recv(self._rbufsize)
- if not data:
- break
- buffers.append(data)
- left = size - buf_len
- nl = data.find('\n', 0, left)
- if nl >= 0:
- nl += 1
- self._rbuf = data[nl:]
- buffers[-1] = data[:nl]
- break
- n = len(data)
- if n >= left:
- self._rbuf = data[left:]
- buffers[-1] = data[:left]
- break
- buf_len += n
- return "".join(buffers)
-
- def readlines(self, sizehint=0):
- total = 0
- list = []
- while True:
- line = self.readline()
- if not line:
- break
- list.append(line)
- total += len(line)
- if sizehint and total >= sizehint:
- break
- return list
-
- # Iterator protocols
-
- def __iter__(self):
- return self
-
- def next(self):
- line = self.readline()
- if not line:
- raise StopIteration
- return line
diff --git a/src/lib/tlslite/HandshakeSettings.py b/src/lib/tlslite/HandshakeSettings.py
deleted file mode 100755
index c7c3223e5..000000000
--- a/src/lib/tlslite/HandshakeSettings.py
+++ /dev/null
@@ -1,159 +0,0 @@
-"""Class for setting handshake parameters."""
-
-from constants import CertificateType
-from utils import cryptomath
-from utils import cipherfactory
-
-class HandshakeSettings:
- """This class encapsulates various parameters that can be used with
- a TLS handshake.
- @sort: minKeySize, maxKeySize, cipherNames, certificateTypes,
- minVersion, maxVersion
-
- @type minKeySize: int
- @ivar minKeySize: The minimum bit length for asymmetric keys.
-
- If the other party tries to use SRP, RSA, or Diffie-Hellman
- parameters smaller than this length, an alert will be
- signalled. The default is 1023.
-
- @type maxKeySize: int
- @ivar maxKeySize: The maximum bit length for asymmetric keys.
-
- If the other party tries to use SRP, RSA, or Diffie-Hellman
- parameters larger than this length, an alert will be signalled.
- The default is 8193.
-
- @type cipherNames: list
- @ivar cipherNames: The allowed ciphers, in order of preference.
-
- The allowed values in this list are 'aes256', 'aes128', '3des', and
- 'rc4'. If these settings are used with a client handshake, they
- determine the order of the ciphersuites offered in the ClientHello
- message.
-
- If these settings are used with a server handshake, the server will
- choose whichever ciphersuite matches the earliest entry in this
- list.
-
- NOTE: If '3des' is used in this list, but TLS Lite can't find an
- add-on library that supports 3DES, then '3des' will be silently
- removed.
-
- The default value is ['aes256', 'aes128', '3des', 'rc4'].
-
- @type certificateTypes: list
- @ivar certificateTypes: The allowed certificate types, in order of
- preference.
-
- The allowed values in this list are 'x509' and 'cryptoID'. This
- list is only used with a client handshake. The client will
- advertise to the server which certificate types are supported, and
- will check that the server uses one of the appropriate types.
-
- NOTE: If 'cryptoID' is used in this list, but cryptoIDlib is not
- installed, then 'cryptoID' will be silently removed.
-
- @type minVersion: tuple
- @ivar minVersion: The minimum allowed SSL/TLS version.
-
- This variable can be set to (3,0) for SSL 3.0, (3,1) for
- TLS 1.0, or (3,2) for TLS 1.1. If the other party wishes to
- use a lower version, a protocol_version alert will be signalled.
- The default is (3,0).
-
- @type maxVersion: tuple
- @ivar maxVersion: The maximum allowed SSL/TLS version.
-
- This variable can be set to (3,0) for SSL 3.0, (3,1) for
- TLS 1.0, or (3,2) for TLS 1.1. If the other party wishes to
- use a higher version, a protocol_version alert will be signalled.
- The default is (3,2). (WARNING: Some servers may (improperly)
- reject clients which offer support for TLS 1.1. In this case,
- try lowering maxVersion to (3,1)).
- """
- def __init__(self):
- self.minKeySize = 1023
- self.maxKeySize = 8193
- self.cipherNames = ["aes256", "aes128", "3des", "rc4"]
- self.cipherImplementations = ["cryptlib", "openssl", "pycrypto",
- "python"]
- self.certificateTypes = ["x509", "cryptoID"]
- self.minVersion = (3,0)
- self.maxVersion = (3,2)
-
- #Filters out options that are not supported
- def _filter(self):
- other = HandshakeSettings()
- other.minKeySize = self.minKeySize
- other.maxKeySize = self.maxKeySize
- other.cipherNames = self.cipherNames
- other.cipherImplementations = self.cipherImplementations
- other.certificateTypes = self.certificateTypes
- other.minVersion = self.minVersion
- other.maxVersion = self.maxVersion
-
- if not cipherfactory.tripleDESPresent:
- other.cipherNames = [e for e in self.cipherNames if e != "3des"]
- if len(other.cipherNames)==0:
- raise ValueError("No supported ciphers")
-
- try:
- import cryptoIDlib
- except ImportError:
- other.certificateTypes = [e for e in self.certificateTypes \
- if e != "cryptoID"]
- if len(other.certificateTypes)==0:
- raise ValueError("No supported certificate types")
-
- if not cryptomath.cryptlibpyLoaded:
- other.cipherImplementations = [e for e in \
- self.cipherImplementations if e != "cryptlib"]
- if not cryptomath.m2cryptoLoaded:
- other.cipherImplementations = [e for e in \
- other.cipherImplementations if e != "openssl"]
- if not cryptomath.pycryptoLoaded:
- other.cipherImplementations = [e for e in \
- other.cipherImplementations if e != "pycrypto"]
- if len(other.cipherImplementations)==0:
- raise ValueError("No supported cipher implementations")
-
- if other.minKeySize<512:
- raise ValueError("minKeySize too small")
- if other.minKeySize>16384:
- raise ValueError("minKeySize too large")
- if other.maxKeySize<512:
- raise ValueError("maxKeySize too small")
- if other.maxKeySize>16384:
- raise ValueError("maxKeySize too large")
- for s in other.cipherNames:
- if s not in ("aes256", "aes128", "rc4", "3des"):
- raise ValueError("Unknown cipher name: '%s'" % s)
- for s in other.cipherImplementations:
- if s not in ("cryptlib", "openssl", "python", "pycrypto"):
- raise ValueError("Unknown cipher implementation: '%s'" % s)
- for s in other.certificateTypes:
- if s not in ("x509", "cryptoID"):
- raise ValueError("Unknown certificate type: '%s'" % s)
-
- if other.minVersion > other.maxVersion:
- raise ValueError("Versions set incorrectly")
-
- if not other.minVersion in ((3,0), (3,1), (3,2)):
- raise ValueError("minVersion set incorrectly")
-
- if not other.maxVersion in ((3,0), (3,1), (3,2)):
- raise ValueError("maxVersion set incorrectly")
-
- return other
-
- def _getCertificateTypes(self):
- l = []
- for ct in self.certificateTypes:
- if ct == "x509":
- l.append(CertificateType.x509)
- elif ct == "cryptoID":
- l.append(CertificateType.cryptoID)
- else:
- raise AssertionError()
- return l
diff --git a/src/lib/tlslite/Session.py b/src/lib/tlslite/Session.py
deleted file mode 100755
index a951f4589..000000000
--- a/src/lib/tlslite/Session.py
+++ /dev/null
@@ -1,131 +0,0 @@
-"""Class representing a TLS session."""
-
-from utils.compat import *
-from mathtls import *
-from constants import *
-
-class Session:
- """
- This class represents a TLS session.
-
- TLS distinguishes between connections and sessions. A new
- handshake creates both a connection and a session. Data is
- transmitted over the connection.
-
- The session contains a more permanent record of the handshake. The
- session can be inspected to determine handshake results. The
- session can also be used to create a new connection through
- "session resumption". If the client and server both support this,
- they can create a new connection based on an old session without
- the overhead of a full handshake.
-
- The session for a L{tlslite.TLSConnection.TLSConnection} can be
- retrieved from the connection's 'session' attribute.
-
- @type srpUsername: str
- @ivar srpUsername: The client's SRP username (or None).
-
- @type sharedKeyUsername: str
- @ivar sharedKeyUsername: The client's shared-key username (or
- None).
-
- @type clientCertChain: L{tlslite.X509CertChain.X509CertChain} or
- L{cryptoIDlib.CertChain.CertChain}
- @ivar clientCertChain: The client's certificate chain (or None).
-
- @type serverCertChain: L{tlslite.X509CertChain.X509CertChain} or
- L{cryptoIDlib.CertChain.CertChain}
- @ivar serverCertChain: The server's certificate chain (or None).
- """
-
- def __init__(self):
- self.masterSecret = createByteArraySequence([])
- self.sessionID = createByteArraySequence([])
- self.cipherSuite = 0
- self.srpUsername = None
- self.sharedKeyUsername = None
- self.clientCertChain = None
- self.serverCertChain = None
- self.resumable = False
- self.sharedKey = False
-
- def _clone(self):
- other = Session()
- other.masterSecret = self.masterSecret
- other.sessionID = self.sessionID
- other.cipherSuite = self.cipherSuite
- other.srpUsername = self.srpUsername
- other.sharedKeyUsername = self.sharedKeyUsername
- other.clientCertChain = self.clientCertChain
- other.serverCertChain = self.serverCertChain
- other.resumable = self.resumable
- other.sharedKey = self.sharedKey
- return other
-
- def _calcMasterSecret(self, version, premasterSecret, clientRandom,
- serverRandom):
- if version == (3,0):
- self.masterSecret = PRF_SSL(premasterSecret,
- concatArrays(clientRandom, serverRandom), 48)
- elif version in ((3,1), (3,2)):
- self.masterSecret = PRF(premasterSecret, "master secret",
- concatArrays(clientRandom, serverRandom), 48)
- else:
- raise AssertionError()
-
- def valid(self):
- """If this session can be used for session resumption.
-
- @rtype: bool
- @return: If this session can be used for session resumption.
- """
- return self.resumable or self.sharedKey
-
- def _setResumable(self, boolean):
- #Only let it be set if this isn't a shared key
- if not self.sharedKey:
- #Only let it be set to True if the sessionID is non-null
- if (not boolean) or (boolean and self.sessionID):
- self.resumable = boolean
-
- def getCipherName(self):
- """Get the name of the cipher used with this connection.
-
- @rtype: str
- @return: The name of the cipher used with this connection.
- Either 'aes128', 'aes256', 'rc4', or '3des'.
- """
- if self.cipherSuite in CipherSuite.aes128Suites:
- return "aes128"
- elif self.cipherSuite in CipherSuite.aes256Suites:
- return "aes256"
- elif self.cipherSuite in CipherSuite.rc4Suites:
- return "rc4"
- elif self.cipherSuite in CipherSuite.tripleDESSuites:
- return "3des"
- else:
- return None
-
- def _createSharedKey(self, sharedKeyUsername, sharedKey):
- if len(sharedKeyUsername)>16:
- raise ValueError()
- if len(sharedKey)>47:
- raise ValueError()
-
- self.sharedKeyUsername = sharedKeyUsername
-
- self.sessionID = createByteArrayZeros(16)
- for x in range(len(sharedKeyUsername)):
- self.sessionID[x] = ord(sharedKeyUsername[x])
-
- premasterSecret = createByteArrayZeros(48)
- sharedKey = chr(len(sharedKey)) + sharedKey
- for x in range(48):
- premasterSecret[x] = ord(sharedKey[x % len(sharedKey)])
-
- self.masterSecret = PRF(premasterSecret, "shared secret",
- createByteArraySequence([]), 48)
- self.sharedKey = True
- return self
-
-
diff --git a/src/lib/tlslite/SessionCache.py b/src/lib/tlslite/SessionCache.py
deleted file mode 100755
index 34cf0b0ec..000000000
--- a/src/lib/tlslite/SessionCache.py
+++ /dev/null
@@ -1,103 +0,0 @@
-"""Class for caching TLS sessions."""
-
-import thread
-import time
-
-class SessionCache:
- """This class is used by the server to cache TLS sessions.
-
- Caching sessions allows the client to use TLS session resumption
- and avoid the expense of a full handshake. To use this class,
- simply pass a SessionCache instance into the server handshake
- function.
-
- This class is thread-safe.
- """
-
- #References to these instances
- #are also held by the caller, who may change the 'resumable'
- #flag, so the SessionCache must return the same instances
- #it was passed in.
-
- def __init__(self, maxEntries=10000, maxAge=14400):
- """Create a new SessionCache.
-
- @type maxEntries: int
- @param maxEntries: The maximum size of the cache. When this
- limit is reached, the oldest sessions will be deleted as
- necessary to make room for new ones. The default is 10000.
-
- @type maxAge: int
- @param maxAge: The number of seconds before a session expires
- from the cache. The default is 14400 (i.e. 4 hours)."""
-
- self.lock = thread.allocate_lock()
-
- # Maps sessionIDs to sessions
- self.entriesDict = {}
-
- #Circular list of (sessionID, timestamp) pairs
- self.entriesList = [(None,None)] * maxEntries
-
- self.firstIndex = 0
- self.lastIndex = 0
- self.maxAge = maxAge
-
- def __getitem__(self, sessionID):
- self.lock.acquire()
- try:
- self._purge() #Delete old items, so we're assured of a new one
- session = self.entriesDict[sessionID]
-
- #When we add sessions they're resumable, but it's possible
- #for the session to be invalidated later on (if a fatal alert
- #is returned), so we have to check for resumability before
- #returning the session.
-
- if session.valid():
- return session
- else:
- raise KeyError()
- finally:
- self.lock.release()
-
-
- def __setitem__(self, sessionID, session):
- self.lock.acquire()
- try:
- #Add the new element
- self.entriesDict[sessionID] = session
- self.entriesList[self.lastIndex] = (sessionID, time.time())
- self.lastIndex = (self.lastIndex+1) % len(self.entriesList)
-
- #If the cache is full, we delete the oldest element to make an
- #empty space
- if self.lastIndex == self.firstIndex:
- del(self.entriesDict[self.entriesList[self.firstIndex][0]])
- self.firstIndex = (self.firstIndex+1) % len(self.entriesList)
- finally:
- self.lock.release()
-
- #Delete expired items
- def _purge(self):
- currentTime = time.time()
-
- #Search through the circular list, deleting expired elements until
- #we reach a non-expired element. Since elements in list are
- #ordered in time, we can break once we reach the first non-expired
- #element
- index = self.firstIndex
- while index != self.lastIndex:
- if currentTime - self.entriesList[index][1] > self.maxAge:
- del(self.entriesDict[self.entriesList[index][0]])
- index = (index+1) % len(self.entriesList)
- else:
- break
- self.firstIndex = index
-
-def _test():
- import doctest, SessionCache
- return doctest.testmod(SessionCache)
-
-if __name__ == "__main__":
- _test()
diff --git a/src/lib/tlslite/SharedKeyDB.py b/src/lib/tlslite/SharedKeyDB.py
deleted file mode 100755
index 3246ec7f1..000000000
--- a/src/lib/tlslite/SharedKeyDB.py
+++ /dev/null
@@ -1,58 +0,0 @@
-"""Class for storing shared keys."""
-
-from utils.cryptomath import *
-from utils.compat import *
-from mathtls import *
-from Session import Session
-from BaseDB import BaseDB
-
-class SharedKeyDB(BaseDB):
- """This class represent an in-memory or on-disk database of shared
- keys.
-
- A SharedKeyDB can be passed to a server handshake function to
- authenticate a client based on one of the shared keys.
-
- This class is thread-safe.
- """
-
- def __init__(self, filename=None):
- """Create a new SharedKeyDB.
-
- @type filename: str
- @param filename: Filename for an on-disk database, or None for
- an in-memory database. If the filename already exists, follow
- this with a call to open(). To create a new on-disk database,
- follow this with a call to create().
- """
- BaseDB.__init__(self, filename, "shared key")
-
- def _getItem(self, username, valueStr):
- session = Session()
- session._createSharedKey(username, valueStr)
- return session
-
- def __setitem__(self, username, sharedKey):
- """Add a shared key to the database.
-
- @type username: str
- @param username: The username to associate the shared key with.
- Must be less than or equal to 16 characters in length, and must
- not already be in the database.
-
- @type sharedKey: str
- @param sharedKey: The shared key to add. Must be less than 48
- characters in length.
- """
- BaseDB.__setitem__(self, username, sharedKey)
-
- def _setItem(self, username, value):
- if len(username)>16:
- raise ValueError("username too long")
- if len(value)>=48:
- raise ValueError("shared key too long")
- return value
-
- def _checkItem(self, value, username, param):
- newSession = self._getItem(username, param)
- return value.masterSecret == newSession.masterSecret \ No newline at end of file
diff --git a/src/lib/tlslite/TLSConnection.py b/src/lib/tlslite/TLSConnection.py
deleted file mode 100755
index d125f8f0a..000000000
--- a/src/lib/tlslite/TLSConnection.py
+++ /dev/null
@@ -1,1600 +0,0 @@
-"""
-MAIN CLASS FOR TLS LITE (START HERE!).
-"""
-from __future__ import generators
-
-import socket
-from utils.compat import formatExceptionTrace
-from TLSRecordLayer import TLSRecordLayer
-from Session import Session
-from constants import *
-from utils.cryptomath import getRandomBytes
-from errors import *
-from messages import *
-from mathtls import *
-from HandshakeSettings import HandshakeSettings
-
-
-class TLSConnection(TLSRecordLayer):
- """
- This class wraps a socket and provides TLS handshaking and data
- transfer.
-
- To use this class, create a new instance, passing a connected
- socket into the constructor. Then call some handshake function.
- If the handshake completes without raising an exception, then a TLS
- connection has been negotiated. You can transfer data over this
- connection as if it were a socket.
-
- This class provides both synchronous and asynchronous versions of
- its key functions. The synchronous versions should be used when
- writing single-or multi-threaded code using blocking sockets. The
- asynchronous versions should be used when performing asynchronous,
- event-based I/O with non-blocking sockets.
-
- Asynchronous I/O is a complicated subject; typically, you should
- not use the asynchronous functions directly, but should use some
- framework like asyncore or Twisted which TLS Lite integrates with
- (see
- L{tlslite.integration.TLSAsyncDispatcherMixIn.TLSAsyncDispatcherMixIn} or
- L{tlslite.integration.TLSTwistedProtocolWrapper.TLSTwistedProtocolWrapper}).
- """
-
-
- def __init__(self, sock):
- """Create a new TLSConnection instance.
-
- @param sock: The socket data will be transmitted on. The
- socket should already be connected. It may be in blocking or
- non-blocking mode.
-
- @type sock: L{socket.socket}
- """
- TLSRecordLayer.__init__(self, sock)
-
- def handshakeClientSRP(self, username, password, session=None,
- settings=None, checker=None, async=False):
- """Perform an SRP handshake in the role of client.
-
- This function performs a TLS/SRP handshake. SRP mutually
- authenticates both parties to each other using only a
- username and password. This function may also perform a
- combined SRP and server-certificate handshake, if the server
- chooses to authenticate itself with a certificate chain in
- addition to doing SRP.
-
- TLS/SRP is non-standard. Most TLS implementations don't
- support it. See
- U{http://www.ietf.org/html.charters/tls-charter.html} or
- U{http://trevp.net/tlssrp/} for the latest information on
- TLS/SRP.
-
- Like any handshake function, this can be called on a closed
- TLS connection, or on a TLS connection that is already open.
- If called on an open connection it performs a re-handshake.
-
- If the function completes without raising an exception, the
- TLS connection will be open and available for data transfer.
-
- If an exception is raised, the connection will have been
- automatically closed (if it was ever open).
-
- @type username: str
- @param username: The SRP username.
-
- @type password: str
- @param password: The SRP password.
-
- @type session: L{tlslite.Session.Session}
- @param session: A TLS session to attempt to resume. This
- session must be an SRP session performed with the same username
- and password as were passed in. If the resumption does not
- succeed, a full SRP handshake will be performed.
-
- @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
- @param settings: Various settings which can be used to control
- the ciphersuites, certificate types, and SSL/TLS versions
- offered by the client.
-
- @type checker: L{tlslite.Checker.Checker}
- @param checker: A Checker instance. This instance will be
- invoked to examine the other party's authentication
- credentials, if the handshake completes succesfully.
-
- @type async: bool
- @param async: If False, this function will block until the
- handshake is completed. If True, this function will return a
- generator. Successive invocations of the generator will
- return 0 if it is waiting to read from the socket, 1 if it is
- waiting to write to the socket, or will raise StopIteration if
- the handshake operation is completed.
-
- @rtype: None or an iterable
- @return: If 'async' is True, a generator object will be
- returned.
-
- @raise socket.error: If a socket error occurs.
- @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
- without a preceding alert.
- @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
- @raise tlslite.errors.TLSAuthenticationError: If the checker
- doesn't like the other party's authentication credentials.
- """
- handshaker = self._handshakeClientAsync(srpParams=(username, password),
- session=session, settings=settings, checker=checker)
- if async:
- return handshaker
- for result in handshaker:
- pass
-
- def handshakeClientCert(self, certChain=None, privateKey=None,
- session=None, settings=None, checker=None,
- async=False):
- """Perform a certificate-based handshake in the role of client.
-
- This function performs an SSL or TLS handshake. The server
- will authenticate itself using an X.509 or cryptoID certificate
- chain. If the handshake succeeds, the server's certificate
- chain will be stored in the session's serverCertChain attribute.
- Unless a checker object is passed in, this function does no
- validation or checking of the server's certificate chain.
-
- If the server requests client authentication, the
- client will send the passed-in certificate chain, and use the
- passed-in private key to authenticate itself. If no
- certificate chain and private key were passed in, the client
- will attempt to proceed without client authentication. The
- server may or may not allow this.
-
- Like any handshake function, this can be called on a closed
- TLS connection, or on a TLS connection that is already open.
- If called on an open connection it performs a re-handshake.
-
- If the function completes without raising an exception, the
- TLS connection will be open and available for data transfer.
-
- If an exception is raised, the connection will have been
- automatically closed (if it was ever open).
-
- @type certChain: L{tlslite.X509CertChain.X509CertChain} or
- L{cryptoIDlib.CertChain.CertChain}
- @param certChain: The certificate chain to be used if the
- server requests client authentication.
-
- @type privateKey: L{tlslite.utils.RSAKey.RSAKey}
- @param privateKey: The private key to be used if the server
- requests client authentication.
-
- @type session: L{tlslite.Session.Session}
- @param session: A TLS session to attempt to resume. If the
- resumption does not succeed, a full handshake will be
- performed.
-
- @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
- @param settings: Various settings which can be used to control
- the ciphersuites, certificate types, and SSL/TLS versions
- offered by the client.
-
- @type checker: L{tlslite.Checker.Checker}
- @param checker: A Checker instance. This instance will be
- invoked to examine the other party's authentication
- credentials, if the handshake completes succesfully.
-
- @type async: bool
- @param async: If False, this function will block until the
- handshake is completed. If True, this function will return a
- generator. Successive invocations of the generator will
- return 0 if it is waiting to read from the socket, 1 if it is
- waiting to write to the socket, or will raise StopIteration if
- the handshake operation is completed.
-
- @rtype: None or an iterable
- @return: If 'async' is True, a generator object will be
- returned.
-
- @raise socket.error: If a socket error occurs.
- @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
- without a preceding alert.
- @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
- @raise tlslite.errors.TLSAuthenticationError: If the checker
- doesn't like the other party's authentication credentials.
- """
- handshaker = self._handshakeClientAsync(certParams=(certChain,
- privateKey), session=session, settings=settings,
- checker=checker)
- if async:
- return handshaker
- for result in handshaker:
- pass
-
- def handshakeClientUnknown(self, srpCallback=None, certCallback=None,
- session=None, settings=None, checker=None,
- async=False):
- """Perform a to-be-determined type of handshake in the role of client.
-
- This function performs an SSL or TLS handshake. If the server
- requests client certificate authentication, the
- certCallback will be invoked and should return a (certChain,
- privateKey) pair. If the callback returns None, the library
- will attempt to proceed without client authentication. The
- server may or may not allow this.
-
- If the server requests SRP authentication, the srpCallback
- will be invoked and should return a (username, password) pair.
- If the callback returns None, the local implementation will
- signal a user_canceled error alert.
-
- After the handshake completes, the client can inspect the
- connection's session attribute to determine what type of
- authentication was performed.
-
- Like any handshake function, this can be called on a closed
- TLS connection, or on a TLS connection that is already open.
- If called on an open connection it performs a re-handshake.
-
- If the function completes without raising an exception, the
- TLS connection will be open and available for data transfer.
-
- If an exception is raised, the connection will have been
- automatically closed (if it was ever open).
-
- @type srpCallback: callable
- @param srpCallback: The callback to be used if the server
- requests SRP authentication. If None, the client will not
- offer support for SRP ciphersuites.
-
- @type certCallback: callable
- @param certCallback: The callback to be used if the server
- requests client certificate authentication.
-
- @type session: L{tlslite.Session.Session}
- @param session: A TLS session to attempt to resume. If the
- resumption does not succeed, a full handshake will be
- performed.
-
- @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
- @param settings: Various settings which can be used to control
- the ciphersuites, certificate types, and SSL/TLS versions
- offered by the client.
-
- @type checker: L{tlslite.Checker.Checker}
- @param checker: A Checker instance. This instance will be
- invoked to examine the other party's authentication
- credentials, if the handshake completes succesfully.
-
- @type async: bool
- @param async: If False, this function will block until the
- handshake is completed. If True, this function will return a
- generator. Successive invocations of the generator will
- return 0 if it is waiting to read from the socket, 1 if it is
- waiting to write to the socket, or will raise StopIteration if
- the handshake operation is completed.
-
- @rtype: None or an iterable
- @return: If 'async' is True, a generator object will be
- returned.
-
- @raise socket.error: If a socket error occurs.
- @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
- without a preceding alert.
- @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
- @raise tlslite.errors.TLSAuthenticationError: If the checker
- doesn't like the other party's authentication credentials.
- """
- handshaker = self._handshakeClientAsync(unknownParams=(srpCallback,
- certCallback), session=session, settings=settings,
- checker=checker)
- if async:
- return handshaker
- for result in handshaker:
- pass
-
- def handshakeClientSharedKey(self, username, sharedKey, settings=None,
- checker=None, async=False):
- """Perform a shared-key handshake in the role of client.
-
- This function performs a shared-key handshake. Using shared
- symmetric keys of high entropy (128 bits or greater) mutually
- authenticates both parties to each other.
-
- TLS with shared-keys is non-standard. Most TLS
- implementations don't support it. See
- U{http://www.ietf.org/html.charters/tls-charter.html} for the
- latest information on TLS with shared-keys. If the shared-keys
- Internet-Draft changes or is superceded, TLS Lite will track
- those changes, so the shared-key support in later versions of
- TLS Lite may become incompatible with this version.
-
- Like any handshake function, this can be called on a closed
- TLS connection, or on a TLS connection that is already open.
- If called on an open connection it performs a re-handshake.
-
- If the function completes without raising an exception, the
- TLS connection will be open and available for data transfer.
-
- If an exception is raised, the connection will have been
- automatically closed (if it was ever open).
-
- @type username: str
- @param username: The shared-key username.
-
- @type sharedKey: str
- @param sharedKey: The shared key.
-
- @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
- @param settings: Various settings which can be used to control
- the ciphersuites, certificate types, and SSL/TLS versions
- offered by the client.
-
- @type checker: L{tlslite.Checker.Checker}
- @param checker: A Checker instance. This instance will be
- invoked to examine the other party's authentication
- credentials, if the handshake completes succesfully.
-
- @type async: bool
- @param async: If False, this function will block until the
- handshake is completed. If True, this function will return a
- generator. Successive invocations of the generator will
- return 0 if it is waiting to read from the socket, 1 if it is
- waiting to write to the socket, or will raise StopIteration if
- the handshake operation is completed.
-
- @rtype: None or an iterable
- @return: If 'async' is True, a generator object will be
- returned.
-
- @raise socket.error: If a socket error occurs.
- @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
- without a preceding alert.
- @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
- @raise tlslite.errors.TLSAuthenticationError: If the checker
- doesn't like the other party's authentication credentials.
- """
- handshaker = self._handshakeClientAsync(sharedKeyParams=(username,
- sharedKey), settings=settings, checker=checker)
- if async:
- return handshaker
- for result in handshaker:
- pass
-
- def _handshakeClientAsync(self, srpParams=(), certParams=(),
- unknownParams=(), sharedKeyParams=(),
- session=None, settings=None, checker=None,
- recursive=False):
-
- handshaker = self._handshakeClientAsyncHelper(srpParams=srpParams,
- certParams=certParams, unknownParams=unknownParams,
- sharedKeyParams=sharedKeyParams, session=session,
- settings=settings, recursive=recursive)
- for result in self._handshakeWrapperAsync(handshaker, checker):
- yield result
-
-
- def _handshakeClientAsyncHelper(self, srpParams, certParams, unknownParams,
- sharedKeyParams, session, settings, recursive):
- if not recursive:
- self._handshakeStart(client=True)
-
- #Unpack parameters
- srpUsername = None # srpParams
- password = None # srpParams
- clientCertChain = None # certParams
- privateKey = None # certParams
- srpCallback = None # unknownParams
- certCallback = None # unknownParams
- #session # sharedKeyParams (or session)
- #settings # settings
-
- if srpParams:
- srpUsername, password = srpParams
- elif certParams:
- clientCertChain, privateKey = certParams
- elif unknownParams:
- srpCallback, certCallback = unknownParams
- elif sharedKeyParams:
- session = Session()._createSharedKey(*sharedKeyParams)
-
- if not settings:
- settings = HandshakeSettings()
- settings = settings._filter()
-
- #Validate parameters
- if srpUsername and not password:
- raise ValueError("Caller passed a username but no password")
- if password and not srpUsername:
- raise ValueError("Caller passed a password but no username")
-
- if clientCertChain and not privateKey:
- raise ValueError("Caller passed a certChain but no privateKey")
- if privateKey and not clientCertChain:
- raise ValueError("Caller passed a privateKey but no certChain")
-
- if clientCertChain:
- foundType = False
- try:
- import cryptoIDlib.CertChain
- if isinstance(clientCertChain, cryptoIDlib.CertChain.CertChain):
- if "cryptoID" not in settings.certificateTypes:
- raise ValueError("Client certificate doesn't "\
- "match Handshake Settings")
- settings.certificateTypes = ["cryptoID"]
- foundType = True
- except ImportError:
- pass
- if not foundType and isinstance(clientCertChain,
- X509CertChain):
- if "x509" not in settings.certificateTypes:
- raise ValueError("Client certificate doesn't match "\
- "Handshake Settings")
- settings.certificateTypes = ["x509"]
- foundType = True
- if not foundType:
- raise ValueError("Unrecognized certificate type")
-
-
- if session:
- if not session.valid():
- session = None #ignore non-resumable sessions...
- elif session.resumable and \
- (session.srpUsername != srpUsername):
- raise ValueError("Session username doesn't match")
-
- #Add Faults to parameters
- if srpUsername and self.fault == Fault.badUsername:
- srpUsername += "GARBAGE"
- if password and self.fault == Fault.badPassword:
- password += "GARBAGE"
- if sharedKeyParams:
- identifier = sharedKeyParams[0]
- sharedKey = sharedKeyParams[1]
- if self.fault == Fault.badIdentifier:
- identifier += "GARBAGE"
- session = Session()._createSharedKey(identifier, sharedKey)
- elif self.fault == Fault.badSharedKey:
- sharedKey += "GARBAGE"
- session = Session()._createSharedKey(identifier, sharedKey)
-
-
- #Initialize locals
- serverCertChain = None
- cipherSuite = 0
- certificateType = CertificateType.x509
- premasterSecret = None
-
- #Get client nonce
- clientRandom = getRandomBytes(32)
-
- #Initialize acceptable ciphersuites
- cipherSuites = []
- if srpParams:
- cipherSuites += CipherSuite.getSrpRsaSuites(settings.cipherNames)
- cipherSuites += CipherSuite.getSrpSuites(settings.cipherNames)
- elif certParams:
- cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames)
- elif unknownParams:
- if srpCallback:
- cipherSuites += \
- CipherSuite.getSrpRsaSuites(settings.cipherNames)
- cipherSuites += \
- CipherSuite.getSrpSuites(settings.cipherNames)
- cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames)
- elif sharedKeyParams:
- cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames)
- else:
- cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames)
-
- #Initialize acceptable certificate types
- certificateTypes = settings._getCertificateTypes()
-
- #Tentatively set the version to the client's minimum version.
- #We'll use this for the ClientHello, and if an error occurs
- #parsing the Server Hello, we'll use this version for the response
- self.version = settings.maxVersion
-
- #Either send ClientHello (with a resumable session)...
- if session:
- #If it's a resumable (i.e. not a shared-key session), then its
- #ciphersuite must be one of the acceptable ciphersuites
- if (not sharedKeyParams) and \
- session.cipherSuite not in cipherSuites:
- raise ValueError("Session's cipher suite not consistent "\
- "with parameters")
- else:
- clientHello = ClientHello()
- clientHello.create(settings.maxVersion, clientRandom,
- session.sessionID, cipherSuites,
- certificateTypes, session.srpUsername)
-
- #Or send ClientHello (without)
- else:
- clientHello = ClientHello()
- clientHello.create(settings.maxVersion, clientRandom,
- createByteArraySequence([]), cipherSuites,
- certificateTypes, srpUsername)
- for result in self._sendMsg(clientHello):
- yield result
-
- #Get ServerHello (or missing_srp_username)
- for result in self._getMsg((ContentType.handshake,
- ContentType.alert),
- HandshakeType.server_hello):
- if result in (0,1):
- yield result
- else:
- break
- msg = result
-
- if isinstance(msg, ServerHello):
- serverHello = msg
- elif isinstance(msg, Alert):
- alert = msg
-
- #If it's not a missing_srp_username, re-raise
- if alert.description != AlertDescription.missing_srp_username:
- self._shutdown(False)
- raise TLSRemoteAlert(alert)
-
- #If we're not in SRP callback mode, we won't have offered SRP
- #without a username, so we shouldn't get this alert
- if not srpCallback:
- for result in self._sendError(\
- AlertDescription.unexpected_message):
- yield result
- srpParams = srpCallback()
- #If the callback returns None, cancel the handshake
- if srpParams == None:
- for result in self._sendError(AlertDescription.user_canceled):
- yield result
-
- #Recursively perform handshake
- for result in self._handshakeClientAsyncHelper(srpParams,
- None, None, None, None, settings, True):
- yield result
- return
-
- #Get the server version. Do this before anything else, so any
- #error alerts will use the server's version
- self.version = serverHello.server_version
-
- #Future responses from server must use this version
- self._versionCheck = True
-
- #Check ServerHello
- if serverHello.server_version < settings.minVersion:
- for result in self._sendError(\
- AlertDescription.protocol_version,
- "Too old version: %s" % str(serverHello.server_version)):
- yield result
- if serverHello.server_version > settings.maxVersion:
- for result in self._sendError(\
- AlertDescription.protocol_version,
- "Too new version: %s" % str(serverHello.server_version)):
- yield result
- if serverHello.cipher_suite not in cipherSuites:
- for result in self._sendError(\
- AlertDescription.illegal_parameter,
- "Server responded with incorrect ciphersuite"):
- yield result
- if serverHello.certificate_type not in certificateTypes:
- for result in self._sendError(\
- AlertDescription.illegal_parameter,
- "Server responded with incorrect certificate type"):
- yield result
- if serverHello.compression_method != 0:
- for result in self._sendError(\
- AlertDescription.illegal_parameter,
- "Server responded with incorrect compression method"):
- yield result
-
- #Get the server nonce
- serverRandom = serverHello.random
-
- #If the server agrees to resume
- if session and session.sessionID and \
- serverHello.session_id == session.sessionID:
-
- #If a shared-key, we're flexible about suites; otherwise the
- #server-chosen suite has to match the session's suite
- if sharedKeyParams:
- session.cipherSuite = serverHello.cipher_suite
- elif serverHello.cipher_suite != session.cipherSuite:
- for result in self._sendError(\
- AlertDescription.illegal_parameter,\
- "Server's ciphersuite doesn't match session"):
- yield result
-
- #Set the session for this connection
- self.session = session
-
- #Calculate pending connection states
- self._calcPendingStates(clientRandom, serverRandom,
- settings.cipherImplementations)
-
- #Exchange ChangeCipherSpec and Finished messages
- for result in self._getFinished():
- yield result
- for result in self._sendFinished():
- yield result
-
- #Mark the connection as open
- self._handshakeDone(resumed=True)
-
- #If server DOES NOT agree to resume
- else:
-
- if sharedKeyParams:
- for result in self._sendError(\
- AlertDescription.user_canceled,
- "Was expecting a shared-key resumption"):
- yield result
-
- #We've already validated these
- cipherSuite = serverHello.cipher_suite
- certificateType = serverHello.certificate_type
-
- #If the server chose an SRP suite...
- if cipherSuite in CipherSuite.srpSuites:
- #Get ServerKeyExchange, ServerHelloDone
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.server_key_exchange, cipherSuite):
- if result in (0,1):
- yield result
- else:
- break
- serverKeyExchange = result
-
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.server_hello_done):
- if result in (0,1):
- yield result
- else:
- break
- serverHelloDone = result
-
- #If the server chose an SRP+RSA suite...
- elif cipherSuite in CipherSuite.srpRsaSuites:
- #Get Certificate, ServerKeyExchange, ServerHelloDone
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.certificate, certificateType):
- if result in (0,1):
- yield result
- else:
- break
- serverCertificate = result
-
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.server_key_exchange, cipherSuite):
- if result in (0,1):
- yield result
- else:
- break
- serverKeyExchange = result
-
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.server_hello_done):
- if result in (0,1):
- yield result
- else:
- break
- serverHelloDone = result
-
- #If the server chose an RSA suite...
- elif cipherSuite in CipherSuite.rsaSuites:
- #Get Certificate[, CertificateRequest], ServerHelloDone
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.certificate, certificateType):
- if result in (0,1):
- yield result
- else:
- break
- serverCertificate = result
-
- for result in self._getMsg(ContentType.handshake,
- (HandshakeType.server_hello_done,
- HandshakeType.certificate_request)):
- if result in (0,1):
- yield result
- else:
- break
- msg = result
-
- certificateRequest = None
- if isinstance(msg, CertificateRequest):
- certificateRequest = msg
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.server_hello_done):
- if result in (0,1):
- yield result
- else:
- break
- serverHelloDone = result
- elif isinstance(msg, ServerHelloDone):
- serverHelloDone = msg
- else:
- raise AssertionError()
-
-
- #Calculate SRP premaster secret, if server chose an SRP or
- #SRP+RSA suite
- if cipherSuite in CipherSuite.srpSuites + \
- CipherSuite.srpRsaSuites:
- #Get and check the server's group parameters and B value
- N = serverKeyExchange.srp_N
- g = serverKeyExchange.srp_g
- s = serverKeyExchange.srp_s
- B = serverKeyExchange.srp_B
-
- if (g,N) not in goodGroupParameters:
- for result in self._sendError(\
- AlertDescription.untrusted_srp_parameters,
- "Unknown group parameters"):
- yield result
- if numBits(N) < settings.minKeySize:
- for result in self._sendError(\
- AlertDescription.untrusted_srp_parameters,
- "N value is too small: %d" % numBits(N)):
- yield result
- if numBits(N) > settings.maxKeySize:
- for result in self._sendError(\
- AlertDescription.untrusted_srp_parameters,
- "N value is too large: %d" % numBits(N)):
- yield result
- if B % N == 0:
- for result in self._sendError(\
- AlertDescription.illegal_parameter,
- "Suspicious B value"):
- yield result
-
- #Check the server's signature, if server chose an
- #SRP+RSA suite
- if cipherSuite in CipherSuite.srpRsaSuites:
- #Hash ServerKeyExchange/ServerSRPParams
- hashBytes = serverKeyExchange.hash(clientRandom,
- serverRandom)
-
- #Extract signature bytes from ServerKeyExchange
- sigBytes = serverKeyExchange.signature
- if len(sigBytes) == 0:
- for result in self._sendError(\
- AlertDescription.illegal_parameter,
- "Server sent an SRP ServerKeyExchange "\
- "message without a signature"):
- yield result
-
- #Get server's public key from the Certificate message
- for result in self._getKeyFromChain(serverCertificate,
- settings):
- if result in (0,1):
- yield result
- else:
- break
- publicKey, serverCertChain = result
-
- #Verify signature
- if not publicKey.verify(sigBytes, hashBytes):
- for result in self._sendError(\
- AlertDescription.decrypt_error,
- "Signature failed to verify"):
- yield result
-
-
- #Calculate client's ephemeral DH values (a, A)
- a = bytesToNumber(getRandomBytes(32))
- A = powMod(g, a, N)
-
- #Calculate client's static DH values (x, v)
- x = makeX(bytesToString(s), srpUsername, password)
- v = powMod(g, x, N)
-
- #Calculate u
- u = makeU(N, A, B)
-
- #Calculate premaster secret
- k = makeK(N, g)
- S = powMod((B - (k*v)) % N, a+(u*x), N)
-
- if self.fault == Fault.badA:
- A = N
- S = 0
- premasterSecret = numberToBytes(S)
-
- #Send ClientKeyExchange
- for result in self._sendMsg(\
- ClientKeyExchange(cipherSuite).createSRP(A)):
- yield result
-
-
- #Calculate RSA premaster secret, if server chose an RSA suite
- elif cipherSuite in CipherSuite.rsaSuites:
-
- #Handle the presence of a CertificateRequest
- if certificateRequest:
- if unknownParams and certCallback:
- certParamsNew = certCallback()
- if certParamsNew:
- clientCertChain, privateKey = certParamsNew
-
- #Get server's public key from the Certificate message
- for result in self._getKeyFromChain(serverCertificate,
- settings):
- if result in (0,1):
- yield result
- else:
- break
- publicKey, serverCertChain = result
-
-
- #Calculate premaster secret
- premasterSecret = getRandomBytes(48)
- premasterSecret[0] = settings.maxVersion[0]
- premasterSecret[1] = settings.maxVersion[1]
-
- if self.fault == Fault.badPremasterPadding:
- premasterSecret[0] = 5
- if self.fault == Fault.shortPremasterSecret:
- premasterSecret = premasterSecret[:-1]
-
- #Encrypt premaster secret to server's public key
- encryptedPreMasterSecret = publicKey.encrypt(premasterSecret)
-
- #If client authentication was requested, send Certificate
- #message, either with certificates or empty
- if certificateRequest:
- clientCertificate = Certificate(certificateType)
-
- if clientCertChain:
- #Check to make sure we have the same type of
- #certificates the server requested
- wrongType = False
- if certificateType == CertificateType.x509:
- if not isinstance(clientCertChain, X509CertChain):
- wrongType = True
- elif certificateType == CertificateType.cryptoID:
- if not isinstance(clientCertChain,
- cryptoIDlib.CertChain.CertChain):
- wrongType = True
- if wrongType:
- for result in self._sendError(\
- AlertDescription.handshake_failure,
- "Client certificate is of wrong type"):
- yield result
-
- clientCertificate.create(clientCertChain)
-
- for result in self._sendMsg(clientCertificate):
- yield result
- else:
- #The server didn't request client auth, so we
- #zeroize these so the clientCertChain won't be
- #stored in the session.
- privateKey = None
- clientCertChain = None
-
- #Send ClientKeyExchange
- clientKeyExchange = ClientKeyExchange(cipherSuite,
- self.version)
- clientKeyExchange.createRSA(encryptedPreMasterSecret)
- for result in self._sendMsg(clientKeyExchange):
- yield result
-
- #If client authentication was requested and we have a
- #private key, send CertificateVerify
- if certificateRequest and privateKey:
- if self.version == (3,0):
- #Create a temporary session object, just for the
- #purpose of creating the CertificateVerify
- session = Session()
- session._calcMasterSecret(self.version,
- premasterSecret,
- clientRandom,
- serverRandom)
- verifyBytes = self._calcSSLHandshakeHash(\
- session.masterSecret, "")
- elif self.version in ((3,1), (3,2)):
- verifyBytes = stringToBytes(\
- self._handshake_md5.digest() + \
- self._handshake_sha.digest())
- if self.fault == Fault.badVerifyMessage:
- verifyBytes[0] = ((verifyBytes[0]+1) % 256)
- signedBytes = privateKey.sign(verifyBytes)
- certificateVerify = CertificateVerify()
- certificateVerify.create(signedBytes)
- for result in self._sendMsg(certificateVerify):
- yield result
-
-
- #Create the session object
- self.session = Session()
- self.session._calcMasterSecret(self.version, premasterSecret,
- clientRandom, serverRandom)
- self.session.sessionID = serverHello.session_id
- self.session.cipherSuite = cipherSuite
- self.session.srpUsername = srpUsername
- self.session.clientCertChain = clientCertChain
- self.session.serverCertChain = serverCertChain
-
- #Calculate pending connection states
- self._calcPendingStates(clientRandom, serverRandom,
- settings.cipherImplementations)
-
- #Exchange ChangeCipherSpec and Finished messages
- for result in self._sendFinished():
- yield result
- for result in self._getFinished():
- yield result
-
- #Mark the connection as open
- self.session._setResumable(True)
- self._handshakeDone(resumed=False)
-
-
-
- def handshakeServer(self, sharedKeyDB=None, verifierDB=None,
- certChain=None, privateKey=None, reqCert=False,
- sessionCache=None, settings=None, checker=None):
- """Perform a handshake in the role of server.
-
- This function performs an SSL or TLS handshake. Depending on
- the arguments and the behavior of the client, this function can
- perform a shared-key, SRP, or certificate-based handshake. It
- can also perform a combined SRP and server-certificate
- handshake.
-
- Like any handshake function, this can be called on a closed
- TLS connection, or on a TLS connection that is already open.
- If called on an open connection it performs a re-handshake.
- This function does not send a Hello Request message before
- performing the handshake, so if re-handshaking is required,
- the server must signal the client to begin the re-handshake
- through some other means.
-
- If the function completes without raising an exception, the
- TLS connection will be open and available for data transfer.
-
- If an exception is raised, the connection will have been
- automatically closed (if it was ever open).
-
- @type sharedKeyDB: L{tlslite.SharedKeyDB.SharedKeyDB}
- @param sharedKeyDB: A database of shared symmetric keys
- associated with usernames. If the client performs a
- shared-key handshake, the session's sharedKeyUsername
- attribute will be set.
-
- @type verifierDB: L{tlslite.VerifierDB.VerifierDB}
- @param verifierDB: A database of SRP password verifiers
- associated with usernames. If the client performs an SRP
- handshake, the session's srpUsername attribute will be set.
-
- @type certChain: L{tlslite.X509CertChain.X509CertChain} or
- L{cryptoIDlib.CertChain.CertChain}
- @param certChain: The certificate chain to be used if the
- client requests server certificate authentication.
-
- @type privateKey: L{tlslite.utils.RSAKey.RSAKey}
- @param privateKey: The private key to be used if the client
- requests server certificate authentication.
-
- @type reqCert: bool
- @param reqCert: Whether to request client certificate
- authentication. This only applies if the client chooses server
- certificate authentication; if the client chooses SRP or
- shared-key authentication, this will be ignored. If the client
- performs a client certificate authentication, the sessions's
- clientCertChain attribute will be set.
-
- @type sessionCache: L{tlslite.SessionCache.SessionCache}
- @param sessionCache: An in-memory cache of resumable sessions.
- The client can resume sessions from this cache. Alternatively,
- if the client performs a full handshake, a new session will be
- added to the cache.
-
- @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
- @param settings: Various settings which can be used to control
- the ciphersuites and SSL/TLS version chosen by the server.
-
- @type checker: L{tlslite.Checker.Checker}
- @param checker: A Checker instance. This instance will be
- invoked to examine the other party's authentication
- credentials, if the handshake completes succesfully.
-
- @raise socket.error: If a socket error occurs.
- @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
- without a preceding alert.
- @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
- @raise tlslite.errors.TLSAuthenticationError: If the checker
- doesn't like the other party's authentication credentials.
- """
- for result in self.handshakeServerAsync(sharedKeyDB, verifierDB,
- certChain, privateKey, reqCert, sessionCache, settings,
- checker):
- pass
-
-
- def handshakeServerAsync(self, sharedKeyDB=None, verifierDB=None,
- certChain=None, privateKey=None, reqCert=False,
- sessionCache=None, settings=None, checker=None):
- """Start a server handshake operation on the TLS connection.
-
- This function returns a generator which behaves similarly to
- handshakeServer(). Successive invocations of the generator
- will return 0 if it is waiting to read from the socket, 1 if it is
- waiting to write to the socket, or it will raise StopIteration
- if the handshake operation is complete.
-
- @rtype: iterable
- @return: A generator; see above for details.
- """
- handshaker = self._handshakeServerAsyncHelper(\
- sharedKeyDB=sharedKeyDB,
- verifierDB=verifierDB, certChain=certChain,
- privateKey=privateKey, reqCert=reqCert,
- sessionCache=sessionCache, settings=settings)
- for result in self._handshakeWrapperAsync(handshaker, checker):
- yield result
-
-
- def _handshakeServerAsyncHelper(self, sharedKeyDB, verifierDB,
- certChain, privateKey, reqCert, sessionCache,
- settings):
-
- self._handshakeStart(client=False)
-
- if (not sharedKeyDB) and (not verifierDB) and (not certChain):
- raise ValueError("Caller passed no authentication credentials")
- if certChain and not privateKey:
- raise ValueError("Caller passed a certChain but no privateKey")
- if privateKey and not certChain:
- raise ValueError("Caller passed a privateKey but no certChain")
-
- if not settings:
- settings = HandshakeSettings()
- settings = settings._filter()
-
- #Initialize acceptable cipher suites
- cipherSuites = []
- if verifierDB:
- if certChain:
- cipherSuites += \
- CipherSuite.getSrpRsaSuites(settings.cipherNames)
- cipherSuites += CipherSuite.getSrpSuites(settings.cipherNames)
- if sharedKeyDB or certChain:
- cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames)
-
- #Initialize acceptable certificate type
- certificateType = None
- if certChain:
- try:
- import cryptoIDlib.CertChain
- if isinstance(certChain, cryptoIDlib.CertChain.CertChain):
- certificateType = CertificateType.cryptoID
- except ImportError:
- pass
- if isinstance(certChain, X509CertChain):
- certificateType = CertificateType.x509
- if certificateType == None:
- raise ValueError("Unrecognized certificate type")
-
- #Initialize locals
- clientCertChain = None
- serverCertChain = None #We may set certChain to this later
- postFinishedError = None
-
- #Tentatively set version to most-desirable version, so if an error
- #occurs parsing the ClientHello, this is what we'll use for the
- #error alert
- self.version = settings.maxVersion
-
- #Get ClientHello
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.client_hello):
- if result in (0,1):
- yield result
- else:
- break
- clientHello = result
-
- #If client's version is too low, reject it
- if clientHello.client_version < settings.minVersion:
- self.version = settings.minVersion
- for result in self._sendError(\
- AlertDescription.protocol_version,
- "Too old version: %s" % str(clientHello.client_version)):
- yield result
-
- #If client's version is too high, propose my highest version
- elif clientHello.client_version > settings.maxVersion:
- self.version = settings.maxVersion
-
- else:
- #Set the version to the client's version
- self.version = clientHello.client_version
-
- #Get the client nonce; create server nonce
- clientRandom = clientHello.random
- serverRandom = getRandomBytes(32)
-
- #Calculate the first cipher suite intersection.
- #This is the 'privileged' ciphersuite. We'll use it if we're
- #doing a shared-key resumption or a new negotiation. In fact,
- #the only time we won't use it is if we're resuming a non-sharedkey
- #session, in which case we use the ciphersuite from the session.
- #
- #Given the current ciphersuite ordering, this means we prefer SRP
- #over non-SRP.
- for cipherSuite in cipherSuites:
- if cipherSuite in clientHello.cipher_suites:
- break
- else:
- for result in self._sendError(\
- AlertDescription.handshake_failure):
- yield result
-
- #If resumption was requested...
- if clientHello.session_id and (sharedKeyDB or sessionCache):
- session = None
-
- #Check in the sharedKeys container
- if sharedKeyDB and len(clientHello.session_id)==16:
- try:
- #Trim off zero padding, if any
- for x in range(16):
- if clientHello.session_id[x]==0:
- break
- self.allegedSharedKeyUsername = bytesToString(\
- clientHello.session_id[:x])
- session = sharedKeyDB[self.allegedSharedKeyUsername]
- if not session.sharedKey:
- raise AssertionError()
- #use privileged ciphersuite
- session.cipherSuite = cipherSuite
- except KeyError:
- pass
-
- #Then check in the session cache
- if sessionCache and not session:
- try:
- session = sessionCache[bytesToString(\
- clientHello.session_id)]
- if session.sharedKey:
- raise AssertionError()
- if not session.resumable:
- raise AssertionError()
- #Check for consistency with ClientHello
- if session.cipherSuite not in cipherSuites:
- for result in self._sendError(\
- AlertDescription.handshake_failure):
- yield result
- if session.cipherSuite not in clientHello.cipher_suites:
- for result in self._sendError(\
- AlertDescription.handshake_failure):
- yield result
- if clientHello.srp_username:
- if clientHello.srp_username != session.srpUsername:
- for result in self._sendError(\
- AlertDescription.handshake_failure):
- yield result
- except KeyError:
- pass
-
- #If a session is found..
- if session:
- #Set the session
- self.session = session
-
- #Send ServerHello
- serverHello = ServerHello()
- serverHello.create(self.version, serverRandom,
- session.sessionID, session.cipherSuite,
- certificateType)
- for result in self._sendMsg(serverHello):
- yield result
-
- #From here on, the client's messages must have the right version
- self._versionCheck = True
-
- #Calculate pending connection states
- self._calcPendingStates(clientRandom, serverRandom,
- settings.cipherImplementations)
-
- #Exchange ChangeCipherSpec and Finished messages
- for result in self._sendFinished():
- yield result
- for result in self._getFinished():
- yield result
-
- #Mark the connection as open
- self._handshakeDone(resumed=True)
- return
-
-
- #If not a resumption...
-
- #TRICKY: we might have chosen an RSA suite that was only deemed
- #acceptable because of the shared-key resumption. If the shared-
- #key resumption failed, because the identifier wasn't recognized,
- #we might fall through to here, where we have an RSA suite
- #chosen, but no certificate.
- if cipherSuite in CipherSuite.rsaSuites and not certChain:
- for result in self._sendError(\
- AlertDescription.handshake_failure):
- yield result
-
- #If an RSA suite is chosen, check for certificate type intersection
- #(We do this check down here because if the mismatch occurs but the
- # client is using a shared-key session, it's okay)
- if cipherSuite in CipherSuite.rsaSuites + \
- CipherSuite.srpRsaSuites:
- if certificateType not in clientHello.certificate_types:
- for result in self._sendError(\
- AlertDescription.handshake_failure,
- "the client doesn't support my certificate type"):
- yield result
-
- #Move certChain -> serverCertChain, now that we're using it
- serverCertChain = certChain
-
-
- #Create sessionID
- if sessionCache:
- sessionID = getRandomBytes(32)
- else:
- sessionID = createByteArraySequence([])
-
- #If we've selected an SRP suite, exchange keys and calculate
- #premaster secret:
- if cipherSuite in CipherSuite.srpSuites + CipherSuite.srpRsaSuites:
-
- #If there's no SRP username...
- if not clientHello.srp_username:
-
- #Ask the client to re-send ClientHello with one
- for result in self._sendMsg(Alert().create(\
- AlertDescription.missing_srp_username,
- AlertLevel.warning)):
- yield result
-
- #Get ClientHello
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.client_hello):
- if result in (0,1):
- yield result
- else:
- break
- clientHello = result
-
- #Check ClientHello
- #If client's version is too low, reject it (COPIED CODE; BAD!)
- if clientHello.client_version < settings.minVersion:
- self.version = settings.minVersion
- for result in self._sendError(\
- AlertDescription.protocol_version,
- "Too old version: %s" % str(clientHello.client_version)):
- yield result
-
- #If client's version is too high, propose my highest version
- elif clientHello.client_version > settings.maxVersion:
- self.version = settings.maxVersion
-
- else:
- #Set the version to the client's version
- self.version = clientHello.client_version
-
- #Recalculate the privileged cipher suite, making sure to
- #pick an SRP suite
- cipherSuites = [c for c in cipherSuites if c in \
- CipherSuite.srpSuites + \
- CipherSuite.srpRsaSuites]
- for cipherSuite in cipherSuites:
- if cipherSuite in clientHello.cipher_suites:
- break
- else:
- for result in self._sendError(\
- AlertDescription.handshake_failure):
- yield result
-
- #Get the client nonce; create server nonce
- clientRandom = clientHello.random
- serverRandom = getRandomBytes(32)
-
- #The username better be there, this time
- if not clientHello.srp_username:
- for result in self._sendError(\
- AlertDescription.illegal_parameter,
- "Client resent a hello, but without the SRP"\
- " username"):
- yield result
-
-
- #Get username
- self.allegedSrpUsername = clientHello.srp_username
-
- #Get parameters from username
- try:
- entry = verifierDB[self.allegedSrpUsername]
- except KeyError:
- for result in self._sendError(\
- AlertDescription.unknown_srp_username):
- yield result
- (N, g, s, v) = entry
-
- #Calculate server's ephemeral DH values (b, B)
- b = bytesToNumber(getRandomBytes(32))
- k = makeK(N, g)
- B = (powMod(g, b, N) + (k*v)) % N
-
- #Create ServerKeyExchange, signing it if necessary
- serverKeyExchange = ServerKeyExchange(cipherSuite)
- serverKeyExchange.createSRP(N, g, stringToBytes(s), B)
- if cipherSuite in CipherSuite.srpRsaSuites:
- hashBytes = serverKeyExchange.hash(clientRandom,
- serverRandom)
- serverKeyExchange.signature = privateKey.sign(hashBytes)
-
- #Send ServerHello[, Certificate], ServerKeyExchange,
- #ServerHelloDone
- msgs = []
- serverHello = ServerHello()
- serverHello.create(self.version, serverRandom, sessionID,
- cipherSuite, certificateType)
- msgs.append(serverHello)
- if cipherSuite in CipherSuite.srpRsaSuites:
- certificateMsg = Certificate(certificateType)
- certificateMsg.create(serverCertChain)
- msgs.append(certificateMsg)
- msgs.append(serverKeyExchange)
- msgs.append(ServerHelloDone())
- for result in self._sendMsgs(msgs):
- yield result
-
- #From here on, the client's messages must have the right version
- self._versionCheck = True
-
- #Get and check ClientKeyExchange
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.client_key_exchange,
- cipherSuite):
- if result in (0,1):
- yield result
- else:
- break
- clientKeyExchange = result
- A = clientKeyExchange.srp_A
- if A % N == 0:
- postFinishedError = (AlertDescription.illegal_parameter,
- "Suspicious A value")
- #Calculate u
- u = makeU(N, A, B)
-
- #Calculate premaster secret
- S = powMod((A * powMod(v,u,N)) % N, b, N)
- premasterSecret = numberToBytes(S)
-
-
- #If we've selected an RSA suite, exchange keys and calculate
- #premaster secret:
- elif cipherSuite in CipherSuite.rsaSuites:
-
- #Send ServerHello, Certificate[, CertificateRequest],
- #ServerHelloDone
- msgs = []
- msgs.append(ServerHello().create(self.version, serverRandom,
- sessionID, cipherSuite, certificateType))
- msgs.append(Certificate(certificateType).create(serverCertChain))
- if reqCert:
- msgs.append(CertificateRequest())
- msgs.append(ServerHelloDone())
- for result in self._sendMsgs(msgs):
- yield result
-
- #From here on, the client's messages must have the right version
- self._versionCheck = True
-
- #Get [Certificate,] (if was requested)
- if reqCert:
- if self.version == (3,0):
- for result in self._getMsg((ContentType.handshake,
- ContentType.alert),
- HandshakeType.certificate,
- certificateType):
- if result in (0,1):
- yield result
- else:
- break
- msg = result
-
- if isinstance(msg, Alert):
- #If it's not a no_certificate alert, re-raise
- alert = msg
- if alert.description != \
- AlertDescription.no_certificate:
- self._shutdown(False)
- raise TLSRemoteAlert(alert)
- elif isinstance(msg, Certificate):
- clientCertificate = msg
- if clientCertificate.certChain and \
- clientCertificate.certChain.getNumCerts()!=0:
- clientCertChain = clientCertificate.certChain
- else:
- raise AssertionError()
- elif self.version in ((3,1), (3,2)):
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.certificate,
- certificateType):
- if result in (0,1):
- yield result
- else:
- break
- clientCertificate = result
- if clientCertificate.certChain and \
- clientCertificate.certChain.getNumCerts()!=0:
- clientCertChain = clientCertificate.certChain
- else:
- raise AssertionError()
-
- #Get ClientKeyExchange
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.client_key_exchange,
- cipherSuite):
- if result in (0,1):
- yield result
- else:
- break
- clientKeyExchange = result
-
- #Decrypt ClientKeyExchange
- premasterSecret = privateKey.decrypt(\
- clientKeyExchange.encryptedPreMasterSecret)
-
- randomPreMasterSecret = getRandomBytes(48)
- versionCheck = (premasterSecret[0], premasterSecret[1])
- if not premasterSecret:
- premasterSecret = randomPreMasterSecret
- elif len(premasterSecret)!=48:
- premasterSecret = randomPreMasterSecret
- elif versionCheck != clientHello.client_version:
- if versionCheck != self.version: #Tolerate buggy IE clients
- premasterSecret = randomPreMasterSecret
-
- #Get and check CertificateVerify, if relevant
- if clientCertChain:
- if self.version == (3,0):
- #Create a temporary session object, just for the purpose
- #of checking the CertificateVerify
- session = Session()
- session._calcMasterSecret(self.version, premasterSecret,
- clientRandom, serverRandom)
- verifyBytes = self._calcSSLHandshakeHash(\
- session.masterSecret, "")
- elif self.version in ((3,1), (3,2)):
- verifyBytes = stringToBytes(self._handshake_md5.digest() +\
- self._handshake_sha.digest())
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.certificate_verify):
- if result in (0,1):
- yield result
- else:
- break
- certificateVerify = result
- publicKey = clientCertChain.getEndEntityPublicKey()
- if len(publicKey) < settings.minKeySize:
- postFinishedError = (AlertDescription.handshake_failure,
- "Client's public key too small: %d" % len(publicKey))
- if len(publicKey) > settings.maxKeySize:
- postFinishedError = (AlertDescription.handshake_failure,
- "Client's public key too large: %d" % len(publicKey))
-
- if not publicKey.verify(certificateVerify.signature,
- verifyBytes):
- postFinishedError = (AlertDescription.decrypt_error,
- "Signature failed to verify")
-
-
- #Create the session object
- self.session = Session()
- self.session._calcMasterSecret(self.version, premasterSecret,
- clientRandom, serverRandom)
- self.session.sessionID = sessionID
- self.session.cipherSuite = cipherSuite
- self.session.srpUsername = self.allegedSrpUsername
- self.session.clientCertChain = clientCertChain
- self.session.serverCertChain = serverCertChain
-
- #Calculate pending connection states
- self._calcPendingStates(clientRandom, serverRandom,
- settings.cipherImplementations)
-
- #Exchange ChangeCipherSpec and Finished messages
- for result in self._getFinished():
- yield result
-
- #If we were holding a post-finished error until receiving the client
- #finished message, send it now. We delay the call until this point
- #because calling sendError() throws an exception, and our caller might
- #shut down the socket upon receiving the exception. If he did, and the
- #client was still sending its ChangeCipherSpec or Finished messages, it
- #would cause a socket error on the client side. This is a lot of
- #consideration to show to misbehaving clients, but this would also
- #cause problems with fault-testing.
- if postFinishedError:
- for result in self._sendError(*postFinishedError):
- yield result
-
- for result in self._sendFinished():
- yield result
-
- #Add the session object to the session cache
- if sessionCache and sessionID:
- sessionCache[bytesToString(sessionID)] = self.session
-
- #Mark the connection as open
- self.session._setResumable(True)
- self._handshakeDone(resumed=False)
-
-
- def _handshakeWrapperAsync(self, handshaker, checker):
- if not self.fault:
- try:
- for result in handshaker:
- yield result
- if checker:
- try:
- checker(self)
- except TLSAuthenticationError:
- alert = Alert().create(AlertDescription.close_notify,
- AlertLevel.fatal)
- for result in self._sendMsg(alert):
- yield result
- raise
- except:
- self._shutdown(False)
- raise
- else:
- try:
- for result in handshaker:
- yield result
- if checker:
- try:
- checker(self)
- except TLSAuthenticationError:
- alert = Alert().create(AlertDescription.close_notify,
- AlertLevel.fatal)
- for result in self._sendMsg(alert):
- yield result
- raise
- except socket.error, e:
- raise TLSFaultError("socket error!")
- except TLSAbruptCloseError, e:
- raise TLSFaultError("abrupt close error!")
- except TLSAlert, alert:
- if alert.description not in Fault.faultAlerts[self.fault]:
- raise TLSFaultError(str(alert))
- else:
- pass
- except:
- self._shutdown(False)
- raise
- else:
- raise TLSFaultError("No error!")
-
-
- def _getKeyFromChain(self, certificate, settings):
- #Get and check cert chain from the Certificate message
- certChain = certificate.certChain
- if not certChain or certChain.getNumCerts() == 0:
- for result in self._sendError(AlertDescription.illegal_parameter,
- "Other party sent a Certificate message without "\
- "certificates"):
- yield result
-
- #Get and check public key from the cert chain
- publicKey = certChain.getEndEntityPublicKey()
- if len(publicKey) < settings.minKeySize:
- for result in self._sendError(AlertDescription.handshake_failure,
- "Other party's public key too small: %d" % len(publicKey)):
- yield result
- if len(publicKey) > settings.maxKeySize:
- for result in self._sendError(AlertDescription.handshake_failure,
- "Other party's public key too large: %d" % len(publicKey)):
- yield result
-
- yield publicKey, certChain
diff --git a/src/lib/tlslite/TLSRecordLayer.py b/src/lib/tlslite/TLSRecordLayer.py
deleted file mode 100755
index 002a56862..000000000
--- a/src/lib/tlslite/TLSRecordLayer.py
+++ /dev/null
@@ -1,1131 +0,0 @@
-"""Helper class for TLSConnection."""
-from __future__ import generators
-
-from utils.compat import *
-from utils.cryptomath import *
-from utils.cipherfactory import createAES, createRC4, createTripleDES
-from utils.codec import *
-from errors import *
-from messages import *
-from mathtls import *
-from constants import *
-from utils.cryptomath import getRandomBytes
-from utils import hmac
-from FileObject import FileObject
-import sha
-import md5
-import socket
-import errno
-import traceback
-
-try:
- GeneratorExit
-except NameError:
- class GeneratorExit(Exception):
- pass
-
-class _ConnectionState:
- def __init__(self):
- self.macContext = None
- self.encContext = None
- self.seqnum = 0
-
- def getSeqNumStr(self):
- w = Writer(8)
- w.add(self.seqnum, 8)
- seqnumStr = bytesToString(w.bytes)
- self.seqnum += 1
- return seqnumStr
-
-
-class TLSRecordLayer:
- """
- This class handles data transmission for a TLS connection.
-
- Its only subclass is L{tlslite.TLSConnection.TLSConnection}. We've
- separated the code in this class from TLSConnection to make things
- more readable.
-
-
- @type sock: socket.socket
- @ivar sock: The underlying socket object.
-
- @type session: L{tlslite.Session.Session}
- @ivar session: The session corresponding to this connection.
-
- Due to TLS session resumption, multiple connections can correspond
- to the same underlying session.
-
- @type version: tuple
- @ivar version: The TLS version being used for this connection.
-
- (3,0) means SSL 3.0, and (3,1) means TLS 1.0.
-
- @type closed: bool
- @ivar closed: If this connection is closed.
-
- @type resumed: bool
- @ivar resumed: If this connection is based on a resumed session.
-
- @type allegedSharedKeyUsername: str or None
- @ivar allegedSharedKeyUsername: This is set to the shared-key
- username asserted by the client, whether the handshake succeeded or
- not. If the handshake fails, this can be inspected to
- determine if a guessing attack is in progress against a particular
- user account.
-
- @type allegedSrpUsername: str or None
- @ivar allegedSrpUsername: This is set to the SRP username
- asserted by the client, whether the handshake succeeded or not.
- If the handshake fails, this can be inspected to determine
- if a guessing attack is in progress against a particular user
- account.
-
- @type closeSocket: bool
- @ivar closeSocket: If the socket should be closed when the
- connection is closed (writable).
-
- If you set this to True, TLS Lite will assume the responsibility of
- closing the socket when the TLS Connection is shutdown (either
- through an error or through the user calling close()). The default
- is False.
-
- @type ignoreAbruptClose: bool
- @ivar ignoreAbruptClose: If an abrupt close of the socket should
- raise an error (writable).
-
- If you set this to True, TLS Lite will not raise a
- L{tlslite.errors.TLSAbruptCloseError} exception if the underlying
- socket is unexpectedly closed. Such an unexpected closure could be
- caused by an attacker. However, it also occurs with some incorrect
- TLS implementations.
-
- You should set this to True only if you're not worried about an
- attacker truncating the connection, and only if necessary to avoid
- spurious errors. The default is False.
-
- @sort: __init__, read, readAsync, write, writeAsync, close, closeAsync,
- getCipherImplementation, getCipherName
- """
-
- def __init__(self, sock):
- self.sock = sock
-
- #My session object (Session instance; read-only)
- self.session = None
-
- #Am I a client or server?
- self._client = None
-
- #Buffers for processing messages
- self._handshakeBuffer = []
- self._readBuffer = ""
-
- #Handshake digests
- self._handshake_md5 = md5.md5()
- self._handshake_sha = sha.sha()
-
- #TLS Protocol Version
- self.version = (0,0) #read-only
- self._versionCheck = False #Once we choose a version, this is True
-
- #Current and Pending connection states
- self._writeState = _ConnectionState()
- self._readState = _ConnectionState()
- self._pendingWriteState = _ConnectionState()
- self._pendingReadState = _ConnectionState()
-
- #Is the connection open?
- self.closed = True #read-only
- self._refCount = 0 #Used to trigger closure
-
- #Is this a resumed (or shared-key) session?
- self.resumed = False #read-only
-
- #What username did the client claim in his handshake?
- self.allegedSharedKeyUsername = None
- self.allegedSrpUsername = None
-
- #On a call to close(), do we close the socket? (writeable)
- self.closeSocket = False
-
- #If the socket is abruptly closed, do we ignore it
- #and pretend the connection was shut down properly? (writeable)
- self.ignoreAbruptClose = False
-
- #Fault we will induce, for testing purposes
- self.fault = None
-
- #*********************************************************
- # Public Functions START
- #*********************************************************
-
- def read(self, max=None, min=1):
- """Read some data from the TLS connection.
-
- This function will block until at least 'min' bytes are
- available (or the connection is closed).
-
- If an exception is raised, the connection will have been
- automatically closed.
-
- @type max: int
- @param max: The maximum number of bytes to return.
-
- @type min: int
- @param min: The minimum number of bytes to return
-
- @rtype: str
- @return: A string of no more than 'max' bytes, and no fewer
- than 'min' (unless the connection has been closed, in which
- case fewer than 'min' bytes may be returned).
-
- @raise socket.error: If a socket error occurs.
- @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
- without a preceding alert.
- @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
- """
- for result in self.readAsync(max, min):
- pass
- return result
-
- def readAsync(self, max=None, min=1):
- """Start a read operation on the TLS connection.
-
- This function returns a generator which behaves similarly to
- read(). Successive invocations of the generator will return 0
- if it is waiting to read from the socket, 1 if it is waiting
- to write to the socket, or a string if the read operation has
- completed.
-
- @rtype: iterable
- @return: A generator; see above for details.
- """
- try:
- while len(self._readBuffer)<min and not self.closed:
- try:
- for result in self._getMsg(ContentType.application_data):
- if result in (0,1):
- yield result
- applicationData = result
- self._readBuffer += bytesToString(applicationData.write())
- except TLSRemoteAlert, alert:
- if alert.description != AlertDescription.close_notify:
- raise
- except TLSAbruptCloseError:
- if not self.ignoreAbruptClose:
- raise
- else:
- self._shutdown(True)
-
- if max == None:
- max = len(self._readBuffer)
-
- returnStr = self._readBuffer[:max]
- self._readBuffer = self._readBuffer[max:]
- yield returnStr
- except GeneratorExit:
- pass
- except:
- self._shutdown(False)
- raise
-
- def write(self, s):
- """Write some data to the TLS connection.
-
- This function will block until all the data has been sent.
-
- If an exception is raised, the connection will have been
- automatically closed.
-
- @type s: str
- @param s: The data to transmit to the other party.
-
- @raise socket.error: If a socket error occurs.
- """
- for result in self.writeAsync(s):
- pass
-
- def writeAsync(self, s):
- """Start a write operation on the TLS connection.
-
- This function returns a generator which behaves similarly to
- write(). Successive invocations of the generator will return
- 1 if it is waiting to write to the socket, or will raise
- StopIteration if the write operation has completed.
-
- @rtype: iterable
- @return: A generator; see above for details.
- """
- try:
- if self.closed:
- raise ValueError()
-
- index = 0
- blockSize = 16384
- skipEmptyFrag = False
- while 1:
- startIndex = index * blockSize
- endIndex = startIndex + blockSize
- if startIndex >= len(s):
- break
- if endIndex > len(s):
- endIndex = len(s)
- block = stringToBytes(s[startIndex : endIndex])
- applicationData = ApplicationData().create(block)
- for result in self._sendMsg(applicationData, skipEmptyFrag):
- yield result
- skipEmptyFrag = True #only send an empy fragment on 1st message
- index += 1
- except:
- self._shutdown(False)
- raise
-
- def close(self):
- """Close the TLS connection.
-
- This function will block until it has exchanged close_notify
- alerts with the other party. After doing so, it will shut down the
- TLS connection. Further attempts to read through this connection
- will return "". Further attempts to write through this connection
- will raise ValueError.
-
- If makefile() has been called on this connection, the connection
- will be not be closed until the connection object and all file
- objects have been closed.
-
- Even if an exception is raised, the connection will have been
- closed.
-
- @raise socket.error: If a socket error occurs.
- @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
- without a preceding alert.
- @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
- """
- if not self.closed:
- for result in self._decrefAsync():
- pass
-
- def closeAsync(self):
- """Start a close operation on the TLS connection.
-
- This function returns a generator which behaves similarly to
- close(). Successive invocations of the generator will return 0
- if it is waiting to read from the socket, 1 if it is waiting
- to write to the socket, or will raise StopIteration if the
- close operation has completed.
-
- @rtype: iterable
- @return: A generator; see above for details.
- """
- if not self.closed:
- for result in self._decrefAsync():
- yield result
-
- def _decrefAsync(self):
- self._refCount -= 1
- if self._refCount == 0 and not self.closed:
- try:
- for result in self._sendMsg(Alert().create(\
- AlertDescription.close_notify, AlertLevel.warning)):
- yield result
- alert = None
- while not alert:
- for result in self._getMsg((ContentType.alert, \
- ContentType.application_data)):
- if result in (0,1):
- yield result
- if result.contentType == ContentType.alert:
- alert = result
- if alert.description == AlertDescription.close_notify:
- self._shutdown(True)
- else:
- raise TLSRemoteAlert(alert)
- except (socket.error, TLSAbruptCloseError):
- #If the other side closes the socket, that's okay
- self._shutdown(True)
- except:
- self._shutdown(False)
- raise
-
- def getCipherName(self):
- """Get the name of the cipher used with this connection.
-
- @rtype: str
- @return: The name of the cipher used with this connection.
- Either 'aes128', 'aes256', 'rc4', or '3des'.
- """
- if not self._writeState.encContext:
- return None
- return self._writeState.encContext.name
-
- def getCipherImplementation(self):
- """Get the name of the cipher implementation used with
- this connection.
-
- @rtype: str
- @return: The name of the cipher implementation used with
- this connection. Either 'python', 'cryptlib', 'openssl',
- or 'pycrypto'.
- """
- if not self._writeState.encContext:
- return None
- return self._writeState.encContext.implementation
-
-
-
- #Emulate a socket, somewhat -
- def send(self, s):
- """Send data to the TLS connection (socket emulation).
-
- @raise socket.error: If a socket error occurs.
- """
- self.write(s)
- return len(s)
-
- def sendall(self, s):
- """Send data to the TLS connection (socket emulation).
-
- @raise socket.error: If a socket error occurs.
- """
- self.write(s)
-
- def recv(self, bufsize):
- """Get some data from the TLS connection (socket emulation).
-
- @raise socket.error: If a socket error occurs.
- @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
- without a preceding alert.
- @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
- """
- return self.read(bufsize)
-
- def makefile(self, mode='r', bufsize=-1):
- """Create a file object for the TLS connection (socket emulation).
-
- @rtype: L{tlslite.FileObject.FileObject}
- """
- self._refCount += 1
- return FileObject(self, mode, bufsize)
-
- def getsockname(self):
- """Return the socket's own address (socket emulation)."""
- return self.sock.getsockname()
-
- def getpeername(self):
- """Return the remote address to which the socket is connected
- (socket emulation)."""
- return self.sock.getpeername()
-
- def settimeout(self, value):
- """Set a timeout on blocking socket operations (socket emulation)."""
- return self.sock.settimeout(value)
-
- def gettimeout(self):
- """Return the timeout associated with socket operations (socket
- emulation)."""
- return self.sock.gettimeout()
-
- def setsockopt(self, level, optname, value):
- """Set the value of the given socket option (socket emulation)."""
- return self.sock.setsockopt(level, optname, value)
-
-
- #*********************************************************
- # Public Functions END
- #*********************************************************
-
- def _shutdown(self, resumable):
- self._writeState = _ConnectionState()
- self._readState = _ConnectionState()
- #Don't do this: self._readBuffer = ""
- self.version = (0,0)
- self._versionCheck = False
- self.closed = True
- if self.closeSocket:
- self.sock.close()
-
- #Even if resumable is False, we'll never toggle this on
- if not resumable and self.session:
- self.session.resumable = False
-
-
- def _sendError(self, alertDescription, errorStr=None):
- alert = Alert().create(alertDescription, AlertLevel.fatal)
- for result in self._sendMsg(alert):
- yield result
- self._shutdown(False)
- raise TLSLocalAlert(alert, errorStr)
-
- def _sendMsgs(self, msgs):
- skipEmptyFrag = False
- for msg in msgs:
- for result in self._sendMsg(msg, skipEmptyFrag):
- yield result
- skipEmptyFrag = True
-
- def _sendMsg(self, msg, skipEmptyFrag=False):
- bytes = msg.write()
- contentType = msg.contentType
-
- #Whenever we're connected and asked to send a message,
- #we first send an empty Application Data message. This prevents
- #an attacker from launching a chosen-plaintext attack based on
- #knowing the next IV.
- if not self.closed and not skipEmptyFrag and self.version == (3,1):
- if self._writeState.encContext:
- if self._writeState.encContext.isBlockCipher:
- for result in self._sendMsg(ApplicationData(),
- skipEmptyFrag=True):
- yield result
-
- #Update handshake hashes
- if contentType == ContentType.handshake:
- bytesStr = bytesToString(bytes)
- self._handshake_md5.update(bytesStr)
- self._handshake_sha.update(bytesStr)
-
- #Calculate MAC
- if self._writeState.macContext:
- seqnumStr = self._writeState.getSeqNumStr()
- bytesStr = bytesToString(bytes)
- mac = self._writeState.macContext.copy()
- mac.update(seqnumStr)
- mac.update(chr(contentType))
- if self.version == (3,0):
- mac.update( chr( int(len(bytes)/256) ) )
- mac.update( chr( int(len(bytes)%256) ) )
- elif self.version in ((3,1), (3,2)):
- mac.update(chr(self.version[0]))
- mac.update(chr(self.version[1]))
- mac.update( chr( int(len(bytes)/256) ) )
- mac.update( chr( int(len(bytes)%256) ) )
- else:
- raise AssertionError()
- mac.update(bytesStr)
- macString = mac.digest()
- macBytes = stringToBytes(macString)
- if self.fault == Fault.badMAC:
- macBytes[0] = (macBytes[0]+1) % 256
-
- #Encrypt for Block or Stream Cipher
- if self._writeState.encContext:
- #Add padding and encrypt (for Block Cipher):
- if self._writeState.encContext.isBlockCipher:
-
- #Add TLS 1.1 fixed block
- if self.version == (3,2):
- bytes = self.fixedIVBlock + bytes
-
- #Add padding: bytes = bytes + (macBytes + paddingBytes)
- currentLength = len(bytes) + len(macBytes) + 1
- blockLength = self._writeState.encContext.block_size
- paddingLength = blockLength-(currentLength % blockLength)
-
- paddingBytes = createByteArraySequence([paddingLength] * \
- (paddingLength+1))
- if self.fault == Fault.badPadding:
- paddingBytes[0] = (paddingBytes[0]+1) % 256
- endBytes = concatArrays(macBytes, paddingBytes)
- bytes = concatArrays(bytes, endBytes)
- #Encrypt
- plaintext = stringToBytes(bytes)
- ciphertext = self._writeState.encContext.encrypt(plaintext)
- bytes = stringToBytes(ciphertext)
-
- #Encrypt (for Stream Cipher)
- else:
- bytes = concatArrays(bytes, macBytes)
- plaintext = bytesToString(bytes)
- ciphertext = self._writeState.encContext.encrypt(plaintext)
- bytes = stringToBytes(ciphertext)
-
- #Add record header and send
- r = RecordHeader3().create(self.version, contentType, len(bytes))
- s = bytesToString(concatArrays(r.write(), bytes))
- while 1:
- try:
- bytesSent = self.sock.send(s) #Might raise socket.error
- except socket.error, why:
- if why[0] == errno.EWOULDBLOCK:
- yield 1
- continue
- else:
- raise
- if bytesSent == len(s):
- return
- s = s[bytesSent:]
- yield 1
-
-
- def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
- try:
- if not isinstance(expectedType, tuple):
- expectedType = (expectedType,)
-
- #Spin in a loop, until we've got a non-empty record of a type we
- #expect. The loop will be repeated if:
- # - we receive a renegotiation attempt; we send no_renegotiation,
- # then try again
- # - we receive an empty application-data fragment; we try again
- while 1:
- for result in self._getNextRecord():
- if result in (0,1):
- yield result
- recordHeader, p = result
-
- #If this is an empty application-data fragment, try again
- if recordHeader.type == ContentType.application_data:
- if p.index == len(p.bytes):
- continue
-
- #If we received an unexpected record type...
- if recordHeader.type not in expectedType:
-
- #If we received an alert...
- if recordHeader.type == ContentType.alert:
- alert = Alert().parse(p)
-
- #We either received a fatal error, a warning, or a
- #close_notify. In any case, we're going to close the
- #connection. In the latter two cases we respond with
- #a close_notify, but ignore any socket errors, since
- #the other side might have already closed the socket.
- if alert.level == AlertLevel.warning or \
- alert.description == AlertDescription.close_notify:
-
- #If the sendMsg() call fails because the socket has
- #already been closed, we will be forgiving and not
- #report the error nor invalidate the "resumability"
- #of the session.
- try:
- alertMsg = Alert()
- alertMsg.create(AlertDescription.close_notify,
- AlertLevel.warning)
- for result in self._sendMsg(alertMsg):
- yield result
- except socket.error:
- pass
-
- if alert.description == \
- AlertDescription.close_notify:
- self._shutdown(True)
- elif alert.level == AlertLevel.warning:
- self._shutdown(False)
-
- else: #Fatal alert:
- self._shutdown(False)
-
- #Raise the alert as an exception
- raise TLSRemoteAlert(alert)
-
- #If we received a renegotiation attempt...
- if recordHeader.type == ContentType.handshake:
- subType = p.get(1)
- reneg = False
- if self._client:
- if subType == HandshakeType.hello_request:
- reneg = True
- else:
- if subType == HandshakeType.client_hello:
- reneg = True
- #Send no_renegotiation, then try again
- if reneg:
- alertMsg = Alert()
- alertMsg.create(AlertDescription.no_renegotiation,
- AlertLevel.warning)
- for result in self._sendMsg(alertMsg):
- yield result
- continue
-
- #Otherwise: this is an unexpected record, but neither an
- #alert nor renegotiation
- for result in self._sendError(\
- AlertDescription.unexpected_message,
- "received type=%d" % recordHeader.type):
- yield result
-
- break
-
- #Parse based on content_type
- if recordHeader.type == ContentType.change_cipher_spec:
- yield ChangeCipherSpec().parse(p)
- elif recordHeader.type == ContentType.alert:
- yield Alert().parse(p)
- elif recordHeader.type == ContentType.application_data:
- yield ApplicationData().parse(p)
- elif recordHeader.type == ContentType.handshake:
- #Convert secondaryType to tuple, if it isn't already
- if not isinstance(secondaryType, tuple):
- secondaryType = (secondaryType,)
-
- #If it's a handshake message, check handshake header
- if recordHeader.ssl2:
- subType = p.get(1)
- if subType != HandshakeType.client_hello:
- for result in self._sendError(\
- AlertDescription.unexpected_message,
- "Can only handle SSLv2 ClientHello messages"):
- yield result
- if HandshakeType.client_hello not in secondaryType:
- for result in self._sendError(\
- AlertDescription.unexpected_message):
- yield result
- subType = HandshakeType.client_hello
- else:
- subType = p.get(1)
- if subType not in secondaryType:
- for result in self._sendError(\
- AlertDescription.unexpected_message,
- "Expecting %s, got %s" % (str(secondaryType), subType)):
- yield result
-
- #Update handshake hashes
- sToHash = bytesToString(p.bytes)
- self._handshake_md5.update(sToHash)
- self._handshake_sha.update(sToHash)
-
- #Parse based on handshake type
- if subType == HandshakeType.client_hello:
- yield ClientHello(recordHeader.ssl2).parse(p)
- elif subType == HandshakeType.server_hello:
- yield ServerHello().parse(p)
- elif subType == HandshakeType.certificate:
- yield Certificate(constructorType).parse(p)
- elif subType == HandshakeType.certificate_request:
- yield CertificateRequest().parse(p)
- elif subType == HandshakeType.certificate_verify:
- yield CertificateVerify().parse(p)
- elif subType == HandshakeType.server_key_exchange:
- yield ServerKeyExchange(constructorType).parse(p)
- elif subType == HandshakeType.server_hello_done:
- yield ServerHelloDone().parse(p)
- elif subType == HandshakeType.client_key_exchange:
- yield ClientKeyExchange(constructorType, \
- self.version).parse(p)
- elif subType == HandshakeType.finished:
- yield Finished(self.version).parse(p)
- else:
- raise AssertionError()
-
- #If an exception was raised by a Parser or Message instance:
- except SyntaxError, e:
- for result in self._sendError(AlertDescription.decode_error,
- formatExceptionTrace(e)):
- yield result
-
-
- #Returns next record or next handshake message
- def _getNextRecord(self):
-
- #If there's a handshake message waiting, return it
- if self._handshakeBuffer:
- recordHeader, bytes = self._handshakeBuffer[0]
- self._handshakeBuffer = self._handshakeBuffer[1:]
- yield (recordHeader, Parser(bytes))
- return
-
- #Otherwise...
- #Read the next record header
- bytes = createByteArraySequence([])
- recordHeaderLength = 1
- ssl2 = False
- while 1:
- try:
- s = self.sock.recv(recordHeaderLength-len(bytes))
- except socket.error, why:
- if why[0] == errno.EWOULDBLOCK:
- yield 0
- continue
- else:
- raise
-
- #If the connection was abruptly closed, raise an error
- if len(s)==0:
- raise TLSAbruptCloseError()
-
- bytes += stringToBytes(s)
- if len(bytes)==1:
- if bytes[0] in ContentType.all:
- ssl2 = False
- recordHeaderLength = 5
- elif bytes[0] == 128:
- ssl2 = True
- recordHeaderLength = 2
- else:
- raise SyntaxError()
- if len(bytes) == recordHeaderLength:
- break
-
- #Parse the record header
- if ssl2:
- r = RecordHeader2().parse(Parser(bytes))
- else:
- r = RecordHeader3().parse(Parser(bytes))
-
- #Check the record header fields
- if r.length > 18432:
- for result in self._sendError(AlertDescription.record_overflow):
- yield result
-
- #Read the record contents
- bytes = createByteArraySequence([])
- while 1:
- try:
- s = self.sock.recv(r.length - len(bytes))
- except socket.error, why:
- if why[0] == errno.EWOULDBLOCK:
- yield 0
- continue
- else:
- raise
-
- #If the connection is closed, raise a socket error
- if len(s)==0:
- raise TLSAbruptCloseError()
-
- bytes += stringToBytes(s)
- if len(bytes) == r.length:
- break
-
- #Check the record header fields (2)
- #We do this after reading the contents from the socket, so that
- #if there's an error, we at least don't leave extra bytes in the
- #socket..
- #
- # THIS CHECK HAS NO SECURITY RELEVANCE (?), BUT COULD HURT INTEROP.
- # SO WE LEAVE IT OUT FOR NOW.
- #
- #if self._versionCheck and r.version != self.version:
- # for result in self._sendError(AlertDescription.protocol_version,
- # "Version in header field: %s, should be %s" % (str(r.version),
- # str(self.version))):
- # yield result
-
- #Decrypt the record
- for result in self._decryptRecord(r.type, bytes):
- if result in (0,1):
- yield result
- else:
- break
- bytes = result
- p = Parser(bytes)
-
- #If it doesn't contain handshake messages, we can just return it
- if r.type != ContentType.handshake:
- yield (r, p)
- #If it's an SSLv2 ClientHello, we can return it as well
- elif r.ssl2:
- yield (r, p)
- else:
- #Otherwise, we loop through and add the handshake messages to the
- #handshake buffer
- while 1:
- if p.index == len(bytes): #If we're at the end
- if not self._handshakeBuffer:
- for result in self._sendError(\
- AlertDescription.decode_error, \
- "Received empty handshake record"):
- yield result
- break
- #There needs to be at least 4 bytes to get a header
- if p.index+4 > len(bytes):
- for result in self._sendError(\
- AlertDescription.decode_error,
- "A record has a partial handshake message (1)"):
- yield result
- p.get(1) # skip handshake type
- msgLength = p.get(3)
- if p.index+msgLength > len(bytes):
- for result in self._sendError(\
- AlertDescription.decode_error,
- "A record has a partial handshake message (2)"):
- yield result
-
- handshakePair = (r, bytes[p.index-4 : p.index+msgLength])
- self._handshakeBuffer.append(handshakePair)
- p.index += msgLength
-
- #We've moved at least one handshake message into the
- #handshakeBuffer, return the first one
- recordHeader, bytes = self._handshakeBuffer[0]
- self._handshakeBuffer = self._handshakeBuffer[1:]
- yield (recordHeader, Parser(bytes))
-
-
- def _decryptRecord(self, recordType, bytes):
- if self._readState.encContext:
-
- #Decrypt if it's a block cipher
- if self._readState.encContext.isBlockCipher:
- blockLength = self._readState.encContext.block_size
- if len(bytes) % blockLength != 0:
- for result in self._sendError(\
- AlertDescription.decryption_failed,
- "Encrypted data not a multiple of blocksize"):
- yield result
- ciphertext = bytesToString(bytes)
- plaintext = self._readState.encContext.decrypt(ciphertext)
- if self.version == (3,2): #For TLS 1.1, remove explicit IV
- plaintext = plaintext[self._readState.encContext.block_size : ]
- bytes = stringToBytes(plaintext)
-
- #Check padding
- paddingGood = True
- paddingLength = bytes[-1]
- if (paddingLength+1) > len(bytes):
- paddingGood=False
- totalPaddingLength = 0
- else:
- if self.version == (3,0):
- totalPaddingLength = paddingLength+1
- elif self.version in ((3,1), (3,2)):
- totalPaddingLength = paddingLength+1
- paddingBytes = bytes[-totalPaddingLength:-1]
- for byte in paddingBytes:
- if byte != paddingLength:
- paddingGood = False
- totalPaddingLength = 0
- else:
- raise AssertionError()
-
- #Decrypt if it's a stream cipher
- else:
- paddingGood = True
- ciphertext = bytesToString(bytes)
- plaintext = self._readState.encContext.decrypt(ciphertext)
- bytes = stringToBytes(plaintext)
- totalPaddingLength = 0
-
- #Check MAC
- macGood = True
- macLength = self._readState.macContext.digest_size
- endLength = macLength + totalPaddingLength
- if endLength > len(bytes):
- macGood = False
- else:
- #Read MAC
- startIndex = len(bytes) - endLength
- endIndex = startIndex + macLength
- checkBytes = bytes[startIndex : endIndex]
-
- #Calculate MAC
- seqnumStr = self._readState.getSeqNumStr()
- bytes = bytes[:-endLength]
- bytesStr = bytesToString(bytes)
- mac = self._readState.macContext.copy()
- mac.update(seqnumStr)
- mac.update(chr(recordType))
- if self.version == (3,0):
- mac.update( chr( int(len(bytes)/256) ) )
- mac.update( chr( int(len(bytes)%256) ) )
- elif self.version in ((3,1), (3,2)):
- mac.update(chr(self.version[0]))
- mac.update(chr(self.version[1]))
- mac.update( chr( int(len(bytes)/256) ) )
- mac.update( chr( int(len(bytes)%256) ) )
- else:
- raise AssertionError()
- mac.update(bytesStr)
- macString = mac.digest()
- macBytes = stringToBytes(macString)
-
- #Compare MACs
- if macBytes != checkBytes:
- macGood = False
-
- if not (paddingGood and macGood):
- for result in self._sendError(AlertDescription.bad_record_mac,
- "MAC failure (or padding failure)"):
- yield result
-
- yield bytes
-
- def _handshakeStart(self, client):
- self._client = client
- self._handshake_md5 = md5.md5()
- self._handshake_sha = sha.sha()
- self._handshakeBuffer = []
- self.allegedSharedKeyUsername = None
- self.allegedSrpUsername = None
- self._refCount = 1
-
- def _handshakeDone(self, resumed):
- self.resumed = resumed
- self.closed = False
-
- def _calcPendingStates(self, clientRandom, serverRandom, implementations):
- if self.session.cipherSuite in CipherSuite.aes128Suites:
- macLength = 20
- keyLength = 16
- ivLength = 16
- createCipherFunc = createAES
- elif self.session.cipherSuite in CipherSuite.aes256Suites:
- macLength = 20
- keyLength = 32
- ivLength = 16
- createCipherFunc = createAES
- elif self.session.cipherSuite in CipherSuite.rc4Suites:
- macLength = 20
- keyLength = 16
- ivLength = 0
- createCipherFunc = createRC4
- elif self.session.cipherSuite in CipherSuite.tripleDESSuites:
- macLength = 20
- keyLength = 24
- ivLength = 8
- createCipherFunc = createTripleDES
- else:
- raise AssertionError()
-
- if self.version == (3,0):
- createMACFunc = MAC_SSL
- elif self.version in ((3,1), (3,2)):
- createMACFunc = hmac.HMAC
-
- outputLength = (macLength*2) + (keyLength*2) + (ivLength*2)
-
- #Calculate Keying Material from Master Secret
- if self.version == (3,0):
- keyBlock = PRF_SSL(self.session.masterSecret,
- concatArrays(serverRandom, clientRandom),
- outputLength)
- elif self.version in ((3,1), (3,2)):
- keyBlock = PRF(self.session.masterSecret,
- "key expansion",
- concatArrays(serverRandom,clientRandom),
- outputLength)
- else:
- raise AssertionError()
-
- #Slice up Keying Material
- clientPendingState = _ConnectionState()
- serverPendingState = _ConnectionState()
- p = Parser(keyBlock)
- clientMACBlock = bytesToString(p.getFixBytes(macLength))
- serverMACBlock = bytesToString(p.getFixBytes(macLength))
- clientKeyBlock = bytesToString(p.getFixBytes(keyLength))
- serverKeyBlock = bytesToString(p.getFixBytes(keyLength))
- clientIVBlock = bytesToString(p.getFixBytes(ivLength))
- serverIVBlock = bytesToString(p.getFixBytes(ivLength))
- clientPendingState.macContext = createMACFunc(clientMACBlock,
- digestmod=sha)
- serverPendingState.macContext = createMACFunc(serverMACBlock,
- digestmod=sha)
- clientPendingState.encContext = createCipherFunc(clientKeyBlock,
- clientIVBlock,
- implementations)
- serverPendingState.encContext = createCipherFunc(serverKeyBlock,
- serverIVBlock,
- implementations)
-
- #Assign new connection states to pending states
- if self._client:
- self._pendingWriteState = clientPendingState
- self._pendingReadState = serverPendingState
- else:
- self._pendingWriteState = serverPendingState
- self._pendingReadState = clientPendingState
-
- if self.version == (3,2) and ivLength:
- #Choose fixedIVBlock for TLS 1.1 (this is encrypted with the CBC
- #residue to create the IV for each sent block)
- self.fixedIVBlock = getRandomBytes(ivLength)
-
- def _changeWriteState(self):
- self._writeState = self._pendingWriteState
- self._pendingWriteState = _ConnectionState()
-
- def _changeReadState(self):
- self._readState = self._pendingReadState
- self._pendingReadState = _ConnectionState()
-
- def _sendFinished(self):
- #Send ChangeCipherSpec
- for result in self._sendMsg(ChangeCipherSpec()):
- yield result
-
- #Switch to pending write state
- self._changeWriteState()
-
- #Calculate verification data
- verifyData = self._calcFinished(True)
- if self.fault == Fault.badFinished:
- verifyData[0] = (verifyData[0]+1)%256
-
- #Send Finished message under new state
- finished = Finished(self.version).create(verifyData)
- for result in self._sendMsg(finished):
- yield result
-
- def _getFinished(self):
- #Get and check ChangeCipherSpec
- for result in self._getMsg(ContentType.change_cipher_spec):
- if result in (0,1):
- yield result
- changeCipherSpec = result
-
- if changeCipherSpec.type != 1:
- for result in self._sendError(AlertDescription.illegal_parameter,
- "ChangeCipherSpec type incorrect"):
- yield result
-
- #Switch to pending read state
- self._changeReadState()
-
- #Calculate verification data
- verifyData = self._calcFinished(False)
-
- #Get and check Finished message under new state
- for result in self._getMsg(ContentType.handshake,
- HandshakeType.finished):
- if result in (0,1):
- yield result
- finished = result
- if finished.verify_data != verifyData:
- for result in self._sendError(AlertDescription.decrypt_error,
- "Finished message is incorrect"):
- yield result
-
- def _calcFinished(self, send=True):
- if self.version == (3,0):
- if (self._client and send) or (not self._client and not send):
- senderStr = "\x43\x4C\x4E\x54"
- else:
- senderStr = "\x53\x52\x56\x52"
-
- verifyData = self._calcSSLHandshakeHash(self.session.masterSecret,
- senderStr)
- return verifyData
-
- elif self.version in ((3,1), (3,2)):
- if (self._client and send) or (not self._client and not send):
- label = "client finished"
- else:
- label = "server finished"
-
- handshakeHashes = stringToBytes(self._handshake_md5.digest() + \
- self._handshake_sha.digest())
- verifyData = PRF(self.session.masterSecret, label, handshakeHashes,
- 12)
- return verifyData
- else:
- raise AssertionError()
-
- #Used for Finished messages and CertificateVerify messages in SSL v3
- def _calcSSLHandshakeHash(self, masterSecret, label):
- masterSecretStr = bytesToString(masterSecret)
-
- imac_md5 = self._handshake_md5.copy()
- imac_sha = self._handshake_sha.copy()
-
- imac_md5.update(label + masterSecretStr + '\x36'*48)
- imac_sha.update(label + masterSecretStr + '\x36'*40)
-
- md5Str = md5.md5(masterSecretStr + ('\x5c'*48) + \
- imac_md5.digest()).digest()
- shaStr = sha.sha(masterSecretStr + ('\x5c'*40) + \
- imac_sha.digest()).digest()
-
- return stringToBytes(md5Str + shaStr)
-
diff --git a/src/lib/tlslite/VerifierDB.py b/src/lib/tlslite/VerifierDB.py
deleted file mode 100755
index f706b1796..000000000
--- a/src/lib/tlslite/VerifierDB.py
+++ /dev/null
@@ -1,90 +0,0 @@
-"""Class for storing SRP password verifiers."""
-
-from utils.cryptomath import *
-from utils.compat import *
-import mathtls
-from BaseDB import BaseDB
-
-class VerifierDB(BaseDB):
- """This class represent an in-memory or on-disk database of SRP
- password verifiers.
-
- A VerifierDB can be passed to a server handshake to authenticate
- a client based on one of the verifiers.
-
- This class is thread-safe.
- """
- def __init__(self, filename=None):
- """Create a new VerifierDB instance.
-
- @type filename: str
- @param filename: Filename for an on-disk database, or None for
- an in-memory database. If the filename already exists, follow
- this with a call to open(). To create a new on-disk database,
- follow this with a call to create().
- """
- BaseDB.__init__(self, filename, "verifier")
-
- def _getItem(self, username, valueStr):
- (N, g, salt, verifier) = valueStr.split(" ")
- N = base64ToNumber(N)
- g = base64ToNumber(g)
- salt = base64ToString(salt)
- verifier = base64ToNumber(verifier)
- return (N, g, salt, verifier)
-
- def __setitem__(self, username, verifierEntry):
- """Add a verifier entry to the database.
-
- @type username: str
- @param username: The username to associate the verifier with.
- Must be less than 256 characters in length. Must not already
- be in the database.
-
- @type verifierEntry: tuple
- @param verifierEntry: The verifier entry to add. Use
- L{tlslite.VerifierDB.VerifierDB.makeVerifier} to create a
- verifier entry.
- """
- BaseDB.__setitem__(self, username, verifierEntry)
-
-
- def _setItem(self, username, value):
- if len(username)>=256:
- raise ValueError("username too long")
- N, g, salt, verifier = value
- N = numberToBase64(N)
- g = numberToBase64(g)
- salt = stringToBase64(salt)
- verifier = numberToBase64(verifier)
- valueStr = " ".join( (N, g, salt, verifier) )
- return valueStr
-
- def _checkItem(self, value, username, param):
- (N, g, salt, verifier) = value
- x = mathtls.makeX(salt, username, param)
- v = powMod(g, x, N)
- return (verifier == v)
-
-
- def makeVerifier(username, password, bits):
- """Create a verifier entry which can be stored in a VerifierDB.
-
- @type username: str
- @param username: The username for this verifier. Must be less
- than 256 characters in length.
-
- @type password: str
- @param password: The password for this verifier.
-
- @type bits: int
- @param bits: This values specifies which SRP group parameters
- to use. It must be one of (1024, 1536, 2048, 3072, 4096, 6144,
- 8192). Larger values are more secure but slower. 2048 is a
- good compromise between safety and speed.
-
- @rtype: tuple
- @return: A tuple which may be stored in a VerifierDB.
- """
- return mathtls.makeVerifier(username, password, bits)
- makeVerifier = staticmethod(makeVerifier) \ No newline at end of file
diff --git a/src/lib/tlslite/X509.py b/src/lib/tlslite/X509.py
deleted file mode 100755
index a47ddcfa2..000000000
--- a/src/lib/tlslite/X509.py
+++ /dev/null
@@ -1,133 +0,0 @@
-"""Class representing an X.509 certificate."""
-
-from utils.ASN1Parser import ASN1Parser
-from utils.cryptomath import *
-from utils.keyfactory import _createPublicRSAKey
-
-
-class X509:
- """This class represents an X.509 certificate.
-
- @type bytes: L{array.array} of unsigned bytes
- @ivar bytes: The DER-encoded ASN.1 certificate
-
- @type publicKey: L{tlslite.utils.RSAKey.RSAKey}
- @ivar publicKey: The subject public key from the certificate.
- """
-
- def __init__(self):
- self.bytes = createByteArraySequence([])
- self.publicKey = None
-
- def parse(self, s):
- """Parse a PEM-encoded X.509 certificate.
-
- @type s: str
- @param s: A PEM-encoded X.509 certificate (i.e. a base64-encoded
- certificate wrapped with "-----BEGIN CERTIFICATE-----" and
- "-----END CERTIFICATE-----" tags).
- """
-
- start = s.find("-----BEGIN CERTIFICATE-----")
- end = s.find("-----END CERTIFICATE-----")
- if start == -1:
- raise SyntaxError("Missing PEM prefix")
- if end == -1:
- raise SyntaxError("Missing PEM postfix")
- s = s[start+len("-----BEGIN CERTIFICATE-----") : end]
-
- bytes = base64ToBytes(s)
- self.parseBinary(bytes)
- return self
-
- def parseBinary(self, bytes):
- """Parse a DER-encoded X.509 certificate.
-
- @type bytes: str or L{array.array} of unsigned bytes
- @param bytes: A DER-encoded X.509 certificate.
- """
-
- if isinstance(bytes, type("")):
- bytes = stringToBytes(bytes)
-
- self.bytes = bytes
- p = ASN1Parser(bytes)
-
- #Get the tbsCertificate
- tbsCertificateP = p.getChild(0)
-
- #Is the optional version field present?
- #This determines which index the key is at.
- if tbsCertificateP.value[0]==0xA0:
- subjectPublicKeyInfoIndex = 6
- else:
- subjectPublicKeyInfoIndex = 5
-
- #Get the subjectPublicKeyInfo
- subjectPublicKeyInfoP = tbsCertificateP.getChild(\
- subjectPublicKeyInfoIndex)
-
- #Get the algorithm
- algorithmP = subjectPublicKeyInfoP.getChild(0)
- rsaOID = algorithmP.value
- if list(rsaOID) != [6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0]:
- raise SyntaxError("Unrecognized AlgorithmIdentifier")
-
- #Get the subjectPublicKey
- subjectPublicKeyP = subjectPublicKeyInfoP.getChild(1)
-
- #Adjust for BIT STRING encapsulation
- if (subjectPublicKeyP.value[0] !=0):
- raise SyntaxError()
- subjectPublicKeyP = ASN1Parser(subjectPublicKeyP.value[1:])
-
- #Get the modulus and exponent
- modulusP = subjectPublicKeyP.getChild(0)
- publicExponentP = subjectPublicKeyP.getChild(1)
-
- #Decode them into numbers
- n = bytesToNumber(modulusP.value)
- e = bytesToNumber(publicExponentP.value)
-
- #Create a public key instance
- self.publicKey = _createPublicRSAKey(n, e)
-
- def getFingerprint(self):
- """Get the hex-encoded fingerprint of this certificate.
-
- @rtype: str
- @return: A hex-encoded fingerprint.
- """
- return sha.sha(self.bytes).hexdigest()
-
- def getCommonName(self):
- """Get the Subject's Common Name from the certificate.
-
- The cryptlib_py module must be installed in order to use this
- function.
-
- @rtype: str or None
- @return: The CN component of the certificate's subject DN, if
- present.
- """
- import cryptlib_py
- import array
- c = cryptlib_py.cryptImportCert(self.bytes, cryptlib_py.CRYPT_UNUSED)
- name = cryptlib_py.CRYPT_CERTINFO_COMMONNAME
- try:
- try:
- length = cryptlib_py.cryptGetAttributeString(c, name, None)
- returnVal = array.array('B', [0] * length)
- cryptlib_py.cryptGetAttributeString(c, name, returnVal)
- returnVal = returnVal.tostring()
- except cryptlib_py.CryptException, e:
- if e[0] == cryptlib_py.CRYPT_ERROR_NOTFOUND:
- returnVal = None
- return returnVal
- finally:
- cryptlib_py.cryptDestroyCert(c)
-
- def writeBytes(self):
- return self.bytes
-
-
diff --git a/src/lib/tlslite/X509CertChain.py b/src/lib/tlslite/X509CertChain.py
deleted file mode 100755
index d5f0b4d42..000000000
--- a/src/lib/tlslite/X509CertChain.py
+++ /dev/null
@@ -1,181 +0,0 @@
-"""Class representing an X.509 certificate chain."""
-
-from utils import cryptomath
-
-class X509CertChain:
- """This class represents a chain of X.509 certificates.
-
- @type x509List: list
- @ivar x509List: A list of L{tlslite.X509.X509} instances,
- starting with the end-entity certificate and with every
- subsequent certificate certifying the previous.
- """
-
- def __init__(self, x509List=None):
- """Create a new X509CertChain.
-
- @type x509List: list
- @param x509List: A list of L{tlslite.X509.X509} instances,
- starting with the end-entity certificate and with every
- subsequent certificate certifying the previous.
- """
- if x509List:
- self.x509List = x509List
- else:
- self.x509List = []
-
- def getNumCerts(self):
- """Get the number of certificates in this chain.
-
- @rtype: int
- """
- return len(self.x509List)
-
- def getEndEntityPublicKey(self):
- """Get the public key from the end-entity certificate.
-
- @rtype: L{tlslite.utils.RSAKey.RSAKey}
- """
- if self.getNumCerts() == 0:
- raise AssertionError()
- return self.x509List[0].publicKey
-
- def getFingerprint(self):
- """Get the hex-encoded fingerprint of the end-entity certificate.
-
- @rtype: str
- @return: A hex-encoded fingerprint.
- """
- if self.getNumCerts() == 0:
- raise AssertionError()
- return self.x509List[0].getFingerprint()
-
- def getCommonName(self):
- """Get the Subject's Common Name from the end-entity certificate.
-
- The cryptlib_py module must be installed in order to use this
- function.
-
- @rtype: str or None
- @return: The CN component of the certificate's subject DN, if
- present.
- """
- if self.getNumCerts() == 0:
- raise AssertionError()
- return self.x509List[0].getCommonName()
-
- def validate(self, x509TrustList):
- """Check the validity of the certificate chain.
-
- This checks that every certificate in the chain validates with
- the subsequent one, until some certificate validates with (or
- is identical to) one of the passed-in root certificates.
-
- The cryptlib_py module must be installed in order to use this
- function.
-
- @type x509TrustList: list of L{tlslite.X509.X509}
- @param x509TrustList: A list of trusted root certificates. The
- certificate chain must extend to one of these certificates to
- be considered valid.
- """
-
- import cryptlib_py
- c1 = None
- c2 = None
- lastC = None
- rootC = None
-
- try:
- rootFingerprints = [c.getFingerprint() for c in x509TrustList]
-
- #Check that every certificate in the chain validates with the
- #next one
- for cert1, cert2 in zip(self.x509List, self.x509List[1:]):
-
- #If we come upon a root certificate, we're done.
- if cert1.getFingerprint() in rootFingerprints:
- return True
-
- c1 = cryptlib_py.cryptImportCert(cert1.writeBytes(),
- cryptlib_py.CRYPT_UNUSED)
- c2 = cryptlib_py.cryptImportCert(cert2.writeBytes(),
- cryptlib_py.CRYPT_UNUSED)
- try:
- cryptlib_py.cryptCheckCert(c1, c2)
- except:
- return False
- cryptlib_py.cryptDestroyCert(c1)
- c1 = None
- cryptlib_py.cryptDestroyCert(c2)
- c2 = None
-
- #If the last certificate is one of the root certificates, we're
- #done.
- if self.x509List[-1].getFingerprint() in rootFingerprints:
- return True
-
- #Otherwise, find a root certificate that the last certificate
- #chains to, and validate them.
- lastC = cryptlib_py.cryptImportCert(self.x509List[-1].writeBytes(),
- cryptlib_py.CRYPT_UNUSED)
- for rootCert in x509TrustList:
- rootC = cryptlib_py.cryptImportCert(rootCert.writeBytes(),
- cryptlib_py.CRYPT_UNUSED)
- if self._checkChaining(lastC, rootC):
- try:
- cryptlib_py.cryptCheckCert(lastC, rootC)
- return True
- except:
- return False
- return False
- finally:
- if not (c1 is None):
- cryptlib_py.cryptDestroyCert(c1)
- if not (c2 is None):
- cryptlib_py.cryptDestroyCert(c2)
- if not (lastC is None):
- cryptlib_py.cryptDestroyCert(lastC)
- if not (rootC is None):
- cryptlib_py.cryptDestroyCert(rootC)
-
-
-
- def _checkChaining(self, lastC, rootC):
- import cryptlib_py
- import array
- def compareNames(name):
- try:
- length = cryptlib_py.cryptGetAttributeString(lastC, name, None)
- lastName = array.array('B', [0] * length)
- cryptlib_py.cryptGetAttributeString(lastC, name, lastName)
- lastName = lastName.tostring()
- except cryptlib_py.CryptException, e:
- if e[0] == cryptlib_py.CRYPT_ERROR_NOTFOUND:
- lastName = None
- try:
- length = cryptlib_py.cryptGetAttributeString(rootC, name, None)
- rootName = array.array('B', [0] * length)
- cryptlib_py.cryptGetAttributeString(rootC, name, rootName)
- rootName = rootName.tostring()
- except cryptlib_py.CryptException, e:
- if e[0] == cryptlib_py.CRYPT_ERROR_NOTFOUND:
- rootName = None
-
- return lastName == rootName
-
- cryptlib_py.cryptSetAttribute(lastC,
- cryptlib_py.CRYPT_CERTINFO_ISSUERNAME,
- cryptlib_py.CRYPT_UNUSED)
-
- if not compareNames(cryptlib_py.CRYPT_CERTINFO_COUNTRYNAME):
- return False
- if not compareNames(cryptlib_py.CRYPT_CERTINFO_LOCALITYNAME):
- return False
- if not compareNames(cryptlib_py.CRYPT_CERTINFO_ORGANIZATIONNAME):
- return False
- if not compareNames(cryptlib_py.CRYPT_CERTINFO_ORGANIZATIONALUNITNAME):
- return False
- if not compareNames(cryptlib_py.CRYPT_CERTINFO_COMMONNAME):
- return False
- return True \ No newline at end of file
diff --git a/src/lib/tlslite/__init__.py b/src/lib/tlslite/__init__.py
deleted file mode 100755
index 47cfd1c6f..000000000
--- a/src/lib/tlslite/__init__.py
+++ /dev/null
@@ -1,39 +0,0 @@
-"""
-TLS Lite is a free python library that implements SSL v3, TLS v1, and
-TLS v1.1. TLS Lite supports non-traditional authentication methods
-such as SRP, shared keys, and cryptoIDs, in addition to X.509
-certificates. TLS Lite is pure python, however it can access OpenSSL,
-cryptlib, pycrypto, and GMPY for faster crypto operations. TLS Lite
-integrates with httplib, xmlrpclib, poplib, imaplib, smtplib,
-SocketServer, asyncore, and Twisted.
-
-To use, do::
-
- from tlslite.api import *
-
-Then use the L{tlslite.TLSConnection.TLSConnection} class with a socket,
-or use one of the integration classes in L{tlslite.integration}.
-
-@version: 0.3.8
-"""
-__version__ = "0.3.8"
-
-__all__ = ["api",
- "BaseDB",
- "Checker",
- "constants",
- "errors",
- "FileObject",
- "HandshakeSettings",
- "mathtls",
- "messages",
- "Session",
- "SessionCache",
- "SharedKeyDB",
- "TLSConnection",
- "TLSRecordLayer",
- "VerifierDB",
- "X509",
- "X509CertChain",
- "integration",
- "utils"]
diff --git a/src/lib/tlslite/api.py b/src/lib/tlslite/api.py
deleted file mode 100755
index eebfbc609..000000000
--- a/src/lib/tlslite/api.py
+++ /dev/null
@@ -1,75 +0,0 @@
-"""Import this module for easy access to TLS Lite objects.
-
-The TLS Lite API consists of classes, functions, and variables spread
-throughout this package. Instead of importing them individually with::
-
- from tlslite.TLSConnection import TLSConnection
- from tlslite.HandshakeSettings import HandshakeSettings
- from tlslite.errors import *
- .
- .
-
-It's easier to do::
-
- from tlslite.api import *
-
-This imports all the important objects (TLSConnection, Checker,
-HandshakeSettings, etc.) into the global namespace. In particular, it
-imports::
-
- from constants import AlertLevel, AlertDescription, Fault
- from errors import *
- from Checker import Checker
- from HandshakeSettings import HandshakeSettings
- from Session import Session
- from SessionCache import SessionCache
- from SharedKeyDB import SharedKeyDB
- from TLSConnection import TLSConnection
- from VerifierDB import VerifierDB
- from X509 import X509
- from X509CertChain import X509CertChain
-
- from integration.HTTPTLSConnection import HTTPTLSConnection
- from integration.POP3_TLS import POP3_TLS
- from integration.IMAP4_TLS import IMAP4_TLS
- from integration.SMTP_TLS import SMTP_TLS
- from integration.XMLRPCTransport import XMLRPCTransport
- from integration.TLSSocketServerMixIn import TLSSocketServerMixIn
- from integration.TLSAsyncDispatcherMixIn import TLSAsyncDispatcherMixIn
- from integration.TLSTwistedProtocolWrapper import TLSTwistedProtocolWrapper
- from utils.cryptomath import cryptlibpyLoaded, m2cryptoLoaded,
- gmpyLoaded, pycryptoLoaded, prngName
- from utils.keyfactory import generateRSAKey, parsePEMKey, parseXMLKey,
- parseAsPublicKey, parsePrivateKey
-"""
-
-from constants import AlertLevel, AlertDescription, Fault
-from errors import *
-from Checker import Checker
-from HandshakeSettings import HandshakeSettings
-from Session import Session
-from SessionCache import SessionCache
-from SharedKeyDB import SharedKeyDB
-from TLSConnection import TLSConnection
-from VerifierDB import VerifierDB
-from X509 import X509
-from X509CertChain import X509CertChain
-
-from integration.HTTPTLSConnection import HTTPTLSConnection
-from integration.TLSSocketServerMixIn import TLSSocketServerMixIn
-from integration.TLSAsyncDispatcherMixIn import TLSAsyncDispatcherMixIn
-from integration.POP3_TLS import POP3_TLS
-from integration.IMAP4_TLS import IMAP4_TLS
-from integration.SMTP_TLS import SMTP_TLS
-from integration.XMLRPCTransport import XMLRPCTransport
-try:
- import twisted
- del(twisted)
- from integration.TLSTwistedProtocolWrapper import TLSTwistedProtocolWrapper
-except ImportError:
- pass
-
-from utils.cryptomath import cryptlibpyLoaded, m2cryptoLoaded, gmpyLoaded, \
- pycryptoLoaded, prngName
-from utils.keyfactory import generateRSAKey, parsePEMKey, parseXMLKey, \
- parseAsPublicKey, parsePrivateKey
diff --git a/src/lib/tlslite/constants.py b/src/lib/tlslite/constants.py
deleted file mode 100755
index 8f2d5590e..000000000
--- a/src/lib/tlslite/constants.py
+++ /dev/null
@@ -1,225 +0,0 @@
-"""Constants used in various places."""
-
-class CertificateType:
- x509 = 0
- openpgp = 1
- cryptoID = 2
-
-class HandshakeType:
- hello_request = 0
- client_hello = 1
- server_hello = 2
- certificate = 11
- server_key_exchange = 12
- certificate_request = 13
- server_hello_done = 14
- certificate_verify = 15
- client_key_exchange = 16
- finished = 20
-
-class ContentType:
- change_cipher_spec = 20
- alert = 21
- handshake = 22
- application_data = 23
- all = (20,21,22,23)
-
-class AlertLevel:
- warning = 1
- fatal = 2
-
-class AlertDescription:
- """
- @cvar bad_record_mac: A TLS record failed to decrypt properly.
-
- If this occurs during a shared-key or SRP handshake it most likely
- indicates a bad password. It may also indicate an implementation
- error, or some tampering with the data in transit.
-
- This alert will be signalled by the server if the SRP password is bad. It
- may also be signalled by the server if the SRP username is unknown to the
- server, but it doesn't wish to reveal that fact.
-
- This alert will be signalled by the client if the shared-key username is
- bad.
-
- @cvar handshake_failure: A problem occurred while handshaking.
-
- This typically indicates a lack of common ciphersuites between client and
- server, or some other disagreement (about SRP parameters or key sizes,
- for example).
-
- @cvar protocol_version: The other party's SSL/TLS version was unacceptable.
-
- This indicates that the client and server couldn't agree on which version
- of SSL or TLS to use.
-
- @cvar user_canceled: The handshake is being cancelled for some reason.
-
- """
-
- close_notify = 0
- unexpected_message = 10
- bad_record_mac = 20
- decryption_failed = 21
- record_overflow = 22
- decompression_failure = 30
- handshake_failure = 40
- no_certificate = 41 #SSLv3
- bad_certificate = 42
- unsupported_certificate = 43
- certificate_revoked = 44
- certificate_expired = 45
- certificate_unknown = 46
- illegal_parameter = 47
- unknown_ca = 48
- access_denied = 49
- decode_error = 50
- decrypt_error = 51
- export_restriction = 60
- protocol_version = 70
- insufficient_security = 71
- internal_error = 80
- user_canceled = 90
- no_renegotiation = 100
- unknown_srp_username = 120
- missing_srp_username = 121
- untrusted_srp_parameters = 122
-
-class CipherSuite:
- TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0x0050
- TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0x0053
- TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0x0056
-
- TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0x0051
- TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0x0054
- TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0x0057
-
- TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A
- TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F
- TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035
- TLS_RSA_WITH_RC4_128_SHA = 0x0005
-
- srpSuites = []
- srpSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)
- srpSuites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA)
- srpSuites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA)
- def getSrpSuites(ciphers):
- suites = []
- for cipher in ciphers:
- if cipher == "aes128":
- suites.append(CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA)
- elif cipher == "aes256":
- suites.append(CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA)
- elif cipher == "3des":
- suites.append(CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)
- return suites
- getSrpSuites = staticmethod(getSrpSuites)
-
- srpRsaSuites = []
- srpRsaSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)
- srpRsaSuites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA)
- srpRsaSuites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)
- def getSrpRsaSuites(ciphers):
- suites = []
- for cipher in ciphers:
- if cipher == "aes128":
- suites.append(CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA)
- elif cipher == "aes256":
- suites.append(CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)
- elif cipher == "3des":
- suites.append(CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)
- return suites
- getSrpRsaSuites = staticmethod(getSrpRsaSuites)
-
- rsaSuites = []
- rsaSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA)
- rsaSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA)
- rsaSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA)
- rsaSuites.append(TLS_RSA_WITH_RC4_128_SHA)
- def getRsaSuites(ciphers):
- suites = []
- for cipher in ciphers:
- if cipher == "aes128":
- suites.append(CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA)
- elif cipher == "aes256":
- suites.append(CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA)
- elif cipher == "rc4":
- suites.append(CipherSuite.TLS_RSA_WITH_RC4_128_SHA)
- elif cipher == "3des":
- suites.append(CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA)
- return suites
- getRsaSuites = staticmethod(getRsaSuites)
-
- tripleDESSuites = []
- tripleDESSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)
- tripleDESSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)
- tripleDESSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA)
-
- aes128Suites = []
- aes128Suites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA)
- aes128Suites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA)
- aes128Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA)
-
- aes256Suites = []
- aes256Suites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA)
- aes256Suites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)
- aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA)
-
- rc4Suites = []
- rc4Suites.append(TLS_RSA_WITH_RC4_128_SHA)
-
-
-class Fault:
- badUsername = 101
- badPassword = 102
- badA = 103
- clientSrpFaults = range(101,104)
-
- badVerifyMessage = 601
- clientCertFaults = range(601,602)
-
- badPremasterPadding = 501
- shortPremasterSecret = 502
- clientNoAuthFaults = range(501,503)
-
- badIdentifier = 401
- badSharedKey = 402
- clientSharedKeyFaults = range(401,403)
-
- badB = 201
- serverFaults = range(201,202)
-
- badFinished = 300
- badMAC = 301
- badPadding = 302
- genericFaults = range(300,303)
-
- faultAlerts = {\
- badUsername: (AlertDescription.unknown_srp_username, \
- AlertDescription.bad_record_mac),\
- badPassword: (AlertDescription.bad_record_mac,),\
- badA: (AlertDescription.illegal_parameter,),\
- badIdentifier: (AlertDescription.handshake_failure,),\
- badSharedKey: (AlertDescription.bad_record_mac,),\
- badPremasterPadding: (AlertDescription.bad_record_mac,),\
- shortPremasterSecret: (AlertDescription.bad_record_mac,),\
- badVerifyMessage: (AlertDescription.decrypt_error,),\
- badFinished: (AlertDescription.decrypt_error,),\
- badMAC: (AlertDescription.bad_record_mac,),\
- badPadding: (AlertDescription.bad_record_mac,)
- }
-
- faultNames = {\
- badUsername: "bad username",\
- badPassword: "bad password",\
- badA: "bad A",\
- badIdentifier: "bad identifier",\
- badSharedKey: "bad sharedkey",\
- badPremasterPadding: "bad premaster padding",\
- shortPremasterSecret: "short premaster secret",\
- badVerifyMessage: "bad verify message",\
- badFinished: "bad finished message",\
- badMAC: "bad MAC",\
- badPadding: "bad padding"
- }
diff --git a/src/lib/tlslite/errors.py b/src/lib/tlslite/errors.py
deleted file mode 100755
index c7f7ba81d..000000000
--- a/src/lib/tlslite/errors.py
+++ /dev/null
@@ -1,149 +0,0 @@
-"""Exception classes.
-@sort: TLSError, TLSAbruptCloseError, TLSAlert, TLSLocalAlert, TLSRemoteAlert,
-TLSAuthenticationError, TLSNoAuthenticationError, TLSAuthenticationTypeError,
-TLSFingerprintError, TLSAuthorizationError, TLSValidationError, TLSFaultError
-"""
-
-from constants import AlertDescription, AlertLevel
-
-class TLSError(Exception):
- """Base class for all TLS Lite exceptions."""
- pass
-
-class TLSAbruptCloseError(TLSError):
- """The socket was closed without a proper TLS shutdown.
-
- The TLS specification mandates that an alert of some sort
- must be sent before the underlying socket is closed. If the socket
- is closed without this, it could signify that an attacker is trying
- to truncate the connection. It could also signify a misbehaving
- TLS implementation, or a random network failure.
- """
- pass
-
-class TLSAlert(TLSError):
- """A TLS alert has been signalled."""
- pass
-
- _descriptionStr = {\
- AlertDescription.close_notify: "close_notify",\
- AlertDescription.unexpected_message: "unexpected_message",\
- AlertDescription.bad_record_mac: "bad_record_mac",\
- AlertDescription.decryption_failed: "decryption_failed",\
- AlertDescription.record_overflow: "record_overflow",\
- AlertDescription.decompression_failure: "decompression_failure",\
- AlertDescription.handshake_failure: "handshake_failure",\
- AlertDescription.no_certificate: "no certificate",\
- AlertDescription.bad_certificate: "bad_certificate",\
- AlertDescription.unsupported_certificate: "unsupported_certificate",\
- AlertDescription.certificate_revoked: "certificate_revoked",\
- AlertDescription.certificate_expired: "certificate_expired",\
- AlertDescription.certificate_unknown: "certificate_unknown",\
- AlertDescription.illegal_parameter: "illegal_parameter",\
- AlertDescription.unknown_ca: "unknown_ca",\
- AlertDescription.access_denied: "access_denied",\
- AlertDescription.decode_error: "decode_error",\
- AlertDescription.decrypt_error: "decrypt_error",\
- AlertDescription.export_restriction: "export_restriction",\
- AlertDescription.protocol_version: "protocol_version",\
- AlertDescription.insufficient_security: "insufficient_security",\
- AlertDescription.internal_error: "internal_error",\
- AlertDescription.user_canceled: "user_canceled",\
- AlertDescription.no_renegotiation: "no_renegotiation",\
- AlertDescription.unknown_srp_username: "unknown_srp_username",\
- AlertDescription.missing_srp_username: "missing_srp_username"}
-
-class TLSLocalAlert(TLSAlert):
- """A TLS alert has been signalled by the local implementation.
-
- @type description: int
- @ivar description: Set to one of the constants in
- L{tlslite.constants.AlertDescription}
-
- @type level: int
- @ivar level: Set to one of the constants in
- L{tlslite.constants.AlertLevel}
-
- @type message: str
- @ivar message: Description of what went wrong.
- """
- def __init__(self, alert, message=None):
- self.description = alert.description
- self.level = alert.level
- self.message = message
-
- def __str__(self):
- alertStr = TLSAlert._descriptionStr.get(self.description)
- if alertStr == None:
- alertStr = str(self.description)
- if self.message:
- return alertStr + ": " + self.message
- else:
- return alertStr
-
-class TLSRemoteAlert(TLSAlert):
- """A TLS alert has been signalled by the remote implementation.
-
- @type description: int
- @ivar description: Set to one of the constants in
- L{tlslite.constants.AlertDescription}
-
- @type level: int
- @ivar level: Set to one of the constants in
- L{tlslite.constants.AlertLevel}
- """
- def __init__(self, alert):
- self.description = alert.description
- self.level = alert.level
-
- def __str__(self):
- alertStr = TLSAlert._descriptionStr.get(self.description)
- if alertStr == None:
- alertStr = str(self.description)
- return alertStr
-
-class TLSAuthenticationError(TLSError):
- """The handshake succeeded, but the other party's authentication
- was inadequate.
-
- This exception will only be raised when a
- L{tlslite.Checker.Checker} has been passed to a handshake function.
- The Checker will be invoked once the handshake completes, and if
- the Checker objects to how the other party authenticated, a
- subclass of this exception will be raised.
- """
- pass
-
-class TLSNoAuthenticationError(TLSAuthenticationError):
- """The Checker was expecting the other party to authenticate with a
- certificate chain, but this did not occur."""
- pass
-
-class TLSAuthenticationTypeError(TLSAuthenticationError):
- """The Checker was expecting the other party to authenticate with a
- different type of certificate chain."""
- pass
-
-class TLSFingerprintError(TLSAuthenticationError):
- """The Checker was expecting the other party to authenticate with a
- certificate chain that matches a different fingerprint."""
- pass
-
-class TLSAuthorizationError(TLSAuthenticationError):
- """The Checker was expecting the other party to authenticate with a
- certificate chain that has a different authorization."""
- pass
-
-class TLSValidationError(TLSAuthenticationError):
- """The Checker has determined that the other party's certificate
- chain is invalid."""
- pass
-
-class TLSFaultError(TLSError):
- """The other party responded incorrectly to an induced fault.
-
- This exception will only occur during fault testing, when a
- TLSConnection's fault variable is set to induce some sort of
- faulty behavior, and the other party doesn't respond appropriately.
- """
- pass
diff --git a/src/lib/tlslite/integration/AsyncStateMachine.py b/src/lib/tlslite/integration/AsyncStateMachine.py
deleted file mode 100755
index abed60432..000000000
--- a/src/lib/tlslite/integration/AsyncStateMachine.py
+++ /dev/null
@@ -1,235 +0,0 @@
-"""
-A state machine for using TLS Lite with asynchronous I/O.
-"""
-
-class AsyncStateMachine:
- """
- This is an abstract class that's used to integrate TLS Lite with
- asyncore and Twisted.
-
- This class signals wantsReadsEvent() and wantsWriteEvent(). When
- the underlying socket has become readable or writeable, the event
- should be passed to this class by calling inReadEvent() or
- inWriteEvent(). This class will then try to read or write through
- the socket, and will update its state appropriately.
-
- This class will forward higher-level events to its subclass. For
- example, when a complete TLS record has been received,
- outReadEvent() will be called with the decrypted data.
- """
-
- def __init__(self):
- self._clear()
-
- def _clear(self):
- #These store the various asynchronous operations (i.e.
- #generators). Only one of them, at most, is ever active at a
- #time.
- self.handshaker = None
- self.closer = None
- self.reader = None
- self.writer = None
-
- #This stores the result from the last call to the
- #currently active operation. If 0 it indicates that the
- #operation wants to read, if 1 it indicates that the
- #operation wants to write. If None, there is no active
- #operation.
- self.result = None
-
- def _checkAssert(self, maxActive=1):
- #This checks that only one operation, at most, is
- #active, and that self.result is set appropriately.
- activeOps = 0
- if self.handshaker:
- activeOps += 1
- if self.closer:
- activeOps += 1
- if self.reader:
- activeOps += 1
- if self.writer:
- activeOps += 1
-
- if self.result == None:
- if activeOps != 0:
- raise AssertionError()
- elif self.result in (0,1):
- if activeOps != 1:
- raise AssertionError()
- else:
- raise AssertionError()
- if activeOps > maxActive:
- raise AssertionError()
-
- def wantsReadEvent(self):
- """If the state machine wants to read.
-
- If an operation is active, this returns whether or not the
- operation wants to read from the socket. If an operation is
- not active, this returns None.
-
- @rtype: bool or None
- @return: If the state machine wants to read.
- """
- if self.result != None:
- return self.result == 0
- return None
-
- def wantsWriteEvent(self):
- """If the state machine wants to write.
-
- If an operation is active, this returns whether or not the
- operation wants to write to the socket. If an operation is
- not active, this returns None.
-
- @rtype: bool or None
- @return: If the state machine wants to write.
- """
- if self.result != None:
- return self.result == 1
- return None
-
- def outConnectEvent(self):
- """Called when a handshake operation completes.
-
- May be overridden in subclass.
- """
- pass
-
- def outCloseEvent(self):
- """Called when a close operation completes.
-
- May be overridden in subclass.
- """
- pass
-
- def outReadEvent(self, readBuffer):
- """Called when a read operation completes.
-
- May be overridden in subclass."""
- pass
-
- def outWriteEvent(self):
- """Called when a write operation completes.
-
- May be overridden in subclass."""
- pass
-
- def inReadEvent(self):
- """Tell the state machine it can read from the socket."""
- try:
- self._checkAssert()
- if self.handshaker:
- self._doHandshakeOp()
- elif self.closer:
- self._doCloseOp()
- elif self.reader:
- self._doReadOp()
- elif self.writer:
- self._doWriteOp()
- else:
- self.reader = self.tlsConnection.readAsync(16384)
- self._doReadOp()
- except:
- self._clear()
- raise
-
- def inWriteEvent(self):
- """Tell the state machine it can write to the socket."""
- try:
- self._checkAssert()
- if self.handshaker:
- self._doHandshakeOp()
- elif self.closer:
- self._doCloseOp()
- elif self.reader:
- self._doReadOp()
- elif self.writer:
- self._doWriteOp()
- else:
- self.outWriteEvent()
- except:
- self._clear()
- raise
-
- def _doHandshakeOp(self):
- try:
- self.result = self.handshaker.next()
- except StopIteration:
- self.handshaker = None
- self.result = None
- self.outConnectEvent()
-
- def _doCloseOp(self):
- try:
- self.result = self.closer.next()
- except StopIteration:
- self.closer = None
- self.result = None
- self.outCloseEvent()
-
- def _doReadOp(self):
- self.result = self.reader.next()
- if not self.result in (0,1):
- readBuffer = self.result
- self.reader = None
- self.result = None
- self.outReadEvent(readBuffer)
-
- def _doWriteOp(self):
- try:
- self.result = self.writer.next()
- except StopIteration:
- self.writer = None
- self.result = None
-
- def setHandshakeOp(self, handshaker):
- """Start a handshake operation.
-
- @type handshaker: generator
- @param handshaker: A generator created by using one of the
- asynchronous handshake functions (i.e. handshakeServerAsync, or
- handshakeClientxxx(..., async=True).
- """
- try:
- self._checkAssert(0)
- self.handshaker = handshaker
- self._doHandshakeOp()
- except:
- self._clear()
- raise
-
- def setServerHandshakeOp(self, **args):
- """Start a handshake operation.
-
- The arguments passed to this function will be forwarded to
- L{tlslite.TLSConnection.TLSConnection.handshakeServerAsync}.
- """
- handshaker = self.tlsConnection.handshakeServerAsync(**args)
- self.setHandshakeOp(handshaker)
-
- def setCloseOp(self):
- """Start a close operation.
- """
- try:
- self._checkAssert(0)
- self.closer = self.tlsConnection.closeAsync()
- self._doCloseOp()
- except:
- self._clear()
- raise
-
- def setWriteOp(self, writeBuffer):
- """Start a write operation.
-
- @type writeBuffer: str
- @param writeBuffer: The string to transmit.
- """
- try:
- self._checkAssert(0)
- self.writer = self.tlsConnection.writeAsync(writeBuffer)
- self._doWriteOp()
- except:
- self._clear()
- raise
-
diff --git a/src/lib/tlslite/integration/ClientHelper.py b/src/lib/tlslite/integration/ClientHelper.py
deleted file mode 100755
index 6de4ab7a0..000000000
--- a/src/lib/tlslite/integration/ClientHelper.py
+++ /dev/null
@@ -1,163 +0,0 @@
-"""
-A helper class for using TLS Lite with stdlib clients
-(httplib, xmlrpclib, imaplib, poplib).
-"""
-
-from Bcfg2.tlslite.Checker import Checker
-
-class ClientHelper:
- """This is a helper class used to integrate TLS Lite with various
- TLS clients (e.g. poplib, smtplib, httplib, etc.)"""
-
- def __init__(self,
- username=None, password=None, sharedKey=None,
- certChain=None, privateKey=None,
- cryptoID=None, protocol=None,
- x509Fingerprint=None,
- x509TrustList=None, x509CommonName=None,
- settings = None):
- """
- For client authentication, use one of these argument
- combinations:
- - username, password (SRP)
- - username, sharedKey (shared-key)
- - certChain, privateKey (certificate)
-
- For server authentication, you can either rely on the
- implicit mutual authentication performed by SRP or
- shared-keys, or you can do certificate-based server
- authentication with one of these argument combinations:
- - cryptoID[, protocol] (requires cryptoIDlib)
- - x509Fingerprint
- - x509TrustList[, x509CommonName] (requires cryptlib_py)
-
- Certificate-based server authentication is compatible with
- SRP or certificate-based client authentication. It is
- not compatible with shared-keys.
-
- The constructor does not perform the TLS handshake itself, but
- simply stores these arguments for later. The handshake is
- performed only when this class needs to connect with the
- server. Then you should be prepared to handle TLS-specific
- exceptions. See the client handshake functions in
- L{tlslite.TLSConnection.TLSConnection} for details on which
- exceptions might be raised.
-
- @type username: str
- @param username: SRP or shared-key username. Requires the
- 'password' or 'sharedKey' argument.
-
- @type password: str
- @param password: SRP password for mutual authentication.
- Requires the 'username' argument.
-
- @type sharedKey: str
- @param sharedKey: Shared key for mutual authentication.
- Requires the 'username' argument.
-
- @type certChain: L{tlslite.X509CertChain.X509CertChain} or
- L{cryptoIDlib.CertChain.CertChain}
- @param certChain: Certificate chain for client authentication.
- Requires the 'privateKey' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type privateKey: L{tlslite.utils.RSAKey.RSAKey}
- @param privateKey: Private key for client authentication.
- Requires the 'certChain' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type cryptoID: str
- @param cryptoID: cryptoID for server authentication. Mutually
- exclusive with the 'x509...' arguments.
-
- @type protocol: str
- @param protocol: cryptoID protocol URI for server
- authentication. Requires the 'cryptoID' argument.
-
- @type x509Fingerprint: str
- @param x509Fingerprint: Hex-encoded X.509 fingerprint for
- server authentication. Mutually exclusive with the 'cryptoID'
- and 'x509TrustList' arguments.
-
- @type x509TrustList: list of L{tlslite.X509.X509}
- @param x509TrustList: A list of trusted root certificates. The
- other party must present a certificate chain which extends to
- one of these root certificates. The cryptlib_py module must be
- installed to use this parameter. Mutually exclusive with the
- 'cryptoID' and 'x509Fingerprint' arguments.
-
- @type x509CommonName: str
- @param x509CommonName: The end-entity certificate's 'CN' field
- must match this value. For a web server, this is typically a
- server name such as 'www.amazon.com'. Mutually exclusive with
- the 'cryptoID' and 'x509Fingerprint' arguments. Requires the
- 'x509TrustList' argument.
-
- @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
- @param settings: Various settings which can be used to control
- the ciphersuites, certificate types, and SSL/TLS versions
- offered by the client.
- """
-
- self.username = None
- self.password = None
- self.sharedKey = None
- self.certChain = None
- self.privateKey = None
- self.checker = None
-
- #SRP Authentication
- if username and password and not \
- (sharedKey or certChain or privateKey):
- self.username = username
- self.password = password
-
- #Shared Key Authentication
- elif username and sharedKey and not \
- (password or certChain or privateKey):
- self.username = username
- self.sharedKey = sharedKey
-
- #Certificate Chain Authentication
- elif certChain and privateKey and not \
- (username or password or sharedKey):
- self.certChain = certChain
- self.privateKey = privateKey
-
- #No Authentication
- elif not password and not username and not \
- sharedKey and not certChain and not privateKey:
- pass
-
- else:
- raise ValueError("Bad parameters")
-
- #Authenticate the server based on its cryptoID or fingerprint
- if sharedKey and (cryptoID or protocol or x509Fingerprint):
- raise ValueError("Can't use shared keys with other forms of"\
- "authentication")
-
- self.checker = Checker(cryptoID, protocol, x509Fingerprint,
- x509TrustList, x509CommonName)
- self.settings = settings
-
- self.tlsSession = None
-
- def _handshake(self, tlsConnection):
- if self.username and self.password:
- tlsConnection.handshakeClientSRP(username=self.username,
- password=self.password,
- checker=self.checker,
- settings=self.settings,
- session=self.tlsSession)
- elif self.username and self.sharedKey:
- tlsConnection.handshakeClientSharedKey(username=self.username,
- sharedKey=self.sharedKey,
- settings=self.settings)
- else:
- tlsConnection.handshakeClientCert(certChain=self.certChain,
- privateKey=self.privateKey,
- checker=self.checker,
- settings=self.settings,
- session=self.tlsSession)
- self.tlsSession = tlsConnection.session
diff --git a/src/lib/tlslite/integration/HTTPTLSConnection.py b/src/lib/tlslite/integration/HTTPTLSConnection.py
deleted file mode 100755
index a50c053c7..000000000
--- a/src/lib/tlslite/integration/HTTPTLSConnection.py
+++ /dev/null
@@ -1,169 +0,0 @@
-"""TLS Lite + httplib."""
-
-import socket
-import httplib
-from Bcfg2.tlslite.TLSConnection import TLSConnection
-from Bcfg2.tlslite.integration.ClientHelper import ClientHelper
-
-
-class HTTPBaseTLSConnection(httplib.HTTPConnection):
- """This abstract class provides a framework for adding TLS support
- to httplib."""
-
- default_port = 443
-
- def __init__(self, host, port=None, strict=None):
- if strict == None:
- #Python 2.2 doesn't support strict
- httplib.HTTPConnection.__init__(self, host, port)
- else:
- httplib.HTTPConnection.__init__(self, host, port, strict)
-
- def connect(self):
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- if hasattr(sock, 'settimeout'):
- sock.settimeout(90)
- sock.connect((self.host, self.port))
-
- #Use a TLSConnection to emulate a socket
- self.sock = TLSConnection(sock)
-
- #When httplib closes this, close the socket
- self.sock.closeSocket = True
- self._handshake(self.sock)
-
- def _handshake(self, tlsConnection):
- """Called to perform some sort of handshake.
-
- This method must be overridden in a subclass to do some type of
- handshake. This method will be called after the socket has
- been connected but before any data has been sent. If this
- method does not raise an exception, the TLS connection will be
- considered valid.
-
- This method may (or may not) be called every time an HTTP
- request is performed, depending on whether the underlying HTTP
- connection is persistent.
-
- @type tlsConnection: L{tlslite.TLSConnection.TLSConnection}
- @param tlsConnection: The connection to perform the handshake
- on.
- """
- raise NotImplementedError()
-
-
-class HTTPTLSConnection(HTTPBaseTLSConnection, ClientHelper):
- """This class extends L{HTTPBaseTLSConnection} to support the
- common types of handshaking."""
-
- def __init__(self, host, port=None,
- username=None, password=None, sharedKey=None,
- certChain=None, privateKey=None,
- cryptoID=None, protocol=None,
- x509Fingerprint=None,
- x509TrustList=None, x509CommonName=None,
- settings = None):
- """Create a new HTTPTLSConnection.
-
- For client authentication, use one of these argument
- combinations:
- - username, password (SRP)
- - username, sharedKey (shared-key)
- - certChain, privateKey (certificate)
-
- For server authentication, you can either rely on the
- implicit mutual authentication performed by SRP or
- shared-keys, or you can do certificate-based server
- authentication with one of these argument combinations:
- - cryptoID[, protocol] (requires cryptoIDlib)
- - x509Fingerprint
- - x509TrustList[, x509CommonName] (requires cryptlib_py)
-
- Certificate-based server authentication is compatible with
- SRP or certificate-based client authentication. It is
- not compatible with shared-keys.
-
- The constructor does not perform the TLS handshake itself, but
- simply stores these arguments for later. The handshake is
- performed only when this class needs to connect with the
- server. Thus you should be prepared to handle TLS-specific
- exceptions when calling methods inherited from
- L{httplib.HTTPConnection} such as request(), connect(), and
- send(). See the client handshake functions in
- L{tlslite.TLSConnection.TLSConnection} for details on which
- exceptions might be raised.
-
- @type host: str
- @param host: Server to connect to.
-
- @type port: int
- @param port: Port to connect to.
-
- @type username: str
- @param username: SRP or shared-key username. Requires the
- 'password' or 'sharedKey' argument.
-
- @type password: str
- @param password: SRP password for mutual authentication.
- Requires the 'username' argument.
-
- @type sharedKey: str
- @param sharedKey: Shared key for mutual authentication.
- Requires the 'username' argument.
-
- @type certChain: L{tlslite.X509CertChain.X509CertChain} or
- L{cryptoIDlib.CertChain.CertChain}
- @param certChain: Certificate chain for client authentication.
- Requires the 'privateKey' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type privateKey: L{tlslite.utils.RSAKey.RSAKey}
- @param privateKey: Private key for client authentication.
- Requires the 'certChain' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type cryptoID: str
- @param cryptoID: cryptoID for server authentication. Mutually
- exclusive with the 'x509...' arguments.
-
- @type protocol: str
- @param protocol: cryptoID protocol URI for server
- authentication. Requires the 'cryptoID' argument.
-
- @type x509Fingerprint: str
- @param x509Fingerprint: Hex-encoded X.509 fingerprint for
- server authentication. Mutually exclusive with the 'cryptoID'
- and 'x509TrustList' arguments.
-
- @type x509TrustList: list of L{tlslite.X509.X509}
- @param x509TrustList: A list of trusted root certificates. The
- other party must present a certificate chain which extends to
- one of these root certificates. The cryptlib_py module must be
- installed to use this parameter. Mutually exclusive with the
- 'cryptoID' and 'x509Fingerprint' arguments.
-
- @type x509CommonName: str
- @param x509CommonName: The end-entity certificate's 'CN' field
- must match this value. For a web server, this is typically a
- server name such as 'www.amazon.com'. Mutually exclusive with
- the 'cryptoID' and 'x509Fingerprint' arguments. Requires the
- 'x509TrustList' argument.
-
- @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
- @param settings: Various settings which can be used to control
- the ciphersuites, certificate types, and SSL/TLS versions
- offered by the client.
- """
-
- HTTPBaseTLSConnection.__init__(self, host, port)
-
- ClientHelper.__init__(self,
- username, password, sharedKey,
- certChain, privateKey,
- cryptoID, protocol,
- x509Fingerprint,
- x509TrustList, x509CommonName,
- settings)
-
- def _handshake(self, tlsConnection):
- ClientHelper._handshake(self, tlsConnection)
diff --git a/src/lib/tlslite/integration/IMAP4_TLS.py b/src/lib/tlslite/integration/IMAP4_TLS.py
deleted file mode 100755
index 2b005dc7e..000000000
--- a/src/lib/tlslite/integration/IMAP4_TLS.py
+++ /dev/null
@@ -1,132 +0,0 @@
-"""TLS Lite + imaplib."""
-
-import socket
-from imaplib import IMAP4
-from Bcfg2.tlslite.TLSConnection import TLSConnection
-from Bcfg2.tlslite.integration.ClientHelper import ClientHelper
-
-# IMAP TLS PORT
-IMAP4_TLS_PORT = 993
-
-class IMAP4_TLS(IMAP4, ClientHelper):
- """This class extends L{imaplib.IMAP4} with TLS support."""
-
- def __init__(self, host = '', port = IMAP4_TLS_PORT,
- username=None, password=None, sharedKey=None,
- certChain=None, privateKey=None,
- cryptoID=None, protocol=None,
- x509Fingerprint=None,
- x509TrustList=None, x509CommonName=None,
- settings=None):
- """Create a new IMAP4_TLS.
-
- For client authentication, use one of these argument
- combinations:
- - username, password (SRP)
- - username, sharedKey (shared-key)
- - certChain, privateKey (certificate)
-
- For server authentication, you can either rely on the
- implicit mutual authentication performed by SRP or
- shared-keys, or you can do certificate-based server
- authentication with one of these argument combinations:
- - cryptoID[, protocol] (requires cryptoIDlib)
- - x509Fingerprint
- - x509TrustList[, x509CommonName] (requires cryptlib_py)
-
- Certificate-based server authentication is compatible with
- SRP or certificate-based client authentication. It is
- not compatible with shared-keys.
-
- The caller should be prepared to handle TLS-specific
- exceptions. See the client handshake functions in
- L{tlslite.TLSConnection.TLSConnection} for details on which
- exceptions might be raised.
-
- @type host: str
- @param host: Server to connect to.
-
- @type port: int
- @param port: Port to connect to.
-
- @type username: str
- @param username: SRP or shared-key username. Requires the
- 'password' or 'sharedKey' argument.
-
- @type password: str
- @param password: SRP password for mutual authentication.
- Requires the 'username' argument.
-
- @type sharedKey: str
- @param sharedKey: Shared key for mutual authentication.
- Requires the 'username' argument.
-
- @type certChain: L{tlslite.X509CertChain.X509CertChain} or
- L{cryptoIDlib.CertChain.CertChain}
- @param certChain: Certificate chain for client authentication.
- Requires the 'privateKey' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type privateKey: L{tlslite.utils.RSAKey.RSAKey}
- @param privateKey: Private key for client authentication.
- Requires the 'certChain' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type cryptoID: str
- @param cryptoID: cryptoID for server authentication. Mutually
- exclusive with the 'x509...' arguments.
-
- @type protocol: str
- @param protocol: cryptoID protocol URI for server
- authentication. Requires the 'cryptoID' argument.
-
- @type x509Fingerprint: str
- @param x509Fingerprint: Hex-encoded X.509 fingerprint for
- server authentication. Mutually exclusive with the 'cryptoID'
- and 'x509TrustList' arguments.
-
- @type x509TrustList: list of L{tlslite.X509.X509}
- @param x509TrustList: A list of trusted root certificates. The
- other party must present a certificate chain which extends to
- one of these root certificates. The cryptlib_py module must be
- installed to use this parameter. Mutually exclusive with the
- 'cryptoID' and 'x509Fingerprint' arguments.
-
- @type x509CommonName: str
- @param x509CommonName: The end-entity certificate's 'CN' field
- must match this value. For a web server, this is typically a
- server name such as 'www.amazon.com'. Mutually exclusive with
- the 'cryptoID' and 'x509Fingerprint' arguments. Requires the
- 'x509TrustList' argument.
-
- @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
- @param settings: Various settings which can be used to control
- the ciphersuites, certificate types, and SSL/TLS versions
- offered by the client.
- """
-
- ClientHelper.__init__(self,
- username, password, sharedKey,
- certChain, privateKey,
- cryptoID, protocol,
- x509Fingerprint,
- x509TrustList, x509CommonName,
- settings)
-
- IMAP4.__init__(self, host, port)
-
-
- def open(self, host = '', port = IMAP4_TLS_PORT):
- """Setup connection to remote server on "host:port".
-
- This connection will be used by the routines:
- read, readline, send, shutdown.
- """
- self.host = host
- self.port = port
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.sock.connect((host, port))
- self.sock = TLSConnection(self.sock)
- self.sock.closeSocket = True
- ClientHelper._handshake(self, self.sock)
- self.file = self.sock.makefile('rb')
diff --git a/src/lib/tlslite/integration/IntegrationHelper.py b/src/lib/tlslite/integration/IntegrationHelper.py
deleted file mode 100755
index af5193b48..000000000
--- a/src/lib/tlslite/integration/IntegrationHelper.py
+++ /dev/null
@@ -1,52 +0,0 @@
-
-class IntegrationHelper:
-
- def __init__(self,
- username=None, password=None, sharedKey=None,
- certChain=None, privateKey=None,
- cryptoID=None, protocol=None,
- x509Fingerprint=None,
- x509TrustList=None, x509CommonName=None,
- settings = None):
-
- self.username = None
- self.password = None
- self.sharedKey = None
- self.certChain = None
- self.privateKey = None
- self.checker = None
-
- #SRP Authentication
- if username and password and not \
- (sharedKey or certChain or privateKey):
- self.username = username
- self.password = password
-
- #Shared Key Authentication
- elif username and sharedKey and not \
- (password or certChain or privateKey):
- self.username = username
- self.sharedKey = sharedKey
-
- #Certificate Chain Authentication
- elif certChain and privateKey and not \
- (username or password or sharedKey):
- self.certChain = certChain
- self.privateKey = privateKey
-
- #No Authentication
- elif not password and not username and not \
- sharedKey and not certChain and not privateKey:
- pass
-
- else:
- raise ValueError("Bad parameters")
-
- #Authenticate the server based on its cryptoID or fingerprint
- if sharedKey and (cryptoID or protocol or x509Fingerprint):
- raise ValueError("Can't use shared keys with other forms of"\
- "authentication")
-
- self.checker = Checker(cryptoID, protocol, x509Fingerprint,
- x509TrustList, x509CommonName)
- self.settings = settings \ No newline at end of file
diff --git a/src/lib/tlslite/integration/POP3_TLS.py b/src/lib/tlslite/integration/POP3_TLS.py
deleted file mode 100755
index 8245a13ca..000000000
--- a/src/lib/tlslite/integration/POP3_TLS.py
+++ /dev/null
@@ -1,142 +0,0 @@
-"""TLS Lite + poplib."""
-
-import socket
-from poplib import POP3
-from Bcfg2.tlslite.TLSConnection import TLSConnection
-from Bcfg2.tlslite.integration.ClientHelper import ClientHelper
-
-# POP TLS PORT
-POP3_TLS_PORT = 995
-
-class POP3_TLS(POP3, ClientHelper):
- """This class extends L{poplib.POP3} with TLS support."""
-
- def __init__(self, host, port = POP3_TLS_PORT,
- username=None, password=None, sharedKey=None,
- certChain=None, privateKey=None,
- cryptoID=None, protocol=None,
- x509Fingerprint=None,
- x509TrustList=None, x509CommonName=None,
- settings=None):
- """Create a new POP3_TLS.
-
- For client authentication, use one of these argument
- combinations:
- - username, password (SRP)
- - username, sharedKey (shared-key)
- - certChain, privateKey (certificate)
-
- For server authentication, you can either rely on the
- implicit mutual authentication performed by SRP or
- shared-keys, or you can do certificate-based server
- authentication with one of these argument combinations:
- - cryptoID[, protocol] (requires cryptoIDlib)
- - x509Fingerprint
- - x509TrustList[, x509CommonName] (requires cryptlib_py)
-
- Certificate-based server authentication is compatible with
- SRP or certificate-based client authentication. It is
- not compatible with shared-keys.
-
- The caller should be prepared to handle TLS-specific
- exceptions. See the client handshake functions in
- L{tlslite.TLSConnection.TLSConnection} for details on which
- exceptions might be raised.
-
- @type host: str
- @param host: Server to connect to.
-
- @type port: int
- @param port: Port to connect to.
-
- @type username: str
- @param username: SRP or shared-key username. Requires the
- 'password' or 'sharedKey' argument.
-
- @type password: str
- @param password: SRP password for mutual authentication.
- Requires the 'username' argument.
-
- @type sharedKey: str
- @param sharedKey: Shared key for mutual authentication.
- Requires the 'username' argument.
-
- @type certChain: L{tlslite.X509CertChain.X509CertChain} or
- L{cryptoIDlib.CertChain.CertChain}
- @param certChain: Certificate chain for client authentication.
- Requires the 'privateKey' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type privateKey: L{tlslite.utils.RSAKey.RSAKey}
- @param privateKey: Private key for client authentication.
- Requires the 'certChain' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type cryptoID: str
- @param cryptoID: cryptoID for server authentication. Mutually
- exclusive with the 'x509...' arguments.
-
- @type protocol: str
- @param protocol: cryptoID protocol URI for server
- authentication. Requires the 'cryptoID' argument.
-
- @type x509Fingerprint: str
- @param x509Fingerprint: Hex-encoded X.509 fingerprint for
- server authentication. Mutually exclusive with the 'cryptoID'
- and 'x509TrustList' arguments.
-
- @type x509TrustList: list of L{tlslite.X509.X509}
- @param x509TrustList: A list of trusted root certificates. The
- other party must present a certificate chain which extends to
- one of these root certificates. The cryptlib_py module must be
- installed to use this parameter. Mutually exclusive with the
- 'cryptoID' and 'x509Fingerprint' arguments.
-
- @type x509CommonName: str
- @param x509CommonName: The end-entity certificate's 'CN' field
- must match this value. For a web server, this is typically a
- server name such as 'www.amazon.com'. Mutually exclusive with
- the 'cryptoID' and 'x509Fingerprint' arguments. Requires the
- 'x509TrustList' argument.
-
- @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
- @param settings: Various settings which can be used to control
- the ciphersuites, certificate types, and SSL/TLS versions
- offered by the client.
- """
-
- self.host = host
- self.port = port
- msg = "getaddrinfo returns an empty list"
- self.sock = None
- for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
- af, socktype, proto, canonname, sa = res
- try:
- self.sock = socket.socket(af, socktype, proto)
- self.sock.connect(sa)
- except socket.error, msg:
- if self.sock:
- self.sock.close()
- self.sock = None
- continue
- break
- if not self.sock:
- raise socket.error, msg
-
- ### New code below (all else copied from poplib)
- ClientHelper.__init__(self,
- username, password, sharedKey,
- certChain, privateKey,
- cryptoID, protocol,
- x509Fingerprint,
- x509TrustList, x509CommonName,
- settings)
-
- self.sock = TLSConnection(self.sock)
- self.sock.closeSocket = True
- ClientHelper._handshake(self, self.sock)
- ###
-
- self.file = self.sock.makefile('rb')
- self._debugging = 0
- self.welcome = self._getresp()
diff --git a/src/lib/tlslite/integration/SMTP_TLS.py b/src/lib/tlslite/integration/SMTP_TLS.py
deleted file mode 100755
index 203cc0b7f..000000000
--- a/src/lib/tlslite/integration/SMTP_TLS.py
+++ /dev/null
@@ -1,114 +0,0 @@
-"""TLS Lite + smtplib."""
-
-from smtplib import SMTP
-from Bcfg2.tlslite.TLSConnection import TLSConnection
-from Bcfg2.tlslite.integration.ClientHelper import ClientHelper
-
-class SMTP_TLS(SMTP):
- """This class extends L{smtplib.SMTP} with TLS support."""
-
- def starttls(self,
- username=None, password=None, sharedKey=None,
- certChain=None, privateKey=None,
- cryptoID=None, protocol=None,
- x509Fingerprint=None,
- x509TrustList=None, x509CommonName=None,
- settings=None):
- """Puts the connection to the SMTP server into TLS mode.
-
- If the server supports TLS, this will encrypt the rest of the SMTP
- session.
-
- For client authentication, use one of these argument
- combinations:
- - username, password (SRP)
- - username, sharedKey (shared-key)
- - certChain, privateKey (certificate)
-
- For server authentication, you can either rely on the
- implicit mutual authentication performed by SRP or
- shared-keys, or you can do certificate-based server
- authentication with one of these argument combinations:
- - cryptoID[, protocol] (requires cryptoIDlib)
- - x509Fingerprint
- - x509TrustList[, x509CommonName] (requires cryptlib_py)
-
- Certificate-based server authentication is compatible with
- SRP or certificate-based client authentication. It is
- not compatible with shared-keys.
-
- The caller should be prepared to handle TLS-specific
- exceptions. See the client handshake functions in
- L{tlslite.TLSConnection.TLSConnection} for details on which
- exceptions might be raised.
-
- @type username: str
- @param username: SRP or shared-key username. Requires the
- 'password' or 'sharedKey' argument.
-
- @type password: str
- @param password: SRP password for mutual authentication.
- Requires the 'username' argument.
-
- @type sharedKey: str
- @param sharedKey: Shared key for mutual authentication.
- Requires the 'username' argument.
-
- @type certChain: L{tlslite.X509CertChain.X509CertChain} or
- L{cryptoIDlib.CertChain.CertChain}
- @param certChain: Certificate chain for client authentication.
- Requires the 'privateKey' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type privateKey: L{tlslite.utils.RSAKey.RSAKey}
- @param privateKey: Private key for client authentication.
- Requires the 'certChain' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type cryptoID: str
- @param cryptoID: cryptoID for server authentication. Mutually
- exclusive with the 'x509...' arguments.
-
- @type protocol: str
- @param protocol: cryptoID protocol URI for server
- authentication. Requires the 'cryptoID' argument.
-
- @type x509Fingerprint: str
- @param x509Fingerprint: Hex-encoded X.509 fingerprint for
- server authentication. Mutually exclusive with the 'cryptoID'
- and 'x509TrustList' arguments.
-
- @type x509TrustList: list of L{tlslite.X509.X509}
- @param x509TrustList: A list of trusted root certificates. The
- other party must present a certificate chain which extends to
- one of these root certificates. The cryptlib_py module must be
- installed to use this parameter. Mutually exclusive with the
- 'cryptoID' and 'x509Fingerprint' arguments.
-
- @type x509CommonName: str
- @param x509CommonName: The end-entity certificate's 'CN' field
- must match this value. For a web server, this is typically a
- server name such as 'www.amazon.com'. Mutually exclusive with
- the 'cryptoID' and 'x509Fingerprint' arguments. Requires the
- 'x509TrustList' argument.
-
- @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
- @param settings: Various settings which can be used to control
- the ciphersuites, certificate types, and SSL/TLS versions
- offered by the client.
- """
- (resp, reply) = self.docmd("STARTTLS")
- if resp == 220:
- helper = ClientHelper(
- username, password, sharedKey,
- certChain, privateKey,
- cryptoID, protocol,
- x509Fingerprint,
- x509TrustList, x509CommonName,
- settings)
- conn = TLSConnection(self.sock)
- conn.closeSocket = True
- helper._handshake(conn)
- self.sock = conn
- self.file = conn.makefile('rb')
- return (resp, reply)
diff --git a/src/lib/tlslite/integration/TLSAsyncDispatcherMixIn.py b/src/lib/tlslite/integration/TLSAsyncDispatcherMixIn.py
deleted file mode 100755
index 9201e5cba..000000000
--- a/src/lib/tlslite/integration/TLSAsyncDispatcherMixIn.py
+++ /dev/null
@@ -1,139 +0,0 @@
-"""TLS Lite + asyncore."""
-
-
-import asyncore
-from Bcfg2.tlslite.TLSConnection import TLSConnection
-from AsyncStateMachine import AsyncStateMachine
-
-
-class TLSAsyncDispatcherMixIn(AsyncStateMachine):
- """This class can be "mixed in" with an
- L{asyncore.dispatcher} to add TLS support.
-
- This class essentially sits between the dispatcher and the select
- loop, intercepting events and only calling the dispatcher when
- applicable.
-
- In the case of handle_read(), a read operation will be activated,
- and when it completes, the bytes will be placed in a buffer where
- the dispatcher can retrieve them by calling recv(), and the
- dispatcher's handle_read() will be called.
-
- In the case of handle_write(), the dispatcher's handle_write() will
- be called, and when it calls send(), a write operation will be
- activated.
-
- To use this class, you must combine it with an asyncore.dispatcher,
- and pass in a handshake operation with setServerHandshakeOp().
-
- Below is an example of using this class with medusa. This class is
- mixed in with http_channel to create http_tls_channel. Note:
- 1. the mix-in is listed first in the inheritance list
-
- 2. the input buffer size must be at least 16K, otherwise the
- dispatcher might not read all the bytes from the TLS layer,
- leaving some bytes in limbo.
-
- 3. IE seems to have a problem receiving a whole HTTP response in a
- single TLS record, so HTML pages containing '\\r\\n\\r\\n' won't
- be displayed on IE.
-
- Add the following text into 'start_medusa.py', in the 'HTTP Server'
- section::
-
- from tlslite.api import *
- s = open("./serverX509Cert.pem").read()
- x509 = X509()
- x509.parse(s)
- certChain = X509CertChain([x509])
-
- s = open("./serverX509Key.pem").read()
- privateKey = parsePEMKey(s, private=True)
-
- class http_tls_channel(TLSAsyncDispatcherMixIn,
- http_server.http_channel):
- ac_in_buffer_size = 16384
-
- def __init__ (self, server, conn, addr):
- http_server.http_channel.__init__(self, server, conn, addr)
- TLSAsyncDispatcherMixIn.__init__(self, conn)
- self.tlsConnection.ignoreAbruptClose = True
- self.setServerHandshakeOp(certChain=certChain,
- privateKey=privateKey)
-
- hs.channel_class = http_tls_channel
-
- If the TLS layer raises an exception, the exception will be caught
- in asyncore.dispatcher, which will call close() on this class. The
- TLS layer always closes the TLS connection before raising an
- exception, so the close operation will complete right away, causing
- asyncore.dispatcher.close() to be called, which closes the socket
- and removes this instance from the asyncore loop.
-
- """
-
-
- def __init__(self, sock=None):
- AsyncStateMachine.__init__(self)
-
- if sock:
- self.tlsConnection = TLSConnection(sock)
-
- #Calculate the sibling I'm being mixed in with.
- #This is necessary since we override functions
- #like readable(), handle_read(), etc., but we
- #also want to call the sibling's versions.
- for cl in self.__class__.__bases__:
- if cl != TLSAsyncDispatcherMixIn and cl != AsyncStateMachine:
- self.siblingClass = cl
- break
- else:
- raise AssertionError()
-
- def readable(self):
- result = self.wantsReadEvent()
- if result != None:
- return result
- return self.siblingClass.readable(self)
-
- def writable(self):
- result = self.wantsWriteEvent()
- if result != None:
- return result
- return self.siblingClass.writable(self)
-
- def handle_read(self):
- self.inReadEvent()
-
- def handle_write(self):
- self.inWriteEvent()
-
- def outConnectEvent(self):
- self.siblingClass.handle_connect(self)
-
- def outCloseEvent(self):
- asyncore.dispatcher.close(self)
-
- def outReadEvent(self, readBuffer):
- self.readBuffer = readBuffer
- self.siblingClass.handle_read(self)
-
- def outWriteEvent(self):
- self.siblingClass.handle_write(self)
-
- def recv(self, bufferSize=16384):
- if bufferSize < 16384 or self.readBuffer == None:
- raise AssertionError()
- returnValue = self.readBuffer
- self.readBuffer = None
- return returnValue
-
- def send(self, writeBuffer):
- self.setWriteOp(writeBuffer)
- return len(writeBuffer)
-
- def close(self):
- if hasattr(self, "tlsConnection"):
- self.setCloseOp()
- else:
- asyncore.dispatcher.close(self)
diff --git a/src/lib/tlslite/integration/TLSSocketServerMixIn.py b/src/lib/tlslite/integration/TLSSocketServerMixIn.py
deleted file mode 100755
index fe9f303b4..000000000
--- a/src/lib/tlslite/integration/TLSSocketServerMixIn.py
+++ /dev/null
@@ -1,59 +0,0 @@
-"""TLS Lite + SocketServer."""
-
-from Bcfg2.tlslite.TLSConnection import TLSConnection
-
-class TLSSocketServerMixIn:
- """
- This class can be mixed in with any L{SocketServer.TCPServer} to
- add TLS support.
-
- To use this class, define a new class that inherits from it and
- some L{SocketServer.TCPServer} (with the mix-in first). Then
- implement the handshake() method, doing some sort of server
- handshake on the connection argument. If the handshake method
- returns True, the RequestHandler will be triggered. Below is a
- complete example of a threaded HTTPS server::
-
- from SocketServer import *
- from BaseHTTPServer import *
- from SimpleHTTPServer import *
- from tlslite.api import *
-
- s = open("./serverX509Cert.pem").read()
- x509 = X509()
- x509.parse(s)
- certChain = X509CertChain([x509])
-
- s = open("./serverX509Key.pem").read()
- privateKey = parsePEMKey(s, private=True)
-
- sessionCache = SessionCache()
-
- class MyHTTPServer(ThreadingMixIn, TLSSocketServerMixIn,
- HTTPServer):
- def handshake(self, tlsConnection):
- try:
- tlsConnection.handshakeServer(certChain=certChain,
- privateKey=privateKey,
- sessionCache=sessionCache)
- tlsConnection.ignoreAbruptClose = True
- return True
- except TLSError, error:
- print "Handshake failure:", str(error)
- return False
-
- httpd = MyHTTPServer(('localhost', 443), SimpleHTTPRequestHandler)
- httpd.serve_forever()
- """
-
-
- def finish_request(self, sock, client_address):
- tlsConnection = TLSConnection(sock)
- if self.handshake(tlsConnection) == True:
- self.RequestHandlerClass(tlsConnection, client_address, self)
- tlsConnection.close()
-
- #Implement this method to do some form of handshaking. Return True
- #if the handshake finishes properly and the request is authorized.
- def handshake(self, tlsConnection):
- raise NotImplementedError()
diff --git a/src/lib/tlslite/integration/TLSTwistedProtocolWrapper.py b/src/lib/tlslite/integration/TLSTwistedProtocolWrapper.py
deleted file mode 100755
index b9d2f8529..000000000
--- a/src/lib/tlslite/integration/TLSTwistedProtocolWrapper.py
+++ /dev/null
@@ -1,196 +0,0 @@
-"""TLS Lite + Twisted."""
-
-from twisted.protocols.policies import ProtocolWrapper, WrappingFactory
-from twisted.python.failure import Failure
-
-from AsyncStateMachine import AsyncStateMachine
-from Bcfg2.tlslite.TLSConnection import TLSConnection
-from Bcfg2.tlslite.errors import *
-
-import socket
-import errno
-
-
-#The TLSConnection is created around a "fake socket" that
-#plugs it into the underlying Twisted transport
-class _FakeSocket:
- def __init__(self, wrapper):
- self.wrapper = wrapper
- self.data = ""
-
- def send(self, data):
- ProtocolWrapper.write(self.wrapper, data)
- return len(data)
-
- def recv(self, numBytes):
- if self.data == "":
- raise socket.error, (errno.EWOULDBLOCK, "")
- returnData = self.data[:numBytes]
- self.data = self.data[numBytes:]
- return returnData
-
-class TLSTwistedProtocolWrapper(ProtocolWrapper, AsyncStateMachine):
- """This class can wrap Twisted protocols to add TLS support.
-
- Below is a complete example of using TLS Lite with a Twisted echo
- server.
-
- There are two server implementations below. Echo is the original
- protocol, which is oblivious to TLS. Echo1 subclasses Echo and
- negotiates TLS when the client connects. Echo2 subclasses Echo and
- negotiates TLS when the client sends "STARTTLS"::
-
- from twisted.internet.protocol import Protocol, Factory
- from twisted.internet import reactor
- from twisted.protocols.policies import WrappingFactory
- from twisted.protocols.basic import LineReceiver
- from twisted.python import log
- from twisted.python.failure import Failure
- import sys
- from tlslite.api import *
-
- s = open("./serverX509Cert.pem").read()
- x509 = X509()
- x509.parse(s)
- certChain = X509CertChain([x509])
-
- s = open("./serverX509Key.pem").read()
- privateKey = parsePEMKey(s, private=True)
-
- verifierDB = VerifierDB("verifierDB")
- verifierDB.open()
-
- class Echo(LineReceiver):
- def connectionMade(self):
- self.transport.write("Welcome to the echo server!\\r\\n")
-
- def lineReceived(self, line):
- self.transport.write(line + "\\r\\n")
-
- class Echo1(Echo):
- def connectionMade(self):
- if not self.transport.tlsStarted:
- self.transport.setServerHandshakeOp(certChain=certChain,
- privateKey=privateKey,
- verifierDB=verifierDB)
- else:
- Echo.connectionMade(self)
-
- def connectionLost(self, reason):
- pass #Handle any TLS exceptions here
-
- class Echo2(Echo):
- def lineReceived(self, data):
- if data == "STARTTLS":
- self.transport.setServerHandshakeOp(certChain=certChain,
- privateKey=privateKey,
- verifierDB=verifierDB)
- else:
- Echo.lineReceived(self, data)
-
- def connectionLost(self, reason):
- pass #Handle any TLS exceptions here
-
- factory = Factory()
- factory.protocol = Echo1
- #factory.protocol = Echo2
-
- wrappingFactory = WrappingFactory(factory)
- wrappingFactory.protocol = TLSTwistedProtocolWrapper
-
- log.startLogging(sys.stdout)
- reactor.listenTCP(1079, wrappingFactory)
- reactor.run()
-
- This class works as follows:
-
- Data comes in and is given to the AsyncStateMachine for handling.
- AsyncStateMachine will forward events to this class, and we'll
- pass them on to the ProtocolHandler, which will proxy them to the
- wrapped protocol. The wrapped protocol may then call back into
- this class, and these calls will be proxied into the
- AsyncStateMachine.
-
- The call graph looks like this:
- - self.dataReceived
- - AsyncStateMachine.inReadEvent
- - self.out(Connect|Close|Read)Event
- - ProtocolWrapper.(connectionMade|loseConnection|dataReceived)
- - self.(loseConnection|write|writeSequence)
- - AsyncStateMachine.(setCloseOp|setWriteOp)
- """
-
- #WARNING: IF YOU COPY-AND-PASTE THE ABOVE CODE, BE SURE TO REMOVE
- #THE EXTRA ESCAPING AROUND "\\r\\n"
-
- def __init__(self, factory, wrappedProtocol):
- ProtocolWrapper.__init__(self, factory, wrappedProtocol)
- AsyncStateMachine.__init__(self)
- self.fakeSocket = _FakeSocket(self)
- self.tlsConnection = TLSConnection(self.fakeSocket)
- self.tlsStarted = False
- self.connectionLostCalled = False
-
- def connectionMade(self):
- try:
- ProtocolWrapper.connectionMade(self)
- except TLSError, e:
- self.connectionLost(Failure(e))
- ProtocolWrapper.loseConnection(self)
-
- def dataReceived(self, data):
- try:
- if not self.tlsStarted:
- ProtocolWrapper.dataReceived(self, data)
- else:
- self.fakeSocket.data += data
- while self.fakeSocket.data:
- AsyncStateMachine.inReadEvent(self)
- except TLSError, e:
- self.connectionLost(Failure(e))
- ProtocolWrapper.loseConnection(self)
-
- def connectionLost(self, reason):
- if not self.connectionLostCalled:
- ProtocolWrapper.connectionLost(self, reason)
- self.connectionLostCalled = True
-
-
- def outConnectEvent(self):
- ProtocolWrapper.connectionMade(self)
-
- def outCloseEvent(self):
- ProtocolWrapper.loseConnection(self)
-
- def outReadEvent(self, data):
- if data == "":
- ProtocolWrapper.loseConnection(self)
- else:
- ProtocolWrapper.dataReceived(self, data)
-
-
- def setServerHandshakeOp(self, **args):
- self.tlsStarted = True
- AsyncStateMachine.setServerHandshakeOp(self, **args)
-
- def loseConnection(self):
- if not self.tlsStarted:
- ProtocolWrapper.loseConnection(self)
- else:
- AsyncStateMachine.setCloseOp(self)
-
- def write(self, data):
- if not self.tlsStarted:
- ProtocolWrapper.write(self, data)
- else:
- #Because of the FakeSocket, write operations are guaranteed to
- #terminate immediately.
- AsyncStateMachine.setWriteOp(self, data)
-
- def writeSequence(self, seq):
- if not self.tlsStarted:
- ProtocolWrapper.writeSequence(self, seq)
- else:
- #Because of the FakeSocket, write operations are guaranteed to
- #terminate immediately.
- AsyncStateMachine.setWriteOp(self, "".join(seq))
diff --git a/src/lib/tlslite/integration/XMLRPCTransport.py b/src/lib/tlslite/integration/XMLRPCTransport.py
deleted file mode 100755
index 61d03428b..000000000
--- a/src/lib/tlslite/integration/XMLRPCTransport.py
+++ /dev/null
@@ -1,137 +0,0 @@
-"""TLS Lite + xmlrpclib."""
-
-import xmlrpclib
-import httplib
-from Bcfg2.tlslite.integration.HTTPTLSConnection import HTTPTLSConnection
-from Bcfg2.tlslite.integration.ClientHelper import ClientHelper
-
-
-class XMLRPCTransport(xmlrpclib.Transport, ClientHelper):
- """Handles an HTTPS transaction to an XML-RPC server."""
-
- def __init__(self,
- username=None, password=None, sharedKey=None,
- certChain=None, privateKey=None,
- cryptoID=None, protocol=None,
- x509Fingerprint=None,
- x509TrustList=None, x509CommonName=None,
- settings=None):
- """Create a new XMLRPCTransport.
-
- An instance of this class can be passed to L{xmlrpclib.ServerProxy}
- to use TLS with XML-RPC calls::
-
- from tlslite.api import XMLRPCTransport
- from xmlrpclib import ServerProxy
-
- transport = XMLRPCTransport(user="alice", password="abra123")
- server = ServerProxy("https://localhost", transport)
-
- For client authentication, use one of these argument
- combinations:
- - username, password (SRP)
- - username, sharedKey (shared-key)
- - certChain, privateKey (certificate)
-
- For server authentication, you can either rely on the
- implicit mutual authentication performed by SRP or
- shared-keys, or you can do certificate-based server
- authentication with one of these argument combinations:
- - cryptoID[, protocol] (requires cryptoIDlib)
- - x509Fingerprint
- - x509TrustList[, x509CommonName] (requires cryptlib_py)
-
- Certificate-based server authentication is compatible with
- SRP or certificate-based client authentication. It is
- not compatible with shared-keys.
-
- The constructor does not perform the TLS handshake itself, but
- simply stores these arguments for later. The handshake is
- performed only when this class needs to connect with the
- server. Thus you should be prepared to handle TLS-specific
- exceptions when calling methods of L{xmlrpclib.ServerProxy}. See the
- client handshake functions in
- L{tlslite.TLSConnection.TLSConnection} for details on which
- exceptions might be raised.
-
- @type username: str
- @param username: SRP or shared-key username. Requires the
- 'password' or 'sharedKey' argument.
-
- @type password: str
- @param password: SRP password for mutual authentication.
- Requires the 'username' argument.
-
- @type sharedKey: str
- @param sharedKey: Shared key for mutual authentication.
- Requires the 'username' argument.
-
- @type certChain: L{tlslite.X509CertChain.X509CertChain} or
- L{cryptoIDlib.CertChain.CertChain}
- @param certChain: Certificate chain for client authentication.
- Requires the 'privateKey' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type privateKey: L{tlslite.utils.RSAKey.RSAKey}
- @param privateKey: Private key for client authentication.
- Requires the 'certChain' argument. Excludes the SRP or
- shared-key related arguments.
-
- @type cryptoID: str
- @param cryptoID: cryptoID for server authentication. Mutually
- exclusive with the 'x509...' arguments.
-
- @type protocol: str
- @param protocol: cryptoID protocol URI for server
- authentication. Requires the 'cryptoID' argument.
-
- @type x509Fingerprint: str
- @param x509Fingerprint: Hex-encoded X.509 fingerprint for
- server authentication. Mutually exclusive with the 'cryptoID'
- and 'x509TrustList' arguments.
-
- @type x509TrustList: list of L{tlslite.X509.X509}
- @param x509TrustList: A list of trusted root certificates. The
- other party must present a certificate chain which extends to
- one of these root certificates. The cryptlib_py module must be
- installed to use this parameter. Mutually exclusive with the
- 'cryptoID' and 'x509Fingerprint' arguments.
-
- @type x509CommonName: str
- @param x509CommonName: The end-entity certificate's 'CN' field
- must match this value. For a web server, this is typically a
- server name such as 'www.amazon.com'. Mutually exclusive with
- the 'cryptoID' and 'x509Fingerprint' arguments. Requires the
- 'x509TrustList' argument.
-
- @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
- @param settings: Various settings which can be used to control
- the ciphersuites, certificate types, and SSL/TLS versions
- offered by the client.
- """
-
- ClientHelper.__init__(self,
- username, password, sharedKey,
- certChain, privateKey,
- cryptoID, protocol,
- x509Fingerprint,
- x509TrustList, x509CommonName,
- settings)
- self._use_datetime = 0
-
- def make_connection(self, host):
- # create a HTTPS connection object from a host descriptor
- host, extra_headers, x509 = self.get_host_info(host)
- http = HTTPTLSConnection(host, None,
- self.username, self.password,
- self.sharedKey,
- self.certChain, self.privateKey,
- self.checker.cryptoID,
- self.checker.protocol,
- self.checker.x509Fingerprint,
- self.checker.x509TrustList,
- self.checker.x509CommonName,
- self.settings)
- http2 = httplib.HTTP()
- http2._setup(http)
- return http2
diff --git a/src/lib/tlslite/integration/__init__.py b/src/lib/tlslite/integration/__init__.py
deleted file mode 100755
index 960f4065f..000000000
--- a/src/lib/tlslite/integration/__init__.py
+++ /dev/null
@@ -1,17 +0,0 @@
-"""Classes for integrating TLS Lite with other packages."""
-
-__all__ = ["AsyncStateMachine",
- "HTTPTLSConnection",
- "POP3_TLS",
- "IMAP4_TLS",
- "SMTP_TLS",
- "XMLRPCTransport",
- "TLSSocketServerMixIn",
- "TLSAsyncDispatcherMixIn",
- "TLSTwistedProtocolWrapper"]
-
-try:
- import twisted
- del twisted
-except ImportError:
- del __all__[__all__.index("TLSTwistedProtocolWrapper")]
diff --git a/src/lib/tlslite/mathtls.py b/src/lib/tlslite/mathtls.py
deleted file mode 100755
index 3b8ede601..000000000
--- a/src/lib/tlslite/mathtls.py
+++ /dev/null
@@ -1,170 +0,0 @@
-"""Miscellaneous helper functions."""
-
-from utils.compat import *
-from utils.cryptomath import *
-
-import hmac
-import md5
-import sha
-
-#1024, 1536, 2048, 3072, 4096, 6144, and 8192 bit groups]
-goodGroupParameters = [(2,0xEEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3),\
- (2,0x9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA9614B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F84380B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0BE3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF56EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734AF7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB),\
- (2,0xAC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73),\
- (2,0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF),\
- (5,0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF),\
- (5,0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF),\
- (5,0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF)]
-
-def P_hash(hashModule, secret, seed, length):
- bytes = createByteArrayZeros(length)
- secret = bytesToString(secret)
- seed = bytesToString(seed)
- A = seed
- index = 0
- while 1:
- A = hmac.HMAC(secret, A, hashModule).digest()
- output = hmac.HMAC(secret, A+seed, hashModule).digest()
- for c in output:
- if index >= length:
- return bytes
- bytes[index] = ord(c)
- index += 1
- return bytes
-
-def PRF(secret, label, seed, length):
- #Split the secret into left and right halves
- S1 = secret[ : int(math.ceil(len(secret)/2.0))]
- S2 = secret[ int(math.floor(len(secret)/2.0)) : ]
-
- #Run the left half through P_MD5 and the right half through P_SHA1
- p_md5 = P_hash(md5, S1, concatArrays(stringToBytes(label), seed), length)
- p_sha1 = P_hash(sha, S2, concatArrays(stringToBytes(label), seed), length)
-
- #XOR the output values and return the result
- for x in range(length):
- p_md5[x] ^= p_sha1[x]
- return p_md5
-
-
-def PRF_SSL(secret, seed, length):
- secretStr = bytesToString(secret)
- seedStr = bytesToString(seed)
- bytes = createByteArrayZeros(length)
- index = 0
- for x in range(26):
- A = chr(ord('A')+x) * (x+1) # 'A', 'BB', 'CCC', etc..
- input = secretStr + sha.sha(A + secretStr + seedStr).digest()
- output = md5.md5(input).digest()
- for c in output:
- if index >= length:
- return bytes
- bytes[index] = ord(c)
- index += 1
- return bytes
-
-def makeX(salt, username, password):
- if len(username)>=256:
- raise ValueError("username too long")
- if len(salt)>=256:
- raise ValueError("salt too long")
- return stringToNumber(sha.sha(salt + sha.sha(username + ":" + password)\
- .digest()).digest())
-
-#This function is used by VerifierDB.makeVerifier
-def makeVerifier(username, password, bits):
- bitsIndex = {1024:0, 1536:1, 2048:2, 3072:3, 4096:4, 6144:5, 8192:6}[bits]
- g,N = goodGroupParameters[bitsIndex]
- salt = bytesToString(getRandomBytes(16))
- x = makeX(salt, username, password)
- verifier = powMod(g, x, N)
- return N, g, salt, verifier
-
-def PAD(n, x):
- nLength = len(numberToString(n))
- s = numberToString(x)
- if len(s) < nLength:
- s = ("\0" * (nLength-len(s))) + s
- return s
-
-def makeU(N, A, B):
- return stringToNumber(sha.sha(PAD(N, A) + PAD(N, B)).digest())
-
-def makeK(N, g):
- return stringToNumber(sha.sha(numberToString(N) + PAD(N, g)).digest())
-
-
-"""
-MAC_SSL
-Modified from Python HMAC by Trevor
-"""
-
-class MAC_SSL:
- """MAC_SSL class.
-
- This supports the API for Cryptographic Hash Functions (PEP 247).
- """
-
- def __init__(self, key, msg = None, digestmod = None):
- """Create a new MAC_SSL object.
-
- key: key for the keyed hash object.
- msg: Initial input for the hash, if provided.
- digestmod: A module supporting PEP 247. Defaults to the md5 module.
- """
- if digestmod is None:
- import md5
- digestmod = md5
-
- if key == None: #TREVNEW - for faster copying
- return #TREVNEW
-
- self.digestmod = digestmod
- self.outer = digestmod.new()
- self.inner = digestmod.new()
- self.digest_size = digestmod.digest_size
-
- ipad = "\x36" * 40
- opad = "\x5C" * 40
-
- self.inner.update(key)
- self.inner.update(ipad)
- self.outer.update(key)
- self.outer.update(opad)
- if msg is not None:
- self.update(msg)
-
-
- def update(self, msg):
- """Update this hashing object with the string msg.
- """
- self.inner.update(msg)
-
- def copy(self):
- """Return a separate copy of this hashing object.
-
- An update to this copy won't affect the original object.
- """
- other = MAC_SSL(None) #TREVNEW - for faster copying
- other.digest_size = self.digest_size #TREVNEW
- other.digestmod = self.digestmod
- other.inner = self.inner.copy()
- other.outer = self.outer.copy()
- return other
-
- def digest(self):
- """Return the hash value of this hashing object.
-
- This returns a string containing 8-bit data. The object is
- not altered in any way by this function; you can continue
- updating the object after calling this function.
- """
- h = self.outer.copy()
- h.update(self.inner.digest())
- return h.digest()
-
- def hexdigest(self):
- """Like digest(), but returns a string of hexadecimal digits instead.
- """
- return "".join([hex(ord(x))[2:].zfill(2)
- for x in tuple(self.digest())])
diff --git a/src/lib/tlslite/messages.py b/src/lib/tlslite/messages.py
deleted file mode 100755
index afccc793a..000000000
--- a/src/lib/tlslite/messages.py
+++ /dev/null
@@ -1,561 +0,0 @@
-"""Classes representing TLS messages."""
-
-from utils.compat import *
-from utils.cryptomath import *
-from errors import *
-from utils.codec import *
-from constants import *
-from X509 import X509
-from X509CertChain import X509CertChain
-
-import sha
-import md5
-
-class RecordHeader3:
- def __init__(self):
- self.type = 0
- self.version = (0,0)
- self.length = 0
- self.ssl2 = False
-
- def create(self, version, type, length):
- self.type = type
- self.version = version
- self.length = length
- return self
-
- def write(self):
- w = Writer(5)
- w.add(self.type, 1)
- w.add(self.version[0], 1)
- w.add(self.version[1], 1)
- w.add(self.length, 2)
- return w.bytes
-
- def parse(self, p):
- self.type = p.get(1)
- self.version = (p.get(1), p.get(1))
- self.length = p.get(2)
- self.ssl2 = False
- return self
-
-class RecordHeader2:
- def __init__(self):
- self.type = 0
- self.version = (0,0)
- self.length = 0
- self.ssl2 = True
-
- def parse(self, p):
- if p.get(1)!=128:
- raise SyntaxError()
- self.type = ContentType.handshake
- self.version = (2,0)
- #We don't support 2-byte-length-headers; could be a problem
- self.length = p.get(1)
- return self
-
-
-class Msg:
- def preWrite(self, trial):
- if trial:
- w = Writer()
- else:
- length = self.write(True)
- w = Writer(length)
- return w
-
- def postWrite(self, w, trial):
- if trial:
- return w.index
- else:
- return w.bytes
-
-class Alert(Msg):
- def __init__(self):
- self.contentType = ContentType.alert
- self.level = 0
- self.description = 0
-
- def create(self, description, level=AlertLevel.fatal):
- self.level = level
- self.description = description
- return self
-
- def parse(self, p):
- p.setLengthCheck(2)
- self.level = p.get(1)
- self.description = p.get(1)
- p.stopLengthCheck()
- return self
-
- def write(self):
- w = Writer(2)
- w.add(self.level, 1)
- w.add(self.description, 1)
- return w.bytes
-
-
-class HandshakeMsg(Msg):
- def preWrite(self, handshakeType, trial):
- if trial:
- w = Writer()
- w.add(handshakeType, 1)
- w.add(0, 3)
- else:
- length = self.write(True)
- w = Writer(length)
- w.add(handshakeType, 1)
- w.add(length-4, 3)
- return w
-
-
-class ClientHello(HandshakeMsg):
- def __init__(self, ssl2=False):
- self.contentType = ContentType.handshake
- self.ssl2 = ssl2
- self.client_version = (0,0)
- self.random = createByteArrayZeros(32)
- self.session_id = createByteArraySequence([])
- self.cipher_suites = [] # a list of 16-bit values
- self.certificate_types = [CertificateType.x509]
- self.compression_methods = [] # a list of 8-bit values
- self.srp_username = None # a string
-
- def create(self, version, random, session_id, cipher_suites,
- certificate_types=None, srp_username=None):
- self.client_version = version
- self.random = random
- self.session_id = session_id
- self.cipher_suites = cipher_suites
- self.certificate_types = certificate_types
- self.compression_methods = [0]
- self.srp_username = srp_username
- return self
-
- def parse(self, p):
- if self.ssl2:
- self.client_version = (p.get(1), p.get(1))
- cipherSpecsLength = p.get(2)
- sessionIDLength = p.get(2)
- randomLength = p.get(2)
- self.cipher_suites = p.getFixList(3, int(cipherSpecsLength/3))
- self.session_id = p.getFixBytes(sessionIDLength)
- self.random = p.getFixBytes(randomLength)
- if len(self.random) < 32:
- zeroBytes = 32-len(self.random)
- self.random = createByteArrayZeros(zeroBytes) + self.random
- self.compression_methods = [0]#Fake this value
-
- #We're not doing a stopLengthCheck() for SSLv2, oh well..
- else:
- p.startLengthCheck(3)
- self.client_version = (p.get(1), p.get(1))
- self.random = p.getFixBytes(32)
- self.session_id = p.getVarBytes(1)
- self.cipher_suites = p.getVarList(2, 2)
- self.compression_methods = p.getVarList(1, 1)
- if not p.atLengthCheck():
- totalExtLength = p.get(2)
- soFar = 0
- while soFar != totalExtLength:
- extType = p.get(2)
- extLength = p.get(2)
- if extType == 6:
- self.srp_username = bytesToString(p.getVarBytes(1))
- elif extType == 7:
- self.certificate_types = p.getVarList(1, 1)
- else:
- p.getFixBytes(extLength)
- soFar += 4 + extLength
- p.stopLengthCheck()
- return self
-
- def write(self, trial=False):
- w = HandshakeMsg.preWrite(self, HandshakeType.client_hello, trial)
- w.add(self.client_version[0], 1)
- w.add(self.client_version[1], 1)
- w.addFixSeq(self.random, 1)
- w.addVarSeq(self.session_id, 1, 1)
- w.addVarSeq(self.cipher_suites, 2, 2)
- w.addVarSeq(self.compression_methods, 1, 1)
-
- extLength = 0
- if self.certificate_types and self.certificate_types != \
- [CertificateType.x509]:
- extLength += 5 + len(self.certificate_types)
- if self.srp_username:
- extLength += 5 + len(self.srp_username)
- if extLength > 0:
- w.add(extLength, 2)
-
- if self.certificate_types and self.certificate_types != \
- [CertificateType.x509]:
- w.add(7, 2)
- w.add(len(self.certificate_types)+1, 2)
- w.addVarSeq(self.certificate_types, 1, 1)
- if self.srp_username:
- w.add(6, 2)
- w.add(len(self.srp_username)+1, 2)
- w.addVarSeq(stringToBytes(self.srp_username), 1, 1)
-
- return HandshakeMsg.postWrite(self, w, trial)
-
-
-class ServerHello(HandshakeMsg):
- def __init__(self):
- self.contentType = ContentType.handshake
- self.server_version = (0,0)
- self.random = createByteArrayZeros(32)
- self.session_id = createByteArraySequence([])
- self.cipher_suite = 0
- self.certificate_type = CertificateType.x509
- self.compression_method = 0
-
- def create(self, version, random, session_id, cipher_suite,
- certificate_type):
- self.server_version = version
- self.random = random
- self.session_id = session_id
- self.cipher_suite = cipher_suite
- self.certificate_type = certificate_type
- self.compression_method = 0
- return self
-
- def parse(self, p):
- p.startLengthCheck(3)
- self.server_version = (p.get(1), p.get(1))
- self.random = p.getFixBytes(32)
- self.session_id = p.getVarBytes(1)
- self.cipher_suite = p.get(2)
- self.compression_method = p.get(1)
- if not p.atLengthCheck():
- totalExtLength = p.get(2)
- soFar = 0
- while soFar != totalExtLength:
- extType = p.get(2)
- extLength = p.get(2)
- if extType == 7:
- self.certificate_type = p.get(1)
- else:
- p.getFixBytes(extLength)
- soFar += 4 + extLength
- p.stopLengthCheck()
- return self
-
- def write(self, trial=False):
- w = HandshakeMsg.preWrite(self, HandshakeType.server_hello, trial)
- w.add(self.server_version[0], 1)
- w.add(self.server_version[1], 1)
- w.addFixSeq(self.random, 1)
- w.addVarSeq(self.session_id, 1, 1)
- w.add(self.cipher_suite, 2)
- w.add(self.compression_method, 1)
-
- extLength = 0
- if self.certificate_type and self.certificate_type != \
- CertificateType.x509:
- extLength += 5
-
- if extLength != 0:
- w.add(extLength, 2)
-
- if self.certificate_type and self.certificate_type != \
- CertificateType.x509:
- w.add(7, 2)
- w.add(1, 2)
- w.add(self.certificate_type, 1)
-
- return HandshakeMsg.postWrite(self, w, trial)
-
-class Certificate(HandshakeMsg):
- def __init__(self, certificateType):
- self.certificateType = certificateType
- self.contentType = ContentType.handshake
- self.certChain = None
-
- def create(self, certChain):
- self.certChain = certChain
- return self
-
- def parse(self, p):
- p.startLengthCheck(3)
- if self.certificateType == CertificateType.x509:
- chainLength = p.get(3)
- index = 0
- certificate_list = []
- while index != chainLength:
- certBytes = p.getVarBytes(3)
- x509 = X509()
- x509.parseBinary(certBytes)
- certificate_list.append(x509)
- index += len(certBytes)+3
- if certificate_list:
- self.certChain = X509CertChain(certificate_list)
- elif self.certificateType == CertificateType.cryptoID:
- s = bytesToString(p.getVarBytes(2))
- if s:
- try:
- import cryptoIDlib.CertChain
- except ImportError:
- raise SyntaxError(\
- "cryptoID cert chain received, cryptoIDlib not present")
- self.certChain = cryptoIDlib.CertChain.CertChain().parse(s)
- else:
- raise AssertionError()
-
- p.stopLengthCheck()
- return self
-
- def write(self, trial=False):
- w = HandshakeMsg.preWrite(self, HandshakeType.certificate, trial)
- if self.certificateType == CertificateType.x509:
- chainLength = 0
- if self.certChain:
- certificate_list = self.certChain.x509List
- else:
- certificate_list = []
- #determine length
- for cert in certificate_list:
- bytes = cert.writeBytes()
- chainLength += len(bytes)+3
- #add bytes
- w.add(chainLength, 3)
- for cert in certificate_list:
- bytes = cert.writeBytes()
- w.addVarSeq(bytes, 1, 3)
- elif self.certificateType == CertificateType.cryptoID:
- if self.certChain:
- bytes = stringToBytes(self.certChain.write())
- else:
- bytes = createByteArraySequence([])
- w.addVarSeq(bytes, 1, 2)
- else:
- raise AssertionError()
- return HandshakeMsg.postWrite(self, w, trial)
-
-class CertificateRequest(HandshakeMsg):
- def __init__(self):
- self.contentType = ContentType.handshake
- self.certificate_types = []
- #treat as opaque bytes for now
- self.certificate_authorities = createByteArraySequence([])
-
- def create(self, certificate_types, certificate_authorities):
- self.certificate_types = certificate_types
- self.certificate_authorities = certificate_authorities
- return self
-
- def parse(self, p):
- p.startLengthCheck(3)
- self.certificate_types = p.getVarList(1, 1)
- self.certificate_authorities = p.getVarBytes(2)
- p.stopLengthCheck()
- return self
-
- def write(self, trial=False):
- w = HandshakeMsg.preWrite(self, HandshakeType.certificate_request,
- trial)
- w.addVarSeq(self.certificate_types, 1, 1)
- w.addVarSeq(self.certificate_authorities, 1, 2)
- return HandshakeMsg.postWrite(self, w, trial)
-
-class ServerKeyExchange(HandshakeMsg):
- def __init__(self, cipherSuite):
- self.cipherSuite = cipherSuite
- self.contentType = ContentType.handshake
- self.srp_N = 0L
- self.srp_g = 0L
- self.srp_s = createByteArraySequence([])
- self.srp_B = 0L
- self.signature = createByteArraySequence([])
-
- def createSRP(self, srp_N, srp_g, srp_s, srp_B):
- self.srp_N = srp_N
- self.srp_g = srp_g
- self.srp_s = srp_s
- self.srp_B = srp_B
- return self
-
- def parse(self, p):
- p.startLengthCheck(3)
- self.srp_N = bytesToNumber(p.getVarBytes(2))
- self.srp_g = bytesToNumber(p.getVarBytes(2))
- self.srp_s = p.getVarBytes(1)
- self.srp_B = bytesToNumber(p.getVarBytes(2))
- if self.cipherSuite in CipherSuite.srpRsaSuites:
- self.signature = p.getVarBytes(2)
- p.stopLengthCheck()
- return self
-
- def write(self, trial=False):
- w = HandshakeMsg.preWrite(self, HandshakeType.server_key_exchange,
- trial)
- w.addVarSeq(numberToBytes(self.srp_N), 1, 2)
- w.addVarSeq(numberToBytes(self.srp_g), 1, 2)
- w.addVarSeq(self.srp_s, 1, 1)
- w.addVarSeq(numberToBytes(self.srp_B), 1, 2)
- if self.cipherSuite in CipherSuite.srpRsaSuites:
- w.addVarSeq(self.signature, 1, 2)
- return HandshakeMsg.postWrite(self, w, trial)
-
- def hash(self, clientRandom, serverRandom):
- oldCipherSuite = self.cipherSuite
- self.cipherSuite = None
- try:
- bytes = clientRandom + serverRandom + self.write()[4:]
- s = bytesToString(bytes)
- return stringToBytes(md5.md5(s).digest() + sha.sha(s).digest())
- finally:
- self.cipherSuite = oldCipherSuite
-
-class ServerHelloDone(HandshakeMsg):
- def __init__(self):
- self.contentType = ContentType.handshake
-
- def create(self):
- return self
-
- def parse(self, p):
- p.startLengthCheck(3)
- p.stopLengthCheck()
- return self
-
- def write(self, trial=False):
- w = HandshakeMsg.preWrite(self, HandshakeType.server_hello_done, trial)
- return HandshakeMsg.postWrite(self, w, trial)
-
-class ClientKeyExchange(HandshakeMsg):
- def __init__(self, cipherSuite, version=None):
- self.cipherSuite = cipherSuite
- self.version = version
- self.contentType = ContentType.handshake
- self.srp_A = 0
- self.encryptedPreMasterSecret = createByteArraySequence([])
-
- def createSRP(self, srp_A):
- self.srp_A = srp_A
- return self
-
- def createRSA(self, encryptedPreMasterSecret):
- self.encryptedPreMasterSecret = encryptedPreMasterSecret
- return self
-
- def parse(self, p):
- p.startLengthCheck(3)
- if self.cipherSuite in CipherSuite.srpSuites + \
- CipherSuite.srpRsaSuites:
- self.srp_A = bytesToNumber(p.getVarBytes(2))
- elif self.cipherSuite in CipherSuite.rsaSuites:
- if self.version in ((3,1), (3,2)):
- self.encryptedPreMasterSecret = p.getVarBytes(2)
- elif self.version == (3,0):
- self.encryptedPreMasterSecret = \
- p.getFixBytes(len(p.bytes)-p.index)
- else:
- raise AssertionError()
- else:
- raise AssertionError()
- p.stopLengthCheck()
- return self
-
- def write(self, trial=False):
- w = HandshakeMsg.preWrite(self, HandshakeType.client_key_exchange,
- trial)
- if self.cipherSuite in CipherSuite.srpSuites + \
- CipherSuite.srpRsaSuites:
- w.addVarSeq(numberToBytes(self.srp_A), 1, 2)
- elif self.cipherSuite in CipherSuite.rsaSuites:
- if self.version in ((3,1), (3,2)):
- w.addVarSeq(self.encryptedPreMasterSecret, 1, 2)
- elif self.version == (3,0):
- w.addFixSeq(self.encryptedPreMasterSecret, 1)
- else:
- raise AssertionError()
- else:
- raise AssertionError()
- return HandshakeMsg.postWrite(self, w, trial)
-
-class CertificateVerify(HandshakeMsg):
- def __init__(self):
- self.contentType = ContentType.handshake
- self.signature = createByteArraySequence([])
-
- def create(self, signature):
- self.signature = signature
- return self
-
- def parse(self, p):
- p.startLengthCheck(3)
- self.signature = p.getVarBytes(2)
- p.stopLengthCheck()
- return self
-
- def write(self, trial=False):
- w = HandshakeMsg.preWrite(self, HandshakeType.certificate_verify,
- trial)
- w.addVarSeq(self.signature, 1, 2)
- return HandshakeMsg.postWrite(self, w, trial)
-
-class ChangeCipherSpec(Msg):
- def __init__(self):
- self.contentType = ContentType.change_cipher_spec
- self.type = 1
-
- def create(self):
- self.type = 1
- return self
-
- def parse(self, p):
- p.setLengthCheck(1)
- self.type = p.get(1)
- p.stopLengthCheck()
- return self
-
- def write(self, trial=False):
- w = Msg.preWrite(self, trial)
- w.add(self.type,1)
- return Msg.postWrite(self, w, trial)
-
-
-class Finished(HandshakeMsg):
- def __init__(self, version):
- self.contentType = ContentType.handshake
- self.version = version
- self.verify_data = createByteArraySequence([])
-
- def create(self, verify_data):
- self.verify_data = verify_data
- return self
-
- def parse(self, p):
- p.startLengthCheck(3)
- if self.version == (3,0):
- self.verify_data = p.getFixBytes(36)
- elif self.version in ((3,1), (3,2)):
- self.verify_data = p.getFixBytes(12)
- else:
- raise AssertionError()
- p.stopLengthCheck()
- return self
-
- def write(self, trial=False):
- w = HandshakeMsg.preWrite(self, HandshakeType.finished, trial)
- w.addFixSeq(self.verify_data, 1)
- return HandshakeMsg.postWrite(self, w, trial)
-
-class ApplicationData(Msg):
- def __init__(self):
- self.contentType = ContentType.application_data
- self.bytes = createByteArraySequence([])
-
- def create(self, bytes):
- self.bytes = bytes
- return self
-
- def parse(self, p):
- self.bytes = p.bytes
- return self
-
- def write(self):
- return self.bytes \ No newline at end of file
diff --git a/src/lib/tlslite/utils/AES.py b/src/lib/tlslite/utils/AES.py
deleted file mode 100755
index 8413f4c10..000000000
--- a/src/lib/tlslite/utils/AES.py
+++ /dev/null
@@ -1,31 +0,0 @@
-"""Abstract class for AES."""
-
-class AES:
- def __init__(self, key, mode, IV, implementation):
- if len(key) not in (16, 24, 32):
- raise AssertionError()
- if mode != 2:
- raise AssertionError()
- if len(IV) != 16:
- raise AssertionError()
- self.isBlockCipher = True
- self.block_size = 16
- self.implementation = implementation
- if len(key)==16:
- self.name = "aes128"
- elif len(key)==24:
- self.name = "aes192"
- elif len(key)==32:
- self.name = "aes256"
- else:
- raise AssertionError()
-
- #CBC-Mode encryption, returns ciphertext
- #WARNING: *MAY* modify the input as well
- def encrypt(self, plaintext):
- assert(len(plaintext) % 16 == 0)
-
- #CBC-Mode decryption, returns plaintext
- #WARNING: *MAY* modify the input as well
- def decrypt(self, ciphertext):
- assert(len(ciphertext) % 16 == 0) \ No newline at end of file
diff --git a/src/lib/tlslite/utils/ASN1Parser.py b/src/lib/tlslite/utils/ASN1Parser.py
deleted file mode 100755
index 16b50f29c..000000000
--- a/src/lib/tlslite/utils/ASN1Parser.py
+++ /dev/null
@@ -1,34 +0,0 @@
-"""Class for parsing ASN.1"""
-from compat import *
-from codec import *
-
-#Takes a byte array which has a DER TLV field at its head
-class ASN1Parser:
- def __init__(self, bytes):
- p = Parser(bytes)
- p.get(1) #skip Type
-
- #Get Length
- self.length = self._getASN1Length(p)
-
- #Get Value
- self.value = p.getFixBytes(self.length)
-
- #Assuming this is a sequence...
- def getChild(self, which):
- p = Parser(self.value)
- for x in range(which+1):
- markIndex = p.index
- p.get(1) #skip Type
- length = self._getASN1Length(p)
- p.getFixBytes(length)
- return ASN1Parser(p.bytes[markIndex : p.index])
-
- #Decode the ASN.1 DER length field
- def _getASN1Length(self, p):
- firstLength = p.get(1)
- if firstLength<=127:
- return firstLength
- else:
- lengthLength = firstLength & 0x7F
- return p.get(lengthLength)
diff --git a/src/lib/tlslite/utils/Cryptlib_AES.py b/src/lib/tlslite/utils/Cryptlib_AES.py
deleted file mode 100755
index 9e101fc62..000000000
--- a/src/lib/tlslite/utils/Cryptlib_AES.py
+++ /dev/null
@@ -1,34 +0,0 @@
-"""Cryptlib AES implementation."""
-
-from cryptomath import *
-from AES import *
-
-if cryptlibpyLoaded:
-
- def new(key, mode, IV):
- return Cryptlib_AES(key, mode, IV)
-
- class Cryptlib_AES(AES):
-
- def __init__(self, key, mode, IV):
- AES.__init__(self, key, mode, IV, "cryptlib")
- self.context = cryptlib_py.cryptCreateContext(cryptlib_py.CRYPT_UNUSED, cryptlib_py.CRYPT_ALGO_AES)
- cryptlib_py.cryptSetAttribute(self.context, cryptlib_py.CRYPT_CTXINFO_MODE, cryptlib_py.CRYPT_MODE_CBC)
- cryptlib_py.cryptSetAttribute(self.context, cryptlib_py.CRYPT_CTXINFO_KEYSIZE, len(key))
- cryptlib_py.cryptSetAttributeString(self.context, cryptlib_py.CRYPT_CTXINFO_KEY, key)
- cryptlib_py.cryptSetAttributeString(self.context, cryptlib_py.CRYPT_CTXINFO_IV, IV)
-
- def __del__(self):
- cryptlib_py.cryptDestroyContext(self.context)
-
- def encrypt(self, plaintext):
- AES.encrypt(self, plaintext)
- bytes = stringToBytes(plaintext)
- cryptlib_py.cryptEncrypt(self.context, bytes)
- return bytesToString(bytes)
-
- def decrypt(self, ciphertext):
- AES.decrypt(self, ciphertext)
- bytes = stringToBytes(ciphertext)
- cryptlib_py.cryptDecrypt(self.context, bytes)
- return bytesToString(bytes)
diff --git a/src/lib/tlslite/utils/Cryptlib_RC4.py b/src/lib/tlslite/utils/Cryptlib_RC4.py
deleted file mode 100755
index 7c6d087b8..000000000
--- a/src/lib/tlslite/utils/Cryptlib_RC4.py
+++ /dev/null
@@ -1,28 +0,0 @@
-"""Cryptlib RC4 implementation."""
-
-from cryptomath import *
-from RC4 import RC4
-
-if cryptlibpyLoaded:
-
- def new(key):
- return Cryptlib_RC4(key)
-
- class Cryptlib_RC4(RC4):
-
- def __init__(self, key):
- RC4.__init__(self, key, "cryptlib")
- self.context = cryptlib_py.cryptCreateContext(cryptlib_py.CRYPT_UNUSED, cryptlib_py.CRYPT_ALGO_RC4)
- cryptlib_py.cryptSetAttribute(self.context, cryptlib_py.CRYPT_CTXINFO_KEYSIZE, len(key))
- cryptlib_py.cryptSetAttributeString(self.context, cryptlib_py.CRYPT_CTXINFO_KEY, key)
-
- def __del__(self):
- cryptlib_py.cryptDestroyContext(self.context)
-
- def encrypt(self, plaintext):
- bytes = stringToBytes(plaintext)
- cryptlib_py.cryptEncrypt(self.context, bytes)
- return bytesToString(bytes)
-
- def decrypt(self, ciphertext):
- return self.encrypt(ciphertext) \ No newline at end of file
diff --git a/src/lib/tlslite/utils/Cryptlib_TripleDES.py b/src/lib/tlslite/utils/Cryptlib_TripleDES.py
deleted file mode 100755
index a4f8155a0..000000000
--- a/src/lib/tlslite/utils/Cryptlib_TripleDES.py
+++ /dev/null
@@ -1,35 +0,0 @@
-"""Cryptlib 3DES implementation."""
-
-from cryptomath import *
-
-from TripleDES import *
-
-if cryptlibpyLoaded:
-
- def new(key, mode, IV):
- return Cryptlib_TripleDES(key, mode, IV)
-
- class Cryptlib_TripleDES(TripleDES):
-
- def __init__(self, key, mode, IV):
- TripleDES.__init__(self, key, mode, IV, "cryptlib")
- self.context = cryptlib_py.cryptCreateContext(cryptlib_py.CRYPT_UNUSED, cryptlib_py.CRYPT_ALGO_3DES)
- cryptlib_py.cryptSetAttribute(self.context, cryptlib_py.CRYPT_CTXINFO_MODE, cryptlib_py.CRYPT_MODE_CBC)
- cryptlib_py.cryptSetAttribute(self.context, cryptlib_py.CRYPT_CTXINFO_KEYSIZE, len(key))
- cryptlib_py.cryptSetAttributeString(self.context, cryptlib_py.CRYPT_CTXINFO_KEY, key)
- cryptlib_py.cryptSetAttributeString(self.context, cryptlib_py.CRYPT_CTXINFO_IV, IV)
-
- def __del__(self):
- cryptlib_py.cryptDestroyContext(self.context)
-
- def encrypt(self, plaintext):
- TripleDES.encrypt(self, plaintext)
- bytes = stringToBytes(plaintext)
- cryptlib_py.cryptEncrypt(self.context, bytes)
- return bytesToString(bytes)
-
- def decrypt(self, ciphertext):
- TripleDES.decrypt(self, ciphertext)
- bytes = stringToBytes(ciphertext)
- cryptlib_py.cryptDecrypt(self.context, bytes)
- return bytesToString(bytes) \ No newline at end of file
diff --git a/src/lib/tlslite/utils/OpenSSL_AES.py b/src/lib/tlslite/utils/OpenSSL_AES.py
deleted file mode 100755
index e60679bf5..000000000
--- a/src/lib/tlslite/utils/OpenSSL_AES.py
+++ /dev/null
@@ -1,49 +0,0 @@
-"""OpenSSL/M2Crypto AES implementation."""
-
-from cryptomath import *
-from AES import *
-
-if m2cryptoLoaded:
-
- def new(key, mode, IV):
- return OpenSSL_AES(key, mode, IV)
-
- class OpenSSL_AES(AES):
-
- def __init__(self, key, mode, IV):
- AES.__init__(self, key, mode, IV, "openssl")
- self.key = key
- self.IV = IV
-
- def _createContext(self, encrypt):
- context = m2.cipher_ctx_new()
- if len(self.key)==16:
- cipherType = m2.aes_128_cbc()
- if len(self.key)==24:
- cipherType = m2.aes_192_cbc()
- if len(self.key)==32:
- cipherType = m2.aes_256_cbc()
- m2.cipher_init(context, cipherType, self.key, self.IV, encrypt)
- return context
-
- def encrypt(self, plaintext):
- AES.encrypt(self, plaintext)
- context = self._createContext(1)
- ciphertext = m2.cipher_update(context, plaintext)
- m2.cipher_ctx_free(context)
- self.IV = ciphertext[-self.block_size:]
- return ciphertext
-
- def decrypt(self, ciphertext):
- AES.decrypt(self, ciphertext)
- context = self._createContext(0)
- #I think M2Crypto has a bug - it fails to decrypt and return the last block passed in.
- #To work around this, we append sixteen zeros to the string, below:
- plaintext = m2.cipher_update(context, ciphertext+('\0'*16))
-
- #If this bug is ever fixed, then plaintext will end up having a garbage
- #plaintext block on the end. That's okay - the below code will discard it.
- plaintext = plaintext[:len(ciphertext)]
- m2.cipher_ctx_free(context)
- self.IV = ciphertext[-self.block_size:]
- return plaintext
diff --git a/src/lib/tlslite/utils/OpenSSL_RC4.py b/src/lib/tlslite/utils/OpenSSL_RC4.py
deleted file mode 100755
index ac433aad7..000000000
--- a/src/lib/tlslite/utils/OpenSSL_RC4.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""OpenSSL/M2Crypto RC4 implementation."""
-
-from cryptomath import *
-from RC4 import RC4
-
-if m2cryptoLoaded:
-
- def new(key):
- return OpenSSL_RC4(key)
-
- class OpenSSL_RC4(RC4):
-
- def __init__(self, key):
- RC4.__init__(self, key, "openssl")
- self.rc4 = m2.rc4_new()
- m2.rc4_set_key(self.rc4, key)
-
- def __del__(self):
- m2.rc4_free(self.rc4)
-
- def encrypt(self, plaintext):
- return m2.rc4_update(self.rc4, plaintext)
-
- def decrypt(self, ciphertext):
- return self.encrypt(ciphertext)
diff --git a/src/lib/tlslite/utils/OpenSSL_RSAKey.py b/src/lib/tlslite/utils/OpenSSL_RSAKey.py
deleted file mode 100755
index fe1a3cd74..000000000
--- a/src/lib/tlslite/utils/OpenSSL_RSAKey.py
+++ /dev/null
@@ -1,148 +0,0 @@
-"""OpenSSL/M2Crypto RSA implementation."""
-
-from cryptomath import *
-
-from RSAKey import *
-from Python_RSAKey import Python_RSAKey
-
-#copied from M2Crypto.util.py, so when we load the local copy of m2
-#we can still use it
-def password_callback(v, prompt1='Enter private key passphrase:',
- prompt2='Verify passphrase:'):
- from getpass import getpass
- while 1:
- try:
- p1=getpass(prompt1)
- if v:
- p2=getpass(prompt2)
- if p1==p2:
- break
- else:
- break
- except KeyboardInterrupt:
- return None
- return p1
-
-
-if m2cryptoLoaded:
- class OpenSSL_RSAKey(RSAKey):
- def __init__(self, n=0, e=0):
- self.rsa = None
- self._hasPrivateKey = False
- if (n and not e) or (e and not n):
- raise AssertionError()
- if n and e:
- self.rsa = m2.rsa_new()
- m2.rsa_set_n(self.rsa, numberToMPI(n))
- m2.rsa_set_e(self.rsa, numberToMPI(e))
-
- def __del__(self):
- if self.rsa:
- m2.rsa_free(self.rsa)
-
- def __getattr__(self, name):
- if name == 'e':
- if not self.rsa:
- return 0
- return mpiToNumber(m2.rsa_get_e(self.rsa))
- elif name == 'n':
- if not self.rsa:
- return 0
- return mpiToNumber(m2.rsa_get_n(self.rsa))
- else:
- raise AttributeError
-
- def hasPrivateKey(self):
- return self._hasPrivateKey
-
- def hash(self):
- return Python_RSAKey(self.n, self.e).hash()
-
- def _rawPrivateKeyOp(self, m):
- s = numberToString(m)
- byteLength = numBytes(self.n)
- if len(s)== byteLength:
- pass
- elif len(s) == byteLength-1:
- s = '\0' + s
- else:
- raise AssertionError()
- c = stringToNumber(m2.rsa_private_encrypt(self.rsa, s,
- m2.no_padding))
- return c
-
- def _rawPublicKeyOp(self, c):
- s = numberToString(c)
- byteLength = numBytes(self.n)
- if len(s)== byteLength:
- pass
- elif len(s) == byteLength-1:
- s = '\0' + s
- else:
- raise AssertionError()
- m = stringToNumber(m2.rsa_public_decrypt(self.rsa, s,
- m2.no_padding))
- return m
-
- def acceptsPassword(self): return True
-
- def write(self, password=None):
- bio = m2.bio_new(m2.bio_s_mem())
- if self._hasPrivateKey:
- if password:
- def f(v): return password
- m2.rsa_write_key(self.rsa, bio, m2.des_ede_cbc(), f)
- else:
- def f(): pass
- m2.rsa_write_key_no_cipher(self.rsa, bio, f)
- else:
- if password:
- raise AssertionError()
- m2.rsa_write_pub_key(self.rsa, bio)
- s = m2.bio_read(bio, m2.bio_ctrl_pending(bio))
- m2.bio_free(bio)
- return s
-
- def writeXMLPublicKey(self, indent=''):
- return Python_RSAKey(self.n, self.e).write(indent)
-
- def generate(bits):
- key = OpenSSL_RSAKey()
- def f():pass
- key.rsa = m2.rsa_generate_key(bits, 3, f)
- key._hasPrivateKey = True
- return key
- generate = staticmethod(generate)
-
- def parse(s, passwordCallback=None):
- if s.startswith("-----BEGIN "):
- if passwordCallback==None:
- callback = password_callback
- else:
- def f(v, prompt1=None, prompt2=None):
- return passwordCallback()
- callback = f
- bio = m2.bio_new(m2.bio_s_mem())
- try:
- m2.bio_write(bio, s)
- key = OpenSSL_RSAKey()
- if s.startswith("-----BEGIN RSA PRIVATE KEY-----"):
- def f():pass
- key.rsa = m2.rsa_read_key(bio, callback)
- if key.rsa == None:
- raise SyntaxError()
- key._hasPrivateKey = True
- elif s.startswith("-----BEGIN PUBLIC KEY-----"):
- key.rsa = m2.rsa_read_pub_key(bio)
- if key.rsa == None:
- raise SyntaxError()
- key._hasPrivateKey = False
- else:
- raise SyntaxError()
- return key
- finally:
- m2.bio_free(bio)
- else:
- raise SyntaxError()
-
- parse = staticmethod(parse)
diff --git a/src/lib/tlslite/utils/OpenSSL_TripleDES.py b/src/lib/tlslite/utils/OpenSSL_TripleDES.py
deleted file mode 100755
index f5ba16565..000000000
--- a/src/lib/tlslite/utils/OpenSSL_TripleDES.py
+++ /dev/null
@@ -1,44 +0,0 @@
-"""OpenSSL/M2Crypto 3DES implementation."""
-
-from cryptomath import *
-from TripleDES import *
-
-if m2cryptoLoaded:
-
- def new(key, mode, IV):
- return OpenSSL_TripleDES(key, mode, IV)
-
- class OpenSSL_TripleDES(TripleDES):
-
- def __init__(self, key, mode, IV):
- TripleDES.__init__(self, key, mode, IV, "openssl")
- self.key = key
- self.IV = IV
-
- def _createContext(self, encrypt):
- context = m2.cipher_ctx_new()
- cipherType = m2.des_ede3_cbc()
- m2.cipher_init(context, cipherType, self.key, self.IV, encrypt)
- return context
-
- def encrypt(self, plaintext):
- TripleDES.encrypt(self, plaintext)
- context = self._createContext(1)
- ciphertext = m2.cipher_update(context, plaintext)
- m2.cipher_ctx_free(context)
- self.IV = ciphertext[-self.block_size:]
- return ciphertext
-
- def decrypt(self, ciphertext):
- TripleDES.decrypt(self, ciphertext)
- context = self._createContext(0)
- #I think M2Crypto has a bug - it fails to decrypt and return the last block passed in.
- #To work around this, we append sixteen zeros to the string, below:
- plaintext = m2.cipher_update(context, ciphertext+('\0'*16))
-
- #If this bug is ever fixed, then plaintext will end up having a garbage
- #plaintext block on the end. That's okay - the below code will ignore it.
- plaintext = plaintext[:len(ciphertext)]
- m2.cipher_ctx_free(context)
- self.IV = ciphertext[-self.block_size:]
- return plaintext \ No newline at end of file
diff --git a/src/lib/tlslite/utils/PyCrypto_AES.py b/src/lib/tlslite/utils/PyCrypto_AES.py
deleted file mode 100755
index e38b19d6f..000000000
--- a/src/lib/tlslite/utils/PyCrypto_AES.py
+++ /dev/null
@@ -1,22 +0,0 @@
-"""PyCrypto AES implementation."""
-
-from cryptomath import *
-from AES import *
-
-if pycryptoLoaded:
- import Crypto.Cipher.AES
-
- def new(key, mode, IV):
- return PyCrypto_AES(key, mode, IV)
-
- class PyCrypto_AES(AES):
-
- def __init__(self, key, mode, IV):
- AES.__init__(self, key, mode, IV, "pycrypto")
- self.context = Crypto.Cipher.AES.new(key, mode, IV)
-
- def encrypt(self, plaintext):
- return self.context.encrypt(plaintext)
-
- def decrypt(self, ciphertext):
- return self.context.decrypt(ciphertext) \ No newline at end of file
diff --git a/src/lib/tlslite/utils/PyCrypto_RC4.py b/src/lib/tlslite/utils/PyCrypto_RC4.py
deleted file mode 100755
index 6c6d86afd..000000000
--- a/src/lib/tlslite/utils/PyCrypto_RC4.py
+++ /dev/null
@@ -1,22 +0,0 @@
-"""PyCrypto RC4 implementation."""
-
-from cryptomath import *
-from RC4 import *
-
-if pycryptoLoaded:
- import Crypto.Cipher.ARC4
-
- def new(key):
- return PyCrypto_RC4(key)
-
- class PyCrypto_RC4(RC4):
-
- def __init__(self, key):
- RC4.__init__(self, key, "pycrypto")
- self.context = Crypto.Cipher.ARC4.new(key)
-
- def encrypt(self, plaintext):
- return self.context.encrypt(plaintext)
-
- def decrypt(self, ciphertext):
- return self.context.decrypt(ciphertext) \ No newline at end of file
diff --git a/src/lib/tlslite/utils/PyCrypto_RSAKey.py b/src/lib/tlslite/utils/PyCrypto_RSAKey.py
deleted file mode 100755
index 48b5cef03..000000000
--- a/src/lib/tlslite/utils/PyCrypto_RSAKey.py
+++ /dev/null
@@ -1,61 +0,0 @@
-"""PyCrypto RSA implementation."""
-
-from cryptomath import *
-
-from RSAKey import *
-from Python_RSAKey import Python_RSAKey
-
-if pycryptoLoaded:
-
- from Crypto.PublicKey import RSA
-
- class PyCrypto_RSAKey(RSAKey):
- def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0):
- if not d:
- self.rsa = RSA.construct( (n, e) )
- else:
- self.rsa = RSA.construct( (n, e, d, p, q) )
-
- def __getattr__(self, name):
- return getattr(self.rsa, name)
-
- def hasPrivateKey(self):
- return self.rsa.has_private()
-
- def hash(self):
- return Python_RSAKey(self.n, self.e).hash()
-
- def _rawPrivateKeyOp(self, m):
- s = numberToString(m)
- byteLength = numBytes(self.n)
- if len(s)== byteLength:
- pass
- elif len(s) == byteLength-1:
- s = '\0' + s
- else:
- raise AssertionError()
- c = stringToNumber(self.rsa.decrypt((s,)))
- return c
-
- def _rawPublicKeyOp(self, c):
- s = numberToString(c)
- byteLength = numBytes(self.n)
- if len(s)== byteLength:
- pass
- elif len(s) == byteLength-1:
- s = '\0' + s
- else:
- raise AssertionError()
- m = stringToNumber(self.rsa.encrypt(s, None)[0])
- return m
-
- def writeXMLPublicKey(self, indent=''):
- return Python_RSAKey(self.n, self.e).write(indent)
-
- def generate(bits):
- key = PyCrypto_RSAKey()
- def f(numBytes):
- return bytesToString(getRandomBytes(numBytes))
- key.rsa = RSA.generate(bits, f)
- return key
- generate = staticmethod(generate)
diff --git a/src/lib/tlslite/utils/PyCrypto_TripleDES.py b/src/lib/tlslite/utils/PyCrypto_TripleDES.py
deleted file mode 100755
index 8c22bb80a..000000000
--- a/src/lib/tlslite/utils/PyCrypto_TripleDES.py
+++ /dev/null
@@ -1,22 +0,0 @@
-"""PyCrypto 3DES implementation."""
-
-from cryptomath import *
-from TripleDES import *
-
-if pycryptoLoaded:
- import Crypto.Cipher.DES3
-
- def new(key, mode, IV):
- return PyCrypto_TripleDES(key, mode, IV)
-
- class PyCrypto_TripleDES(TripleDES):
-
- def __init__(self, key, mode, IV):
- TripleDES.__init__(self, key, mode, IV, "pycrypto")
- self.context = Crypto.Cipher.DES3.new(key, mode, IV)
-
- def encrypt(self, plaintext):
- return self.context.encrypt(plaintext)
-
- def decrypt(self, ciphertext):
- return self.context.decrypt(ciphertext) \ No newline at end of file
diff --git a/src/lib/tlslite/utils/Python_AES.py b/src/lib/tlslite/utils/Python_AES.py
deleted file mode 100755
index 657152f89..000000000
--- a/src/lib/tlslite/utils/Python_AES.py
+++ /dev/null
@@ -1,68 +0,0 @@
-"""Pure-Python AES implementation."""
-
-from cryptomath import *
-
-from AES import *
-from rijndael import rijndael
-
-def new(key, mode, IV):
- return Python_AES(key, mode, IV)
-
-class Python_AES(AES):
- def __init__(self, key, mode, IV):
- AES.__init__(self, key, mode, IV, "python")
- self.rijndael = rijndael(key, 16)
- self.IV = IV
-
- def encrypt(self, plaintext):
- AES.encrypt(self, plaintext)
-
- plaintextBytes = stringToBytes(plaintext)
- chainBytes = stringToBytes(self.IV)
-
- #CBC Mode: For each block...
- for x in range(len(plaintextBytes)/16):
-
- #XOR with the chaining block
- blockBytes = plaintextBytes[x*16 : (x*16)+16]
- for y in range(16):
- blockBytes[y] ^= chainBytes[y]
- blockString = bytesToString(blockBytes)
-
- #Encrypt it
- encryptedBytes = stringToBytes(self.rijndael.encrypt(blockString))
-
- #Overwrite the input with the output
- for y in range(16):
- plaintextBytes[(x*16)+y] = encryptedBytes[y]
-
- #Set the next chaining block
- chainBytes = encryptedBytes
-
- self.IV = bytesToString(chainBytes)
- return bytesToString(plaintextBytes)
-
- def decrypt(self, ciphertext):
- AES.decrypt(self, ciphertext)
-
- ciphertextBytes = stringToBytes(ciphertext)
- chainBytes = stringToBytes(self.IV)
-
- #CBC Mode: For each block...
- for x in range(len(ciphertextBytes)/16):
-
- #Decrypt it
- blockBytes = ciphertextBytes[x*16 : (x*16)+16]
- blockString = bytesToString(blockBytes)
- decryptedBytes = stringToBytes(self.rijndael.decrypt(blockString))
-
- #XOR with the chaining block and overwrite the input with output
- for y in range(16):
- decryptedBytes[y] ^= chainBytes[y]
- ciphertextBytes[(x*16)+y] = decryptedBytes[y]
-
- #Set the next chaining block
- chainBytes = blockBytes
-
- self.IV = bytesToString(chainBytes)
- return bytesToString(ciphertextBytes)
diff --git a/src/lib/tlslite/utils/Python_RC4.py b/src/lib/tlslite/utils/Python_RC4.py
deleted file mode 100755
index 56ce5fb2f..000000000
--- a/src/lib/tlslite/utils/Python_RC4.py
+++ /dev/null
@@ -1,39 +0,0 @@
-"""Pure-Python RC4 implementation."""
-
-from RC4 import RC4
-from cryptomath import *
-
-def new(key):
- return Python_RC4(key)
-
-class Python_RC4(RC4):
- def __init__(self, key):
- RC4.__init__(self, key, "python")
- keyBytes = stringToBytes(key)
- S = [i for i in range(256)]
- j = 0
- for i in range(256):
- j = (j + S[i] + keyBytes[i % len(keyBytes)]) % 256
- S[i], S[j] = S[j], S[i]
-
- self.S = S
- self.i = 0
- self.j = 0
-
- def encrypt(self, plaintext):
- plaintextBytes = stringToBytes(plaintext)
- S = self.S
- i = self.i
- j = self.j
- for x in range(len(plaintextBytes)):
- i = (i + 1) % 256
- j = (j + S[i]) % 256
- S[i], S[j] = S[j], S[i]
- t = (S[i] + S[j]) % 256
- plaintextBytes[x] ^= S[t]
- self.i = i
- self.j = j
- return bytesToString(plaintextBytes)
-
- def decrypt(self, ciphertext):
- return self.encrypt(ciphertext)
diff --git a/src/lib/tlslite/utils/Python_RSAKey.py b/src/lib/tlslite/utils/Python_RSAKey.py
deleted file mode 100755
index 2c469b572..000000000
--- a/src/lib/tlslite/utils/Python_RSAKey.py
+++ /dev/null
@@ -1,209 +0,0 @@
-"""Pure-Python RSA implementation."""
-
-from cryptomath import *
-import xmltools
-from ASN1Parser import ASN1Parser
-from RSAKey import *
-
-class Python_RSAKey(RSAKey):
- def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0):
- if (n and not e) or (e and not n):
- raise AssertionError()
- self.n = n
- self.e = e
- self.d = d
- self.p = p
- self.q = q
- self.dP = dP
- self.dQ = dQ
- self.qInv = qInv
- self.blinder = 0
- self.unblinder = 0
-
- def hasPrivateKey(self):
- return self.d != 0
-
- def hash(self):
- s = self.writeXMLPublicKey('\t\t')
- return hashAndBase64(s.strip())
-
- def _rawPrivateKeyOp(self, m):
- #Create blinding values, on the first pass:
- if not self.blinder:
- self.unblinder = getRandomNumber(2, self.n)
- self.blinder = powMod(invMod(self.unblinder, self.n), self.e,
- self.n)
-
- #Blind the input
- m = (m * self.blinder) % self.n
-
- #Perform the RSA operation
- c = self._rawPrivateKeyOpHelper(m)
-
- #Unblind the output
- c = (c * self.unblinder) % self.n
-
- #Update blinding values
- self.blinder = (self.blinder * self.blinder) % self.n
- self.unblinder = (self.unblinder * self.unblinder) % self.n
-
- #Return the output
- return c
-
-
- def _rawPrivateKeyOpHelper(self, m):
- #Non-CRT version
- #c = powMod(m, self.d, self.n)
-
- #CRT version (~3x faster)
- s1 = powMod(m, self.dP, self.p)
- s2 = powMod(m, self.dQ, self.q)
- h = ((s1 - s2) * self.qInv) % self.p
- c = s2 + self.q * h
- return c
-
- def _rawPublicKeyOp(self, c):
- m = powMod(c, self.e, self.n)
- return m
-
- def acceptsPassword(self): return False
-
- def write(self, indent=''):
- if self.d:
- s = indent+'<privateKey xmlns="http://trevp.net/rsa">\n'
- else:
- s = indent+'<publicKey xmlns="http://trevp.net/rsa">\n'
- s += indent+'\t<n>%s</n>\n' % numberToBase64(self.n)
- s += indent+'\t<e>%s</e>\n' % numberToBase64(self.e)
- if self.d:
- s += indent+'\t<d>%s</d>\n' % numberToBase64(self.d)
- s += indent+'\t<p>%s</p>\n' % numberToBase64(self.p)
- s += indent+'\t<q>%s</q>\n' % numberToBase64(self.q)
- s += indent+'\t<dP>%s</dP>\n' % numberToBase64(self.dP)
- s += indent+'\t<dQ>%s</dQ>\n' % numberToBase64(self.dQ)
- s += indent+'\t<qInv>%s</qInv>\n' % numberToBase64(self.qInv)
- s += indent+'</privateKey>'
- else:
- s += indent+'</publicKey>'
- #Only add \n if part of a larger structure
- if indent != '':
- s += '\n'
- return s
-
- def writeXMLPublicKey(self, indent=''):
- return Python_RSAKey(self.n, self.e).write(indent)
-
- def generate(bits):
- key = Python_RSAKey()
- p = getRandomPrime(bits/2, False)
- q = getRandomPrime(bits/2, False)
- t = lcm(p-1, q-1)
- key.n = p * q
- key.e = 3L #Needed to be long, for Java
- key.d = invMod(key.e, t)
- key.p = p
- key.q = q
- key.dP = key.d % (p-1)
- key.dQ = key.d % (q-1)
- key.qInv = invMod(q, p)
- return key
- generate = staticmethod(generate)
-
- def parsePEM(s, passwordCallback=None):
- """Parse a string containing a <privateKey> or <publicKey>, or
- PEM-encoded key."""
-
- start = s.find("-----BEGIN PRIVATE KEY-----")
- if start != -1:
- end = s.find("-----END PRIVATE KEY-----")
- if end == -1:
- raise SyntaxError("Missing PEM Postfix")
- s = s[start+len("-----BEGIN PRIVATE KEY -----") : end]
- bytes = base64ToBytes(s)
- return Python_RSAKey._parsePKCS8(bytes)
- else:
- start = s.find("-----BEGIN RSA PRIVATE KEY-----")
- if start != -1:
- end = s.find("-----END RSA PRIVATE KEY-----")
- if end == -1:
- raise SyntaxError("Missing PEM Postfix")
- s = s[start+len("-----BEGIN RSA PRIVATE KEY -----") : end]
- bytes = base64ToBytes(s)
- return Python_RSAKey._parseSSLeay(bytes)
- raise SyntaxError("Missing PEM Prefix")
- parsePEM = staticmethod(parsePEM)
-
- def parseXML(s):
- element = xmltools.parseAndStripWhitespace(s)
- return Python_RSAKey._parseXML(element)
- parseXML = staticmethod(parseXML)
-
- def _parsePKCS8(bytes):
- p = ASN1Parser(bytes)
-
- version = p.getChild(0).value[0]
- if version != 0:
- raise SyntaxError("Unrecognized PKCS8 version")
-
- rsaOID = p.getChild(1).value
- if list(rsaOID) != [6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0]:
- raise SyntaxError("Unrecognized AlgorithmIdentifier")
-
- #Get the privateKey
- privateKeyP = p.getChild(2)
-
- #Adjust for OCTET STRING encapsulation
- privateKeyP = ASN1Parser(privateKeyP.value)
-
- return Python_RSAKey._parseASN1PrivateKey(privateKeyP)
- _parsePKCS8 = staticmethod(_parsePKCS8)
-
- def _parseSSLeay(bytes):
- privateKeyP = ASN1Parser(bytes)
- return Python_RSAKey._parseASN1PrivateKey(privateKeyP)
- _parseSSLeay = staticmethod(_parseSSLeay)
-
- def _parseASN1PrivateKey(privateKeyP):
- version = privateKeyP.getChild(0).value[0]
- if version != 0:
- raise SyntaxError("Unrecognized RSAPrivateKey version")
- n = bytesToNumber(privateKeyP.getChild(1).value)
- e = bytesToNumber(privateKeyP.getChild(2).value)
- d = bytesToNumber(privateKeyP.getChild(3).value)
- p = bytesToNumber(privateKeyP.getChild(4).value)
- q = bytesToNumber(privateKeyP.getChild(5).value)
- dP = bytesToNumber(privateKeyP.getChild(6).value)
- dQ = bytesToNumber(privateKeyP.getChild(7).value)
- qInv = bytesToNumber(privateKeyP.getChild(8).value)
- return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv)
- _parseASN1PrivateKey = staticmethod(_parseASN1PrivateKey)
-
- def _parseXML(element):
- try:
- xmltools.checkName(element, "privateKey")
- except SyntaxError:
- xmltools.checkName(element, "publicKey")
-
- #Parse attributes
- xmltools.getReqAttribute(element, "xmlns", "http://trevp.net/rsa\Z")
- xmltools.checkNoMoreAttributes(element)
-
- #Parse public values (<n> and <e>)
- n = base64ToNumber(xmltools.getText(xmltools.getChild(element, 0, "n"), xmltools.base64RegEx))
- e = base64ToNumber(xmltools.getText(xmltools.getChild(element, 1, "e"), xmltools.base64RegEx))
- d = 0
- p = 0
- q = 0
- dP = 0
- dQ = 0
- qInv = 0
- #Parse private values, if present
- if element.childNodes.length>=3:
- d = base64ToNumber(xmltools.getText(xmltools.getChild(element, 2, "d"), xmltools.base64RegEx))
- p = base64ToNumber(xmltools.getText(xmltools.getChild(element, 3, "p"), xmltools.base64RegEx))
- q = base64ToNumber(xmltools.getText(xmltools.getChild(element, 4, "q"), xmltools.base64RegEx))
- dP = base64ToNumber(xmltools.getText(xmltools.getChild(element, 5, "dP"), xmltools.base64RegEx))
- dQ = base64ToNumber(xmltools.getText(xmltools.getChild(element, 6, "dQ"), xmltools.base64RegEx))
- qInv = base64ToNumber(xmltools.getText(xmltools.getLastChild(element, 7, "qInv"), xmltools.base64RegEx))
- return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv)
- _parseXML = staticmethod(_parseXML)
diff --git a/src/lib/tlslite/utils/RC4.py b/src/lib/tlslite/utils/RC4.py
deleted file mode 100755
index 550692327..000000000
--- a/src/lib/tlslite/utils/RC4.py
+++ /dev/null
@@ -1,17 +0,0 @@
-"""Abstract class for RC4."""
-
-from compat import * #For False
-
-class RC4:
- def __init__(self, keyBytes, implementation):
- if len(keyBytes) < 16 or len(keyBytes) > 256:
- raise ValueError()
- self.isBlockCipher = False
- self.name = "rc4"
- self.implementation = implementation
-
- def encrypt(self, plaintext):
- raise NotImplementedError()
-
- def decrypt(self, ciphertext):
- raise NotImplementedError() \ No newline at end of file
diff --git a/src/lib/tlslite/utils/RSAKey.py b/src/lib/tlslite/utils/RSAKey.py
deleted file mode 100755
index 37c292df5..000000000
--- a/src/lib/tlslite/utils/RSAKey.py
+++ /dev/null
@@ -1,264 +0,0 @@
-"""Abstract class for RSA."""
-
-from cryptomath import *
-
-
-class RSAKey:
- """This is an abstract base class for RSA keys.
-
- Particular implementations of RSA keys, such as
- L{OpenSSL_RSAKey.OpenSSL_RSAKey},
- L{Python_RSAKey.Python_RSAKey}, and
- L{PyCrypto_RSAKey.PyCrypto_RSAKey},
- inherit from this.
-
- To create or parse an RSA key, don't use one of these classes
- directly. Instead, use the factory functions in
- L{tlslite.utils.keyfactory}.
- """
-
- def __init__(self, n=0, e=0):
- """Create a new RSA key.
-
- If n and e are passed in, the new key will be initialized.
-
- @type n: int
- @param n: RSA modulus.
-
- @type e: int
- @param e: RSA public exponent.
- """
- raise NotImplementedError()
-
- def __len__(self):
- """Return the length of this key in bits.
-
- @rtype: int
- """
- return numBits(self.n)
-
- def hasPrivateKey(self):
- """Return whether or not this key has a private component.
-
- @rtype: bool
- """
- raise NotImplementedError()
-
- def hash(self):
- """Return the cryptoID <keyHash> value corresponding to this
- key.
-
- @rtype: str
- """
- raise NotImplementedError()
-
- def getSigningAlgorithm(self):
- """Return the cryptoID sigAlgo value corresponding to this key.
-
- @rtype: str
- """
- return "pkcs1-sha1"
-
- def hashAndSign(self, bytes):
- """Hash and sign the passed-in bytes.
-
- This requires the key to have a private component. It performs
- a PKCS1-SHA1 signature on the passed-in data.
-
- @type bytes: str or L{array.array} of unsigned bytes
- @param bytes: The value which will be hashed and signed.
-
- @rtype: L{array.array} of unsigned bytes.
- @return: A PKCS1-SHA1 signature on the passed-in data.
- """
- if not isinstance(bytes, type("")):
- bytes = bytesToString(bytes)
- hashBytes = stringToBytes(sha.sha(bytes).digest())
- prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes)
- sigBytes = self.sign(prefixedHashBytes)
- return sigBytes
-
- def hashAndVerify(self, sigBytes, bytes):
- """Hash and verify the passed-in bytes with the signature.
-
- This verifies a PKCS1-SHA1 signature on the passed-in data.
-
- @type sigBytes: L{array.array} of unsigned bytes
- @param sigBytes: A PKCS1-SHA1 signature.
-
- @type bytes: str or L{array.array} of unsigned bytes
- @param bytes: The value which will be hashed and verified.
-
- @rtype: bool
- @return: Whether the signature matches the passed-in data.
- """
- if not isinstance(bytes, type("")):
- bytes = bytesToString(bytes)
- hashBytes = stringToBytes(sha.sha(bytes).digest())
- prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes)
- return self.verify(sigBytes, prefixedHashBytes)
-
- def sign(self, bytes):
- """Sign the passed-in bytes.
-
- This requires the key to have a private component. It performs
- a PKCS1 signature on the passed-in data.
-
- @type bytes: L{array.array} of unsigned bytes
- @param bytes: The value which will be signed.
-
- @rtype: L{array.array} of unsigned bytes.
- @return: A PKCS1 signature on the passed-in data.
- """
- if not self.hasPrivateKey():
- raise AssertionError()
- paddedBytes = self._addPKCS1Padding(bytes, 1)
- m = bytesToNumber(paddedBytes)
- if m >= self.n:
- raise ValueError()
- c = self._rawPrivateKeyOp(m)
- sigBytes = numberToBytes(c)
- return sigBytes
-
- def verify(self, sigBytes, bytes):
- """Verify the passed-in bytes with the signature.
-
- This verifies a PKCS1 signature on the passed-in data.
-
- @type sigBytes: L{array.array} of unsigned bytes
- @param sigBytes: A PKCS1 signature.
-
- @type bytes: L{array.array} of unsigned bytes
- @param bytes: The value which will be verified.
-
- @rtype: bool
- @return: Whether the signature matches the passed-in data.
- """
- paddedBytes = self._addPKCS1Padding(bytes, 1)
- c = bytesToNumber(sigBytes)
- if c >= self.n:
- return False
- m = self._rawPublicKeyOp(c)
- checkBytes = numberToBytes(m)
- return checkBytes == paddedBytes
-
- def encrypt(self, bytes):
- """Encrypt the passed-in bytes.
-
- This performs PKCS1 encryption of the passed-in data.
-
- @type bytes: L{array.array} of unsigned bytes
- @param bytes: The value which will be encrypted.
-
- @rtype: L{array.array} of unsigned bytes.
- @return: A PKCS1 encryption of the passed-in data.
- """
- paddedBytes = self._addPKCS1Padding(bytes, 2)
- m = bytesToNumber(paddedBytes)
- if m >= self.n:
- raise ValueError()
- c = self._rawPublicKeyOp(m)
- encBytes = numberToBytes(c)
- return encBytes
-
- def decrypt(self, encBytes):
- """Decrypt the passed-in bytes.
-
- This requires the key to have a private component. It performs
- PKCS1 decryption of the passed-in data.
-
- @type encBytes: L{array.array} of unsigned bytes
- @param encBytes: The value which will be decrypted.
-
- @rtype: L{array.array} of unsigned bytes or None.
- @return: A PKCS1 decryption of the passed-in data or None if
- the data is not properly formatted.
- """
- if not self.hasPrivateKey():
- raise AssertionError()
- c = bytesToNumber(encBytes)
- if c >= self.n:
- return None
- m = self._rawPrivateKeyOp(c)
- decBytes = numberToBytes(m)
- if (len(decBytes) != numBytes(self.n)-1): #Check first byte
- return None
- if decBytes[0] != 2: #Check second byte
- return None
- for x in range(len(decBytes)-1): #Scan through for zero separator
- if decBytes[x]== 0:
- break
- else:
- return None
- return decBytes[x+1:] #Return everything after the separator
-
- def _rawPrivateKeyOp(self, m):
- raise NotImplementedError()
-
- def _rawPublicKeyOp(self, c):
- raise NotImplementedError()
-
- def acceptsPassword(self):
- """Return True if the write() method accepts a password for use
- in encrypting the private key.
-
- @rtype: bool
- """
- raise NotImplementedError()
-
- def write(self, password=None):
- """Return a string containing the key.
-
- @rtype: str
- @return: A string describing the key, in whichever format (PEM
- or XML) is native to the implementation.
- """
- raise NotImplementedError()
-
- def writeXMLPublicKey(self, indent=''):
- """Return a string containing the key.
-
- @rtype: str
- @return: A string describing the public key, in XML format.
- """
- return Python_RSAKey(self.n, self.e).write(indent)
-
- def generate(bits):
- """Generate a new key with the specified bit length.
-
- @rtype: L{tlslite.utils.RSAKey.RSAKey}
- """
- raise NotImplementedError()
- generate = staticmethod(generate)
-
-
- # **************************************************************************
- # Helper Functions for RSA Keys
- # **************************************************************************
-
- def _addPKCS1SHA1Prefix(self, bytes):
- prefixBytes = createByteArraySequence(\
- [48,33,48,9,6,5,43,14,3,2,26,5,0,4,20])
- prefixedBytes = prefixBytes + bytes
- return prefixedBytes
-
- def _addPKCS1Padding(self, bytes, blockType):
- padLength = (numBytes(self.n) - (len(bytes)+3))
- if blockType == 1: #Signature padding
- pad = [0xFF] * padLength
- elif blockType == 2: #Encryption padding
- pad = createByteArraySequence([])
- while len(pad) < padLength:
- padBytes = getRandomBytes(padLength * 2)
- pad = [b for b in padBytes if b != 0]
- pad = pad[:padLength]
- else:
- raise AssertionError()
-
- #NOTE: To be proper, we should add [0,blockType]. However,
- #the zero is lost when the returned padding is converted
- #to a number, so we don't even bother with it. Also,
- #adding it would cause a misalignment in verify()
- padding = createByteArraySequence([blockType] + pad + [0])
- paddedBytes = padding + bytes
- return paddedBytes
diff --git a/src/lib/tlslite/utils/TripleDES.py b/src/lib/tlslite/utils/TripleDES.py
deleted file mode 100755
index 2db45888b..000000000
--- a/src/lib/tlslite/utils/TripleDES.py
+++ /dev/null
@@ -1,26 +0,0 @@
-"""Abstract class for 3DES."""
-
-from compat import * #For True
-
-class TripleDES:
- def __init__(self, key, mode, IV, implementation):
- if len(key) != 24:
- raise ValueError()
- if mode != 2:
- raise ValueError()
- if len(IV) != 8:
- raise ValueError()
- self.isBlockCipher = True
- self.block_size = 8
- self.implementation = implementation
- self.name = "3des"
-
- #CBC-Mode encryption, returns ciphertext
- #WARNING: *MAY* modify the input as well
- def encrypt(self, plaintext):
- assert(len(plaintext) % 8 == 0)
-
- #CBC-Mode decryption, returns plaintext
- #WARNING: *MAY* modify the input as well
- def decrypt(self, ciphertext):
- assert(len(ciphertext) % 8 == 0)
diff --git a/src/lib/tlslite/utils/__init__.py b/src/lib/tlslite/utils/__init__.py
deleted file mode 100755
index f63f080fa..000000000
--- a/src/lib/tlslite/utils/__init__.py
+++ /dev/null
@@ -1,32 +0,0 @@
-"""Toolkit for crypto and other stuff."""
-
-__all__ = ["AES",
- "ASN1Parser",
- "cipherfactory",
- "codec",
- "Cryptlib_AES",
- "Cryptlib_RC4",
- "Cryptlib_TripleDES",
- "cryptomath: cryptomath module",
- "dateFuncs",
- "hmac",
- "JCE_RSAKey",
- "compat",
- "keyfactory",
- "OpenSSL_AES",
- "OpenSSL_RC4",
- "OpenSSL_RSAKey",
- "OpenSSL_TripleDES",
- "prngd: prngd module",
- "PyCrypto_AES",
- "PyCrypto_RC4",
- "PyCrypto_RSAKey",
- "PyCrypto_TripleDES",
- "Python_AES",
- "Python_RC4",
- "Python_RSAKey",
- "RC4",
- "rijndael",
- "RSAKey",
- "TripleDES",
- "xmltools"]
diff --git a/src/lib/tlslite/utils/cipherfactory.py b/src/lib/tlslite/utils/cipherfactory.py
deleted file mode 100755
index ccbb6b5ff..000000000
--- a/src/lib/tlslite/utils/cipherfactory.py
+++ /dev/null
@@ -1,111 +0,0 @@
-"""Factory functions for symmetric cryptography."""
-
-import os
-
-import Python_AES
-import Python_RC4
-
-import cryptomath
-
-tripleDESPresent = False
-
-if cryptomath.m2cryptoLoaded:
- import OpenSSL_AES
- import OpenSSL_RC4
- import OpenSSL_TripleDES
- tripleDESPresent = True
-
-if cryptomath.cryptlibpyLoaded:
- import Cryptlib_AES
- import Cryptlib_RC4
- import Cryptlib_TripleDES
- tripleDESPresent = True
-
-if cryptomath.pycryptoLoaded:
- import PyCrypto_AES
- import PyCrypto_RC4
- import PyCrypto_TripleDES
- tripleDESPresent = True
-
-# **************************************************************************
-# Factory Functions for AES
-# **************************************************************************
-
-def createAES(key, IV, implList=None):
- """Create a new AES object.
-
- @type key: str
- @param key: A 16, 24, or 32 byte string.
-
- @type IV: str
- @param IV: A 16 byte string
-
- @rtype: L{tlslite.utils.AES}
- @return: An AES object.
- """
- if implList == None:
- implList = ["cryptlib", "openssl", "pycrypto", "python"]
-
- for impl in implList:
- if impl == "cryptlib" and cryptomath.cryptlibpyLoaded:
- return Cryptlib_AES.new(key, 2, IV)
- elif impl == "openssl" and cryptomath.m2cryptoLoaded:
- return OpenSSL_AES.new(key, 2, IV)
- elif impl == "pycrypto" and cryptomath.pycryptoLoaded:
- return PyCrypto_AES.new(key, 2, IV)
- elif impl == "python":
- return Python_AES.new(key, 2, IV)
- raise NotImplementedError()
-
-def createRC4(key, IV, implList=None):
- """Create a new RC4 object.
-
- @type key: str
- @param key: A 16 to 32 byte string.
-
- @type IV: object
- @param IV: Ignored, whatever it is.
-
- @rtype: L{tlslite.utils.RC4}
- @return: An RC4 object.
- """
- if implList == None:
- implList = ["cryptlib", "openssl", "pycrypto", "python"]
-
- if len(IV) != 0:
- raise AssertionError()
- for impl in implList:
- if impl == "cryptlib" and cryptomath.cryptlibpyLoaded:
- return Cryptlib_RC4.new(key)
- elif impl == "openssl" and cryptomath.m2cryptoLoaded:
- return OpenSSL_RC4.new(key)
- elif impl == "pycrypto" and cryptomath.pycryptoLoaded:
- return PyCrypto_RC4.new(key)
- elif impl == "python":
- return Python_RC4.new(key)
- raise NotImplementedError()
-
-#Create a new TripleDES instance
-def createTripleDES(key, IV, implList=None):
- """Create a new 3DES object.
-
- @type key: str
- @param key: A 24 byte string.
-
- @type IV: str
- @param IV: An 8 byte string
-
- @rtype: L{tlslite.utils.TripleDES}
- @return: A 3DES object.
- """
- if implList == None:
- implList = ["cryptlib", "openssl", "pycrypto"]
-
- for impl in implList:
- if impl == "cryptlib" and cryptomath.cryptlibpyLoaded:
- return Cryptlib_TripleDES.new(key, 2, IV)
- elif impl == "openssl" and cryptomath.m2cryptoLoaded:
- return OpenSSL_TripleDES.new(key, 2, IV)
- elif impl == "pycrypto" and cryptomath.pycryptoLoaded:
- return PyCrypto_TripleDES.new(key, 2, IV)
- raise NotImplementedError() \ No newline at end of file
diff --git a/src/lib/tlslite/utils/codec.py b/src/lib/tlslite/utils/codec.py
deleted file mode 100755
index 13022a0b9..000000000
--- a/src/lib/tlslite/utils/codec.py
+++ /dev/null
@@ -1,94 +0,0 @@
-"""Classes for reading/writing binary data (such as TLS records)."""
-
-from compat import *
-
-class Writer:
- def __init__(self, length=0):
- #If length is zero, then this is just a "trial run" to determine length
- self.index = 0
- self.bytes = createByteArrayZeros(length)
-
- def add(self, x, length):
- if self.bytes:
- newIndex = self.index+length-1
- while newIndex >= self.index:
- self.bytes[newIndex] = x & 0xFF
- x >>= 8
- newIndex -= 1
- self.index += length
-
- def addFixSeq(self, seq, length):
- if self.bytes:
- for e in seq:
- self.add(e, length)
- else:
- self.index += len(seq)*length
-
- def addVarSeq(self, seq, length, lengthLength):
- if self.bytes:
- self.add(len(seq)*length, lengthLength)
- for e in seq:
- self.add(e, length)
- else:
- self.index += lengthLength + (len(seq)*length)
-
-
-class Parser:
- def __init__(self, bytes):
- self.bytes = bytes
- self.index = 0
-
- def get(self, length):
- if self.index + length > len(self.bytes):
- raise SyntaxError()
- x = 0
- for count in range(length):
- x <<= 8
- x |= self.bytes[self.index]
- self.index += 1
- return x
-
- def getFixBytes(self, lengthBytes):
- bytes = self.bytes[self.index : self.index+lengthBytes]
- self.index += lengthBytes
- return bytes
-
- def getVarBytes(self, lengthLength):
- lengthBytes = self.get(lengthLength)
- return self.getFixBytes(lengthBytes)
-
- def getFixList(self, length, lengthList):
- l = [0] * lengthList
- for x in range(lengthList):
- l[x] = self.get(length)
- return l
-
- def getVarList(self, length, lengthLength):
- lengthList = self.get(lengthLength)
- if lengthList % length != 0:
- raise SyntaxError()
- lengthList = int(lengthList/length)
- l = [0] * lengthList
- for x in range(lengthList):
- l[x] = self.get(length)
- return l
-
- def startLengthCheck(self, lengthLength):
- self.lengthCheck = self.get(lengthLength)
- self.indexCheck = self.index
-
- def setLengthCheck(self, length):
- self.lengthCheck = length
- self.indexCheck = self.index
-
- def stopLengthCheck(self):
- if (self.index - self.indexCheck) != self.lengthCheck:
- raise SyntaxError()
-
- def atLengthCheck(self):
- if (self.index - self.indexCheck) < self.lengthCheck:
- return False
- elif (self.index - self.indexCheck) == self.lengthCheck:
- return True
- else:
- raise SyntaxError() \ No newline at end of file
diff --git a/src/lib/tlslite/utils/compat.py b/src/lib/tlslite/utils/compat.py
deleted file mode 100755
index 7d2d9250d..000000000
--- a/src/lib/tlslite/utils/compat.py
+++ /dev/null
@@ -1,140 +0,0 @@
-"""Miscellaneous functions to mask Python version differences."""
-
-import sys
-import os
-
-if sys.version_info < (2,2):
- raise AssertionError("Python 2.2 or later required")
-
-if sys.version_info < (2,3):
-
- def enumerate(collection):
- return zip(range(len(collection)), collection)
-
- class Set:
- def __init__(self, seq=None):
- self.values = {}
- if seq:
- for e in seq:
- self.values[e] = None
-
- def add(self, e):
- self.values[e] = None
-
- def discard(self, e):
- if e in self.values.keys():
- del(self.values[e])
-
- def union(self, s):
- ret = Set()
- for e in self.values.keys():
- ret.values[e] = None
- for e in s.values.keys():
- ret.values[e] = None
- return ret
-
- def issubset(self, other):
- for e in self.values.keys():
- if e not in other.values.keys():
- return False
- return True
-
- def __nonzero__( self):
- return len(self.values.keys())
-
- def __contains__(self, e):
- return e in self.values.keys()
-
- def __iter__(self):
- return iter(set.values.keys())
-
-
-if os.name != "java":
-
- import array
- def createByteArraySequence(seq):
- return array.array('B', seq)
- def createByteArrayZeros(howMany):
- return array.array('B', [0] * howMany)
- def concatArrays(a1, a2):
- return a1+a2
-
- def bytesToString(bytes):
- return bytes.tostring()
- def stringToBytes(s):
- bytes = createByteArrayZeros(0)
- bytes.fromstring(s)
- return bytes
-
- import math
- def numBits(n):
- if n==0:
- return 0
- s = "%x" % n
- return ((len(s)-1)*4) + \
- {'0':0, '1':1, '2':2, '3':2,
- '4':3, '5':3, '6':3, '7':3,
- '8':4, '9':4, 'a':4, 'b':4,
- 'c':4, 'd':4, 'e':4, 'f':4,
- }[s[0]]
- return int(math.floor(math.log(n, 2))+1)
-
- BaseException = Exception
- import sys
- import traceback
- def formatExceptionTrace(e):
- newStr = "".join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
- return newStr
-
-else:
- #Jython 2.1 is missing lots of python 2.3 stuff,
- #which we have to emulate here:
- #NOTE: JYTHON SUPPORT NO LONGER WORKS, DUE TO USE OF GENERATORS.
- #THIS CODE IS LEFT IN SO THAT ONE JYTHON UPDATES TO 2.2, IT HAS A
- #CHANCE OF WORKING AGAIN.
-
- import java
- import jarray
-
- def createByteArraySequence(seq):
- if isinstance(seq, type("")): #If it's a string, convert
- seq = [ord(c) for c in seq]
- return jarray.array(seq, 'h') #use short instead of bytes, cause bytes are signed
- def createByteArrayZeros(howMany):
- return jarray.zeros(howMany, 'h') #use short instead of bytes, cause bytes are signed
- def concatArrays(a1, a2):
- l = list(a1)+list(a2)
- return createByteArraySequence(l)
-
- #WAY TOO SLOW - MUST BE REPLACED------------
- def bytesToString(bytes):
- return "".join([chr(b) for b in bytes])
-
- def stringToBytes(s):
- bytes = createByteArrayZeros(len(s))
- for count, c in enumerate(s):
- bytes[count] = ord(c)
- return bytes
- #WAY TOO SLOW - MUST BE REPLACED------------
-
- def numBits(n):
- if n==0:
- return 0
- n= 1L * n; #convert to long, if it isn't already
- return n.__tojava__(java.math.BigInteger).bitLength()
-
- #Adjust the string to an array of bytes
- def stringToJavaByteArray(s):
- bytes = jarray.zeros(len(s), 'b')
- for count, c in enumerate(s):
- x = ord(c)
- if x >= 128: x -= 256
- bytes[count] = x
- return bytes
-
- BaseException = java.lang.Exception
- import sys
- import traceback
- def formatExceptionTrace(e):
- newStr = "".join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
- return newStr \ No newline at end of file
diff --git a/src/lib/tlslite/utils/cryptomath.py b/src/lib/tlslite/utils/cryptomath.py
deleted file mode 100755
index 9b6f0495f..000000000
--- a/src/lib/tlslite/utils/cryptomath.py
+++ /dev/null
@@ -1,411 +0,0 @@
-"""cryptomath module
-
-This module has basic math/crypto code."""
-
-import os
-import math
-import base64
-import binascii
-import sha
-
-from compat import *
-
-
-# **************************************************************************
-# Load Optional Modules
-# **************************************************************************
-
-# Try to load M2Crypto/OpenSSL
-try:
- from M2Crypto import m2
- m2cryptoLoaded = True
-
-except ImportError:
- m2cryptoLoaded = False
-
-
-# Try to load cryptlib
-try:
- import cryptlib_py
- try:
- cryptlib_py.cryptInit()
- except cryptlib_py.CryptException, e:
- #If tlslite and cryptoIDlib are both present,
- #they might each try to re-initialize this,
- #so we're tolerant of that.
- if e[0] != cryptlib_py.CRYPT_ERROR_INITED:
- raise
- cryptlibpyLoaded = True
-
-except ImportError:
- cryptlibpyLoaded = False
-
-#Try to load GMPY
-try:
- import gmpy
- gmpyLoaded = True
-except ImportError:
- gmpyLoaded = False
-
-#Try to load pycrypto
-try:
- import Crypto.Cipher.AES
- pycryptoLoaded = True
-except ImportError:
- pycryptoLoaded = False
-
-
-# **************************************************************************
-# PRNG Functions
-# **************************************************************************
-
-# Get os.urandom PRNG
-try:
- os.urandom(1)
- def getRandomBytes(howMany):
- return stringToBytes(os.urandom(howMany))
- prngName = "os.urandom"
-
-except:
- # Else get cryptlib PRNG
- if cryptlibpyLoaded:
- def getRandomBytes(howMany):
- randomKey = cryptlib_py.cryptCreateContext(cryptlib_py.CRYPT_UNUSED,
- cryptlib_py.CRYPT_ALGO_AES)
- cryptlib_py.cryptSetAttribute(randomKey,
- cryptlib_py.CRYPT_CTXINFO_MODE,
- cryptlib_py.CRYPT_MODE_OFB)
- cryptlib_py.cryptGenerateKey(randomKey)
- bytes = createByteArrayZeros(howMany)
- cryptlib_py.cryptEncrypt(randomKey, bytes)
- return bytes
- prngName = "cryptlib"
-
- else:
- #Else get UNIX /dev/urandom PRNG
- try:
- devRandomFile = open("/dev/urandom", "rb")
- def getRandomBytes(howMany):
- return stringToBytes(devRandomFile.read(howMany))
- prngName = "/dev/urandom"
- except IOError:
- #Else get Win32 CryptoAPI PRNG
- try:
- import win32prng
- def getRandomBytes(howMany):
- s = win32prng.getRandomBytes(howMany)
- if len(s) != howMany:
- raise AssertionError()
- return stringToBytes(s)
- prngName ="CryptoAPI"
- except ImportError:
- # Else see if we ahve Pprngd running
- try:
- def getRandomBytes(howMany):
- from prngd import PRNGD
- try:
- p = PRNGD(sockname="/var/run/egd-pool")
- except:
- p = PRNGD(sockname="/dev/egd-pool")
- return stringToBytes(p.read(howMany))
- prngName = "PRNGD"
- except:
- #Else no PRNG :-(
- def getRandomBytes(howMany):
- raise NotImplementedError("No Random Number Generator "\
- "available.")
- prngName = "None"
-
-# **************************************************************************
-# Converter Functions
-# **************************************************************************
-
-def bytesToNumber(bytes):
- total = 0L
- multiplier = 1L
- for count in range(len(bytes)-1, -1, -1):
- byte = bytes[count]
- total += multiplier * byte
- multiplier *= 256
- return total
-
-def numberToBytes(n):
- howManyBytes = numBytes(n)
- bytes = createByteArrayZeros(howManyBytes)
- for count in range(howManyBytes-1, -1, -1):
- bytes[count] = int(n % 256)
- n >>= 8
- return bytes
-
-def bytesToBase64(bytes):
- s = bytesToString(bytes)
- return stringToBase64(s)
-
-def base64ToBytes(s):
- s = base64ToString(s)
- return stringToBytes(s)
-
-def numberToBase64(n):
- bytes = numberToBytes(n)
- return bytesToBase64(bytes)
-
-def base64ToNumber(s):
- bytes = base64ToBytes(s)
- return bytesToNumber(bytes)
-
-def stringToNumber(s):
- bytes = stringToBytes(s)
- return bytesToNumber(bytes)
-
-def numberToString(s):
- bytes = numberToBytes(s)
- return bytesToString(bytes)
-
-def base64ToString(s):
- try:
- return base64.decodestring(s)
- except binascii.Error, e:
- raise SyntaxError(e)
- except binascii.Incomplete, e:
- raise SyntaxError(e)
-
-def stringToBase64(s):
- return base64.encodestring(s).replace("\n", "")
-
-def mpiToNumber(mpi): #mpi is an openssl-format bignum string
- if (ord(mpi[4]) & 0x80) !=0: #Make sure this is a positive number
- raise AssertionError()
- bytes = stringToBytes(mpi[4:])
- return bytesToNumber(bytes)
-
-def numberToMPI(n):
- bytes = numberToBytes(n)
- ext = 0
- #If the high-order bit is going to be set,
- #add an extra byte of zeros
- if (numBits(n) & 0x7)==0:
- ext = 1
- length = numBytes(n) + ext
- bytes = concatArrays(createByteArrayZeros(4+ext), bytes)
- bytes[0] = (length >> 24) & 0xFF
- bytes[1] = (length >> 16) & 0xFF
- bytes[2] = (length >> 8) & 0xFF
- bytes[3] = length & 0xFF
- return bytesToString(bytes)
-
-
-
-# **************************************************************************
-# Misc. Utility Functions
-# **************************************************************************
-
-def numBytes(n):
- if n==0:
- return 0
- bits = numBits(n)
- return int(math.ceil(bits / 8.0))
-
-def hashAndBase64(s):
- return stringToBase64(sha.sha(s).digest())
-
-def getBase64Nonce(numChars=22): #defaults to an 132 bit nonce
- bytes = getRandomBytes(numChars)
- bytesStr = "".join([chr(b) for b in bytes])
- return stringToBase64(bytesStr)[:numChars]
-
-
-# **************************************************************************
-# Big Number Math
-# **************************************************************************
-
-def getRandomNumber(low, high):
- if low >= high:
- raise AssertionError()
- howManyBits = numBits(high)
- howManyBytes = numBytes(high)
- lastBits = howManyBits % 8
- while 1:
- bytes = getRandomBytes(howManyBytes)
- if lastBits:
- bytes[0] = bytes[0] % (1 << lastBits)
- n = bytesToNumber(bytes)
- if n >= low and n < high:
- return n
-
-def gcd(a,b):
- a, b = max(a,b), min(a,b)
- while b:
- a, b = b, a % b
- return a
-
-def lcm(a, b):
- #This will break when python division changes, but we can't use // cause
- #of Jython
- return (a * b) / gcd(a, b)
-
-#Returns inverse of a mod b, zero if none
-#Uses Extended Euclidean Algorithm
-def invMod(a, b):
- c, d = a, b
- uc, ud = 1, 0
- while c != 0:
- #This will break when python division changes, but we can't use //
- #cause of Jython
- q = d / c
- c, d = d-(q*c), c
- uc, ud = ud - (q * uc), uc
- if d == 1:
- return ud % b
- return 0
-
-
-if gmpyLoaded:
- def powMod(base, power, modulus):
- base = gmpy.mpz(base)
- power = gmpy.mpz(power)
- modulus = gmpy.mpz(modulus)
- result = pow(base, power, modulus)
- return long(result)
-
-else:
- #Copied from Bryan G. Olson's post to comp.lang.python
- #Does left-to-right instead of pow()'s right-to-left,
- #thus about 30% faster than the python built-in with small bases
- def powMod(base, power, modulus):
- nBitScan = 5
-
- """ Return base**power mod modulus, using multi bit scanning
- with nBitScan bits at a time."""
-
- #TREV - Added support for negative exponents
- negativeResult = False
- if (power < 0):
- power *= -1
- negativeResult = True
-
- exp2 = 2**nBitScan
- mask = exp2 - 1
-
- # Break power into a list of digits of nBitScan bits.
- # The list is recursive so easy to read in reverse direction.
- nibbles = None
- while power:
- nibbles = int(power & mask), nibbles
- power = power >> nBitScan
-
- # Make a table of powers of base up to 2**nBitScan - 1
- lowPowers = [1]
- for i in xrange(1, exp2):
- lowPowers.append((lowPowers[i-1] * base) % modulus)
-
- # To exponentiate by the first nibble, look it up in the table
- nib, nibbles = nibbles
- prod = lowPowers[nib]
-
- # For the rest, square nBitScan times, then multiply by
- # base^nibble
- while nibbles:
- nib, nibbles = nibbles
- for i in xrange(nBitScan):
- prod = (prod * prod) % modulus
- if nib: prod = (prod * lowPowers[nib]) % modulus
-
- #TREV - Added support for negative exponents
- if negativeResult:
- prodInv = invMod(prod, modulus)
- #Check to make sure the inverse is correct
- if (prod * prodInv) % modulus != 1:
- raise AssertionError()
- return prodInv
- return prod
-
-
-#Pre-calculate a sieve of the ~100 primes < 1000:
-def makeSieve(n):
- sieve = range(n)
- for count in range(2, int(math.sqrt(n))):
- if sieve[count] == 0:
- continue
- x = sieve[count] * 2
- while x < len(sieve):
- sieve[x] = 0
- x += sieve[count]
- sieve = [x for x in sieve[2:] if x]
- return sieve
-
-sieve = makeSieve(1000)
-
-def isPrime(n, iterations=5, display=False):
- #Trial division with sieve
- for x in sieve:
- if x >= n: return True
- if n % x == 0: return False
- #Passed trial division, proceed to Rabin-Miller
- #Rabin-Miller implemented per Ferguson & Schneier
- #Compute s, t for Rabin-Miller
- if display: print "*",
- s, t = n-1, 0
- while s % 2 == 0:
- s, t = s/2, t+1
- #Repeat Rabin-Miller x times
- a = 2 #Use 2 as a base for first iteration speedup, per HAC
- for count in range(iterations):
- v = powMod(a, s, n)
- if v==1:
- continue
- i = 0
- while v != n-1:
- if i == t-1:
- return False
- else:
- v, i = powMod(v, 2, n), i+1
- a = getRandomNumber(2, n)
- return True
-
-def getRandomPrime(bits, display=False):
- if bits < 10:
- raise AssertionError()
- #The 1.5 ensures the 2 MSBs are set
- #Thus, when used for p,q in RSA, n will have its MSB set
- #
- #Since 30 is lcm(2,3,5), we'll set our test numbers to
- #29 % 30 and keep them there
- low = (2L ** (bits-1)) * 3/2
- high = 2L ** bits - 30
- p = getRandomNumber(low, high)
- p += 29 - (p % 30)
- while 1:
- if display: print ".",
- p += 30
- if p >= high:
- p = getRandomNumber(low, high)
- p += 29 - (p % 30)
- if isPrime(p, display=display):
- return p
-
-#Unused at the moment...
-def getRandomSafePrime(bits, display=False):
- if bits < 10:
- raise AssertionError()
- #The 1.5 ensures the 2 MSBs are set
- #Thus, when used for p,q in RSA, n will have its MSB set
- #
- #Since 30 is lcm(2,3,5), we'll set our test numbers to
- #29 % 30 and keep them there
- low = (2 ** (bits-2)) * 3/2
- high = (2 ** (bits-1)) - 30
- q = getRandomNumber(low, high)
- q += 29 - (q % 30)
- while 1:
- if display: print ".",
- q += 30
- if (q >= high):
- q = getRandomNumber(low, high)
- q += 29 - (q % 30)
- #Ideas from Tom Wu's SRP code
- #Do trial division on p and q before Rabin-Miller
- if isPrime(q, 0, display=display):
- p = (2 * q) + 1
- if isPrime(p, display=display):
- if isPrime(q, display=display):
- return p
diff --git a/src/lib/tlslite/utils/dateFuncs.py b/src/lib/tlslite/utils/dateFuncs.py
deleted file mode 100755
index 38812ebf8..000000000
--- a/src/lib/tlslite/utils/dateFuncs.py
+++ /dev/null
@@ -1,75 +0,0 @@
-
-import os
-
-#Functions for manipulating datetime objects
-#CCYY-MM-DDThh:mm:ssZ
-def parseDateClass(s):
- year, month, day = s.split("-")
- day, tail = day[:2], day[2:]
- hour, minute, second = tail[1:].split(":")
- second = second[:2]
- year, month, day = int(year), int(month), int(day)
- hour, minute, second = int(hour), int(minute), int(second)
- return createDateClass(year, month, day, hour, minute, second)
-
-
-if os.name != "java":
- from datetime import datetime, timedelta
-
- #Helper functions for working with a date/time class
- def createDateClass(year, month, day, hour, minute, second):
- return datetime(year, month, day, hour, minute, second)
-
- def printDateClass(d):
- #Split off fractional seconds, append 'Z'
- return d.isoformat().split(".")[0]+"Z"
-
- def getNow():
- return datetime.utcnow()
-
- def getHoursFromNow(hours):
- return datetime.utcnow() + timedelta(hours=hours)
-
- def getMinutesFromNow(minutes):
- return datetime.utcnow() + timedelta(minutes=minutes)
-
- def isDateClassExpired(d):
- return d < datetime.utcnow()
-
- def isDateClassBefore(d1, d2):
- return d1 < d2
-
-else:
- #Jython 2.1 is missing lots of python 2.3 stuff,
- #which we have to emulate here:
- import java
- import jarray
-
- def createDateClass(year, month, day, hour, minute, second):
- c = java.util.Calendar.getInstance()
- c.setTimeZone(java.util.TimeZone.getTimeZone("UTC"))
- c.set(year, month-1, day, hour, minute, second)
- return c
-
- def printDateClass(d):
- return "%04d-%02d-%02dT%02d:%02d:%02dZ" % \
- (d.get(d.YEAR), d.get(d.MONTH)+1, d.get(d.DATE), \
- d.get(d.HOUR_OF_DAY), d.get(d.MINUTE), d.get(d.SECOND))
-
- def getNow():
- c = java.util.Calendar.getInstance()
- c.setTimeZone(java.util.TimeZone.getTimeZone("UTC"))
- c.get(c.HOUR) #force refresh?
- return c
-
- def getHoursFromNow(hours):
- d = getNow()
- d.add(d.HOUR, hours)
- return d
-
- def isDateClassExpired(d):
- n = getNow()
- return d.before(n)
-
- def isDateClassBefore(d1, d2):
- return d1.before(d2)
diff --git a/src/lib/tlslite/utils/entropy.c b/src/lib/tlslite/utils/entropy.c
deleted file mode 100755
index c627794d2..000000000
--- a/src/lib/tlslite/utils/entropy.c
+++ /dev/null
@@ -1,173 +0,0 @@
-
-#include "Python.h"
-
-
-#ifdef MS_WINDOWS
-
-/* The following #define is not needed on VC6 with the Platform SDK, and it
-may not be needed on VC7, I'm not sure. I don't think it hurts anything.*/
-#define _WIN32_WINNT 0x0400
-
-#include <windows.h>
-
-
-typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
- LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
- DWORD dwFlags );
-typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
- BYTE *pbBuffer );
-typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv,\
- DWORD dwFlags);
-
-
-static PyObject* entropy(PyObject *self, PyObject *args)
-{
- int howMany = 0;
- HINSTANCE hAdvAPI32 = NULL;
- CRYPTACQUIRECONTEXTA pCryptAcquireContextA = NULL;
- CRYPTGENRANDOM pCryptGenRandom = NULL;
- CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;
- HCRYPTPROV hCryptProv = 0;
- unsigned char* bytes = NULL;
- PyObject* returnVal = NULL;
-
-
- /* Read arguments */
- if (!PyArg_ParseTuple(args, "i", &howMany))
- return(NULL);
-
- /* Obtain handle to the DLL containing CryptoAPI
- This should not fail */
- if( (hAdvAPI32 = GetModuleHandle("advapi32.dll")) == NULL) {
- PyErr_Format(PyExc_SystemError,
- "Advapi32.dll not found");
- return NULL;
- }
-
- /* Obtain pointers to the CryptoAPI functions
- This will fail on some early version of Win95 */
- pCryptAcquireContextA = (CRYPTACQUIRECONTEXTA)GetProcAddress(hAdvAPI32,\
- "CryptAcquireContextA");
- pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32,\
- "CryptGenRandom");
- pCryptReleaseContext = (CRYPTRELEASECONTEXT) GetProcAddress(hAdvAPI32,\
- "CryptReleaseContext");
- if (pCryptAcquireContextA == NULL || pCryptGenRandom == NULL ||
- pCryptReleaseContext == NULL) {
- PyErr_Format(PyExc_NotImplementedError,
- "CryptoAPI not available on this version of Windows");
- return NULL;
- }
-
- /* Allocate bytes */
- if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
- return PyErr_NoMemory();
-
-
- /* Acquire context */
- if(!pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT)) {
- PyErr_Format(PyExc_SystemError,
- "CryptAcquireContext failed, error %d", GetLastError());
- PyMem_Free(bytes);
- return NULL;
- }
-
- /* Get random data */
- if(!pCryptGenRandom(hCryptProv, howMany, bytes)) {
- PyErr_Format(PyExc_SystemError,
- "CryptGenRandom failed, error %d", GetLastError());
- PyMem_Free(bytes);
- CryptReleaseContext(hCryptProv, 0);
- return NULL;
- }
-
- /* Build return value */
- returnVal = Py_BuildValue("s#", bytes, howMany);
- PyMem_Free(bytes);
-
- /* Release context */
- if (!pCryptReleaseContext(hCryptProv, 0)) {
- PyErr_Format(PyExc_SystemError,
- "CryptReleaseContext failed, error %d", GetLastError());
- return NULL;
- }
-
- return returnVal;
-}
-
-#elif defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL_H)
-
-#include <unistd.h>
-#include <fcntl.h>
-
-static PyObject* entropy(PyObject *self, PyObject *args)
-{
- int howMany;
- int fd;
- unsigned char* bytes = NULL;
- PyObject* returnVal = NULL;
-
-
- /* Read arguments */
- if (!PyArg_ParseTuple(args, "i", &howMany))
- return(NULL);
-
- /* Allocate bytes */
- if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
- return PyErr_NoMemory();
-
- /* Open device */
- if ((fd = open("/dev/urandom", O_RDONLY, 0)) == -1) {
- PyErr_Format(PyExc_NotImplementedError,
- "No entropy source found");
- PyMem_Free(bytes);
- return NULL;
- }
-
- /* Get random data */
- if (read(fd, bytes, howMany) < howMany) {
- PyErr_Format(PyExc_SystemError,
- "Reading from /dev/urandom failed");
- PyMem_Free(bytes);
- close(fd);
- return NULL;
- }
-
- /* Build return value */
- returnVal = Py_BuildValue("s#", bytes, howMany);
- PyMem_Free(bytes);
-
- /* Close device */
- close(fd);
-
- return returnVal;
-}
-
-#else
-
-static PyObject* entropy(PyObject *self, PyObject *args)
-{
- PyErr_Format(PyExc_NotImplementedError,
- "Function not supported");
- return NULL;
-}
-
-#endif
-
-
-
-/* List of functions exported by this module */
-
-static struct PyMethodDef entropy_functions[] = {
- {"entropy", (PyCFunction)entropy, METH_VARARGS, "Return a string of random bytes produced by a platform-specific\nentropy source."},
- {NULL, NULL} /* Sentinel */
-};
-
-
-/* Initialize this module. */
-
-PyMODINIT_FUNC initentropy(void)
-{
- Py_InitModule("entropy", entropy_functions);
-} \ No newline at end of file
diff --git a/src/lib/tlslite/utils/hmac.py b/src/lib/tlslite/utils/hmac.py
deleted file mode 100755
index fe8feec21..000000000
--- a/src/lib/tlslite/utils/hmac.py
+++ /dev/null
@@ -1,104 +0,0 @@
-"""HMAC (Keyed-Hashing for Message Authentication) Python module.
-
-Implements the HMAC algorithm as described by RFC 2104.
-
-(This file is modified from the standard library version to do faster
-copying)
-"""
-
-def _strxor(s1, s2):
- """Utility method. XOR the two strings s1 and s2 (must have same length).
- """
- return "".join(map(lambda x, y: chr(ord(x) ^ ord(y)), s1, s2))
-
-# The size of the digests returned by HMAC depends on the underlying
-# hashing module used.
-digest_size = None
-
-class HMAC:
- """RFC2104 HMAC class.
-
- This supports the API for Cryptographic Hash Functions (PEP 247).
- """
-
- def __init__(self, key, msg = None, digestmod = None):
- """Create a new HMAC object.
-
- key: key for the keyed hash object.
- msg: Initial input for the hash, if provided.
- digestmod: A module supporting PEP 247. Defaults to the md5 module.
- """
- if digestmod is None:
- import md5
- digestmod = md5
-
- if key == None: #TREVNEW - for faster copying
- return #TREVNEW
-
- self.digestmod = digestmod
- self.outer = digestmod.new()
- self.inner = digestmod.new()
- self.digest_size = digestmod.digest_size
-
- blocksize = 64
- ipad = "\x36" * blocksize
- opad = "\x5C" * blocksize
-
- if len(key) > blocksize:
- key = digestmod.new(key).digest()
-
- key = key + chr(0) * (blocksize - len(key))
- self.outer.update(_strxor(key, opad))
- self.inner.update(_strxor(key, ipad))
- if msg is not None:
- self.update(msg)
-
-## def clear(self):
-## raise NotImplementedError, "clear() method not available in HMAC."
-
- def update(self, msg):
- """Update this hashing object with the string msg.
- """
- self.inner.update(msg)
-
- def copy(self):
- """Return a separate copy of this hashing object.
-
- An update to this copy won't affect the original object.
- """
- other = HMAC(None) #TREVNEW - for faster copying
- other.digest_size = self.digest_size #TREVNEW
- other.digestmod = self.digestmod
- other.inner = self.inner.copy()
- other.outer = self.outer.copy()
- return other
-
- def digest(self):
- """Return the hash value of this hashing object.
-
- This returns a string containing 8-bit data. The object is
- not altered in any way by this function; you can continue
- updating the object after calling this function.
- """
- h = self.outer.copy()
- h.update(self.inner.digest())
- return h.digest()
-
- def hexdigest(self):
- """Like digest(), but returns a string of hexadecimal digits instead.
- """
- return "".join([hex(ord(x))[2:].zfill(2)
- for x in tuple(self.digest())])
-
-def new(key, msg = None, digestmod = None):
- """Create a new hashing object and return it.
-
- key: The starting key for the hash.
- msg: if available, will immediately be hashed into the object's starting
- state.
-
- You can now feed arbitrary strings into the object using its update()
- method, and can ask for the hash value at any time by calling its digest()
- method.
- """
- return HMAC(key, msg, digestmod)
diff --git a/src/lib/tlslite/utils/jython_compat.py b/src/lib/tlslite/utils/jython_compat.py
deleted file mode 100755
index 1245183a9..000000000
--- a/src/lib/tlslite/utils/jython_compat.py
+++ /dev/null
@@ -1,195 +0,0 @@
-"""Miscellaneous functions to mask Python/Jython differences."""
-
-import os
-import sha
-
-if os.name != "java":
- BaseException = Exception
-
- from sets import Set
- import array
- import math
-
- def createByteArraySequence(seq):
- return array.array('B', seq)
- def createByteArrayZeros(howMany):
- return array.array('B', [0] * howMany)
- def concatArrays(a1, a2):
- return a1+a2
-
- def bytesToString(bytes):
- return bytes.tostring()
-
- def stringToBytes(s):
- bytes = createByteArrayZeros(0)
- bytes.fromstring(s)
- return bytes
-
- def numBits(n):
- if n==0:
- return 0
- return int(math.floor(math.log(n, 2))+1)
-
- class CertChainBase: pass
- class SelfTestBase: pass
- class ReportFuncBase: pass
-
- #Helper functions for working with sets (from Python 2.3)
- def iterSet(set):
- return iter(set)
-
- def getListFromSet(set):
- return list(set)
-
- #Factory function for getting a SHA1 object
- def getSHA1(s):
- return sha.sha(s)
-
- import sys
- import traceback
-
- def formatExceptionTrace(e):
- newStr = "".join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
- return newStr
-
-else:
- #Jython 2.1 is missing lots of python 2.3 stuff,
- #which we have to emulate here:
- import java
- import jarray
-
- BaseException = java.lang.Exception
-
- def createByteArraySequence(seq):
- if isinstance(seq, type("")): #If it's a string, convert
- seq = [ord(c) for c in seq]
- return jarray.array(seq, 'h') #use short instead of bytes, cause bytes are signed
- def createByteArrayZeros(howMany):
- return jarray.zeros(howMany, 'h') #use short instead of bytes, cause bytes are signed
- def concatArrays(a1, a2):
- l = list(a1)+list(a2)
- return createByteArraySequence(l)
-
- #WAY TOO SLOW - MUST BE REPLACED------------
- def bytesToString(bytes):
- return "".join([chr(b) for b in bytes])
-
- def stringToBytes(s):
- bytes = createByteArrayZeros(len(s))
- for count, c in enumerate(s):
- bytes[count] = ord(c)
- return bytes
- #WAY TOO SLOW - MUST BE REPLACED------------
-
- def numBits(n):
- if n==0:
- return 0
- n= 1L * n; #convert to long, if it isn't already
- return n.__tojava__(java.math.BigInteger).bitLength()
-
- #This properly creates static methods for Jython
- class staticmethod:
- def __init__(self, anycallable): self.__call__ = anycallable
-
- #Properties are not supported for Jython
- class property:
- def __init__(self, anycallable): pass
-
- #True and False have to be specially defined
- False = 0
- True = 1
-
- class StopIteration(Exception): pass
-
- def enumerate(collection):
- return zip(range(len(collection)), collection)
-
- class Set:
- def __init__(self, seq=None):
- self.values = {}
- if seq:
- for e in seq:
- self.values[e] = None
-
- def add(self, e):
- self.values[e] = None
-
- def discard(self, e):
- if e in self.values.keys():
- del(self.values[e])
-
- def union(self, s):
- ret = Set()
- for e in self.values.keys():
- ret.values[e] = None
- for e in s.values.keys():
- ret.values[e] = None
- return ret
-
- def issubset(self, other):
- for e in self.values.keys():
- if e not in other.values.keys():
- return False
- return True
-
- def __nonzero__( self):
- return len(self.values.keys())
-
- def __contains__(self, e):
- return e in self.values.keys()
-
- def iterSet(set):
- return set.values.keys()
-
- def getListFromSet(set):
- return set.values.keys()
-
- """
- class JCE_SHA1:
- def __init__(self, s=None):
- self.md = java.security.MessageDigest.getInstance("SHA1")
- if s:
- self.update(s)
-
- def update(self, s):
- self.md.update(s)
-
- def copy(self):
- sha1 = JCE_SHA1()
- sha1.md = self.md.clone()
- return sha1
-
- def digest(self):
- digest = self.md.digest()
- bytes = jarray.zeros(20, 'h')
- for count in xrange(20):
- x = digest[count]
- if x < 0: x += 256
- bytes[count] = x
- return bytes
- """
-
- #Factory function for getting a SHA1 object
- #The JCE_SHA1 class is way too slow...
- #the sha.sha object we use instead is broken in the jython 2.1
- #release, and needs to be patched
- def getSHA1(s):
- #return JCE_SHA1(s)
- return sha.sha(s)
-
-
- #Adjust the string to an array of bytes
- def stringToJavaByteArray(s):
- bytes = jarray.zeros(len(s), 'b')
- for count, c in enumerate(s):
- x = ord(c)
- if x >= 128: x -= 256
- bytes[count] = x
- return bytes
-
- import sys
- import traceback
-
- def formatExceptionTrace(e):
- newStr = "".join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
- return newStr
diff --git a/src/lib/tlslite/utils/keyfactory.py b/src/lib/tlslite/utils/keyfactory.py
deleted file mode 100755
index 5005af7f5..000000000
--- a/src/lib/tlslite/utils/keyfactory.py
+++ /dev/null
@@ -1,243 +0,0 @@
-"""Factory functions for asymmetric cryptography.
-@sort: generateRSAKey, parseXMLKey, parsePEMKey, parseAsPublicKey,
-parseAsPrivateKey
-"""
-
-from compat import *
-
-from RSAKey import RSAKey
-from Python_RSAKey import Python_RSAKey
-import cryptomath
-
-if cryptomath.m2cryptoLoaded:
- from OpenSSL_RSAKey import OpenSSL_RSAKey
-
-if cryptomath.pycryptoLoaded:
- from PyCrypto_RSAKey import PyCrypto_RSAKey
-
-# **************************************************************************
-# Factory Functions for RSA Keys
-# **************************************************************************
-
-def generateRSAKey(bits, implementations=["openssl", "python"]):
- """Generate an RSA key with the specified bit length.
-
- @type bits: int
- @param bits: Desired bit length of the new key's modulus.
-
- @rtype: L{tlslite.utils.RSAKey.RSAKey}
- @return: A new RSA private key.
- """
- for implementation in implementations:
- if implementation == "openssl" and cryptomath.m2cryptoLoaded:
- return OpenSSL_RSAKey.generate(bits)
- elif implementation == "python":
- return Python_RSAKey.generate(bits)
- raise ValueError("No acceptable implementations")
-
-def parseXMLKey(s, private=False, public=False, implementations=["python"]):
- """Parse an XML-format key.
-
- The XML format used here is specific to tlslite and cryptoIDlib. The
- format can store the public component of a key, or the public and
- private components. For example::
-
- <publicKey xmlns="http://trevp.net/rsa">
- <n>4a5yzB8oGNlHo866CAspAC47M4Fvx58zwK8pou...
- <e>Aw==</e>
- </publicKey>
-
- <privateKey xmlns="http://trevp.net/rsa">
- <n>4a5yzB8oGNlHo866CAspAC47M4Fvx58zwK8pou...
- <e>Aw==</e>
- <d>JZ0TIgUxWXmL8KJ0VqyG1V0J3ern9pqIoB0xmy...
- <p>5PreIj6z6ldIGL1V4+1C36dQFHNCQHJvW52GXc...
- <q>/E/wDit8YXPCxx126zTq2ilQ3IcW54NJYyNjiZ...
- <dP>mKc+wX8inDowEH45Qp4slRo1YveBgExKPROu6...
- <dQ>qDVKtBz9lk0shL5PR3ickXDgkwS576zbl2ztB...
- <qInv>j6E8EA7dNsTImaXexAmLA1DoeArsYeFAInr...
- </privateKey>
-
- @type s: str
- @param s: A string containing an XML public or private key.
-
- @type private: bool
- @param private: If True, a L{SyntaxError} will be raised if the private
- key component is not present.
-
- @type public: bool
- @param public: If True, the private key component (if present) will be
- discarded, so this function will always return a public key.
-
- @rtype: L{tlslite.utils.RSAKey.RSAKey}
- @return: An RSA key.
-
- @raise SyntaxError: If the key is not properly formatted.
- """
- for implementation in implementations:
- if implementation == "python":
- key = Python_RSAKey.parseXML(s)
- break
- else:
- raise ValueError("No acceptable implementations")
-
- return _parseKeyHelper(key, private, public)
-
-#Parse as an OpenSSL or Python key
-def parsePEMKey(s, private=False, public=False, passwordCallback=None,
- implementations=["openssl", "python"]):
- """Parse a PEM-format key.
-
- The PEM format is used by OpenSSL and other tools. The
- format is typically used to store both the public and private
- components of a key. For example::
-
- -----BEGIN RSA PRIVATE KEY-----
- MIICXQIBAAKBgQDYscuoMzsGmW0pAYsmyHltxB2TdwHS0dImfjCMfaSDkfLdZY5+
- dOWORVns9etWnr194mSGA1F0Pls/VJW8+cX9+3vtJV8zSdANPYUoQf0TP7VlJxkH
- dSRkUbEoz5bAAs/+970uos7n7iXQIni+3erUTdYEk2iWnMBjTljfgbK/dQIDAQAB
- AoGAJHoJZk75aKr7DSQNYIHuruOMdv5ZeDuJvKERWxTrVJqE32/xBKh42/IgqRrc
- esBN9ZregRCd7YtxoL+EVUNWaJNVx2mNmezEznrc9zhcYUrgeaVdFO2yBF1889zO
- gCOVwrO8uDgeyj6IKa25H6c1N13ih/o7ZzEgWbGG+ylU1yECQQDv4ZSJ4EjSh/Fl
- aHdz3wbBa/HKGTjC8iRy476Cyg2Fm8MZUe9Yy3udOrb5ZnS2MTpIXt5AF3h2TfYV
- VoFXIorjAkEA50FcJmzT8sNMrPaV8vn+9W2Lu4U7C+K/O2g1iXMaZms5PC5zV5aV
- CKXZWUX1fq2RaOzlbQrpgiolhXpeh8FjxwJBAOFHzSQfSsTNfttp3KUpU0LbiVvv
- i+spVSnA0O4rq79KpVNmK44Mq67hsW1P11QzrzTAQ6GVaUBRv0YS061td1kCQHnP
- wtN2tboFR6lABkJDjxoGRvlSt4SOPr7zKGgrWjeiuTZLHXSAnCY+/hr5L9Q3ZwXG
- 6x6iBdgLjVIe4BZQNtcCQQDXGv/gWinCNTN3MPWfTW/RGzuMYVmyBFais0/VrgdH
- h1dLpztmpQqfyH/zrBXQ9qL/zR4ojS6XYneO/U18WpEe
- -----END RSA PRIVATE KEY-----
-
- To generate a key like this with OpenSSL, run::
-
- openssl genrsa 2048 > key.pem
-
- This format also supports password-encrypted private keys. TLS
- Lite can only handle password-encrypted private keys when OpenSSL
- and M2Crypto are installed. In this case, passwordCallback will be
- invoked to query the user for the password.
-
- @type s: str
- @param s: A string containing a PEM-encoded public or private key.
-
- @type private: bool
- @param private: If True, a L{SyntaxError} will be raised if the
- private key component is not present.
-
- @type public: bool
- @param public: If True, the private key component (if present) will
- be discarded, so this function will always return a public key.
-
- @type passwordCallback: callable
- @param passwordCallback: This function will be called, with no
- arguments, if the PEM-encoded private key is password-encrypted.
- The callback should return the password string. If the password is
- incorrect, SyntaxError will be raised. If no callback is passed
- and the key is password-encrypted, a prompt will be displayed at
- the console.
-
- @rtype: L{tlslite.utils.RSAKey.RSAKey}
- @return: An RSA key.
-
- @raise SyntaxError: If the key is not properly formatted.
- """
- for implementation in implementations:
- if implementation == "openssl" and cryptomath.m2cryptoLoaded:
- key = OpenSSL_RSAKey.parse(s, passwordCallback)
- break
- elif implementation == "python":
- key = Python_RSAKey.parsePEM(s)
- break
- else:
- raise ValueError("No acceptable implementations")
-
- return _parseKeyHelper(key, private, public)
-
-
-def _parseKeyHelper(key, private, public):
- if private:
- if not key.hasPrivateKey():
- raise SyntaxError("Not a private key!")
-
- if public:
- return _createPublicKey(key)
-
- if private:
- if hasattr(key, "d"):
- return _createPrivateKey(key)
- else:
- return key
-
- return key
-
-def parseAsPublicKey(s):
- """Parse an XML or PEM-formatted public key.
-
- @type s: str
- @param s: A string containing an XML or PEM-encoded public or private key.
-
- @rtype: L{tlslite.utils.RSAKey.RSAKey}
- @return: An RSA public key.
-
- @raise SyntaxError: If the key is not properly formatted.
- """
- try:
- return parsePEMKey(s, public=True)
- except:
- return parseXMLKey(s, public=True)
-
-def parsePrivateKey(s):
- """Parse an XML or PEM-formatted private key.
-
- @type s: str
- @param s: A string containing an XML or PEM-encoded private key.
-
- @rtype: L{tlslite.utils.RSAKey.RSAKey}
- @return: An RSA private key.
-
- @raise SyntaxError: If the key is not properly formatted.
- """
- try:
- return parsePEMKey(s, private=True)
- except:
- return parseXMLKey(s, private=True)
-
-def _createPublicKey(key):
- """
- Create a new public key. Discard any private component,
- and return the most efficient key possible.
- """
- if not isinstance(key, RSAKey):
- raise AssertionError()
- return _createPublicRSAKey(key.n, key.e)
-
-def _createPrivateKey(key):
- """
- Create a new private key. Return the most efficient key possible.
- """
- if not isinstance(key, RSAKey):
- raise AssertionError()
- if not key.hasPrivateKey():
- raise AssertionError()
- return _createPrivateRSAKey(key.n, key.e, key.d, key.p, key.q, key.dP,
- key.dQ, key.qInv)
-
-def _createPublicRSAKey(n, e, implementations = ["openssl", "pycrypto",
- "python"]):
- for implementation in implementations:
- if implementation == "openssl" and cryptomath.m2cryptoLoaded:
- return OpenSSL_RSAKey(n, e)
- elif implementation == "pycrypto" and cryptomath.pycryptoLoaded:
- return PyCrypto_RSAKey(n, e)
- elif implementation == "python":
- return Python_RSAKey(n, e)
- raise ValueError("No acceptable implementations")
-
-def _createPrivateRSAKey(n, e, d, p, q, dP, dQ, qInv,
- implementations = ["pycrypto", "python"]):
- for implementation in implementations:
- if implementation == "pycrypto" and cryptomath.pycryptoLoaded:
- return PyCrypto_RSAKey(n, e, d, p, q, dP, dQ, qInv)
- elif implementation == "python":
- return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv)
- raise ValueError("No acceptable implementations")
diff --git a/src/lib/tlslite/utils/prngd.py b/src/lib/tlslite/utils/prngd.py
deleted file mode 100644
index c86b7046a..000000000
--- a/src/lib/tlslite/utils/prngd.py
+++ /dev/null
@@ -1,62 +0,0 @@
-"""prngd module
-
-This module interfaces with PRNGD - Pseudo Random Number Generator
-Daemon for platforms without /dev/random or /dev/urandom.
-
-It is based on code from Stuart D. Gathman stuart at bmsi.com and is
-Public Domain. The original code is available from
-http://mail.python.org/pipermail/python-list/2002-November/170737.html"""
-
-import socket
-from struct import unpack,pack
-
-class PRNGD:
- "Provide access to the Portable Random Number Generator Daemon"
-
- def __init__(self,sockname="/var/run/egd-pool"):
- self.randfile = socket.socket(socket.AF_UNIX,socket.SOCK_STREAM)
- self.randfile.connect(sockname)
-
- def _readall(self,n):
- s = self.randfile.recv(n)
- while len(s) < n:
- s = s + self.randfile.recv(n - len(s))
- return s
-
- def get(self):
- "Return number of available bytes of entropy."
- self.randfile.sendall('\x00')
- return unpack(">i",self._readall(4))[0]
-
- def read(self,cnt):
- "Return available entropy, up to cnt bytes."
- if cnt > 255: cnt = 255
- self.randfile.sendall(pack("BB",0x01,cnt))
- buf = self._readall(1)
- assert len(buf) == 1
- count = unpack("B",buf)[0]
- buf = self._readall(count)
- assert len(buf) == count, "didn't get all the entropy"
- return buf
-
- def readall(self,cnt):
- "Return all entropy bytes requested"
- if cnt < 256:
- self.randfile.sendall(pack("BB",0x02,cnt))
- return self._readall(cnt)
- buf = readall(self,255)
- cnt -= len(buf)
- while cnt > 255:
- buf += readall(self,255)
- cnt -= len(buf)
- return buf + readall(self,cnt)
-
- def getpid(self):
- "Return the process id string of the prngd"
- self.randfile.sendall('\x04')
- buf = self._readall(1)
- assert len(buf) == 1
- count = unpack("B",buf)[0]
- buf = self._readall(count)
- assert len(buf) == count, "didn't get whole PID string"
- return buf
diff --git a/src/lib/tlslite/utils/rijndael.py b/src/lib/tlslite/utils/rijndael.py
deleted file mode 100755
index cb2f54734..000000000
--- a/src/lib/tlslite/utils/rijndael.py
+++ /dev/null
@@ -1,392 +0,0 @@
-"""
-A pure python (slow) implementation of rijndael with a decent interface
-
-To include -
-
-from rijndael import rijndael
-
-To do a key setup -
-
-r = rijndael(key, block_size = 16)
-
-key must be a string of length 16, 24, or 32
-blocksize must be 16, 24, or 32. Default is 16
-
-To use -
-
-ciphertext = r.encrypt(plaintext)
-plaintext = r.decrypt(ciphertext)
-
-If any strings are of the wrong length a ValueError is thrown
-"""
-
-# ported from the Java reference code by Bram Cohen, bram@gawth.com, April 2001
-# this code is public domain, unless someone makes
-# an intellectual property claim against the reference
-# code, in which case it can be made public domain by
-# deleting all the comments and renaming all the variables
-
-import copy
-import string
-
-
-
-#-----------------------
-#TREV - ADDED BECAUSE THERE'S WARNINGS ABOUT INT OVERFLOW BEHAVIOR CHANGING IN
-#2.4.....
-import os
-if os.name != "java":
- import exceptions
- if hasattr(exceptions, "FutureWarning"):
- import warnings
- warnings.filterwarnings("ignore", category=FutureWarning, append=1)
-#-----------------------
-
-
-
-shifts = [[[0, 0], [1, 3], [2, 2], [3, 1]],
- [[0, 0], [1, 5], [2, 4], [3, 3]],
- [[0, 0], [1, 7], [3, 5], [4, 4]]]
-
-# [keysize][block_size]
-num_rounds = {16: {16: 10, 24: 12, 32: 14}, 24: {16: 12, 24: 12, 32: 14}, 32: {16: 14, 24: 14, 32: 14}}
-
-A = [[1, 1, 1, 1, 1, 0, 0, 0],
- [0, 1, 1, 1, 1, 1, 0, 0],
- [0, 0, 1, 1, 1, 1, 1, 0],
- [0, 0, 0, 1, 1, 1, 1, 1],
- [1, 0, 0, 0, 1, 1, 1, 1],
- [1, 1, 0, 0, 0, 1, 1, 1],
- [1, 1, 1, 0, 0, 0, 1, 1],
- [1, 1, 1, 1, 0, 0, 0, 1]]
-
-# produce log and alog tables, needed for multiplying in the
-# field GF(2^m) (generator = 3)
-alog = [1]
-for i in xrange(255):
- j = (alog[-1] << 1) ^ alog[-1]
- if j & 0x100 != 0:
- j ^= 0x11B
- alog.append(j)
-
-log = [0] * 256
-for i in xrange(1, 255):
- log[alog[i]] = i
-
-# multiply two elements of GF(2^m)
-def mul(a, b):
- if a == 0 or b == 0:
- return 0
- return alog[(log[a & 0xFF] + log[b & 0xFF]) % 255]
-
-# substitution box based on F^{-1}(x)
-box = [[0] * 8 for i in xrange(256)]
-box[1][7] = 1
-for i in xrange(2, 256):
- j = alog[255 - log[i]]
- for t in xrange(8):
- box[i][t] = (j >> (7 - t)) & 0x01
-
-B = [0, 1, 1, 0, 0, 0, 1, 1]
-
-# affine transform: box[i] <- B + A*box[i]
-cox = [[0] * 8 for i in xrange(256)]
-for i in xrange(256):
- for t in xrange(8):
- cox[i][t] = B[t]
- for j in xrange(8):
- cox[i][t] ^= A[t][j] * box[i][j]
-
-# S-boxes and inverse S-boxes
-S = [0] * 256
-Si = [0] * 256
-for i in xrange(256):
- S[i] = cox[i][0] << 7
- for t in xrange(1, 8):
- S[i] ^= cox[i][t] << (7-t)
- Si[S[i] & 0xFF] = i
-
-# T-boxes
-G = [[2, 1, 1, 3],
- [3, 2, 1, 1],
- [1, 3, 2, 1],
- [1, 1, 3, 2]]
-
-AA = [[0] * 8 for i in xrange(4)]
-
-for i in xrange(4):
- for j in xrange(4):
- AA[i][j] = G[i][j]
- AA[i][i+4] = 1
-
-for i in xrange(4):
- pivot = AA[i][i]
- if pivot == 0:
- t = i + 1
- while AA[t][i] == 0 and t < 4:
- t += 1
- assert t != 4, 'G matrix must be invertible'
- for j in xrange(8):
- AA[i][j], AA[t][j] = AA[t][j], AA[i][j]
- pivot = AA[i][i]
- for j in xrange(8):
- if AA[i][j] != 0:
- AA[i][j] = alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) % 255]
- for t in xrange(4):
- if i != t:
- for j in xrange(i+1, 8):
- AA[t][j] ^= mul(AA[i][j], AA[t][i])
- AA[t][i] = 0
-
-iG = [[0] * 4 for i in xrange(4)]
-
-for i in xrange(4):
- for j in xrange(4):
- iG[i][j] = AA[i][j + 4]
-
-def mul4(a, bs):
- if a == 0:
- return 0
- r = 0
- for b in bs:
- r <<= 8
- if b != 0:
- r = r | mul(a, b)
- return r
-
-T1 = []
-T2 = []
-T3 = []
-T4 = []
-T5 = []
-T6 = []
-T7 = []
-T8 = []
-U1 = []
-U2 = []
-U3 = []
-U4 = []
-
-for t in xrange(256):
- s = S[t]
- T1.append(mul4(s, G[0]))
- T2.append(mul4(s, G[1]))
- T3.append(mul4(s, G[2]))
- T4.append(mul4(s, G[3]))
-
- s = Si[t]
- T5.append(mul4(s, iG[0]))
- T6.append(mul4(s, iG[1]))
- T7.append(mul4(s, iG[2]))
- T8.append(mul4(s, iG[3]))
-
- U1.append(mul4(t, iG[0]))
- U2.append(mul4(t, iG[1]))
- U3.append(mul4(t, iG[2]))
- U4.append(mul4(t, iG[3]))
-
-# round constants
-rcon = [1]
-r = 1
-for t in xrange(1, 30):
- r = mul(2, r)
- rcon.append(r)
-
-del A
-del AA
-del pivot
-del B
-del G
-del box
-del log
-del alog
-del i
-del j
-del r
-del s
-del t
-del mul
-del mul4
-del cox
-del iG
-
-class rijndael:
- def __init__(self, key, block_size = 16):
- if block_size != 16 and block_size != 24 and block_size != 32:
- raise ValueError('Invalid block size: ' + str(block_size))
- if len(key) != 16 and len(key) != 24 and len(key) != 32:
- raise ValueError('Invalid key size: ' + str(len(key)))
- self.block_size = block_size
-
- ROUNDS = num_rounds[len(key)][block_size]
- BC = block_size / 4
- # encryption round keys
- Ke = [[0] * BC for i in xrange(ROUNDS + 1)]
- # decryption round keys
- Kd = [[0] * BC for i in xrange(ROUNDS + 1)]
- ROUND_KEY_COUNT = (ROUNDS + 1) * BC
- KC = len(key) / 4
-
- # copy user material bytes into temporary ints
- tk = []
- for i in xrange(0, KC):
- tk.append((ord(key[i * 4]) << 24) | (ord(key[i * 4 + 1]) << 16) |
- (ord(key[i * 4 + 2]) << 8) | ord(key[i * 4 + 3]))
-
- # copy values into round key arrays
- t = 0
- j = 0
- while j < KC and t < ROUND_KEY_COUNT:
- Ke[t / BC][t % BC] = tk[j]
- Kd[ROUNDS - (t / BC)][t % BC] = tk[j]
- j += 1
- t += 1
- tt = 0
- rconpointer = 0
- while t < ROUND_KEY_COUNT:
- # extrapolate using phi (the round key evolution function)
- tt = tk[KC - 1]
- tk[0] ^= (S[(tt >> 16) & 0xFF] & 0xFF) << 24 ^ \
- (S[(tt >> 8) & 0xFF] & 0xFF) << 16 ^ \
- (S[ tt & 0xFF] & 0xFF) << 8 ^ \
- (S[(tt >> 24) & 0xFF] & 0xFF) ^ \
- (rcon[rconpointer] & 0xFF) << 24
- rconpointer += 1
- if KC != 8:
- for i in xrange(1, KC):
- tk[i] ^= tk[i-1]
- else:
- for i in xrange(1, KC / 2):
- tk[i] ^= tk[i-1]
- tt = tk[KC / 2 - 1]
- tk[KC / 2] ^= (S[ tt & 0xFF] & 0xFF) ^ \
- (S[(tt >> 8) & 0xFF] & 0xFF) << 8 ^ \
- (S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^ \
- (S[(tt >> 24) & 0xFF] & 0xFF) << 24
- for i in xrange(KC / 2 + 1, KC):
- tk[i] ^= tk[i-1]
- # copy values into round key arrays
- j = 0
- while j < KC and t < ROUND_KEY_COUNT:
- Ke[t / BC][t % BC] = tk[j]
- Kd[ROUNDS - (t / BC)][t % BC] = tk[j]
- j += 1
- t += 1
- # inverse MixColumn where needed
- for r in xrange(1, ROUNDS):
- for j in xrange(BC):
- tt = Kd[r][j]
- Kd[r][j] = U1[(tt >> 24) & 0xFF] ^ \
- U2[(tt >> 16) & 0xFF] ^ \
- U3[(tt >> 8) & 0xFF] ^ \
- U4[ tt & 0xFF]
- self.Ke = Ke
- self.Kd = Kd
-
- def encrypt(self, plaintext):
- if len(plaintext) != self.block_size:
- raise ValueError('wrong block length, expected ' + str(self.block_size) + ' got ' + str(len(plaintext)))
- Ke = self.Ke
-
- BC = self.block_size / 4
- ROUNDS = len(Ke) - 1
- if BC == 4:
- SC = 0
- elif BC == 6:
- SC = 1
- else:
- SC = 2
- s1 = shifts[SC][1][0]
- s2 = shifts[SC][2][0]
- s3 = shifts[SC][3][0]
- a = [0] * BC
- # temporary work array
- t = []
- # plaintext to ints + key
- for i in xrange(BC):
- t.append((ord(plaintext[i * 4 ]) << 24 |
- ord(plaintext[i * 4 + 1]) << 16 |
- ord(plaintext[i * 4 + 2]) << 8 |
- ord(plaintext[i * 4 + 3]) ) ^ Ke[0][i])
- # apply round transforms
- for r in xrange(1, ROUNDS):
- for i in xrange(BC):
- a[i] = (T1[(t[ i ] >> 24) & 0xFF] ^
- T2[(t[(i + s1) % BC] >> 16) & 0xFF] ^
- T3[(t[(i + s2) % BC] >> 8) & 0xFF] ^
- T4[ t[(i + s3) % BC] & 0xFF] ) ^ Ke[r][i]
- t = copy.copy(a)
- # last round is special
- result = []
- for i in xrange(BC):
- tt = Ke[ROUNDS][i]
- result.append((S[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
- result.append((S[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
- result.append((S[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
- result.append((S[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF)
- return string.join(map(chr, result), '')
-
- def decrypt(self, ciphertext):
- if len(ciphertext) != self.block_size:
- raise ValueError('wrong block length, expected ' + str(self.block_size) + ' got ' + str(len(plaintext)))
- Kd = self.Kd
-
- BC = self.block_size / 4
- ROUNDS = len(Kd) - 1
- if BC == 4:
- SC = 0
- elif BC == 6:
- SC = 1
- else:
- SC = 2
- s1 = shifts[SC][1][1]
- s2 = shifts[SC][2][1]
- s3 = shifts[SC][3][1]
- a = [0] * BC
- # temporary work array
- t = [0] * BC
- # ciphertext to ints + key
- for i in xrange(BC):
- t[i] = (ord(ciphertext[i * 4 ]) << 24 |
- ord(ciphertext[i * 4 + 1]) << 16 |
- ord(ciphertext[i * 4 + 2]) << 8 |
- ord(ciphertext[i * 4 + 3]) ) ^ Kd[0][i]
- # apply round transforms
- for r in xrange(1, ROUNDS):
- for i in xrange(BC):
- a[i] = (T5[(t[ i ] >> 24) & 0xFF] ^
- T6[(t[(i + s1) % BC] >> 16) & 0xFF] ^
- T7[(t[(i + s2) % BC] >> 8) & 0xFF] ^
- T8[ t[(i + s3) % BC] & 0xFF] ) ^ Kd[r][i]
- t = copy.copy(a)
- # last round is special
- result = []
- for i in xrange(BC):
- tt = Kd[ROUNDS][i]
- result.append((Si[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
- result.append((Si[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
- result.append((Si[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
- result.append((Si[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF)
- return string.join(map(chr, result), '')
-
-def encrypt(key, block):
- return rijndael(key, len(block)).encrypt(block)
-
-def decrypt(key, block):
- return rijndael(key, len(block)).decrypt(block)
-
-def test():
- def t(kl, bl):
- b = 'b' * bl
- r = rijndael('a' * kl, bl)
- assert r.decrypt(r.encrypt(b)) == b
- t(16, 16)
- t(16, 24)
- t(16, 32)
- t(24, 16)
- t(24, 24)
- t(24, 32)
- t(32, 16)
- t(32, 24)
- t(32, 32)
-
diff --git a/src/lib/tlslite/utils/win32prng.c b/src/lib/tlslite/utils/win32prng.c
deleted file mode 100755
index de08b3b3b..000000000
--- a/src/lib/tlslite/utils/win32prng.c
+++ /dev/null
@@ -1,63 +0,0 @@
-
-#include "Python.h"
-#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
-#include <windows.h>
-
-
-static PyObject* getRandomBytes(PyObject *self, PyObject *args)
-{
- int howMany;
- HCRYPTPROV hCryptProv;
- unsigned char* bytes = NULL;
- PyObject* returnVal = NULL;
-
-
- /* Read Arguments */
- if (!PyArg_ParseTuple(args, "i", &howMany))
- return(NULL);
-
- /* Get Context */
- if(CryptAcquireContext(
- &hCryptProv,
- NULL,
- NULL,
- PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT) == 0)
- return Py_BuildValue("s#", NULL, 0);
-
-
- /* Allocate bytes */
- bytes = malloc(howMany);
-
-
- /* Get random data */
- if(CryptGenRandom(
- hCryptProv,
- howMany,
- bytes) == 0)
- returnVal = Py_BuildValue("s#", NULL, 0);
- else
- returnVal = Py_BuildValue("s#", bytes, howMany);
-
- free(bytes);
- CryptReleaseContext(hCryptProv, 0);
-
- return returnVal;
-}
-
-
-
-/* List of functions exported by this module */
-
-static struct PyMethodDef win32prng_functions[] = {
- {"getRandomBytes", (PyCFunction)getRandomBytes, METH_VARARGS},
- {NULL, NULL} /* Sentinel */
-};
-
-
-/* Initialize this module. */
-
-DL_EXPORT(void) initwin32prng(void)
-{
- Py_InitModule("win32prng", win32prng_functions);
-}
diff --git a/src/lib/tlslite/utils/xmltools.py b/src/lib/tlslite/utils/xmltools.py
deleted file mode 100755
index 06f2e4307..000000000
--- a/src/lib/tlslite/utils/xmltools.py
+++ /dev/null
@@ -1,201 +0,0 @@
-"""Helper functions for XML.
-
-This module has misc. helper functions for working with XML DOM nodes."""
-
-import re
-from compat import *
-
-import os
-if os.name != "java":
- from xml.dom import minidom
- from xml.sax import saxutils
-
- def parseDocument(s):
- return minidom.parseString(s)
-else:
- from javax.xml.parsers import *
- import java
-
- builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
-
- def parseDocument(s):
- stream = java.io.ByteArrayInputStream(java.lang.String(s).getBytes())
- return builder.parse(stream)
-
-def parseAndStripWhitespace(s):
- try:
- element = parseDocument(s).documentElement
- except BaseException, e:
- raise SyntaxError(str(e))
- stripWhitespace(element)
- return element
-
-#Goes through a DOM tree and removes whitespace besides child elements,
-#as long as this whitespace is correctly tab-ified
-def stripWhitespace(element, tab=0):
- element.normalize()
-
- lastSpacer = "\n" + ("\t"*tab)
- spacer = lastSpacer + "\t"
-
- #Zero children aren't allowed (i.e. <empty/>)
- #This makes writing output simpler, and matches Canonical XML
- if element.childNodes.length==0: #DON'T DO len(element.childNodes) - doesn't work in Jython
- raise SyntaxError("Empty XML elements not allowed")
-
- #If there's a single child, it must be text context
- if element.childNodes.length==1:
- if element.firstChild.nodeType == element.firstChild.TEXT_NODE:
- #If it's an empty element, remove
- if element.firstChild.data == lastSpacer:
- element.removeChild(element.firstChild)
- return
- #If not text content, give an error
- elif element.firstChild.nodeType == element.firstChild.ELEMENT_NODE:
- raise SyntaxError("Bad whitespace under '%s'" % element.tagName)
- else:
- raise SyntaxError("Unexpected node type in XML document")
-
- #Otherwise there's multiple child element
- child = element.firstChild
- while child:
- if child.nodeType == child.ELEMENT_NODE:
- stripWhitespace(child, tab+1)
- child = child.nextSibling
- elif child.nodeType == child.TEXT_NODE:
- if child == element.lastChild:
- if child.data != lastSpacer:
- raise SyntaxError("Bad whitespace under '%s'" % element.tagName)
- elif child.data != spacer:
- raise SyntaxError("Bad whitespace under '%s'" % element.tagName)
- next = child.nextSibling
- element.removeChild(child)
- child = next
- else:
- raise SyntaxError("Unexpected node type in XML document")
-
-
-def checkName(element, name):
- if element.nodeType != element.ELEMENT_NODE:
- raise SyntaxError("Missing element: '%s'" % name)
-
- if name == None:
- return
-
- if element.tagName != name:
- raise SyntaxError("Wrong element name: should be '%s', is '%s'" % (name, element.tagName))
-
-def getChild(element, index, name=None):
- if element.nodeType != element.ELEMENT_NODE:
- raise SyntaxError("Wrong node type in getChild()")
-
- child = element.childNodes.item(index)
- if child == None:
- raise SyntaxError("Missing child: '%s'" % name)
- checkName(child, name)
- return child
-
-def getChildIter(element, index):
- class ChildIter:
- def __init__(self, element, index):
- self.element = element
- self.index = index
-
- def next(self):
- if self.index < len(self.element.childNodes):
- retVal = self.element.childNodes.item(self.index)
- self.index += 1
- else:
- retVal = None
- return retVal
-
- def checkEnd(self):
- if self.index != len(self.element.childNodes):
- raise SyntaxError("Too many elements under: '%s'" % self.element.tagName)
- return ChildIter(element, index)
-
-def getChildOrNone(element, index):
- if element.nodeType != element.ELEMENT_NODE:
- raise SyntaxError("Wrong node type in getChild()")
- child = element.childNodes.item(index)
- return child
-
-def getLastChild(element, index, name=None):
- if element.nodeType != element.ELEMENT_NODE:
- raise SyntaxError("Wrong node type in getLastChild()")
-
- child = element.childNodes.item(index)
- if child == None:
- raise SyntaxError("Missing child: '%s'" % name)
- if child != element.lastChild:
- raise SyntaxError("Too many elements under: '%s'" % element.tagName)
- checkName(child, name)
- return child
-
-#Regular expressions for syntax-checking attribute and element content
-nsRegEx = "http://trevp.net/cryptoID\Z"
-cryptoIDRegEx = "([a-km-z3-9]{5}\.){3}[a-km-z3-9]{5}\Z"
-urlRegEx = "http(s)?://.{1,100}\Z"
-sha1Base64RegEx = "[A-Za-z0-9+/]{27}=\Z"
-base64RegEx = "[A-Za-z0-9+/]+={0,4}\Z"
-certsListRegEx = "(0)?(1)?(2)?(3)?(4)?(5)?(6)?(7)?(8)?(9)?\Z"
-keyRegEx = "[A-Z]\Z"
-keysListRegEx = "(A)?(B)?(C)?(D)?(E)?(F)?(G)?(H)?(I)?(J)?(K)?(L)?(M)?(N)?(O)?(P)?(Q)?(R)?(S)?(T)?(U)?(V)?(W)?(X)?(Y)?(Z)?\Z"
-dateTimeRegEx = "\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ\Z"
-shortStringRegEx = ".{1,100}\Z"
-exprRegEx = "[a-zA-Z0-9 ,()]{1,200}\Z"
-notAfterDeltaRegEx = "0|([1-9][0-9]{0,8})\Z" #A number from 0 to (1 billion)-1
-booleanRegEx = "(true)|(false)"
-
-def getReqAttribute(element, attrName, regEx=""):
- if element.nodeType != element.ELEMENT_NODE:
- raise SyntaxError("Wrong node type in getReqAttribute()")
-
- value = element.getAttribute(attrName)
- if not value:
- raise SyntaxError("Missing Attribute: " + attrName)
- if not re.match(regEx, value):
- raise SyntaxError("Bad Attribute Value for '%s': '%s' " % (attrName, value))
- element.removeAttribute(attrName)
- return str(value) #de-unicode it; this is needed for bsddb, for example
-
-def getAttribute(element, attrName, regEx=""):
- if element.nodeType != element.ELEMENT_NODE:
- raise SyntaxError("Wrong node type in getAttribute()")
-
- value = element.getAttribute(attrName)
- if value:
- if not re.match(regEx, value):
- raise SyntaxError("Bad Attribute Value for '%s': '%s' " % (attrName, value))
- element.removeAttribute(attrName)
- return str(value) #de-unicode it; this is needed for bsddb, for example
-
-def checkNoMoreAttributes(element):
- if element.nodeType != element.ELEMENT_NODE:
- raise SyntaxError("Wrong node type in checkNoMoreAttributes()")
-
- if element.attributes.length!=0:
- raise SyntaxError("Extra attributes on '%s'" % element.tagName)
-
-def getText(element, regEx=""):
- textNode = element.firstChild
- if textNode == None:
- raise SyntaxError("Empty element '%s'" % element.tagName)
- if textNode.nodeType != textNode.TEXT_NODE:
- raise SyntaxError("Non-text node: '%s'" % element.tagName)
- if not re.match(regEx, textNode.data):
- raise SyntaxError("Bad Text Value for '%s': '%s' " % (element.tagName, textNode.data))
- return str(textNode.data) #de-unicode it; this is needed for bsddb, for example
-
-#Function for adding tabs to a string
-def indent(s, steps, ch="\t"):
- tabs = ch*steps
- if s[-1] != "\n":
- s = tabs + s.replace("\n", "\n"+tabs)
- else:
- s = tabs + s.replace("\n", "\n"+tabs)
- s = s[ : -len(tabs)]
- return s
-
-def escape(s):
- return saxutils.escape(s)