_ _ _ __ ___ ___ __| | ___ ___| | mod_ssl | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org |_____| _____________________________________________________________________________ GLOBAL-SERVER-IDs (Verisign) or INTERNATIONAL STEP-UP (Netscape) or SERVER GATED CRYPTOGRAPHY (SGC) (Microsoft) ``Server Gated Cryptography (SGC): A mechanism for negotiating strong cryptographic security for SSL/TLS sessions based on the presence of a special server-side certificate. Distribution of these certificates is controlled in accordance with an export license from the U.S. Department of Commerce. The SGC certificates are distinguished by a special extendedKeyUsage extension value.'' As you usually know, export-grade versions of Netscape Communicator are restricted to 40-bit cryptography because of the US laws (ITAR). In practice this means although your Apache+mod_ssl+OpenSSL webserver supports 128-bit your European clients always choose only 40 bit ciphers at the SSL/TLS negotiation phase. To overcome this restriction Fortify [1] regularly produces a program which can be used to patch-up the various export-grade Netscape Navigator (v3) and Communicator (v4) version to allow full strength cryptography with 128-bit encryption and 1024-bit key generation. This is important because without Fortify'ing your browser, it's limited to 40-bit encryption facilities, which are substantially weaker, and have been demonstrated to be `crackable'. But the obvious question usually is: Why does Netscape Communicator already have 128-bit encryption built-in when it's just disabled and can be enabled such easily by a patching program like Fortify? The answer is, that the two high-grade SSL ciphers RSA-RC4-MD5 (128 bit RC4) and RSA-DES-CBC3-MD5 (168 bit Triple-DES) which Communicator supports are only enabled when you connect to specific, specially approved SSL webservers. Netscape calls this enabling the `Internal Step-Up' [3] and Microsoft calls it `Server Gated Cryptography (SGC)' [4][5]. The Certificate Authority (CA) Verisign Inc. grants these special approvals, under its `Global Server ID' certificate program [2]. Outside the US, approvals are only available to certain, specific categories of organizations, for instance banks and other financial organizations, etc. How does this `Global Server ID' stuff work? First Netscape Communicator ships with some pre-configured CA certificates, including the general Verisign root CA certificates. Although they all look similar, on the `Communicator -> Security Info -> Signers' panel when you select a CA certificate and push the `Edit' button, they are not equal. Actually when you dump out the cert7.db files contents (that's the database in DB/1.85 format where Communicator stores all certificates, including the CA certificates), then you can recognize a subtle difference between the entries: There are some internal bits set differently for some CA certificates. Those bits aren't represented by any radio buttons or flags in the GUI, but they indicate what CA certificates have the `Global Server ID' functionality attached. Second the server gets a Versign's Global Server ID certificate. This is nothing more than a X.509v3 certificate with additional extensions. The important extension here is the extKeyUsage [6]. This is an extensible version of the ordinary keyUsage extension. It is a sequence of ASN.1 OBJECT IDENTIFIERS which specify other usages for the key. In the situation of a Global Server ID this is an object with the ids 2.16.840.1.113730.4.1 ( `Netscape SGC') and 1.3.6.1.4.1.311.10.3.3 (`Microsoft SGC'). Now, when Communicator connects with HTTPS to a webserver which has such a Global Server ID the following happens: First Communicator doesn't know anything about the remote server, so it initiates an SSL connection with a 40-bit cipher, only. Then the server certificate is transferred and Communicator verifies it against it's known CAs. Here it recognizes that both the server certificate has the `Netscape SGC' extension and the CA certificate of the issuer is tagged for the `Global Server ID' functionality. What now happens is very interesting: Communicator immediately forces a SSL renegotiation. But this time with a 128-bit cipher! (For MSIE this should work similar but couldn't be tested until now, because it's still not known how to manually tag a CA certificate inside MSIE in a similar way we did it for Communicator above). How does such a connection look from mod_ssl's point of view? Let's look at its dedicated SSL engine logfile for a request from my Netscape Communicator to an Apache+mod_ssl+OpenSSL webserver who has a certificate signed by a CA which has the `Global Server ID' tag. | Connection to child 0 established (server en1.engelschall.com:8443) | Connection: Client IP: 192.76.162.40, Protocol: SSLv3, Cipher: EXP-RC4-MD5 (40/128 bits) | Connection: Client IP: 192.76.162.40, Protocol: SSLv3, Cipher: RC4-MD5 (128/128 bits) | Connection to child 0 closed (server en1.engelschall.com:8443) As you can see, my Communicator established a low-security connection to child 0 of Apache with the EXP-RC4-MD5 cipher. Then it recognized that the issuer has the `Global Server ID' tag and immediately upgraded the cipher to RC4-MD5 by re-negotiating the SSL parameters for the connection. For subsequent requests Communicator now already knows that it can use full-strength encryption and immediately uses the RC4-MD5 cipher: | Connection to child 0 established (server en1.engelschall.com:8443) | Connection: Client IP: 192.76.162.40, Protocol: SSLv3, Cipher: EXP-RC4-MD5 (40/128 bits) | Connection: Client IP: 192.76.162.40, Protocol: SSLv3, Cipher: RC4-MD5 (128/128 bits) | Connection to child 0 closed (server en1.engelschall.com:8443) | Connection to child 0 established (server en1.engelschall.com:8443) | Connection: Client IP: 192.76.162.40, Protocol: SSLv3, Cipher: RC4-MD5 (128/128 bits) | Connection to child 0 closed (server en1.engelschall.com:8443) | Connection to child 0 established (server en1.engelschall.com:8443) | Connection: Client IP: 192.76.162.40, Protocol: SSLv3, Cipher: RC4-MD5 (128/128 bits) | Connection to child 0 closed (server en1.engelschall.com:8443) A complete logfile snippet generated with `SSLLogLevel trace' shows you the gory details of such a communication: | Connection to child 0 established (server en1.engelschall.com:8443) | OpenSSL: Handshake: start | OpenSSL: Loop: before SSL initalisation | OpenSSL: Loop: SSLv3 read client hello A | OpenSSL: Loop: SSLv3 write server hello A | OpenSSL: Loop: SSLv3 write certificate A | OpenSSL: Loop: SSLv3 write key exchange A | OpenSSL: Loop: SSLv3 write server done A | OpenSSL: Loop: SSLv3 flush data | OpenSSL: Loop: SSLv3 read client key exchange A | OpenSSL: Loop: SSLv3 read finished A | OpenSSL: Loop: SSLv3 write change cipher spec A | OpenSSL: Loop: SSLv3 write finished A | OpenSSL: Loop: SSLv3 flush data | Inter-Process Session Cache: request=SET id=645981D01B0051AA921BA9BDDC7F9308D0D1FA7A3AFB2C1589DE20288F69BF26 timeout=298s (session caching) | OpenSSL: Handshake: done | Connection: Client IP: 192.76.162.40, Protocol: SSLv3, Cipher: EXP-RC4-MD5 (40/128 bits) | OpenSSL: Handshake: start | OpenSSL: Loop: before SSL initalisation | OpenSSL: Loop: SSLv3 read client hello A | OpenSSL: Loop: SSLv3 write server hello A | OpenSSL: Loop: SSLv3 write certificate A | OpenSSL: Loop: SSLv3 write server done A | OpenSSL: Loop: SSLv3 flush data | OpenSSL: Loop: SSLv3 read client key exchange A | OpenSSL: Loop: SSLv3 read finished A | OpenSSL: Loop: SSLv3 write change cipher spec A | OpenSSL: Loop: SSLv3 write finished A | OpenSSL: Loop: SSLv3 flush data | Inter-Process Session Cache: request=SET id=07797044E5D77D86FC610F70F7367AF1F37E1D3ED769A5C4DF2AE05D63D44596 timeout=299s (session caching) | OpenSSL: Handshake: done | Connection: Client IP: 192.76.162.40, Protocol: SSLv3, Cipher: RC4-MD5 (128/128 bits) | Connection to child 0 closed (server en1.engelschall.com:8443) | Connection to child 0 established (server en1.engelschall.com:8443) | OpenSSL: Handshake: start | OpenSSL: Loop: before SSL initalisation | OpenSSL: Loop: SSLv3 read client hello A | OpenSSL: Loop: SSLv3 write server hello A | OpenSSL: Loop: SSLv3 write change cipher spec A | OpenSSL: Loop: SSLv3 write finished A | OpenSSL: Loop: SSLv3 flush data | OpenSSL: Loop: SSLv3 read finished A | OpenSSL: Handshake: done | Connection: Client IP: 192.76.162.40, Protocol: SSLv3, Cipher: RC4-MD5 (128/128 bits) | Connection to child 0 closed (server en1.engelschall.com:8443) So, how can you now profit from this new knowledge? First you should recognize that Apache+mod_ssl+OpenSSL allow such renegotiations since version 2.1.3 Actually AFAIK currently mod_ssl is the only SSL solution for Apache which supports it. Then, when you want to use the `Global Server ID' stuff with Apache+mod_ssl+OpenSSL all you have to do is to use an appropriate server certificate. But now, how can you get such an appropriate server certificate? Obviously the easiest but most expensive way is to order a `Global Server ID' from Verisign, Inc, USA. It currently costs you $695,00. When you don't know your clients or cannot configure their webservers (the reason for this you will see later) this is the only chance, of course. Because per default Communicator has only a few pre-defined CA certificates. But let us assume you want to do it just for fun and for testing purposes or you want to use this for your Intranet or closed user group only. Here are the steps you have to perform as an overview: 1. You have to create a standard CA certificate 2. You have to create a server certificate with the extKeyUsage field 3. You have to sign the server certificate with the CA certificate 4. You have to import the CA certificate into the client's browser 5. You have to tag the CA certificate inside the client's browser database And in details: o Create CA and Server certificate Use the shell script gid-mkcert.sh (can be found inside the mod_ssl distribution under pkg.contrib/) to generate a custom root CA certificate & private key pair and a server certificate & private key pair signed by this CA. The result are at least four PEM-encoded files: ca.crt/ca.key (CA cert/key) and server.crt/server.key (server cert/key). Configure the server.crt and server.key files as usual with SSLCertifiateFile and SSLCertificateKeyFile inside your Apache+mod_ssl+OpenSSL webserver. o Import the CA certificate into the browser Fire up your Communicator and use the Perl script loadcacert.cgi (also inside pkg.contrib/) to load the ca.crt file into the browser. You have to walk through the dialog boxes which pop up. Then go to `Communicator -> Security Info -> Signers' and click on your imported CA. Then push the `Edit' button and accept this CA with the radio buttons. When you now go back and push the `Verify' button all should be ok. o Tag the CA certificate in the browser database At least now all is ok for Communicator. But the certificate is still a standard one. You have to tag it manually for the `Global Server ID' facility. For this shutdown your Communicator first. Then go to your $HOME/.netscape/ directory and patch the cert7.db file (make a copy first, please) with the gid-tagcert.c program (can be found also in pkg.contrib/). The output should read like this (replace the name with your real CA name as it's displayed in the Communicator list panel). $ tagcacert cert7.db 'SnakeOil CA - SnakeOil, Ltd' Trustflags changed from 0x0018 to 0x0238 Now the CA certificate is tagged as the pre-defined ones. You can fire up Communicator again. Now fire up your Apache and connect to it. After you got the welcome page, go to `Communicator -> Security Info -> Open Page Info'. Under "Security:" there should be the following text occur now: ``This is a secure document that uses a high-grade encryption key for U.S. domestic use only (RC4, 128 bit).'' Voila! Although you're using an export-grade Communicator you've now established a HTTPS connection with full-strength 128 bit cryptography. Many thanks to Matthias Loepfe for the initial research and hacking on this topic. ____________ References: [1] Fortify http://www.fortify.net/ [2] Global Server ID (Verisign) http://www.verisign.com/globalserver/ [3] International Step-Up (Netscape) http://home.netscape.com/products/security/technology/128bit.html [4] Server Gated Cryptography (Microsoft) http://microsoft.com/security/tech/sgc/ [5] SGC WhitePaper (Microsoft) http://microsoft.com/industry/finserv/press/SGCpaper.stm [6] extKeyUsage (PKIX) ftp://ietf.org/internet-drafts/draft-ietf-pkix-ipki-part1-11.txt