Hello all,

I'm trying to configure an SSL-enabled twisted.web service, and I'm having a problem getting it to work with my certificate chain file.

I'm trying to replace a similar configuration on an Apache server, so I know my certificates/keys are valid and current, and they work fine under mod_ssl.

The issue seems to be with the chain file. If I just include the primary cert and key, the connection works properly, but of course displays an 'unknown root certificate' warning.

This is the ContextFactory I'm using:

    class ContextFactory:
        isClient = 0

        def getContext(self):
            ctx = SSL.Context(SSL.SSLv23_METHOD)
            ctx.use_certificate_file('/usr/local/dram/certs/shib.crt')
            ctx.use_privatekey_file('/usr/local/dram/certs/www.key')
ctx.use_certificate_chain_file('/usr/local/dram/certs/ intermediate.crt')
            return ctx

I've attached a minimal test case, but there's really nothing of consequence besides the class above.

Using s_client, I got the following debug output:

optimus:dram2 phil$ openssl s_client -connect shib.dramonline.org: 443 -debug -state -nbio 2>&1
    CONNECTED(00000003)
    turning on non blocking io
    SSL_connect:before/connect initialization
    write to 0020BE30 [00127000] (118 bytes => 118 (0x76))
0000 - 80 74 01 03 01 00 4b 00-00 00 20 00 00 39 00 00 .t....K... ..9.. 0010 - 38 00 00 35 00 00 16 00-00 13 00 00 0a 07 00 c0 8..5............ 0020 - 00 00 33 00 00 32 00 00-2f 03 00 80 00 00 05 00 .. 3..2../....... 0030 - 00 04 01 00 80 00 00 15-00 00 12 00 00 09 06 00 ................ 0040 - 40 00 00 14 00 00 11 00-00 08 00 00 06 04 00 80 @............... 0050 - 00 00 03 02 00 80 ec 36-f1 ee 1c 4e 29 1e 5d 3c ....... 6...N).]< 0060 - 82 c8 19 76 7d b8 85 94-a0 59 62 67 da 5a 69 7f ...v}....Ybg.Zi.
    0070 - 2b 62 68 b3 c7 5e                                 +bh..^
    SSL_connect:SSLv2/v3 write client hello A
    read from 0020BE30 [0012D000] (7 bytes => -1 (0xFFFFFFFF))
    SSL_connect:error in SSLv2/v3 read server hello A
    write R BLOCK
    read from 0020BE30 [0012D000] (7 bytes => 7 (0x7))
    0000 - 15 03 01 00 02 02 28                              ......(
    SSL3 alert read:fatal:handshake failure
    SSL_connect:error in SSLv2/v3 read server hello A
5765:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:596:

As I said before, I find this strange because I have a working SSL config already in Apache, and it's relatively simple:

    <VirtualHost 69.60.xxx.xxx:443>
        ServerName shib.dramonline.org

        DocumentRoot /var/www/html

        SSLEngine on
        SSLProtocol all -TLSv1

        SSLCertificateFile      /usr/local/dram/certs/shib.crt
        SSLCertificateKeyFile   /usr/local/dram/certs/www.key
        SSLCACertificateFile    /usr/local/dram/certs/intermediate.crt

        SetEnvIf User-Agent ".*MSIE.*" nokeepalive \
            ssl-unclean-shutdown downgrade-1.0 force-response-1.0
    </VirtualHost>

This may be something I need to take to the py/OpenSSL folks, but I wanted to check here first to make sure I wasn't missing something obvious. I've tried disabling various SSL protocols (using context.set_options()) and sometimes it seems like it gets a little farther in the process, but

Thanks in advance for any help,

-phil

from zope.interface import implements

from twisted.python import usage
from twisted.plugin import IPlugin
from twisted.application import internet, service
from twisted.web import server, resource

from OpenSSL import SSL

class ContextFactory:
	isClient = 0
	
	def getContext(self):
		ctx = SSL.Context(SSL.SSLv23_METHOD)
		ctx.use_certificate_file('/usr/local/dram/certs/shib.crt')
		ctx.use_privatekey_file('/usr/local/dram/certs/www.key')
		ctx.use_certificate_chain_file('/usr/local/dram/certs/intermediate.crt')
		return ctx

class ExampleResource(resource.Resource):
	isLeaf = True
	
	def render(self, request):
		request.setHeader('Content-Type', 'text/html')
		request.write("It worked!")
		request.finish()
		return server.NOT_DONE_YET

class SSLTestServiceMaker(object):
	implements(service.IServiceMaker, IPlugin)
	tapname = "ssl-test"
	description = "Illustrate the chain certificate issue."
	options = usage.Options
	
	def makeService(self, config):
		site = server.Site(ExampleResource())
		
		master_service = service.MultiService()
		
		web_service = internet.TCPServer(80, site)
		ssl_service = internet.SSLServer(443, site, ContextFactory())
		
		web_service.setServiceParent(master_service)
		ssl_service.setServiceParent(master_service)
		
		return master_service

serviceMaker = SSLTestServiceMaker()

_______________________________________________
Twisted-web mailing list
[email protected]
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

Reply via email to