Upgrade to openssl-1.0.0e

Bug: 5261862
Change-Id: I34d2d458aa85e61b1faacb8b5f386353be679d9b
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c
index af319af..eedac8a 100644
--- a/ssl/bio_ssl.c
+++ b/ssl/bio_ssl.c
@@ -348,7 +348,11 @@
 		break;
 	case BIO_C_SET_SSL:
 		if (ssl != NULL)
+			{
 			ssl_free(b);
+			if (!ssl_new(b))
+				return 0;
+			}
 		b->shutdown=(int)num;
 		ssl=(SSL *)ptr;
 		((BIO_SSL *)b->ptr)->ssl=ssl;
diff --git a/ssl/d1_both.c b/ssl/d1_both.c
index 4ce4064..2180c6d 100644
--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -153,7 +153,7 @@
 #endif
 
 static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
-static unsigned char bitmask_end_values[]   = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
+static unsigned char bitmask_end_values[]   = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
 
 /* XDTLS:  figure out the right values */
 static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
@@ -464,20 +464,9 @@
 
 	memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
 
-	s->d1->handshake_read_seq++;
-	/* we just read a handshake message from the other side:
-	 * this means that we don't need to retransmit of the
-	 * buffered messages.  
-	 * XDTLS: may be able clear out this
-	 * buffer a little sooner (i.e if an out-of-order
-	 * handshake message/record is received at the record
-	 * layer.  
-	 * XDTLS: exception is that the server needs to
-	 * know that change cipher spec and finished messages
-	 * have been received by the client before clearing this
-	 * buffer.  this can simply be done by waiting for the
-	 * first data  segment, but is there a better way?  */
-	dtls1_clear_record_buffer(s);
+	/* Don't change sequence numbers while listening */
+	if (!s->d1->listen)
+		s->d1->handshake_read_seq++;
 
 	s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
 	return s->init_num;
@@ -813,9 +802,11 @@
 
 	/* 
 	 * if this is a future (or stale) message it gets buffered
-	 * (or dropped)--no further processing at this time 
+	 * (or dropped)--no further processing at this time
+	 * While listening, we accept seq 1 (ClientHello with cookie)
+	 * although we're still expecting seq 0 (ClientHello)
 	 */
-	if ( msg_hdr.seq != s->d1->handshake_read_seq)
+	if (msg_hdr.seq != s->d1->handshake_read_seq && !(s->d1->listen && msg_hdr.seq == 1))
 		return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
 
 	len = msg_hdr.msg_len;
