Add error code support to libtls
authorjoshua <joshua@openbsd.org>
Tue, 26 Mar 2024 06:24:52 +0000 (06:24 +0000)
committerjoshua <joshua@openbsd.org>
Tue, 26 Mar 2024 06:24:52 +0000 (06:24 +0000)
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@

12 files changed:
lib/libtls/tls.c
lib/libtls/tls.h
lib/libtls/tls_bio_cb.c
lib/libtls/tls_client.c
lib/libtls/tls_config.c
lib/libtls/tls_conninfo.c
lib/libtls/tls_internal.h
lib/libtls/tls_keypair.c
lib/libtls/tls_ocsp.c
lib/libtls/tls_server.c
lib/libtls/tls_signer.c
lib/libtls/tls_verify.c

index 5824500..8433f55 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.c,v 1.100 2024/03/26 01:15:57 joshua Exp $ */
+/* $OpenBSD: tls.c,v 1.101 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -72,23 +72,32 @@ tls_error(struct tls *ctx)
        return ctx->error.msg;
 }
 
+int
+tls_error_code(struct tls *ctx)
+{
+       return ctx->error.code;
+}
+
 void
 tls_error_clear(struct tls_error *error)
 {
        free(error->msg);
        error->msg = NULL;
+       error->code = TLS_ERROR_UNKNOWN;
        error->errno_value = 0;
        error->tls = 0;
 }
 
 static int
-tls_error_vset(struct tls_error *error, int errno_value, const char *fmt, va_list ap)
+tls_error_vset(struct tls_error *error, int code, int errno_value,
+    const char *fmt, va_list ap)
 {
        char *errmsg = NULL;
        int rv = -1;
 
        tls_error_clear(error);
 
+       error->code = code;
        error->errno_value = errno_value;
        error->tls = 1;
 
@@ -115,7 +124,7 @@ tls_error_vset(struct tls_error *error, int errno_value, const char *fmt, va_lis
 }
 
 int
-tls_error_set(struct tls_error *error, const char *fmt, ...)
+tls_error_set(struct tls_error *error, int code, const char *fmt, ...)
 {
        va_list ap;
        int errno_value, rv;
@@ -123,27 +132,27 @@ tls_error_set(struct tls_error *error, const char *fmt, ...)
        errno_value = errno;
 
        va_start(ap, fmt);
-       rv = tls_error_vset(error, errno_value, fmt, ap);
+       rv = tls_error_vset(error, code, errno_value, fmt, ap);
        va_end(ap);
 
        return (rv);
 }
 
 int
-tls_error_setx(struct tls_error *error, const char *fmt, ...)
+tls_error_setx(struct tls_error *error, int code, const char *fmt, ...)
 {
        va_list ap;
        int rv;
 
        va_start(ap, fmt);
-       rv = tls_error_vset(error, -1, fmt, ap);
+       rv = tls_error_vset(error, code, -1, fmt, ap);
        va_end(ap);
 
        return (rv);
 }
 
 int
-tls_config_set_error(struct tls_config *config, const char *fmt, ...)
+tls_config_set_error(struct tls_config *config, int code, const char *fmt, ...)
 {
        va_list ap;
        int errno_value, rv;
@@ -151,27 +160,27 @@ tls_config_set_error(struct tls_config *config, const char *fmt, ...)
        errno_value = errno;
 
        va_start(ap, fmt);
-       rv = tls_error_vset(&config->error, errno_value, fmt, ap);
+       rv = tls_error_vset(&config->error, code, errno_value, fmt, ap);
        va_end(ap);
 
        return (rv);
 }
 
 int
-tls_config_set_errorx(struct tls_config *config, const char *fmt, ...)
+tls_config_set_errorx(struct tls_config *config, int code, const char *fmt, ...)
 {
        va_list ap;
        int rv;
 
        va_start(ap, fmt);
-       rv = tls_error_vset(&config->error, -1, fmt, ap);
+       rv = tls_error_vset(&config->error, code, -1, fmt, ap);
        va_end(ap);
 
        return (rv);
 }
 
 int
-tls_set_error(struct tls *ctx, const char *fmt, ...)
+tls_set_error(struct tls *ctx, int code, const char *fmt, ...)
 {
        va_list ap;
        int errno_value, rv;
@@ -179,27 +188,27 @@ tls_set_error(struct tls *ctx, const char *fmt, ...)
        errno_value = errno;
 
        va_start(ap, fmt);
-       rv = tls_error_vset(&ctx->error, errno_value, fmt, ap);
+       rv = tls_error_vset(&ctx->error, code, errno_value, fmt, ap);
        va_end(ap);
 
        return (rv);
 }
 
 int
-tls_set_errorx(struct tls *ctx, const char *fmt, ...)
+tls_set_errorx(struct tls *ctx, int code, const char *fmt, ...)
 {
        va_list ap;
        int rv;
 
        va_start(ap, fmt);
-       rv = tls_error_vset(&ctx->error, -1, fmt, ap);
+       rv = tls_error_vset(&ctx->error, code, -1, fmt, ap);
        va_end(ap);
 
        return (rv);
 }
 
 int
-tls_set_ssl_errorx(struct tls *ctx, const char *fmt, ...)
+tls_set_ssl_errorx(struct tls *ctx, int code, const char *fmt, ...)
 {
        va_list ap;
        int rv;
@@ -209,7 +218,7 @@ tls_set_ssl_errorx(struct tls *ctx, const char *fmt, ...)
                return (0);
 
        va_start(ap, fmt);
-       rv = tls_error_vset(&ctx->error, -1, fmt, ap);
+       rv = tls_error_vset(&ctx->error, code, -1, fmt, ap);
        va_end(ap);
 
        return (rv);
@@ -350,31 +359,35 @@ tls_keypair_to_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY **pke
                return (0);
 
        if (len > INT_MAX) {
-               tls_set_errorx(ctx, ctx->config->use_fake_private_key ?
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   ctx->config->use_fake_private_key ?
                    "cert too long" : "key too long");
                goto err;
        }
 
        if ((bio = BIO_new_mem_buf(mem, len)) == NULL) {
-               tls_set_errorx(ctx, "failed to create buffer");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "failed to create buffer");
                goto err;
        }
 
        if (ctx->config->use_fake_private_key) {
                if ((x509 = PEM_read_bio_X509(bio, NULL, tls_password_cb,
                    NULL)) == NULL) {
-                       tls_set_errorx(ctx, "failed to read X509 certificate");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to read X509 certificate");
                        goto err;
                }
                if ((*pkey = X509_get_pubkey(x509)) == NULL) {
-                       tls_set_errorx(ctx, "failed to retrieve pubkey");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to retrieve pubkey");
                        goto err;
                }
        } else {
                if ((*pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb,
                    NULL)) ==  NULL) {
-                       tls_set_errorx(ctx, "failed to read private key");
-                       goto err;
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to read private key");
+                       goto err;
                }
        }
 
@@ -399,7 +412,7 @@ tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *p
                return (0);
 
        if (keypair->pubkey_hash == NULL) {
-               tls_set_errorx(ctx, "public key hash not set");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "public key hash not set");
                goto err;
        }
 
@@ -407,7 +420,8 @@ tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *p
        case EVP_PKEY_RSA:
                if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL ||
                    RSA_set_ex_data(rsa, 0, keypair->pubkey_hash) == 0) {
-                       tls_set_errorx(ctx, "RSA key setup failure");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "RSA key setup failure");
                        goto err;
                }
                if (ctx->config->sign_cb != NULL) {
@@ -415,20 +429,23 @@ tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *p
                        if (rsa_method == NULL ||
                            RSA_set_ex_data(rsa, 1, ctx->config) == 0 ||
                            RSA_set_method(rsa, rsa_method) == 0) {
-                               tls_set_errorx(ctx, "failed to setup RSA key");
+                               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                                   "failed to setup RSA key");
                                goto err;
                        }
                }
                /* Reset the key to work around caching in OpenSSL 3. */
                if (EVP_PKEY_set1_RSA(pkey, rsa) == 0) {
-                       tls_set_errorx(ctx, "failed to set RSA key");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to set RSA key");
                        goto err;
                }
                break;
        case EVP_PKEY_EC:
                if ((eckey = EVP_PKEY_get1_EC_KEY(pkey)) == NULL ||
                    EC_KEY_set_ex_data(eckey, 0, keypair->pubkey_hash) == 0) {
-                       tls_set_errorx(ctx, "EC key setup failure");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "EC key setup failure");
                        goto err;
                }
                if (ctx->config->sign_cb != NULL) {
@@ -436,18 +453,20 @@ tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *p
                        if (ecdsa_method == NULL ||
                            EC_KEY_set_ex_data(eckey, 1, ctx->config) == 0 ||
                            EC_KEY_set_method(eckey, ecdsa_method) == 0) {
-                               tls_set_errorx(ctx, "failed to setup EC key");
+                               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                                   "failed to setup EC key");
                                goto err;
                        }
                }
                /* Reset the key to work around caching in OpenSSL 3. */
                if (EVP_PKEY_set1_EC_KEY(pkey, eckey) == 0) {
-                       tls_set_errorx(ctx, "failed to set EC key");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to set EC key");
                        goto err;
                }
                break;
        default:
