Ticket #302: ssl.2.patch

File ssl.2.patch, 3.7 KB (added by jknight, 19 years ago)
  • ssl.py

    RCS file: /cvs/Twisted/twisted/internet/ssl.py,v
    retrieving revision 1.44
    diff -u -r1.44 ssl.py
     
    4545
    4646# System imports
    4747from OpenSSL import SSL
     48import md5
    4849import socket
    4950
     51# Hack! This should be in the python SSL interface, *but isn't*.
     52# (grumblegrumble)
     53SSL_OP_ALL = 0x0000FFFF
     54
    5055# sibling imports
    5156import tcp, main, interfaces
    5257
     
    6368        """Return a SSL.Context object. override in subclasses."""
    6469        raise NotImplementedError
    6570
     71NO_VERIFY_CERT, VERIFY_CERT, REQUIRE_CERT = range(3)
    6672
    6773class DefaultOpenSSLContextFactory(ContextFactory):
    68 
     74    _sessionIdCtxNum = 0
    6975    def __init__(self, privateKeyFileName, certificateFileName,
    70                  sslmethod=SSL.SSLv23_METHOD):
     76                 sslmethod=SSL.SSLv23_METHOD,
     77                 verifyPeer=NO_VERIFY_CERT, verifyDepth=10,
     78                 clientCACertsFile=None):
     79        """Initialize an SSL server context.
     80
     81        privateKeyFileName and certificateFileName should be set to the
     82        PEM-encoded key and certificates for this server.
     83       
     84        verifyPeer can be set to NO_VERIFY_CERT (no verification),
     85        VERIFY_CERT (verify client cert but don't fail if none is given),
     86        or REQUIRE_CERT (verify and require client cert).
     87
     88        verifyDepth sets how long a certificate chain is allowed.
     89       
     90        clientCACertsFile can be set to a file containing (PEM-format)
     91        certificates of the CAs to verify clients again. This must be
     92        set if verifyPeer is non-zero.
     93
     94        """
    7195        self.privateKeyFileName = privateKeyFileName
    7296        self.certificateFileName = certificateFileName
    7397        self.sslmethod = sslmethod
     98        self.verifyPeer = verifyPeer
     99        self.verifyDepth = verifyDepth
     100        self.clientCACertsFile = clientCACertsFile
    74101        self.cacheContext()
    75102
    76103    def cacheContext(self):
    77104        ctx = SSL.Context(self.sslmethod)
    78105        ctx.use_certificate_file(self.certificateFileName)
    79106        ctx.use_privatekey_file(self.privateKeyFileName)
     107
     108        ctx.set_verify_depth(self.verifyDepth)
     109       
     110        if self.clientCACertsFile:
     111            ctx.load_client_ca(self.clientCACertsFile)
     112            ctx.load_verify_locations(self.clientCACertsFile)
     113       
     114        if self.verifyPeer != NO_VERIFY_CERT:
     115            callback = lambda conn,cert,errno,depth,retcode: retcode
     116            if self.verifyPeer == REQUIRE_CERT:
     117                options = SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT
     118            else:
     119                options = SSL.VERIFY_PEER
     120            ctx.set_verify(options, callback)
     121       
     122        # turn on fixing SSL client bugs
     123        ctx.set_options(SSL_OP_ALL|SSL.OP_SINGLE_DH_USE)
     124
     125        # session id is supposed to be unique between servers in this process.
     126        # i'm unsure what the point is, but it's required. In the sample
     127        # code (1 server), it's simply set to 1.
     128        DefaultOpenSSLContextFactory._sessionIdCtxNum = DefaultOpenSSLContextFactory._sessionIdCtxNum + 1
     129        ctx.set_session_id(md5.new("DefaultOpenSSLContextFactory%d"%DefaultOpenSSLContextFactory._sessionIdCtxNum).digest())
    80130        self._context = ctx
    81131
    82132    def __getstate__(self):
     
    184234    def getDestination(self):
    185235        return ('SSL', self.host, self.port)
    186236
    187 __all__ = ["ContextFactory", "DefaultOpenSSLContextFactory", "ClientContextFactory"]
     237__all__ = ["ContextFactory", "DefaultOpenSSLContextFactory", "ClientContextFactory", "NO_VERIFY_CERT", "VERIFY_CERT", "REQUIRE_CERT"]
    188238
    189239supported = True