From f00a4e850dc965820597bc422de6d60fd42a1969 Mon Sep 17 00:00:00 2001 From: beck Date: Wed, 7 Oct 2015 23:33:38 +0000 Subject: [PATCH] Add tls_peer_cert_notbefore and tls_peer_cert_notafter to expose peer certificate validity times for tls connections. ok jsing@ --- lib/libtls/Makefile | 4 +++- lib/libtls/tls.h | 5 ++++- lib/libtls/tls_conninfo.c | 36 +++++++++++++++++++++++++++++++++++- lib/libtls/tls_init.3 | 34 ++++++++++++++++++++++++++++++---- lib/libtls/tls_internal.h | 6 +++++- lib/libtls/tls_peer.c | 22 +++++++++++++++++++++- 6 files changed, 98 insertions(+), 9 deletions(-) diff --git a/lib/libtls/Makefile b/lib/libtls/Makefile index 679aabb9eda..5807780a843 100644 --- a/lib/libtls/Makefile +++ b/lib/libtls/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.21 2015/09/14 16:16:38 jsing Exp $ +# $OpenBSD: Makefile,v 1.22 2015/10/07 23:33:38 beck Exp $ CFLAGS+= -Wall -Werror -Wimplicit CFLAGS+= -DLIBRESSL_INTERNAL @@ -53,6 +53,8 @@ MLINKS+=tls_init.3 tls_peer_cert_contains_name.3 MLINKS+=tls_init.3 tls_peer_cert_issuer.3 MLINKS+=tls_init.3 tls_peer_cert_subject.3 MLINKS+=tls_init.3 tls_peer_cert_hash.3 +MLINKS+=tls_init.3 tls_peer_cert_notbefore.3 +MLINKS+=tls_init.3 tls_peer_cert_notafter.3 MLINKS+=tls_init.3 tls_conn_version.3 MLINKS+=tls_init.3 tls_conn_cipher.3 MLINKS+=tls_init.3 tls_load_file.3 diff --git a/lib/libtls/tls.h b/lib/libtls/tls.h index f6e489d8e4e..e5c31ed5813 100644 --- a/lib/libtls/tls.h +++ b/lib/libtls/tls.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls.h,v 1.25 2015/10/01 10:27:34 bcook Exp $ */ +/* $OpenBSD: tls.h,v 1.26 2015/10/07 23:33:38 beck Exp $ */ /* * Copyright (c) 2014 Joel Sing * @@ -108,6 +108,9 @@ int tls_peer_cert_contains_name(struct tls *ctx, const char *name); 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); +time_t tls_peer_cert_notbefore(struct tls *ctx); +time_t tls_peer_cert_notafter(struct tls *ctx); + const char * tls_conn_version(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 48bb89fe635..1e134bfe598 100644 --- a/lib/libtls/tls_conninfo.c +++ b/lib/libtls/tls_conninfo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_conninfo.c,v 1.4 2015/10/07 23:25:45 beck Exp $ */ +/* $OpenBSD: tls_conninfo.c,v 1.5 2015/10/07 23:33:38 beck Exp $ */ /* * Copyright (c) 2015 Joel Sing * Copyright (c) 2015 Bob Beck @@ -119,6 +119,37 @@ tls_get_peer_cert_subject(struct tls *ctx, char **subject) return (0); } +static int +tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore, time_t *notafter) +{ + struct tm before_tm, after_tm; + ASN1_TIME *before, *after; + int rv = -1; + + memset(&before_tm, 0, sizeof(before_tm)); + memset(&after_tm, 0, sizeof(after_tm)); + + if (ctx->ssl_peer_cert != NULL) { + if ((before = X509_get_notBefore(ctx->ssl_peer_cert)) == NULL) + goto err; + if ((after = X509_get_notAfter(ctx->ssl_peer_cert)) == NULL) + goto err; + if (asn1_time_parse(before->data, before->length, &before_tm, 0) + == -1) + goto err; + if (asn1_time_parse(after->data, after->length, &after_tm, 0) + == -1) + goto err; + if ((*notbefore = timegm(&before_tm)) == -1) + goto err; + if ((*notafter = timegm(&after_tm)) == -1) + goto err; + } + rv = 0; + err: + return (rv); +} + int tls_get_conninfo(struct tls *ctx) { const char * tmp; @@ -130,6 +161,9 @@ tls_get_conninfo(struct tls *ctx) { goto err; if (tls_get_peer_cert_issuer(ctx, &ctx->conninfo->issuer) == -1) goto err; + if (tls_get_peer_cert_times(ctx, &ctx->conninfo->notbefore, + &ctx->conninfo->notafter) == -1) + goto err; } if ((tmp = SSL_get_version(ctx->ssl_conn)) == NULL) goto err; diff --git a/lib/libtls/tls_init.3 b/lib/libtls/tls_init.3 index bf34b714662..d10c7cf73a2 100644 --- a/lib/libtls/tls_init.3 +++ b/lib/libtls/tls_init.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tls_init.3,v 1.49 2015/09/14 21:23:00 jmc Exp $ +.\" $OpenBSD: tls_init.3,v 1.50 2015/10/07 23:33:38 beck Exp $ .\" .\" Copyright (c) 2014 Ted Unangst .\" @@ -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 14 2015 $ +.Dd $Mdocdate: October 7 2015 $ .Dt TLS_INIT 3 .Os .Sh NAME @@ -49,6 +49,8 @@ .Nm tls_peer_cert_issuer , .Nm tls_peer_cert_subject , .Nm tls_peer_cert_hash , +.Nm tls_peer_cert_notbefore , +.Nm tls_peer_cert_notafter , .Nm tls_conn_version , .Nm tls_conn_cipher , .Nm tls_load_file , @@ -132,6 +134,10 @@ .Fn tls_peer_cert_subject "struct tls *ctx" .Ft "const char *" .Fn tls_peer_cert_hash "struct tls *ctx" +.Ft "time_t" +.Fn tls_peer_cert_notbefore "struct tls *ctx" +.Ft "time_t" +.Fn tls_peer_cert_notafter "struct tls *ctx" .Ft "const char *" .Fn tls_conn_version "struct tls *ctx" .Ft "const char *" @@ -431,6 +437,22 @@ h=$(openssl x509 -outform der -in mycert.crt | sha256) printf "SHA256:${h}\\n" .Ed .It +.Fn tls_peer_cert_notbefore +returns the time corresponding to the start of the validity period of +the peer certificate from +.Ar ctx . +.Fn tls_peer_cert_notbefore +will only succeed after the handshake is complete. +.Em (Server and client) +.It +.Fn tls_peer_cert_notafter +returns the time corresponding to the end of the validity period of +the peer certificate from +.Ar ctx . +.Fn tls_peer_cert_notafter +will only succeed after the handshake is complete. +.Em (Server and client) +.It .Fn tls_conn_version returns a string corresponding to a TLS version negotiated with the peer @@ -554,10 +576,14 @@ The and .Fn tls_peer_cert_contains_name functions return 1 if the check succeeds, and 0 if it does not. +Functions that return a +.Vt time_t +will return a time in epoch-seconds on success, and -1 on error. +Functions that return a +.Vt ssize_t +will return a size on success, and -1 on error. All other functions that return .Vt int -or -.Vt ssize_t will return 0 on success and -1 on error. Functions that return a pointer will return NULL on error, which indicates an out of memory condition. diff --git a/lib/libtls/tls_internal.h b/lib/libtls/tls_internal.h index b070b326c11..b203b5662ed 100644 --- a/lib/libtls/tls_internal.h +++ b/lib/libtls/tls_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_internal.h,v 1.25 2015/09/29 13:10:53 jsing Exp $ */ +/* $OpenBSD: tls_internal.h,v 1.26 2015/10/07 23:33:38 beck Exp $ */ /* * Copyright (c) 2014 Jeremie Courreges-Anglas * Copyright (c) 2014 Joel Sing @@ -65,6 +65,8 @@ struct tls_conninfo { char *fingerprint; char *version; char *cipher; + time_t notbefore; + time_t notafter; }; #define TLS_CLIENT (1 << 0) @@ -113,4 +115,6 @@ int tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, int tls_get_conninfo(struct tls *ctx); void tls_free_conninfo(struct tls_conninfo *conninfo); +int asn1_time_parse(const char *, size_t, struct tm *, int); + #endif /* HEADER_TLS_INTERNAL_H */ diff --git a/lib/libtls/tls_peer.c b/lib/libtls/tls_peer.c index 3145e500c47..8a74613ef82 100644 --- a/lib/libtls/tls_peer.c +++ b/lib/libtls/tls_peer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_peer.c,v 1.4 2015/09/12 21:00:38 beck Exp $ */ +/* $OpenBSD: tls_peer.c,v 1.5 2015/10/07 23:33:38 beck Exp $ */ /* * Copyright (c) 2015 Joel Sing * Copyright (c) 2015 Bob Beck @@ -61,3 +61,23 @@ tls_peer_cert_contains_name(struct tls *ctx, const char *name) return (tls_check_name(ctx, ctx->ssl_peer_cert, name) == 0); } +time_t +tls_peer_cert_notbefore(struct tls *ctx) +{ + if (ctx->ssl_peer_cert == NULL) + return (-1); + if (ctx->conninfo == NULL) + return (-1); + return (ctx->conninfo->notbefore); +} + +time_t +tls_peer_cert_notafter(struct tls *ctx) +{ + if (ctx->ssl_peer_cert == NULL) + return (-1); + if (ctx->conninfo == NULL) + return (-1); + return (ctx->conninfo->notafter); +} + -- 2.20.1