-               tls_set_errorx(ctx, "incorrect key type");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "incorrect key type");
                goto err;
        }
 
@@ -472,13 +491,15 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx,
 
        if (keypair->cert_mem != NULL) {
                if (keypair->cert_len > INT_MAX) {
-                       tls_set_errorx(ctx, "certificate too long");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "certificate too long");
                        goto err;
                }
 
                if (SSL_CTX_use_certificate_chain_mem(ssl_ctx,
                    keypair->cert_mem, keypair->cert_len) != 1) {
-                       tls_set_errorx(ctx, "failed to load certificate");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to load certificate");
                        goto err;
                }
        }
@@ -489,7 +510,8 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx,
                if (tls_keypair_setup_pkey(ctx, keypair, pkey) == -1)
                        goto err;
                if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) {
-                       tls_set_errorx(ctx, "failed to load private key");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to load private key");
                        goto err;
                }
                EVP_PKEY_free(pkey);
@@ -498,7 +520,8 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx,
 
        if (!ctx->config->skip_private_key_check &&
            SSL_CTX_check_private_key(ssl_ctx) != 1) {
-               tls_set_errorx(ctx, "private/public key mismatch");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "private/public key mismatch");
                goto err;
        }
 
@@ -534,7 +557,8 @@ tls_configure_ssl(struct tls *ctx, SSL_CTX *ssl_ctx)
        if (ctx->config->alpn != NULL) {
                if (SSL_CTX_set_alpn_protos(ssl_ctx, ctx->config->alpn,
                    ctx->config->alpn_len) != 0) {
-                       tls_set_errorx(ctx, "failed to set alpn");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to set alpn");
                        goto err;
                }
        }
@@ -542,7 +566,8 @@ tls_configure_ssl(struct tls *ctx, SSL_CTX *ssl_ctx)
        if (ctx->config->ciphers != NULL) {
                if (SSL_CTX_set_cipher_list(ssl_ctx,
                    ctx->config->ciphers) != 1) {
-                       tls_set_errorx(ctx, "failed to set ciphers");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to set ciphers");
                        goto err;
                }
        }
@@ -572,7 +597,8 @@ tls_ssl_cert_verify_cb(X509_STORE_CTX *x509_ctx, void *arg)
                return (1);
 
        if ((X509_verify_cert(x509_ctx)) < 0) {
-               tls_set_errorx(ctx, "X509 verify cert failed");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "X509 verify cert failed");
                return (0);
        }
 
@@ -580,7 +606,8 @@ tls_ssl_cert_verify_cb(X509_STORE_CTX *x509_ctx, void *arg)
        if (x509_err == X509_V_OK)
                return (1);
 
-       tls_set_errorx(ctx, "certificate verification failed: %s",
+       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+           "certificate verification failed: %s",
            X509_verify_cert_error_string(x509_err));
 
        return (0);
@@ -620,31 +647,35 @@ tls_configure_ssl_verify(struct tls *ctx, SSL_CTX *ssl_ctx, int verify)
 
        if (ca_mem != NULL) {
                if (ca_len > INT_MAX) {
-                       tls_set_errorx(ctx, "ca too long");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "ca too long");
                        goto err;
                }
                if (SSL_CTX_load_verify_mem(ssl_ctx, ca_mem, ca_len) != 1) {
-                       tls_set_errorx(ctx, "ssl verify memory setup failure");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "ssl verify memory setup failure");
                        goto err;
                }
        } else if (SSL_CTX_load_verify_locations(ssl_ctx, NULL,
            ctx->config->ca_path) != 1) {
-               tls_set_errorx(ctx, "ssl verify locations failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "ssl verify locations failure");
                goto err;
        }
 
        if (crl_mem != NULL) {
                if (crl_len > INT_MAX) {
-                       tls_set_errorx(ctx, "crl too long");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "crl too long");
                        goto err;
                }
                if ((bio = BIO_new_mem_buf(crl_mem, crl_len)) == NULL) {
-                       tls_set_errorx(ctx, "failed to create buffer");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to create buffer");
                        goto err;
                }
                if ((xis = PEM_X509_INFO_read_bio(bio, NULL, tls_password_cb,
                    NULL)) == NULL) {
-                       tls_set_errorx(ctx, "failed to parse crl");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to parse crl");
                        goto err;
                }
                store = SSL_CTX_get_cert_store(ssl_ctx);
@@ -653,7 +684,8 @@ tls_configure_ssl_verify(struct tls *ctx, SSL_CTX *ssl_ctx, int verify)
                        if (xi->crl == NULL)
                                continue;
                        if (!X509_STORE_add_crl(store, xi->crl)) {
-                               tls_set_error(ctx, "failed to add crl");
+                               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                                   "failed to add crl");
                                goto err;
                        }
                }
@@ -759,21 +791,24 @@ tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, const char *prefix)
                } else if (ssl_ret == -1) {
                        errstr = strerror(errno);
                }
-               tls_set_ssl_errorx(ctx, "%s failed: %s", prefix, errstr);
+               tls_set_ssl_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "%s failed: %s", prefix, errstr);
                return (-1);
 
        case SSL_ERROR_SSL:
                if ((err = ERR_peek_error()) != 0) {
                        errstr = ERR_error_string(err, NULL);
                }
-               tls_set_ssl_errorx(ctx, "%s failed: %s", prefix, errstr);
+               tls_set_ssl_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "%s failed: %s", prefix, errstr);
                return (-1);
 
        case SSL_ERROR_WANT_CONNECT:
        case SSL_ERROR_WANT_ACCEPT:
        case SSL_ERROR_WANT_X509_LOOKUP:
        default:
-               tls_set_ssl_errorx(ctx, "%s failed (%d)", prefix, ssl_err);
+               tls_set_ssl_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "%s failed (%d)", prefix, ssl_err);
                return (-1);
        }
 }
@@ -786,12 +821,14 @@ tls_handshake(struct tls *ctx)
        tls_error_clear(&ctx->error);
 
        if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) {
-               tls_set_errorx(ctx, "invalid operation for context");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "invalid operation for context");
                goto out;
        }
 
        if ((ctx->state & TLS_HANDSHAKE_COMPLETE) != 0) {
-               tls_set_errorx(ctx, "handshake already completed");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "handshake already completed");
                goto out;
        }
 
@@ -828,7 +865,8 @@ tls_read(struct tls *ctx, void *buf, size_t buflen)
        }
 
        if (buflen > INT_MAX) {
-               tls_set_errorx(ctx, "buflen too long");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "buflen too long");
                goto out;
        }
 
@@ -859,7 +897,8 @@ tls_write(struct tls *ctx, const void *buf, size_t buflen)
        }
 
        if (buflen > INT_MAX) {
-               tls_set_errorx(ctx, "buflen too long");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "buflen too long");
                goto out;
        }
 
@@ -885,7 +924,8 @@ tls_close(struct tls *ctx)
        tls_error_clear(&ctx->error);
 
        if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) {
-               tls_set_errorx(ctx, "invalid operation for context");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "invalid operation for context");
                rv = -1;
                goto out;
        }
@@ -906,13 +946,13 @@ tls_close(struct tls *ctx)
                if (shutdown(ctx->socket, SHUT_RDWR) != 0) {
                        if (rv == 0 &&
                            errno != ENOTCONN && errno != ECONNRESET) {
-                               tls_set_error(ctx, "shutdown");
+                               tls_set_error(ctx, TLS_ERROR_UNKNOWN, "shutdown");
                                rv = -1;
                        }
                }
                if (close(ctx->socket) != 0) {
                        if (rv == 0) {
-                               tls_set_error(ctx, "close");
+                               tls_set_error(ctx, TLS_ERROR_UNKNOWN, "close");
                                rv = -1;
                        }
                }
@@ -920,7 +960,7 @@ tls_close(struct tls *ctx)
        }
 
        if ((ctx->state & TLS_EOF_NO_CLOSE_NOTIFY) != 0) {
-               tls_set_errorx(ctx, "EOF without close notify");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "EOF without close notify");
                rv = -1;
        }
 
index 3418374..0113c1c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.h,v 1.63 2023/07/02 06:37:27 beck Exp $ */
+/* $OpenBSD: tls.h,v 1.64 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -76,6 +76,12 @@ extern "C" {
 #define TLS_MAX_SESSION_ID_LENGTH              32
 #define TLS_TICKET_KEY_SIZE                    48
 
+/* Error codes */
+#if defined(LIBRESSL_NEXT_API) || defined(LIBRESSL_INTERNAL)
+#define TLS_ERROR_UNKNOWN                      0x0000
+#define TLS_ERROR_OUT_OF_MEMORY                        0x1000
+#endif
+
 struct tls;
 struct tls_config;
 
@@ -88,6 +94,10 @@ int tls_init(void);
 
 const char *tls_config_error(struct tls_config *_config);
 const char *tls_error(struct tls *_ctx);
+#if defined(LIBRESSL_NEXT_API) || defined(LIBRESSL_INTERNAL)
+int tls_config_error_code(struct tls_config *_config);
+int tls_error_code(struct tls *_ctx);
+#endif
 
 struct tls_config *tls_config_new(void);
 void tls_config_free(struct tls_config *_config);
index 8a1edfd..56b9e12 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_bio_cb.c,v 1.21 2023/05/14 07:26:25 op Exp $ */
+/* $OpenBSD: tls_bio_cb.c,v 1.22 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2016 Tobias Pape <tobias@netshed.de>
  *
@@ -143,7 +143,7 @@ tls_set_cbs(struct tls *ctx, tls_read_cb read_cb, tls_write_cb write_cb,
        int rv = -1;
 
        if (read_cb == NULL || write_cb == NULL) {
-               tls_set_errorx(ctx, "no callbacks provided");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "no callbacks provided");
                goto err;
        }
 
@@ -152,11 +152,13 @@ tls_set_cbs(struct tls *ctx, tls_read_cb read_cb, tls_write_cb write_cb,
        ctx->cb_arg = cb_arg;
 
        if ((bio_cb = bio_s_cb()) == NULL) {
-               tls_set_errorx(ctx, "failed to create callback method");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "failed to create callback method");
                goto err;
        }
        if ((bio = BIO_new(bio_cb)) == NULL) {
-               tls_set_errorx(ctx, "failed to create callback i/o");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "failed to create callback i/o");
                goto err;
        }
        BIO_set_data(bio, ctx);
index deb24eb..40ef9a0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_client.c,v 1.49 2023/05/14 07:26:25 op Exp $ */
+/* $OpenBSD: tls_client.c,v 1.50 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -66,12 +66,12 @@ tls_connect_servername(struct tls *ctx, const char *host, const char *port,
        int rv = -1, s = -1, ret;
 
        if ((ctx->flags & TLS_CLIENT) == 0) {
-               tls_set_errorx(ctx, "not a client context");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "not a client context");
                goto err;
        }
 
        if (host == NULL) {
-               tls_set_errorx(ctx, "host not specified");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "host not specified");
                goto err;
        }
 
@@ -79,11 +79,11 @@ tls_connect_servername(struct tls *ctx, const char *host, const char *port,
        if (port == NULL) {
                ret = tls_host_port(host, &hs, &ps);
                if (ret == -1) {
-                       tls_set_errorx(ctx, "memory allocation failure");
+                       tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY, "out of memory");
                        goto err;
                }
                if (ret != 0) {
-                       tls_set_errorx(ctx, "no port provided");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "no port provided");
                        goto err;
                }
        }
@@ -114,7 +114,8 @@ tls_connect_servername(struct tls *ctx, const char *host, const char *port,
                        hints.ai_family = AF_UNSPEC;
                        hints.ai_flags = AI_ADDRCONFIG;
                        if ((s = getaddrinfo(h, p, &hints, &res0)) != 0) {
-                               tls_set_error(ctx, "%s", gai_strerror(s));
+                               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                                   "%s", gai_strerror(s));
                                goto err;
                        }
                }
@@ -125,11 +126,13 @@ tls_connect_servername(struct tls *ctx, const char *host, const char *port,
        for (res = res0; res; res = res->ai_next) {
                s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
                if (s == -1) {
-                       tls_set_error(ctx, "socket");
+                       tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                           "socket");
                        continue;
                }
                if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
-                       tls_set_error(ctx, "connect");
+                       tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                           "connect");
                        close(s);
                        s = -1;
                        continue;
@@ -174,11 +177,13 @@ tls_client_read_session(struct tls *ctx)
        int rv = -1;
 
        if (fstat(sfd, &sb) == -1) {
-               tls_set_error(ctx, "failed to stat session file");
+               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                   "failed to stat session file");
                goto err;
        }
        if (sb.st_size < 0 || sb.st_size > INT_MAX) {
-               tls_set_errorx(ctx, "invalid session file size");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "invalid session file size");
                goto err;
        }
        session_len = (size_t)sb.st_size;
@@ -192,19 +197,22 @@ tls_client_read_session(struct tls *ctx)
 
        n = pread(sfd, session, session_len, 0);
        if (n < 0 || (size_t)n != session_len) {
-               tls_set_error(ctx, "failed to read session file");
+               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                   "failed to read session file");
                goto err;
        }
        if ((bio = BIO_new_mem_buf(session, session_len)) == NULL)
                goto err;
        if ((ss = PEM_read_bio_SSL_SESSION(bio, NULL, tls_password_cb,
            NULL)) == NULL) {
-               tls_set_errorx(ctx, "failed to parse session");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "failed to parse session");
                goto err;
        }
 
        if (SSL_set_session(ctx->ssl_conn, ss) != 1) {
-               tls_set_errorx(ctx, "failed to set session");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "failed to set session");
                goto err;
        }
 
@@ -234,7 +242,8 @@ tls_client_write_session(struct tls *ctx)
 
        if ((ss = SSL_get1_session(ctx->ssl_conn)) == NULL) {
                if (ftruncate(sfd, 0) == -1) {
-                       tls_set_error(ctx, "failed to truncate session file");
+                       tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to truncate session file");
                        goto err;
                }
                goto done;
@@ -251,12 +260,14 @@ tls_client_write_session(struct tls *ctx)
        offset = 0;
 
        if (ftruncate(sfd, len) == -1) {
-               tls_set_error(ctx, "failed to truncate session file");
+               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                   "failed to truncate session file");
                goto err;
        }
        while (len > 0) {
                if ((n = pwrite(sfd, data + offset, len, offset)) == -1) {
-                       tls_set_error(ctx, "failed to write session file");
+                       tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to write session file");
                        goto err;
                }
                offset += n;
@@ -281,13 +292,14 @@ tls_connect_common(struct tls *ctx, const char *servername)
        int rv = -1;
 
        if ((ctx->flags & TLS_CLIENT) == 0) {
-               tls_set_errorx(ctx, "not a client context");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "not a client context");
                goto err;
        }
 
        if (servername != NULL) {
                if ((ctx->servername = strdup(servername)) == NULL) {
-                       tls_set_errorx(ctx, "out of memory");
+                       tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY,
+                           "out of memory");
                        goto err;
                }
 
@@ -304,7 +316,7 @@ tls_connect_common(struct tls *ctx, const char *servername)
        }
 
        if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) {
-               tls_set_errorx(ctx, "ssl context failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "ssl context failure");
                goto err;
        }
 
@@ -317,7 +329,8 @@ tls_connect_common(struct tls *ctx, const char *servername)
 
        if (ctx->config->verify_name) {
                if (ctx->servername == NULL) {
-                       tls_set_errorx(ctx, "server name not specified");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "server name not specified");
                        goto err;
                }
        }
@@ -328,23 +341,26 @@ tls_connect_common(struct tls *ctx, const char *servername)
        if (ctx->config->ecdhecurves != NULL) {
                if (SSL_CTX_set1_groups(ctx->ssl_ctx, ctx->config->ecdhecurves,
                    ctx->config->ecdhecurves_len) != 1) {
-                       tls_set_errorx(ctx, "failed to set ecdhe curves");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to set ecdhe curves");
                        goto err;
                }
        }
 
        if (SSL_CTX_set_tlsext_status_cb(ctx->ssl_ctx, tls_ocsp_verify_cb) != 1) {
-               tls_set_errorx(ctx, "ssl OCSP verification setup failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "ssl OCSP verification setup failure");
                goto err;
        }
 
        if ((ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) {
-               tls_set_errorx(ctx, "ssl connection failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "ssl connection failure");
                goto err;
        }
 
        if (SSL_set_app_data(ctx->ssl_conn, ctx) != 1) {
-               tls_set_errorx(ctx, "ssl application data failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "ssl application data failure");
                goto err;
        }
 
@@ -355,7 +371,8 @@ tls_connect_common(struct tls *ctx, const char *servername)
        }
 
        if (SSL_set_tlsext_status_type(ctx->ssl_conn, TLSEXT_STATUSTYPE_ocsp) != 1) {
-               tls_set_errorx(ctx, "ssl OCSP extension setup failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "ssl OCSP extension setup failure");
                goto err;
        }
 
@@ -368,7 +385,8 @@ tls_connect_common(struct tls *ctx, const char *servername)
            inet_pton(AF_INET6, ctx->servername, &addrbuf) != 1) {
                if (SSL_set_tlsext_host_name(ctx->ssl_conn,
                    ctx->servername) == 0) {
-                       tls_set_errorx(ctx, "server name indication failure");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "server name indication failure");
                        goto err;
                }
        }
@@ -393,7 +411,7 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write,
        int rv = -1;
 
        if (fd_read < 0 || fd_write < 0) {
-               tls_set_errorx(ctx, "invalid file descriptors");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "invalid file descriptors");
                goto err;
        }
 
@@ -402,7 +420,8 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write,
 
        if (SSL_set_rfd(ctx->ssl_conn, fd_read) != 1 ||
            SSL_set_wfd(ctx->ssl_conn, fd_write) != 1) {
-               tls_set_errorx(ctx, "ssl file descriptor failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "ssl file descriptor failure");
                goto err;
        }
 
@@ -437,12 +456,12 @@ tls_handshake_client(struct tls *ctx)
        int rv = -1;
 
        if ((ctx->flags & TLS_CLIENT) == 0) {
-               tls_set_errorx(ctx, "not a client context");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "not a client context");
                goto err;
        }
 
        if ((ctx->state & TLS_CONNECTED) == 0) {
-               tls_set_errorx(ctx, "context not connected");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "context not connected");
                goto err;
        }
 
@@ -457,14 +476,16 @@ tls_handshake_client(struct tls *ctx)
        if (ctx->config->verify_name) {
                cert = SSL_get_peer_certificate(ctx->ssl_conn);
                if (cert == NULL) {
-                       tls_set_errorx(ctx, "no server certificate");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "no server certificate");
                        goto err;
                }
                if (tls_check_name(ctx, cert, ctx->servername, &match) == -1)
                        goto err;
                if (!match) {
-                       tls_set_errorx(ctx, "name `%s' not present in"
-                           " server certificate", ctx->servername);
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "name `%s' not present in server certificate",
+                           ctx->servername);
                        goto err;
                }
        }
index 5eb5b69..4490716 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_config.c,v 1.67 2023/07/02 06:37:27 beck Exp $ */
+/* $OpenBSD: tls_config.c,v 1.68 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -50,12 +50,14 @@ tls_config_load_file(struct tls_error *error, const char *filetype,
        *len = 0;
 
        if ((fd = open(filename, O_RDONLY)) == -1) {
-               tls_error_set(error, "failed to open %s file '%s'",
+               tls_error_set(error, TLS_ERROR_UNKNOWN,
+                   "failed to open %s file '%s'",
                    filetype, filename);
                goto err;
        }
        if (fstat(fd, &st) != 0) {
-               tls_error_set(error, "failed to stat %s file '%s'",
+               tls_error_set(error, TLS_ERROR_UNKNOWN,
+                   "failed to stat %s file '%s'",
                    filetype, filename);
                goto err;
        }
@@ -63,13 +65,15 @@ tls_config_load_file(struct tls_error *error, const char *filetype,
                goto err;
        *len = (size_t)st.st_size;
        if ((*buf = malloc(*len)) == NULL) {
-               tls_error_set(error, "failed to allocate buffer for "
-                   "%s file", filetype);
+               tls_error_set(error, TLS_ERROR_UNKNOWN,
+                   "failed to allocate buffer for %s file",
+                   filetype);
                goto err;
        }
        n = read(fd, *buf, *len);
        if (n < 0 || (size_t)n != *len) {
-               tls_error_set(error, "failed to read %s file '%s'",
+               tls_error_set(error, TLS_ERROR_UNKNOWN,
+                   "failed to read %s file '%s'",
                    filetype, filename);
                goto err;
        }
@@ -203,6 +207,12 @@ tls_config_error(struct tls_config *config)
        return config->error.msg;
 }
 
+int
+tls_config_error_code(struct tls_config *config)
+{
+       return config->error.code;
+}
+
 void
 tls_config_clear_keys(struct tls_config *config)
 {
@@ -291,17 +301,19 @@ tls_config_parse_alpn(struct tls_config *config, const char *alpn,
        *alpn_len = 0;
 
        if ((buf_len = strlen(alpn) + 1) > 65535) {
-               tls_config_set_errorx(config, "alpn too large");
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN, "alpn too large");
                goto err;
        }
 
        if ((buf = malloc(buf_len)) == NULL) {
-               tls_config_set_errorx(config, "out of memory");
+               tls_config_set_errorx(config, TLS_ERROR_OUT_OF_MEMORY,
+                   "out of memory");
                goto err;
        }
 
        if ((s = strdup(alpn)) == NULL) {
-               tls_config_set_errorx(config, "out of memory");
+               tls_config_set_errorx(config, TLS_ERROR_OUT_OF_MEMORY,
+                   "out of memory");
                goto err;
        }
 
@@ -309,12 +321,12 @@ tls_config_parse_alpn(struct tls_config *config, const char *alpn,
        q = s;
        while ((p = strsep(&q, ",")) != NULL) {
                if ((len = strlen(p)) == 0) {
-                       tls_config_set_errorx(config,
+                       tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
                            "alpn protocol with zero length");
                        goto err;
                }
                if (len > 255) {
-                       tls_config_set_errorx(config,
+                       tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
                            "alpn protocol too long");
                        goto err;
                }
@@ -484,11 +496,13 @@ tls_config_set_ciphers(struct tls_config *config, const char *ciphers)
                ciphers = TLS_CIPHERS_ALL;
 
        if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) {
-               tls_config_set_errorx(config, "out of memory");
+               tls_config_set_errorx(config, TLS_ERROR_OUT_OF_MEMORY,
+                   "out of memory");
                goto err;
        }
        if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) {
-               tls_config_set_errorx(config, "no ciphers for '%s'", ciphers);
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
+                   "no ciphers for '%s'", ciphers);
                goto err;
        }
 
@@ -526,7 +540,8 @@ tls_config_set_dheparams(struct tls_config *config, const char *params)
        else if (strcasecmp(params, "legacy") == 0)
                keylen = 1024;
        else {
-               tls_config_set_errorx(config, "invalid dhe param '%s'", params);
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
+                   "invalid dhe param '%s'", params);
                return (-1);
        }
 
@@ -543,8 +558,8 @@ tls_config_set_ecdhecurve(struct tls_config *config, const char *curve)
            strcasecmp(curve, "auto") == 0) {
                curve = TLS_ECDHE_CURVES;
        } else if (strchr(curve, ',') != NULL || strchr(curve, ':') != NULL) {
-               tls_config_set_errorx(config, "invalid ecdhe curve '%s'",
-                   curve);
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
+                   "invalid ecdhe curve '%s'", curve);
                return (-1);
        }
 
@@ -569,7 +584,8 @@ tls_config_set_ecdhecurves(struct tls_config *config, const char *curves)
                curves = TLS_ECDHE_CURVES;
 
        if ((cs = strdup(curves)) == NULL) {
-               tls_config_set_errorx(config, "out of memory");
+               tls_config_set_errorx(config, TLS_ERROR_OUT_OF_MEMORY,
+                   "out of memory");
                goto err;
        }
 
@@ -584,14 +600,15 @@ tls_config_set_ecdhecurves(struct tls_config *config, const char *curves)
                if (nid == NID_undef)
                        nid = EC_curve_nist2nid(p);
                if (nid == NID_undef) {
-                       tls_config_set_errorx(config,
+                       tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
                            "invalid ecdhe curve '%s'", p);
                        goto err;
                }
 
                if ((curves_new = reallocarray(curves_list, curves_num + 1,
                    sizeof(int))) == NULL) {
-                       tls_config_set_errorx(config, "out of memory");
+                       tls_config_set_errorx(config, TLS_ERROR_OUT_OF_MEMORY,
+                           "out of memory");
                        goto err;
                }
                curves_list = curves_new;
@@ -712,24 +729,26 @@ tls_config_set_session_fd(struct tls_config *config, int session_fd)
        }
 
        if (fstat(session_fd, &sb) == -1) {
-               tls_config_set_error(config, "failed to stat session file");
+               tls_config_set_error(config, TLS_ERROR_UNKNOWN,
+                   "failed to stat session file");
                return (-1);
        }
        if (!S_ISREG(sb.st_mode)) {
-               tls_config_set_errorx(config,
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
                    "session file is not a regular file");
                return (-1);
        }
 
        if (sb.st_uid != getuid()) {
-               tls_config_set_errorx(config, "session file has incorrect "
-                   "owner (uid %u != %u)", sb.st_uid, getuid());
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
+                   "session file has incorrect owner (uid %u != %u)",
+                   sb.st_uid, getuid());
                return (-1);
        }
        mugo = sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO);
        if (mugo != (S_IRUSR|S_IWUSR)) {
-               tls_config_set_errorx(config, "session file has incorrect "
-                   "permissions (%o != 600)", mugo);
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
+                   "session file has incorrect permissions (%o != 600)", mugo);
                return (-1);
        }
 
@@ -846,7 +865,8 @@ tls_config_set_session_id(struct tls_config *config,
     const unsigned char *session_id, size_t len)
 {
        if (len > TLS_MAX_SESSION_ID_LENGTH) {
-               tls_config_set_errorx(config, "session ID too large");
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
+                   "session ID too large");
                return (-1);
        }
        memset(config->session_id, 0, sizeof(config->session_id));
@@ -858,11 +878,13 @@ int
 tls_config_set_session_lifetime(struct tls_config *config, int lifetime)
 {
        if (lifetime > TLS_MAX_SESSION_TIMEOUT) {
-               tls_config_set_errorx(config, "session lifetime too large");
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
+                   "session lifetime too large");
                return (-1);
        }
        if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) {
-               tls_config_set_errorx(config, "session lifetime too small");
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
+                   "session lifetime too small");
                return (-1);
        }
 
@@ -879,7 +901,7 @@ tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev,
 
        if (TLS_TICKET_KEY_SIZE != keylen ||
            sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) {
-               tls_config_set_errorx(config,
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
                    "wrong amount of ticket key data");
                return (-1);
        }
@@ -903,7 +925,8 @@ tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev,
                    sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key,
                    tk->hmac_key, sizeof(tk->hmac_key)) == 0)
                        return (0);
-               tls_config_set_errorx(config, "ticket key already present");
+               tls_config_set_errorx(config, TLS_ERROR_UNKNOWN,
+                   "ticket key already present");
                return (-1);
        }
 
index 08f8714..bc15b85 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_conninfo.c,v 1.25 2024/03/24 11:30:12 beck Exp $ */
+/* $OpenBSD: tls_conninfo.c,v 1.26 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
  * Copyright (c) 2015 Bob Beck <beck@openbsd.org>
@@ -79,7 +79,7 @@ tls_get_peer_cert_hash(struct tls *ctx, char **hash)
                return (0);
 
        if (tls_cert_hash(ctx->ssl_peer_cert, hash) == -1) {
-               tls_set_errorx(ctx, "unable to compute peer certificate hash - out of memory");
+               tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY, "out of memory")y
                *hash = NULL;
                return -1;
        }
@@ -245,7 +245,7 @@ tls_conninfo_populate(struct tls *ctx)
        tls_conninfo_free(ctx->conninfo);
 
        if ((ctx->conninfo = calloc(1, sizeof(struct tls_conninfo))) == NULL) {
-               tls_set_errorx(ctx, "out of memory");
+               tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY, "out of memory");
                goto err;
        }
 
index c06e821..5ff48ed 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_internal.h,v 1.84 2024/03/26 00:50:22 joshua Exp $ */
+/* $OpenBSD: tls_internal.h,v 1.85 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -46,6 +46,7 @@ union tls_addr {
 
 struct tls_error {
        char *msg;
+       int code;
        int errno_value;
        int tls;
 };
@@ -258,27 +259,27 @@ int tls_set_cbs(struct tls *ctx,
     tls_read_cb read_cb, tls_write_cb write_cb, void *cb_arg);
 
 void tls_error_clear(struct tls_error *error);
-int tls_error_set(struct tls_error *error, const char *fmt, ...)
-    __attribute__((__format__ (printf, 2, 3)))
-    __attribute__((__nonnull__ (2)));
-int tls_error_setx(struct tls_error *error, const char *fmt, ...)
-    __attribute__((__format__ (printf, 2, 3)))
-    __attribute__((__nonnull__ (2)));
-int tls_config_set_error(struct tls_config *cfg, const char *fmt, ...)
-    __attribute__((__format__ (printf, 2, 3)))
-    __attribute__((__nonnull__ (2)));
-int tls_config_set_errorx(struct tls_config *cfg, const char *fmt, ...)
-    __attribute__((__format__ (printf, 2, 3)))
-    __attribute__((__nonnull__ (2)));
-int tls_set_error(struct tls *ctx, const char *fmt, ...)
-    __attribute__((__format__ (printf, 2, 3)))
-    __attribute__((__nonnull__ (2)));
-int tls_set_errorx(struct tls *ctx, const char *fmt, ...)
-    __attribute__((__format__ (printf, 2, 3)))
-    __attribute__((__nonnull__ (2)));
-int tls_set_ssl_errorx(struct tls *ctx, const char *fmt, ...)
-    __attribute__((__format__ (printf, 2, 3)))
-    __attribute__((__nonnull__ (2)));
+int tls_error_set(struct tls_error *error, int code, const char *fmt, ...)
+    __attribute__((__format__ (printf, 3, 4)))
+    __attribute__((__nonnull__ (3)));
+int tls_error_setx(struct tls_error *error, int code, const char *fmt, ...)
+    __attribute__((__format__ (printf, 3, 4)))
+    __attribute__((__nonnull__ (3)));
+int tls_config_set_error(struct tls_config *cfg, int code, const char *fmt, ...)
+    __attribute__((__format__ (printf, 3, 4)))
+    __attribute__((__nonnull__ (3)));
+int tls_config_set_errorx(struct tls_config *cfg, int code, const char *fmt, ...)
+    __attribute__((__format__ (printf, 3, 4)))
+    __attribute__((__nonnull__ (3)));
+int tls_set_error(struct tls *ctx, int code, const char *fmt, ...)
+    __attribute__((__format__ (printf, 3, 4)))
+    __attribute__((__nonnull__ (3)));
+int tls_set_errorx(struct tls *ctx, int code, const char *fmt, ...)
+    __attribute__((__format__ (printf, 3, 4)))
+    __attribute__((__nonnull__ (3)));
+int tls_set_ssl_errorx(struct tls *ctx, int code, const char *fmt, ...)
+    __attribute__((__format__ (printf, 3, 4)))
+    __attribute__((__nonnull__ (3)));
 
 int tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret,
     const char *prefix);
index a12d21d..ffda91d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_keypair.c,v 1.8 2021/01/05 17:37:12 jsing Exp $ */
+/* $OpenBSD: tls_keypair.c,v 1.9 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -144,19 +144,22 @@ tls_keypair_load_cert(struct tls_keypair *keypair, struct tls_error *error,
        *cert = NULL;
 
        if (keypair->cert_mem == NULL) {
-               tls_error_set(error, "keypair has no certificate");
+               tls_error_set(error, TLS_ERROR_UNKNOWN,
+                   "keypair has no certificate");
                goto err;
        }
        if ((cert_bio = BIO_new_mem_buf(keypair->cert_mem,
            keypair->cert_len)) == NULL) {
-               tls_error_set(error, "failed to create certificate bio");
+               tls_error_set(error, TLS_ERROR_UNKNOWN,
+                   "failed to create certificate bio");
                goto err;
        }
        if ((*cert = PEM_read_bio_X509(cert_bio, NULL, tls_password_cb,
            NULL)) == NULL) {
                if ((ssl_err = ERR_peek_error()) != 0)
                        errstr = ERR_error_string(ssl_err, NULL);
-               tls_error_set(error, "failed to load certificate: %s", errstr);
+               tls_error_set(error, TLS_ERROR_UNKNOWN,
+                   "failed to load certificate: %s", errstr);
                goto err;
        }
 
index f7d7ba9..bfd06e3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tls_ocsp.c,v 1.25 2024/03/24 11:30:12 beck Exp $ */
+/*     $OpenBSD: tls_ocsp.c,v 1.26 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2015 Marko Kreen <markokr@gmail.com>
  * Copyright (c) 2016 Bob Beck <beck@openbsd.org>
@@ -85,7 +85,7 @@ tls_ocsp_fill_info(struct tls *ctx, int response_status, int cert_status,
        ctx->ocsp->ocsp_result = NULL;
 
        if ((info = calloc(1, sizeof (struct tls_ocsp_result))) == NULL) {
-               tls_set_error(ctx, "calloc");
+               tls_set_error(ctx, TLS_ERROR_OUT_OF_MEMORY, "out of memory");
                return -1;
        }
        info->response_status = response_status;
@@ -102,19 +102,19 @@ tls_ocsp_fill_info(struct tls *ctx, int response_status, int cert_status,
        info->revocation_time = info->this_update = info->next_update = -1;
        if (revtime != NULL &&
            tls_ocsp_asn1_parse_time(ctx, revtime, &info->revocation_time) != 0) {
-               tls_set_error(ctx,
+               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
                    "unable to parse revocation time in OCSP reply");
                goto err;
        }
        if (thisupd != NULL &&
            tls_ocsp_asn1_parse_time(ctx, thisupd, &info->this_update) != 0) {
-               tls_set_error(ctx,
+               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
                    "unable to parse this update time in OCSP reply");
                goto err;
        }
        if (nextupd != NULL &&
            tls_ocsp_asn1_parse_time(ctx, nextupd, &info->next_update) != 0) {
-               tls_set_error(ctx,
+               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
                    "unable to parse next update time in OCSP reply");
                goto err;
        }
@@ -180,19 +180,21 @@ tls_ocsp_setup_from_peer(struct tls *ctx)
        ocsp->main_cert = SSL_get_peer_certificate(ctx->ssl_conn);
        ocsp->extra_certs = SSL_get_peer_cert_chain(ctx->ssl_conn);
        if (ocsp->main_cert == NULL) {
-               tls_set_errorx(ctx, "no peer certificate for OCSP");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "no peer certificate for OCSP");
                goto err;
        }
 
        ocsp_urls = X509_get1_ocsp(ocsp->main_cert);
        if (ocsp_urls == NULL) {
-               tls_set_errorx(ctx, "no OCSP URLs in peer certificate");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "no OCSP URLs in peer certificate");
                goto err;
        }
 
        ocsp->ocsp_url = strdup(sk_OPENSSL_STRING_value(ocsp_urls, 0));
        if (ocsp->ocsp_url == NULL) {
-               tls_set_errorx(ctx, "out of memory");
+               tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY, "out of memory");
                goto err;
        }
 
@@ -217,7 +219,7 @@ tls_ocsp_verify_response(struct tls *ctx, OCSP_RESPONSE *resp)
        unsigned long flags;
 
        if ((br = OCSP_response_get1_basic(resp)) == NULL) {
-               tls_set_errorx(ctx, "cannot load ocsp reply");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "cannot load ocsp reply");
                goto err;
        }
 
@@ -230,14 +232,15 @@ tls_ocsp_verify_response(struct tls *ctx, OCSP_RESPONSE *resp)
        /* now verify */
        if (OCSP_basic_verify(br, ctx->ocsp->extra_certs,
                SSL_CTX_get_cert_store(ctx->ssl_ctx), flags) != 1) {
-               tls_set_errorx(ctx, "ocsp verify failed");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "ocsp verify failed");
                goto err;
        }
 
        /* signature OK, look inside */
        response_status = OCSP_response_status(resp);
        if (response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
-               tls_set_errorx(ctx, "ocsp verify failed: response - %s",
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "ocsp verify failed: response - %s",
                    OCSP_response_status_str(response_status));
                goto err;
        }
@@ -245,19 +248,21 @@ tls_ocsp_verify_response(struct tls *ctx, OCSP_RESPONSE *resp)
        cid = tls_ocsp_get_certid(ctx->ocsp->main_cert,
            ctx->ocsp->extra_certs, ctx->ssl_ctx);
        if (cid == NULL) {
-               tls_set_errorx(ctx, "ocsp verify failed: no issuer cert");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "ocsp verify failed: no issuer cert");
                goto err;
        }
 
        if (OCSP_resp_find_status(br, cid, &cert_status, &crl_reason,
            &revtime, &thisupd, &nextupd) != 1) {
-               tls_set_errorx(ctx, "ocsp verify failed: no result for cert");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "ocsp verify failed: no result for cert");
                goto err;
        }
 
        if (OCSP_check_validity(thisupd, nextupd, JITTER_SEC,
            MAXAGE_SEC) != 1) {
-               tls_set_errorx(ctx,
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
                    "ocsp verify failed: ocsp response not current");
                goto err;
        }
@@ -269,8 +274,9 @@ tls_ocsp_verify_response(struct tls *ctx, OCSP_RESPONSE *resp)
        /* finally can look at status */
        if (cert_status != V_OCSP_CERTSTATUS_GOOD && cert_status !=
            V_OCSP_CERTSTATUS_UNKNOWN) {
-               tls_set_errorx(ctx, "ocsp verify failed: revoked cert - %s",
-                              OCSP_crl_reason_str(crl_reason));
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "ocsp verify failed: revoked cert - %s",
+                   OCSP_crl_reason_str(crl_reason));
                goto err;
        }
        ret = 0;
@@ -298,7 +304,8 @@ tls_ocsp_process_response_internal(struct tls *ctx, const unsigned char *respons
        if (resp == NULL) {
                tls_ocsp_free(ctx->ocsp);
                ctx->ocsp = NULL;
-               tls_set_error(ctx, "unable to parse OCSP response");
+               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                   "unable to parse OCSP response");
                return -1;
        }
        ret = tls_ocsp_verify_response(ctx, resp);
@@ -320,7 +327,8 @@ tls_ocsp_verify_cb(SSL *ssl, void *arg)
        size = SSL_get_tlsext_status_ocsp_resp(ssl, &raw);
        if (size <= 0) {
                if (ctx->config->ocsp_require_stapling) {
-                       tls_set_errorx(ctx, "no stapled OCSP response provided");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "no stapled OCSP response provided");
                        return 0;
                }
                return 1;
index 5f93c7a..a429857 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_server.c,v 1.49 2023/05/14 07:26:25 op Exp $ */
+/* $OpenBSD: tls_server.c,v 1.50 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -181,7 +181,8 @@ tls_server_ticket_cb(SSL *ssl, unsigned char *keyname, unsigned char *iv,
                /* create new session */
                key = tls_server_ticket_key(tls_ctx->config, NULL);
                if (key == NULL) {
-                       tls_set_errorx(tls_ctx, "no valid ticket key found");
+                       tls_set_errorx(tls_ctx, TLS_ERROR_UNKNOWN,
+                           "no valid ticket key found");
                        return (-1);
                }
 
