SSL / TLS

Multipath Certification Desired

Open issue is that we have private keys for both ends of the connection, and although it is possible and rather desirable to generate multiple certificate requests for each of our private keys, perhaps two to verify our identity, and another to certify our competency, the description of a server certificate currently assumes there will only be one such thing. “it chooses one”.

This may be like saying to a bank that ask for 2 forms of identity, I am only allowed to give you one.

Also, where we establish the principle of a “generally trusted” person, commonly described as a well-known trusted root certificate authority we could end up requiring that person’s permission, be that in the form of a certificate, to do anything. 😼

Both these effects we might mitigate by allowing multipath wherever certification of public keys are used.

Tunnelling with SSL

This is access through a proxy followed by a patched Apache2 with "AllowCONNECT" and "SSLVerifyClient require" options set.

The server requires "-cert" to be signed by "SSLCACertificateFile" and the client requires "SSLCertificateFile" to be signed by "-CAfile".

The tunnel gateway can share port 443 with other websites with a different configuration, via Server Name Indication. These other sites may choose to require or not a client certificate depending on their application. We can also enable TLS upgrade on port 80, in that situation it is activated via SSLEngine optional.

Also, some adversary networks will even check the SNI indicator as it is also sent in the clear and unencrypted, and may thus even need to be set specifically to please it. It may be possible to patch apache2 further to remove the requirement that the SNI and tunnelled service be the same.

Sample Apache2 configuration

<VirtualHost *:443>
        SSLEngine on
        # remove SSLv2 SSLv3, let TLSv1 onwards for now
        # SSLv2 has been cracked and so even has SSLv3
        SSLProtocol all -SSLv2 -SSLv3

        # use only the best cipher! - check string with "openssl ciphers -v $'AES256-SHA'"
        SSLCipherSuite AES256-SHA
        #SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

        # we are this certificate
        SSLCertificateFile /usr/local/lib/ssl/certs/apache.crt
        SSLCertificateKeyFile /usr/local/lib/ssl/private/apache.key

        # our cert was from our root
        SSLCertificateChainFile /usr/local/lib/ssl/cacert.pem

        # we expect clients to have a cert signed with our root's private key
        SSLCACertificateFile /usr/local/lib/ssl/cacert.pem
        SSLCARevocationPath /usr/local/lib/ssl/crl/
        SSLCADNRequestFile /usr/local/lib/ssl/cacert.pem
	SSLOptions +StdEnvVars +ExportCertData +FakeBasicAuth +StrictRequire
        SSLVerifyClient require

        # SSL functions as a forward proxy to interesting places
        ProxyRequests On
        ProxyVia On

	# allow connection to interesting ports
        AllowCONNECT 443 22 5222 5223 119 143 993 587 80 8080

        <Proxy *>
                Order deny,allow
                Deny from all
                Allow from  127.0.0.0/255.0.0.0 ::1/128
                Allow from  192.0.2.0/24 2001:db8::/32

		# Be ready to evaluate the security of apache2 with local pen-tests before enabling something such as the following: 
		# Allow from all
		# The proxy is expected to be protected by the SSLVerifyClient require line,
		# this does depend on adversaries not guessing or having been issued a key signed by SSLCertificateChainFile
        </Proxy>
</VirtualHost>

Sample Client end script

This should also check verify the server certificate, and abandon the connection if it is not right.

#!/bin/bash

CERT=/usr/local/lib/ssl/certs/cert.pem
KEY=/usr/local/lib/ssl/private/private.key
TRUSTED=/usr/local/lib/ssl/certs/trusted.crt
SNI=$1

# first connect to the webserver on its SSL port via the local proxy
nc6 -l -s 127.0.0.1 -p 0 --exec "nc.openbsd -X connect -x $1 $2 443" &

C=($(jobs -l|tail -1))
PID=${C[1]}
D=($(netstat -lnp 2>&-|grep ${PID}/nc6))
PORT=${D[3]}

# user is to see if the server certificate is not as expected
exec 4>&2

# open a SSL session on the webserver
nc6 -l -s 127.0.0.1 -p 0 --exec "2>&4 /usr/bin/openssl s_client -nbio -verify -1 \
-servername ${SNI} -quiet -connect ${PORT} -cert ${CERT} \
-key ${KEY} -CAfile ${TRUSTED}" &

C=($(jobs -l|tail -1))
PID=${C[1]}
D=($(netstat -lnp 2>&-|grep ${PID}/nc6))
PORT=${D[3]}

# treat this webserver as a proxy to connect to the destination within the SSL tunnel
# note that if apache2 is to be used as the forward proxy it seems necessary to have it connect to itself at this point,
# such as on port 80.
exec nc.openbsd -X connect -x ${PORT} ${SNI} 22

To use, add something like this to ~/.ssh/config

Host tunnel
ProxyCommand ssltunnel wpad:8080 remote.example.net

Then you may connect to the remote SSH server inside SSL with ssh tunnel