diff options
Diffstat (limited to 'src/lib/libtls/tls_client.c')
| -rw-r--r-- | src/lib/libtls/tls_client.c | 87 |
1 files changed, 54 insertions, 33 deletions
diff --git a/src/lib/libtls/tls_client.c b/src/lib/libtls/tls_client.c index deb24ebc23..40ef9a02e2 100644 --- a/src/lib/libtls/tls_client.c +++ b/src/lib/libtls/tls_client.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls_client.c,v 1.49 2023/05/14 07:26:25 op Exp $ */ | 1 | /* $OpenBSD: tls_client.c,v 1.50 2024/03/26 06:24:52 joshua Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -66,12 +66,12 @@ tls_connect_servername(struct tls *ctx, const char *host, const char *port, | |||
| 66 | int rv = -1, s = -1, ret; | 66 | int rv = -1, s = -1, ret; |
| 67 | 67 | ||
| 68 | if ((ctx->flags & TLS_CLIENT) == 0) { | 68 | if ((ctx->flags & TLS_CLIENT) == 0) { |
| 69 | tls_set_errorx(ctx, "not a client context"); | 69 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "not a client context"); |
| 70 | goto err; | 70 | goto err; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | if (host == NULL) { | 73 | if (host == NULL) { |
| 74 | tls_set_errorx(ctx, "host not specified"); | 74 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "host not specified"); |
| 75 | goto err; | 75 | goto err; |
| 76 | } | 76 | } |
| 77 | 77 | ||
| @@ -79,11 +79,11 @@ tls_connect_servername(struct tls *ctx, const char *host, const char *port, | |||
| 79 | if (port == NULL) { | 79 | if (port == NULL) { |
| 80 | ret = tls_host_port(host, &hs, &ps); | 80 | ret = tls_host_port(host, &hs, &ps); |
| 81 | if (ret == -1) { | 81 | if (ret == -1) { |
| 82 | tls_set_errorx(ctx, "memory allocation failure"); | 82 | tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY, "out of memory"); |
| 83 | goto err; | 83 | goto err; |
| 84 | } | 84 | } |
| 85 | if (ret != 0) { | 85 | if (ret != 0) { |
| 86 | tls_set_errorx(ctx, "no port provided"); | 86 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "no port provided"); |
| 87 | goto err; | 87 | goto err; |
| 88 | } | 88 | } |
| 89 | } | 89 | } |
| @@ -114,7 +114,8 @@ tls_connect_servername(struct tls *ctx, const char *host, const char *port, | |||
| 114 | hints.ai_family = AF_UNSPEC; | 114 | hints.ai_family = AF_UNSPEC; |
| 115 | hints.ai_flags = AI_ADDRCONFIG; | 115 | hints.ai_flags = AI_ADDRCONFIG; |
| 116 | if ((s = getaddrinfo(h, p, &hints, &res0)) != 0) { | 116 | if ((s = getaddrinfo(h, p, &hints, &res0)) != 0) { |
| 117 | tls_set_error(ctx, "%s", gai_strerror(s)); | 117 | tls_set_error(ctx, TLS_ERROR_UNKNOWN, |
| 118 | "%s", gai_strerror(s)); | ||
| 118 | goto err; | 119 | goto err; |
| 119 | } | 120 | } |
| 120 | } | 121 | } |
| @@ -125,11 +126,13 @@ tls_connect_servername(struct tls *ctx, const char *host, const char *port, | |||
| 125 | for (res = res0; res; res = res->ai_next) { | 126 | for (res = res0; res; res = res->ai_next) { |
| 126 | s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | 127 | s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); |
| 127 | if (s == -1) { | 128 | if (s == -1) { |
| 128 | tls_set_error(ctx, "socket"); | 129 | tls_set_error(ctx, TLS_ERROR_UNKNOWN, |
| 130 | "socket"); | ||
| 129 | continue; | 131 | continue; |
| 130 | } | 132 | } |
| 131 | if (connect(s, res->ai_addr, res->ai_addrlen) == -1) { | 133 | if (connect(s, res->ai_addr, res->ai_addrlen) == -1) { |
| 132 | tls_set_error(ctx, "connect"); | 134 | tls_set_error(ctx, TLS_ERROR_UNKNOWN, |
| 135 | "connect"); | ||
| 133 | close(s); | 136 | close(s); |
| 134 | s = -1; | 137 | s = -1; |
| 135 | continue; | 138 | continue; |
| @@ -174,11 +177,13 @@ tls_client_read_session(struct tls *ctx) | |||
| 174 | int rv = -1; | 177 | int rv = -1; |
| 175 | 178 | ||
| 176 | if (fstat(sfd, &sb) == -1) { | 179 | if (fstat(sfd, &sb) == -1) { |
| 177 | tls_set_error(ctx, "failed to stat session file"); | 180 | tls_set_error(ctx, TLS_ERROR_UNKNOWN, |
| 181 | "failed to stat session file"); | ||
| 178 | goto err; | 182 | goto err; |
| 179 | } | 183 | } |
| 180 | if (sb.st_size < 0 || sb.st_size > INT_MAX) { | 184 | if (sb.st_size < 0 || sb.st_size > INT_MAX) { |
| 181 | tls_set_errorx(ctx, "invalid session file size"); | 185 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 186 | "invalid session file size"); | ||
| 182 | goto err; | 187 | goto err; |
| 183 | } | 188 | } |
| 184 | session_len = (size_t)sb.st_size; | 189 | session_len = (size_t)sb.st_size; |
| @@ -192,19 +197,22 @@ tls_client_read_session(struct tls *ctx) | |||
| 192 | 197 | ||
| 193 | n = pread(sfd, session, session_len, 0); | 198 | n = pread(sfd, session, session_len, 0); |
| 194 | if (n < 0 || (size_t)n != session_len) { | 199 | if (n < 0 || (size_t)n != session_len) { |
| 195 | tls_set_error(ctx, "failed to read session file"); | 200 | tls_set_error(ctx, TLS_ERROR_UNKNOWN, |
| 201 | "failed to read session file"); | ||
| 196 | goto err; | 202 | goto err; |
| 197 | } | 203 | } |
| 198 | if ((bio = BIO_new_mem_buf(session, session_len)) == NULL) | 204 | if ((bio = BIO_new_mem_buf(session, session_len)) == NULL) |
| 199 | goto err; | 205 | goto err; |
| 200 | if ((ss = PEM_read_bio_SSL_SESSION(bio, NULL, tls_password_cb, | 206 | if ((ss = PEM_read_bio_SSL_SESSION(bio, NULL, tls_password_cb, |
| 201 | NULL)) == NULL) { | 207 | NULL)) == NULL) { |
| 202 | tls_set_errorx(ctx, "failed to parse session"); | 208 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 209 | "failed to parse session"); | ||
| 203 | goto err; | 210 | goto err; |
| 204 | } | 211 | } |
| 205 | 212 | ||
| 206 | if (SSL_set_session(ctx->ssl_conn, ss) != 1) { | 213 | if (SSL_set_session(ctx->ssl_conn, ss) != 1) { |
| 207 | tls_set_errorx(ctx, "failed to set session"); | 214 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 215 | "failed to set session"); | ||
| 208 | goto err; | 216 | goto err; |
| 209 | } | 217 | } |
| 210 | 218 | ||
| @@ -234,7 +242,8 @@ tls_client_write_session(struct tls *ctx) | |||
| 234 | 242 | ||
| 235 | if ((ss = SSL_get1_session(ctx->ssl_conn)) == NULL) { | 243 | if ((ss = SSL_get1_session(ctx->ssl_conn)) == NULL) { |
| 236 | if (ftruncate(sfd, 0) == -1) { | 244 | if (ftruncate(sfd, 0) == -1) { |
| 237 | tls_set_error(ctx, "failed to truncate session file"); | 245 | tls_set_error(ctx, TLS_ERROR_UNKNOWN, |
| 246 | "failed to truncate session file"); | ||
| 238 | goto err; | 247 | goto err; |
| 239 | } | 248 | } |
| 240 | goto done; | 249 | goto done; |
| @@ -251,12 +260,14 @@ tls_client_write_session(struct tls *ctx) | |||
| 251 | offset = 0; | 260 | offset = 0; |
| 252 | 261 | ||
| 253 | if (ftruncate(sfd, len) == -1) { | 262 | if (ftruncate(sfd, len) == -1) { |
| 254 | tls_set_error(ctx, "failed to truncate session file"); | 263 | tls_set_error(ctx, TLS_ERROR_UNKNOWN, |
| 264 | "failed to truncate session file"); | ||
| 255 | goto err; | 265 | goto err; |
| 256 | } | 266 | } |
| 257 | while (len > 0) { | 267 | while (len > 0) { |
| 258 | if ((n = pwrite(sfd, data + offset, len, offset)) == -1) { | 268 | if ((n = pwrite(sfd, data + offset, len, offset)) == -1) { |
| 259 | tls_set_error(ctx, "failed to write session file"); | 269 | tls_set_error(ctx, TLS_ERROR_UNKNOWN, |
| 270 | "failed to write session file"); | ||
| 260 | goto err; | 271 | goto err; |
| 261 | } | 272 | } |
| 262 | offset += n; | 273 | offset += n; |
| @@ -281,13 +292,14 @@ tls_connect_common(struct tls *ctx, const char *servername) | |||
| 281 | int rv = -1; | 292 | int rv = -1; |
| 282 | 293 | ||
| 283 | if ((ctx->flags & TLS_CLIENT) == 0) { | 294 | if ((ctx->flags & TLS_CLIENT) == 0) { |
| 284 | tls_set_errorx(ctx, "not a client context"); | 295 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "not a client context"); |
| 285 | goto err; | 296 | goto err; |
| 286 | } | 297 | } |
| 287 | 298 | ||
| 288 | if (servername != NULL) { | 299 | if (servername != NULL) { |
| 289 | if ((ctx->servername = strdup(servername)) == NULL) { | 300 | if ((ctx->servername = strdup(servername)) == NULL) { |
| 290 | tls_set_errorx(ctx, "out of memory"); | 301 | tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY, |
| 302 | "out of memory"); | ||
| 291 | goto err; | 303 | goto err; |
| 292 | } | 304 | } |
| 293 | 305 | ||
| @@ -304,7 +316,7 @@ tls_connect_common(struct tls *ctx, const char *servername) | |||
| 304 | } | 316 | } |
| 305 | 317 | ||
| 306 | if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) { | 318 | if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) { |
| 307 | tls_set_errorx(ctx, "ssl context failure"); | 319 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "ssl context failure"); |
| 308 | goto err; | 320 | goto err; |
| 309 | } | 321 | } |
| 310 | 322 | ||
| @@ -317,7 +329,8 @@ tls_connect_common(struct tls *ctx, const char *servername) | |||
| 317 | 329 | ||
| 318 | if (ctx->config->verify_name) { | 330 | if (ctx->config->verify_name) { |
| 319 | if (ctx->servername == NULL) { | 331 | if (ctx->servername == NULL) { |
| 320 | tls_set_errorx(ctx, "server name not specified"); | 332 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 333 | "server name not specified"); | ||
| 321 | goto err; | 334 | goto err; |
| 322 | } | 335 | } |
| 323 | } | 336 | } |
| @@ -328,23 +341,26 @@ tls_connect_common(struct tls *ctx, const char *servername) | |||
| 328 | if (ctx->config->ecdhecurves != NULL) { | 341 | if (ctx->config->ecdhecurves != NULL) { |
| 329 | if (SSL_CTX_set1_groups(ctx->ssl_ctx, ctx->config->ecdhecurves, | 342 | if (SSL_CTX_set1_groups(ctx->ssl_ctx, ctx->config->ecdhecurves, |
| 330 | ctx->config->ecdhecurves_len) != 1) { | 343 | ctx->config->ecdhecurves_len) != 1) { |
| 331 | tls_set_errorx(ctx, "failed to set ecdhe curves"); | 344 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 345 | "failed to set ecdhe curves"); | ||
| 332 | goto err; | 346 | goto err; |
| 333 | } | 347 | } |
| 334 | } | 348 | } |
| 335 | 349 | ||
| 336 | if (SSL_CTX_set_tlsext_status_cb(ctx->ssl_ctx, tls_ocsp_verify_cb) != 1) { | 350 | if (SSL_CTX_set_tlsext_status_cb(ctx->ssl_ctx, tls_ocsp_verify_cb) != 1) { |
| 337 | tls_set_errorx(ctx, "ssl OCSP verification setup failure"); | 351 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 352 | "ssl OCSP verification setup failure"); | ||
| 338 | goto err; | 353 | goto err; |
| 339 | } | 354 | } |
| 340 | 355 | ||
| 341 | if ((ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { | 356 | if ((ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { |
| 342 | tls_set_errorx(ctx, "ssl connection failure"); | 357 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "ssl connection failure"); |
| 343 | goto err; | 358 | goto err; |
| 344 | } | 359 | } |
| 345 | 360 | ||
| 346 | if (SSL_set_app_data(ctx->ssl_conn, ctx) != 1) { | 361 | if (SSL_set_app_data(ctx->ssl_conn, ctx) != 1) { |
| 347 | tls_set_errorx(ctx, "ssl application data failure"); | 362 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 363 | "ssl application data failure"); | ||
| 348 | goto err; | 364 | goto err; |
| 349 | } | 365 | } |
| 350 | 366 | ||
| @@ -355,7 +371,8 @@ tls_connect_common(struct tls *ctx, const char *servername) | |||
| 355 | } | 371 | } |
| 356 | 372 | ||
| 357 | if (SSL_set_tlsext_status_type(ctx->ssl_conn, TLSEXT_STATUSTYPE_ocsp) != 1) { | 373 | if (SSL_set_tlsext_status_type(ctx->ssl_conn, TLSEXT_STATUSTYPE_ocsp) != 1) { |
| 358 | tls_set_errorx(ctx, "ssl OCSP extension setup failure"); | 374 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 375 | "ssl OCSP extension setup failure"); | ||
| 359 | goto err; | 376 | goto err; |
| 360 | } | 377 | } |
| 361 | 378 | ||
| @@ -368,7 +385,8 @@ tls_connect_common(struct tls *ctx, const char *servername) | |||
| 368 | inet_pton(AF_INET6, ctx->servername, &addrbuf) != 1) { | 385 | inet_pton(AF_INET6, ctx->servername, &addrbuf) != 1) { |
| 369 | if (SSL_set_tlsext_host_name(ctx->ssl_conn, | 386 | if (SSL_set_tlsext_host_name(ctx->ssl_conn, |
| 370 | ctx->servername) == 0) { | 387 | ctx->servername) == 0) { |
| 371 | tls_set_errorx(ctx, "server name indication failure"); | 388 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 389 | "server name indication failure"); | ||
| 372 | goto err; | 390 | goto err; |
| 373 | } | 391 | } |
| 374 | } | 392 | } |
| @@ -393,7 +411,7 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write, | |||
| 393 | int rv = -1; | 411 | int rv = -1; |
| 394 | 412 | ||
| 395 | if (fd_read < 0 || fd_write < 0) { | 413 | if (fd_read < 0 || fd_write < 0) { |
| 396 | tls_set_errorx(ctx, "invalid file descriptors"); | 414 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "invalid file descriptors"); |
| 397 | goto err; | 415 | goto err; |
| 398 | } | 416 | } |
| 399 | 417 | ||
| @@ -402,7 +420,8 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write, | |||
| 402 | 420 | ||
| 403 | if (SSL_set_rfd(ctx->ssl_conn, fd_read) != 1 || | 421 | if (SSL_set_rfd(ctx->ssl_conn, fd_read) != 1 || |
| 404 | SSL_set_wfd(ctx->ssl_conn, fd_write) != 1) { | 422 | SSL_set_wfd(ctx->ssl_conn, fd_write) != 1) { |
| 405 | tls_set_errorx(ctx, "ssl file descriptor failure"); | 423 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 424 | "ssl file descriptor failure"); | ||
| 406 | goto err; | 425 | goto err; |
| 407 | } | 426 | } |
| 408 | 427 | ||
| @@ -437,12 +456,12 @@ tls_handshake_client(struct tls *ctx) | |||
| 437 | int rv = -1; | 456 | int rv = -1; |
| 438 | 457 | ||
| 439 | if ((ctx->flags & TLS_CLIENT) == 0) { | 458 | if ((ctx->flags & TLS_CLIENT) == 0) { |
| 440 | tls_set_errorx(ctx, "not a client context"); | 459 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "not a client context"); |
| 441 | goto err; | 460 | goto err; |
| 442 | } | 461 | } |
| 443 | 462 | ||
| 444 | if ((ctx->state & TLS_CONNECTED) == 0) { | 463 | if ((ctx->state & TLS_CONNECTED) == 0) { |
| 445 | tls_set_errorx(ctx, "context not connected"); | 464 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "context not connected"); |
| 446 | goto err; | 465 | goto err; |
| 447 | } | 466 | } |
| 448 | 467 | ||
| @@ -457,14 +476,16 @@ tls_handshake_client(struct tls *ctx) | |||
| 457 | if (ctx->config->verify_name) { | 476 | if (ctx->config->verify_name) { |
| 458 | cert = SSL_get_peer_certificate(ctx->ssl_conn); | 477 | cert = SSL_get_peer_certificate(ctx->ssl_conn); |
| 459 | if (cert == NULL) { | 478 | if (cert == NULL) { |
| 460 | tls_set_errorx(ctx, "no server certificate"); | 479 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 480 | "no server certificate"); | ||
| 461 | goto err; | 481 | goto err; |
| 462 | } | 482 | } |
| 463 | if (tls_check_name(ctx, cert, ctx->servername, &match) == -1) | 483 | if (tls_check_name(ctx, cert, ctx->servername, &match) == -1) |
| 464 | goto err; | 484 | goto err; |
| 465 | if (!match) { | 485 | if (!match) { |
| 466 | tls_set_errorx(ctx, "name `%s' not present in" | 486 | tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, |
| 467 | " server certificate", ctx->servername); | 487 | "name `%s' not present in server certificate", |
| 488 | ctx->servername); | ||
| 468 | goto err; | 489 | goto err; |
| 469 | } | 490 | } |
| 470 | } | 491 | } |
