aboutsummaryrefslogtreecommitdiff
path: root/patches/0008-alpn.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/0008-alpn.patch')
-rw-r--r--patches/0008-alpn.patch592
1 files changed, 0 insertions, 592 deletions
diff --git a/patches/0008-alpn.patch b/patches/0008-alpn.patch
deleted file mode 100644
index 6fccbd31fa..0000000000
--- a/patches/0008-alpn.patch
+++ /dev/null
@@ -1,592 +0,0 @@
-From 5ebeb8b5d90f9f47418b6b8d898ace8f1b4d4104 Mon Sep 17 00:00:00 2001
-From: Adam Langley <agl@chromium.org>
-Date: Mon, 15 Apr 2013 18:07:47 -0400
-
-This change adds support for ALPN[1] in OpenSSL. ALPN is the IETF
-blessed version of NPN and we'll be supporting both ALPN and NPN for
-some time yet.
-
-[1] https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-00
----
- apps/s_client.c | 40 +++++++++++++-
- ssl/s3_lib.c | 13 +++++
- ssl/ssl.h | 45 +++++++++++++++
- ssl/ssl3.h | 10 ++++
- ssl/ssl_lib.c | 87 +++++++++++++++++++++++++++++
- ssl/t1_lib.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
- ssl/tls1.h | 3 +
- 7 files changed, 362 insertions(+), 3 deletions(-)
-
-diff --git a/apps/s_client.c b/apps/s_client.c
-index 791e277..cb1efcd 100644
---- a/apps/s_client.c
-+++ b/apps/s_client.c
-@@ -359,6 +359,7 @@ static void sc_usage(void)
- BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
- # ifndef OPENSSL_NO_NEXTPROTONEG
- BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
-+ BIO_printf(bio_err," -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
- # endif
- #endif
- BIO_printf(bio_err," -cutthrough - enable 1-RTT full-handshake for strong ciphers\n");
-@@ -611,6 +612,7 @@ int MAIN(int argc, char **argv)
- {NULL,0};
- # ifndef OPENSSL_NO_NEXTPROTONEG
- const char *next_proto_neg_in = NULL;
-+ const char *alpn_in = NULL;
- # endif
- #endif
- char *sess_in = NULL;
-@@ -883,6 +885,11 @@ int MAIN(int argc, char **argv)
- if (--argc < 1) goto bad;
- next_proto_neg_in = *(++argv);
- }
-+ else if (strcmp(*argv,"-alpn") == 0)
-+ {
-+ if (--argc < 1) goto bad;
-+ alpn_in = *(++argv);
-+ }
- # endif
- #endif
- else if (strcmp(*argv,"-cutthrough") == 0)
-@@ -1157,9 +1164,23 @@ bad:
- */
- if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
-
--#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+#if !defined(OPENSSL_NO_TLSEXT)
-+# if !defined(OPENSSL_NO_NEXTPROTONEG)
- if (next_proto.data)
- SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
-+# endif
-+ if (alpn_in)
-+ {
-+ unsigned short alpn_len;
-+ unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in);
-+
-+ if (alpn == NULL)
-+ {
-+ BIO_printf(bio_err, "Error parsing -alpn argument\n");
-+ goto end;
-+ }
-+ SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
-+ }
- #endif
-
- /* Enable handshake cutthrough for client connections using
-@@ -2077,7 +2098,8 @@ static void print_stuff(BIO *bio, SSL *s, int full)
- }
- #endif
-
--#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+#if !defined(OPENSSL_NO_TLSEXT)
-+# if !defined(OPENSSL_NO_NEXTPROTONEG)
- if (next_proto.status != -1) {
- const unsigned char *proto;
- unsigned int proto_len;
-@@ -2086,6 +2108,20 @@ static void print_stuff(BIO *bio, SSL *s, int full)
- BIO_write(bio, proto, proto_len);
- BIO_write(bio, "\n", 1);
- }
-+ {
-+ const unsigned char *proto;
-+ unsigned int proto_len;
-+ SSL_get0_alpn_selected(s, &proto, &proto_len);
-+ if (proto_len > 0)
-+ {
-+ BIO_printf(bio, "ALPN protocol: ");
-+ BIO_write(bio, proto, proto_len);
-+ BIO_write(bio, "\n", 1);
-+ }
-+ else
-+ BIO_printf(bio, "No ALPN negotiated\n");
-+ }
-+# endif
- #endif
-
- #ifndef OPENSSL_NO_SRTP
-diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
-index 5e46393..2cd1654 100644
---- a/ssl/s3_lib.c
-+++ b/ssl/s3_lib.c
-@@ -2996,6 +2996,11 @@ void ssl3_free(SSL *s)
- BIO_free(s->s3->handshake_buffer);
- }
- if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
-+#ifndef OPENSSL_NO_TLSEXT
-+ if (s->s3->alpn_selected)
-+ OPENSSL_free(s->s3->alpn_selected);
-+#endif
-+
- #ifndef OPENSSL_NO_SRP
- SSL_SRP_CTX_free(s);
- #endif
-@@ -3055,6 +3060,14 @@ void ssl3_clear(SSL *s)
- if (s->s3->handshake_dgst) {
- ssl3_free_digest_list(s);
- }
-+
-+#if !defined(OPENSSL_NO_TLSEXT)
-+ if (s->s3->alpn_selected)
-+ {
-+ free(s->s3->alpn_selected);
-+ s->s3->alpn_selected = NULL;
-+ }
-+#endif
- memset(s->s3,0,sizeof *s->s3);
- s->s3->rbuf.buf = rp;
- s->s3->wbuf.buf = wp;
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index e8c73fa..612c7aa 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -1019,6 +1019,31 @@ struct ssl_ctx_st
- void *arg);
- void *next_proto_select_cb_arg;
- # endif
-+
-+ /* ALPN information
-+ * (we are in the process of transitioning from NPN to ALPN.) */
-+
-+ /* For a server, this contains a callback function that allows the
-+ * server to select the protocol for the connection.
-+ * out: on successful return, this must point to the raw protocol
-+ * name (without the length prefix).
-+ * outlen: on successful return, this contains the length of |*out|.
-+ * in: points to the client's list of supported protocols in
-+ * wire-format.
-+ * inlen: the length of |in|. */
-+ int (*alpn_select_cb)(SSL *s,
-+ const unsigned char **out,
-+ unsigned char *outlen,
-+ const unsigned char* in,
-+ unsigned int inlen,
-+ void *arg);
-+ void *alpn_select_cb_arg;
-+
-+ /* For a client, this contains the list of supported protocols in wire
-+ * format. */
-+ unsigned char* alpn_client_proto_list;
-+ unsigned alpn_client_proto_list_len;
-+
- /* SRTP profiles we are willing to do from RFC 5764 */
- STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
-
-@@ -1120,6 +1145,21 @@ void SSL_get0_next_proto_negotiated(const SSL *s,
- #define OPENSSL_NPN_NO_OVERLAP 2
- #endif
-
-+int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char* protos,
-+ unsigned protos_len);
-+int SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos,
-+ unsigned protos_len);
-+void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
-+ int (*cb) (SSL *ssl,
-+ const unsigned char **out,
-+ unsigned char *outlen,
-+ const unsigned char *in,
-+ unsigned int inlen,
-+ void *arg),
-+ void *arg);
-+void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
-+ unsigned *len);
-+
- #ifndef OPENSSL_NO_PSK
- /* the maximum length of the buffer given to callbacks containing the
- * resulting identity/psk */
-@@ -1422,6 +1462,11 @@ struct ssl_st
- char tlsext_channel_id_enabled;
- /* The client's Channel ID private key. */
- EVP_PKEY *tlsext_channel_id_private;
-+
-+ /* For a client, this contains the list of supported protocols in wire
-+ * format. */
-+ unsigned char* alpn_client_proto_list;
-+ unsigned alpn_client_proto_list_len;
- #else
- #define session_ctx ctx
- #endif /* OPENSSL_NO_TLSEXT */
-diff --git a/ssl/ssl3.h b/ssl/ssl3.h
-index 3229995..28c46d5 100644
---- a/ssl/ssl3.h
-+++ b/ssl/ssl3.h
-@@ -551,6 +551,16 @@ typedef struct ssl3_state_st
- * each are big-endian values. */
- unsigned char tlsext_channel_id[64];
-
-+ /* ALPN information
-+ * (we are in the process of transitioning from NPN to ALPN.) */
-+
-+ /* In a server these point to the selected ALPN protocol after the
-+ * ClientHello has been processed. In a client these contain the
-+ * protocol that the server selected once the ServerHello has been
-+ * processed. */
-+ unsigned char *alpn_selected;
-+ unsigned alpn_selected_len;
-+
- /* These point to the digest function to use for signatures made with
- * each type of public key. A NULL value indicates that the default
- * digest should be used, which is SHA1 as of TLS 1.2.
-diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
-index e360550..b472423 100644
---- a/ssl/ssl_lib.c
-+++ b/ssl/ssl_lib.c
-@@ -359,6 +359,17 @@ SSL *SSL_new(SSL_CTX *ctx)
- # ifndef OPENSSL_NO_NEXTPROTONEG
- s->next_proto_negotiated = NULL;
- # endif
-+
-+ if (s->ctx->alpn_client_proto_list)
-+ {
-+ s->alpn_client_proto_list =
-+ OPENSSL_malloc(s->ctx->alpn_client_proto_list_len);
-+ if (s->alpn_client_proto_list == NULL)
-+ goto err;
-+ memcpy(s->alpn_client_proto_list, s->ctx->alpn_client_proto_list,
-+ s->ctx->alpn_client_proto_list_len);
-+ s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
-+ }
- #endif
-
- s->verify_result=X509_V_OK;
-@@ -564,6 +575,8 @@ void SSL_free(SSL *s)
- OPENSSL_free(s->tlsext_ocsp_resp);
- if (s->tlsext_channel_id_private)
- EVP_PKEY_free(s->tlsext_channel_id_private);
-+ if (s->alpn_client_proto_list)
-+ OPENSSL_free(s->alpn_client_proto_list);
- #endif
-
- if (s->client_CA != NULL)
-@@ -1615,6 +1628,78 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned
- ctx->next_proto_select_cb_arg = arg;
- }
- # endif
-+
-+/* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
-+ * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
-+ * length-prefixed strings).
-+ *
-+ * Returns 0 on success. */
-+int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char* protos,
-+ unsigned protos_len)
-+ {
-+ if (ctx->alpn_client_proto_list)
-+ OPENSSL_free(ctx->alpn_client_proto_list);
-+
-+ ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len);
-+ if (!ctx->alpn_client_proto_list)
-+ return 1;
-+ memcpy(ctx->alpn_client_proto_list, protos, protos_len);
-+ ctx->alpn_client_proto_list_len = protos_len;
-+
-+ return 0;
-+ }
-+
-+/* SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|.
-+ * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
-+ * length-prefixed strings).
-+ *
-+ * Returns 0 on success. */
-+int SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos,
-+ unsigned protos_len)
-+ {
-+ if (ssl->alpn_client_proto_list)
-+ OPENSSL_free(ssl->alpn_client_proto_list);
-+
-+ ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len);
-+ if (!ssl->alpn_client_proto_list)
-+ return 1;
-+ memcpy(ssl->alpn_client_proto_list, protos, protos_len);
-+ ssl->alpn_client_proto_list_len = protos_len;
-+
-+ return 0;
-+ }
-+
-+/* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called
-+ * during ClientHello processing in order to select an ALPN protocol from the
-+ * client's list of offered protocols. */
-+void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
-+ int (*cb) (SSL *ssl,
-+ const unsigned char **out,
-+ unsigned char *outlen,
-+ const unsigned char *in,
-+ unsigned int inlen,
-+ void *arg),
-+ void *arg)
-+ {
-+ ctx->alpn_select_cb = cb;
-+ ctx->alpn_select_cb_arg = arg;
-+ }
-+
-+/* SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
-+ * On return it sets |*data| to point to |*len| bytes of protocol name (not
-+ * including the leading length-prefix byte). If the server didn't respond with
-+ * a negotiated protocol then |*len| will be zero. */
-+void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
-+ unsigned *len)
-+ {
-+ *data = NULL;
-+ if (ssl->s3)
-+ *data = ssl->s3->alpn_selected;
-+ if (*data == NULL)
-+ *len = 0;
-+ else
-+ *len = ssl->s3->alpn_selected_len;
-+ }
- #endif
-
- int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
-@@ -1955,6 +2040,8 @@ void SSL_CTX_free(SSL_CTX *a)
- #ifndef OPENSSL_NO_TLSEXT
- if (a->tlsext_channel_id_private)
- EVP_PKEY_free(a->tlsext_channel_id_private);
-+ if (a->alpn_client_proto_list != NULL)
-+ OPENSSL_free(a->alpn_client_proto_list);
- #endif
-
- OPENSSL_free(a);
-diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
-index 1f93a6f..b2e049a 100644
---- a/ssl/t1_lib.c
-+++ b/ssl/t1_lib.c
-@@ -659,6 +659,18 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
- s2n(0,ret);
- }
-
-+ if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len)
-+ {
-+ if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len)
-+ return NULL;
-+ s2n(TLSEXT_TYPE_application_layer_protocol_negotiation,ret);
-+ s2n(2 + s->alpn_client_proto_list_len,ret);
-+ s2n(s->alpn_client_proto_list_len,ret);
-+ memcpy(ret, s->alpn_client_proto_list,
-+ s->alpn_client_proto_list_len);
-+ ret += s->alpn_client_proto_list_len;
-+ }
-+
- #ifndef OPENSSL_NO_SRTP
- if(SSL_get_srtp_profiles(s))
- {
-@@ -879,6 +891,21 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
- s2n(0,ret);
- }
-
-+ if (s->s3->alpn_selected)
-+ {
-+ const unsigned char *selected = s->s3->alpn_selected;
-+ unsigned len = s->s3->alpn_selected_len;
-+
-+ if ((long)(limit - ret - 4 - 2 - 1 - len) < 0)
-+ return NULL;
-+ s2n(TLSEXT_TYPE_application_layer_protocol_negotiation,ret);
-+ s2n(3 + len,ret);
-+ s2n(1 + len,ret);
-+ *ret++ = len;
-+ memcpy(ret, selected, len);
-+ ret += len;
-+ }
-+
- if ((extdatalen = ret-orig-2)== 0)
- return p;
-
-@@ -966,6 +993,76 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, const unsign
- s->is_probably_safari = 1;
- }
-
-+/* tls1_alpn_handle_client_hello is called to process the ALPN extension in a
-+ * ClientHello.
-+ * data: the contents of the extension, not including the type and length.
-+ * data_len: the number of bytes in |data|
-+ * al: a pointer to the alert value to send in the event of a non-zero
-+ * return.
-+ *
-+ * returns: 0 on success. */
-+static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data,
-+ unsigned data_len, int *al)
-+ {
-+ unsigned i;
-+ unsigned proto_len;
-+ const unsigned char *selected;
-+ unsigned char selected_len;
-+ int r;
-+
-+ if (s->ctx->alpn_select_cb == NULL)
-+ return 0;
-+
-+ if (data_len < 2)
-+ goto parse_error;
-+
-+ /* data should contain a uint16 length followed by a series of 8-bit,
-+ * length-prefixed strings. */
-+ i = ((unsigned) data[0]) << 8 |
-+ ((unsigned) data[1]);
-+ data_len -= 2;
-+ data += 2;
-+ if (data_len != i)
-+ goto parse_error;
-+
-+ if (data_len < 2)
-+ goto parse_error;
-+
-+ for (i = 0; i < data_len;)
-+ {
-+ proto_len = data[i];
-+ i++;
-+
-+ if (proto_len == 0)
-+ goto parse_error;
-+
-+ if (i + proto_len < i || i + proto_len > data_len)
-+ goto parse_error;
-+
-+ i += proto_len;
-+ }
-+
-+ r = s->ctx->alpn_select_cb(s, &selected, &selected_len, data, data_len,
-+ s->ctx->alpn_select_cb_arg);
-+ if (r == SSL_TLSEXT_ERR_OK) {
-+ if (s->s3->alpn_selected)
-+ OPENSSL_free(s->s3->alpn_selected);
-+ s->s3->alpn_selected = OPENSSL_malloc(selected_len);
-+ if (!s->s3->alpn_selected)
-+ {
-+ *al = SSL_AD_INTERNAL_ERROR;
-+ return -1;
-+ }
-+ memcpy(s->s3->alpn_selected, selected, selected_len);
-+ s->s3->alpn_selected_len = selected_len;
-+ }
-+ return 0;
-+
-+parse_error:
-+ *al = SSL_AD_DECODE_ERROR;
-+ return -1;
-+ }
-+
- int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
- {
- unsigned short type;
-@@ -988,6 +1085,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
- s->s3->next_proto_neg_seen = 0;
- #endif
-
-+ if (s->s3->alpn_selected)
-+ {
-+ OPENSSL_free(s->s3->alpn_selected);
-+ s->s3->alpn_selected = NULL;
-+ }
-+
- #ifndef OPENSSL_NO_HEARTBEATS
- s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
- SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
-@@ -1420,7 +1523,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
- #endif
- #ifndef OPENSSL_NO_NEXTPROTONEG
- else if (type == TLSEXT_TYPE_next_proto_neg &&
-- s->s3->tmp.finish_md_len == 0)
-+ s->s3->tmp.finish_md_len == 0 &&
-+ s->s3->alpn_selected == NULL)
- {
- /* We shouldn't accept this extension on a
- * renegotiation.
-@@ -1444,6 +1548,16 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
- else if (type == TLSEXT_TYPE_channel_id && s->tlsext_channel_id_enabled)
- s->s3->tlsext_channel_id_valid = 1;
-
-+ else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
-+ s->ctx->alpn_select_cb &&
-+ s->s3->tmp.finish_md_len == 0)
-+ {
-+ if (tls1_alpn_handle_client_hello(s, data, size, al) != 0)
-+ return 0;
-+ /* ALPN takes precedence over NPN. */
-+ s->s3->next_proto_neg_seen = 0;
-+ }
-+
- /* session ticket processed earlier */
- #ifndef OPENSSL_NO_SRTP
- else if (type == TLSEXT_TYPE_use_srtp)
-@@ -1508,6 +1622,12 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
- s->s3->next_proto_neg_seen = 0;
- #endif
-
-+ if (s->s3->alpn_selected)
-+ {
-+ OPENSSL_free(s->s3->alpn_selected);
-+ s->s3->alpn_selected = NULL;
-+ }
-+
- #ifndef OPENSSL_NO_HEARTBEATS
- s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
- SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
-@@ -1677,6 +1797,51 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
- else if (type == TLSEXT_TYPE_channel_id)
- s->s3->tlsext_channel_id_valid = 1;
-
-+ else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation)
-+ {
-+ unsigned len;
-+
-+ /* We must have requested it. */
-+ if (s->alpn_client_proto_list == NULL)
-+ {
-+ *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-+ return 0;
-+ }
-+ if (size < 4)
-+ {
-+ *al = TLS1_AD_DECODE_ERROR;
-+ return 0;
-+ }
-+ /* The extension data consists of:
-+ * uint16 list_length
-+ * uint8 proto_length;
-+ * uint8 proto[proto_length]; */
-+ len = data[0];
-+ len <<= 8;
-+ len |= data[1];
-+ if (len != (unsigned) size - 2)
-+ {
-+ *al = TLS1_AD_DECODE_ERROR;
-+ return 0;
-+ }
-+ len = data[2];
-+ if (len != (unsigned) size - 3)
-+ {
-+ *al = TLS1_AD_DECODE_ERROR;
-+ return 0;
-+ }
-+ if (s->s3->alpn_selected)
-+ OPENSSL_free(s->s3->alpn_selected);
-+ s->s3->alpn_selected = OPENSSL_malloc(len);
-+ if (!s->s3->alpn_selected)
-+ {
-+ *al = TLS1_AD_INTERNAL_ERROR;
-+ return 0;
-+ }
-+ memcpy(s->s3->alpn_selected, data + 3, len);
-+ s->s3->alpn_selected_len = len;
-+ }
-+
- else if (type == TLSEXT_TYPE_renegotiate)
- {
- if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
-diff --git a/ssl/tls1.h b/ssl/tls1.h
-index 8fc1ff4..c6670f4 100644
---- a/ssl/tls1.h
-+++ b/ssl/tls1.h
-@@ -230,6 +230,9 @@ extern "C" {
- /* ExtensionType value from RFC5620 */
- #define TLSEXT_TYPE_heartbeat 15
-
-+/* ExtensionType value from draft-ietf-tls-applayerprotoneg-00 */
-+#define TLSEXT_TYPE_application_layer_protocol_negotiation 16
-+
- /* ExtensionType value from RFC4507 */
- #define TLSEXT_TYPE_session_ticket 35
-
---
-1.8.2.1
-