Forefront TMG Beta 3 on Windows Server 2008 R2(RC) - TLS 1.1 and TLS 1.2

As you may know TLS 1.1 and TLS 1.2 have arrived on the server side on Windows Server 2008 R2(if you use IIS 7.5), on the client side Windows 7(if you use IE8) or with Opera 10.
GnuTLS also supports TLS 1.1 and TLS 1.2.
What exactly each of these actually supports, that’s another story.

You can find the Microsoft Interop Test Server at:
https://tls.woodgrovebank.com/

You may like to read:
- http://technet.microsoft.com/en-us/library/dd560644(WS.10).aspx
- http://msdn.microsoft.com/en-us/library/dd208005(PROT.13).aspx
- http://blogs.msdn.com/ieinternals/archive/2009/06/19/Windows-7-support-for-TLS-and-ciphers.aspx
- http://forums.iis.net/p/1155254/1905006.aspx

Additional reading:
- http://my.opera.com/core/blog/2009/02/25/new-in-opera-presto-2-2-tls-1-2-support

You may like to visit Michael D'Errico “Mike's Toolbox Multi-Threaded SSL/TLS Test Server”:
- https://www.mikestoolbox.net/

TLS 1.1 and TLS 1.2 online server scanner, please go to Ivan Ristic’s SSL Labs project:
- https://www.ssllabs.com/

 

So, what if we installed Forefront TMG Beta 3 on Windows Server 2008 R2(RC)(note that apparently this is not officially supported), do we get TLS 1.1 and TLS 1.2 support in some form or another ?
Also note that what we will do bellow, probably will not be supported by Microsoft either.
But it’s all fine, as we are in a lab(you can use a virtual lab if you fell more comfortable like so), ready to taste and touch TLS 1.2, probably on one of the first firewall out there that supports it in a form or another, so let’s feel free and ignore any Microsoft advices like “we do not officially support …”. –;)
Can we get TLS 1.1 or TLS 1.2 support if we configure Forefront TMG Beta 3 on Windows Server 2008 R2(RC) to act as a reverse-proxy doing SSL bridging(web publishing rule) ?
Let’s take a look.

 

Suppose we have installed Forefront TMG Beta 3 SE on Windows Server 2008 R2 RC SE.
We have created a test web publishing rule to publish a secure web site:
tmg_b3_ssl_test-pub

 

Modified as desired the TLS preferences on IE8 running on Windows 7 or on Opera 10(you might be better if you try with IE8 on Windows 7 first, as it’s the same TLS implementation, and thus can avoid potential bumps):

ie8_tls

opera_tls

 

Will Forefront TMG Beta 3 SE on Windows Server 2008 R2 RC SE acting as a reverse-proxy doing SSL bridging(web publishing rule) accept by default TLS 1.1 and TLS 1.2 sessions ?
Not really, as TLS 1.1 and TLS 1.2 are disabled by default for the server side.
We need to make some registry changes first.

Note that these changes are not yet(as writing) officially documented by Microsoft, so use them at your own risk.
http://support.microsoft.com/kb/245030

If we navigate to [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols], we will see that a registry key for SSL 2.0 exist, under this Key there is a Client Key, and the Client Key contains a REG_DWORD DisabledByDefault value, set to 1. We are not interested in it.

reg_1

 

As can be noted from above, I’ve added some registry entries under [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols], which are:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.1\Server]
"DisabledByDefault"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Server]
"DisabledByDefault"=dword:00000000

reg_2
reg_3

After adding this registry values, reboot the TMG machine.

 

So what’s changed now ?

Forefront TMG Beta 3 SE on Windows Server 2008 R2 RC SE acting as a reverse-proxy doing SSL bridging(web publishing rule) can now accept TLS 1.1 and TLS 1.2 sessions.
But, as far as I’ve seen, this will not influence the outbound HTTPS Inspection, if the client behind TMG Beta 3, say IE 7 on Windows 7 attempts to use only TLS 1.1 and TLS 1.2, this connection will fail(remember that with the outbound HTTPS Inspection enabled, the TLS connection is established between the client and TMG, and then between TMG and the destination server, TMG act as a MITM agent in order to inspect the traffic). Maybe it’s just me, but the outbound HTTPS Inspection sometimes seems to be in its “own world”.

 

There are caveats, though.
Apparently Forefront TMG Beta 3 SE does not have support for ECDSA certificates. For example if we want to use an ECDHE_ECDSA cipher suite(note that certain ECDHE_ECDSA cipher suites can be used with TLS 1.0 too), the server’s certificate should contain an ECDSA-capable public key, must allow the key to be used for signing with the hash algorithm that will be employed in the server key exchange message and the public key must use a curve and point format supported by the client.
If you already didn’t, you can take a look at https://tls.woodgrovebank.com/, go now there, and spot such a certificate.

 

