Add Next Protocol Negotiation.
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index ef40e5e..39b5e72 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -494,6 +494,18 @@
 			i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
 		}
 
+#ifndef OPENSSL_NO_NPN
+	if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len)
+		{
+		/* The client advertises an emtpy extension to indicate its
+		 * support for Next Protocol Negotiation */
+		if (limit - ret - 4 < 0)
+			return NULL;
+		s2n(TLSEXT_TYPE_next_proto_neg,ret);
+		s2n(0,ret);
+		}
+#endif
+
 	if ((extdatalen = ret-p-2)== 0) 
 		return p;
 
@@ -505,6 +517,9 @@
 	{
 	int extdatalen=0;
 	unsigned char *ret = p;
+#ifndef OPENSSL_NO_NPN
+	char next_proto_neg_seen;
+#endif
 
 	/* don't add extensions for SSLv3, unless doing secure renegotiation */
 	if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
@@ -618,6 +633,28 @@
 
 		}
 
+#ifndef OPENSSL_NO_NPN
+	next_proto_neg_seen = s->s3->next_proto_neg_seen;
+	s->s3->next_proto_neg_seen = 0;
+	if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb)
+		{
+		const unsigned char *npa;
+		unsigned int npalen;
+		int r;
+
+		r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, s->ctx->next_protos_advertised_cb_arg);
+		if (r == SSL_TLSEXT_ERR_OK)
+			{
+			if ((long)(limit - ret - 4 - npalen) < 0) return NULL;
+			s2n(TLSEXT_TYPE_next_proto_neg,ret);
+			s2n(npalen,ret);
+			memcpy(ret, npa, npalen);
+			ret += npalen;
+			s->s3->next_proto_neg_seen = 1;
+			}
+		}
+#endif
+
 	if ((extdatalen = ret-p-2)== 0) 
 		return p;
 
@@ -958,6 +995,28 @@
 				else
 					s->tlsext_status_type = -1;
 			}
+#ifndef OPENSSL_NO_NPN
+		else if (type == TLSEXT_TYPE_next_proto_neg &&
+                         s->s3->tmp.finish_md_len == 0)
+			{
+			/* We shouldn't accept this extension on a
+			 * renegotiation.
+			 *
+			 * s->new_session will be set on renegotiation, but we
+			 * probably shouldn't rely that it couldn't be set on
+			 * the initial renegotation too in certain cases (when
+			 * there's some other reason to disallow resuming an
+			 * earlier session -- the current code won't be doing
+			 * anything like that, but this might change).
+
+			 * A valid sign that there's been a previous handshake
+			 * in this connection is if s->s3->tmp.finish_md_len >
+			 * 0.  (We are talking about a check that will happen
+			 * in the Hello protocol round, well before a new
+			 * Finished message could have been computed.) */
+			s->s3->next_proto_neg_seen = 1;
+			}
+#endif
 
 		/* session ticket processed earlier */
 		data+=size;
@@ -981,6 +1040,26 @@
 	return 1;
 	}
 
+#ifndef OPENSSL_NO_NPN
+/* ssl_next_proto_validate validates a Next Protocol Negotiation block. No
+ * elements of zero length are allowed and the set of elements must exactly fill
+ * the length of the block. */
+static char ssl_next_proto_validate(unsigned char *d, unsigned len)
+	{
+	unsigned int off = 0;
+
+	while (off < len)
+		{
+		if (d[off] == 0)
+			return 0;
+		off += d[off];
+		off++;
+		}
+
+	return off == len;
+	}
+#endif
+
 int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
 	{
 	unsigned short length;
@@ -1115,6 +1194,39 @@
 			/* Set flag to expect CertificateStatus message */
 			s->tlsext_status_expected = 1;
 			}
+#ifndef OPENSSL_NO_NPN
+		else if (type == TLSEXT_TYPE_next_proto_neg)
+			{
+			unsigned char *selected;
+			unsigned char selected_len;
+
+			/* We must have requested it. */
+			if ((s->ctx->next_proto_select_cb == NULL))
+				{
+				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
+				return 0;
+				}
+			/* The data must be valid */
+			if (!ssl_next_proto_validate(data, size))
+				{
+				*al = TLS1_AD_DECODE_ERROR;
+				return 0;
+				}
+			if (s->ctx->next_proto_select_cb(s, &selected, &selected_len, data, size, s->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			s->next_proto_negotiated = OPENSSL_malloc(selected_len);
+			if (!s->next_proto_negotiated)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			memcpy(s->next_proto_negotiated, selected, selected_len);
+			s->next_proto_negotiated_len = selected_len;
+			}
+#endif
 		else if (type == TLSEXT_TYPE_renegotiate)
 			{
 			if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))