In a message of Sun, 03 Jun 2007 20:19:45 EDT, Eric Dorland writes:
>> >So the LD_LIBRARY_PATH is set to /usr/lib/iceweasel in the iceweasel
>> >shell script (which invokes the actual binary,
>> >/usr/lib/iceweasel/firefox-bin). How are you invoking it? 
>> 
>> Using the /usr/bin/iceweasel script... So at least theoretically,
>> running it as "env LD_LIBRARY_PATH=/usr/lib/iceweasel iceweasel"
>> vs just "iceweasel" shouldn't make any difference (I've read the
>> script now). But it certainly did when I was chasing the SSL problem
>> friday (or am I going insane?).
>
>I doubt you're crazy but maybe you made a mistake. Try it again on the
>machine you were having problems with and see.

Ok, I have some more data now (which also explains why I thought
setting LD_LIBRARY_PATH helped). I haven't managed to recreate
exactly the same situation I had on friday, but it looks similar
enough that I think it's still the same problem.

It seems that it is caused by interaction between the SSL server and
iceweasel. If the SSL server asks for a client certificate, but does
not specify any acceptable certificate authorities, connecting to the
SSL server will always work flawlessly the first time. Sometimes
the second and further attempts to connect will fail with a "connection
interrupted" error message:

    The connection was interrupted

    The connection to localhost:9999 was interrupted while the page was loading.

    * The site could be temporarily unavailable or too busy. Try again in a few
      moments.

    * If you are unable to load any pages, check your computer's network
      connection.

    * If your computer or network is protected by a firewall or proxy, make sure
      that Iceweasel is permitted to access the Web.

Sometimes, if the SSL server uses TLSv1 only, it will instead say that
the "Iceweasel can't connect securely to localhost because the site uses
a security protocol which isn't enabled."

Unfortunately, I can't trigger it consistently, but it seems more common
if the server uses SSLv3 only or TLSv1 only. Using SSLv23 (i.e. 2 and 3
autonegotiation) breaks less often, but it happens there too.

Oh, and it's not the server, because openssl s_client connects just fine.

I'm including a small python program to test it. Uncommenting the
load_client_ca() line seems to make it consistently not break. If it's
not there, it will occasionally break. Switching methods seems to trigger
it quicker, so changing which SSL.*_METHOD is uncommented and then
reloading the page is more likely to trigger.

You'll need python-twisted-web2 and python-pyopenssl installed.

Generate the required certificates like:

$ openssl genrsa -out CA.key 1024
$ openssl req -new -key CA.key -x509 -out cacert
$ openssl genrsa -out foo.pkey 1024
$ openssl req -new -key foo.pkey -out foo.creq
$ openssl x509 -req -in foo.creq -CA cacert -CAkey CA.key -CAcreateserial -out 
foo.cert

/Anders

from twisted.python import log
from twisted.internet import reactor, ssl
from twisted.web2 import server, resource, channel, http
import sys

from OpenSSL import SSL, crypto

class Root(resource.Resource):
    addSlash = True
    
    def render(self, req):
        return http.Response(code=200, stream='foo')

class SSLContextFactory(ssl.ContextFactory):
    def __init__(self, pkey, cert, cacert, method):
        _pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, open(pkey).read())
        _cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(cert).read())
        _cacert = crypto.load_certificate(crypto.FILETYPE_PEM, open(cacert).read())
        
        self._ctx = ctx = SSL.Context(method)
        #ctx.load_client_ca(cacert)
        ctx.set_verify(SSL.VERIFY_PEER, self.verifyClientCallback)
        ctx.set_cipher_list('RC4:-EXP:-LOW:-ADH:@STRENGTH')
        ctx.use_certificate(_cert)
        ctx.use_privatekey(_pkey)
        certstore = ctx.get_cert_store()
        certstore.add_cert(_cacert)

    def verifyClientCallback(self, conn, cert, errnum, depth, ok):
        """
        Verifiy the client connection.

        Arguments:   conn - the SSL connection
                     cert - the certificate being checked
                     errnum - error code from SSL (if applicable)
                     depth - depth in certificate verification chain
                     ok - 1: everything ok so far,
                          0: an error (available in errnum)
        Returns:     The new 'ok' value
        """
        return ok


    def getContext(self):
        return self._ctx

def main():
    log.startLogging(sys.stderr)
    site = server.Site(Root())
    print site
    
    sslctx = SSLContextFactory('foo.pkey', 'foo.cert', 'cacert',
                               #SSL.SSLv23_METHOD)
                               #SSL.SSLv3_METHOD)
                               SSL.TLSv1_METHOD)

    print site
    reactor.listenSSL(9999, channel.HTTPFactory(site), sslctx)
    reactor.run()

if __name__ == '__main__':
    main()

Reply via email to