-/* $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>
*
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;
}
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;
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;
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;
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;
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);
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;
}
}
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;
}
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) {
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) {
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;
}
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;
}
}
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);
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;
}
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;
}
}
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;
}
}
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);
}
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);
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);
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;
}
}
} 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);
}
}
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;
}
}
if (buflen > INT_MAX) {
- tls_set_errorx(ctx, "buflen too long");
+ tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+ "buflen too long");
goto out;
}
}
if (buflen > INT_MAX) {
- tls_set_errorx(ctx, "buflen too long");
+ tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
+ "buflen too long");
goto out;
}
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;
}
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;
}
}
}
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;
}
-/* $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>
*
#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;
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);
-/* $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>
*
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;
}
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);
-/* $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>
*
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;
}
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;
}
}
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;
}
}
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;
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;
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;
}
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;
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;
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;
}
}
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;
}
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;
}
}
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;
}
}
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;
}
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;
}
}
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;
}
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;
}
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;
}
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;
}
}
-/* $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>
*
*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;
}
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;
}
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)
{
*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;
}
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;
}
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;
}
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);
}
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);
}
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;
}
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;
}
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);
}
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));
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);
}
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);
}
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);
}
-/* $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>
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;
}
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;
}
-/* $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>
struct tls_error {
char *msg;
+ int code;
int errno_value;
int tls;
};
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);
-/* $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>
*
*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;
}
-/* $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>
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;
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;
}
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;
}
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;
}
/* 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;
}
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;
}
/* 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;
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);
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;
-/* $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>
*
/* 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);
}
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);
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);
}
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;
}
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;
}
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;
}
}
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;
}
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;
}
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;
}
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;
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;
}
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;
}
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;
}
-/* $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>
*
/* 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;
}
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;
}
/* 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;
}
} 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);
}
*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);
}
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);
}
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);
}
-/* $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>
*
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;
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",
* 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);
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;
* 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;
* 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;
* 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;
* 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;
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;
}