Home | History | Annotate | Download | only in patches
      1 From 5ebeb8b5d90f9f47418b6b8d898ace8f1b4d4104 Mon Sep 17 00:00:00 2001
      2 From: Adam Langley <agl (a] chromium.org>
      3 Date: Mon, 15 Apr 2013 18:07:47 -0400
      4 
      5 This change adds support for ALPN[1] in OpenSSL. ALPN is the IETF
      6 blessed version of NPN and we'll be supporting both ALPN and NPN for
      7 some time yet.
      8 
      9 [1] https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-00
     10 ---
     11  apps/s_client.c |  40 +++++++++++++-
     12  ssl/s3_lib.c    |  13 +++++
     13  ssl/ssl.h       |  45 +++++++++++++++
     14  ssl/ssl3.h      |  10 ++++
     15  ssl/ssl_lib.c   |  87 +++++++++++++++++++++++++++++
     16  ssl/t1_lib.c    | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
     17  ssl/tls1.h      |   3 +
     18  7 files changed, 362 insertions(+), 3 deletions(-)
     19 
     20 diff --git a/apps/s_client.c b/apps/s_client.c
     21 index 791e277..cb1efcd 100644
     22 --- a/apps/s_client.c
     23 +++ b/apps/s_client.c
     24 @@ -359,6 +359,7 @@ static void sc_usage(void)
     25  	BIO_printf(bio_err," -no_ticket        - disable use of RFC4507bis session tickets\n");
     26  # ifndef OPENSSL_NO_NEXTPROTONEG
     27  	BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
     28 +	BIO_printf(bio_err," -alpn arg         - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
     29  # endif
     30  #endif
     31  	BIO_printf(bio_err," -cutthrough       - enable 1-RTT full-handshake for strong ciphers\n");
     32 @@ -611,6 +612,7 @@ int MAIN(int argc, char **argv)
     33          {NULL,0};
     34  # ifndef OPENSSL_NO_NEXTPROTONEG
     35  	const char *next_proto_neg_in = NULL;
     36 +	const char *alpn_in = NULL;
     37  # endif
     38  #endif
     39  	char *sess_in = NULL;
     40 @@ -883,6 +885,11 @@ int MAIN(int argc, char **argv)
     41  			if (--argc < 1) goto bad;
     42  			next_proto_neg_in = *(++argv);
     43  			}
     44 +		else if (strcmp(*argv,"-alpn") == 0)
     45 +			{
     46 +			if (--argc < 1) goto bad;
     47 +			alpn_in = *(++argv);
     48 +			}
     49  # endif
     50  #endif
     51  		else if (strcmp(*argv,"-cutthrough") == 0)
     52 @@ -1157,9 +1164,23 @@ bad:
     53  	 */
     54  	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
     55  
     56 -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
     57 +#if !defined(OPENSSL_NO_TLSEXT)
     58 +# if !defined(OPENSSL_NO_NEXTPROTONEG)
     59  	if (next_proto.data)
     60  		SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
     61 +# endif
     62 +	if (alpn_in)
     63 +		{
     64 +		unsigned short alpn_len;
     65 +		unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in);
     66 +
     67 +		if (alpn == NULL)
     68 +			{
     69 +			BIO_printf(bio_err, "Error parsing -alpn argument\n");
     70 +			goto end;
     71 +			}
     72 +		SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
     73 +		}
     74  #endif
     75  
     76  	/* Enable handshake cutthrough for client connections using
     77 @@ -2077,7 +2098,8 @@ static void print_stuff(BIO *bio, SSL *s, int full)
     78  	}
     79  #endif
     80  
     81 -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
     82 +#if !defined(OPENSSL_NO_TLSEXT)
     83 +# if !defined(OPENSSL_NO_NEXTPROTONEG)
     84  	if (next_proto.status != -1) {
     85  		const unsigned char *proto;
     86  		unsigned int proto_len;
     87 @@ -2086,6 +2108,20 @@ static void print_stuff(BIO *bio, SSL *s, int full)
     88  		BIO_write(bio, proto, proto_len);
     89  		BIO_write(bio, "\n", 1);
     90  	}
     91 +	{
     92 +		const unsigned char *proto;
     93 +		unsigned int proto_len;
     94 +		SSL_get0_alpn_selected(s, &proto, &proto_len);
     95 +		if (proto_len > 0)
     96 +			{
     97 +			BIO_printf(bio, "ALPN protocol: ");
     98 +			BIO_write(bio, proto, proto_len);
     99 +			BIO_write(bio, "\n", 1);
    100 +			}
    101 +		else
    102 +			BIO_printf(bio, "No ALPN negotiated\n");
    103 +	}
    104 +# endif
    105  #endif
    106  
    107  #ifndef OPENSSL_NO_SRTP
    108 diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
    109 index 5e46393..2cd1654 100644
    110 --- a/ssl/s3_lib.c
    111 +++ b/ssl/s3_lib.c
    112 @@ -2996,6 +2996,11 @@ void ssl3_free(SSL *s)
    113  		BIO_free(s->s3->handshake_buffer);
    114  	}
    115  	if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
    116 +#ifndef OPENSSL_NO_TLSEXT
    117 +	if (s->s3->alpn_selected)
    118 +		OPENSSL_free(s->s3->alpn_selected);
    119 +#endif
    120 +
    121  #ifndef OPENSSL_NO_SRP
    122  	SSL_SRP_CTX_free(s);
    123  #endif
    124 @@ -3055,6 +3060,14 @@ void ssl3_clear(SSL *s)
    125  	if (s->s3->handshake_dgst) {
    126  		ssl3_free_digest_list(s);
    127  	}	
    128 +
    129 +#if !defined(OPENSSL_NO_TLSEXT)
    130 +	if (s->s3->alpn_selected)
    131 +		{
    132 +		free(s->s3->alpn_selected);
    133 +		s->s3->alpn_selected = NULL;
    134 +		}
    135 +#endif
    136  	memset(s->s3,0,sizeof *s->s3);
    137  	s->s3->rbuf.buf = rp;
    138  	s->s3->wbuf.buf = wp;
    139 diff --git a/ssl/ssl.h b/ssl/ssl.h
    140 index e8c73fa..612c7aa 100644
    141 --- a/ssl/ssl.h
    142 +++ b/ssl/ssl.h
    143 @@ -1019,6 +1019,31 @@ struct ssl_ctx_st
    144  				    void *arg);
    145  	void *next_proto_select_cb_arg;
    146  # endif
    147 +
    148 +	/* ALPN information
    149 +	 * (we are in the process of transitioning from NPN to ALPN.) */
    150 +
    151 +	/* For a server, this contains a callback function that allows the
    152 +	 * server to select the protocol for the connection.
    153 +	 *   out: on successful return, this must point to the raw protocol
    154 +	 *        name (without the length prefix).
    155 +	 *   outlen: on successful return, this contains the length of |*out|.
    156 +	 *   in: points to the client's list of supported protocols in
    157 +	 *       wire-format.
    158 +	 *   inlen: the length of |in|. */
    159 +	int (*alpn_select_cb)(SSL *s,
    160 +			      const unsigned char **out,
    161 +			      unsigned char *outlen,
    162 +			      const unsigned char* in,
    163 +			      unsigned int inlen,
    164 +			      void *arg);
    165 +	void *alpn_select_cb_arg;
    166 +
    167 +	/* For a client, this contains the list of supported protocols in wire
    168 +	 * format. */
    169 +	unsigned char* alpn_client_proto_list;
    170 +	unsigned alpn_client_proto_list_len;
    171 +
    172          /* SRTP profiles we are willing to do from RFC 5764 */
    173          STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;  
    174  
    175 @@ -1120,6 +1145,21 @@ void SSL_get0_next_proto_negotiated(const SSL *s,
    176  #define OPENSSL_NPN_NO_OVERLAP	2
    177  #endif
    178  
    179 +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char* protos,
    180 +			    unsigned protos_len);
    181 +int SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos,
    182 +			unsigned protos_len);
    183 +void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
    184 +				int (*cb) (SSL *ssl,
    185 +					   const unsigned char **out,
    186 +					   unsigned char *outlen,
    187 +					   const unsigned char *in,
    188 +					   unsigned int inlen,
    189 +					   void *arg),
    190 +				void *arg);
    191 +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
    192 +			    unsigned *len);
    193 +
    194  #ifndef OPENSSL_NO_PSK
    195  /* the maximum length of the buffer given to callbacks containing the
    196   * resulting identity/psk */
    197 @@ -1422,6 +1462,11 @@ struct ssl_st
    198  	char tlsext_channel_id_enabled;
    199  	/* The client's Channel ID private key. */
    200  	EVP_PKEY *tlsext_channel_id_private;
    201 +
    202 +	/* For a client, this contains the list of supported protocols in wire
    203 +	 * format. */
    204 +	unsigned char* alpn_client_proto_list;
    205 +	unsigned alpn_client_proto_list_len;
    206  #else
    207  #define session_ctx ctx
    208  #endif /* OPENSSL_NO_TLSEXT */
    209 diff --git a/ssl/ssl3.h b/ssl/ssl3.h
    210 index 3229995..28c46d5 100644
    211 --- a/ssl/ssl3.h
    212 +++ b/ssl/ssl3.h
    213 @@ -551,6 +551,16 @@ typedef struct ssl3_state_st
    214  	 *     each are big-endian values. */
    215  	unsigned char tlsext_channel_id[64];
    216  
    217 +	/* ALPN information
    218 +	 * (we are in the process of transitioning from NPN to ALPN.) */
    219 +
    220 +	/* In a server these point to the selected ALPN protocol after the
    221 +	 * ClientHello has been processed. In a client these contain the
    222 +	 * protocol that the server selected once the ServerHello has been
    223 +	 * processed. */
    224 +	unsigned char *alpn_selected;
    225 +	unsigned alpn_selected_len;
    226 +
    227  	/* These point to the digest function to use for signatures made with
    228  	 * each type of public key. A NULL value indicates that the default
    229  	 * digest should be used, which is SHA1 as of TLS 1.2.
    230 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
    231 index e360550..b472423 100644
    232 --- a/ssl/ssl_lib.c
    233 +++ b/ssl/ssl_lib.c
    234 @@ -359,6 +359,17 @@ SSL *SSL_new(SSL_CTX *ctx)
    235  # ifndef OPENSSL_NO_NEXTPROTONEG
    236  	s->next_proto_negotiated = NULL;
    237  # endif
    238 +
    239 +	if (s->ctx->alpn_client_proto_list)
    240 +		{
    241 +		s->alpn_client_proto_list =
    242 +			OPENSSL_malloc(s->ctx->alpn_client_proto_list_len);
    243 +		if (s->alpn_client_proto_list == NULL)
    244 +			goto err;
    245 +		memcpy(s->alpn_client_proto_list, s->ctx->alpn_client_proto_list,
    246 +		       s->ctx->alpn_client_proto_list_len);
    247 +		s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
    248 +		}
    249  #endif
    250  
    251  	s->verify_result=X509_V_OK;
    252 @@ -564,6 +575,8 @@ void SSL_free(SSL *s)
    253  		OPENSSL_free(s->tlsext_ocsp_resp);
    254  	if (s->tlsext_channel_id_private)
    255  		EVP_PKEY_free(s->tlsext_channel_id_private);
    256 +	if (s->alpn_client_proto_list)
    257 +		OPENSSL_free(s->alpn_client_proto_list);
    258  #endif
    259  
    260  	if (s->client_CA != NULL)
    261 @@ -1615,6 +1628,78 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned
    262  	ctx->next_proto_select_cb_arg = arg;
    263  	}
    264  # endif
    265 +
    266 +/* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
    267 + * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
    268 + * length-prefixed strings).
    269 + *
    270 + * Returns 0 on success. */
    271 +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char* protos,
    272 +			    unsigned protos_len)
    273 +	{
    274 +	if (ctx->alpn_client_proto_list)
    275 +		OPENSSL_free(ctx->alpn_client_proto_list);
    276 +
    277 +	ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len);
    278 +	if (!ctx->alpn_client_proto_list)
    279 +		return 1;
    280 +	memcpy(ctx->alpn_client_proto_list, protos, protos_len);
    281 +	ctx->alpn_client_proto_list_len = protos_len;
    282 +
    283 +	return 0;
    284 +	}
    285 +
    286 +/* SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|.
    287 + * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
    288 + * length-prefixed strings).
    289 + *
    290 + * Returns 0 on success. */
    291 +int SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos,
    292 +			unsigned protos_len)
    293 +	{
    294 +	if (ssl->alpn_client_proto_list)
    295 +		OPENSSL_free(ssl->alpn_client_proto_list);
    296 +
    297 +	ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len);
    298 +	if (!ssl->alpn_client_proto_list)
    299 +		return 1;
    300 +	memcpy(ssl->alpn_client_proto_list, protos, protos_len);
    301 +	ssl->alpn_client_proto_list_len = protos_len;
    302 +
    303 +	return 0;
    304 +	}
    305 +
    306 +/* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called
    307 + * during ClientHello processing in order to select an ALPN protocol from the
    308 + * client's list of offered protocols. */
    309 +void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
    310 +				int (*cb) (SSL *ssl,
    311 +					   const unsigned char **out,
    312 +					   unsigned char *outlen,
    313 +					   const unsigned char *in,
    314 +					   unsigned int inlen,
    315 +					   void *arg),
    316 +				void *arg)
    317 +	{
    318 +	ctx->alpn_select_cb = cb;
    319 +	ctx->alpn_select_cb_arg = arg;
    320 +	}
    321 +
    322 +/* SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
    323 + * On return it sets |*data| to point to |*len| bytes of protocol name (not
    324 + * including the leading length-prefix byte). If the server didn't respond with
    325 + * a negotiated protocol then |*len| will be zero. */
    326 +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
    327 +			    unsigned *len)
    328 +	{
    329 +	*data = NULL;
    330 +	if (ssl->s3)
    331 +		*data = ssl->s3->alpn_selected;
    332 +	if (*data == NULL)
    333 +		*len = 0;
    334 +	else
    335 +		*len = ssl->s3->alpn_selected_len;
    336 +	}
    337  #endif
    338  
    339  int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
    340 @@ -1955,6 +2040,8 @@ void SSL_CTX_free(SSL_CTX *a)
    341  #ifndef OPENSSL_NO_TLSEXT
    342  	if (a->tlsext_channel_id_private)
    343  		EVP_PKEY_free(a->tlsext_channel_id_private);
    344 +	if (a->alpn_client_proto_list != NULL)
    345 +		OPENSSL_free(a->alpn_client_proto_list);
    346  #endif
    347  
    348  	OPENSSL_free(a);
    349 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
    350 index 1f93a6f..b2e049a 100644
    351 --- a/ssl/t1_lib.c
    352 +++ b/ssl/t1_lib.c
    353 @@ -659,6 +659,18 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
    354  		s2n(0,ret);
    355  		}
    356  
    357 +	if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len)
    358 +		{
    359 +		if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len)
    360 +			return NULL;
    361 +		s2n(TLSEXT_TYPE_application_layer_protocol_negotiation,ret);
    362 +		s2n(2 + s->alpn_client_proto_list_len,ret);
    363 +		s2n(s->alpn_client_proto_list_len,ret);
    364 +		memcpy(ret, s->alpn_client_proto_list,
    365 +		       s->alpn_client_proto_list_len);
    366 +		ret += s->alpn_client_proto_list_len;
    367 +		}
    368 +
    369  #ifndef OPENSSL_NO_SRTP
    370          if(SSL_get_srtp_profiles(s))
    371                  {
    372 @@ -879,6 +891,21 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
    373  		s2n(0,ret);
    374  		}
    375  
    376 +	if (s->s3->alpn_selected)
    377 +		{
    378 +		const unsigned char *selected = s->s3->alpn_selected;
    379 +		unsigned len = s->s3->alpn_selected_len;
    380 +
    381 +		if ((long)(limit - ret - 4 - 2 - 1 - len) < 0)
    382 +			return NULL;
    383 +		s2n(TLSEXT_TYPE_application_layer_protocol_negotiation,ret);
    384 +		s2n(3 + len,ret);
    385 +		s2n(1 + len,ret);
    386 +		*ret++ = len;
    387 +		memcpy(ret, selected, len);
    388 +		ret += len;
    389 +		}
    390 +
    391  	if ((extdatalen = ret-orig-2)== 0) 
    392  		return p;
    393  
    394 @@ -966,6 +993,76 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, const unsign
    395  	s->is_probably_safari = 1;
    396  }
    397  
    398 +/* tls1_alpn_handle_client_hello is called to process the ALPN extension in a
    399 + * ClientHello.
    400 + *   data: the contents of the extension, not including the type and length.
    401 + *   data_len: the number of bytes in |data|
    402 + *   al: a pointer to the alert value to send in the event of a non-zero
    403 + *       return.
    404 + *
    405 + *   returns: 0 on success. */
    406 +static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data,
    407 +					 unsigned data_len, int *al)
    408 +	{
    409 +	unsigned i;
    410 +	unsigned proto_len;
    411 +	const unsigned char *selected;
    412 +	unsigned char selected_len;
    413 +	int r;
    414 +
    415 +	if (s->ctx->alpn_select_cb == NULL)
    416 +		return 0;
    417 +
    418 +	if (data_len < 2)
    419 +		goto parse_error;
    420 +
    421 +	/* data should contain a uint16 length followed by a series of 8-bit,
    422 +	 * length-prefixed strings. */
    423 +	i = ((unsigned) data[0]) << 8 |
    424 +	    ((unsigned) data[1]);
    425 +	data_len -= 2;
    426 +	data += 2;
    427 +	if (data_len != i)
    428 +		goto parse_error;
    429 +
    430 +	if (data_len < 2)
    431 +		goto parse_error;
    432 +
    433 +	for (i = 0; i < data_len;)
    434 +		{
    435 +		proto_len = data[i];
    436 +		i++;
    437 +
    438 +		if (proto_len == 0)
    439 +			goto parse_error;
    440 +
    441 +		if (i + proto_len < i || i + proto_len > data_len)
    442 +			goto parse_error;
    443 +
    444 +		i += proto_len;
    445 +		}
    446 +
    447 +	r = s->ctx->alpn_select_cb(s, &selected, &selected_len, data, data_len,
    448 +				   s->ctx->alpn_select_cb_arg);
    449 +	if (r == SSL_TLSEXT_ERR_OK) {
    450 +		if (s->s3->alpn_selected)
    451 +			OPENSSL_free(s->s3->alpn_selected);
    452 +		s->s3->alpn_selected = OPENSSL_malloc(selected_len);
    453 +		if (!s->s3->alpn_selected)
    454 +			{
    455 +			*al = SSL_AD_INTERNAL_ERROR;
    456 +			return -1;
    457 +			}
    458 +		memcpy(s->s3->alpn_selected, selected, selected_len);
    459 +		s->s3->alpn_selected_len = selected_len;
    460 +	}
    461 +	return 0;
    462 +
    463 +parse_error:
    464 +	*al = SSL_AD_DECODE_ERROR;
    465 +	return -1;
    466 +	}
    467 +
    468  int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
    469  	{
    470  	unsigned short type;
    471 @@ -988,6 +1085,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
    472  	s->s3->next_proto_neg_seen = 0;
    473  #endif
    474  
    475 +	if (s->s3->alpn_selected)
    476 +		{
    477 +		OPENSSL_free(s->s3->alpn_selected);
    478 +		s->s3->alpn_selected = NULL;
    479 +		}
    480 +
    481  #ifndef OPENSSL_NO_HEARTBEATS
    482  	s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
    483  	                       SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
    484 @@ -1420,7 +1523,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
    485  #endif
    486  #ifndef OPENSSL_NO_NEXTPROTONEG
    487  		else if (type == TLSEXT_TYPE_next_proto_neg &&
    488 -			 s->s3->tmp.finish_md_len == 0)
    489 +			 s->s3->tmp.finish_md_len == 0 &&
    490 +			 s->s3->alpn_selected == NULL)
    491  			{
    492  			/* We shouldn't accept this extension on a
    493  			 * renegotiation.
    494 @@ -1444,6 +1548,16 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
    495  		else if (type == TLSEXT_TYPE_channel_id && s->tlsext_channel_id_enabled)
    496  			s->s3->tlsext_channel_id_valid = 1;
    497  
    498 +		else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
    499 +			 s->ctx->alpn_select_cb &&
    500 +			 s->s3->tmp.finish_md_len == 0)
    501 +			{
    502 +			if (tls1_alpn_handle_client_hello(s, data, size, al) != 0)
    503 +				return 0;
    504 +			/* ALPN takes precedence over NPN. */
    505 +			s->s3->next_proto_neg_seen = 0;
    506 +			}
    507 +
    508  		/* session ticket processed earlier */
    509  #ifndef OPENSSL_NO_SRTP
    510  		else if (type == TLSEXT_TYPE_use_srtp)
    511 @@ -1508,6 +1622,12 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
    512  	s->s3->next_proto_neg_seen = 0;
    513  #endif
    514  
    515 +	if (s->s3->alpn_selected)
    516 +		{
    517 +		OPENSSL_free(s->s3->alpn_selected);
    518 +		s->s3->alpn_selected = NULL;
    519 +		}
    520 +
    521  #ifndef OPENSSL_NO_HEARTBEATS
    522  	s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
    523  	                       SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
    524 @@ -1677,6 +1797,51 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
    525  		else if (type == TLSEXT_TYPE_channel_id)
    526  			s->s3->tlsext_channel_id_valid = 1;
    527  
    528 +		else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation)
    529 +			{
    530 +			unsigned len;
    531 +
    532 +			/* We must have requested it. */
    533 +			if (s->alpn_client_proto_list == NULL)
    534 +				{
    535 +				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
    536 +				return 0;
    537 +				}
    538 +			if (size < 4)
    539 +				{
    540 +				*al = TLS1_AD_DECODE_ERROR;
    541 +				return 0;
    542 +				}
    543 +			/* The extension data consists of:
    544 +			 *   uint16 list_length
    545 +			 *   uint8 proto_length;
    546 +			 *   uint8 proto[proto_length]; */
    547 +			len = data[0];
    548 +			len <<= 8;
    549 +			len |= data[1];
    550 +			if (len != (unsigned) size - 2)
    551 +				{
    552 +				*al = TLS1_AD_DECODE_ERROR;
    553 +				return 0;
    554 +				}
    555 +			len = data[2];
    556 +			if (len != (unsigned) size - 3)
    557 +				{
    558 +				*al = TLS1_AD_DECODE_ERROR;
    559 +				return 0;
    560 +				}
    561 +			if (s->s3->alpn_selected)
    562 +				OPENSSL_free(s->s3->alpn_selected);
    563 +			s->s3->alpn_selected = OPENSSL_malloc(len);
    564 +			if (!s->s3->alpn_selected)
    565 +				{
    566 +				*al = TLS1_AD_INTERNAL_ERROR;
    567 +				return 0;
    568 +				}
    569 +			memcpy(s->s3->alpn_selected, data + 3, len);
    570 +			s->s3->alpn_selected_len = len;
    571 +			}
    572 +
    573  		else if (type == TLSEXT_TYPE_renegotiate)
    574  			{
    575  			if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
    576 diff --git a/ssl/tls1.h b/ssl/tls1.h
    577 index 8fc1ff4..c6670f4 100644
    578 --- a/ssl/tls1.h
    579 +++ b/ssl/tls1.h
    580 @@ -230,6 +230,9 @@ extern "C" {
    581  /* ExtensionType value from RFC5620 */
    582  #define TLSEXT_TYPE_heartbeat	15
    583  
    584 +/* ExtensionType value from draft-ietf-tls-applayerprotoneg-00 */
    585 +#define TLSEXT_TYPE_application_layer_protocol_negotiation 16
    586 +
    587  /* ExtensionType value from RFC4507 */
    588  #define TLSEXT_TYPE_session_ticket		35
    589  
    590 -- 
    591 1.8.2.1
    592 
    593