1 /* $OpenBSD: tls_conninfo.c,v 1.27 2024/03/26 06:31:22 jsing 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 #include <string.h> 21 22 #include <openssl/posix_time.h> 23 #include <openssl/x509.h> 24 25 #include <tls.h> 26 #include "tls_internal.h" 27 28 static int 29 tls_convert_notafter(struct tm *tm, time_t *out_time) 30 { 31 int64_t posix_time; 32 33 /* OPENSSL_timegm() fails if tm is not representable in a time_t */ 34 if (OPENSSL_timegm(tm, out_time)) 35 return 1; 36 if (!OPENSSL_tm_to_posix(tm, &posix_time)) 37 return 0; 38 if (posix_time < INT32_MIN) 39 return 0; 40 *out_time = (posix_time > INT32_MAX) ? INT32_MAX : posix_time; 41 return 1; 42 } 43 44 int 45 tls_hex_string(const unsigned char *in, size_t inlen, char **out, 46 size_t *outlen) 47 { 48 static const char hex[] = "0123456789abcdef"; 49 size_t i, len; 50 char *p; 51 52 if (outlen != NULL) 53 *outlen = 0; 54 55 if (inlen >= SIZE_MAX) 56 return (-1); 57 if ((*out = reallocarray(NULL, inlen + 1, 2)) == NULL) 58 return (-1); 59 60 p = *out; 61 len = 0; 62 for (i = 0; i < inlen; i++) { 63 p[len++] = hex[(in[i] >> 4) & 0x0f]; 64 p[len++] = hex[in[i] & 0x0f]; 65 } 66 p[len++] = 0; 67 68 if (outlen != NULL) 69 *outlen = len; 70 71 return (0); 72 } 73 74 static int 75 tls_get_peer_cert_hash(struct tls *ctx, char **hash) 76 { 77 *hash = NULL; 78 if (ctx->ssl_peer_cert == NULL) 79 return (0); 80 81 if (tls_cert_hash(ctx->ssl_peer_cert, hash) == -1) { 82 tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY, "out of memory"); 83 *hash = NULL; 84 return -1; 85 } 86 return 0; 87 } 88 89 static int 90 tls_get_peer_cert_issuer(struct tls *ctx, char **issuer) 91 { 92 X509_NAME *name = NULL; 93 94 *issuer = NULL; 95 if (ctx->ssl_peer_cert == NULL) 96 return (-1); 97 if ((name = X509_get_issuer_name(ctx->ssl_peer_cert)) == NULL) 98 return (-1); 99 *issuer = X509_NAME_oneline(name, 0, 0); 100 if (*issuer == NULL) 101 return (-1); 102 return (0); 103 } 104 105 static int 106 tls_get_peer_cert_subject(struct tls *ctx, char **subject) 107 { 108 X509_NAME *name = NULL; 109 110 *subject = NULL; 111 if (ctx->ssl_peer_cert == NULL) 112 return (-1); 113 if ((name = X509_get_subject_name(ctx->ssl_peer_cert)) == NULL) 114 return (-1); 115 *subject = X509_NAME_oneline(name, 0, 0); 116 if (*subject == NULL) 117 return (-1); 118 return (0); 119 } 120 121 static int 122 tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore, 123 time_t *notafter) 124 { 125 struct tm before_tm, after_tm; 126 ASN1_TIME *before, *after; 127 128 if (ctx->ssl_peer_cert == NULL) 129 return (-1); 130 131 if ((before = X509_get_notBefore(ctx->ssl_peer_cert)) == NULL) 132 goto err; 133 if ((after = X509_get_notAfter(ctx->ssl_peer_cert)) == NULL) 134 goto err; 135 if (!ASN1_TIME_to_tm(before, &before_tm)) 136 goto err; 137 if (!ASN1_TIME_to_tm(after, &after_tm)) 138 goto err; 139 if (!tls_convert_notafter(&after_tm, notafter)) 140 goto err; 141 if (!OPENSSL_timegm(&before_tm, notbefore)) 142 goto err; 143 return (0); 144 145 err: 146 return (-1); 147 } 148 149 static int 150 tls_get_peer_cert_info(struct tls *ctx) 151 { 152 if (ctx->ssl_peer_cert == NULL) 153 return (0); 154 155 if (tls_get_peer_cert_hash(ctx, &ctx->conninfo->hash) == -1) 156 goto err; 157 if (tls_get_peer_cert_subject(ctx, &ctx->conninfo->subject) == -1) 158 goto err; 159 if (tls_get_peer_cert_issuer(ctx, &ctx->conninfo->issuer) == -1) 160 goto err; 161 if (tls_get_peer_cert_times(ctx, &ctx->conninfo->notbefore, 162 &ctx->conninfo->notafter) == -1) 163 goto err; 164 165 return (0); 166 167 err: 168 return (-1); 169 } 170 171 static int 172 tls_conninfo_alpn_proto(struct tls *ctx) 173 { 174 const unsigned char *p; 175 unsigned int len; 176 177 free(ctx->conninfo->alpn); 178 ctx->conninfo->alpn = NULL; 179 180 SSL_get0_alpn_selected(ctx->ssl_conn, &p, &len); 181 if (len > 0) { 182 if ((ctx->conninfo->alpn = malloc(len + 1)) == NULL) 183 return (-1); 184 memcpy(ctx->conninfo->alpn, p, len); 185 ctx->conninfo->alpn[len] = '\0'; 186 } 187 188 return (0); 189 } 190 191 static int 192 tls_conninfo_cert_pem(struct tls *ctx) 193 { 194 int i, rv = -1; 195 BIO *membio = NULL; 196 BUF_MEM *bptr = NULL; 197 198 if (ctx->ssl_peer_cert == NULL) 199 return 0; 200 if ((membio = BIO_new(BIO_s_mem()))== NULL) 201 goto err; 202 203 /* 204 * We have to write the peer cert out separately, because 205 * the certificate chain may or may not contain it. 206 */ 207 if (!PEM_write_bio_X509(membio, ctx->ssl_peer_cert)) 208 goto err; 209 for (i = 0; i < sk_X509_num(ctx->ssl_peer_chain); i++) { 210 X509 *chaincert = sk_X509_value(ctx->ssl_peer_chain, i); 211 if (chaincert != ctx->ssl_peer_cert && 212 !PEM_write_bio_X509(membio, chaincert)) 213 goto err; 214 } 215 216 BIO_get_mem_ptr(membio, &bptr); 217 free(ctx->conninfo->peer_cert); 218 ctx->conninfo->peer_cert_len = 0; 219 if ((ctx->conninfo->peer_cert = malloc(bptr->length)) == NULL) 220 goto err; 221 ctx->conninfo->peer_cert_len = bptr->length; 222 memcpy(ctx->conninfo->peer_cert, bptr->data, 223 ctx->conninfo->peer_cert_len); 224 225 /* BIO_free() will kill BUF_MEM - because we have not set BIO_NOCLOSE */ 226 rv = 0; 227 err: 228 BIO_free(membio); 229 return rv; 230 } 231 232 static int 233 tls_conninfo_session(struct tls *ctx) 234 { 235 ctx->conninfo->session_resumed = SSL_session_reused(ctx->ssl_conn); 236 237 return 0; 238 } 239 240 int 241 tls_conninfo_populate(struct tls *ctx) 242 { 243 const char *tmp; 244 245 tls_conninfo_free(ctx->conninfo); 246 247 if ((ctx->conninfo = calloc(1, sizeof(struct tls_conninfo))) == NULL) { 248 tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY, "out of memory"); 249 goto err; 250 } 251 252 if (tls_conninfo_alpn_proto(ctx) == -1) 253 goto err; 254 255 if ((tmp = SSL_get_cipher(ctx->ssl_conn)) == NULL) 256 goto err; 257 if ((ctx->conninfo->cipher = strdup(tmp)) == NULL) 258 goto err; 259 ctx->conninfo->cipher_strength = SSL_get_cipher_bits(ctx->ssl_conn, NULL); 260 261 if (ctx->servername != NULL) { 262 if ((ctx->conninfo->servername = 263 strdup(ctx->servername)) == NULL) 264 goto err; 265 } 266 267 if ((tmp = SSL_get_version(ctx->ssl_conn)) == NULL) 268 goto err; 269 if ((ctx->conninfo->version = strdup(tmp)) == NULL) 270 goto err; 271 272 if (tls_get_peer_cert_info(ctx) == -1) 273 goto err; 274 275 if (tls_conninfo_cert_pem(ctx) == -1) 276 goto err; 277 278 if (tls_conninfo_session(ctx) == -1) 279 goto err; 280 281 return (0); 282 283 err: 284 tls_conninfo_free(ctx->conninfo); 285 ctx->conninfo = NULL; 286 287 return (-1); 288 } 289 290 void 291 tls_conninfo_free(struct tls_conninfo *conninfo) 292 { 293 if (conninfo == NULL) 294 return; 295 296 free(conninfo->alpn); 297 free(conninfo->cipher); 298 free(conninfo->servername); 299 free(conninfo->version); 300 301 free(conninfo->hash); 302 free(conninfo->issuer); 303 free(conninfo->subject); 304 305 free(conninfo->peer_cert); 306 307 free(conninfo); 308 } 309 310 const char * 311 tls_conn_alpn_selected(struct tls *ctx) 312 { 313 if (ctx->conninfo == NULL) 314 return (NULL); 315 return (ctx->conninfo->alpn); 316 } 317 318 const char * 319 tls_conn_cipher(struct tls *ctx) 320 { 321 if (ctx->conninfo == NULL) 322 return (NULL); 323 return (ctx->conninfo->cipher); 324 } 325 326 int 327 tls_conn_cipher_strength(struct tls *ctx) 328 { 329 if (ctx->conninfo == NULL) 330 return (0); 331 return (ctx->conninfo->cipher_strength); 332 } 333 334 const char * 335 tls_conn_servername(struct tls *ctx) 336 { 337 if (ctx->conninfo == NULL) 338 return (NULL); 339 return (ctx->conninfo->servername); 340 } 341 342 int 343 tls_conn_session_resumed(struct tls *ctx) 344 { 345 if (ctx->conninfo == NULL) 346 return (0); 347 return (ctx->conninfo->session_resumed); 348 } 349 350 const char * 351 tls_conn_version(struct tls *ctx) 352 { 353 if (ctx->conninfo == NULL) 354 return (NULL); 355 return (ctx->conninfo->version); 356 } 357