Closed Bug 363073 Opened 18 years ago Closed 18 years ago

ECC TLS client crashes if the server doesn't send the ServerKeyExchange message

Categories

(NSS :: Libraries, defect, P1)

3.11.4
defect

Tracking

(Not tracked)

RESOLVED FIXED
3.11.5

People

(Reporter: wtc, Assigned: wtc)

References

Details

(Whiteboard: [hot fix in 3.11.5])

Attachments

(3 files, 1 obsolete file)

Based on the information Vipul provided in email, I commented out all the ssl3_AppendXXX calls in ssl3_SendECDHServerKeyExchange so that our ECC TLS server doesn't send the ServerKeyExchange message, and ran all.sh. I got tstclnt and strsclnt to crash. This may or may not be the Firefox crash that Vipul saw. Here is a stack trace of tstclnt: (gdb) where #0 0x005cf095 in memcpy () from /lib/tls/libc.so.6 #1 0x009bd7b1 in sftk_NewAttribute (object=0x95115c8, type=384, value=0xa, len=156304975) at pkcs11u.c:98 #2 0x009c14d9 in sftk_AddAttributeType (object=0x95115c8, type=384, valPtr=0xa, length=156304975) at pkcs11u.c:2080 #3 0x009b8444 in NSC_GenerateKeyPair (hSession=1, pMechanism=0xbff928f0, pPublicKeyTemplate=0xbff92920, ulPublicKeyAttributeCount=7, pPrivateKeyTemplate=0xbff92ae0, ulPrivateKeyAttributeCount=7, phPublicKey=0xbff928d0, phPrivateKey=0xbff928d4) at pkcs11c.c:3371 #4 0x0013449a in PK11_GenerateKeyPairWithFlags (slot=0x94e2348, type=4160, param=0x95105a8, pubKey=0xbff92c00, attrFlags=138, wincx=0x0) at pk11akey.c:988 #5 0x0013490b in PK11_GenerateKeyPair (slot=0x94e2348, type=4160, param=0x95105a8, pubKey=0xbff92c00, token=0, sensitive=0, wincx=0x0) at pk11akey.c:1105 #6 0x0012c045 in SECKEY_CreateECPrivateKey (param=0x95105a8, pubk=0xbff92c00, cx=0x0) at seckey.c:258 #7 0x00ce4311 in ssl3_SendECDHClientKeyExchange (ss=0x94e9e90, svrPubKey=0x9510598) at ssl3ecc.c:350 #8 0x00cc6a8d in ssl3_SendClientKeyExchange (ss=0x94e9e90) at ssl3con.c:4322 #9 0x00cc873c in ssl3_HandleServerHelloDone (ss=0x94e9e90) at ssl3con.c:5214 #10 0x00ccd605 in ssl3_HandleHandshakeMessage (ss=0x94e9e90, b=0x94f1c26 "", length=0) at ssl3con.c:7706 #11 0x00ccd8cb in ssl3_HandleHandshake (ss=0x94e9e90, origBuf=0x94ea0ec) at ssl3con.c:7793 #12 0x00cce19e in ssl3_HandleRecord (ss=0x94e9e90, cText=0xbff92e00, databuf=0x94ea0ec) at ssl3con.c:8056 #13 0x00ccf38f in ssl3_GatherCompleteHandshake (ss=0x94e9e90, flags=0) at ssl3gthr.c:206 #14 0x00cd1d3b in ssl_GatherRecord1stHandshake (ss=0x94e9e90) at sslcon.c:1258 #15 0x00cd94e9 in ssl_Do1stHandshake (ss=0x94e9e90) at sslsecur.c:149 #16 0x00cdb406 in ssl_SecureSend (ss=0x94e9e90, buf=0xbff92f60 "GET / HTTP/1.0\r\n\r\nhare/dev1/nspr/wtchang/nss-3.11-branch -extended-ecc/mozilla/security/nss/cmd/tstclnt/Linux2.6_x86_glibc_PTH_DBG.OBJ/ts tclnt", len=18, flags=0) at sslsecur.c:1090 #17 0x00ce10fc in ssl_Send (fd=0x94e9cb8, buf=0xbff92f60, len=18, flags=0, timeout=4294967295) at sslsock.c:1414 #18 0x00a185b1 in PR_Send (fd=0x94e9cb8, buf=0xbff92f60, amount=18, flags=0, timeout=4294967295) at ../../../../pr/src/io/priometh.c:226 #19 0x0804d1df in main (argc=13, argv=0xbff945a4) at tstclnt.c:890
Apply this patch to NSS_3_11_BRANCH, build Extended ECC, and run all.sh to reproduce this bug. strsclnt crashed at the same place: (gdb) where #0 0x005cf095 in memcpy () from /lib/tls/libc.so.6 #1 0x002447b1 in sftk_NewAttribute (object=0x9401210, type=384, value=0xa, len=155182999) at pkcs11u.c:98 #2 0x002484d9 in sftk_AddAttributeType (object=0x9401210, type=384, valPtr=0xa, length=155182999) at pkcs11u.c:2080 #3 0x0023f444 in NSC_GenerateKeyPair (hSession=16777217, pMechanism=0xb7fb79f0, pPublicKeyTemplate=0xb7fb7a20, ulPublicKeyAttributeCount=7, pPrivateKeyTemplate=0xb7fb7be0, ulPrivateKeyAttributeCount=7, phPublicKey=0xb7fb79d0, phPrivateKey=0xb7fb79d4) at pkcs11c.c:3371 #4 0x006be49a in PK11_GenerateKeyPairWithFlags (slot=0x93a8490, type=4160, param=0x93fe6f0, pubKey=0xb7fb7d00, attrFlags=138, wincx=0x0) at pk11akey.c:988 #5 0x006be90b in PK11_GenerateKeyPair (slot=0x93a8490, type=4160, param=0x93fe6f0, pubKey=0xb7fb7d00, token=0, sensitive=0, wincx=0x0) at pk11akey.c:1105 #6 0x006b6045 in SECKEY_CreateECPrivateKey (param=0x93fe6f0, pubk=0xb7fb7d00, cx=0x0) at seckey.c:258 #7 0x00998311 in ssl3_SendECDHClientKeyExchange (ss=0x93d9d98, svrPubKey=0x93fe6e0) at ssl3ecc.c:350 #8 0x0097aa8d in ssl3_SendClientKeyExchange (ss=0x93d9d98) at ssl3con.c:4322 #9 0x0097c73c in ssl3_HandleServerHelloDone (ss=0x93d9d98) at ssl3con.c:5214 #10 0x00981605 in ssl3_HandleHandshakeMessage (ss=0x93d9d98, b=0x93e17ee "", length=0) at ssl3con.c:7706 #11 0x009818cb in ssl3_HandleHandshake (ss=0x93d9d98, origBuf=0x93d9ff4) at ssl3con.c:7793 #12 0x0098219e in ssl3_HandleRecord (ss=0x93d9d98, cText=0xb7fb7f00, databuf=0x93d9ff4) at ssl3con.c:8056 #13 0x0098338f in ssl3_GatherCompleteHandshake (ss=0x93d9d98, flags=0) at ssl3gthr.c:206 #14 0x00985d3b in ssl_GatherRecord1stHandshake (ss=0x93d9d98) at sslcon.c:1258 #15 0x0098d4e9 in ssl_Do1stHandshake (ss=0x93d9d98) at sslsecur.c:149 #16 0x0098f406 in ssl_SecureSend (ss=0x93d9d98, buf=0x80576b6 "GET /abc HTTP/1.0\r\n\r\n", len=21, flags=0) at sslsecur.c:1090 #17 0x009950fc in ssl_Send (fd=0x93bb528, buf=0x80576b6, len=21, flags=0, timeout=4294967295) at sslsock.c:1414 #18 0x001d95b1 in PR_Send (fd=0x93bb528, buf=0x80576b6, amount=21, flags=0, timeout=4294967295) at ../../../../pr/src/io/priometh.c:226 #19 0x0804c997 in handle_connection (ssl_sock=0x93bb528, tid=0) at strsclnt.c:693 #20 0x0804d07c in do_connects (a=0xbfeae2f0, b=0x93af980, tid=0) at strsclnt.c:884 #21 0x0804c24d in thread_wrapper (arg=0x805fe40) at strsclnt.c:436 #22 0x001fc136 in _pt_root (arg=0x93bb400) at ../../../../pr/src/pthreads/ptthread.c:220 #23 0x007993ae in start_thread () from /lib/tls/libpthread.so.0 #24 0x0062baee in clone () from /lib/tls/libc.so.6
I printed some values in the debugger: #3 0x00263444 in NSC_GenerateKeyPair (hSession=16777217, pMechanism=0xb7fb79f0, pPublicKeyTemplate=0xb7fb7a20, ulPublicKeyAttributeCount=7, pPrivateKeyTemplate=0xb7fb7be0, ulPrivateKeyAttributeCount=7, phPublicKey=0xb7fb79d0, phPrivateKey=0xb7fb79d4) at pkcs11c.c:3371 3371 crv = sftk_AddAttributeType(publicKey, (gdb) print pPublicKeyTemplate[0] $5 = {type = 384, pValue = 0xa, ulValueLen = 167016343} (gdb) print i $6 = 0 Note: 384 is CKA_EC_PARAMS. ulValueLen seems to be garbge because other core files have different values of ulValueLen. pValue is 0xa in all core files. #4 0x00c7349a in PK11_GenerateKeyPairWithFlags (slot=0x9ef1490, type=4160, param=0x9f476f0, pubKey=0xb7fb7d00, attrFlags=138, wincx=0x0) at pk11akey.c:988 988 crv = PK11_GETTAB(slot)->C_GenerateKeyPair(session_handle, &mechanis m, (gdb) print param $8 = (void *) 0x9f476f0 (gdb) print ecParams $9 = (SECKEYECParams *) 0x9f476f0 (gdb) print *ecParams $10 = {type = siBuffer, data = 0xa "", len = 167016343} #7 0x00fcc311 in ssl3_SendECDHClientKeyExchange (ss=0x9f22d98, svrPubKey=0x9f476e0) at ssl3ecc.c:350 350 privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParam s, (gdb) print svrPubKey->u.ec $17 = {DEREncodedParams = {type = siBuffer, data = 0xa "", len = 167016343}, size = 128, publicValue = {type = siUnsignedInteger, data = 0x9f47819 "\001", len = 3}}
Taking. I invite discussion on the priority and target milestone of this bug. Vipul, please add a comment here telling us about what kind (brand) of server you were testing with that failed to send a Server Key Exchange? I hope it wasn't an NSS server.
Assignee: nobody → nelson
Priority: -- → P1
Target Milestone: --- → 3.11.5
The output.log file is too big to attach, so I reproduce the relevant excerpts here. It shows that all the crashes occurred with ECDHE RSA cipher suites (C010 - C014): ssl.sh: running TLS ECDHE RSA WITH AES 128 CBC SHA ---------------------------- kill -0 21012 >/dev/null 2>/dev/null selfserv with PID 21012 found at Thu Dec 7 07:41:23 PST 2006 tstclnt -p 8443 -h earthquake.dsdev.sjc.redhat.com -c :C013 -B -s \ -f -d ../client < /share/dev1/nspr/wtchang/nss-3.11-branch-extended-ecc/ mozilla/security/nss/tests/ssl/sslreq.dat ./ssl.sh: line 260: 21087 Segmentation fault tstclnt -p ${PORT} -h ${HOSTAD DR} -c ${param} ${TLS_FLAG} ${CLIENT_OPTIONS} -f -d ${P_R_CLIENTDIR} <${REQUEST_ FILE} >${TMP}/$HOST.tmp.$$ 2>&1 ssl.sh: TLS ECDHE RSA WITH AES 128 CBC SHA produced a returncode of 139, expecte d is 0 FAILED In contrast, ECDHE ECDSA cipher suites failed but didn't crash: ssl.sh: running TLS ECDHE ECDSA WITH AES 128 CBC SHA --------------------------- - kill -0 24930 >/dev/null 2>/dev/null selfserv with PID 24930 found at Thu Dec 7 07:42:29 PST 2006 tstclnt -p 8443 -h earthquake.dsdev.sjc.redhat.com -c :C009 -B -s \ -f -d ../ext_client < /share/dev1/nspr/wtchang/nss-3.11-branch-extended- ecc/mozilla/security/nss/tests/ssl/sslreq.dat selfserv: HDX PR_Read returned error -12273: SSL received a record with an incorrect Message Authentication Code. tstclnt: write to SSL socket failed: SSL peer reports incorrect Message Authenti cation Code. ssl.sh: TLS ECDHE ECDSA WITH AES 128 CBC SHA produced a returncode of 254, expec ted is 0 FAILED This is consistent with the fact that all the core files have serverKey->keyType equal to rsaKey in ssl3_SendClientKeyExchange.
I think this is where things start to go wrong in ssl3_SendClientKeyExchange: 4282 if (ss->sec.peerKey == NULL) { 4283 serverKey = CERT_ExtractPublicKey(ss->sec.peerCert); 4284 if (serverKey == NULL) { 4285 PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); 4286 return SECFailure; 4287 } 4288 } else { 4289 serverKey = ss->sec.peerKey; 4290 ss->sec.peerKey = NULL; /* we're done with it now */ 4291 } We incorrectly use the public key from the peer's cert as the peer's ephemeral public key. If the peer's cert has an ECDSA public key, we go on to do EC Diffie-Hellman key derivation with that key, but eventually will fail the handshake. If the peer's cert has an RSA public key, we crash in EC Diffie-Hellman key derivation because RSA public key, when interpreted as an EC public key, contains garbage. This patch fixes the crash by making sure the server's public key has the expected key type. It only fixes the symptom (crash), not the bug. I also patched the equivalent code in sendDHClientKeyExchange but don't have an easy way to test it.
Comment on attachment 247904 [details] [diff] [review] Patch to fix the crash (the symptom only) I tested both changes in this patch with Firefox 2.0 in a debugger. I injected the error in the debugger by setting ss->sec.peerKey to NULL in ssl3_SendClientKeyExchange for DHE-RSA and ECDHE-RSA, and verified that this patch was effective. Note that for DHE-RSA the original code doesn't crash because we eventually find out that the peer's ephemeral public key is of the wrong type in the PK11_PubDerive call made by sendDHClientKeyExchange, so the ssl3con.c change in this patch isn't necessary, but it catches that error sooner and avoids the useless SECKEY_CreateDHPrivateKey call (which succeeded in my test). Nelson, the bug is now all yours.
Comment on attachment 247904 [details] [diff] [review] Patch to fix the crash (the symptom only) r=nelson I think it is entirely appropriate to commit this fix now. That will eliminate the DOS potential. We can do something more elegant for 3.12. But this work will not have been wasted. Requesting second review for the 3.11 branch. Thanks for the patch, Wan-Teh!
Attachment #247904 - Flags: superreview?(alexei.volkov.bugs)
Attachment #247904 - Flags: review+
I checked in the "patch to fix the crash (the symptom only)", with a minor comment change (to not separate the XXX comment from the code it refers to), on the NSS trunk (NSS 3.12). Checking in ssl3con.c; /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v <-- ssl3con.c new revision: 1.99; previous revision: 1.98 done Checking in ssl3ecc.c; /cvsroot/mozilla/security/nss/lib/ssl/ssl3ecc.c,v <-- ssl3ecc.c new revision: 1.18; previous revision: 1.17 done
Attachment #247904 - Attachment is obsolete: true
Attachment #248016 - Flags: superreview?(alexei.volkov.bugs)
Attachment #247904 - Flags: superreview?(alexei.volkov.bugs)
Comment on attachment 248016 [details] [diff] [review] Patch to fix the crash (the symptom only) v1.1 Vipul confirmed that the ssl3ecc.c change in this patch fixed the crash for him, too.
Comment on attachment 248016 [details] [diff] [review] Patch to fix the crash (the symptom only) v1.1 r=nelson Carrying my r= forward to this patch from the previous one.
Attachment #248016 - Flags: review+
Comment on attachment 248016 [details] [diff] [review] Patch to fix the crash (the symptom only) v1.1 r=alexei.volkov.bugs
Attachment #248016 - Flags: superreview?(alexei.volkov.bugs) → superreview+
I checked in the "patch to fix the crash (the symptom only) v1.1" on the NSS_3_11_BRANCH (NSS 3.11.5). Checking in ssl3con.c; /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v <-- ssl3con.c new revision: 1.76.2.19; previous revision: 1.76.2.18 done Checking in ssl3ecc.c; /cvsroot/mozilla/security/nss/lib/ssl/ssl3ecc.c,v <-- ssl3ecc.c new revision: 1.3.2.11; previous revision: 1.3.2.10 done
Whiteboard: [hot fix in 3.11.5]
This bug reports a crash. Wan-Teh fixed the crash in NSS 3.11.5. I am reassigning this bug to him (to record that he fixed it), and then will mark it resolved/fixed. A new bug needs to be opened about the fact that the client uses the wrong key if/when the server omits the necessary SKE message.
Assignee: nelson → wtc
Status: NEW → RESOLVED
Closed: 18 years ago
Resolution: --- → FIXED
See bug 379557 for the continuation of this issue.
Blocks: 379557
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: