1 /* $OpenBSD: tls_conninfo.c,v 1.16 2017/08/27 01:39:26 beck 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"
26 int ASN1_time_tm_clamp_notafter(struct tm
*tm
);
29 tls_hex_string(const unsigned char *in
, size_t inlen
, char **out
,
32 static const char hex
[] = "0123456789abcdef";
39 if (inlen
>= SIZE_MAX
)
41 if ((*out
= reallocarray(NULL
, inlen
+ 1, 2)) == NULL
)
46 for (i
= 0; i
< inlen
; i
++) {
47 p
[len
++] = hex
[(in
[i
] >> 4) & 0x0f];
48 p
[len
++] = hex
[in
[i
] & 0x0f];
59 tls_get_peer_cert_hash(struct tls
*ctx
, char **hash
)
62 if (ctx
->ssl_peer_cert
== NULL
)
65 if (tls_cert_hash(ctx
->ssl_peer_cert
, hash
) == -1) {
66 tls_set_errorx(ctx
, "unable to compute peer certificate hash - out of memory");
74 tls_get_peer_cert_issuer(struct tls
*ctx
, char **issuer
)
76 X509_NAME
*name
= NULL
;
79 if (ctx
->ssl_peer_cert
== NULL
)
81 if ((name
= X509_get_issuer_name(ctx
->ssl_peer_cert
)) == NULL
)
83 *issuer
= X509_NAME_oneline(name
, 0, 0);
90 tls_get_peer_cert_subject(struct tls
*ctx
, char **subject
)
92 X509_NAME
*name
= NULL
;
95 if (ctx
->ssl_peer_cert
== NULL
)
97 if ((name
= X509_get_subject_name(ctx
->ssl_peer_cert
)) == NULL
)
99 *subject
= X509_NAME_oneline(name
, 0, 0);
100 if (*subject
== NULL
)
106 tls_get_peer_cert_times(struct tls
*ctx
, time_t *notbefore
,
109 struct tm before_tm
, after_tm
;
110 ASN1_TIME
*before
, *after
;
112 if (ctx
->ssl_peer_cert
== NULL
)
115 memset(&before_tm
, 0, sizeof(before_tm
));
116 memset(&after_tm
, 0, sizeof(after_tm
));
118 if ((before
= X509_get_notBefore(ctx
->ssl_peer_cert
)) == NULL
)
120 if ((after
= X509_get_notAfter(ctx
->ssl_peer_cert
)) == NULL
)
122 if (ASN1_time_parse(before
->data
, before
->length
, &before_tm
, 0) == -1)
124 if (ASN1_time_parse(after
->data
, after
->length
, &after_tm
, 0) == -1)
126 if (!ASN1_time_tm_clamp_notafter(&after_tm
))
128 if ((*notbefore
= timegm(&before_tm
)) == -1)
130 if ((*notafter
= timegm(&after_tm
)) == -1)
140 tls_get_peer_cert_info(struct tls
*ctx
)
142 if (ctx
->ssl_peer_cert
== NULL
)
145 if (tls_get_peer_cert_hash(ctx
, &ctx
->conninfo
->hash
) == -1)
147 if (tls_get_peer_cert_subject(ctx
, &ctx
->conninfo
->subject
) == -1)
149 if (tls_get_peer_cert_issuer(ctx
, &ctx
->conninfo
->issuer
) == -1)
151 if (tls_get_peer_cert_times(ctx
, &ctx
->conninfo
->notbefore
,
152 &ctx
->conninfo
->notafter
) == -1)
162 tls_conninfo_alpn_proto(struct tls
*ctx
)
164 const unsigned char *p
;
167 free(ctx
->conninfo
->alpn
);
168 ctx
->conninfo
->alpn
= NULL
;
170 SSL_get0_alpn_selected(ctx
->ssl_conn
, &p
, &len
);
172 if ((ctx
->conninfo
->alpn
= malloc(len
+ 1)) == NULL
)
174 memcpy(ctx
->conninfo
->alpn
, p
, len
);
175 ctx
->conninfo
->alpn
[len
] = '\0';
182 tls_conninfo_cert_pem(struct tls
*ctx
)
186 BUF_MEM
*bptr
= NULL
;
188 if (ctx
->conninfo
== NULL
)
190 if (ctx
->ssl_peer_cert
== NULL
)
192 if ((membio
= BIO_new(BIO_s_mem()))== NULL
)
196 * We have to write the peer cert out separately, because
197 * the certificate chain may or may not contain it.
199 if (!PEM_write_bio_X509(membio
, ctx
->ssl_peer_cert
))
201 for (i
= 0; i
< sk_X509_num(ctx
->ssl_peer_chain
); i
++) {
202 X509
*chaincert
= sk_X509_value(ctx
->ssl_peer_chain
, i
);
203 if (chaincert
!= ctx
->ssl_peer_cert
&&
204 !PEM_write_bio_X509(membio
, chaincert
))
208 BIO_get_mem_ptr(membio
, &bptr
);
209 free(ctx
->conninfo
->peer_cert
);
210 ctx
->conninfo
->peer_cert_len
= 0;
211 if ((ctx
->conninfo
->peer_cert
= malloc(bptr
->length
)) == NULL
)
213 ctx
->conninfo
->peer_cert_len
= bptr
->length
;
214 memcpy(ctx
->conninfo
->peer_cert
, bptr
->data
,
215 ctx
->conninfo
->peer_cert_len
);
217 /* BIO_free() will kill BUF_MEM - because we have not set BIO_NOCLOSE */
225 tls_conninfo_populate(struct tls
*ctx
)
229 tls_conninfo_free(ctx
->conninfo
);
231 if ((ctx
->conninfo
= calloc(1, sizeof(struct tls_conninfo
))) == NULL
) {
232 tls_set_errorx(ctx
, "out of memory");
236 if (tls_conninfo_alpn_proto(ctx
) == -1)
239 if ((tmp
= SSL_get_cipher(ctx
->ssl_conn
)) == NULL
)
241 ctx
->conninfo
->cipher
= strdup(tmp
);
242 if (ctx
->conninfo
->cipher
== NULL
)
245 if (ctx
->servername
!= NULL
) {
246 if ((ctx
->conninfo
->servername
=
247 strdup(ctx
->servername
)) == NULL
)
251 if ((tmp
= SSL_get_version(ctx
->ssl_conn
)) == NULL
)
253 ctx
->conninfo
->version
= strdup(tmp
);
254 if (ctx
->conninfo
->version
== NULL
)
257 if (tls_get_peer_cert_info(ctx
) == -1)
260 if (tls_conninfo_cert_pem(ctx
) == -1)
266 tls_conninfo_free(ctx
->conninfo
);
267 ctx
->conninfo
= NULL
;
273 tls_conninfo_free(struct tls_conninfo
*conninfo
)
275 if (conninfo
== NULL
)
278 free(conninfo
->alpn
);
279 conninfo
->alpn
= NULL
;
280 free(conninfo
->cipher
);
281 conninfo
->cipher
= NULL
;
282 free(conninfo
->servername
);
283 conninfo
->servername
= NULL
;
284 free(conninfo
->version
);
285 conninfo
->version
= NULL
;
287 free(conninfo
->hash
);
288 conninfo
->hash
= NULL
;
289 free(conninfo
->issuer
);
290 conninfo
->issuer
= NULL
;
291 free(conninfo
->subject
);
292 conninfo
->subject
= NULL
;
294 free(conninfo
->peer_cert
);
295 conninfo
->peer_cert
= NULL
;
296 conninfo
->peer_cert_len
= 0;
302 tls_conn_alpn_selected(struct tls
*ctx
)
304 if (ctx
->conninfo
== NULL
)
306 return (ctx
->conninfo
->alpn
);
310 tls_conn_cipher(struct tls
*ctx
)
312 if (ctx
->conninfo
== NULL
)
314 return (ctx
->conninfo
->cipher
);
318 tls_conn_servername(struct tls
*ctx
)
320 if (ctx
->conninfo
== NULL
)
322 return (ctx
->conninfo
->servername
);
326 tls_conn_version(struct tls
*ctx
)
328 if (ctx
->conninfo
== NULL
)
330 return (ctx
->conninfo
->version
);