summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libtls/Symbols.list1
-rw-r--r--lib/libtls/shlib_version2
-rw-r--r--lib/libtls/tls.c5
-rw-r--r--lib/libtls/tls.h3
-rw-r--r--lib/libtls/tls_conninfo.c52
-rw-r--r--lib/libtls/tls_internal.h7
-rw-r--r--lib/libtls/tls_peer.c13
7 files changed, 77 insertions, 6 deletions
diff --git a/lib/libtls/Symbols.list b/lib/libtls/Symbols.list
index 98465dde273..248784a4887 100644
--- a/lib/libtls/Symbols.list
+++ b/lib/libtls/Symbols.list
@@ -60,6 +60,7 @@ tls_handshake
tls_init
tls_load_file
tls_ocsp_process_response
+tls_peer_cert_chain_pem
tls_peer_cert_contains_name
tls_peer_cert_hash
tls_peer_cert_issuer
diff --git a/lib/libtls/shlib_version b/lib/libtls/shlib_version
index 4c073ef03c9..f0f244c56ae 100644
--- a/lib/libtls/shlib_version
+++ b/lib/libtls/shlib_version
@@ -1,2 +1,2 @@
major=15
-minor=4
+minor=5
diff --git a/lib/libtls/tls.c b/lib/libtls/tls.c
index 419554818c3..446f93430d7 100644
--- a/lib/libtls/tls.c
+++ b/lib/libtls/tls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.c,v 1.60 2017/04/05 03:13:53 beck Exp $ */
+/* $OpenBSD: tls.c,v 1.61 2017/04/05 03:19:22 beck Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
@@ -528,6 +528,8 @@ tls_reset(struct tls *ctx)
ctx->ssl_conn = NULL;
ctx->ssl_ctx = NULL;
ctx->ssl_peer_cert = NULL;
+ /* X509 objects in chain are freed with the SSL */
+ ctx->ssl_peer_chain = NULL;
ctx->socket = -1;
ctx->state = 0;
@@ -625,6 +627,7 @@ tls_handshake(struct tls *ctx)
if (rv == 0) {
ctx->ssl_peer_cert = SSL_get_peer_certificate(ctx->ssl_conn);
+ ctx->ssl_peer_chain = SSL_get_peer_cert_chain(ctx->ssl_conn);
if (tls_conninfo_populate(ctx) == -1)
rv = -1;
if (ctx->ocsp == NULL)
diff --git a/lib/libtls/tls.h b/lib/libtls/tls.h
index d9b2972e92a..c9da8aa06e6 100644
--- a/lib/libtls/tls.h
+++ b/lib/libtls/tls.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.h,v 1.47 2017/01/31 16:18:57 beck Exp $ */
+/* $OpenBSD: tls.h,v 1.48 2017/04/05 03:19:22 beck Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
@@ -179,6 +179,7 @@ const char *tls_peer_cert_issuer(struct tls *_ctx);
const char *tls_peer_cert_subject(struct tls *_ctx);
time_t tls_peer_cert_notbefore(struct tls *_ctx);
time_t tls_peer_cert_notafter(struct tls *_ctx);
+const uint8_t *tls_peer_cert_chain_pem(struct tls *_ctx, size_t *_len);
const char *tls_conn_alpn_selected(struct tls *_ctx);
const char *tls_conn_cipher(struct tls *_ctx);
diff --git a/lib/libtls/tls_conninfo.c b/lib/libtls/tls_conninfo.c
index c4d23c308b5..87660fa9899 100644
--- a/lib/libtls/tls_conninfo.c
+++ b/lib/libtls/tls_conninfo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_conninfo.c,v 1.14 2017/04/05 03:13:53 beck Exp $ */
+/* $OpenBSD: tls_conninfo.c,v 1.15 2017/04/05 03:19:22 beck Exp $ */
/*
* Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2015 Bob Beck <beck@openbsd.org>
@@ -174,6 +174,49 @@ tls_conninfo_alpn_proto(struct tls *ctx)
return (0);
}
+static int
+tls_conninfo_cert_pem(struct tls *ctx)
+{
+ int i, rv = -1;
+ BIO *membio = NULL;
+ BUF_MEM *bptr = NULL;
+
+ if (ctx->conninfo == NULL)
+ goto err;
+ if (ctx->ssl_peer_cert == NULL)
+ return 0;
+ if ((membio = BIO_new(BIO_s_mem()))== NULL)
+ goto err;
+
+ /*
+ * We have to write the peer cert out separately, because
+ * the certificate chain may or may not contain it.
+ */
+ if (!PEM_write_bio_X509(membio, ctx->ssl_peer_cert))
+ goto err;
+ for (i = 0; i < sk_X509_num(ctx->ssl_peer_chain); i++) {
+ X509 *chaincert = sk_X509_value(ctx->ssl_peer_chain, i);
+ if (chaincert != ctx->ssl_peer_cert &&
+ !PEM_write_bio_X509(membio, chaincert))
+ goto err;
+ }
+
+ BIO_get_mem_ptr(membio, &bptr);
+ free(ctx->conninfo->peer_cert);
+ ctx->conninfo->peer_cert_len = 0;
+ if ((ctx->conninfo->peer_cert = malloc(bptr->length)) == NULL)
+ goto err;
+ ctx->conninfo->peer_cert_len = bptr->length;
+ memcpy(ctx->conninfo->peer_cert, bptr->data,
+ ctx->conninfo->peer_cert_len);
+
+ /* BIO_free() will kill BUF_MEM - because we have not set BIO_NOCLOSE */
+ rv = 0;
+ err:
+ BIO_free(membio);
+ return rv;
+}
+
int
tls_conninfo_populate(struct tls *ctx)
{
@@ -210,6 +253,9 @@ tls_conninfo_populate(struct tls *ctx)
if (tls_get_peer_cert_info(ctx) == -1)
goto err;
+ if (tls_conninfo_cert_pem(ctx) == -1)
+ goto err;
+
return (0);
err:
@@ -241,6 +287,10 @@ tls_conninfo_free(struct tls_conninfo *conninfo)
free(conninfo->subject);
conninfo->subject = NULL;
+ free(conninfo->peer_cert);
+ conninfo->peer_cert = NULL;
+ conninfo->peer_cert_len = 0;
+
free(conninfo);
}
diff --git a/lib/libtls/tls_internal.h b/lib/libtls/tls_internal.h
index b1d53c8fa30..5bbcadf8043 100644
--- a/lib/libtls/tls_internal.h
+++ b/lib/libtls/tls_internal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_internal.h,v 1.54 2017/04/05 03:13:53 beck Exp $ */
+/* $OpenBSD: tls_internal.h,v 1.55 2017/04/05 03:19:22 beck Exp $ */
/*
* Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -110,6 +110,9 @@ struct tls_conninfo {
char *issuer;
char *subject;
+ u_int8_t *peer_cert;
+ size_t peer_cert_len;
+
time_t notbefore;
time_t notafter;
};
@@ -166,6 +169,7 @@ struct tls {
struct tls_sni_ctx *sni_ctx;
X509 *ssl_peer_cert;
+ STACK_OF(X509) *ssl_peer_chain;
struct tls_conninfo *conninfo;
@@ -237,6 +241,7 @@ struct tls_ocsp *tls_ocsp_setup_from_peer(struct tls *ctx);
int tls_hex_string(const unsigned char *_in, size_t _inlen, char **_out,
size_t *_outlen);
int tls_cert_hash(X509 *_cert, char **_hash);
+void tls_config_skip_private_key_check(struct tls_config *config);
__END_HIDDEN_DECLS
diff --git a/lib/libtls/tls_peer.c b/lib/libtls/tls_peer.c
index 802a9c2780d..1a9065dfb1a 100644
--- a/lib/libtls/tls_peer.c
+++ b/lib/libtls/tls_peer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_peer.c,v 1.6 2016/08/22 17:08:10 jsing Exp $ */
+/* $OpenBSD: tls_peer.c,v 1.7 2017/04/05 03:19:22 beck Exp $ */
/*
* Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2015 Bob Beck <beck@openbsd.org>
@@ -81,3 +81,14 @@ tls_peer_cert_notafter(struct tls *ctx)
return (ctx->conninfo->notafter);
}
+const uint8_t *
+tls_peer_cert_chain_pem(struct tls *ctx, size_t *size)
+{
+ if (ctx->ssl_peer_cert == NULL)
+ return (NULL);
+ if (ctx->conninfo == NULL)
+ return (NULL);
+ *size = ctx->conninfo->peer_cert_len;
+ return (ctx->conninfo->peer_cert);
+}
+