summaryrefslogtreecommitdiff
path: root/src/lib/libtls/tls_conninfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libtls/tls_conninfo.c')
-rw-r--r--src/lib/libtls/tls_conninfo.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/lib/libtls/tls_conninfo.c b/src/lib/libtls/tls_conninfo.c
new file mode 100644
index 0000000000..267a8747c9
--- /dev/null
+++ b/src/lib/libtls/tls_conninfo.c
@@ -0,0 +1,149 @@
1/* $OpenBSD: tls_conninfo.c,v 1.1 2015/09/12 21:00:38 beck Exp $ */
2/*
3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2015 Bob Beck <beck@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <stdio.h>
20
21#include <openssl/x509.h>
22
23#include <tls.h>
24#include "tls_internal.h"
25
26static int
27tls_hex_string(const unsigned char *in, size_t inlen, char **out,
28 size_t *outlen)
29{
30 static const char hex[] = "0123456789abcdef";
31 size_t i, len;
32 char *p;
33
34 if (outlen != NULL)
35 *outlen = 0;
36
37 if (inlen >= SIZE_MAX)
38 return (-1);
39 if ((*out = reallocarray(NULL, inlen + 1, 2)) == NULL)
40 return (-1);
41
42 p = *out;
43 len = 0;
44 for (i = 0; i < inlen; i++) {
45 p[len++] = hex[(in[i] >> 4) & 0x0f];
46 p[len++] = hex[in[i] & 0x0f];
47 }
48 p[len++] = 0;
49
50 if (outlen != NULL)
51 *outlen = len;
52
53 return (0);
54}
55
56static int
57tls_get_peer_cert_hash(struct tls *ctx, char **hash)
58{
59 char d[EVP_MAX_MD_SIZE], *dhex = NULL;
60 int dlen, rv = -1;
61
62 *hash = NULL;
63 if (ctx->ssl_peer_cert == NULL)
64 return (0);
65
66 if (X509_digest(ctx->ssl_peer_cert, EVP_sha256(), d, &dlen) != 1) {
67 tls_set_errorx(ctx, "digest failed");
68 goto err;
69 }
70
71 if (tls_hex_string(d, dlen, &dhex, NULL) != 0) {
72 tls_set_errorx(ctx, "digest hex string failed");
73 goto err;
74 }
75
76 if (asprintf(hash, "SHA256:%s", dhex) == -1) {
77 tls_set_errorx(ctx, "out of memory");
78 *hash = NULL;
79 goto err;
80 }
81
82 rv = 0;
83
84err:
85 free(dhex);
86
87 return (rv);
88}
89
90static int
91tls_get_peer_cert_issuer(struct tls *ctx, char **issuer)
92{
93 X509_NAME *name = NULL;
94
95 *issuer = NULL;
96 if (ctx->ssl_peer_cert == NULL)
97 return (-1);
98 if ((name = X509_get_issuer_name(ctx->ssl_peer_cert)) == NULL)
99 return (-1);
100 *issuer = X509_NAME_oneline(name, 0, 0);
101 if (*issuer == NULL)
102 return (-1);
103 return (0);
104}
105
106static int
107tls_get_peer_cert_subject(struct tls *ctx, char **subject)
108{
109 X509_NAME *name = NULL;
110
111 *subject = NULL;
112 if (ctx->ssl_peer_cert == NULL)
113 return (-1);
114 if ((name = X509_get_subject_name(ctx->ssl_peer_cert)) == NULL)
115 return (-1);
116 *subject = X509_NAME_oneline(name, 0, 0);
117 if (*subject == NULL)
118 return (-1);
119 return (0);
120}
121
122int
123tls_get_conninfo(struct tls *ctx) {
124 int rv = -1;
125 if (ctx->ssl_peer_cert != NULL) {
126 if (tls_get_peer_cert_hash(ctx, &ctx->conninfo->hash) == -1)
127 goto err;
128 if (tls_get_peer_cert_subject(ctx, &ctx->conninfo->subject)
129 == -1)
130 goto err;
131 if (tls_get_peer_cert_issuer(ctx, &ctx->conninfo->issuer) == -1)
132 goto err;
133 }
134 rv = 0;
135err:
136 return (rv);
137}
138
139void
140tls_free_conninfo(struct tls_conninfo *conninfo) {
141 if (conninfo != NULL) {
142 free(conninfo->hash);
143 conninfo->hash = NULL;
144 free(conninfo->subject);
145 conninfo->subject = NULL;
146 free(conninfo->issuer);
147 conninfo->issuer = NULL;
148 }
149}