summaryrefslogtreecommitdiffstats
path: root/lib/libssl/ssl_lib.c
diff options
context:
space:
mode:
authorjsing <jsing@openbsd.org>2014-12-10 14:58:56 +0000
committerjsing <jsing@openbsd.org>2014-12-10 14:58:56 +0000
commitd436807c3fafcdd2569d3d41472f012dd477b2a9 (patch)
treea15b7e477ed8ba85a84f131c7324004133d3ba7b /lib/libssl/ssl_lib.c
parentadd stdint.h to ssl.h. (diff)
downloadwireguard-openbsd-d436807c3fafcdd2569d3d41472f012dd477b2a9.tar.xz
wireguard-openbsd-d436807c3fafcdd2569d3d41472f012dd477b2a9.zip
Add support for ALPN.
Based on OpenSSL and BoringSSL. ok bcook@
Diffstat (limited to 'lib/libssl/ssl_lib.c')
-rw-r--r--lib/libssl/ssl_lib.c86
1 files changed, 85 insertions, 1 deletions
diff --git a/lib/libssl/ssl_lib.c b/lib/libssl/ssl_lib.c
index bdd47ff87f6..a03ee735ada 100644
--- a/lib/libssl/ssl_lib.c
+++ b/lib/libssl/ssl_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_lib.c,v 1.90 2014/11/16 14:12:47 jsing Exp $ */
+/* $OpenBSD: ssl_lib.c,v 1.91 2014/12/10 14:58:56 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -337,6 +337,18 @@ SSL_new(SSL_CTX *ctx)
s->next_proto_negotiated = NULL;
# endif
+ if (s->ctx->alpn_client_proto_list != NULL) {
+ s->alpn_client_proto_list =
+ malloc(s->ctx->alpn_client_proto_list_len);
+ if (s->alpn_client_proto_list == NULL)
+ goto err;
+ memcpy(s->alpn_client_proto_list,
+ s->ctx->alpn_client_proto_list,
+ s->ctx->alpn_client_proto_list_len);
+ s->alpn_client_proto_list_len =
+ s->ctx->alpn_client_proto_list_len;
+ }
+
s->verify_result = X509_V_OK;
s->method = ctx->method;
@@ -551,6 +563,7 @@ SSL_free(SSL *s)
#ifndef OPENSSL_NO_NEXTPROTONEG
free(s->next_proto_negotiated);
#endif
+ free(s->alpn_client_proto_list);
#ifndef OPENSSL_NO_SRTP
if (s->srtp_profiles)
@@ -1629,6 +1642,75 @@ SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s,
}
# endif
+/*
+ * SSL_CTX_set_alpn_protos sets the ALPN protocol list to the specified
+ * protocols, which must be in wire-format (i.e. a series of non-empty,
+ * 8-bit length-prefixed strings). Returns 0 on success.
+ */
+int
+SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
+ unsigned int protos_len)
+{
+ free(ctx->alpn_client_proto_list);
+ if ((ctx->alpn_client_proto_list = malloc(protos_len)) == NULL)
+ return (1);
+ memcpy(ctx->alpn_client_proto_list, protos, protos_len);
+ ctx->alpn_client_proto_list_len = protos_len;
+
+ return (0);
+}
+
+/*
+ * SSL_set_alpn_protos sets the ALPN protocol list to the specified
+ * protocols, which must be in wire-format (i.e. a series of non-empty,
+ * 8-bit length-prefixed strings). Returns 0 on success.
+ */
+int
+SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos,
+ unsigned int protos_len)
+{
+ free(ssl->alpn_client_proto_list);
+ if ((ssl->alpn_client_proto_list = malloc(protos_len)) == NULL)
+ return (1);
+ memcpy(ssl->alpn_client_proto_list, protos, protos_len);
+ ssl->alpn_client_proto_list_len = protos_len;
+
+ return (0);
+}
+
+/*
+ * SSL_CTX_set_alpn_select_cb sets a callback function that is called during
+ * ClientHello processing in order to select an ALPN protocol from the
+ * client's list of offered protocols.
+ */
+void
+SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
+ int (*cb) (SSL *ssl, const unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen, void *arg), void *arg)
+{
+ ctx->alpn_select_cb = cb;
+ ctx->alpn_select_cb_arg = arg;
+}
+
+/*
+ * SSL_get0_alpn_selected gets the selected ALPN protocol (if any). On return
+ * it sets data to point to len bytes of protocol name (not including the
+ * leading length-prefix byte). If the server didn't respond with* a negotiated
+ * protocol then len will be zero.
+ */
+void
+SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
+ unsigned *len)
+{
+ *data = NULL;
+ *len = 0;
+
+ if (ssl->s3 != NULL) {
+ *data = ssl->s3->alpn_selected;
+ *len = ssl->s3->alpn_selected_len;
+ }
+}
+
int
SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
const char *label, size_t llen, const unsigned char *p, size_t plen,
@@ -1894,6 +1976,8 @@ SSL_CTX_free(SSL_CTX *a)
ENGINE_finish(a->client_cert_engine);
#endif
+ free(a->alpn_client_proto_list);
+
free(a);
}