Steve Hall
Steve Hall

Reputation: 469

Using ciphers in Twisted Python - attribute errors?

We've been having trouble getting one of our client machines to connect over TLS to my Twisted based mail receiver. Bearing in mind my limited understanding of TLS / ciphers, discussions with colleagues suggested it was a cipher issue. Looking at the Twisted docs I modified my code as follows:

from twisted.internet.ssl import CertificateOptions, DiffieHellmanParameters
from twisted.python.filepath import FilePath
dhFilePath = './dh_param_1024.pem'
dhParams = ssl.DiffieHellmanParameters.fromFile(dhFilePath)
sslCtxFactory = ssl.CertificateOptions(privateKey=pKey, certificate=cert, trustRoot=caCert, method=SSLv3_METHOD, dhParameters=dhParams)

(previously I hadn't specifed the dhParameters)

I generated dh_param_1024.pem file using openssl, as advised in a different page of the Twisted Docs.

However, when I try to connect to the revised listener from the remote client, I get:

Unhandled Error
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/twisted/python/log.py", line 88, in callWithLogger
    return callWithContext({"system": lp}, func, *args, **kw)
  File "/usr/local/lib/python2.7/site-packages/twisted/python/log.py", line 73, in callWithContext
    return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 118, in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 81, in callWithContext
    return func(*args,**kw)
--- <exception caught here> ---
  File "/usr/local/lib/python2.7/site-packages/twisted/internet/posixbase.py", line 614, in _doReadOrWrite
    why = selectable.doRead()
  File "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 214, in doRead
    return self._dataReceived(data)
  File "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 220, in _dataReceived
    rval = self.protocol.dataReceived(data)
  File "/usr/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 454, in dataReceived
    self.lineReceived(line)
  File "/usr/local/lib/python2.7/site-packages/twisted/mail/smtp.py", line 568, in lineReceived
    return getattr(self, 'state_' + self.mode)(line)
  File "/usr/local/lib/python2.7/site-packages/twisted/mail/smtp.py", line 582, in state_COMMAND
    method('')
  File "/root/TwistedSMTP/custom_esmtp.py", line 279, in ext_STARTTLS
    self.transport.startTLS(self.ctx)
  File "/usr/local/lib/python2.7/site-packages/twisted/internet/_newtls.py", line 179, in startTLS
    startTLS(self, ctx, normal, FileDescriptor)
  File "/usr/local/lib/python2.7/site-packages/twisted/internet/_newtls.py", line 139, in startTLS
    tlsFactory = TLSMemoryBIOFactory(contextFactory, client, None)
  File "/usr/local/lib/python2.7/site-packages/twisted/protocols/tls.py", line 769, in __init__
    contextFactory = _ContextFactoryToConnectionFactory(contextFactory)
  File "/usr/local/lib/python2.7/site-packages/twisted/protocols/tls.py", line 648, in __init__
    oldStyleContextFactory.getContext()
  File "/usr/local/lib/python2.7/site-packages/twisted/internet/_sslverify.py", line 1429, in getContext
    self._context = self._makeContext()
  File "/usr/local/lib/python2.7/site-packages/twisted/internet/_sslverify.py", line 1470, in _makeContext
    ctx.load_tmp_dh(self.dhParameters._dhFile.path)
exceptions.AttributeError: 'str' object has no attribute 'path'

When I revert my code to set my sslCtxFactory without specifying the dhParameters property, while the connection fails, I do not get this error. It looks to me like twisted's _sslverify.py is receiving self.dhParameters._dhFile as a string, rather than a file object - or some similar issue?

Can anyone advise? Has anyone experienced similar?

Thanks!

Upvotes: 1

Views: 296

Answers (1)

Jean-Paul Calderone
Jean-Paul Calderone

Reputation: 48335

The type of the argument accepted by fromFile is not bytes but that is the type being passed in this code.

It looks like you meant to pass a FilePath instance (FilePath is being imported) but you forgot and passed bytes instead.

Upvotes: 1

Related Questions