diff options
author | jsing <> | 2014-12-10 14:58:56 +0000 |
---|---|---|
committer | jsing <> | 2014-12-10 14:58:56 +0000 |
commit | 73d0add4b5d2e01d460eb9eaa91dd531da22e21c (patch) | |
tree | e9391008296b8ff8be480e9f3e9eb1be0aab121a /src | |
parent | beadb77d202842e04b02ab287d37d0397108d0a3 (diff) | |
download | openbsd-73d0add4b5d2e01d460eb9eaa91dd531da22e21c.tar.gz openbsd-73d0add4b5d2e01d460eb9eaa91dd531da22e21c.tar.bz2 openbsd-73d0add4b5d2e01d460eb9eaa91dd531da22e21c.zip |
Add support for ALPN.
Based on OpenSSL and BoringSSL.
ok bcook@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/s3_lib.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_lib.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/ssl.h | 41 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/ssl3.h | 16 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/ssl_lib.c | 86 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/t1_lib.c | 155 | ||||
-rw-r--r-- | src/lib/libssl/ssl.h | 41 | ||||
-rw-r--r-- | src/lib/libssl/ssl3.h | 16 | ||||
-rw-r--r-- | src/lib/libssl/ssl_lib.c | 86 | ||||
-rw-r--r-- | src/lib/libssl/t1_lib.c | 155 |
10 files changed, 594 insertions, 16 deletions
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c index f2d2cb040d..9897fba6c5 100644 --- a/src/lib/libssl/s3_lib.c +++ b/src/lib/libssl/s3_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s3_lib.c,v 1.85 2014/11/18 05:33:43 miod Exp $ */ | 1 | /* $OpenBSD: s3_lib.c,v 1.86 2014/12/10 14:58:56 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1905,6 +1905,8 @@ ssl3_free(SSL *s) | |||
1905 | sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); | 1905 | sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); |
1906 | BIO_free(s->s3->handshake_buffer); | 1906 | BIO_free(s->s3->handshake_buffer); |
1907 | ssl3_free_digest_list(s); | 1907 | ssl3_free_digest_list(s); |
1908 | free(s->s3->alpn_selected); | ||
1909 | |||
1908 | OPENSSL_cleanse(s->s3, sizeof *s->s3); | 1910 | OPENSSL_cleanse(s->s3, sizeof *s->s3); |
1909 | free(s->s3); | 1911 | free(s->s3); |
1910 | s->s3 = NULL; | 1912 | s->s3 = NULL; |
@@ -1939,6 +1941,9 @@ ssl3_clear(SSL *s) | |||
1939 | 1941 | ||
1940 | ssl3_free_digest_list(s); | 1942 | ssl3_free_digest_list(s); |
1941 | 1943 | ||
1944 | free(s->s3->alpn_selected); | ||
1945 | s->s3->alpn_selected = NULL; | ||
1946 | |||
1942 | memset(s->s3, 0, sizeof *s->s3); | 1947 | memset(s->s3, 0, sizeof *s->s3); |
1943 | s->s3->rbuf.buf = rp; | 1948 | s->s3->rbuf.buf = rp; |
1944 | s->s3->wbuf.buf = wp; | 1949 | s->s3->wbuf.buf = wp; |
diff --git a/src/lib/libssl/src/ssl/s3_lib.c b/src/lib/libssl/src/ssl/s3_lib.c index f2d2cb040d..9897fba6c5 100644 --- a/src/lib/libssl/src/ssl/s3_lib.c +++ b/src/lib/libssl/src/ssl/s3_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s3_lib.c,v 1.85 2014/11/18 05:33:43 miod Exp $ */ | 1 | /* $OpenBSD: s3_lib.c,v 1.86 2014/12/10 14:58:56 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1905,6 +1905,8 @@ ssl3_free(SSL *s) | |||
1905 | sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); | 1905 | sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); |
1906 | BIO_free(s->s3->handshake_buffer); | 1906 | BIO_free(s->s3->handshake_buffer); |
1907 | ssl3_free_digest_list(s); | 1907 | ssl3_free_digest_list(s); |
1908 | free(s->s3->alpn_selected); | ||
1909 | |||
1908 | OPENSSL_cleanse(s->s3, sizeof *s->s3); | 1910 | OPENSSL_cleanse(s->s3, sizeof *s->s3); |
1909 | free(s->s3); | 1911 | free(s->s3); |
1910 | s->s3 = NULL; | 1912 | s->s3 = NULL; |
@@ -1939,6 +1941,9 @@ ssl3_clear(SSL *s) | |||
1939 | 1941 | ||
1940 | ssl3_free_digest_list(s); | 1942 | ssl3_free_digest_list(s); |
1941 | 1943 | ||
1944 | free(s->s3->alpn_selected); | ||
1945 | s->s3->alpn_selected = NULL; | ||
1946 | |||
1942 | memset(s->s3, 0, sizeof *s->s3); | 1947 | memset(s->s3, 0, sizeof *s->s3); |
1943 | s->s3->rbuf.buf = rp; | 1948 | s->s3->rbuf.buf = rp; |
1944 | s->s3->wbuf.buf = wp; | 1949 | s->s3->wbuf.buf = wp; |
diff --git a/src/lib/libssl/src/ssl/ssl.h b/src/lib/libssl/src/ssl/ssl.h index e8388923a4..0059da6791 100644 --- a/src/lib/libssl/src/ssl/ssl.h +++ b/src/lib/libssl/src/ssl/ssl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl.h,v 1.74 2014/12/10 14:51:00 bcook Exp $ */ | 1 | /* $OpenBSD: ssl.h,v 1.75 2014/12/10 14:58:56 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -861,9 +861,33 @@ struct ssl_ctx_st { | |||
861 | unsigned int inlen, void *arg); | 861 | unsigned int inlen, void *arg); |
862 | void *next_proto_select_cb_arg; | 862 | void *next_proto_select_cb_arg; |
863 | # endif | 863 | # endif |
864 | |||
865 | /* | ||
866 | * ALPN information | ||
867 | * (we are in the process of transitioning from NPN to ALPN). | ||
868 | */ | ||
869 | |||
870 | /* | ||
871 | * Server callback function that allows the server to select the | ||
872 | * protocol for the connection. | ||
873 | * out: on successful return, this must point to the raw protocol | ||
874 | * name (without the length prefix). | ||
875 | * outlen: on successful return, this contains the length of out. | ||
876 | * in: points to the client's list of supported protocols in | ||
877 | * wire-format. | ||
878 | * inlen: the length of in. | ||
879 | */ | ||
880 | int (*alpn_select_cb)(SSL *s, const unsigned char **out, | ||
881 | unsigned char *outlen, const unsigned char *in, unsigned int inlen, | ||
882 | void *arg); | ||
883 | void *alpn_select_cb_arg; | ||
884 | |||
885 | /* Client list of supported protocols in wire format. */ | ||
886 | unsigned char *alpn_client_proto_list; | ||
887 | unsigned int alpn_client_proto_list_len; | ||
888 | |||
864 | /* SRTP profiles we are willing to do from RFC 5764 */ | 889 | /* SRTP profiles we are willing to do from RFC 5764 */ |
865 | STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; | 890 | STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; |
866 | |||
867 | }; | 891 | }; |
868 | 892 | ||
869 | #endif | 893 | #endif |
@@ -954,6 +978,15 @@ void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, | |||
954 | #define OPENSSL_NPN_NO_OVERLAP 2 | 978 | #define OPENSSL_NPN_NO_OVERLAP 2 |
955 | #endif | 979 | #endif |
956 | 980 | ||
981 | int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, | ||
982 | unsigned int protos_len); | ||
983 | int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, | ||
984 | unsigned int protos_len); | ||
985 | void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, | ||
986 | int (*cb)(SSL *ssl, const unsigned char **out, unsigned char *outlen, | ||
987 | const unsigned char *in, unsigned int inlen, void *arg), void *arg); | ||
988 | void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, | ||
989 | unsigned int *len); | ||
957 | 990 | ||
958 | #define SSL_NOTHING 1 | 991 | #define SSL_NOTHING 1 |
959 | #define SSL_WRITING 2 | 992 | #define SSL_WRITING 2 |
@@ -1187,6 +1220,10 @@ struct ssl_st { | |||
1187 | unsigned int tlsext_hb_pending; /* Indicates if a HeartbeatRequest is in flight */ | 1220 | unsigned int tlsext_hb_pending; /* Indicates if a HeartbeatRequest is in flight */ |
1188 | unsigned int tlsext_hb_seq; /* HeartbeatRequest sequence number */ | 1221 | unsigned int tlsext_hb_seq; /* HeartbeatRequest sequence number */ |
1189 | 1222 | ||
1223 | /* Client list of supported protocols in wire format. */ | ||
1224 | unsigned char *alpn_client_proto_list; | ||
1225 | unsigned int alpn_client_proto_list_len; | ||
1226 | |||
1190 | int renegotiate;/* 1 if we are renegotiating. | 1227 | int renegotiate;/* 1 if we are renegotiating. |
1191 | * 2 if we are a server and are inside a handshake | 1228 | * 2 if we are a server and are inside a handshake |
1192 | * (i.e. not just sending a HelloRequest) */ | 1229 | * (i.e. not just sending a HelloRequest) */ |
diff --git a/src/lib/libssl/src/ssl/ssl3.h b/src/lib/libssl/src/ssl/ssl3.h index 5b9e31754b..2055f0f834 100644 --- a/src/lib/libssl/src/ssl/ssl3.h +++ b/src/lib/libssl/src/ssl/ssl3.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl3.h,v 1.29 2014/11/18 05:33:43 miod Exp $ */ | 1 | /* $OpenBSD: ssl3.h,v 1.30 2014/12/10 14:58:56 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -497,6 +497,20 @@ typedef struct ssl3_state_st { | |||
497 | int next_proto_neg_seen; | 497 | int next_proto_neg_seen; |
498 | #endif | 498 | #endif |
499 | 499 | ||
500 | /* | ||
501 | * ALPN information | ||
502 | * (we are in the process of transitioning from NPN to ALPN). | ||
503 | */ | ||
504 | |||
505 | /* | ||
506 | * In a server these point to the selected ALPN protocol after the | ||
507 | * ClientHello has been processed. In a client these contain the | ||
508 | * protocol that the server selected once the ServerHello has been | ||
509 | * processed. | ||
510 | */ | ||
511 | unsigned char *alpn_selected; | ||
512 | unsigned int alpn_selected_len; | ||
513 | |||
500 | /* This is set to true if we believe that this is a version of Safari | 514 | /* This is set to true if we believe that this is a version of Safari |
501 | * running on OS X 10.6 or newer. We wish to know this because Safari | 515 | * running on OS X 10.6 or newer. We wish to know this because Safari |
502 | * on 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. */ | 516 | * on 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. */ |
diff --git a/src/lib/libssl/src/ssl/ssl_lib.c b/src/lib/libssl/src/ssl/ssl_lib.c index bdd47ff87f..a03ee735ad 100644 --- a/src/lib/libssl/src/ssl/ssl_lib.c +++ b/src/lib/libssl/src/ssl/ssl_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_lib.c,v 1.90 2014/11/16 14:12:47 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.91 2014/12/10 14:58:56 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -337,6 +337,18 @@ SSL_new(SSL_CTX *ctx) | |||
337 | s->next_proto_negotiated = NULL; | 337 | s->next_proto_negotiated = NULL; |
338 | # endif | 338 | # endif |
339 | 339 | ||
340 | if (s->ctx->alpn_client_proto_list != NULL) { | ||
341 | s->alpn_client_proto_list = | ||
342 | malloc(s->ctx->alpn_client_proto_list_len); | ||
343 | if (s->alpn_client_proto_list == NULL) | ||
344 | goto err; | ||
345 | memcpy(s->alpn_client_proto_list, | ||
346 | s->ctx->alpn_client_proto_list, | ||
347 | s->ctx->alpn_client_proto_list_len); | ||
348 | s->alpn_client_proto_list_len = | ||
349 | s->ctx->alpn_client_proto_list_len; | ||
350 | } | ||
351 | |||
340 | s->verify_result = X509_V_OK; | 352 | s->verify_result = X509_V_OK; |
341 | 353 | ||
342 | s->method = ctx->method; | 354 | s->method = ctx->method; |
@@ -551,6 +563,7 @@ SSL_free(SSL *s) | |||
551 | #ifndef OPENSSL_NO_NEXTPROTONEG | 563 | #ifndef OPENSSL_NO_NEXTPROTONEG |
552 | free(s->next_proto_negotiated); | 564 | free(s->next_proto_negotiated); |
553 | #endif | 565 | #endif |
566 | free(s->alpn_client_proto_list); | ||
554 | 567 | ||
555 | #ifndef OPENSSL_NO_SRTP | 568 | #ifndef OPENSSL_NO_SRTP |
556 | if (s->srtp_profiles) | 569 | if (s->srtp_profiles) |
@@ -1629,6 +1642,75 @@ SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, | |||
1629 | } | 1642 | } |
1630 | # endif | 1643 | # endif |
1631 | 1644 | ||
1645 | /* | ||
1646 | * SSL_CTX_set_alpn_protos sets the ALPN protocol list to the specified | ||
1647 | * protocols, which must be in wire-format (i.e. a series of non-empty, | ||
1648 | * 8-bit length-prefixed strings). Returns 0 on success. | ||
1649 | */ | ||
1650 | int | ||
1651 | SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, | ||
1652 | unsigned int protos_len) | ||
1653 | { | ||
1654 | free(ctx->alpn_client_proto_list); | ||
1655 | if ((ctx->alpn_client_proto_list = malloc(protos_len)) == NULL) | ||
1656 | return (1); | ||
1657 | memcpy(ctx->alpn_client_proto_list, protos, protos_len); | ||
1658 | ctx->alpn_client_proto_list_len = protos_len; | ||
1659 | |||
1660 | return (0); | ||
1661 | } | ||
1662 | |||
1663 | /* | ||
1664 | * SSL_set_alpn_protos sets the ALPN protocol list to the specified | ||
1665 | * protocols, which must be in wire-format (i.e. a series of non-empty, | ||
1666 | * 8-bit length-prefixed strings). Returns 0 on success. | ||
1667 | */ | ||
1668 | int | ||
1669 | SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos, | ||
1670 | unsigned int protos_len) | ||
1671 | { | ||
1672 | free(ssl->alpn_client_proto_list); | ||
1673 | if ((ssl->alpn_client_proto_list = malloc(protos_len)) == NULL) | ||
1674 | return (1); | ||
1675 | memcpy(ssl->alpn_client_proto_list, protos, protos_len); | ||
1676 | ssl->alpn_client_proto_list_len = protos_len; | ||
1677 | |||
1678 | return (0); | ||
1679 | } | ||
1680 | |||
1681 | /* | ||
1682 | * SSL_CTX_set_alpn_select_cb sets a callback function that is called during | ||
1683 | * ClientHello processing in order to select an ALPN protocol from the | ||
1684 | * client's list of offered protocols. | ||
1685 | */ | ||
1686 | void | ||
1687 | SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx, | ||
1688 | int (*cb) (SSL *ssl, const unsigned char **out, unsigned char *outlen, | ||
1689 | const unsigned char *in, unsigned int inlen, void *arg), void *arg) | ||
1690 | { | ||
1691 | ctx->alpn_select_cb = cb; | ||
1692 | ctx->alpn_select_cb_arg = arg; | ||
1693 | } | ||
1694 | |||
1695 | /* | ||
1696 | * SSL_get0_alpn_selected gets the selected ALPN protocol (if any). On return | ||
1697 | * it sets data to point to len bytes of protocol name (not including the | ||
1698 | * leading length-prefix byte). If the server didn't respond with* a negotiated | ||
1699 | * protocol then len will be zero. | ||
1700 | */ | ||
1701 | void | ||
1702 | SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, | ||
1703 | unsigned *len) | ||
1704 | { | ||
1705 | *data = NULL; | ||
1706 | *len = 0; | ||
1707 | |||
1708 | if (ssl->s3 != NULL) { | ||
1709 | *data = ssl->s3->alpn_selected; | ||
1710 | *len = ssl->s3->alpn_selected_len; | ||
1711 | } | ||
1712 | } | ||
1713 | |||
1632 | int | 1714 | int |
1633 | SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, | 1715 | SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, |
1634 | const char *label, size_t llen, const unsigned char *p, size_t plen, | 1716 | const char *label, size_t llen, const unsigned char *p, size_t plen, |
@@ -1894,6 +1976,8 @@ SSL_CTX_free(SSL_CTX *a) | |||
1894 | ENGINE_finish(a->client_cert_engine); | 1976 | ENGINE_finish(a->client_cert_engine); |
1895 | #endif | 1977 | #endif |
1896 | 1978 | ||
1979 | free(a->alpn_client_proto_list); | ||
1980 | |||
1897 | free(a); | 1981 | free(a); |
1898 | } | 1982 | } |
1899 | 1983 | ||
diff --git a/src/lib/libssl/src/ssl/t1_lib.c b/src/lib/libssl/src/ssl/t1_lib.c index 8a7553e3e7..5df45ab359 100644 --- a/src/lib/libssl/src/ssl/t1_lib.c +++ b/src/lib/libssl/src/ssl/t1_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: t1_lib.c,v 1.71 2014/12/06 13:51:06 jsing Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.72 2014/12/10 14:58:56 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -878,6 +878,18 @@ skip_ext: | |||
878 | } | 878 | } |
879 | #endif | 879 | #endif |
880 | 880 | ||
881 | if (s->alpn_client_proto_list != NULL && | ||
882 | s->s3->tmp.finish_md_len == 0) { | ||
883 | if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len) | ||
884 | return (NULL); | ||
885 | s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); | ||
886 | s2n(2 + s->alpn_client_proto_list_len, ret); | ||
887 | s2n(s->alpn_client_proto_list_len, ret); | ||
888 | memcpy(ret, s->alpn_client_proto_list, | ||
889 | s->alpn_client_proto_list_len); | ||
890 | ret += s->alpn_client_proto_list_len; | ||
891 | } | ||
892 | |||
881 | #ifndef OPENSSL_NO_SRTP | 893 | #ifndef OPENSSL_NO_SRTP |
882 | if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { | 894 | if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { |
883 | int el; | 895 | int el; |
@@ -1107,6 +1119,20 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
1107 | } | 1119 | } |
1108 | #endif | 1120 | #endif |
1109 | 1121 | ||
1122 | if (s->s3->alpn_selected != NULL) { | ||
1123 | const unsigned char *selected = s->s3->alpn_selected; | ||
1124 | unsigned int len = s->s3->alpn_selected_len; | ||
1125 | |||
1126 | if ((long)(limit - ret - 4 - 2 - 1 - len) < 0) | ||
1127 | return (NULL); | ||
1128 | s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); | ||
1129 | s2n(3 + len, ret); | ||
1130 | s2n(1 + len, ret); | ||
1131 | *ret++ = len; | ||
1132 | memcpy(ret, selected, len); | ||
1133 | ret += len; | ||
1134 | } | ||
1135 | |||
1110 | if ((extdatalen = ret - p - 2) == 0) | 1136 | if ((extdatalen = ret - p - 2) == 0) |
1111 | return p; | 1137 | return p; |
1112 | 1138 | ||
@@ -1114,6 +1140,76 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
1114 | return ret; | 1140 | return ret; |
1115 | } | 1141 | } |
1116 | 1142 | ||
1143 | /* | ||
1144 | * tls1_alpn_handle_client_hello is called to process the ALPN extension in a | ||
1145 | * ClientHello. | ||
1146 | * data: the contents of the extension, not including the type and length. | ||
1147 | * data_len: the number of bytes in data. | ||
1148 | * al: a pointer to the alert value to send in the event of a non-zero | ||
1149 | * return. | ||
1150 | * returns: 1 on success. | ||
1151 | */ | ||
1152 | static int | ||
1153 | tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data, | ||
1154 | unsigned int data_len, int *al) | ||
1155 | { | ||
1156 | const unsigned char *selected; | ||
1157 | unsigned char selected_len; | ||
1158 | unsigned int proto_len; | ||
1159 | unsigned int i; | ||
1160 | int r; | ||
1161 | |||
1162 | if (s->ctx->alpn_select_cb == NULL) | ||
1163 | return (1); | ||
1164 | |||
1165 | if (data_len < 2) | ||
1166 | goto parse_error; | ||
1167 | |||
1168 | /* | ||
1169 | * data should contain a uint16 length followed by a series of 8-bit, | ||
1170 | * length-prefixed strings. | ||
1171 | */ | ||
1172 | i = ((unsigned int)data[0]) << 8 | ((unsigned int)data[1]); | ||
1173 | data_len -= 2; | ||
1174 | data += 2; | ||
1175 | if (data_len != i) | ||
1176 | goto parse_error; | ||
1177 | |||
1178 | if (data_len < 2) | ||
1179 | goto parse_error; | ||
1180 | |||
1181 | for (i = 0; i < data_len; ) { | ||
1182 | proto_len = data[i]; | ||
1183 | i++; | ||
1184 | |||
1185 | if (proto_len == 0) | ||
1186 | goto parse_error; | ||
1187 | |||
1188 | if (i + proto_len < i || i + proto_len > data_len) | ||
1189 | goto parse_error; | ||
1190 | |||
1191 | i += proto_len; | ||
1192 | } | ||
1193 | |||
1194 | r = s->ctx->alpn_select_cb(s, &selected, &selected_len, | ||
1195 | data, data_len, s->ctx->alpn_select_cb_arg); | ||
1196 | if (r == SSL_TLSEXT_ERR_OK) { | ||
1197 | free(s->s3->alpn_selected); | ||
1198 | if ((s->s3->alpn_selected = malloc(selected_len)) == NULL) { | ||
1199 | *al = SSL_AD_INTERNAL_ERROR; | ||
1200 | return (-1); | ||
1201 | } | ||
1202 | memcpy(s->s3->alpn_selected, selected, selected_len); | ||
1203 | s->s3->alpn_selected_len = selected_len; | ||
1204 | } | ||
1205 | |||
1206 | return (1); | ||
1207 | |||
1208 | parse_error: | ||
1209 | *al = SSL_AD_DECODE_ERROR; | ||
1210 | return (0); | ||
1211 | } | ||
1212 | |||
1117 | /* ssl_check_for_safari attempts to fingerprint Safari using OS X | 1213 | /* ssl_check_for_safari attempts to fingerprint Safari using OS X |
1118 | * SecureTransport using the TLS extension block in |d|, of length |n|. | 1214 | * SecureTransport using the TLS extension block in |d|, of length |n|. |
1119 | * Safari, since 10.6, sends exactly these extensions, in this order: | 1215 | * Safari, since 10.6, sends exactly these extensions, in this order: |
@@ -1211,6 +1307,8 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1211 | #ifndef OPENSSL_NO_NEXTPROTONEG | 1307 | #ifndef OPENSSL_NO_NEXTPROTONEG |
1212 | s->s3->next_proto_neg_seen = 0; | 1308 | s->s3->next_proto_neg_seen = 0; |
1213 | #endif | 1309 | #endif |
1310 | free(s->s3->alpn_selected); | ||
1311 | s->s3->alpn_selected = NULL; | ||
1214 | 1312 | ||
1215 | if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) | 1313 | if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) |
1216 | ssl_check_for_safari(s, data, d, n); | 1314 | ssl_check_for_safari(s, data, d, n); |
@@ -1520,7 +1618,8 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1520 | } | 1618 | } |
1521 | #ifndef OPENSSL_NO_NEXTPROTONEG | 1619 | #ifndef OPENSSL_NO_NEXTPROTONEG |
1522 | else if (type == TLSEXT_TYPE_next_proto_neg && | 1620 | else if (type == TLSEXT_TYPE_next_proto_neg && |
1523 | s->s3->tmp.finish_md_len == 0) { | 1621 | s->s3->tmp.finish_md_len == 0 && |
1622 | s->s3->alpn_selected == NULL) { | ||
1524 | /* We shouldn't accept this extension on a | 1623 | /* We shouldn't accept this extension on a |
1525 | * renegotiation. | 1624 | * renegotiation. |
1526 | * | 1625 | * |
@@ -1539,6 +1638,16 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1539 | s->s3->next_proto_neg_seen = 1; | 1638 | s->s3->next_proto_neg_seen = 1; |
1540 | } | 1639 | } |
1541 | #endif | 1640 | #endif |
1641 | else if (type == | ||
1642 | TLSEXT_TYPE_application_layer_protocol_negotiation && | ||
1643 | s->ctx->alpn_select_cb != NULL && | ||
1644 | s->s3->tmp.finish_md_len == 0) { | ||
1645 | if (tls1_alpn_handle_client_hello(s, data, | ||
1646 | size, al) != 1) | ||
1647 | return (0); | ||
1648 | /* ALPN takes precedence over NPN. */ | ||
1649 | s->s3->next_proto_neg_seen = 0; | ||
1650 | } | ||
1542 | 1651 | ||
1543 | /* session ticket processed earlier */ | 1652 | /* session ticket processed earlier */ |
1544 | #ifndef OPENSSL_NO_SRTP | 1653 | #ifndef OPENSSL_NO_SRTP |
@@ -1601,6 +1710,8 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1601 | #ifndef OPENSSL_NO_NEXTPROTONEG | 1710 | #ifndef OPENSSL_NO_NEXTPROTONEG |
1602 | s->s3->next_proto_neg_seen = 0; | 1711 | s->s3->next_proto_neg_seen = 0; |
1603 | #endif | 1712 | #endif |
1713 | free(s->s3->alpn_selected); | ||
1714 | s->s3->alpn_selected = NULL; | ||
1604 | 1715 | ||
1605 | if (data >= (d + n - 2)) | 1716 | if (data >= (d + n - 2)) |
1606 | goto ri_check; | 1717 | goto ri_check; |
@@ -1716,7 +1827,45 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1716 | s->s3->next_proto_neg_seen = 1; | 1827 | s->s3->next_proto_neg_seen = 1; |
1717 | } | 1828 | } |
1718 | #endif | 1829 | #endif |
1719 | else if (type == TLSEXT_TYPE_renegotiate) { | 1830 | else if (type == |
1831 | TLSEXT_TYPE_application_layer_protocol_negotiation) { | ||
1832 | unsigned int len; | ||
1833 | |||
1834 | /* We must have requested it. */ | ||
1835 | if (s->alpn_client_proto_list == NULL) { | ||
1836 | *al = TLS1_AD_UNSUPPORTED_EXTENSION; | ||
1837 | return 0; | ||
1838 | } | ||
1839 | if (size < 4) { | ||
1840 | *al = TLS1_AD_DECODE_ERROR; | ||
1841 | return (0); | ||
1842 | } | ||
1843 | |||
1844 | /* The extension data consists of: | ||
1845 | * uint16 list_length | ||
1846 | * uint8 proto_length; | ||
1847 | * uint8 proto[proto_length]; */ | ||
1848 | len = ((unsigned int)data[0]) << 8 | | ||
1849 | ((unsigned int)data[1]); | ||
1850 | if (len != (unsigned int)size - 2) { | ||
1851 | *al = TLS1_AD_DECODE_ERROR; | ||
1852 | return (0); | ||
1853 | } | ||
1854 | len = data[2]; | ||
1855 | if (len != (unsigned int)size - 3) { | ||
1856 | *al = TLS1_AD_DECODE_ERROR; | ||
1857 | return (0); | ||
1858 | } | ||
1859 | free(s->s3->alpn_selected); | ||
1860 | s->s3->alpn_selected = malloc(len); | ||
1861 | if (s->s3->alpn_selected == NULL) { | ||
1862 | *al = TLS1_AD_INTERNAL_ERROR; | ||
1863 | return (0); | ||
1864 | } | ||
1865 | memcpy(s->s3->alpn_selected, data + 3, len); | ||
1866 | s->s3->alpn_selected_len = len; | ||
1867 | |||
1868 | } else if (type == TLSEXT_TYPE_renegotiate) { | ||
1720 | if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) | 1869 | if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) |
1721 | return 0; | 1870 | return 0; |
1722 | renegotiate_seen = 1; | 1871 | renegotiate_seen = 1; |
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h index e8388923a4..0059da6791 100644 --- a/src/lib/libssl/ssl.h +++ b/src/lib/libssl/ssl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl.h,v 1.74 2014/12/10 14:51:00 bcook Exp $ */ | 1 | /* $OpenBSD: ssl.h,v 1.75 2014/12/10 14:58:56 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -861,9 +861,33 @@ struct ssl_ctx_st { | |||
861 | unsigned int inlen, void *arg); | 861 | unsigned int inlen, void *arg); |
862 | void *next_proto_select_cb_arg; | 862 | void *next_proto_select_cb_arg; |
863 | # endif | 863 | # endif |
864 | |||
865 | /* | ||
866 | * ALPN information | ||
867 | * (we are in the process of transitioning from NPN to ALPN). | ||
868 | */ | ||
869 | |||
870 | /* | ||
871 | * Server callback function that allows the server to select the | ||
872 | * protocol for the connection. | ||
873 | * out: on successful return, this must point to the raw protocol | ||
874 | * name (without the length prefix). | ||
875 | * outlen: on successful return, this contains the length of out. | ||
876 | * in: points to the client's list of supported protocols in | ||
877 | * wire-format. | ||
878 | * inlen: the length of in. | ||
879 | */ | ||
880 | int (*alpn_select_cb)(SSL *s, const unsigned char **out, | ||
881 | unsigned char *outlen, const unsigned char *in, unsigned int inlen, | ||
882 | void *arg); | ||
883 | void *alpn_select_cb_arg; | ||
884 | |||
885 | /* Client list of supported protocols in wire format. */ | ||
886 | unsigned char *alpn_client_proto_list; | ||
887 | unsigned int alpn_client_proto_list_len; | ||
888 | |||
864 | /* SRTP profiles we are willing to do from RFC 5764 */ | 889 | /* SRTP profiles we are willing to do from RFC 5764 */ |
865 | STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; | 890 | STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; |
866 | |||
867 | }; | 891 | }; |
868 | 892 | ||
869 | #endif | 893 | #endif |
@@ -954,6 +978,15 @@ void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, | |||
954 | #define OPENSSL_NPN_NO_OVERLAP 2 | 978 | #define OPENSSL_NPN_NO_OVERLAP 2 |
955 | #endif | 979 | #endif |
956 | 980 | ||
981 | int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, | ||
982 | unsigned int protos_len); | ||
983 | int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, | ||
984 | unsigned int protos_len); | ||
985 | void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, | ||
986 | int (*cb)(SSL *ssl, const unsigned char **out, unsigned char *outlen, | ||
987 | const unsigned char *in, unsigned int inlen, void *arg), void *arg); | ||
988 | void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, | ||
989 | unsigned int *len); | ||
957 | 990 | ||
958 | #define SSL_NOTHING 1 | 991 | #define SSL_NOTHING 1 |
959 | #define SSL_WRITING 2 | 992 | #define SSL_WRITING 2 |
@@ -1187,6 +1220,10 @@ struct ssl_st { | |||
1187 | unsigned int tlsext_hb_pending; /* Indicates if a HeartbeatRequest is in flight */ | 1220 | unsigned int tlsext_hb_pending; /* Indicates if a HeartbeatRequest is in flight */ |
1188 | unsigned int tlsext_hb_seq; /* HeartbeatRequest sequence number */ | 1221 | unsigned int tlsext_hb_seq; /* HeartbeatRequest sequence number */ |
1189 | 1222 | ||
1223 | /* Client list of supported protocols in wire format. */ | ||
1224 | unsigned char *alpn_client_proto_list; | ||
1225 | unsigned int alpn_client_proto_list_len; | ||
1226 | |||
1190 | int renegotiate;/* 1 if we are renegotiating. | 1227 | int renegotiate;/* 1 if we are renegotiating. |
1191 | * 2 if we are a server and are inside a handshake | 1228 | * 2 if we are a server and are inside a handshake |
1192 | * (i.e. not just sending a HelloRequest) */ | 1229 | * (i.e. not just sending a HelloRequest) */ |
diff --git a/src/lib/libssl/ssl3.h b/src/lib/libssl/ssl3.h index 5b9e31754b..2055f0f834 100644 --- a/src/lib/libssl/ssl3.h +++ b/src/lib/libssl/ssl3.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl3.h,v 1.29 2014/11/18 05:33:43 miod Exp $ */ | 1 | /* $OpenBSD: ssl3.h,v 1.30 2014/12/10 14:58:56 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -497,6 +497,20 @@ typedef struct ssl3_state_st { | |||
497 | int next_proto_neg_seen; | 497 | int next_proto_neg_seen; |
498 | #endif | 498 | #endif |
499 | 499 | ||
500 | /* | ||
501 | * ALPN information | ||
502 | * (we are in the process of transitioning from NPN to ALPN). | ||
503 | */ | ||
504 | |||
505 | /* | ||
506 | * In a server these point to the selected ALPN protocol after the | ||
507 | * ClientHello has been processed. In a client these contain the | ||
508 | * protocol that the server selected once the ServerHello has been | ||
509 | * processed. | ||
510 | */ | ||
511 | unsigned char *alpn_selected; | ||
512 | unsigned int alpn_selected_len; | ||
513 | |||
500 | /* This is set to true if we believe that this is a version of Safari | 514 | /* This is set to true if we believe that this is a version of Safari |
501 | * running on OS X 10.6 or newer. We wish to know this because Safari | 515 | * running on OS X 10.6 or newer. We wish to know this because Safari |
502 | * on 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. */ | 516 | * on 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. */ |
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index bdd47ff87f..a03ee735ad 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_lib.c,v 1.90 2014/11/16 14:12:47 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.91 2014/12/10 14:58:56 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -337,6 +337,18 @@ SSL_new(SSL_CTX *ctx) | |||
337 | s->next_proto_negotiated = NULL; | 337 | s->next_proto_negotiated = NULL; |
338 | # endif | 338 | # endif |
339 | 339 | ||
340 | if (s->ctx->alpn_client_proto_list != NULL) { | ||
341 | s->alpn_client_proto_list = | ||
342 | malloc(s->ctx->alpn_client_proto_list_len); | ||
343 | if (s->alpn_client_proto_list == NULL) | ||
344 | goto err; | ||
345 | memcpy(s->alpn_client_proto_list, | ||
346 | s->ctx->alpn_client_proto_list, | ||
347 | s->ctx->alpn_client_proto_list_len); | ||
348 | s->alpn_client_proto_list_len = | ||
349 | s->ctx->alpn_client_proto_list_len; | ||
350 | } | ||
351 | |||
340 | s->verify_result = X509_V_OK; | 352 | s->verify_result = X509_V_OK; |
341 | 353 | ||
342 | s->method = ctx->method; | 354 | s->method = ctx->method; |
@@ -551,6 +563,7 @@ SSL_free(SSL *s) | |||
551 | #ifndef OPENSSL_NO_NEXTPROTONEG | 563 | #ifndef OPENSSL_NO_NEXTPROTONEG |
552 | free(s->next_proto_negotiated); | 564 | free(s->next_proto_negotiated); |
553 | #endif | 565 | #endif |
566 | free(s->alpn_client_proto_list); | ||
554 | 567 | ||
555 | #ifndef OPENSSL_NO_SRTP | 568 | #ifndef OPENSSL_NO_SRTP |
556 | if (s->srtp_profiles) | 569 | if (s->srtp_profiles) |
@@ -1629,6 +1642,75 @@ SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, | |||
1629 | } | 1642 | } |
1630 | # endif | 1643 | # endif |
1631 | 1644 | ||
1645 | /* | ||
1646 | * SSL_CTX_set_alpn_protos sets the ALPN protocol list to the specified | ||
1647 | * protocols, which must be in wire-format (i.e. a series of non-empty, | ||
1648 | * 8-bit length-prefixed strings). Returns 0 on success. | ||
1649 | */ | ||
1650 | int | ||
1651 | SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, | ||
1652 | unsigned int protos_len) | ||
1653 | { | ||
1654 | free(ctx->alpn_client_proto_list); | ||
1655 | if ((ctx->alpn_client_proto_list = malloc(protos_len)) == NULL) | ||
1656 | return (1); | ||
1657 | memcpy(ctx->alpn_client_proto_list, protos, protos_len); | ||
1658 | ctx->alpn_client_proto_list_len = protos_len; | ||
1659 | |||
1660 | return (0); | ||
1661 | } | ||
1662 | |||
1663 | /* | ||
1664 | * SSL_set_alpn_protos sets the ALPN protocol list to the specified | ||
1665 | * protocols, which must be in wire-format (i.e. a series of non-empty, | ||
1666 | * 8-bit length-prefixed strings). Returns 0 on success. | ||
1667 | */ | ||
1668 | int | ||
1669 | SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos, | ||
1670 | unsigned int protos_len) | ||
1671 | { | ||
1672 | free(ssl->alpn_client_proto_list); | ||
1673 | if ((ssl->alpn_client_proto_list = malloc(protos_len)) == NULL) | ||
1674 | return (1); | ||
1675 | memcpy(ssl->alpn_client_proto_list, protos, protos_len); | ||
1676 | ssl->alpn_client_proto_list_len = protos_len; | ||
1677 | |||
1678 | return (0); | ||
1679 | } | ||
1680 | |||
1681 | /* | ||
1682 | * SSL_CTX_set_alpn_select_cb sets a callback function that is called during | ||
1683 | * ClientHello processing in order to select an ALPN protocol from the | ||
1684 | * client's list of offered protocols. | ||
1685 | */ | ||
1686 | void | ||
1687 | SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx, | ||
1688 | int (*cb) (SSL *ssl, const unsigned char **out, unsigned char *outlen, | ||
1689 | const unsigned char *in, unsigned int inlen, void *arg), void *arg) | ||
1690 | { | ||
1691 | ctx->alpn_select_cb = cb; | ||
1692 | ctx->alpn_select_cb_arg = arg; | ||
1693 | } | ||
1694 | |||
1695 | /* | ||
1696 | * SSL_get0_alpn_selected gets the selected ALPN protocol (if any). On return | ||
1697 | * it sets data to point to len bytes of protocol name (not including the | ||
1698 | * leading length-prefix byte). If the server didn't respond with* a negotiated | ||
1699 | * protocol then len will be zero. | ||
1700 | */ | ||
1701 | void | ||
1702 | SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, | ||
1703 | unsigned *len) | ||
1704 | { | ||
1705 | *data = NULL; | ||
1706 | *len = 0; | ||
1707 | |||
1708 | if (ssl->s3 != NULL) { | ||
1709 | *data = ssl->s3->alpn_selected; | ||
1710 | *len = ssl->s3->alpn_selected_len; | ||
1711 | } | ||
1712 | } | ||
1713 | |||
1632 | int | 1714 | int |
1633 | SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, | 1715 | SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, |
1634 | const char *label, size_t llen, const unsigned char *p, size_t plen, | 1716 | const char *label, size_t llen, const unsigned char *p, size_t plen, |
@@ -1894,6 +1976,8 @@ SSL_CTX_free(SSL_CTX *a) | |||
1894 | ENGINE_finish(a->client_cert_engine); | 1976 | ENGINE_finish(a->client_cert_engine); |
1895 | #endif | 1977 | #endif |
1896 | 1978 | ||
1979 | free(a->alpn_client_proto_list); | ||
1980 | |||
1897 | free(a); | 1981 | free(a); |
1898 | } | 1982 | } |
1899 | 1983 | ||
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index 8a7553e3e7..5df45ab359 100644 --- a/src/lib/libssl/t1_lib.c +++ b/src/lib/libssl/t1_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: t1_lib.c,v 1.71 2014/12/06 13:51:06 jsing Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.72 2014/12/10 14:58:56 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -878,6 +878,18 @@ skip_ext: | |||
878 | } | 878 | } |
879 | #endif | 879 | #endif |
880 | 880 | ||
881 | if (s->alpn_client_proto_list != NULL && | ||
882 | s->s3->tmp.finish_md_len == 0) { | ||
883 | if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len) | ||
884 | return (NULL); | ||
885 | s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); | ||
886 | s2n(2 + s->alpn_client_proto_list_len, ret); | ||
887 | s2n(s->alpn_client_proto_list_len, ret); | ||
888 | memcpy(ret, s->alpn_client_proto_list, | ||
889 | s->alpn_client_proto_list_len); | ||
890 | ret += s->alpn_client_proto_list_len; | ||
891 | } | ||
892 | |||
881 | #ifndef OPENSSL_NO_SRTP | 893 | #ifndef OPENSSL_NO_SRTP |
882 | if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { | 894 | if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { |
883 | int el; | 895 | int el; |
@@ -1107,6 +1119,20 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
1107 | } | 1119 | } |
1108 | #endif | 1120 | #endif |
1109 | 1121 | ||
1122 | if (s->s3->alpn_selected != NULL) { | ||
1123 | const unsigned char *selected = s->s3->alpn_selected; | ||
1124 | unsigned int len = s->s3->alpn_selected_len; | ||
1125 | |||
1126 | if ((long)(limit - ret - 4 - 2 - 1 - len) < 0) | ||
1127 | return (NULL); | ||
1128 | s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); | ||
1129 | s2n(3 + len, ret); | ||
1130 | s2n(1 + len, ret); | ||
1131 | *ret++ = len; | ||
1132 | memcpy(ret, selected, len); | ||
1133 | ret += len; | ||
1134 | } | ||
1135 | |||
1110 | if ((extdatalen = ret - p - 2) == 0) | 1136 | if ((extdatalen = ret - p - 2) == 0) |
1111 | return p; | 1137 | return p; |
1112 | 1138 | ||
@@ -1114,6 +1140,76 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
1114 | return ret; | 1140 | return ret; |
1115 | } | 1141 | } |
1116 | 1142 | ||
1143 | /* | ||
1144 | * tls1_alpn_handle_client_hello is called to process the ALPN extension in a | ||
1145 | * ClientHello. | ||
1146 | * data: the contents of the extension, not including the type and length. | ||
1147 | * data_len: the number of bytes in data. | ||
1148 | * al: a pointer to the alert value to send in the event of a non-zero | ||
1149 | * return. | ||
1150 | * returns: 1 on success. | ||
1151 | */ | ||
1152 | static int | ||
1153 | tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data, | ||
1154 | unsigned int data_len, int *al) | ||
1155 | { | ||
1156 | const unsigned char *selected; | ||
1157 | unsigned char selected_len; | ||
1158 | unsigned int proto_len; | ||
1159 | unsigned int i; | ||
1160 | int r; | ||
1161 | |||
1162 | if (s->ctx->alpn_select_cb == NULL) | ||
1163 | return (1); | ||
1164 | |||
1165 | if (data_len < 2) | ||
1166 | goto parse_error; | ||
1167 | |||
1168 | /* | ||
1169 | * data should contain a uint16 length followed by a series of 8-bit, | ||
1170 | * length-prefixed strings. | ||
1171 | */ | ||
1172 | i = ((unsigned int)data[0]) << 8 | ((unsigned int)data[1]); | ||
1173 | data_len -= 2; | ||
1174 | data += 2; | ||
1175 | if (data_len != i) | ||
1176 | goto parse_error; | ||
1177 | |||
1178 | if (data_len < 2) | ||
1179 | goto parse_error; | ||
1180 | |||
1181 | for (i = 0; i < data_len; ) { | ||
1182 | proto_len = data[i]; | ||
1183 | i++; | ||
1184 | |||
1185 | if (proto_len == 0) | ||
1186 | goto parse_error; | ||
1187 | |||
1188 | if (i + proto_len < i || i + proto_len > data_len) | ||
1189 | goto parse_error; | ||
1190 | |||
1191 | i += proto_len; | ||
1192 | } | ||
1193 | |||
1194 | r = s->ctx->alpn_select_cb(s, &selected, &selected_len, | ||
1195 | data, data_len, s->ctx->alpn_select_cb_arg); | ||
1196 | if (r == SSL_TLSEXT_ERR_OK) { | ||
1197 | free(s->s3->alpn_selected); | ||
1198 | if ((s->s3->alpn_selected = malloc(selected_len)) == NULL) { | ||
1199 | *al = SSL_AD_INTERNAL_ERROR; | ||
1200 | return (-1); | ||
1201 | } | ||
1202 | memcpy(s->s3->alpn_selected, selected, selected_len); | ||
1203 | s->s3->alpn_selected_len = selected_len; | ||
1204 | } | ||
1205 | |||
1206 | return (1); | ||
1207 | |||
1208 | parse_error: | ||
1209 | *al = SSL_AD_DECODE_ERROR; | ||
1210 | return (0); | ||
1211 | } | ||
1212 | |||
1117 | /* ssl_check_for_safari attempts to fingerprint Safari using OS X | 1213 | /* ssl_check_for_safari attempts to fingerprint Safari using OS X |
1118 | * SecureTransport using the TLS extension block in |d|, of length |n|. | 1214 | * SecureTransport using the TLS extension block in |d|, of length |n|. |
1119 | * Safari, since 10.6, sends exactly these extensions, in this order: | 1215 | * Safari, since 10.6, sends exactly these extensions, in this order: |
@@ -1211,6 +1307,8 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1211 | #ifndef OPENSSL_NO_NEXTPROTONEG | 1307 | #ifndef OPENSSL_NO_NEXTPROTONEG |
1212 | s->s3->next_proto_neg_seen = 0; | 1308 | s->s3->next_proto_neg_seen = 0; |
1213 | #endif | 1309 | #endif |
1310 | free(s->s3->alpn_selected); | ||
1311 | s->s3->alpn_selected = NULL; | ||
1214 | 1312 | ||
1215 | if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) | 1313 | if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) |
1216 | ssl_check_for_safari(s, data, d, n); | 1314 | ssl_check_for_safari(s, data, d, n); |
@@ -1520,7 +1618,8 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1520 | } | 1618 | } |
1521 | #ifndef OPENSSL_NO_NEXTPROTONEG | 1619 | #ifndef OPENSSL_NO_NEXTPROTONEG |
1522 | else if (type == TLSEXT_TYPE_next_proto_neg && | 1620 | else if (type == TLSEXT_TYPE_next_proto_neg && |
1523 | s->s3->tmp.finish_md_len == 0) { | 1621 | s->s3->tmp.finish_md_len == 0 && |
1622 | s->s3->alpn_selected == NULL) { | ||
1524 | /* We shouldn't accept this extension on a | 1623 | /* We shouldn't accept this extension on a |
1525 | * renegotiation. | 1624 | * renegotiation. |
1526 | * | 1625 | * |
@@ -1539,6 +1638,16 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1539 | s->s3->next_proto_neg_seen = 1; | 1638 | s->s3->next_proto_neg_seen = 1; |
1540 | } | 1639 | } |
1541 | #endif | 1640 | #endif |
1641 | else if (type == | ||
1642 | TLSEXT_TYPE_application_layer_protocol_negotiation && | ||
1643 | s->ctx->alpn_select_cb != NULL && | ||
1644 | s->s3->tmp.finish_md_len == 0) { | ||
1645 | if (tls1_alpn_handle_client_hello(s, data, | ||
1646 | size, al) != 1) | ||
1647 | return (0); | ||
1648 | /* ALPN takes precedence over NPN. */ | ||
1649 | s->s3->next_proto_neg_seen = 0; | ||
1650 | } | ||
1542 | 1651 | ||
1543 | /* session ticket processed earlier */ | 1652 | /* session ticket processed earlier */ |
1544 | #ifndef OPENSSL_NO_SRTP | 1653 | #ifndef OPENSSL_NO_SRTP |
@@ -1601,6 +1710,8 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1601 | #ifndef OPENSSL_NO_NEXTPROTONEG | 1710 | #ifndef OPENSSL_NO_NEXTPROTONEG |
1602 | s->s3->next_proto_neg_seen = 0; | 1711 | s->s3->next_proto_neg_seen = 0; |
1603 | #endif | 1712 | #endif |
1713 | free(s->s3->alpn_selected); | ||
1714 | s->s3->alpn_selected = NULL; | ||
1604 | 1715 | ||
1605 | if (data >= (d + n - 2)) | 1716 | if (data >= (d + n - 2)) |
1606 | goto ri_check; | 1717 | goto ri_check; |
@@ -1716,7 +1827,45 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1716 | s->s3->next_proto_neg_seen = 1; | 1827 | s->s3->next_proto_neg_seen = 1; |
1717 | } | 1828 | } |
1718 | #endif | 1829 | #endif |
1719 | else if (type == TLSEXT_TYPE_renegotiate) { | 1830 | else if (type == |
1831 | TLSEXT_TYPE_application_layer_protocol_negotiation) { | ||
1832 | unsigned int len; | ||
1833 | |||
1834 | /* We must have requested it. */ | ||
1835 | if (s->alpn_client_proto_list == NULL) { | ||
1836 | *al = TLS1_AD_UNSUPPORTED_EXTENSION; | ||
1837 | return 0; | ||
1838 | } | ||
1839 | if (size < 4) { | ||
1840 | *al = TLS1_AD_DECODE_ERROR; | ||
1841 | return (0); | ||
1842 | } | ||
1843 | |||
1844 | /* The extension data consists of: | ||
1845 | * uint16 list_length | ||
1846 | * uint8 proto_length; | ||
1847 | * uint8 proto[proto_length]; */ | ||
1848 | len = ((unsigned int)data[0]) << 8 | | ||
1849 | ((unsigned int)data[1]); | ||
1850 | if (len != (unsigned int)size - 2) { | ||
1851 | *al = TLS1_AD_DECODE_ERROR; | ||
1852 | return (0); | ||
1853 | } | ||
1854 | len = data[2]; | ||
1855 | if (len != (unsigned int)size - 3) { | ||
1856 | *al = TLS1_AD_DECODE_ERROR; | ||
1857 | return (0); | ||
1858 | } | ||
1859 | free(s->s3->alpn_selected); | ||
1860 | s->s3->alpn_selected = malloc(len); | ||
1861 | if (s->s3->alpn_selected == NULL) { | ||
1862 | *al = TLS1_AD_INTERNAL_ERROR; | ||
1863 | return (0); | ||
1864 | } | ||
1865 | memcpy(s->s3->alpn_selected, data + 3, len); | ||
1866 | s->s3->alpn_selected_len = len; | ||
1867 | |||
1868 | } else if (type == TLSEXT_TYPE_renegotiate) { | ||
1720 | if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) | 1869 | if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) |
1721 | return 0; | 1870 | return 0; |
1722 | renegotiate_seen = 1; | 1871 | renegotiate_seen = 1; |