* bugfix: duplicate command-line arguments [7dfdb3c] * Add minisign-dup-command-line-args.patch - Security fix: [gpg.fail/trustcomment] * Trusted comment injection (minisign) [6c59875] * trim(): only trim trailing \r\n, reject straight \r characters * Add minisign-gpg.fail-trustcomment.patch - Security fix: [gpg.fail/minisign] * Trusted comment injection (minisign) [a10dc92] * Bail out if the signature file contains unprintable characters * Add minisign-gpg.fail-minisign.patch OBS-URL: https://build.opensuse.org/package/show/security/minisign?expand=0&rev=8
85 lines
2.7 KiB
Diff
85 lines
2.7 KiB
Diff
From 6c5987575002b7b636f35120fa819fa990248898 Mon Sep 17 00:00:00 2001
|
|
From: Frank Denis <github@pureftpd.org>
|
|
Date: Mon, 29 Dec 2025 23:03:30 +0100
|
|
Subject: [PATCH] Bail out if the signature file contains unprintable
|
|
characters
|
|
|
|
Spotted by @two-heart, thanks!
|
|
---
|
|
src/minisign.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 55 insertions(+)
|
|
|
|
diff --git a/src/minisign.c b/src/minisign.c
|
|
index 0444716..8f82304 100644
|
|
--- a/src/minisign.c
|
|
+++ b/src/minisign.c
|
|
@@ -72,6 +72,58 @@ usage(void)
|
|
exit(2);
|
|
}
|
|
|
|
+static int
|
|
+is_printable(const char *str)
|
|
+{
|
|
+ const unsigned char *p = (const unsigned char *) (const void *) str;
|
|
+
|
|
+ while (*p != 0U) {
|
|
+ const unsigned char c = *p++;
|
|
+
|
|
+ if (c == '\t') {
|
|
+ continue;
|
|
+ } else if (c >= 0x20U && c <= 0x7eU) {
|
|
+ continue;
|
|
+ } else if (c < 0x20U || c == 0x7fU) {
|
|
+ return 0;
|
|
+ } else {
|
|
+ size_t need;
|
|
+ size_t i;
|
|
+ uint32_t cp;
|
|
+
|
|
+ if (c >= 0xc2U && c <= 0xdfU) {
|
|
+ need = 1U;
|
|
+ } else if (c >= 0xe0U && c <= 0xefU) {
|
|
+ need = 2U;
|
|
+ } else if (c >= 0xf0U && c <= 0xf4U) {
|
|
+ need = 3U;
|
|
+ } else {
|
|
+ return 0;
|
|
+ }
|
|
+ for (i = 1U; i <= need; i++) {
|
|
+ const unsigned char cc = p[i - 1U];
|
|
+
|
|
+ if (cc == 0U || (cc & 0xc0U) != 0x80U) {
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ if ((c == 0xe0U && p[0] < 0xa0U) || (c == 0xedU && p[0] > 0x9fU) ||
|
|
+ (c == 0xf0U && p[0] < 0x90U) || (c == 0xf4U && p[0] > 0x8fU)) {
|
|
+ return 0;
|
|
+ }
|
|
+ cp = (uint32_t) (c & (need == 1U ? 0x1fU : need == 2U ? 0x0fU : 0x07U));
|
|
+ for (i = 1U; i <= need; i++) {
|
|
+ cp = (cp << 6) | (uint32_t) (p[i - 1U] & 0x3fU);
|
|
+ }
|
|
+ if (cp <= 0x1fU || (cp >= 0x7fU && cp <= 0x9fU)) {
|
|
+ return 0;
|
|
+ }
|
|
+ p += need;
|
|
+ }
|
|
+ }
|
|
+ return 1;
|
|
+}
|
|
+
|
|
static unsigned char *
|
|
message_load_hashed(size_t *message_len, const char *message_file)
|
|
{
|
|
@@ -201,6 +253,9 @@ sig_load(const char *sig_file, unsigned char global_sig[crypto_sign_BYTES], int
|
|
if (trim(trusted_comment) == 0) {
|
|
exit_msg("Trusted comment too long");
|
|
}
|
|
+ if (is_printable(trusted_comment) == 0) {
|
|
+ exit_msg("Signature file contains unprintable characters");
|
|
+ }
|
|
global_sig_s_size = B64_MAX_LEN_FROM_BIN_LEN(crypto_sign_BYTES) + 2U;
|
|
global_sig_s = xmalloc(global_sig_s_size);
|
|
if (fgets(global_sig_s, (int) global_sig_s_size, fp) == NULL) {
|