@@ -1322,7 +1313,8 @@
 dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt,
 			unsigned long len, unsigned long frag_off, unsigned long frag_len)
 	{
-	if ( frag_off == 0)
+	/* Don't change sequence numbers while listening */
+	if (frag_off == 0 && !s->d1->listen)
 		{
 		s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
 		s->d1->next_handshake_write_seq++;
diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
index aabbef8..5776671 100644
--- a/ssl/d1_clnt.c
+++ b/ssl/d1_clnt.c
@@ -407,7 +407,8 @@
 
 		case SSL3_ST_CW_CHANGE_A:
 		case SSL3_ST_CW_CHANGE_B:
-			dtls1_start_timer(s);
+			if (!s->hit)
+				dtls1_start_timer(s);
 			ret=dtls1_send_change_cipher_spec(s,
 				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
 			if (ret <= 0) goto end;
@@ -442,7 +443,8 @@
 
 		case SSL3_ST_CW_FINISHED_A:
 		case SSL3_ST_CW_FINISHED_B:
-			dtls1_start_timer(s);
+			if (!s->hit)
+				dtls1_start_timer(s);
 			ret=dtls1_send_finished(s,
 				SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
 				s->method->ssl3_enc->client_finished_label,
diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
index 96b220e..48e8b6f 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -129,26 +129,33 @@
 	return(1);
 	}
 
-void dtls1_free(SSL *s)
+static void dtls1_clear_queues(SSL *s)
 	{
     pitem *item = NULL;
     hm_fragment *frag = NULL;
-
-	ssl3_free(s);
+	DTLS1_RECORD_DATA *rdata;
 
     while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL)
         {
+		rdata = (DTLS1_RECORD_DATA *) item->data;
+		if (rdata->rbuf.buf)
+			{
+			OPENSSL_free(rdata->rbuf.buf);
+			}
         OPENSSL_free(item->data);
         pitem_free(item);
         }
-    pqueue_free(s->d1->unprocessed_rcds.q);
 
     while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL)
         {
+		rdata = (DTLS1_RECORD_DATA *) item->data;
+		if (rdata->rbuf.buf)
+			{
+			OPENSSL_free(rdata->rbuf.buf);
+			}
         OPENSSL_free(item->data);
         pitem_free(item);
         }
-    pqueue_free(s->d1->processed_rcds.q);
 
     while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
         {
@@ -157,7 +164,6 @@
         OPENSSL_free(frag);
         pitem_free(item);
         }
-    pqueue_free(s->d1->buffered_messages);
 
     while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
         {
@@ -166,7 +172,6 @@
         OPENSSL_free(frag);
         pitem_free(item);
         }
-	pqueue_free(s->d1->sent_messages);
 
 	while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
 		{
@@ -175,6 +180,18 @@
 		OPENSSL_free(frag);
 		pitem_free(item);
 		}
+	}
+
+void dtls1_free(SSL *s)
+	{
+	ssl3_free(s);
+
+	dtls1_clear_queues(s);
+
+    pqueue_free(s->d1->unprocessed_rcds.q);
+    pqueue_free(s->d1->processed_rcds.q);
+    pqueue_free(s->d1->buffered_messages);
+	pqueue_free(s->d1->sent_messages);
 	pqueue_free(s->d1->buffered_app_data.q);
 
 	OPENSSL_free(s->d1);
@@ -182,6 +199,36 @@
 
 void dtls1_clear(SSL *s)
 	{
+    pqueue unprocessed_rcds;
+    pqueue processed_rcds;
+    pqueue buffered_messages;
+	pqueue sent_messages;
+	pqueue buffered_app_data;
+	
+	if (s->d1)
+		{
+		unprocessed_rcds = s->d1->unprocessed_rcds.q;
+		processed_rcds = s->d1->processed_rcds.q;
+		buffered_messages = s->d1->buffered_messages;
+		sent_messages = s->d1->sent_messages;
+		buffered_app_data = s->d1->buffered_app_data.q;
+
+		dtls1_clear_queues(s);
+
+		memset(s->d1, 0, sizeof(*(s->d1)));
+
+		if (s->server)
+			{
+			s->d1->cookie_len = sizeof(s->d1->cookie);
+			}
+
+		s->d1->unprocessed_rcds.q = unprocessed_rcds;
+		s->d1->processed_rcds.q = processed_rcds;
+		s->d1->buffered_messages = buffered_messages;
+		s->d1->sent_messages = sent_messages;
+		s->d1->buffered_app_data.q = buffered_app_data;
+		}
+
 	ssl3_clear(s);
 	if (s->options & SSL_OP_CISCO_ANYCONNECT)
 		s->version=DTLS1_BAD_VER;
@@ -330,6 +377,8 @@
 	memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
 	s->d1->timeout_duration = 1;
 	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
+	/* Clear retransmission buffer */
+	dtls1_clear_record_buffer(s);
 	}
 
 int dtls1_handle_timeout(SSL *s)
@@ -349,7 +398,7 @@
 		{
 		/* fail the connection, enough alerts have been sent */
 		SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
-		return 0;
+		return -1;
 		}
 
 	state->timeout.read_timeouts++;
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index c0f6055..91562f3 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -409,13 +409,13 @@
 	enc_err = s->method->ssl3_enc->enc(s,0);
 	if (enc_err <= 0)
 		{
-		if (enc_err == 0)
-			/* SSLerr() and ssl3_send_alert() have been called */
-			goto err;
-
-		/* otherwise enc_err == -1 */
-		al=SSL_AD_BAD_RECORD_MAC;
-		goto f_err;
+		/* decryption failed, silently discard message */
+		if (enc_err < 0)
+			{
+			rr->length = 0;
+			s->packet_length = 0;
+			}
+		goto err;
 		}
 
 #ifdef TLS_DEBUG
@@ -676,10 +676,12 @@
 
 	/* If this record is from the next epoch (either HM or ALERT),
 	 * and a handshake is currently in progress, buffer it since it
-	 * cannot be processed at this time. */
+	 * cannot be processed at this time. However, do not buffer
+	 * anything while listening.
+	 */
 	if (is_next_epoch)
 		{
-		if (SSL_in_init(s) || s->in_handshake)
+		if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen)
 			{
 			dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
 			}
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 301ceda..a6a4c87 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -150,6 +150,7 @@
 	unsigned long alg_k;
 	int ret= -1;
 	int new_state,state,skip=0;
+	int listen;
 
 	RAND_add(&Time,sizeof(Time),0);
 	ERR_clear_error();
@@ -159,11 +160,15 @@
 		cb=s->info_callback;
 	else if (s->ctx->info_callback != NULL)
 		cb=s->ctx->info_callback;
+	
+	listen = s->d1->listen;
 
 	/* init things to blank */
 	s->in_handshake++;
 	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
 
+	s->d1->listen = listen;
+
 	if (s->cert == NULL)
 		{
 		SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
@@ -273,11 +278,23 @@
 
 			s->init_num=0;
 
+			/* Reflect ClientHello sequence to remain stateless while listening */
+			if (listen)
+				{
+				memcpy(s->s3->write_sequence, s->s3->read_sequence, sizeof(s->s3->write_sequence));
+				}
+
 			/* If we're just listening, stop here */
-			if (s->d1->listen && s->state == SSL3_ST_SW_SRVR_HELLO_A)
+			if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A)
 				{
 				ret = 2;
 				s->d1->listen = 0;
+				/* Set expected sequence numbers
+				 * to continue the handshake.
+				 */
+				s->d1->handshake_read_seq = 2;
+				s->d1->handshake_write_seq = 1;
+				s->d1->next_handshake_write_seq = 1;
 				goto end;
 				}
 			
@@ -286,7 +303,6 @@
 		case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
 		case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
 
-			dtls1_start_timer(s);
 			ret = dtls1_send_hello_verify_request(s);
 			if ( ret <= 0) goto end;
 			s->state=SSL3_ST_SW_FLUSH;
@@ -736,9 +752,6 @@
 		/* number of bytes to write */
 		s->init_num=p-buf;
 		s->init_off=0;
-
-		/* buffer the message to handle re-xmits */
-		dtls1_buffer_message(s, 0);
 		}
 
 	/* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */
@@ -1017,12 +1030,11 @@
 				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
 				goto err;
 				}
