Bug 1397482

Summary: Segfault in selfserv during session handshake when using SessionTicket extension and ECDHE-ECDSA ciphersuites [rhel-6]
Product: Red Hat Enterprise Linux 6 Reporter: Frantisek Sumsal <fsumsal>
Component: nssAssignee: Daiki Ueno <dueno>
Status: CLOSED WONTFIX QA Contact: BaseOS QE Security Team <qe-baseos-security>
Severity: urgent Docs Contact:
Priority: high    
Version: 6.8CC: hkario, kengert, nmavrogi, nss-nspr-maint, qe-baseos-security, rrelyea, szidek
Target Milestone: rc   
Target Release: 6.9   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: 1397410 Environment:
Last Closed: 2017-02-18 10:00:53 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1397410, 1426182, 1455876    
Bug Blocks: 1397012    

Description Frantisek Sumsal 2016-11-22 15:55:45 UTC
Description of problem:
selfserv segfaults during handshake while using SessionTicket extension for session resumption. This issue although does not occur when using client certificates.

Version-Release number of selected component (if applicable):
nss-3.21.3-2.el6_8.x86_64

How reproducible:
always

Steps to Reproduce:
# NSS_CIPHER="C00A"
# OPENSSL_CIPHER="ECDHE-ECDSA-AES256-SHA"
# ulimit -c unlimited
# openssl ecparam -genkey -name prime256v1 -out ec.key
# openssl req -new -x509 -key ec.key -out ec-cert.pem -days 3650 -subj "/CN=localhost" -nodes
# openssl pkcs12 -name ec -export -inkey ec.key -out ec.p12 -in ec-cert.pem -passout "pass:"
# mkdir nssdb
# certutil -N --empty-password -d sql:./nssdb
# certutil -A -d sql:./nssdb/ -n ec -t ',,' -a -i ec-cert.pem
# pk12util -i ec.p12 -d sql:./nssdb -W ''
# /usr/lib64/nss/unsupported-tools/selfserv -d sql:./nssdb/ -p 4433 -V tls1.0: -H 1 -e ec -c :$NSS_CIPHER -u &
# sleep 3
# openssl s_client -connect localhost:4433 -CAfile ec-cert.pem -cipher $OPENSSL_CIPHER -sess_out sess.pem > full.log < /dev/null
# grep "New, TLSv1/SSLv3" full.log || echo "ERROR: HANDSHAKE ERROR"
# openssl s_client -connect localhost:4433 -CAfile ec-cert.pem -cipher $OPENSSL_CIPHER -sess_in sess.pem > resumption.log < /dev/null
# grep "Reused, TLSv1/SSLv3" resumption.log || echo "ERROR: RESUMPTION EXPECTED"

Actual results:
# openssl s_client -connect localhost:4433 -CAfile ec-cert.pem -cipher $OPENSSL_CIPHER -sess_out sess.pem > full.log < /dev/null
depth=0 CN = localhost
verify return:1
140699908630432:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:
# grep "New, TLSv1/SSLv3" full.log || echo "ERROR: HANDSHAKE ERROR"
New, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-AES256-SHA
# openssl s_client -connect localhost:4433 -CAfile ec-cert.pem -cipher $OPENSSL_CIPHER -sess_in sess.pem > resumption.log < /dev/null
Can't open session file sess.pem
140226465114016:error:02001002:system library:fopen:No such file or directory:bss_file.c:169:fopen('sess.pem','r')
140226465114016:error:2006D080:BIO routines:BIO_new_file:no such file:bss_file.c:172:
# grep "Reused, TLSv1/SSLv3" resumption.log || echo "ERROR: RESUMPTION EXPECTED"
[1]+  Segmentation fault      (core dumped) /usr/lib64/nss/unsupported-tools/selfserv -d sql:./nssdb/ -p 4433 -V tls1.0: -H 1 -e ec -c :$NSS_CIPHER -u
ERROR: RESUMPTION EXPECTED

