1 /* $OpenBSD: tls_conninfo.c,v 1.13 2017/01/09 15:31:20 jsing Exp $ */
3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2015 Bob Beck <beck@openbsd.org>
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.
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.
21 #include <openssl/x509.h>
24 #include "tls_internal.h"
27 tls_hex_string(const unsigned char *in
, size_t inlen
, char **out
,
30 static const char hex
[] = "0123456789abcdef";
37 if (inlen
>= SIZE_MAX
)
39 if ((*out
= reallocarray(NULL
, inlen
+ 1, 2)) == NULL
)
44 for (i
= 0; i
< inlen
; i
++) {
45 p
[len
++] = hex
[(in
[i
] >> 4) & 0x0f];
46 p
[len
++] = hex
[in
[i
] & 0x0f];
57 tls_get_peer_cert_hash(struct tls
*ctx
, char **hash
)
59 char d
[EVP_MAX_MD_SIZE
], *dhex
= NULL
;
63 if (ctx
->ssl_peer_cert
== NULL
)
66 if (X509_digest(ctx
->ssl_peer_cert
, EVP_sha256(), d
, &dlen
) != 1) {
67 tls_set_errorx(ctx
, "digest failed");
71 if (tls_hex_string(d
, dlen
, &dhex
, NULL
) != 0) {
72 tls_set_errorx(ctx
, "digest hex string failed");
76 if (asprintf(hash
, "SHA256:%s", dhex
) == -1) {
77 tls_set_errorx(ctx
, "out of memory");
91 tls_get_peer_cert_issuer(struct tls
*ctx
, char **issuer
)
93 X509_NAME
*name
= NULL
;
96 if (ctx
->ssl_peer_cert
== NULL
)
98 if ((name
= X509_get_issuer_name(ctx
->ssl_peer_cert
)) == NULL
)
100 *issuer
= X509_NAME_oneline(name
, 0, 0);
107 tls_get_peer_cert_subject(struct tls
*ctx
, char **subject
)
109 X509_NAME
*name
= NULL
;
112 if (ctx
->ssl_peer_cert
== NULL
)
114 if ((name
= X509_get_subject_name(ctx
->ssl_peer_cert
)) == NULL
)
116 *subject
= X509_NAME_oneline(name
, 0, 0);
117 if (*subject
== NULL
)
123 tls_get_peer_cert_times(struct tls
*ctx
, time_t *notbefore
,
126 struct tm before_tm
, after_tm
;
127 ASN1_TIME
*before
, *after
;
129 if (ctx
->ssl_peer_cert
== NULL
)
132 memset(&before_tm
, 0, sizeof(before_tm
));
133 memset(&after_tm
, 0, sizeof(after_tm
));
135 if ((before
= X509_get_notBefore(ctx
->ssl_peer_cert
)) == NULL
)
137 if ((after
= X509_get_notAfter(ctx
->ssl_peer_cert
)) == NULL
)
139 if (ASN1_time_parse(before
->data
, before
->length
, &before_tm
, 0) == -1)
141 if (ASN1_time_parse(after
->data
, after
->length
, &after_tm
, 0) == -1)
143 if ((*notbefore
= timegm(&before_tm
)) == -1)
145 if ((*notafter
= timegm(&after_tm
)) == -1)
155 tls_get_peer_cert_info(struct tls
*ctx
)
157 if (ctx
->ssl_peer_cert
== NULL
)
160 if (tls_get_peer_cert_hash(ctx
, &ctx
->conninfo
->hash
) == -1)
162 if (tls_get_peer_cert_subject(ctx
, &ctx
->conninfo
->subject
) == -1)
164 if (tls_get_peer_cert_issuer(ctx
, &ctx
->conninfo
->issuer
) == -1)
166 if (tls_get_peer_cert_times(ctx
, &ctx
->conninfo
->notbefore
,
167 &ctx
->conninfo
->notafter
) == -1)
177 tls_conninfo_alpn_proto(struct tls
*ctx
)
179 const unsigned char *p
;
182 free(ctx
->conninfo
->alpn
);
183 ctx
->conninfo
->alpn
= NULL
;
185 SSL_get0_alpn_selected(ctx
->ssl_conn
, &p
, &len
);
187 if ((ctx
->conninfo
->alpn
= malloc(len
+ 1)) == NULL
)
189 memcpy(ctx
->conninfo
->alpn
, p
, len
);
190 ctx
->conninfo
->alpn
[len
] = '\0';
197 tls_conninfo_populate(struct tls
*ctx
)
201 tls_conninfo_free(ctx
->conninfo
);
203 if ((ctx
->conninfo
= calloc(1, sizeof(struct tls_conninfo
))) == NULL
) {
204 tls_set_errorx(ctx
, "out of memory");
208 if (tls_conninfo_alpn_proto(ctx
) == -1)
211 if ((tmp
= SSL_get_cipher(ctx
->ssl_conn
)) == NULL
)
213 ctx
->conninfo
->cipher
= strdup(tmp
);
214 if (ctx
->conninfo
->cipher
== NULL
)
217 if (ctx
->servername
!= NULL
) {
218 if ((ctx
->conninfo
->servername
=
219 strdup(ctx
->servername
)) == NULL
)
223 if ((tmp
= SSL_get_version(ctx
->ssl_conn
)) == NULL
)
225 ctx
->conninfo
->version
= strdup(tmp
);
226 if (ctx
->conninfo
->version
== NULL
)
229 if (tls_get_peer_cert_info(ctx
) == -1)
235 tls_conninfo_free(ctx
->conninfo
);
236 ctx
->conninfo
= NULL
;
242 tls_conninfo_free(struct tls_conninfo
*conninfo
)
244 if (conninfo
== NULL
)
247 free(conninfo
->alpn
);
248 conninfo
->alpn
= NULL
;
249 free(conninfo
->cipher
);
250 conninfo
->cipher
= NULL
;
251 free(conninfo
->servername
);
252 conninfo
->servername
= NULL
;
253 free(conninfo
->version
);
254 conninfo
->version
= NULL
;
256 free(conninfo
->hash
);
257 conninfo
->hash
= NULL
;
258 free(conninfo
->issuer
);
259 conninfo
->issuer
= NULL
;
260 free(conninfo
->subject
);
261 conninfo
->subject
= NULL
;
267 tls_conn_alpn_selected(struct tls
*ctx
)
269 if (ctx
->conninfo
== NULL
)
271 return (ctx
->conninfo
->alpn
);
275 tls_conn_cipher(struct tls
*ctx
)
277 if (ctx
->conninfo
== NULL
)
279 return (ctx
->conninfo
->cipher
);
283 tls_conn_servername(struct tls
*ctx
)
285 if (ctx
->conninfo
== NULL
)
287 return (ctx
->conninfo
->servername
);
291 tls_conn_version(struct tls
*ctx
)
293 if (ctx
->conninfo
== NULL
)
295 return (ctx
->conninfo
->version
);