-			if (!EC_KEY_up_ref(ecdhp))
+			if ((ecdh = EC_KEY_dup(ecdhp)) == NULL)
 				{
 				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
 				goto err;
 				}
-			ecdh = ecdhp;
 
 			s->s3->tmp.ecdh=ecdh;
 			if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index a10528e..42bcd62 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -2320,6 +2320,7 @@
 			if (!DH_generate_key(dh_clnt))
 				{
 				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+				DH_free(dh_clnt);
 				goto err;
 				}
 
@@ -2331,6 +2332,7 @@
 			if (n <= 0)
 				{
 				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+				DH_free(dh_clnt);
 				goto err;
 				}
 
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index fddcf6c..28ee474 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -2198,11 +2198,17 @@
 		}
 #ifndef OPENSSL_NO_DH
 	if (s->s3->tmp.dh != NULL)
+		{
 		DH_free(s->s3->tmp.dh);
+		s->s3->tmp.dh = NULL;
+		}
 #endif
 #ifndef OPENSSL_NO_ECDH
 	if (s->s3->tmp.ecdh != NULL)
+		{
 		EC_KEY_free(s->s3->tmp.ecdh);
+		s->s3->tmp.ecdh = NULL;
+		}
 #endif
 
 	rp = s->s3->rbuf.buf;
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 31238f6..0d3874a 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -246,7 +246,8 @@
 		if (i <= 0)
 			{
 			rb->left = left;
-			if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+			if (s->mode & SSL_MODE_RELEASE_BUFFERS &&
+			    SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
 				if (len+left == 0)
 					ssl3_release_read_buffer(s);
 			return(i);
@@ -885,7 +886,8 @@
 			{
 			wb->left=0;
 			wb->offset+=i;
-			if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+			if (s->mode & SSL_MODE_RELEASE_BUFFERS &&
+			    SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
 				ssl3_release_write_buffer(s);
 			s->rwstate=SSL_NOTHING;
 			return(s->s3->wpend_ret);
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 6095d52..6059162 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -801,9 +801,7 @@
 	if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
 		{
 		/* Throw away what we have done so far in the current handshake,
-		 * which will now be aborted. (A full SSL_clear would be too much.)
-		 * I hope that tmp.dh is the only thing that may need to be cleared
-		 * when a handshake is not completed ... */
+		 * which will now be aborted. (A full SSL_clear would be too much.) */
 #ifndef OPENSSL_NO_DH
 		if (s->s3->tmp.dh != NULL)
 			{
@@ -811,6 +809,13 @@
 			s->s3->tmp.dh = NULL;
 			}
 #endif
+#ifndef OPENSSL_NO_ECDH
+		if (s->s3->tmp.ecdh != NULL)
+			{
+			EC_KEY_free(s->s3->tmp.ecdh);
+			s->s3->tmp.ecdh = NULL;
+			}
+#endif
 		return 2;
 		}
 	return 1;
@@ -1536,7 +1541,6 @@
 
 			if (s->s3->tmp.dh != NULL)
 				{
-				DH_free(dh);
 				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
 				goto err;
 				}
@@ -1597,7 +1601,6 @@
 
 			if (s->s3->tmp.ecdh != NULL)
 				{
-				EC_KEY_free(s->s3->tmp.ecdh); 
 				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
 				goto err;
 				}
@@ -1608,12 +1611,11 @@
 				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
 				goto err;
 				}
-			if (!EC_KEY_up_ref(ecdhp))
+			if ((ecdh = EC_KEY_dup(ecdhp)) == NULL)
 				{
 				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
 				goto err;
 				}
-			ecdh = ecdhp;
 
 			s->s3->tmp.ecdh=ecdh;
 			if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
@@ -1776,6 +1778,7 @@
 			    (unsigned char *)encodedPoint, 
 			    encodedlen);
 			OPENSSL_free(encodedPoint);
+			encodedPoint = NULL;
 			p += encodedlen;
 			}
 #endif
@@ -2485,6 +2488,12 @@
 			/* Get encoded point length */
 			i = *p; 
 			p += 1;
+			if (n != 1 + i)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				    ERR_R_EC_LIB);
+				goto err;
+				}
 			if (EC_POINT_oct2point(group, 
 			    clnt_ecpoint, p, i, bn_ctx) == 0)
 				{
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 38104a2..b169ba9 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1990,7 +1990,7 @@
 #endif
 	X509 *x = NULL;
 	EVP_PKEY *ecc_pkey = NULL;
-	int signature_nid = 0;
+	int signature_nid = 0, pk_nid = 0, md_nid = 0;
 
 	if (c == NULL) return;
 
@@ -2120,18 +2120,15 @@
 		    EVP_PKEY_bits(ecc_pkey) : 0;
 		EVP_PKEY_free(ecc_pkey);
 		if ((x->sig_alg) && (x->sig_alg->algorithm))
+			{
 			signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
+			OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
+			}
 #ifndef OPENSSL_NO_ECDH
 		if (ecdh_ok)
 			{
-			const char *sig = OBJ_nid2ln(signature_nid);
-			if (sig == NULL)
-				{
-				ERR_clear_error();
-				sig = "unknown";
-				}
-				
-			if (strstr(sig, "WithRSA"))
+
+			if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa)
 				{
 				mask_k|=SSL_kECDHr;
 				mask_a|=SSL_aECDH;
@@ -2142,7 +2139,7 @@
 					}
 				}
 
