OpenBSD 5.4 errata 8, June 5, 2014:

This patch contains fixes for the following issues:

CVE-2014-0195 - Buffer overflow with crafted DTLS fragments
CVE-2014-0221 - DTLS infinite recursion flaw with "Hello Request"s
CVE-2014-0224 - SSL/TLS MITM vulnerability (Early ChangeCipherSpec Attack)
CVE-2014-3470 - Anonymous ECDH denial of service (null session certs)

Other issues in https://www.openssl.org/news/secadv_20140605.txt

CVE-2010-5298 - SSL_MODE_RELEASE_BUFFERS session injection or denial of service
This issue was fixed in 008_openssl.patch and subsequently in OpenSSL.

CVE-2014-0198 - SSL_MODE_RELEASE_BUFFERS NULL pointer dereference
This issue was fixed in 009_openssl.patch and subsequently in OpenSSL.

Apply patch using:

    cat 012_openssl.patch | (cd /usr/src && patch -p0)

Then build and install libssl

    cd /usr/src/lib/libssl/ssl
    make obj
    make
    make install

Then restart services which depend on SSL.

Index: lib/libssl/src/ssl/d1_both.c
===================================================================
RCS file: /cvs/src/lib/libssl/src/ssl/d1_both.c,v
retrieving revision 1.1.1.5.4.1
retrieving revision 1.1.1.5.4.3
diff -u -p -r1.1.1.5.4.1 -r1.1.1.5.4.3
--- lib/libssl/src/ssl/d1_both.c	8 Apr 2014 00:55:23 -0000	1.1.1.5.4.1
+++ lib/libssl/src/ssl/d1_both.c	5 Jun 2014 20:39:09 -0000	1.1.1.5.4.3
@@ -619,8 +619,14 @@ dtls1_reassemble_fragment(SSL *s, struct
 		frag->msg_header.frag_len = frag->msg_header.msg_len;
 		frag->msg_header.frag_off = 0;
 		}
-	else
+	else {
 		frag = (hm_fragment*) item->data;
+		if (frag->msg_header.msg_len != msg_hdr->msg_len) {
+			item = NULL;
+			frag = NULL;
+			goto err;
+		}
+	}
 
 	/* If message is already reassembled, this must be a
 	 * retransmit and can be dropped.
@@ -777,6 +783,7 @@ dtls1_get_message_fragment(SSL *s, int s
 	int i,al;
 	struct hm_header_st msg_hdr;
 
+again:
 	/* see if we have the required fragment already */
 	if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
 		{
@@ -835,8 +842,7 @@ dtls1_get_message_fragment(SSL *s, int s
 					s->msg_callback_arg);
 			
 			s->init_num = 0;
-			return dtls1_get_message_fragment(s, st1, stn,
-				max, ok);
+			goto again;
 			}
 		else /* Incorrectly formated Hello request */
 			{
Index: lib/libssl/src/ssl/s3_clnt.c
===================================================================
RCS file: /cvs/src/lib/libssl/src/ssl/s3_clnt.c,v
retrieving revision 1.26
retrieving revision 1.26.4.2
diff -u -p -r1.26 -r1.26.4.2
--- lib/libssl/src/ssl/s3_clnt.c	13 Oct 2012 21:25:14 -0000	1.26
+++ lib/libssl/src/ssl/s3_clnt.c	5 Jun 2014 20:38:10 -0000	1.26.4.2
@@ -559,7 +559,7 @@ int ssl3_connect(SSL *s)
 
 		case SSL3_ST_CR_FINISHED_A:
 		case SSL3_ST_CR_FINISHED_B:
-
+			s->s3->flags |= SSL3_FLAGS_CCS_OK;
 			ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
 				SSL3_ST_CR_FINISHED_B);
 			if (ret <= 0) goto end;
@@ -917,6 +917,7 @@ int ssl3_get_server_hello(SSL *s)
 		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
 		goto f_err;
 		}
+	    s->s3->flags |= SSL3_FLAGS_CCS_OK;
 	    s->hit=1;
 	    }
 	else	/* a miss or crap from the other end */