@@ -189,12 +190,14 @@ tls_server_ticket_cb(SSL *ssl, unsigned char *keyname, unsigned char *iv,
                arc4random_buf(iv, EVP_MAX_IV_LENGTH);
                if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
                    key->aes_key, iv)) {
-                       tls_set_errorx(tls_ctx, "failed to init encrypt");
+                       tls_set_errorx(tls_ctx, TLS_ERROR_UNKNOWN,
+                           "failed to init encrypt");
                        return (-1);
                }
                if (!HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key),
                    EVP_sha256(), NULL)) {
-                       tls_set_errorx(tls_ctx, "failed to init hmac");
+                       tls_set_errorx(tls_ctx, TLS_ERROR_UNKNOWN,
+                           "failed to init hmac");
                        return (-1);
                }
                return (0);
@@ -206,12 +209,14 @@ tls_server_ticket_cb(SSL *ssl, unsigned char *keyname, unsigned char *iv,
 
                if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
                    key->aes_key, iv)) {
-                       tls_set_errorx(tls_ctx, "failed to init decrypt");
+                       tls_set_errorx(tls_ctx, TLS_ERROR_UNKNOWN,
+                           "failed to init decrypt");
                        return (-1);
                }
                if (!HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key),
                    EVP_sha256(), NULL)) {
-                       tls_set_errorx(tls_ctx, "failed to init hmac");
+                       tls_set_errorx(tls_ctx, TLS_ERROR_UNKNOWN,
+                           "failed to init hmac");
                        return (-1);
                }
 
@@ -229,7 +234,7 @@ tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx,
        SSL_CTX_free(*ssl_ctx);
 
        if ((*ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) {
-               tls_set_errorx(ctx, "ssl context failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "ssl context failure");
                goto err;
        }
 
@@ -237,11 +242,13 @@ tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx,
 
        if (SSL_CTX_set_tlsext_servername_callback(*ssl_ctx,
            tls_servername_cb) != 1) {
-               tls_set_error(ctx, "failed to set servername callback");
+               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                   "failed to set servername callback");
                goto err;
        }
        if (SSL_CTX_set_tlsext_servername_arg(*ssl_ctx, ctx) != 1) {
-               tls_set_error(ctx, "failed to set servername callback arg");
+               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                   "failed to set servername callback arg");
                goto err;
        }
 
@@ -270,7 +277,8 @@ tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx,
                SSL_CTX_set_ecdh_auto(*ssl_ctx, 1);
                if (SSL_CTX_set1_groups(*ssl_ctx, ctx->config->ecdhecurves,
                    ctx->config->ecdhecurves_len) != 1) {
-                       tls_set_errorx(ctx, "failed to set ecdhe curves");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "failed to set ecdhe curves");
                        goto err;
                }
        }
@@ -279,7 +287,8 @@ tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx,
                SSL_CTX_set_options(*ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
 
        if (SSL_CTX_set_tlsext_status_cb(*ssl_ctx, tls_ocsp_stapling_cb) != 1) {
-               tls_set_errorx(ctx, "failed to add OCSP stapling callback");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "failed to add OCSP stapling callback");
                goto err;
        }
 
@@ -289,7 +298,7 @@ tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx,
                SSL_CTX_clear_options(*ssl_ctx, SSL_OP_NO_TICKET);
                if (!SSL_CTX_set_tlsext_ticket_key_cb(*ssl_ctx,
                    tls_server_ticket_cb)) {
-                       tls_set_error(ctx,
+                       tls_set_error(ctx, TLS_ERROR_UNKNOWN,
                            "failed to set the TLS ticket callback");
                        goto err;
                }
@@ -297,7 +306,8 @@ tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx,
 
        if (SSL_CTX_set_session_id_context(*ssl_ctx, ctx->config->session_id,
            sizeof(ctx->config->session_id)) != 1) {
-               tls_set_error(ctx, "failed to set session id context");
+               tls_set_error(ctx, TLS_ERROR_UNKNOWN,
+                   "failed to set session id context");
                goto err;
        }
 
@@ -323,7 +333,7 @@ tls_configure_server_sni(struct tls *ctx)
        sni_ctx = &ctx->sni_ctx;
        for (kp = ctx->config->keypair->next; kp != NULL; kp = kp->next) {
                if ((*sni_ctx = tls_sni_ctx_new()) == NULL) {
-                       tls_set_errorx(ctx, "out of memory");
+                       tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY, "out of memory");
                        goto err;
                }
                (*sni_ctx)->keypair = kp;
@@ -362,22 +372,24 @@ tls_accept_common(struct tls *ctx)
        struct tls *conn_ctx = NULL;
 
        if ((ctx->flags & TLS_SERVER) == 0) {
-               tls_set_errorx(ctx, "not a server context");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "not a server context");
                goto err;
        }
 
        if ((conn_ctx = tls_server_conn(ctx)) == NULL) {
-               tls_set_errorx(ctx, "connection context failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "connection context failure");
                goto err;
        }
 
        if ((conn_ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) {
-               tls_set_errorx(ctx, "ssl failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "ssl failure");
                goto err;
        }
 
        if (SSL_set_app_data(conn_ctx->ssl_conn, conn_ctx) != 1) {
-               tls_set_errorx(ctx, "ssl application data failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "ssl application data failure");
                goto err;
        }
 
@@ -405,7 +417,8 @@ tls_accept_fds(struct tls *ctx, struct tls **cctx, int fd_read, int fd_write)
 
        if (SSL_set_rfd(conn_ctx->ssl_conn, fd_read) != 1 ||
            SSL_set_wfd(conn_ctx->ssl_conn, fd_write) != 1) {
-               tls_set_errorx(ctx, "ssl file descriptor failure");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "ssl file descriptor failure");
                goto err;
        }
 
@@ -448,7 +461,8 @@ tls_handshake_server(struct tls *ctx)
        int rv = -1;
 
        if ((ctx->flags & TLS_SERVER_CONN) == 0) {
-               tls_set_errorx(ctx, "not a server connection context");
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "not a server connection context");
                goto err;
        }
 
index 177c9d0..5eb3707 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_signer.c,v 1.9 2023/06/18 19:12:58 tb Exp $ */
+/* $OpenBSD: tls_signer.c,v 1.10 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2021 Eric Faurot <eric@openbsd.org>
  *
@@ -91,7 +91,7 @@ tls_signer_add_keypair_mem(struct tls_signer *signer, const uint8_t *cert,
 
        /* Compute certificate hash */
        if ((bio = BIO_new_mem_buf(cert, cert_len)) == NULL) {
-               tls_error_setx(&signer->error,
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
                    "failed to create certificate bio");
                goto err;
        }
@@ -99,12 +99,12 @@ tls_signer_add_keypair_mem(struct tls_signer *signer, const uint8_t *cert,
            NULL)) == NULL) {
                if ((ssl_err = ERR_peek_error()) != 0)
                        errstr = ERR_error_string(ssl_err, NULL);
-               tls_error_setx(&signer->error, "failed to load certificate: %s",
-                   errstr);
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "failed to load certificate: %s", errstr);
                goto err;
        }
        if (tls_cert_pubkey_hash(x509, &hash) == -1) {
-               tls_error_setx(&signer->error,
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
                    "failed to get certificate hash");
                goto err;
        }