-			if (signature_nid == NID_ecdsa_with_SHA1)
+			if (pk_nid == NID_X9_62_id_ecPublicKey)
 				{
 				mask_k|=SSL_kECDHe;
 				mask_a|=SSL_aECDH;
@@ -2196,7 +2193,7 @@
 	unsigned long alg_k, alg_a;
 	EVP_PKEY *pkey = NULL;
 	int keysize = 0;
-	int signature_nid = 0;
+	int signature_nid = 0, md_nid = 0, pk_nid = 0;
 
 	alg_k = cs->algorithm_mkey;
 	alg_a = cs->algorithm_auth;
@@ -2214,7 +2211,10 @@
 	/* This call populates the ex_flags field correctly */
 	X509_check_purpose(x, -1, 0);
 	if ((x->sig_alg) && (x->sig_alg->algorithm))
+		{
 		signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
+		OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
+		}
 	if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr)
 		{
 		/* key usage, if present, must allow key agreement */
@@ -2226,7 +2226,7 @@
 		if (alg_k & SSL_kECDHe)
 			{
 			/* signature alg must be ECDSA */
-			if (signature_nid != NID_ecdsa_with_SHA1)
+			if (pk_nid != NID_X9_62_id_ecPublicKey)
 				{
 				SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE);
 				return 0;
@@ -2236,13 +2236,7 @@
 			{
 			/* signature alg must be RSA */
 
-			const char *sig = OBJ_nid2ln(signature_nid);
-			if (sig == NULL)
-				{
-				ERR_clear_error();
-				sig = "unknown";
-				}
-			if (strstr(sig, "WithRSA") == NULL)
+			if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa)
 				{
 				SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE);
 				return 0;