Hi all,

I am having trouble getting OpenSSL to understand my server key exchange

messages so am trying to determine how OpenSSL checks these messages.

The version of OpenSSL is 0.9.2b.

The steps our SSL server took to create the message:

The result of computing the MD5/SHA message digests using the client
and server random structures and the RSA key exchange parameters is:

00000: 85 49 9A 18 36 87 6E C2  03 3C 90 D8 45 48 15 8E
.I..6.n..<..EH..
00016: 4C 8F 04 B2 BF B4 B6 AC  E5 89 61 C8 B2 DD 3C CA
L.........a...<.
00032: 5F EF 53 31                                        _.S1

The above byte array is signed using the private key corresponding to
the
public key sent in the server certificate message. The PKCS#1 block as
constructed while signing the above data:

00000: 00 01 FF FF FF FF FF FF  FF FF FF FF FF FF FF FF
................
00016: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF
................
00032: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF
................
00048: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF
................
00064: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF
................
00080: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF 00
................
00096: 30 1E 30 0A 06 08 2A 86  48 86 F7 0D 02 05 04 10
0.0...*.H.......
00112: 22 77 F3 01 D9 F8 7B 44  E1 FD 60 CD 24 1E 54 C5
"w....{D..`.$.T.

The second last row is the opening DER encoding and the MD identifier.
The second line is the MD5 MD of the above data.

Server key exchange message sent from our SSL server:

00000: 0C 00 00 CA 00 41 00 9B  00 51 21 29 87 FC D4 72
.....A...Q!)...r
00016: 2F F7 25 A6 5D BD D8 65  9B 53 39 A0 7F B4 12 BD
/.%.]..e.S9....
00032: 00 F1 A7 53 04 0D 10 8D  15 3A A9 46 01 8B 2D 2D
...S.....:.F..--
00048: D9 01 29 7A BA EC 64 88  34 99 B6 A5 65 19 A7 8A
..)z..d.4...e...
00064: 30 95 56 63 31 C4 63 00  03 01 00 01 00 80 9A 60
0.Vc1.c........`
00080: 3C F0 B8 27 1E DA DA 30  1A 28 73 D8 DF A9 CB 2C
<..'...0.(s....,
00096: 47 B0 EB F0 F5 7C 8D C2  80 AA C6 FA 0A DF 95 A6
G....|..........
00112: 35 C2 2D 7D 2E 36 C8 B5  2E 30 F3 92 2D 89 21 C5
5.-}.6...0..-.!.
00128: 19 2C 6B 92 A5 EC BF 15  24 E8 B1 D0 10 B7 C7 8B
.,k.....$.......
00144: 19 D7 F7 8E CB 4B 76 11  E0 17 FE A2 57 A7 DA 60
.....Kv.....W..`
00160: 30 F5 FC 2E F6 35 7A 1D  2F 38 3C 8E E4 D2 F6 3E
0....5z./8<....>
00176: AE 20 9A 14 00 9E 2D 23  10 1F C0 4C AA B6 BA D0   .
....-#...L....
00192: 55 DE 77 CF D7 A5 21 2C  A7 C0 00 F1 0D F6         U.w...!,......



The server key exchange message contents received by OpenSSL (slightly
different as the message header is not shown):

00 41 00 9b 00 51 21 29 87 fc d4 72 2f f7 25 a6
5d bd d8 65 9b 53 39 a0 7f b4 12 bd 00 f1 a7 53
04 0d 10 8d 15 3a a9 46 01 8b 2d 2d d9 01 29 7a
ba ec 64 88 34 99 b6 a5 65 19 a7 8a 30 95 56 63
31 c4 63 00 03 01 00 01 00 80 9a 60 3c f0 b8 27
1e da da 30 1a 28 73 d8 df a9 cb 2c 47 b0 eb f0
f5 7c 8d c2 80 aa c6 fa 0a df 95 a6 35 c2 2d 7d
2e 36 c8 b5 2e 30 f3 92 2d 89 21 c5 19 2c 6b 92
a5 ec bf 15 24 e8 b1 d0 10 b7 c7 8b 19 d7 f7 8e
cb 4b 76 11 e0 17 fe a2 57 a7 da 60 30 f5 fc 2e
f6 35 7a 1d 2f 38 3c 8e e4 d2 f6 3e ae 20 9a 14
00 9e 2d 23 10 1f c0 4c aa b6 ba d0 55 de 77 cf
d7 a5 21 2c a7 c0 00 f1 0d f6


