summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libtls/Makefile3
-rw-r--r--lib/libtls/tls.c17
-rw-r--r--lib/libtls/tls.h8
-rw-r--r--lib/libtls/tls_conninfo.c149
-rw-r--r--lib/libtls/tls_init.330
-rw-r--r--lib/libtls/tls_internal.h13
-rw-r--r--lib/libtls/tls_peer.c108
7 files changed, 208 insertions, 120 deletions
diff --git a/lib/libtls/Makefile b/lib/libtls/Makefile
index 1d7815f686a..6e5914685cb 100644
--- a/lib/libtls/Makefile
+++ b/lib/libtls/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.18 2015/09/11 15:17:46 deraadt Exp $
+# $OpenBSD: Makefile,v 1.19 2015/09/12 21:00:38 beck Exp $
CFLAGS+= -Wall -Werror -Wimplicit
CFLAGS+= -DLIBRESSL_INTERNAL
@@ -15,6 +15,7 @@ HDRS= tls.h
SRCS= tls.c \
tls_client.c \
tls_config.c \
+ tls_conninfo.c \
tls_peer.c \
tls_server.c \
tls_util.c \
diff --git a/lib/libtls/tls.c b/lib/libtls/tls.c
index 65103f106d4..277970c932e 100644
--- a/lib/libtls/tls.c
+++ b/lib/libtls/tls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.c,v 1.26 2015/09/12 19:54:31 jsing Exp $ */
+/* $OpenBSD: tls.c,v 1.27 2015/09/12 21:00:38 beck Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
@@ -323,6 +323,10 @@ tls_reset(struct tls *ctx)
free(ctx->errmsg);
ctx->errmsg = NULL;
ctx->errnum = 0;
+
+ tls_free_conninfo(ctx->conninfo);
+ free(ctx->conninfo);
+ ctx->conninfo = NULL;
}
int
@@ -376,14 +380,19 @@ tls_handshake(struct tls *ctx)
{
int rv = -1;
+ if ((ctx->conninfo = calloc(1, sizeof(*ctx->conninfo))) == NULL)
+ goto out;
+
if ((ctx->flags & TLS_CLIENT) != 0)
rv = tls_handshake_client(ctx);
else if ((ctx->flags & TLS_SERVER_CONN) != 0)
rv = tls_handshake_server(ctx);
- if (rv == 0)
- ctx->ssl_peer_cert = SSL_get_peer_certificate(ctx->ssl_conn);
-
+ if (rv == 0 &&
+ (ctx->ssl_peer_cert = SSL_get_peer_certificate(ctx->ssl_conn)) &&
+ (tls_get_conninfo(ctx) == -1))
+ rv = -1;
+out:
/* Prevent callers from performing incorrect error handling */
errno = 0;
return (rv);
diff --git a/lib/libtls/tls.h b/lib/libtls/tls.h
index 1a6cb475445..2f91ea68bab 100644
--- a/lib/libtls/tls.h
+++ b/lib/libtls/tls.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.h,v 1.21 2015/09/12 16:46:43 jsing Exp $ */
+/* $OpenBSD: tls.h,v 1.22 2015/09/12 21:00:38 beck Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
@@ -102,9 +102,9 @@ int tls_close(struct tls *_ctx);
int tls_peer_cert_provided(struct tls *ctx);
int tls_peer_cert_contains_name(struct tls *ctx, const char *name);
-int tls_peer_cert_hash(struct tls *_ctx, char **_hash);
-int tls_peer_cert_issuer(struct tls *ctx, char **name);
-int tls_peer_cert_subject(struct tls *ctx, char **subject);
+const char * tls_peer_cert_hash(struct tls *_ctx);
+const char * tls_peer_cert_issuer(struct tls *ctx);
+const char * tls_peer_cert_subject(struct tls *ctx);
uint8_t *tls_load_file(const char *_file, size_t *_len, char *_password);
diff --git a/lib/libtls/tls_conninfo.c b/lib/libtls/tls_conninfo.c
new file mode 100644
index 00000000000..267a8747c91
--- /dev/null
+++ b/lib/libtls/tls_conninfo.c
@@ -0,0 +1,149 @@
+/* $OpenBSD: tls_conninfo.c,v 1.1 2015/09/12 21:00:38 beck Exp $ */
+/*
+ * Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
+ * Copyright (c) 2015 Bob Beck <beck@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 <stdio.h>
+
+#include <openssl/x509.h>
+
+#include <tls.h>
+#include "tls_internal.h"
+
+static int
+tls_hex_string(const unsigned char *in, size_t inlen, char **out,
+ size_t *outlen)
+{
+ static const char hex[] = "0123456789abcdef";
+ size_t i, len;
+ char *p;
+
+ if (outlen != NULL)
+ *outlen = 0;
+
+ if (inlen >= SIZE_MAX)
+ return (-1);
+ if ((*out = reallocarray(NULL, inlen + 1, 2)) == NULL)
+ return (-1);
+
+ p = *out;
+ len = 0;
+ for (i = 0; i < inlen; i++) {
+ p[len++] = hex[(in[i] >> 4) & 0x0f];
+ p[len++] = hex[in[i] & 0x0f];
+ }
+ p[len++] = 0;
+
+ if (outlen != NULL)
+ *outlen = len;
+
+ return (0);
+}
+
+static int
+tls_get_peer_cert_hash(struct tls *ctx, char **hash)
+{
+ char d[EVP_MAX_MD_SIZE], *dhex = NULL;
+ int dlen, rv = -1;
+
+ *hash = NULL;
+ if (ctx->ssl_peer_cert == NULL)
+ return (0);
+
+ if (X509_digest(ctx->ssl_peer_cert, EVP_sha256(), d, &dlen) != 1) {
+ tls_set_errorx(ctx, "digest failed");
+ goto err;
+ }
+
+ if (tls_hex_string(d, dlen, &dhex, NULL) != 0) {
+ tls_set_errorx(ctx, "digest hex string failed");
+ goto err;
+ }
+
+ if (asprintf(hash, "SHA256:%s", dhex) == -1) {
+ tls_set_errorx(ctx, "out of memory");
+ *hash = NULL;
+ goto err;
+ }
+
+ rv = 0;
+
+err:
+ free(dhex);
+
+ return (rv);
+}
+
+static int
+tls_get_peer_cert_issuer(struct tls *ctx, char **issuer)
+{
+ X509_NAME *name = NULL;
+
+ *issuer = NULL;
+ if (ctx->ssl_peer_cert == NULL)
+ return (-1);
+ if ((name = X509_get_issuer_name(ctx->ssl_peer_cert)) == NULL)
+ return (-1);
+ *issuer = X509_NAME_oneline(name, 0, 0);
+ if (*issuer == NULL)
+ return (-1);
+ return (0);
+}
+
+static int
+tls_get_peer_cert_subject(struct tls *ctx, char **subject)
+{
+ X509_NAME *name = NULL;
+
+ *subject = NULL;
+ if (ctx->ssl_peer_cert == NULL)
+ return (-1);
+ if ((name = X509_get_subject_name(ctx->ssl_peer_cert)) == NULL)
+ return (-1);
+ *subject = X509_NAME_oneline(name, 0, 0);
+ if (*subject == NULL)
+ return (-1);
+ return (0);
+}
+
+int
+tls_get_conninfo(struct tls *ctx) {
+ int rv = -1;
+ if (ctx->ssl_peer_cert != NULL) {
+ if (tls_get_peer_cert_hash(ctx, &ctx->conninfo->hash) == -1)
+ goto err;
+ if (tls_get_peer_cert_subject(ctx, &ctx->conninfo->subject)
+ == -1)
+ goto err;
+ if (tls_get_peer_cert_issuer(ctx, &ctx->conninfo->issuer) == -1)
+ goto err;
+ }
+ rv = 0;
+err:
+ return (rv);
+}
+
+void
+tls_free_conninfo(struct tls_conninfo *conninfo) {
+ if (conninfo != NULL) {
+ free(conninfo->hash);
+ conninfo->hash = NULL;
+ free(conninfo->subject);
+ conninfo->subject = NULL;
+ free(conninfo->issuer);
+ conninfo->issuer = NULL;
+ }
+}
diff --git a/lib/libtls/tls_init.3 b/lib/libtls/tls_init.3
index a1fe52c83c4..90cbdb3f3bd 100644
--- a/lib/libtls/tls_init.3
+++ b/lib/libtls/tls_init.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tls_init.3,v 1.42 2015/09/11 14:22:53 jmc Exp $
+.\" $OpenBSD: tls_init.3,v 1.43 2015/09/12 21:00:38 beck Exp $
.\"
.\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: September 11 2015 $
+.Dd $Mdocdate: September 12 2015 $
.Dt TLS_INIT 3
.Os
.Sh NAME
@@ -121,12 +121,12 @@
.Fn tls_peer_cert_provided "struct tls *ctx"
.Ft "int"
.Fn tls_peer_cert_contains_name "struct tls *ctx" "const char *name"
-.Ft "int"
-.Fn tls_peer_cert_issuer "struct tls *ctx" "char **issuer"
-.Ft "int"
-.Fn tls_peer_cert_subject "struct tls *ctx" "char **subject"
-.Ft "int"
-.Fn tls_peer_cert_hash "struct tls *ctx" "char **hash"
+.Ft "const char *"
+.Fn tls_peer_cert_issuer "struct tls *ctx"
+.Ft "const char *"
+.Fn tls_peer_cert_subject "struct tls *ctx"
+.Ft "const char *"
+.Fn tls_peer_cert_hash "struct tls *ctx"
.Ft "uint8_t *"
.Fn tls_load_file "const char *file" "size_t *len" "char *password"
.Ft "struct tls *"
@@ -386,31 +386,23 @@ can only succeed after the handshake is complete.
.Em (Server and client)
.It
.Fn tls_peer_cert_subject
-returns a string in
-.Ar subject
+returns a string
corresponding to the subject of the peer certificate from
.Ar ctx .
.Fn tls_peer_cert_subject
will only succeed after the handshake is complete.
-Callers must free the string returned in
-.Ar subject .
.Em (Server and client)
.It
.Fn tls_peer_cert_issuer
-returns a string in
-.Ar subject
+returns a string
corresponding to the issuer of the peer certificate from
.Ar ctx .
.Fn tls_peer_cert_issuer
will only succeed after the handshake is complete.
-Callers must free the string returned in
-.Ar issuer .
.Em (Server and client)
.It
.Fn tls_peer_cert_hash
returns a string
-in
-.Ar hash
corresponding to a hash of the raw peer certificate from
.Ar ctx
prefixed by a hash name followed by a colon.
@@ -426,8 +418,6 @@ printf "SHA256:${h}\\n"
.Pp
.Fn tls_peer_cert_subject
will only succeed after the handshake is complete.
-Callers must free the string returned in
-.Ar hash .
.Em (Server and client)
.It
.Fn tls_config_verify_client_opional
diff --git a/lib/libtls/tls_internal.h b/lib/libtls/tls_internal.h
index 34af0fb48a6..e31c39a135b 100644
--- a/lib/libtls/tls_internal.h
+++ b/lib/libtls/tls_internal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_internal.h,v 1.20 2015/09/11 12:56:55 beck Exp $ */
+/* $OpenBSD: tls_internal.h,v 1.21 2015/09/12 21:00:38 beck Exp $ */
/*
* Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -48,6 +48,14 @@ struct tls_config {
int verify_name;
};
+struct tls_conninfo {
+ char *issuer;
+ char *subject;
+ char *hash;
+ char *serial;
+ char *fingerprint;
+};
+
#define TLS_CLIENT (1 << 0)
#define TLS_SERVER (1 << 1)
#define TLS_SERVER_CONN (1 << 2)
@@ -68,6 +76,7 @@ struct tls {
SSL *ssl_conn;
SSL_CTX *ssl_ctx;
X509 *ssl_peer_cert;
+ struct tls_conninfo *conninfo;
};
struct tls *tls_new(void);
@@ -89,5 +98,7 @@ int tls_set_errorx(struct tls *ctx, const char *fmt, ...)
__attribute__((__nonnull__ (2)));
int tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret,
const char *prefix);
+int tls_get_conninfo(struct tls *ctx);
+void tls_free_conninfo(struct tls_conninfo *conninfo);
#endif /* HEADER_TLS_INTERNAL_H */
diff --git a/lib/libtls/tls_peer.c b/lib/libtls/tls_peer.c
index cd1984f2153..3145e500c47 100644
--- a/lib/libtls/tls_peer.c
+++ b/lib/libtls/tls_peer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_peer.c,v 1.3 2015/09/11 13:22:39 beck Exp $ */
+/* $OpenBSD: tls_peer.c,v 1.4 2015/09/12 21:00:38 beck Exp $ */
/*
* Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2015 Bob Beck <beck@openbsd.org>
@@ -23,68 +23,27 @@
#include <tls.h>
#include "tls_internal.h"
-static int
-tls_hex_string(const unsigned char *in, size_t inlen, char **out,
- size_t *outlen)
+const char *
+tls_peer_cert_hash(struct tls *ctx)
{
- static const char hex[] = "0123456789abcdef";
- size_t i, len;
- char *p;
-
- if (outlen != NULL)
- *outlen = 0;
-
- if (inlen >= SIZE_MAX)
- return (-1);
- if ((*out = reallocarray(NULL, inlen + 1, 2)) == NULL)
- return (-1);
-
- p = *out;
- len = 0;
- for (i = 0; i < inlen; i++) {
- p[len++] = hex[(in[i] >> 4) & 0x0f];
- p[len++] = hex[in[i] & 0x0f];
- }
- p[len++] = 0;
-
- if (outlen != NULL)
- *outlen = len;
-
- return (0);
+ if (ctx->conninfo)
+ return (ctx->conninfo->hash);
+ return NULL;
}
-
-int
-tls_peer_cert_hash(struct tls *ctx, char **hash)
+const char *
+tls_peer_cert_issuer(struct tls *ctx)
{
- char d[EVP_MAX_MD_SIZE], *dhex = NULL;
- int dlen, rv = -1;
-
- *hash = NULL;
- if (ctx->ssl_peer_cert == NULL)
- return (0);
-
- if (X509_digest(ctx->ssl_peer_cert, EVP_sha256(), d, &dlen) != 1) {
- tls_set_errorx(ctx, "digest failed");
- goto err;
- }
-
- if (tls_hex_string(d, dlen, &dhex, NULL) != 0) {
- tls_set_errorx(ctx, "digest hex string failed");
- goto err;
- }
-
- if (asprintf(hash, "SHA256:%s", dhex) == -1) {
- tls_set_errorx(ctx, "out of memory");
- *hash = NULL;
- goto err;
- }
-
- rv = 0;
-
-err:
- free(dhex);
+ if (ctx->conninfo)
+ return (ctx->conninfo->issuer);
+ return NULL;
+}
- return (rv);
+const char *
+tls_peer_cert_subject(struct tls *ctx)
+{
+ if (ctx->conninfo)
+ return (ctx->conninfo->subject);
+ return NULL;
}
int
@@ -102,34 +61,3 @@ tls_peer_cert_contains_name(struct tls *ctx, const char *name)
return (tls_check_name(ctx, ctx->ssl_peer_cert, name) == 0);
}
-int
-tls_peer_cert_issuer(struct tls *ctx, char **issuer)
-{
- X509_NAME *name = NULL;
-
- *issuer = NULL;
- if (ctx->ssl_peer_cert == NULL)
- return (-1);
- if ((name = X509_get_issuer_name(ctx->ssl_peer_cert)) == NULL)
- return (-1);
- *issuer = X509_NAME_oneline(name, 0, 0);
- if (*issuer == NULL)
- return (-1);
- return (0);
-}
-
-int
-tls_peer_cert_subject(struct tls *ctx, char **subject)
-{
- X509_NAME *name = NULL;
-
- *subject = NULL;
- if (ctx->ssl_peer_cert == NULL)
- return (-1);
- if ((name = X509_get_subject_name(ctx->ssl_peer_cert)) == NULL)
- return (-1);
- *subject = X509_NAME_oneline(name, 0, 0);
- if (*subject == NULL)
- return (-1);
- return (0);
-}