1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
|
_ _
_ __ ___ ___ __| | ___ ___| | 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 <Matthias.Loepfe@AdNovum.CH>
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
|