The MD5/SHA message digests as computed by OpenSSL using the
client and server random and the RSA key exchange parameters
taken from the server key exchange message are:

85 49 9a 18 36 87 6e c2 03 3c 90 d8 45 48 15 8e
4c 8f 04 b2 bf b4 b6 ac e5 89 61 c8 b2 dd 3c ca
5f ef 53 31

This is the same result as computed by our SSL server.


When OpenSSL checks the signature with the public key received
with the server certificate message, the following is returned:

30 1e 30 0a 06 08 2a 86 48 86 f7 0d 02 05 04 10
22 77 f3 01 d9 f8 7b 44 e1 fd 60 cd 24 1e 54 c5

The PKCS#1 padding had been removed by the time my debugging
code saw the result but the DER encoding and the MD5 message
digest are the same.

To my mind the next step should have been for OpenSSL to compute
the MD5 digest of the combined MD5/SHA message digests computed
from the client and server randoms and the tempory RSA key parameters
and then compare that message digest to the one in the signature.

However, what happens is OpenSSL closes the connection claiming
the signature is bad based on the following:

My debugging info in OpenSSL shows:

Failing with bad signature - why?
36 == 32?
p:
30 1e 30 0a 06 08 2a 86 48 86 f7 0d 02 05 04 10
22 77 f3 01 d9 f8 7b 44 e1 fd 60 cd 24 1e 54 c5

md_buf:
85 49 9a 18 36 87 6e c2 03 3c 90 d8 45 48 15 8e
4c 8f 04 b2 bf b4 b6 ac e5 89 61 c8 b2 dd 3c ca

There are two problems here.

i) OpenSSL is checking two numbers against each other that
are now equal but as everything so far has worked correctly,
what is wrong?

ii) If the first check did work, the second check would fail
because OpenSSL is checking the combined MD5/SHA message
digests computed earlier to the output from an MD5 message
digest of that value that is contained in the signature.

This check is done in the following code in s3_clnt.c:

  if (pkey->type == EVP_PKEY_RSA)
   {
   int num;
   j=0;
   q=md_buf;
   for (num=2; num > 0; num--)
    {
    EVP_DigestInit(&md_ctx,(num == 2)
     ?s->ctx->md5:s->ctx->sha1);

EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);

EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
    EVP_DigestUpdate(&md_ctx,param,param_len);
    EVP_DigestFinal(&md_ctx,q,(unsigned int *)&i);
    q+=i;
    j+=i;
    }

*** at this point, md_buf contains the MD5 message digest of the randoms

*** and params followed by the SHA message digest of same. This is the
info
*** that is put through an MD5 during the signature creation process.

   i=RSA_public_decrypt((int)n,p,p,pkey->pkey.rsa,
    RSA_PKCS1_PADDING);
   if (i <= 0)
    {
    al=SSL_AD_DECRYPT_ERROR;
    SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT);
    goto f_err;
    }

*** now the signature has been decrypted and the PKCS#1 padding removed.

   if ((j != i) || (memcmp(p,md_buf,i) != 0))
    {
*** this is where the above debugging message comes out. Even if j == i,
the
*** memcmp test seems to be testing apples and oranges.

    /* bad signature */
    al=SSL_AD_DECRYPT_ERROR;
    SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE);
    goto f_err;
    }
   }

I've asked OpenSSL to talk to itself and server key exchange messages
seem
to work okay, so we must have different ideas of what goes into the
signature.

I'm happy to be proved wrong on any of this, as long as someone can give
an
explanation of exactly how the server key exchange message should be
created.
I can't read the OpenSSL code well enough to know where to put all the
debugging info I need in the server :(

--

Regards,
David Taylor

=======================================================================
David Taylor                           e-mail  [EMAIL PROTECTED]
Software Engineer
Forge Research Pty Ltd                 Phone  +61 2 9209 4175
PO Box 598, Alexandria                 Fax    +61 2 9209 4172
NSW 1435, Australia                    Web     http://www.forge.com.au
=======================================================================

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to