summaryrefslogtreecommitdiff
path: root/lib/libssl
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2019-01-21 13:45:58 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2019-01-21 13:45:58 +0000
commit60bbdcb85a3f5d62f272f34886d323f2197d9e72 (patch)
treef125bda090b1d3c84fc8367369062e13f8450992 /lib/libssl
parent44d2bf3b4bd98b62d4c9f6363bf0e0034a9ad3c8 (diff)
Provide the initial TLSv1.3 client implementation.
Move tls13_connect() to a new tls13_client.c file and provide a legacy wrapper to it, which allocates a struct tls_ctx if necessary. Also move tls13_client_hello_send() to tls13_client.c and actual implement the building of a client hello. ok tb@
Diffstat (limited to 'lib/libssl')
-rw-r--r--lib/libssl/Makefile3
-rw-r--r--lib/libssl/tls13_client.c139
-rw-r--r--lib/libssl/tls13_handshake.c27
-rw-r--r--lib/libssl/tls13_internal.h9
-rw-r--r--lib/libssl/tls13_lib.c39
5 files changed, 192 insertions, 25 deletions
diff --git a/lib/libssl/Makefile b/lib/libssl/Makefile
index b51d7168c03..de8d66c653e 100644
--- a/lib/libssl/Makefile
+++ b/lib/libssl/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.52 2019/01/21 10:28:52 tb Exp $
+# $OpenBSD: Makefile,v 1.53 2019/01/21 13:45:57 jsing Exp $
.include <bsd.own.mk>
.ifndef NOMAN
@@ -63,6 +63,7 @@ SRCS= \
t1_hash.c \
t1_lib.c \
tls13_buffer.c \
+ tls13_client.c \
tls13_handshake.c \
tls13_handshake_msg.c \
tls13_key_schedule.c \
diff --git a/lib/libssl/tls13_client.c b/lib/libssl/tls13_client.c
new file mode 100644
index 00000000000..1a2529be6af
--- /dev/null
+++ b/lib/libssl/tls13_client.c
@@ -0,0 +1,139 @@
+/* $OpenBSD: tls13_client.c,v 1.1 2019/01/21 13:45:57 jsing Exp $ */
+/*
+ * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ssl_locl.h"
+
+#include <openssl/curve25519.h>
+#include <openssl/ssl3.h>
+
+#include "bytestring.h"
+#include "ssl_tlsext.h"
+#include "tls13_internal.h"
+
+int
+tls13_connect(struct tls13_ctx *ctx)
+{
+ if (ctx->mode != TLS13_HS_CLIENT)
+ return TLS13_IO_FAILURE;
+
+ return tls13_handshake_perform(ctx);
+}
+
+static int
+tls13_client_init(SSL *s)
+{
+ if (!ssl_supported_version_range(s, &S3I(s)->hs_tls13.min_version,
+ &S3I(s)->hs_tls13.max_version)) {
+ SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
+ return 0;
+ }
+ s->client_version = s->version = S3I(s)->hs_tls13.max_version;
+
+ if (!ssl_get_new_session(s, 0)) /* XXX */
+ return 0;
+
+ if (!tls1_transcript_init(s))
+ return 0;
+
+ arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE);
+
+ return 1;
+}
+
+int
+tls13_legacy_connect(SSL *ssl)
+{
+ struct tls13_ctx *ctx = ssl->internal->tls13;
+ int ret;
+
+ if (ctx == NULL) {
+ if ((ctx = tls13_ctx_new(TLS13_HS_CLIENT)) == NULL) {
+ SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
+ return -1;
+ }
+ ssl->internal->tls13 = ctx;
+ ctx->ssl = ssl;
+
+ if (!tls13_client_init(ssl)) {
+ if (ERR_peek_error() == 0)
+ SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
+ return -1;
+ }
+ }
+
+ ret = tls13_connect(ctx);
+
+ return tls13_legacy_return_code(ssl, ret);
+}
+
+static int
+tls13_client_hello_build(SSL *s, CBB *cbb)
+{
+ CBB cipher_suites, compression_methods, session_id;
+ uint8_t *sid;
+
+ if (!CBB_add_u16(cbb, TLS1_2_VERSION))
+ goto err;
+ if (!CBB_add_bytes(cbb, s->s3->client_random, SSL3_RANDOM_SIZE))
+ goto err;
+
+ /* Either 32-random bytes or zero length... */
+ /* XXX - session resumption for TLSv1.2? */
+ if (!CBB_add_u8_length_prefixed(cbb, &session_id))
+ goto err;
+ if (!CBB_add_space(&session_id, &sid, 32))
+ goto err;
+ arc4random_buf(sid, 32);
+
+ if (!CBB_add_u16_length_prefixed(cbb, &cipher_suites))
+ goto err;
+ if (!ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &cipher_suites)) {
+ SSLerror(s, SSL_R_NO_CIPHERS_AVAILABLE);
+ goto err;
+ }
+
+ if (!CBB_add_u8_length_prefixed(cbb, &compression_methods))
+ goto err;
+ if (!CBB_add_u8(&compression_methods, 0))
+ goto err;
+
+ if (!tlsext_client_build(s, cbb, SSL_TLSEXT_MSG_CH))
+ goto err;
+
+ if (!CBB_flush(cbb))
+ goto err;
+
+ return 1;
+
+ err:
+ return 0;
+}
+
+int
+tls13_client_hello_send(struct tls13_ctx *ctx)
+{
+ CBB body;
+
+ if (!tls13_handshake_msg_start(ctx->hs_msg, &body, TLS13_MT_CLIENT_HELLO))
+ return 0;
+ if (!tls13_client_hello_build(ctx->ssl, &body))
+ return 0;
+ if (!tls13_handshake_msg_finish(ctx->hs_msg))
+ return 0;
+
+ return 1;
+}
diff --git a/lib/libssl/tls13_handshake.c b/lib/libssl/tls13_handshake.c
index 78f5611b70b..160202421c0 100644
--- a/lib/libssl/tls13_handshake.c
+++ b/lib/libssl/tls13_handshake.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_handshake.c,v 1.17 2019/01/21 13:13:46 jsing Exp $ */
+/* $OpenBSD: tls13_handshake.c,v 1.18 2019/01/21 13:45:57 jsing Exp $ */
/*
* Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2019 Joel Sing <jsing@openbsd.org>
@@ -31,11 +31,7 @@
struct tls13_handshake_action {
uint8_t record_type;
uint8_t handshake_type;
-
uint8_t sender;
-#define TLS13_HS_CLIENT 1
-#define TLS13_HS_SERVER 2
-
uint8_t handshake_complete;
int (*send)(struct tls13_ctx *ctx);
@@ -44,7 +40,6 @@ struct tls13_handshake_action {
enum tls13_message_type tls13_handshake_active_state(struct tls13_ctx *ctx);
-int tls13_connect(struct tls13_ctx *ctx);
int tls13_accept(struct tls13_ctx *ctx);
struct tls13_handshake_action *
@@ -313,14 +308,6 @@ tls13_handshake_perform(struct tls13_ctx *ctx)
}
int
-tls13_connect(struct tls13_ctx *ctx)
-{
- ctx->mode = TLS13_HS_CLIENT;
-
- return tls13_handshake_perform(ctx);
-}
-
-int
tls13_accept(struct tls13_ctx *ctx)
{
ctx->mode = TLS13_HS_SERVER;
@@ -391,13 +378,13 @@ tls13_handshake_recv_action(struct tls13_ctx *ctx,
return TLS13_IO_FAILURE;
}
- return action->recv(ctx);
-}
+ /* XXX provide CBS and check all consumed. */
+ ret = action->recv(ctx);
-int
-tls13_client_hello_send(struct tls13_ctx *ctx)
-{
- return 0;
+ tls13_handshake_msg_free(ctx->hs_msg);
+ ctx->hs_msg = NULL;
+
+ return ret;
}
int
diff --git a/lib/libssl/tls13_internal.h b/lib/libssl/tls13_internal.h
index 6ddce37ca32..2738c40c4c1 100644
--- a/lib/libssl/tls13_internal.h
+++ b/lib/libssl/tls13_internal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_internal.h,v 1.14 2019/01/21 13:13:46 jsing Exp $ */
+/* $OpenBSD: tls13_internal.h,v 1.15 2019/01/21 13:45:57 jsing Exp $ */
/*
* Copyright (c) 2018 Bob Beck <beck@openbsd.org>
* Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
@@ -26,6 +26,9 @@
__BEGIN_HIDDEN_DECLS
+#define TLS13_HS_CLIENT 1
+#define TLS13_HS_SERVER 2
+
#define TLS13_IO_SUCCESS 1
#define TLS13_IO_EOF 0
#define TLS13_IO_FAILURE -1
@@ -152,9 +155,13 @@ struct tls13_ctx {
struct tls13_handshake_msg *hs_msg;
};
+struct tls13_ctx *tls13_ctx_new(int mode);
+void tls13_ctx_free(struct tls13_ctx *ctx);
+
/*
* Legacy interfaces.
*/
+int tls13_legacy_return_code(SSL *ssl, ssize_t ret);
ssize_t tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg);
ssize_t tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg);
int tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len,
diff --git a/lib/libssl/tls13_lib.c b/lib/libssl/tls13_lib.c
index c4cce26ca53..3860ddefef6 100644
--- a/lib/libssl/tls13_lib.c
+++ b/lib/libssl/tls13_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_lib.c,v 1.2 2019/01/21 10:24:25 jsing Exp $ */
+/* $OpenBSD: tls13_lib.c,v 1.3 2019/01/21 13:45:57 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -61,6 +61,39 @@ tls13_cipher_hash(const SSL_CIPHER *cipher)
return NULL;
}
+struct tls13_ctx *
+tls13_ctx_new(int mode)
+{
+ struct tls13_ctx *ctx = NULL;
+
+ if ((ctx = calloc(sizeof(struct tls13_ctx), 1)) == NULL)
+ goto err;
+
+ ctx->mode = mode;
+
+ if ((ctx->rl = tls13_record_layer_new(tls13_legacy_wire_read_cb,
+ tls13_legacy_wire_write_cb, NULL, NULL, ctx)) == NULL)
+ goto err;
+
+ return ctx;
+
+ err:
+ tls13_ctx_free(ctx);
+
+ return NULL;
+}
+
+void
+tls13_ctx_free(struct tls13_ctx *ctx)
+{
+ if (ctx == NULL)
+ return;
+
+ tls13_record_layer_free(ctx->rl);
+
+ freezero(ctx, sizeof(struct tls13_ctx));
+}
+
static ssize_t
tls13_legacy_wire_read(SSL *ssl, uint8_t *buf, size_t len)
{
@@ -131,7 +164,7 @@ tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg)
return tls13_legacy_wire_write(ctx->ssl, buf, n);
}
-static int
+int
tls13_legacy_return_code(SSL *ssl, ssize_t ret)
{
if (ret > INT_MAX) {
@@ -139,7 +172,7 @@ tls13_legacy_return_code(SSL *ssl, ssize_t ret)
return -1;
}
- /* A successful read or write. */
+ /* A successful read, write or other operation. */
if (ret > 0)
return ret;