Re: [openssl.org #1950] [PATCH] DTLS fragment retransmission bug
Here is an updated version, the last didn't cover every variation of the handshake message flow because the CertificateVerify state is entered every time, not only when a CertificateVerify message is really expected. --- crypto/bio/bss_dgram.c 5 Jun 2009 08:35:54 - 1.7.2.13 +++ crypto/bio/bss_dgram.c 5 Jun 2009 12:05:47 - @@ -220,9 +220,10 @@ /* Adjust socket timeout if next handhake message timer * will expire earlier. */ - if (data-socket_timeout.tv_sec timeleft.tv_sec || + if ((data-socket_timeout.tv_sec == 0 data- socket_timeout.tv_usec == 0) || + (data-socket_timeout.tv_sec timeleft.tv_sec) || (data-socket_timeout.tv_sec == timeleft.tv_sec -data-socket_timeout.tv_usec = timeleft.tv_usec)) +data-socket_timeout.tv_usec = timeleft.tv_usec)) { #ifdef OPENSSL_SYS_WINDOWS timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; --- ssl/d1_both.c 16 May 2009 16:22:11 - 1.14.2.9 +++ ssl/d1_both.c 5 Jun 2009 12:05:47 - @@ -569,9 +569,13 @@ item = pqueue_find(s-d1-buffered_messages, seq64be); /* Discard the message if sequence number was already there, is -* too far in the future or the fragment is already in the queue */ +* too far in the future, already in the queue or if we received +* a FINISHED before the SERVER_HELLO, which then must be a stale +* retransmit. +*/ if (msg_hdr-seq = s-d1-handshake_read_seq || - msg_hdr-seq s-d1-handshake_read_seq + 10 || item != NULL) + msg_hdr-seq s-d1-handshake_read_seq + 10 || item != NULL || + s-d1-handshake_read_seq == 0 msg_hdr-type == SSL3_MT_FINISHED) { unsigned char devnull [256]; --- ssl/d1_clnt.c 31 May 2009 17:11:24 - 1.16.2.8 +++ ssl/d1_clnt.c 5 Jun 2009 12:05:47 - @@ -442,7 +442,7 @@ case SSL3_ST_CR_FINISHED_A: case SSL3_ST_CR_FINISHED_B: - + s-d1-change_cipher_spec_ok = 1; ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B); if (ret = 0) goto end; --- ssl/d1_pkt.c16 May 2009 16:17:46 - 1.27.2.8 +++ ssl/d1_pkt.c5 Jun 2009 12:05:47 - @@ -1102,6 +1102,16 @@ s-msg_callback(0, s-version, SSL3_RT_CHANGE_CIPHER_SPEC, rr-data, 1, s, s-msg_callback_arg); + /* We can't process a CCS now, because previous handshake +* messages are still missing, so just drop it. +*/ + if (!s-d1-change_cipher_spec_ok) + { + goto start; + } + + s-d1-change_cipher_spec_ok = 0; + s-s3-change_cipher_spec=1; if (!ssl3_do_change_cipher_spec(s)) goto err; --- ssl/d1_srvr.c 31 May 2009 17:11:24 - 1.20.2.5 +++ ssl/d1_srvr.c 5 Jun 2009 12:05:47 - @@ -497,6 +497,7 @@ case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_B: + s-d1-change_cipher_spec_ok = 1; /* we should decide if we expected this one */ ret=ssl3_get_cert_verify(s); if (ret = 0) goto end; @@ -508,6 +509,7 @@ case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: + s-d1-change_cipher_spec_ok = 1; ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); if (ret = 0) goto end; --- ssl/dtls1.h 2 Jun 2009 11:23:30 - 1.12.2.9 +++ ssl/dtls1.h 5 Jun 2009 12:05:47 - @@ -231,6 +231,7 @@ unsigned int handshake_fragment_len; unsigned int retransmitting; + unsigned int change_cipher_spec_ok; } DTLS1_STATE; dtls-fragment-retransmission-bug-1.0.0.patch Description: Binary data dtls-fragment-retransmission-bug-0.9.8.patch Description: Binary data
Re: Rehashing Directories
2009/6/5 Victor B. Wagner vi...@cryptocom.ru: I think you are missing something with this idea. OpenSSL now provides two X509_LOOKUP_METHODS - lookup_file and lookup_hashed_dir. First one requires big multi-cert file with concatenated PEM certificates - exactly as your OS provided, I suppose. Second requires hashed dir with individual certs and CRLs one per file. And it is done for good reason: If you use lookup_file method, it loads entire file into memory. And this file can be quite big, if you use CRL checks and have big public CAs in your trusted certificate set - big public CA can have multimegabyte CRLs. If you use lookup_dir method, OpenSSL would load only certificates and CRLs when needed, one per time, and thus potentially save you much space. Allowing to put multicertificate file into hashed dir would defeat benefits of lookup_dir method. Although it would work. It is better to fix your daemon so it would allow both files and hashed directories as trusted certificate store. It should be simple - both SSL_CTX_load_verify_locations (which should be used for SSL peer certificate validation) and X509_STORE_load_locations (which should be used for SMIME, timestamping and outher non-SSL uses) accept two arguments - name of file and name of directory. If your daemon uses default cert store location, than corresponding X509_STORE_set_default_paths function supports file and dir too. In this case you probably do not need to change code. You just have to either set environment variable SSL_CERT_FILE pointing to you multicert file, or make symlink pointing to this file named cert.pem in your OPENSSLDIR (run openssl version -d to determine where your OPENSSL dir is). Hi, Okay, thanks for the explanation. I will patch the daemon instead and see if their upstream developers agree with the changes. __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org
Re: [openssl.org #1950] [PATCH] DTLS fragment retransmission bug
I just found another timing bug... --- crypto/bio/bss_dgram.c 5 Jun 2009 08:35:54 - 1.7.2.13 +++ crypto/bio/bss_dgram.c 5 Jun 2009 14:00:26 - @@ -217,12 +217,19 @@ timeleft.tv_usec += 100; } + if (timeleft.tv_sec 0) + { + timeleft.tv_sec = 0; + timeleft.tv_usec = 1; + } + /* Adjust socket timeout if next handhake message timer * will expire earlier. */ - if (data-socket_timeout.tv_sec timeleft.tv_sec || + if ((data-socket_timeout.tv_sec == 0 data- socket_timeout.tv_usec == 0) || + (data-socket_timeout.tv_sec timeleft.tv_sec) || (data-socket_timeout.tv_sec == timeleft.tv_sec -data-socket_timeout.tv_usec = timeleft.tv_usec)) +data-socket_timeout.tv_usec = timeleft.tv_usec)) { #ifdef OPENSSL_SYS_WINDOWS timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; --- ssl/d1_both.c 16 May 2009 16:22:11 - 1.14.2.9 +++ ssl/d1_both.c 5 Jun 2009 14:00:31 - @@ -569,9 +569,13 @@ item = pqueue_find(s-d1-buffered_messages, seq64be); /* Discard the message if sequence number was already there, is -* too far in the future or the fragment is already in the queue */ +* too far in the future, already in the queue or if we received +* a FINISHED before the SERVER_HELLO, which then must be a stale +* retransmit. +*/ if (msg_hdr-seq = s-d1-handshake_read_seq || - msg_hdr-seq s-d1-handshake_read_seq + 10 || item != NULL) + msg_hdr-seq s-d1-handshake_read_seq + 10 || item != NULL || + s-d1-handshake_read_seq == 0 msg_hdr-type == SSL3_MT_FINISHED) { unsigned char devnull [256]; --- ssl/d1_clnt.c 31 May 2009 17:11:24 - 1.16.2.8 +++ ssl/d1_clnt.c 5 Jun 2009 14:00:31 - @@ -442,7 +442,7 @@ case SSL3_ST_CR_FINISHED_A: case SSL3_ST_CR_FINISHED_B: - + s-d1-change_cipher_spec_ok = 1; ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B); if (ret = 0) goto end; --- ssl/d1_pkt.c16 May 2009 16:17:46 - 1.27.2.8 +++ ssl/d1_pkt.c5 Jun 2009 14:00:31 - @@ -1102,6 +1102,16 @@ s-msg_callback(0, s-version, SSL3_RT_CHANGE_CIPHER_SPEC, rr-data, 1, s, s-msg_callback_arg); + /* We can't process a CCS now, because previous handshake +* messages are still missing, so just drop it. +*/ + if (!s-d1-change_cipher_spec_ok) + { + goto start; + } + + s-d1-change_cipher_spec_ok = 0; + s-s3-change_cipher_spec=1; if (!ssl3_do_change_cipher_spec(s)) goto err; --- ssl/d1_srvr.c 31 May 2009 17:11:24 - 1.20.2.5 +++ ssl/d1_srvr.c 5 Jun 2009 14:00:31 - @@ -497,6 +497,7 @@ case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_B: + s-d1-change_cipher_spec_ok = 1; /* we should decide if we expected this one */ ret=ssl3_get_cert_verify(s); if (ret = 0) goto end; @@ -508,6 +509,7 @@ case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: + s-d1-change_cipher_spec_ok = 1; ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); if (ret = 0) goto end; --- ssl/dtls1.h 2 Jun 2009 11:23:30 - 1.12.2.9 +++ ssl/dtls1.h 5 Jun 2009 14:00:31 - @@ -231,6 +231,7 @@ unsigned int handshake_fragment_len; unsigned int retransmitting; + unsigned int change_cipher_spec_ok; } DTLS1_STATE; dtls-fragment-retransmission-bug-1.0.0.patch Description: Binary data dtls-fragment-retransmission-bug-0.9.8.patch Description: Binary data