Updates from 1.0.0-stable
diff --git a/apps/s_server.c b/apps/s_server.c
index 6bbbd7f..6c9e6ba 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -298,7 +298,9 @@
 
 static int enable_timeouts = 0;
 static long socket_mtu;
+#ifndef OPENSSL_NO_DTLS1
 static int cert_chain = 0;
+#endif
 
 #ifndef OPENSSL_NO_PSK
 static char *psk_identity="Client_identity";
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
index 2e1a6fa..027cdf9 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -217,12 +217,19 @@
 			timeleft.tv_usec += 1000000;
 			}
 
+		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;
diff --git a/ssl/d1_both.c b/ssl/d1_both.c
index ebc0348..a56586f 100644
--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -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];
 
diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
index 2364ad2..a4a438a 100644
--- a/ssl/d1_clnt.c
+++ b/ssl/d1_clnt.c
@@ -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;
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index a89edbc..394daf6 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -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;
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 6d6363f..ac09b45 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -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;
diff --git a/ssl/dtls1.h b/ssl/dtls1.h
index 2fe0405..73af56d 100644
--- a/ssl/dtls1.h
+++ b/ssl/dtls1.h
@@ -231,6 +231,7 @@
 	unsigned int handshake_fragment_len;
 
 	unsigned int retransmitting;
+	unsigned int change_cipher_spec_ok;
 
 	} DTLS1_STATE;