@@ -116,23 +116,27 @@ tls_signer_add_keypair_mem(struct tls_signer *signer, const uint8_t *cert,
 
        /* Read private key */
        if ((bio = BIO_new_mem_buf(key, key_len)) == NULL) {
-               tls_error_setx(&signer->error, "failed to create key bio");
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "failed to create key bio");
                goto err;
        }
        if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb,
            NULL)) == NULL) {
-               tls_error_setx(&signer->error, "failed to read private key");
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "failed to read private key");
                goto err;
        }
 
        if ((skey = calloc(1, sizeof(*skey))) == NULL) {
-               tls_error_set(&signer->error, "failed to create key entry");
+               tls_error_set(&signer->error, TLS_ERROR_UNKNOWN,
+                   "failed to create key entry");
                goto err;
        }
        skey->hash = hash;
        if ((skey->rsa = EVP_PKEY_get1_RSA(pkey)) == NULL &&
            (skey->ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) {
-               tls_error_setx(&signer->error, "unknown key type");
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "unknown key type");
                goto err;
        }
 
@@ -194,29 +198,31 @@ tls_sign_rsa(struct tls_signer *signer, struct tls_signer_key *skey,
        } else if (padding_type == TLS_PADDING_RSA_PKCS1) {
                rsa_padding = RSA_PKCS1_PADDING;
        } else {
-               tls_error_setx(&signer->error, "invalid RSA padding type (%d)",
-                   padding_type);
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "invalid RSA padding type (%d)", padding_type);
                return (-1);
        }
 
        if (input_len > INT_MAX) {
-               tls_error_setx(&signer->error, "input too large");
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "input too large");
                return (-1);
        }
        if ((rsa_size = RSA_size(skey->rsa)) <= 0) {
-               tls_error_setx(&signer->error, "invalid RSA size: %d",
-                   rsa_size);
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "invalid RSA size: %d", rsa_size);
                return (-1);
        }
        if ((signature = calloc(1, rsa_size)) == NULL) {
-               tls_error_set(&signer->error, "RSA signature");
+               tls_error_set(&signer->error, TLS_ERROR_UNKNOWN, "RSA signature");
                return (-1);
        }
 
        if ((signature_len = RSA_private_encrypt((int)input_len, input,
            signature, skey->rsa, rsa_padding)) <= 0) {
                /* XXX - include further details from libcrypto. */
-               tls_error_setx(&signer->error, "RSA signing failed");
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "RSA signing failed");
                free(signature);
                return (-1);
        }
@@ -239,28 +245,32 @@ tls_sign_ecdsa(struct tls_signer *signer, struct tls_signer_key *skey,
        *out_signature_len = 0;
 
        if (padding_type != TLS_PADDING_NONE) {
-               tls_error_setx(&signer->error, "invalid ECDSA padding");
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "invalid ECDSA padding");
                return (-1);
        }
 
        if (input_len > INT_MAX) {
-               tls_error_setx(&signer->error, "digest too large");
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "digest too large");
                return (-1);
        }
        if ((signature_len = ECDSA_size(skey->ecdsa)) <= 0) {
-               tls_error_setx(&signer->error, "invalid ECDSA size: %d",
-                   signature_len);
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "invalid ECDSA size: %d", signature_len);
                return (-1);
        }
        if ((signature = calloc(1, signature_len)) == NULL) {
-               tls_error_set(&signer->error, "ECDSA signature");
+               tls_error_set(&signer->error, TLS_ERROR_UNKNOWN,
+                   "ECDSA signature");
                return (-1);
        }
 
        if (!ECDSA_sign(0, input, input_len, signature, &signature_len,
            skey->ecdsa)) {
                /* XXX - include further details from libcrypto. */
-               tls_error_setx(&signer->error, "ECDSA signing failed");
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN,
+                   "ECDSA signing failed");
                free(signature);
                return (-1);
        }
@@ -286,7 +296,7 @@ tls_signer_sign(struct tls_signer *signer, const char *pubkey_hash,
                        break;
 
        if (skey == NULL) {
-               tls_error_setx(&signer->error, "key not found");
+               tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN, "key not found");
                return (-1);
        }
 
@@ -298,7 +308,7 @@ tls_signer_sign(struct tls_signer *signer, const char *pubkey_hash,
                return tls_sign_ecdsa(signer, skey, input, input_len,
                    padding_type, out_signature, out_signature_len);
 
-       tls_error_setx(&signer->error, "unknown key type");
+       tls_error_setx(&signer->error, TLS_ERROR_UNKNOWN, "unknown key type");
 
        return (-1);
 }
index a35ebe0..78f6c24 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_verify.c,v 1.29 2023/11/22 18:23:09 op Exp $ */
+/* $OpenBSD: tls_verify.c,v 1.30 2024/03/26 06:24:52 joshua Exp $ */
 /*
  * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
  *
@@ -102,7 +102,8 @@ tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *name,
            NULL);
        if (altname_stack == NULL) {
                if (critical != -1) {
-                       tls_set_errorx(ctx, "error decoding subjectAltName");
+                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                           "error decoding subjectAltName");
                        goto err;
                }
                goto done;
@@ -141,7 +142,7 @@ tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *name,
                                len = ASN1_STRING_length(altname->d.dNSName);
 
                                if (len < 0 || (size_t)len != strlen(data)) {
-                                       tls_set_errorx(ctx,
+                                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
                                            "error verifying name '%s': "
                                            "NUL byte in subjectAltName, "
                                            "probably a malicious certificate",
@@ -155,7 +156,7 @@ tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *name,
                                 * dNSName must be rejected.
                                 */
                                if (strcmp(data, " ") == 0) {
-                                       tls_set_errorx(ctx,
+                                       tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
                                            "error verifying name '%s': "
                                            "a dNSName of \" \" must not be "
                                            "used", name);
@@ -182,7 +183,7 @@ tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *name,
                        data = ASN1_STRING_get0_data(altname->d.iPAddress);
 
                        if (datalen < 0) {
-                               tls_set_errorx(ctx,
+                               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
                                    "Unexpected negative length for an "
                                    "IP address: %d", datalen);
                                goto err;
@@ -243,7 +244,8 @@ tls_check_common_name(struct tls *ctx, X509 *cert, const char *name,
                 * more than one CN fed to us in the subject, treating the
                 * certificate as hostile.
                 */
-               tls_set_errorx(ctx, "error verifying name '%s': "
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "error verifying name '%s': "
                    "Certificate subject contains multiple Common Name fields, "
                    "probably a malicious or malformed certificate", name);
                goto err;
@@ -255,7 +257,8 @@ tls_check_common_name(struct tls *ctx, X509 *cert, const char *name,
         * Fail if we cannot encode the CN bytes as UTF-8.
         */
        if ((common_name_len = ASN1_STRING_to_UTF8(&utf8_bytes, data)) < 0) {
-               tls_set_errorx(ctx, "error verifying name '%s': "
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "error verifying name '%s': "
                    "Common Name field cannot be encoded as a UTF-8 string, "
                    "probably a malicious certificate", name);
                goto err;
@@ -265,7 +268,8 @@ tls_check_common_name(struct tls *ctx, X509 *cert, const char *name,
         * must be between 1 and 64 bytes long.
         */
        if (common_name_len < 1 || common_name_len > 64) {
-               tls_set_errorx(ctx, "error verifying name '%s': "
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "error verifying name '%s': "
                    "Common Name field has invalid length, "
                    "probably a malicious certificate", name);
                goto err;
@@ -274,7 +278,8 @@ tls_check_common_name(struct tls *ctx, X509 *cert, const char *name,
         * Fail if the resulting text contains a NUL byte.
         */
        if (memchr(utf8_bytes, 0, common_name_len) != NULL) {
-               tls_set_errorx(ctx, "error verifying name '%s': "
+               tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+                   "error verifying name '%s': "
                    "NUL byte in Common Name field, "
                    "probably a malicious certificate", name);
                goto err;
@@ -282,7 +287,8 @@ tls_check_common_name(struct tls *ctx, X509 *cert, const char *name,
 
        common_name = strndup(utf8_bytes, common_name_len);
        if (common_name == NULL) {
-               tls_set_error(ctx, "out of memory");
+               tls_set_error(ctx, TLS_ERROR_OUT_OF_MEMORY,
+                   "out of memory");
                goto err;
        }