diff options
author | joshua <> | 2024-03-26 06:24:52 +0000 |
---|---|---|
committer | joshua <> | 2024-03-26 06:24:52 +0000 |
commit | 936498dd6ef929653cff09dd6b3303e39c8ad08d (patch) | |
tree | c0d04141b5fceb9e1cb05bec1e7e8fe3d0ac35f9 /src/lib/libtls/tls_config.c | |
parent | 7e79cc7d135c6ac69536ff44c870a4af9ecee499 (diff) | |
download | openbsd-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_config.c')
-rw-r--r-- | src/lib/libtls/tls_config.c | 83 |
1 files changed, 53 insertions, 30 deletions
diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c index 5eb5b69ac6..449071641b 100644 --- a/src/lib/libtls/tls_config.c +++ b/src/lib/libtls/tls_config.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls_config.c,v 1.67 2023/07/02 06:37:27 beck Exp $ */ | 1 | /* $OpenBSD: tls_config.c,v 1.68 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 | * |
@@ -50,12 +50,14 @@ tls_config_load_file(struct tls_error *error, const char *filetype, | |||
50 | *len = 0; | 50 | *len = 0; |
51 | 51 | ||
52 | if ((fd = open(filename, O_RDONLY)) == -1) { | 52 | if ((fd = open(filename, O_RDONLY)) == -1) { |
53 | tls_error_set(error, "failed to open %s file '%s'", | 53 | tls_error_set(error, TLS_ERROR_UNKNOWN, |
54 | "failed to open %s file '%s'", | ||
54 | filetype, filename); | 55 | filetype, filename); |
55 | goto err; | 56 | goto err; |
56 | } | 57 | } |
57 | if (fstat(fd, &st) != 0) { | 58 | if (fstat(fd, &st) != 0) { |
58 | tls_error_set(error, "failed to stat %s file '%s'", | 59 | tls_error_set(error, TLS_ERROR_UNKNOWN, |
60 | "failed to stat %s file '%s'", | ||
59 | filetype, filename); | 61 | filetype, filename); |
60 | goto err; | 62 | goto err; |
61 | } | 63 | } |
@@ -63,13 +65,15 @@ tls_config_load_file(struct tls_error *error, const char *filetype, | |||
63 | goto err; | 65 | goto err; |
64 | *len = (size_t)st.st_size; | 66 | *len = (size_t)st.st_size; |
65 | if ((*buf = malloc(*len)) == NULL) { | 67 | if ((*buf = malloc(*len)) == NULL) { |
66 | tls_error_set(error, "failed to allocate buffer for " | 68 | tls_error_set(error, TLS_ERROR_UNKNOWN, |
67 | "%s file", filetype); | 69 | "failed to allocate buffer for %s file", |
70 | filetype); | ||
68 | goto err; | 71 | goto err; |
69 | } | 72 | } |
70 | n = read(fd, *buf, *len); | 73 | n = read(fd, *buf, *len); |
71 | if (n < 0 || (size_t)n != *len) { | 74 | if (n < 0 || (size_t)n != *len) { |
72 | tls_error_set(error, "failed to read %s file '%s'", | 75 | tls_error_set(error, TLS_ERROR_UNKNOWN, |
76 | "failed to read %s file '%s'", | ||
73 | filetype, filename); | 77 | filetype, filename); |
74 | goto err; | 78 | goto err; |
75 | } | 79 | } |
@@ -203,6 +207,12 @@ tls_config_error(struct tls_config *config) | |||
203 | return config->error.msg; | 207 | return config->error.msg; |
204 | } | 208 | } |
205 | 209 | ||
210 | int | ||
211 | tls_config_error_code(struct tls_config *config) | ||
212 | { | ||
213 | return config->error.code; | ||
214 | } | ||
215 | |||
206 | void | 216 | void |
207 | tls_config_clear_keys(struct tls_config *config) | 217 | tls_config_clear_keys(struct tls_config *config) |
208 | { | 218 | { |
@@ -291,17 +301,19 @@ tls_config_parse_alpn(struct tls_config *config, const char *alpn, | |||
291 | *alpn_len = 0; | 301 | *alpn_len = 0; |
292 | 302 | ||
293 | if ((buf_len = strlen(alpn) + 1) > 65535) { | 303 | if ((buf_len = strlen(alpn) + 1) > 65535) { |
294 | tls_config_set_errorx(config, "alpn too large"); | 304 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, "alpn too large"); |
295 | goto err; | 305 | goto err; |
296 | } | 306 | } |
297 | 307 | ||
298 | if ((buf = malloc(buf_len)) == NULL) { | 308 | if ((buf = malloc(buf_len)) == NULL) { |
299 | tls_config_set_errorx(config, "out of memory"); | 309 | tls_config_set_errorx(config, TLS_ERROR_OUT_OF_MEMORY, |
310 | "out of memory"); | ||
300 | goto err; | 311 | goto err; |
301 | } | 312 | } |
302 | 313 | ||
303 | if ((s = strdup(alpn)) == NULL) { | 314 | if ((s = strdup(alpn)) == NULL) { |
304 | tls_config_set_errorx(config, "out of memory"); | 315 | tls_config_set_errorx(config, TLS_ERROR_OUT_OF_MEMORY, |
316 | "out of memory"); | ||
305 | goto err; | 317 | goto err; |
306 | } | 318 | } |
307 | 319 | ||
@@ -309,12 +321,12 @@ tls_config_parse_alpn(struct tls_config *config, const char *alpn, | |||
309 | q = s; | 321 | q = s; |
310 | while ((p = strsep(&q, ",")) != NULL) { | 322 | while ((p = strsep(&q, ",")) != NULL) { |
311 | if ((len = strlen(p)) == 0) { | 323 | if ((len = strlen(p)) == 0) { |
312 | tls_config_set_errorx(config, | 324 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
313 | "alpn protocol with zero length"); | 325 | "alpn protocol with zero length"); |
314 | goto err; | 326 | goto err; |
315 | } | 327 | } |
316 | if (len > 255) { | 328 | if (len > 255) { |
317 | tls_config_set_errorx(config, | 329 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
318 | "alpn protocol too long"); | 330 | "alpn protocol too long"); |
319 | goto err; | 331 | goto err; |
320 | } | 332 | } |
@@ -484,11 +496,13 @@ tls_config_set_ciphers(struct tls_config *config, const char *ciphers) | |||
484 | ciphers = TLS_CIPHERS_ALL; | 496 | ciphers = TLS_CIPHERS_ALL; |
485 | 497 | ||
486 | if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) { | 498 | if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) { |
487 | tls_config_set_errorx(config, "out of memory"); | 499 | tls_config_set_errorx(config, TLS_ERROR_OUT_OF_MEMORY, |
500 | "out of memory"); | ||
488 | goto err; | 501 | goto err; |
489 | } | 502 | } |
490 | if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) { | 503 | if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) { |
491 | tls_config_set_errorx(config, "no ciphers for '%s'", ciphers); | 504 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
505 | "no ciphers for '%s'", ciphers); | ||
492 | goto err; | 506 | goto err; |
493 | } | 507 | } |
494 | 508 | ||
@@ -526,7 +540,8 @@ tls_config_set_dheparams(struct tls_config *config, const char *params) | |||
526 | else if (strcasecmp(params, "legacy") == 0) | 540 | else if (strcasecmp(params, "legacy") == 0) |
527 | keylen = 1024; | 541 | keylen = 1024; |
528 | else { | 542 | else { |
529 | tls_config_set_errorx(config, "invalid dhe param '%s'", params); | 543 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
544 | "invalid dhe param '%s'", params); | ||
530 | return (-1); | 545 | return (-1); |
531 | } | 546 | } |
532 | 547 | ||
@@ -543,8 +558,8 @@ tls_config_set_ecdhecurve(struct tls_config *config, const char *curve) | |||
543 | strcasecmp(curve, "auto") == 0) { | 558 | strcasecmp(curve, "auto") == 0) { |
544 | curve = TLS_ECDHE_CURVES; | 559 | curve = TLS_ECDHE_CURVES; |
545 | } else if (strchr(curve, ',') != NULL || strchr(curve, ':') != NULL) { | 560 | } else if (strchr(curve, ',') != NULL || strchr(curve, ':') != NULL) { |
546 | tls_config_set_errorx(config, "invalid ecdhe curve '%s'", | 561 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
547 | curve); | 562 | "invalid ecdhe curve '%s'", curve); |
548 | return (-1); | 563 | return (-1); |
549 | } | 564 | } |
550 | 565 | ||
@@ -569,7 +584,8 @@ tls_config_set_ecdhecurves(struct tls_config *config, const char *curves) | |||
569 | curves = TLS_ECDHE_CURVES; | 584 | curves = TLS_ECDHE_CURVES; |
570 | 585 | ||
571 | if ((cs = strdup(curves)) == NULL) { | 586 | if ((cs = strdup(curves)) == NULL) { |
572 | tls_config_set_errorx(config, "out of memory"); | 587 | tls_config_set_errorx(config, TLS_ERROR_OUT_OF_MEMORY, |
588 | "out of memory"); | ||
573 | goto err; | 589 | goto err; |
574 | } | 590 | } |
575 | 591 | ||
@@ -584,14 +600,15 @@ tls_config_set_ecdhecurves(struct tls_config *config, const char *curves) | |||
584 | if (nid == NID_undef) | 600 | if (nid == NID_undef) |
585 | nid = EC_curve_nist2nid(p); | 601 | nid = EC_curve_nist2nid(p); |
586 | if (nid == NID_undef) { | 602 | if (nid == NID_undef) { |
587 | tls_config_set_errorx(config, | 603 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
588 | "invalid ecdhe curve '%s'", p); | 604 | "invalid ecdhe curve '%s'", p); |
589 | goto err; | 605 | goto err; |
590 | } | 606 | } |
591 | 607 | ||
592 | if ((curves_new = reallocarray(curves_list, curves_num + 1, | 608 | if ((curves_new = reallocarray(curves_list, curves_num + 1, |
593 | sizeof(int))) == NULL) { | 609 | sizeof(int))) == NULL) { |
594 | tls_config_set_errorx(config, "out of memory"); | 610 | tls_config_set_errorx(config, TLS_ERROR_OUT_OF_MEMORY, |
611 | "out of memory"); | ||
595 | goto err; | 612 | goto err; |
596 | } | 613 | } |
597 | curves_list = curves_new; | 614 | curves_list = curves_new; |
@@ -712,24 +729,26 @@ tls_config_set_session_fd(struct tls_config *config, int session_fd) | |||
712 | } | 729 | } |
713 | 730 | ||
714 | if (fstat(session_fd, &sb) == -1) { | 731 | if (fstat(session_fd, &sb) == -1) { |
715 | tls_config_set_error(config, "failed to stat session file"); | 732 | tls_config_set_error(config, TLS_ERROR_UNKNOWN, |
733 | "failed to stat session file"); | ||
716 | return (-1); | 734 | return (-1); |
717 | } | 735 | } |
718 | if (!S_ISREG(sb.st_mode)) { | 736 | if (!S_ISREG(sb.st_mode)) { |
719 | tls_config_set_errorx(config, | 737 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
720 | "session file is not a regular file"); | 738 | "session file is not a regular file"); |
721 | return (-1); | 739 | return (-1); |
722 | } | 740 | } |
723 | 741 | ||
724 | if (sb.st_uid != getuid()) { | 742 | if (sb.st_uid != getuid()) { |
725 | tls_config_set_errorx(config, "session file has incorrect " | 743 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
726 | "owner (uid %u != %u)", sb.st_uid, getuid()); | 744 | "session file has incorrect owner (uid %u != %u)", |
745 | sb.st_uid, getuid()); | ||
727 | return (-1); | 746 | return (-1); |
728 | } | 747 | } |
729 | mugo = sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO); | 748 | mugo = sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO); |
730 | if (mugo != (S_IRUSR|S_IWUSR)) { | 749 | if (mugo != (S_IRUSR|S_IWUSR)) { |
731 | tls_config_set_errorx(config, "session file has incorrect " | 750 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
732 | "permissions (%o != 600)", mugo); | 751 | "session file has incorrect permissions (%o != 600)", mugo); |
733 | return (-1); | 752 | return (-1); |
734 | } | 753 | } |
735 | 754 | ||
@@ -846,7 +865,8 @@ tls_config_set_session_id(struct tls_config *config, | |||
846 | const unsigned char *session_id, size_t len) | 865 | const unsigned char *session_id, size_t len) |
847 | { | 866 | { |
848 | if (len > TLS_MAX_SESSION_ID_LENGTH) { | 867 | if (len > TLS_MAX_SESSION_ID_LENGTH) { |
849 | tls_config_set_errorx(config, "session ID too large"); | 868 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
869 | "session ID too large"); | ||
850 | return (-1); | 870 | return (-1); |
851 | } | 871 | } |
852 | memset(config->session_id, 0, sizeof(config->session_id)); | 872 | memset(config->session_id, 0, sizeof(config->session_id)); |
@@ -858,11 +878,13 @@ int | |||
858 | tls_config_set_session_lifetime(struct tls_config *config, int lifetime) | 878 | tls_config_set_session_lifetime(struct tls_config *config, int lifetime) |
859 | { | 879 | { |
860 | if (lifetime > TLS_MAX_SESSION_TIMEOUT) { | 880 | if (lifetime > TLS_MAX_SESSION_TIMEOUT) { |
861 | tls_config_set_errorx(config, "session lifetime too large"); | 881 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
882 | "session lifetime too large"); | ||
862 | return (-1); | 883 | return (-1); |
863 | } | 884 | } |
864 | if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) { | 885 | if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) { |
865 | tls_config_set_errorx(config, "session lifetime too small"); | 886 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
887 | "session lifetime too small"); | ||
866 | return (-1); | 888 | return (-1); |
867 | } | 889 | } |
868 | 890 | ||
@@ -879,7 +901,7 @@ tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev, | |||
879 | 901 | ||
880 | if (TLS_TICKET_KEY_SIZE != keylen || | 902 | if (TLS_TICKET_KEY_SIZE != keylen || |
881 | sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) { | 903 | sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) { |
882 | tls_config_set_errorx(config, | 904 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
883 | "wrong amount of ticket key data"); | 905 | "wrong amount of ticket key data"); |
884 | return (-1); | 906 | return (-1); |
885 | } | 907 | } |
@@ -903,7 +925,8 @@ tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev, | |||
903 | sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key, | 925 | sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key, |
904 | tk->hmac_key, sizeof(tk->hmac_key)) == 0) | 926 | tk->hmac_key, sizeof(tk->hmac_key)) == 0) |
905 | return (0); | 927 | return (0); |
906 | tls_config_set_errorx(config, "ticket key already present"); | 928 | tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, |
929 | "ticket key already present"); | ||
907 | return (-1); | 930 | return (-1); |
908 | } | 931 | } |
909 | 932 | ||