summaryrefslogtreecommitdiff
path: root/src/lib/libtls/tls_client.c
diff options
context:
space:
mode:
authorjoshua <>2024-03-26 06:24:52 +0000
committerjoshua <>2024-03-26 06:24:52 +0000
commit936498dd6ef929653cff09dd6b3303e39c8ad08d (patch)
treec0d04141b5fceb9e1cb05bec1e7e8fe3d0ac35f9 /src/lib/libtls/tls_client.c
parent7e79cc7d135c6ac69536ff44c870a4af9ecee499 (diff)
downloadopenbsd-936498dd6ef929653cff09dd6b3303e39c8ad08d.tar.gz
openbsd-936498dd6ef929653cff09dd6b3303e39c8ad08d.tar.bz2
openbsd-936498dd6ef929653cff09dd6b3303e39c8ad08d.zip
Add error code support to libtls
This adds tls_config_error_code() and tls_error_code(), which will become public API at a later date. Additional error codes will be added in follow-up commits. ok jsing@ beck@
Diffstat (limited to 'src/lib/libtls/tls_client.c')
-rw-r--r--src/lib/libtls/tls_client.c87
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 }