I am seeing some strange behaviour with openssl, versions 0.9.8e, f, g and h on a Gentoo Linux 2.6.22 machine Intel Core2 (amd64 architecture). Following some googling with gentoo, I have built each version with and without enable-tlsext.
The problem that I am seeing is that an openssl server, using any of the above named releases, is successfully serving some connections and rejecting others (all when using the same certificates). I first encountered this with exim 4.69 and TLS and apache 2.2.8-r4 with SSLv3. I reproduced the problem using openssl s_client and openssl s_server, which I hoped would simplify debugging. The problem, simply stated: >From my own machine, Apache https works correctly with: w3m (using whichever the current version of libssl I am testing) firefox 2.009 - using 32 bit pre-compiled binaries (thus not the currently installed libssl) opera 9.50 - again with pre-compiled 32 bit binaries (thus not the currently installed libssl) openssl s_client -connect j-e-s.net:443 -debug -state -msg -ssl3 >From my wife's machine - running Debian Linux on Intel 32, the https server also works for: firefox 2.009 opera 9.50 A very old version of Netscape - I can't currently get the version number w3m openssl s_client ... However, from Windows XP and Windows 98 using IE6 and IE7, Firefox 2.x, Opera 8.x, and some version of Safari, it fails. Again, no version numbers, as these are non-technical friends who tried remote connections and reported failures) The same problem arises from a FreeBSD 7 machine using Firefox 2.x, w3m, and openssl s_client. I began testing with s_client and s_server to simplify debugging: A successful session runs through (-debug and -msg omitted, as there's no problem to be seen +++++++++++++++++++++++++++++++++++++++++++++++++++++++ [EMAIL PROTECTED]:/root# openssl s_client -connect j-e-s.net:443 -state -ssl3 CONNECTED(00000003) SSL_connect:before/connect initialization SSL_connect:SSLv3 write client hello A SSL_connect:SSLv3 read server hello A depth=0 /C=NL/ST=NH/O=j-e-s.net/CN=j-e-s.net verify error:num=20:unable to get local issuer certificate verify return:1 depth=0 /C=NL/ST=NH/O=j-e-s.net/CN=j-e-s.net verify error:num=27:certificate not trusted verify return:1 depth=0 /C=NL/ST=NH/O=j-e-s.net/CN=j-e-s.net verify error:num=21:unable to verify the first certificate verify return:1 SSL_connect:SSLv3 read server certificate A SSL_connect:SSLv3 read server key exchange A SSL_connect:SSLv3 read server done A SSL_connect:SSLv3 write client key exchange A SSL_connect:SSLv3 write change cipher spec A SSL_connect:SSLv3 write finished A SSL_connect:SSLv3 flush data SSL_connect:SSLv3 read finished A --- Certificate chain 0 s:/C=NL/ST=NH/O=j-e-s.net/CN=j-e-s.net i:/O=j-e-s.net/[EMAIL PROTECTED]/L=Amsterdam/ST=NH/C=NL/CN=Jim Segr\ ave --- Server certificate -----BEGIN CERTIFICATE----- MIIC7jCCAdYCAhALMA0GCSqGSIb3DQEBBAUAMHYxEjAQBgNVBAoTCWotZS1zLm5l [snip] JtyoEPpZrqvLKMPcWT1Pu3n0y9xpkh9kQ5KhW2o0KWXfMQ== -----END CERTIFICATE----- subject=/C=NL/ST=NH/O=j-e-s.net/CN=j-e-s.net issuer=/O=j-e-s.net/[EMAIL PROTECTED]/L=Amsterdam/ST=NH/C=NL/CN=Jim Segrave --- No client certificate CA names sent --- SSL handshake has read 1590 bytes and written 442 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA Server public key is 1024 bit SSL-Session: Protocol : SSLv3 Cipher : DHE-RSA-AES256-SHA Session-ID: 1FFB6D486555ABDD06EDC8DC6E20BBE96C54151F31BC1919B737BF72A4C84354 Session-ID-ctx: Master-Key: BC107DE1CD0E0A0B37854EB68AC4D983839EC49375EA20945846D8172E56D427A69A8D78B9C\ C39C862B5A44A0054AB79 Key-Arg : None Start Time: 1213966029 Timeout : 7200 (sec) Verify return code: 21 --- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Here is a client view of a failed session from a FreeBSD machine using the command openssl s_client -connect j-e-s.net:443 -debug -msg -stat -ssl3 I've snipped some but not all of the hex dump away to concentrate on the problem areas. Note that the encryption/integrity choice 00 39, is DHE-RSA-AES256-SHA, the same as in the successful session above, so it's not an encryption error for some protocol. Following this is the output from the openssl s_server to which this was connecting, so the messages can be matched up: CONNECTED(00000003) write to 0x606160 [0x67d000] (98 bytes => 98 (0x62)) >>> SSL 3.0 Handshake [length 005d], ClientHello 01 00 00 59 03 00 48 5b aa fa 5e 8e b8 30 28 5b 4e 87 4c 3e 2a 28 fa 94 fb 6e 12 6c 2a 54 82 0c 14 96 f0 f8 64 35 00 00 32 00 39 00 38 00 35 00 88 00 87 00 84 00 16 00 13 00 0a 00 33 00 32 00 2f 00 45 00 44 00 41 00 05 00 04 00 15 00 12 00 09 00 14 00 11 00 08 00 06 00 03 01 00 read from 0x606160 [0x678000] (5 bytes => 5 (0x5)) 0000 - 16 03 00 00 4a ....J read from 0x606160 [0x678005] (74 bytes => 74 (0x4A)) <<< SSL 3.0 Handshake [length 004a], ServerHello 02 00 00 46 03 00 48 5b aa fa 24 51 cf c1 fa af 8f d2 ec 0f b6 6f 8a cd 62 68 41 f6 fc ba 0b 22 a4 7e 38 c8 51 01 20 3d 45 e5 2f 70 e2 43 c2 67 1d 46 49 18 4b c0 90 b3 a2 41 d2 b6 65 73 28 6e 3b 1f 31 b1 15 95 65 00 39 00 read from 0x606160 [0x678000] (5 bytes => 5 (0x5)) 0000 - 16 03 00 02 fc ..... read from 0x606160 [0x678005] (764 bytes => 764 (0x2FC)) <<< SSL 3.0 Handshake [length 02fc], Certificate [snip data] read from 0x606160 [0x678000] (5 bytes => 5 (0x5)) 0000 - 16 03 00 02 8d ..... read from 0x606160 [0x678005] (653 bytes => 653 (0x28D)) <<< SSL 3.0 Handshake [length 028d], ServerKeyExchange [snip data] read from 0x606160 [0x678000] (5 bytes => 5 (0x5)) 0000 - 16 03 00 00 04 ..... read from 0x606160 [0x678005] (4 bytes => 4 (0x4)) <<< SSL 3.0 Handshake [length 0004], ServerHelloDone 0e 00 00 00 >>> SSL 3.0 Handshake [length 0106], ClientKeyExchange [snip data] write to 0x606160 [0x683000] (267 bytes => 267 (0x10B)) [snip data] >>> SSL 3.0 ChangeCipherSpec [length 0001] 01 write to 0x606160 [0x683000] (6 bytes => 6 (0x6)) 0000 - 14 03 00 00 01 01 ...... Here I've left the data in, as it's very relevant - the unencrypted hash of the handshake messages etc: >>> SSL 3.0 Handshake [length 0028], Finished 14 00 00 24 df e8 75 30 88 46 8d 3e 96 51 30 90 2c 7d 47 c9 da 19 13 5c c1 43 f2 05 82 d9 bf 51 33 9e 4b 06 c8 c3 74 75 The encrypted version of the hash of the handshake messages: write to 0x606160 [0x683000] (69 bytes => 69 (0x45)) 0000 - 16 03 00 00 40 a5 fb 1a-87 b0 a7 f9 6e c7 2d f8 [EMAIL PROTECTED] 0010 - ed 50 57 8c 29 4e 19 78-b6 3b 0d f6 d0 6b 87 38 .PW.)N.x.;...k.8 0020 - d8 e2 8f 45 7b 3a 18 76-ec b7 35 3f f9 42 c2 52 ...E{:.v..5?.B.R 0030 - 00 47 b5 65 79 b4 64 13-a4 d0 0d fe 8e b1 5c e0 .G.ey.d.......\. 0040 - 9b 37 e1 d6 30 .7..0 The openssl s_server was not impressed: read from 0x606160 [0x678000] (5 bytes => 5 (0x5)) 0000 - 15 03 00 00 02 ..... read from 0x606160 [0x678005] (2 bytes => 2 (0x2)) 0000 - 02 28 .( <<< SSL 3.0 Alert [length 0002], fatal handshake_failure 02 28 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Here's what the server saw during that same session (port 443 is being redirected to port 2443): Script started on Fri 20 Jun 2008 03:04:29 PM CEST root:/var/tmp$ openssl s_server -accept 2443 -cert /etc/apache2/ssl/jes-net-1024.crt -key /etc/apache2/ssl/jes-net-1024.key -dhparam /etc/apache2/ssl/dh.parm -state -debug -msg Setting temp DH parameters Using default temp ECDH parameters ACCEPT SSL_accept:before/accept initialization read from 0x6889b0 [0x68e090] (11 bytes => 11 (0xB)) read from 0x6889b0 [0x68e09b] (87 bytes => 87 (0x57)) <<< SSL 3.0 Handshake [length 005d], ClientHello 01 00 00 59 03 00 48 5b aa fa 5e 8e b8 30 28 5b 4e 87 4c 3e 2a 28 fa 94 fb 6e 12 6c 2a 54 82 0c 14 96 f0 f8 64 35 00 00 32 00 39 00 38 00 35 00 88 00 87 00 84 00 16 00 13 00 0a 00 33 00 32 00 2f 00 45 00 44 00 41 00 05 00 04 00 15 00 12 00 09 00 14 00 11 00 08 00 06 00 03 01 00 SSL_accept:SSLv3 read client hello A >>> SSL 3.0 Handshake [length 004a], ServerHello 02 00 00 46 03 00 48 5b aa fa 24 51 cf c1 fa af 8f d2 ec 0f b6 6f 8a cd 62 68 41 f6 fc ba 0b 22 a4 7e 38 c8 51 01 20 3d 45 e5 2f 70 e2 43 c2 67 1d 46 49 18 4b c0 90 b3 a2 41 d2 b6 65 73 28 6e 3b 1f 31 b1 15 95 65 00 39 00 write to 0x6889b0 [0x6982e0] (79 bytes => 79 (0x4F)) SSL_accept:SSLv3 write server hello A >>> SSL 3.0 Handshake [length 02fc], Certificate [snip data] write to 0x6889b0 [0x6982e0] (769 bytes => 769 (0x301)) 0000 - 16 03 00 02 fc 0b 00 02-f8 00 02 f5 00 02 f2 30 ...............0 [snip remainder] SSL_accept:SSLv3 write certificate A >>> SSL 3.0 Handshake [length 028d], ServerKeyExchange [snip data] write to 0x6889b0 [0x6982e0] (658 bytes => 658 (0x292)) 0000 - 16 03 00 02 8d 0c 00 02-89 01 00 c7 62 b9 1e 78 ............b..x [snip remainder] SSL_accept:SSLv3 write key exchange A >>> SSL 3.0 Handshake [length 0004], ServerHelloDone 0e 00 00 00 write to 0x6889b0 [0x6982e0] (9 bytes => 9 (0x9)) 0000 - 16 03 00 00 04 0e ...... 0009 - <SPACES/NULS> SSL_accept:SSLv3 write server done A SSL_accept:SSLv3 flush data read from 0x6889b0 [0x68e090] (5 bytes => 5 (0x5)) 0000 - 16 03 00 01 06 ..... read from 0x6889b0 [0x68e095] (262 bytes => 262 (0x106)) 0000 - 10 00 01 02 01 00 55 f5-cb 5f 1a 15 c9 e9 f9 2e ......U.._...... [snip data] <<< SSL 3.0 Handshake [length 0106], ClientKeyExchange 10 00 01 02 01 00 55 f5 cb 5f 1a 15 c9 e9 f9 2e [snip data] SSL_accept:SSLv3 read client key exchange A read from 0x6889b0 [0x68e090] (5 bytes => 5 (0x5)) 0000 - 14 03 00 00 01 ..... read from 0x6889b0 [0x68e095] (1 bytes => 1 (0x1)) 0000 - 01 . <<< SSL 3.0 ChangeCipherSpec [length 0001] 01 read from 0x6889b0 [0x68e090] (5 bytes => 5 (0x5)) 0000 - 16 03 00 00 40 ....@ Here's the encrypted closing handshake from the client - note that it matches the encrypted write from the client log: read from 0x6889b0 [0x68e095] (64 bytes => 64 (0x40)) 0000 - a5 fb 1a 87 b0 a7 f9 6e-c7 2d f8 ed 50 57 8c 29 .......n.-..PW.) 0010 - 4e 19 78 b6 3b 0d f6 d0-6b 87 38 d8 e2 8f 45 7b N.x.;...k.8...E{ 0020 - 3a 18 76 ec b7 35 3f f9-42 c2 52 00 47 b5 65 79 :.v..5?.B.R.G.ey 0030 - b4 64 13 a4 d0 0d fe 8e-b1 5c e0 9b 37 e1 d6 30 .d.......\..7..0 And here's the decrypted closing handshake, which again, matches the unencrypted data from the client log: <<< SSL 3.0 Handshake [length 0028], Finished 14 00 00 24 df e8 75 30 88 46 8d 3e 96 51 30 90 2c 7d 47 c9 da 19 13 5c c1 43 f2 05 82 d9 bf 51 33 9e 4b 06 c8 c3 74 75 And here the server complains: write to 0x6889b0 [0x6982e0] (7 bytes => 7 (0x7)) 0000 - 15 03 00 00 02 02 28 ......( >>> SSL 3.0 Alert [length 0002], fatal handshake_failure 02 28 SSL3 alert write:fatal:handshake failure SSL_accept:failed in SSLv3 read finished A ERROR 12325:error:1408C095:SSL routines:SSL3_GET_FINISHED:digest check failed:s3_both.c:231: shutting down SSL CONNECTION CLOSED ACCEPT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Now the same FreeBSD openssl s_client isn't broken - if I aim it for example, at www.amazon.com:443, the session comes up without problems. Nor is the openssl s_client on my machine broken - I too, can connect to various public https sites using the openssl s_client. So the problem appears to be that if both s_clients are working, then the server must be erroneous, but in a way that is compatible with my local client and not with other, remote clients. Does anyone have any further ideas? I may be able to create a debugging openssl on the FreeBSD server where I can track how the closing handshake is built by the client (although I'm not sure where to find the places where the digest is being built so I can dump the data and results. Any help there would be appreciated). Similarly I can do the same for a local client and a server, as I'd like to know how it is that a local client can create the closing handshake data such that it's accepted by other https servers as well as this one, whereas some other s_clients and many other browsers do not generate closing handshakes that this server accepts. -- Jim Segrave [EMAIL PROTECTED] ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]