diff options
| author | jsing <> | 2014-12-10 14:58:56 +0000 |
|---|---|---|
| committer | jsing <> | 2014-12-10 14:58:56 +0000 |
| commit | 732fdd2bcb9886c4f4ab17540c0c7bb002ca55f1 (patch) | |
| tree | e9391008296b8ff8be480e9f3e9eb1be0aab121a /src | |
| parent | 1b81594902955b3473f83fbc3af50e4cad85e0c6 (diff) | |
| download | openbsd-732fdd2bcb9886c4f4ab17540c0c7bb002ca55f1.tar.gz openbsd-732fdd2bcb9886c4f4ab17540c0c7bb002ca55f1.tar.bz2 openbsd-732fdd2bcb9886c4f4ab17540c0c7bb002ca55f1.zip | |
Add support for ALPN.
Based on OpenSSL and BoringSSL.
ok bcook@
Diffstat (limited to '')
| -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; |
