1 /* $OpenBSD: tls_conninfo.c,v 1.28 2024/12/10 08:40:30 tb 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_common_name(struct tls *ctx, char **common_name) 123 { 124 if (ctx->ssl_peer_cert == NULL) 125 return (-1); 126 return tls_get_common_name(ctx, ctx->ssl_peer_cert, NULL, common_name); 127 } 128 129 static int 130 tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore, 131 time_t *notafter) 132 { 133 struct tm before_tm, after_tm; 134 ASN1_TIME *before, *after; 135 136 if (ctx->ssl_peer_cert == NULL) 137 return (-1); 138 139 if ((before = X509_get_notBefore(ctx->ssl_peer_cert)) == NULL) 140 goto err; 141 if ((after = X509_get_notAfter(ctx->ssl_peer_cert)) == NULL) 142 goto err; 143 if (!ASN1_TIME_to_tm(before, &before_tm)) 144 goto err; 145 if (!ASN1_TIME_to_tm(after, &after_tm)) 146 goto err; 147 if (!tls_convert_notafter(&after_tm, notafter)) 148 goto err; 149 if (!OPENSSL_timegm(&before_tm, notbefore)) 150 goto err; 151 return (0); 152 153 err: 154 return (-1); 155 } 156 157 static int 158 tls_get_peer_cert_info(struct tls *ctx) 159 { 160 if (ctx->ssl_peer_cert == NULL) 161 return (0); 162 163 if (tls_get_peer_cert_hash(ctx, &ctx->conninfo->hash) == -1) 164 goto err; 165 if (tls_get_peer_cert_subject(ctx, &ctx->conninfo->subject) == -1) 166 goto err; 167 if (tls_get_peer_cert_issuer(ctx, &ctx->conninfo->issuer) == -1) 168 goto err; 169 if (tls_get_peer_cert_common_name(ctx, 170 &ctx->conninfo->common_name) == -1) 171 goto err; 172 if (tls_get_peer_cert_times(ctx, &ctx->conninfo->notbefore, 173 &ctx->conninfo->notafter) == -1) 174 goto err; 175 176 return (0); 177 178 err: 179 return (-1); 180 } 181 182 static int 183 tls_conninfo_alpn_proto(struct tls *ctx) 184 { 185 const unsigned char *p; 186 unsigned int len; 187 188 free(ctx->conninfo->alpn); 189 ctx->conninfo->alpn = NULL; 190 191 SSL_get0_alpn_selected(ctx->ssl_conn, &p, &len); 192 if (len > 0) { 193 if ((ctx->conninfo->alpn = malloc(len + 1)) == NULL) 194 return (-1); 195 memcpy(ctx->conninfo->alpn, p, len); 196 ctx->conninfo->alpn[len] = '\0'; 197 } 198 199 return (0); 200 } 201 202 static int 203 tls_conninfo_cert_pem(struct tls *ctx) 204 { 205 int i, rv = -1; 206 BIO *membio = NULL; 207 BUF_MEM *bptr = NULL; 208 209 if (ctx->ssl_peer_cert == NULL) 210 return 0; 211 if ((membio = BIO_new(BIO_s_mem()))== NULL) 212 goto err; 213 214 /* 215 * We have to write the peer cert out separately, because 216 * the certificate chain may or may not contain it. 217 */ 218 if (!PEM_write_bio_X509(membio, ctx->ssl_peer_cert)) 219 goto err; 220 for (i = 0; i < sk_X509_num(ctx->ssl_peer_chain); i++) { 221 X509 *chaincert = sk_X509_value(ctx->ssl_peer_chain, i); 222 if (chaincert != ctx->ssl_peer_cert && 223 !PEM_write_bio_X509(membio, chaincert)) 224 goto err; 225 } 226 227 BIO_get_mem_ptr(membio, &bptr); 228 free(ctx->conninfo->peer_cert); 229 ctx->conninfo->peer_cert_len = 0; 230 if ((ctx->conninfo->peer_cert = malloc(bptr->length)) == NULL) 231 goto err; 232 ctx->conninfo->peer_cert_len = bptr->length; 233 memcpy(ctx->conninfo->peer_cert, bptr->data, 234 ctx->conninfo->peer_cert_len); 235 236 /* BIO_free() will kill BUF_MEM - because we have not set BIO_NOCLOSE */ 237 rv = 0; 238 err: 239 BIO_free(membio); 240 return rv; 241 } 242 243 static int 244 tls_conninfo_session(struct tls *ctx) 245 { 246 ctx->conninfo->session_resumed = SSL_session_reused(ctx->ssl_conn); 247 248 return 0; 249 } 250 251 int 252 tls_conninfo_populate(struct tls *ctx) 253 { 254 const char *tmp; 255 256 tls_conninfo_free(ctx->conninfo); 257 258 if ((ctx->conninfo = calloc(1, sizeof(struct tls_conninfo))) == NULL) { 259 tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY, "out of memory"); 260 goto err; 261 } 262 263 if (tls_conninfo_alpn_proto(ctx) == -1) 264 goto err; 265 266 if ((tmp = SSL_get_cipher(ctx->ssl_conn)) == NULL) 267 goto err; 268 if ((ctx->conninfo->cipher = strdup(tmp)) == NULL) 269 goto err; 270 ctx->conninfo->cipher_strength = SSL_get_cipher_bits(ctx->ssl_conn, NULL); 271 272 if (ctx->servername != NULL) { 273 if ((ctx->conninfo->servername = 274 strdup(ctx->servername)) == NULL) 275 goto err; 276 } 277 278 if ((tmp = SSL_get_version(ctx->ssl_conn)) == NULL) 279 goto err; 280 if ((ctx->conninfo->version = strdup(tmp)) == NULL) 281 goto err; 282 283 if (tls_get_peer_cert_info(ctx) == -1) 284 goto err; 285 286 if (tls_conninfo_cert_pem(ctx) == -1) 287 goto err; 288 289 if (tls_conninfo_session(ctx) == -1) 290 goto err; 291 292 return (0); 293 294 err: 295 tls_conninfo_free(ctx->conninfo); 296 ctx->conninfo = NULL; 297 298 return (-1); 299 } 300 301 void 302 tls_conninfo_free(struct tls_conninfo *conninfo) 303 { 304 if (conninfo == NULL) 305 return; 306 307 free(conninfo->alpn); 308 free(conninfo->cipher); 309 free(conninfo->servername); 310 free(conninfo->version); 311 312 free(conninfo->common_name); 313 free(conninfo->hash); 314 free(conninfo->issuer); 315 free(conninfo->subject); 316 317 free(conninfo->peer_cert); 318 319 free(conninfo); 320 } 321 322 const char * 323 tls_conn_alpn_selected(struct tls *ctx) 324 { 325 if (ctx->conninfo == NULL) 326 return (NULL); 327 return (ctx->conninfo->alpn); 328 } 329 330 const char * 331 tls_conn_cipher(struct tls *ctx) 332 { 333 if (ctx->conninfo == NULL) 334 return (NULL); 335 return (ctx->conninfo->cipher); 336 } 337 338 int 339 tls_conn_cipher_strength(struct tls *ctx) 340 { 341 if (ctx->conninfo == NULL) 342 return (0); 343 return (ctx->conninfo->cipher_strength); 344 } 345 346 const char * 347 tls_conn_servername(struct tls *ctx) 348 { 349 if (ctx->conninfo == NULL) 350 return (NULL); 351 return (ctx->conninfo->servername); 352 } 353 354 int 355 tls_conn_session_resumed(struct tls *ctx) 356 { 357 if (ctx->conninfo == NULL) 358 return (0); 359 return (ctx->conninfo->session_resumed); 360 } 361 362 const char * 363 tls_conn_version(struct tls *ctx) 364 { 365 if (ctx->conninfo == NULL) 366 return (NULL); 367 return (ctx->conninfo->version); 368 } 369