diff options
-rw-r--r-- | lib/libtls/tls.c | 13 | ||||
-rw-r--r-- | lib/libtls/tls_conninfo.c | 147 | ||||
-rw-r--r-- | lib/libtls/tls_internal.h | 6 |
3 files changed, 97 insertions, 69 deletions
diff --git a/lib/libtls/tls.c b/lib/libtls/tls.c index df610fe2384..85faedd56de 100644 --- a/lib/libtls/tls.c +++ b/lib/libtls/tls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls.c,v 1.47 2016/08/22 14:51:37 jsing Exp $ */ +/* $OpenBSD: tls.c,v 1.48 2016/08/22 17:12:35 jsing Exp $ */ /* * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> * @@ -387,7 +387,9 @@ tls_free(struct tls *ctx) { if (ctx == NULL) return; + tls_reset(ctx); + free(ctx); } @@ -414,8 +416,7 @@ tls_reset(struct tls *ctx) ctx->error.msg = NULL; ctx->error.num = -1; - tls_free_conninfo(ctx->conninfo); - free(ctx->conninfo); + tls_conninfo_free(ctx->conninfo); ctx->conninfo = NULL; for (sni = ctx->sni_ctx; sni != NULL; sni = nsni) { @@ -485,10 +486,6 @@ tls_handshake(struct tls *ctx) goto out; } - if (ctx->conninfo == NULL && - (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) @@ -496,7 +493,7 @@ tls_handshake(struct tls *ctx) if (rv == 0) { ctx->ssl_peer_cert = SSL_get_peer_certificate(ctx->ssl_conn); - if (tls_get_conninfo(ctx) == -1) + if (tls_conninfo_populate(ctx) == -1) rv = -1; } out: diff --git a/lib/libtls/tls_conninfo.c b/lib/libtls/tls_conninfo.c index 281af798665..5882a19cee8 100644 --- a/lib/libtls/tls_conninfo.c +++ b/lib/libtls/tls_conninfo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_conninfo.c,v 1.10 2016/08/22 14:55:59 jsing Exp $ */ +/* $OpenBSD: tls_conninfo.c,v 1.11 2016/08/22 17:12:35 jsing Exp $ */ /* * Copyright (c) 2015 Joel Sing <jsing@openbsd.org> * Copyright (c) 2015 Bob Beck <beck@openbsd.org> @@ -120,34 +120,57 @@ tls_get_peer_cert_subject(struct tls *ctx, char **subject) } static int -tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore, time_t *notafter) +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; + + if (ctx->ssl_peer_cert == NULL) + return (-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; + 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; + + return (0); + err: - return (rv); + return (-1); +} + +static int +tls_get_peer_cert_info(struct tls *ctx) +{ + if (ctx->ssl_peer_cert == NULL) + return (0); + + 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; + if (tls_get_peer_cert_times(ctx, &ctx->conninfo->notbefore, + &ctx->conninfo->notafter) == -1) + goto err; + + return (0); + + err: + return (-1); } static int @@ -171,63 +194,71 @@ tls_conninfo_alpn_proto(struct tls *ctx) } int -tls_get_conninfo(struct tls *ctx) +tls_conninfo_populate(struct tls *ctx) { - const char * tmp; + const char *tmp; - 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; - 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) + tls_conninfo_free(ctx->conninfo); + + if ((ctx->conninfo = calloc(1, sizeof(struct tls_conninfo))) == NULL) { + tls_set_errorx(ctx, "out of memory"); goto err; - ctx->conninfo->version = strdup(tmp); - if (ctx->conninfo->version == NULL) + } + + if (tls_conninfo_alpn_proto(ctx) == -1) goto err; + if ((tmp = SSL_get_cipher(ctx->ssl_conn)) == NULL) goto err; ctx->conninfo->cipher = strdup(tmp); if (ctx->conninfo->cipher == NULL) goto err; - if (tls_conninfo_alpn_proto(ctx) == -1) - goto err; + if (ctx->servername != NULL) { if ((ctx->conninfo->servername = strdup(ctx->servername)) == NULL) goto err; } + if ((tmp = SSL_get_version(ctx->ssl_conn)) == NULL) + goto err; + ctx->conninfo->version = strdup(tmp); + if (ctx->conninfo->version == NULL) + goto err; + + if (tls_get_peer_cert_info(ctx) == -1) + goto err; + return (0); -err: - tls_free_conninfo(ctx->conninfo); + + err: + tls_conninfo_free(ctx->conninfo); + ctx->conninfo = NULL; + return (-1); } void -tls_free_conninfo(struct tls_conninfo *conninfo) +tls_conninfo_free(struct tls_conninfo *conninfo) { - if (conninfo != NULL) { - free(conninfo->alpn); - conninfo->alpn = NULL; - free(conninfo->hash); - conninfo->hash = NULL; - free(conninfo->subject); - conninfo->subject = NULL; - free(conninfo->issuer); - conninfo->issuer = NULL; - free(conninfo->version); - conninfo->version = NULL; - free(conninfo->cipher); - conninfo->cipher = NULL; - } + if (conninfo == NULL) + return; + + free(conninfo->alpn); + conninfo->alpn = NULL; + free(conninfo->cipher); + conninfo->cipher = NULL; + free(conninfo->version); + conninfo->version = NULL; + + free(conninfo->hash); + conninfo->hash = NULL; + free(conninfo->issuer); + conninfo->issuer = NULL; + free(conninfo->subject); + conninfo->subject = NULL; + + free(conninfo); } const char * @@ -253,7 +284,7 @@ tls_conn_servername(struct tls *ctx) return (NULL); return (ctx->conninfo->servername); } - + const char * tls_conn_version(struct tls *ctx) { diff --git a/lib/libtls/tls_internal.h b/lib/libtls/tls_internal.h index 3fcc7a021fa..c7bf50af832 100644 --- a/lib/libtls/tls_internal.h +++ b/lib/libtls/tls_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_internal.h,v 1.41 2016/08/22 14:55:59 jsing Exp $ */ +/* $OpenBSD: tls_internal.h,v 1.42 2016/08/22 17:12:35 jsing Exp $ */ /* * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> @@ -162,8 +162,8 @@ int tls_set_errorx(struct tls *ctx, const char *fmt, ...) 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); +int tls_conninfo_populate(struct tls *ctx); +void tls_conninfo_free(struct tls_conninfo *conninfo); int asn1_time_parse(const char *, size_t, struct tm *, int); |