|
|
|
|
@@ -0,0 +1,248 @@
|
|
|
|
|
From 1d56f96f6ab5034d677136b9d50b5a75dff0faf5 Mon Sep 17 00:00:00 2001
|
|
|
|
|
From: Daiki Ueno <ueno@gnu.org>
|
|
|
|
|
Date: Tue, 18 Nov 2025 13:17:55 +0900
|
|
|
|
|
Subject: [PATCH] pkcs11: avoid stack overwrite when initializing a token
|
|
|
|
|
|
|
|
|
|
If gnutls_pkcs11_token_init is called with label longer than 32
|
|
|
|
|
characters, the internal storage used to blank-fill it would
|
|
|
|
|
overflow. This adds a guard to prevent that.
|
|
|
|
|
|
|
|
|
|
Signed-off-by: Daiki Ueno <ueno@gnu.org>
|
|
|
|
|
---
|
|
|
|
|
.gitignore | 2 +
|
|
|
|
|
NEWS | 4 +
|
|
|
|
|
lib/pkcs11_write.c | 5 +-
|
|
|
|
|
tests/Makefile.am | 2 +-
|
|
|
|
|
tests/pkcs11/long-label.c | 164 ++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
5 files changed, 174 insertions(+), 3 deletions(-)
|
|
|
|
|
create mode 100644 tests/pkcs11/long-label.c
|
|
|
|
|
|
|
|
|
|
Index: gnutls-3.8.10/NEWS
|
|
|
|
|
===================================================================
|
|
|
|
|
--- gnutls-3.8.10.orig/NEWS
|
|
|
|
|
+++ gnutls-3.8.10/NEWS
|
|
|
|
|
@@ -5,6 +5,12 @@ Copyright (C) 2000-2016 Free Software Fo
|
|
|
|
|
Copyright (C) 2013-2019 Nikos Mavrogiannopoulos
|
|
|
|
|
See the end for copying conditions.
|
|
|
|
|
|
|
|
|
|
+ * Version 3.8.11 (unreleased)
|
|
|
|
|
+
|
|
|
|
|
+** libgnutls: Fix stack overwrite in gnutls_pkcs11_token_init
|
|
|
|
|
+ Reported by Luigino Camastra from Aisle Research. [GNUTLS-SA-2025-11-18,
|
|
|
|
|
+ CVSS: low] [CVE-2025-9820]
|
|
|
|
|
+
|
|
|
|
|
* Version 3.8.10 (released 2025-07-08)
|
|
|
|
|
|
|
|
|
|
** libgnutls: Fix NULL pointer dereference when 2nd Client Hello omits PSK
|
|
|
|
|
Index: gnutls-3.8.10/lib/pkcs11_write.c
|
|
|
|
|
===================================================================
|
|
|
|
|
--- gnutls-3.8.10.orig/lib/pkcs11_write.c
|
|
|
|
|
+++ gnutls-3.8.10/lib/pkcs11_write.c
|
|
|
|
|
@@ -28,6 +28,7 @@
|
|
|
|
|
#include "pkcs11x.h"
|
|
|
|
|
#include "x509/common.h"
|
|
|
|
|
#include "pk.h"
|
|
|
|
|
+#include "minmax.h"
|
|
|
|
|
|
|
|
|
|
static const ck_bool_t tval = 1;
|
|
|
|
|
static const ck_bool_t fval = 0;
|
|
|
|
|
@@ -1172,7 +1173,7 @@ int gnutls_pkcs11_delete_url(const char
|
|
|
|
|
* gnutls_pkcs11_token_init:
|
|
|
|
|
* @token_url: A PKCS #11 URL specifying a token
|
|
|
|
|
* @so_pin: Security Officer's PIN
|
|
|
|
|
- * @label: A name to be used for the token
|
|
|
|
|
+ * @label: A name to be used for the token, at most 32 characters
|
|
|
|
|
*
|
|
|
|
|
* This function will initialize (format) a token. If the token is
|
|
|
|
|
* at a factory defaults state the security officer's PIN given will be
|
|
|
|
|
@@ -1210,7 +1211,7 @@ int gnutls_pkcs11_token_init(const char
|
|
|
|
|
/* so it seems memset has other uses than zeroing! */
|
|
|
|
|
memset(flabel, ' ', sizeof(flabel));
|
|
|
|
|
if (label != NULL)
|
|
|
|
|
- memcpy(flabel, label, strlen(label));
|
|
|
|
|
+ memcpy(flabel, label, MIN(sizeof(flabel), strlen(label)));
|
|
|
|
|
|
|
|
|
|
rv = pkcs11_init_token(module, slot, (uint8_t *)so_pin, strlen(so_pin),
|
|
|
|
|
(uint8_t *)flabel);
|
|
|
|
|
Index: gnutls-3.8.10/tests/Makefile.am
|
|
|
|
|
===================================================================
|
|
|
|
|
--- gnutls-3.8.10.orig/tests/Makefile.am
|
|
|
|
|
+++ gnutls-3.8.10/tests/Makefile.am
|
|
|
|
|
@@ -503,7 +503,7 @@ pathbuf_CPPFLAGS = $(AM_CPPFLAGS) \
|
|
|
|
|
if ENABLE_PKCS11
|
|
|
|
|
if !WINDOWS
|
|
|
|
|
ctests += tls13/post-handshake-with-cert-pkcs11 pkcs11/tls-neg-pkcs11-no-key \
|
|
|
|
|
- global-init-override pkcs11/distrust-after
|
|
|
|
|
+ global-init-override pkcs11/distrust-after pkcs11/long-label
|
|
|
|
|
tls13_post_handshake_with_cert_pkcs11_DEPENDENCIES = libpkcs11mock2.la libutils.la
|
|
|
|
|
tls13_post_handshake_with_cert_pkcs11_LDADD = $(LDADD) $(LIBDL)
|
|
|
|
|
pkcs11_tls_neg_pkcs11_no_key_DEPENDENCIES = libpkcs11mock2.la libutils.la
|
|
|
|
|
Index: gnutls-3.8.10/tests/pkcs11/long-label.c
|
|
|
|
|
===================================================================
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ gnutls-3.8.10/tests/pkcs11/long-label.c
|
|
|
|
|
@@ -0,0 +1,164 @@
|
|
|
|
|
+/*
|
|
|
|
|
+ * Copyright (C) 2025 Red Hat, Inc.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Author: Daiki Ueno
|
|
|
|
|
+ *
|
|
|
|
|
+ * This file is part of GnuTLS.
|
|
|
|
|
+ *
|
|
|
|
|
+ * GnuTLS is free software; you can redistribute it and/or modify it
|
|
|
|
|
+ * under the terms of the GNU General Public License as published by
|
|
|
|
|
+ * the Free Software Foundation; either version 3 of the License, or
|
|
|
|
|
+ * (at your option) any later version.
|
|
|
|
|
+ *
|
|
|
|
|
+ * GnuTLS is distributed in the hope that it will be useful, but
|
|
|
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
+ * General Public License for more details.
|
|
|
|
|
+ *
|
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public License
|
|
|
|
|
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+#ifdef HAVE_CONFIG_H
|
|
|
|
|
+#include "config.h"
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#include <stdbool.h>
|
|
|
|
|
+#include <stdio.h>
|
|
|
|
|
+#include <stdlib.h>
|
|
|
|
|
+
|
|
|
|
|
+#if defined(_WIN32)
|
|
|
|
|
+
|
|
|
|
|
+int main(void)
|
|
|
|
|
+{
|
|
|
|
|
+ exit(77);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#else
|
|
|
|
|
+
|
|
|
|
|
+#include <string.h>
|
|
|
|
|
+#include <unistd.h>
|
|
|
|
|
+#include <gnutls/gnutls.h>
|
|
|
|
|
+
|
|
|
|
|
+#include "cert-common.h"
|
|
|
|
|
+#include "pkcs11/softhsm.h"
|
|
|
|
|
+#include "utils.h"
|
|
|
|
|
+
|
|
|
|
|
+/* This program tests that a token can be initialized with
|
|
|
|
|
+ * a label longer than 32 characters.
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+static void tls_log_func(int level, const char *str)
|
|
|
|
|
+{
|
|
|
|
|
+ fprintf(stderr, "server|<%d>| %s", level, str);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#define PIN "1234"
|
|
|
|
|
+
|
|
|
|
|
+#define CONFIG_NAME "softhsm-long-label"
|
|
|
|
|
+#define CONFIG CONFIG_NAME ".config"
|
|
|
|
|
+
|
|
|
|
|
+static int pin_func(void *userdata, int attempt, const char *url,
|
|
|
|
|
+ const char *label, unsigned flags, char *pin,
|
|
|
|
|
+ size_t pin_max)
|
|
|
|
|
+{
|
|
|
|
|
+ if (attempt == 0) {
|
|
|
|
|
+ strcpy(pin, PIN);
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ return -1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void test(const char *provider)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret;
|
|
|
|
|
+ size_t i;
|
|
|
|
|
+
|
|
|
|
|
+ gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
|
|
|
|
|
+
|
|
|
|
|
+ success("test with %s\n", provider);
|
|
|
|
|
+
|
|
|
|
|
+ if (debug) {
|
|
|
|
|
+ gnutls_global_set_log_function(tls_log_func);
|
|
|
|
|
+ gnutls_global_set_log_level(4711);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* point to SoftHSM token that libpkcs11mock4.so internally uses */
|
|
|
|
|
+ setenv(SOFTHSM_ENV, CONFIG, 1);
|
|
|
|
|
+
|
|
|
|
|
+ gnutls_pkcs11_set_pin_function(pin_func, NULL);
|
|
|
|
|
+
|
|
|
|
|
+ ret = gnutls_pkcs11_add_provider(provider, "trusted");
|
|
|
|
|
+ if (ret != 0) {
|
|
|
|
|
+ fail("gnutls_pkcs11_add_provider: %s\n", gnutls_strerror(ret));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* initialize softhsm token */
|
|
|
|
|
+ ret = gnutls_pkcs11_token_init(
|
|
|
|
|
+ SOFTHSM_URL, PIN,
|
|
|
|
|
+ "this is a very long label whose length exceeds 32");
|
|
|
|
|
+ if (ret < 0) {
|
|
|
|
|
+ fail("gnutls_pkcs11_token_init: %s\n", gnutls_strerror(ret));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for (i = 0;; i++) {
|
|
|
|
|
+ char *url = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ ret = gnutls_pkcs11_token_get_url(i, 0, &url);
|
|
|
|
|
+ if (ret < 0)
|
|
|
|
|
+ break;
|
|
|
|
|
+ if (strstr(url,
|
|
|
|
|
+ "token=this%20is%20a%20very%20long%20label%20whose"))
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (ret < 0)
|
|
|
|
|
+ fail("gnutls_pkcs11_token_get_url: %s\n", gnutls_strerror(ret));
|
|
|
|
|
+
|
|
|
|
|
+ gnutls_pkcs11_deinit();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void doit(void)
|
|
|
|
|
+{
|
|
|
|
|
+ const char *bin;
|
|
|
|
|
+ const char *lib;
|
|
|
|
|
+ char buf[128];
|
|
|
|
|
+
|
|
|
|
|
+ if (gnutls_fips140_mode_enabled())
|
|
|
|
|
+ exit(77);
|
|
|
|
|
+
|
|
|
|
|
+ /* this must be called once in the program */
|
|
|
|
|
+ global_init();
|
|
|
|
|
+
|
|
|
|
|
+ /* we call gnutls_pkcs11_init manually */
|
|
|
|
|
+ gnutls_pkcs11_deinit();
|
|
|
|
|
+
|
|
|
|
|
+ /* check if softhsm module is loadable */
|
|
|
|
|
+ lib = softhsm_lib();
|
|
|
|
|
+
|
|
|
|
|
+ /* initialize SoftHSM token that libpkcs11mock4.so internally uses */
|
|
|
|
|
+ bin = softhsm_bin();
|
|
|
|
|
+
|
|
|
|
|
+ set_softhsm_conf(CONFIG);
|
|
|
|
|
+ snprintf(buf, sizeof(buf),
|
|
|
|
|
+ "%s --init-token --slot 0 --label test --so-pin " PIN
|
|
|
|
|
+ " --pin " PIN,
|
|
|
|
|
+ bin);
|
|
|
|
|
+ system(buf);
|
|
|
|
|
+
|
|
|
|
|
+ test(lib);
|
|
|
|
|
+
|
|
|
|
|
+ lib = getenv("P11MOCKLIB4");
|
|
|
|
|
+ if (lib == NULL) {
|
|
|
|
|
+ fail("P11MOCKLIB4 is not set\n");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ set_softhsm_conf(CONFIG);
|
|
|
|
|
+ snprintf(buf, sizeof(buf),
|
|
|
|
|
+ "%s --init-token --slot 0 --label test --so-pin " PIN
|
|
|
|
|
+ " --pin " PIN,
|
|
|
|
|
+ bin);
|
|
|
|
|
+ system(buf);
|
|
|
|
|
+
|
|
|
|
|
+ test(lib);
|
|
|
|
|
+}
|
|
|
|
|
+#endif /* _WIN32 */
|