Expected results:
Handshake and session resumption should finish successfully.
SessionID example:
# /usr/lib64/nss/unsupported-tools/selfserv -d sql:./nssdb/ -p 4433 -V tls1.0: -H 1 -e ec -c :$NSS_CIPHER &
[1] 14341
# sleep 3
# openssl s_client -connect localhost:4433 -CAfile ec-cert.pem -cipher $OPENSSL_CIPHER -no_ticket -sess_out sess.pem > full.log < /dev/null
depth=0 CN = localhost
verify return:1
DONE
# grep "New, TLSv1/SSLv3" full.log || echo "ERROR: HANDSHAKE ERROR"
New, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-AES256-SHA
# openssl s_client -connect localhost:4433 -CAfile ec-cert.pem -cipher $OPENSSL_CIPHER -no_ticket -sess_in sess.pem > resumption.log < /dev/null
DONE
# grep "Reused, TLSv1/SSLv3" resumption.log || echo "ERROR: RESUMPTION EXPECTED"
Reused, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-AES256-SHA

Additional info:
Offending ciphersuites (openssl/nss):
ECDHE-ECDSA-AES256-SHA/C00A
ECDHE-ECDSA-AES128-SHA256/C023
ECDHE-ECDSA-AES128-GCM-SHA256/C02B
ECDHE-ECDSA-AES256-GCM-SHA384/C02C

Backtrace:
#0  0x00007f7deb81f42e in ssl3_GenerateSessionTicketKeysPKCS11 () from /lib64/libssl3.so
#1  0x00007f7deaa57c95 in PR_CallOnceWithArg () from /lib64/libnspr4.so
#2  0x00007f7deb81e672 in ssl3_GetSessionTicketKeysPKCS11 () from /lib64/libssl3.so
#3  0x00007f7deb8206c2 in ssl3_SendNewSessionTicket () from /lib64/libssl3.so
#4  0x00007f7deb8159c6 in ssl3_HandleHandshakeMessage () from /lib64/libssl3.so
#5  0x00007f7deb818051 in ssl3_HandleRecord () from /lib64/libssl3.so
#6  0x00007f7deb8194a2 in ssl3_GatherCompleteHandshake () from /lib64/libssl3.so
#7  0x00007f7deb81a285 in ssl_GatherRecord1stHandshake () from /lib64/libssl3.so
#8  0x00007f7deb822925 in ssl_Do1stHandshake () from /lib64/libssl3.so
#9  0x00007f7deb823e6f in ssl_SecureRecv () from /lib64/libssl3.so
#10 0x00007f7deb827fe8 in ssl_Read () from /lib64/libssl3.so
#11 0x0000000000408512 in handle_connection ()
#12 0x0000000000409004 in jobLoop ()
#13 0x0000000000407641 in thread_wrapper ()
#14 0x00007f7deaa6596b in _pt_root () from /lib64/libnspr4.so
#15 0x00007f7dea5eadc5 in start_thread () from /lib64/libpthread.so.0
#16 0x00007f7dea11573d in clone () from /lib64/libc.so.6

Comment 2 Bob Relyea 2016-11-30 01:48:27 UTC
it looks like a bug in ssl_ext.c

static unsigned char  key_name[SESS_TICKET_KEY_NAME_LEN];

.
.
.
.

   if (!ssl_GetSessionTicketKeysPKCS11(svrPrivKey, svrPubKey,
 ->           ss->pkcs11PinArg, &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
            &session_ticket_enc_key_pkcs11, &session_ticket_mac_key_pkcs11))
.
.
.
.
.

    PORT_Memcpy(keyName, ticketKeyNameSuffix, SESS_TICKET_KEY_VAR_NAME_LEN);


The code has been rewritten in 3.27.1 (which is the top of 6.9). Is this still a problem in 3.27?

bob

Comment 3 Bob Relyea 2016-11-30 01:49:43 UTC
OK, yes, I found the same code in 3.27.1 with the same bug.

bob

Comment 4 Bob Relyea 2016-11-30 01:53:42 UTC
Never mind SESS_TICKET_KEY_NAME_PREFIX_LEN + SESS_TICKET_KEY_VAR_NAME_LEN = SESS_TIKCET_KEY_NAME_LEN which is correct.

We'd need a better stack traceback with the actual line number of the crash

Comment 5 Hubert Kario 2016-11-30 12:05:11 UTC
From upstream bug (with 3.27):

Actual results:

# cat client_err.log 
depth=0 CN = localhost
verify return:1
139942008751992:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
depth=0 CN = localhost
verify return:1
139640958179192:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:

# cat server.log 
selfserv: HDX PR_Read returned error 0:
Success
selfserv: HDX PR_Read returned error -5925:
The one-time function was previously called and failed. Its error code is no longer available


Expected results:

Handshake should not fail and selfserv should be able to handle following connections.