summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Beck <beck@cvs.openbsd.org>2015-09-09 19:23:05 +0000
committerBob Beck <beck@cvs.openbsd.org>2015-09-09 19:23:05 +0000
commitc807ec2ba1a15aed34fa85d686db01a97e0d831a (patch)
tree53b104b077c1ce2069340701d8f851f242f61a69
parenta7f868b1c0b00915dc9b2316c5a2e5663b65c155 (diff)
Add client certificate support. Still needs a few tweaks but this will
ride upcoming minor bump ok jsing@
-rw-r--r--lib/libtls/tls.c42
-rw-r--r--lib/libtls/tls.h5
-rw-r--r--lib/libtls/tls_client.c32
-rw-r--r--lib/libtls/tls_config.c14
-rw-r--r--lib/libtls/tls_internal.h6
-rw-r--r--lib/libtls/tls_server.c11
6 files changed, 76 insertions, 34 deletions
diff --git a/lib/libtls/tls.c b/lib/libtls/tls.c
index db14d3fc7dc..0c4793cc9a2 100644
--- a/lib/libtls/tls.c
+++ b/lib/libtls/tls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.c,v 1.17 2015/09/09 18:22:33 beck Exp $ */
+/* $OpenBSD: tls.c,v 1.18 2015/09/09 19:23:04 beck Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
@@ -147,12 +147,19 @@ tls_configure(struct tls *ctx, struct tls_config *config)
}
int
-tls_configure_keypair(struct tls *ctx)
+tls_configure_keypair(struct tls *ctx, int required)
{
EVP_PKEY *pkey = NULL;
X509 *cert = NULL;
BIO *bio = NULL;
+ if (!required &&
+ ctx->config->cert_mem == NULL &&
+ ctx->config->key_mem == NULL &&
+ ctx->config->cert_file == NULL &&
+ ctx->config->key_file == NULL)
+ return(0);
+
if (ctx->config->cert_mem != NULL) {
if (ctx->config->cert_len > INT_MAX) {
tls_set_errorx(ctx, "certificate too long");
@@ -256,6 +263,37 @@ err:
return (-1);
}
+int
+tls_configure_ssl_verify(struct tls *ctx, int verify)
+{
+ SSL_CTX_set_verify(ctx->ssl_ctx, verify, NULL);
+
+ if (ctx->config->ca_mem != NULL) {
+ /* XXX do this in set. */
+ if (ctx->config->ca_len > INT_MAX) {
+ tls_set_error(ctx, "client ca too long");
+ goto err;
+ }
+ if (SSL_CTX_load_verify_mem(ctx->ssl_ctx,
+ ctx->config->ca_mem, ctx->config->ca_len) != 1) {
+ tls_set_error(ctx,
+ "ssl verify memory setup failure");
+ goto err;
+ }
+ } else if (SSL_CTX_load_verify_locations(ctx->ssl_ctx,
+ ctx->config->ca_file, ctx->config->ca_path) != 1) {
+ tls_set_error(ctx, "ssl verify setup failure");
+ goto err;
+ }
+ if (ctx->config->verify_depth >= 0)
+ SSL_CTX_set_verify_depth(ctx->ssl_ctx,
+ ctx->config->verify_depth);
+ return (0);
+
+ err:
+ return (-1);
+}
+
void
tls_free(struct tls *ctx)
{
diff --git a/lib/libtls/tls.h b/lib/libtls/tls.h
index cb02ee8824b..1a6257232c5 100644
--- a/lib/libtls/tls.h
+++ b/lib/libtls/tls.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.h,v 1.13 2015/06/19 06:20:11 bcook Exp $ */
+/* $OpenBSD: tls.h,v 1.14 2015/09/09 19:23:04 beck Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
@@ -73,6 +73,9 @@ void tls_config_insecure_noverifycert(struct tls_config *_config);
void tls_config_insecure_noverifyname(struct tls_config *_config);
void tls_config_verify(struct tls_config *_config);
+void tls_config_verify_client(struct tls_config *_config);
+void tls_config_verify_client_optional(struct tls_config *_config);
+
struct tls *tls_client(void);
struct tls *tls_server(void);
int tls_configure(struct tls *_ctx, struct tls_config *_config);
diff --git a/lib/libtls/tls_client.c b/lib/libtls/tls_client.c
index 81b55104311..056526ddc37 100644
--- a/lib/libtls/tls_client.c
+++ b/lib/libtls/tls_client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_client.c,v 1.23 2015/09/09 14:32:06 jsing Exp $ */
+/* $OpenBSD: tls_client.c,v 1.24 2015/09/09 19:23:04 beck Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
@@ -21,7 +21,6 @@
#include <arpa/inet.h>
#include <netinet/in.h>
-#include <limits.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
@@ -190,6 +189,8 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write,
if (tls_configure_ssl(ctx) != 0)
goto err;
+ if (tls_configure_keypair(ctx, 0) != 0)
+ goto err;
if (ctx->config->verify_name) {
if (servername == NULL) {
@@ -198,30 +199,9 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write,
}
}
- if (ctx->config->verify_cert) {
- SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, NULL);
-
- if (ctx->config->ca_mem != NULL) {
- if (ctx->config->ca_len > INT_MAX) {
- tls_set_errorx(ctx, "ca too long");
- goto err;
- }
-
- if (SSL_CTX_load_verify_mem(ctx->ssl_ctx,
- ctx->config->ca_mem, ctx->config->ca_len) != 1) {
- tls_set_errorx(ctx,
- "ssl verify memory setup failure");
- goto err;
- }
- } else if (SSL_CTX_load_verify_locations(ctx->ssl_ctx,
- ctx->config->ca_file, ctx->config->ca_path) != 1) {
- tls_set_errorx(ctx, "ssl verify setup failure");
- goto err;
- }
- if (ctx->config->verify_depth >= 0)
- SSL_CTX_set_verify_depth(ctx->ssl_ctx,
- ctx->config->verify_depth);
- }
+ if (ctx->config->verify_cert &&
+ (tls_configure_ssl_verify(ctx, SSL_VERIFY_PEER) == -1))
+ goto err;
if ((ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) {
tls_set_errorx(ctx, "ssl connection failure");
diff --git a/lib/libtls/tls_config.c b/lib/libtls/tls_config.c
index 4c25a793039..73073d8ff7f 100644
--- a/lib/libtls/tls_config.c
+++ b/lib/libtls/tls_config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_config.c,v 1.9 2015/02/22 15:09:54 jsing Exp $ */
+/* $OpenBSD: tls_config.c,v 1.10 2015/09/09 19:23:04 beck Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
@@ -300,3 +300,15 @@ tls_config_verify(struct tls_config *config)
config->verify_cert = 1;
config->verify_name = 1;
}
+
+void
+tls_config_verify_client(struct tls_config *config)
+{
+ config->verify_client = 1;
+}
+
+void
+tls_config_verify_client_optional(struct tls_config *config)
+{
+ config->verify_client = 2;
+}
diff --git a/lib/libtls/tls_internal.h b/lib/libtls/tls_internal.h
index d767c374941..58834c999f0 100644
--- a/lib/libtls/tls_internal.h
+++ b/lib/libtls/tls_internal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_internal.h,v 1.15 2015/09/08 15:29:34 jsing Exp $ */
+/* $OpenBSD: tls_internal.h,v 1.16 2015/09/09 19:23:04 beck Exp $ */
/*
* Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -42,6 +42,7 @@ struct tls_config {
size_t key_len;
uint32_t protocols;
int verify_cert;
+ int verify_client;
int verify_depth;
int verify_name;
};
@@ -70,9 +71,10 @@ struct tls *tls_new(void);
struct tls *tls_server_conn(struct tls *ctx);
int tls_check_servername(struct tls *ctx, X509 *cert, const char *servername);
-int tls_configure_keypair(struct tls *ctx);
+int tls_configure_keypair(struct tls *ctx, int);
int tls_configure_server(struct tls *ctx);
int tls_configure_ssl(struct tls *ctx);
+int tls_configure_ssl_verify(struct tls *ctx, int verify);
int tls_host_port(const char *hostport, char **host, char **port);
int tls_set_error(struct tls *ctx, const char *fmt, ...)
__attribute__((__format__ (printf, 2, 3)))
diff --git a/lib/libtls/tls_server.c b/lib/libtls/tls_server.c
index 190682e630a..6f8daa0acab 100644
--- a/lib/libtls/tls_server.c
+++ b/lib/libtls/tls_server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_server.c,v 1.11 2015/09/09 14:32:06 jsing Exp $ */
+/* $OpenBSD: tls_server.c,v 1.12 2015/09/09 19:23:04 beck Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
@@ -60,8 +60,15 @@ tls_configure_server(struct tls *ctx)
if (tls_configure_ssl(ctx) != 0)
goto err;
- if (tls_configure_keypair(ctx) != 0)
+ if (tls_configure_keypair(ctx, 1) != 0)
goto err;
+ if (ctx->config->verify_client != 0) {
+ int verify = SSL_VERIFY_PEER;
+ if (ctx->config->verify_client == 1)
+ verify |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+ if (tls_configure_ssl_verify(ctx, verify) == -1)
+ goto err;
+ }
if (ctx->config->dheparams == -1)
SSL_CTX_set_dh_auto(ctx->ssl_ctx, 1);