Subject: [P2PSIP] Android DTLS bug fix needed by RELOAD?

From: "Michael Chen" <[email-masked]>
Date: Sun, 06 Jan 2013 09:42:38 -0700

Hi Eric,

I ran into an Android DTLS problem and the bug you logged at openssl.org:

#2662 NPN patch breaks DTLS Finished exchange

I came up with the attached fix for the Ice Cream Sandwich code, and it seems to be working. However, is NPN even relevant to RELOAD?

Thanks

--Michael

project external/openssl/
diff --git a/ssl/d1_both.c b/ssl/d1_both.c
index 2180c6d..7dc563e 100644
--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -401,6 +401,28 @@ int dtls1_do_write(SSL *s, int type)
 	return(0);
 	}
 
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */
+static void ssl3_take_mac(SSL *s)
+	{
+	const char *sender;
+	int slen;
+
+	if (s->state & SSL_ST_CONNECT)
+		{
+		sender=s->method->ssl3_enc->server_finished_label;
+		slen=s->method->ssl3_enc->server_finished_label_len;
+		}
+	else
+		{
+		sender=s->method->ssl3_enc->client_finished_label;
+		slen=s->method->ssl3_enc->client_finished_label_len;
+		}
+
+	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
+		sender,slen,s->s3->tmp.peer_finish_md);
+	}
+#endif
 
 /* Obtain handshake message of message type 'mt' (any if mt == -1),
  * maximum acceptable body length 'max'.
@@ -456,6 +478,13 @@ again:
 		msg_len += DTLS1_HM_HEADER_LENGTH;
 	}
 
+#ifndef OPENSSL_NO_NEXTPROTONEG
+	/* If receiving Finished, record MAC of prior handshake messages for
+	 * Finished verification. */
+	if (*s->init_buf->data == SSL3_MT_FINISHED)
+		ssl3_take_mac(s);
+#endif
+
 	ssl3_finish_mac(s, p, msg_len);
 	if (s->msg_callback)
 		s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index 91562f3..327d88c 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -248,8 +248,6 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
 	if (!ssl3_setup_buffers(s))
 		{
 		SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
-		OPENSSL_free(rdata);
-		pitem_free(item);
 		return(0);
 		}