Say I have on Forefront TMG Beta 3 SE a certificate like:

srv_cert_1
srv_cert_2
srv_cert_3

Certificate which was signed by this CA:

ca_cert_1
ca_cert_2

 

If I want to use this certificate with Forefront TMG Beta 3 SE on my test web publishing rule:

tmg_b3_ssl_test-pub_certs

Bummer –:(.

 

However, if I get a certificate from the very same CA, certificate containing a public RSA key(like bellow), as can be seen from above this certificate looks valid to Forefront TMG Beta 3 SE, and I can use it on the test web publishing rule.

srv_cert_4
srv_cert_5

 

You can have a “regular” RSA certificate on Forefront TMG Beta 3 SE and use TLS 1.1 and 1.2.
Take a look here to see what cipher suites might be available(we already discussed about some of them here –in the context of TLS 1.0-, if you open the group policy mentioned there you will get a better picture about the available cipher suites under Windows Server 2008 R2 and Windows 7):
- http://msdn.microsoft.com/en-us/library/aa374757(VS.85).aspx
- http://technet.microsoft.com/en-us/library/cc766285(WS.10).aspx
Cipher suites for TLS 1.2 within RFC5246:
http://tools.ietf.org/html/rfc5246#appendix-A.5

 

 

Now, with the arrival of TLS 1.1, TLS 1.2, new cipher suites and so on, it becomes difficult to manually probe the server for the supported cipher suites. If you want to use OpenSSL or GnuTLS you will soon realize that they have certain limitations regarding what they currently support(also you will likely find that most SSL scanners out there are outdated).
Personal I use a simplified approach. This approach will not give me confidence that I can really use a certain TLS version with a certain cipher suite with a server(as I never complete the TLS negotiations), but it has the advantage that it does not depend on any SSL libraries.

For example, I’ve written a little basic Python script to connect to a server and send a Client Hello message to that server.
Say the bellow script, I can easily(the process is not automated) use a certain TLS version, specify a certain cipher suite(yeah, I know that if the server’s reply will span along multiple frames, I do not close the connection in an elegant way):

#!/usr/bin/python
from socket import socket
from time import sleep
raddr = "192.168.22.235", 443
test = (
# -> Start TLS Record Protocol
"\x16" #  ContentType: Handshake
"\x03\x02" # ProtocolVersion: TLS 1.1
"\x00\x2d" # Length
# -> Start Handshake Protocol
"\x01" # HandshakeType: ClientHello
"\x00\x00\x29" # Length
"\x03\x02" # ProtocolVersion: TLS 1.1
"\x4a\xb2\x5e\x62" # Random: gmt_unix_time
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" # Random: random_bytes
"\x00" # SessionID
"\x00\x02" # CipherSuites Length
"\x00\x1f" # CipherSuites
"\x01" # CompressionMethods Length
"\x00" # CompressionMethods
# <- End Handshake Protocol
# <- End TLS Record Layer
)
s = socket()
s.connect(raddr)
s.send(test)
reply = s.recv(1024)
s.shutdown(1)
print 'Received Reply:\n', repr(reply)

 

Actually I want to show you something(that’s why the above script contains a certain cipher suite) that I’ve noticed with Windows Server 2008 R2 RC build 7100(can’t make it happen with Windows Server 2008 R2 RTM though, looks like an RC glitch), say I use TLS 1.1 and the TLS_KRB5_WITH_3DES_EDE_CBC_SHA (0x001f) cipher suite(I can use other cipher suite, in fact as I’ve discovered while scanning such a server with Ivan Ristic’s SSL Labs scanner, many other cipher suites) within client’s Hello Message.
Note that this is not necessarily related to Forefront TMG Beta 3, rather to Windows Server 2008 R2 RC(it happens without Forefront TMG Beta 3, say with IIS 7.5 running on Windows Server 2008 R2 RC).

Running the script:

wrong_tl_rc_a

Which translates into:

- client has sent:

wrong_tl_rc_1

- reply received from server:

wrong_tl_rc_2

Interesting, eh ?
As said above, this (mis)behavior can be reproduced for other cipher suites too proposed by the client(thanks to Ivan Ristic’s SSL Labs scanner for pointing them out).
Note that I do not have to enable TLS 1.1 and/or TLS1.2 on the Windows Server 2008 R2 RC to have the server misbehave, it will (mis)reply with a TLS 1.0 response when I probe with TLS 1.1.
This (mis)behavior seems to occur when I configure the server(IIS 7.5 or TMG Beta 3) to use a certificate like(the one we saw above): say signed with sha256ECDSA containing a RSA public key(might exist other possibilities, but I cannot comment on such possibilities).

 

Anyway, coming back to probing Forefront TMG Beta 3 on Windows Server 2008 R2 RC, for example I can easily adjust the script to probe for the TLS_RSA_WITHS_AES_128_CBC_SHA256 (0x003c) cipher suite and TLS 1.2, while adding the Signature Algorithms extension  too:

#!/usr/bin/python
from socket import socket
from time import sleep
raddr = "192.168.22.235", 443
test = (
# -> Start TLS Record Protocol
"\x16" #  ContentType: Handshake
"\x03\x03" # ProtocolVersion: TLS 1.2
"\x00\x43" # Length
# -> Start Handshake Protocol
"\x01" # HandshakeType: ClientHello
"\x00\x00\x3f" # Length
"\x03\x03" # ProtocolVersion: TLS 1.2
"\x4a\xb2\x5e\x62" # Random: gmt_unix_time
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" # Random: random_bytes
"\x00" # SessionID
"\x00\x02" # CipherSuites Length
"\x00\x3c" # CipherSuites
"\x01" # CompressionMethods Length
"\x00" # CompressionMethods
"\x00\x14" # Extensions Length
"\x00\x0d\x00\x10\x00\x0e\x04\x01\x05\x01\x02\x01"
"\x04\x03\x05\x03\x02\x03\x02\x02" # Extension: signature_algorithms
# <- End Handshake Protocol
# <- End TLS Record Layer
)
s = socket()
s.connect(raddr)
s.send(test)
reply = s.recv(1024)
s.shutdown(1)
print 'Received Reply:\n', repr(reply)

Which translates into:

-  the client proposes:

prob_tls_1_2_1

- and the server replies:

prob_tls_1_2_2

 

Or mimic an IE8 on Windows 7 using TLS 1.2(not that I’m really interested in doing this):

#!/usr/bin/python
from socket import socket
from time import sleep
raddr = "192.168.22.235", 443
test = (
# -> Start TLS Record Protocol
"\x16" #  ContentType: Handshake
"\x03\x03" # ProtocolVersion: TLS 1.2
"\x00\x9b" # Length
# -> Start Handshake Protocol
"\x01" # HandshakeType: ClientHello
"\x00\x00\x97" # Length
"\x03\x03" # ProtocolVersion: TLS 1.2
"\x4a\xb2\x5e\x62" # Random: gmt_unix_time
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" # Random: random_bytes
"\x00" # SessionID
"\x00\x26" # CipherSuites Length
"\x00\x3c"
"\x00\x2f"
"\x00\x3d"
"\x00\x35"
"\x00\x0a"
"\xc0\x27"
"\xc0\x13"
"\xc0\x14"
"\xc0\x2b"
"\xc0\x23"
"\xc0\x2c"
"\xc0\x24"
"\xc0\x09"
"\xc0\x0a"
"\x00\x40"
"\x00\x32"
"\x00\x6a"
"\x00\x38"
"\x00\x13" # CipherSuites
"\x01" # CompressionMethods Length
"\x00" # CompressionMethods
"\x00\x48" # Extensions Length
"\x00\x00\x00\x17\x00\x15\x00\x00\x12\x77\x77\x77\x2e\x63"
"\x61\x72\x62\x6f\x6e\x77\x69\x6e\x64\x2e\x6e\x65\x74" # Extension: server_name
"\x00\x05\x00\x05\x01\x00\x00\x00\x00" # Extension: status_request
"\x00\x0a\x00\x06\x00\x04\x00\x17\x00\x18" # Extension: elliptic_curves
"\x00\x0b\x00\x02\x01\x00" # Extension: ec_point_formats
"\x00\x0d\x00\x10\x00\x0e\x04\x01\x05\x01\x02\x01\x04\x03"
"\x05\x03\x02\x03\x02\x02" # Extensions: signature_algorithms
# <- End Handshake Protocol
# <- End TLS Record Layer
)
s = socket()
s.connect(raddr)
s.send(test)
reply = s.recv(1024)
s.shutdown(1)
print 'Received Reply:\n', repr(reply)

Which translates into:

- the client sends(note that the server’s name is www.carbonwind.net within the server_name extension):

prob_tls_1_2_3

- and the server replies:

prob_tls_1_2_4

Comments (1) -

  • Emanuel

    10/3/2009 12:27:21 PM |

    great blog! thanks!

Pingbacks and trackbacks (1)+

Comments are closed