@@ -2508,6 +2509,14 @@ int ssl3_send_client_key_exchange(SSL *s
 			EC_KEY *tkey;
 			int ecdh_clnt_cert = 0;
 			int field_size = 0;
+
+			if (s->session->sess_cert == NULL) {
+				ssl3_send_alert(s, SSL3_AL_FATAL,
+				    SSL_AD_UNEXPECTED_MESSAGE);
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+				    SSL_R_UNEXPECTED_MESSAGE);
+				goto err;
+			}
 
 			/* Did we send out the client's
 			 * ECDH share for use in premaster
Index: lib/libssl/src/ssl/s3_pkt.c
===================================================================
RCS file: /cvs/src/lib/libssl/src/ssl/s3_pkt.c,v
retrieving revision 1.19.4.2
retrieving revision 1.19.4.3
diff -u -p -r1.19.4.2 -r1.19.4.3
--- lib/libssl/src/ssl/s3_pkt.c	1 May 2014 14:17:40 -0000	1.19.4.2
+++ lib/libssl/src/ssl/s3_pkt.c	5 Jun 2014 20:37:47 -0000	1.19.4.3
@@ -1300,6 +1300,14 @@ start:
 			goto f_err;
 			}
 
+		/* Check that we should be receiving a Change Cipher Spec. */
+		if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) {
+			al = SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY);
+			goto f_err;
+		}
+		s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+
 		rr->length=0;
 
 		if (s->msg_callback)
@@ -1434,7 +1442,7 @@ int ssl3_do_change_cipher_spec(SSL *s)
 
 	if (s->s3->tmp.key_block == NULL)
 		{
-		if (s->session == NULL) 
+		if (s->session == NULL || s->session->master_key_length == 0) 
 			{
 			/* might happen if dtls1_read_bytes() calls this */
 			SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);
Index: lib/libssl/src/ssl/s3_srvr.c
===================================================================
RCS file: /cvs/src/lib/libssl/src/ssl/s3_srvr.c,v
retrieving revision 1.29
retrieving revision 1.29.4.1
diff -u -p -r1.29 -r1.29.4.1
--- lib/libssl/src/ssl/s3_srvr.c	13 Oct 2012 21:25:14 -0000	1.29
+++ lib/libssl/src/ssl/s3_srvr.c	5 Jun 2014 20:37:47 -0000	1.29.4.1
@@ -670,6 +670,7 @@ int ssl3_accept(SSL *s)
 
 		case SSL3_ST_SR_CERT_VRFY_A:
 		case SSL3_ST_SR_CERT_VRFY_B:
+			s->s3->flags |= SSL3_FLAGS_CCS_OK;
 
 			/* we should decide if we expected this one */
 			ret=ssl3_get_cert_verify(s);
@@ -698,6 +699,7 @@ int ssl3_accept(SSL *s)
 
 		case SSL3_ST_SR_FINISHED_A:
 		case SSL3_ST_SR_FINISHED_B:
+			s->s3->flags |= SSL3_FLAGS_CCS_OK;
 			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
 				SSL3_ST_SR_FINISHED_B);
 			if (ret <= 0) goto end;
@@ -767,9 +769,10 @@ int ssl3_accept(SSL *s)
 #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
 				s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
 #else
-				if (s->s3->next_proto_neg_seen)
+				if (s->s3->next_proto_neg_seen) {
+					s->s3->flags |= SSL3_FLAGS_CCS_OK;
 					s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
-				else
+				} else
 					s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
 #endif
 				}
Index: lib/libssl/src/ssl/ssl_locl.h
===================================================================
RCS file: /cvs/src/lib/libssl/src/ssl/ssl_locl.h,v
retrieving revision 1.19
retrieving revision 1.19.4.1
diff -u -p -r1.19 -r1.19.4.1
--- lib/libssl/src/ssl/ssl_locl.h	14 Feb 2013 15:11:43 -0000	1.19
+++ lib/libssl/src/ssl/ssl_locl.h	5 Jun 2014 20:37:47 -0000	1.19.4.1
@@ -165,6 +165,12 @@
 #include <openssl/ssl.h>
 #include <openssl/symhacks.h>
 
+/*
+ * Macro defined here rather than in ssl.h for -stable, avoiding
+ * the need to update installed headers before building.
+ */
+#define SSL3_FLAGS_CCS_OK	0x0080
+
 #ifdef OPENSSL_BUILD_SHLIBSSL
 # undef OPENSSL_EXTERN
 # define OPENSSL_EXTERN OPENSSL_EXPORT
