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
major=15
-minor=4
+minor=5
-/* $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>
*
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;
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)
-/* $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>
*
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);
-/* $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>
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)
{
if (tls_get_peer_cert_info(ctx) == -1)
goto err;
+ if (tls_conninfo_cert_pem(ctx) == -1)
+ goto err;
+
return (0);
err:
free(conninfo->subject);
conninfo->subject = NULL;
+ free(conninfo->peer_cert);
+ conninfo->peer_cert = NULL;
+ conninfo->peer_cert_len = 0;
+
free(conninfo);
}
-/* $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>
char *issuer;
char *subject;
+ u_int8_t *peer_cert;
+ size_t peer_cert_len;
+
time_t notbefore;
time_t notafter;
};
struct tls_sni_ctx *sni_ctx;
X509 *ssl_peer_cert;
+ STACK_OF(X509) *ssl_peer_chain;
struct tls_conninfo *conninfo;
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
-/* $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>
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);
+}
+