|
|
|
@ -1,16 +1,32 @@
|
|
|
|
|
commit a3a4d5ea80dc34e7a14952380b85be8b1b0bc1e3
|
|
|
|
|
Author: Damien Goutte-Gattat <dgouttegattat@incenp.org>
|
|
|
|
|
Date: Wed Dec 10 01:24:36 2014 +0100
|
|
|
|
|
From 3e13d5493c74427655a7208a7bc4fcbcabda6774 Mon Sep 17 00:00:00 2001
|
|
|
|
|
From: Damien Goutte-Gattat <dgouttegattat@incenp.org>
|
|
|
|
|
Date: Wed, 28 Jan 2015 16:03:10 +0100
|
|
|
|
|
Subject: [PATCH 2/2] Remove extra nul byte in signature data
|
|
|
|
|
To: gnupg-devel@gnupg.org
|
|
|
|
|
|
|
|
|
|
Remove extra nul byte in signature data
|
|
|
|
|
|
|
|
|
|
GPG Agent prepends a nul byte in the signature value if the first
|
|
|
|
|
byte has its most signifiant bit set, to prevent it from being
|
|
|
|
|
interpreted as a sign bit. We need to remove that byte when it is
|
|
|
|
|
present.
|
|
|
|
|
* src/agent.c (scute_agent_sign): Check for extra nul byte at the
|
|
|
|
|
beginning of signature data.
|
|
|
|
|
--
|
|
|
|
|
|
|
|
|
|
GPG Agent 2.1 prepends a nul byte in the signature value if the first
|
|
|
|
|
byte has its most significant bit set, to prevent it from being
|
|
|
|
|
interpreted as a sign bit (see agent_pksign_do, in GnuPG's
|
|
|
|
|
agent/pksign.c).
|
|
|
|
|
|
|
|
|
|
But Scute expects the signature to be always of a fixed size (128 or
|
|
|
|
|
256 bytes), and it will reject a signature containing this extra nul
|
|
|
|
|
byte.
|
|
|
|
|
|
|
|
|
|
This patch makes Scute read the effective size of the signature from
|
|
|
|
|
the S-expression, and remove the prepended nul byte if present.
|
|
|
|
|
|
|
|
|
|
Signed-off-by: Damien Goutte-Gattat <dgouttegattat@incenp.org>
|
|
|
|
|
---
|
|
|
|
|
src/agent.c | 57 ++++++++++++++++++++++++++++++++-------------------------
|
|
|
|
|
1 file changed, 32 insertions(+), 25 deletions(-)
|
|
|
|
|
|
|
|
|
|
diff --git a/src/agent.c b/src/agent.c
|
|
|
|
|
index b1fdbf0..525c2a9 100644
|
|
|
|
|
index 9265ca2..547c587 100644
|
|
|
|
|
--- a/src/agent.c
|
|
|
|
|
+++ b/src/agent.c
|
|
|
|
|
@@ -981,13 +981,12 @@ pksign_cb (void *opaque, const void *buffer, size_t length)
|
|
|
|
@ -28,9 +44,9 @@ index b1fdbf0..525c2a9 100644
|
|
|
|
|
+#define SIG_MIN_LEN 128
|
|
|
|
|
+#define SIG_MAX_LEN 256
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned char sha1_prefix[15] = /* (1.3.14.3.2.26) */
|
|
|
|
|
@@ -1033,14 +1032,14 @@ scute_agent_sign (char *grip, unsigned char *data, int len,
|
|
|
|
|
/* Call the agent to learn about a smartcard. */
|
|
|
|
|
gpg_error_t
|
|
|
|
|
@@ -1009,14 +1008,14 @@ scute_agent_sign (char *grip, unsigned char *data, int len,
|
|
|
|
|
if (sig_result == NULL)
|
|
|
|
|
{
|
|
|
|
|
/* FIXME: We return the largest supported size - is that correct? */
|
|
|
|
@ -47,7 +63,7 @@ index b1fdbf0..525c2a9 100644
|
|
|
|
|
return gpg_error (GPG_ERR_INV_ARG);
|
|
|
|
|
|
|
|
|
|
snprintf (cmd, sizeof (cmd), "SIGKEY %s", grip);
|
|
|
|
|
@@ -1092,30 +1091,37 @@ scute_agent_sign (char *grip, unsigned char *data, int len,
|
|
|
|
|
@@ -1041,30 +1040,38 @@ scute_agent_sign (char *grip, unsigned char *data, int len,
|
|
|
|
|
return err;
|
|
|
|
|
|
|
|
|
|
/* FIXME: we need a real parser to cope with all kind of S-expressions. */
|
|
|
|
@ -65,42 +81,46 @@ index b1fdbf0..525c2a9 100644
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- if (sig.len != SIG_PREFIX_LEN + SIG_LEN + SIG_POSTFIX_LEN)
|
|
|
|
|
+ int data_len;
|
|
|
|
|
+ unsigned char *sig_begin;
|
|
|
|
|
+ unsigned char *sig_val;
|
|
|
|
|
+ unsigned int sig_val_len;
|
|
|
|
|
+
|
|
|
|
|
+ data_len = atoi(sig.data + SIG_PREFIX_LEN);
|
|
|
|
|
+ sig_begin = strchr(sig.data + SIG_PREFIX_LEN, ':');
|
|
|
|
|
+ if (!sig_begin) /* Invalid S-expression? */
|
|
|
|
|
+ sig_val_len = strtol (sig.data + SIG_PREFIX_LEN, (char **)&sig_val, 10);
|
|
|
|
|
+
|
|
|
|
|
+ if (*(sig_val++) != ':')
|
|
|
|
|
return gpg_error (GPG_ERR_BAD_SIGNATURE);
|
|
|
|
|
- if (memcmp (sig.data, SIG_PREFIX, SIG_PREFIX_LEN))
|
|
|
|
|
+
|
|
|
|
|
+ sig_begin += 1; /* Skip colon. */
|
|
|
|
|
+
|
|
|
|
|
+ if (sig.len != sig_begin - sig.data + data_len + SIG_POSTFIX_LEN)
|
|
|
|
|
+ if (sig.len != sig_val - sig.data + sig_val_len + SIG_POSTFIX_LEN)
|
|
|
|
|
return gpg_error (GPG_ERR_BAD_SIGNATURE);
|
|
|
|
|
- if (memcmp (sig.data + sig.len - SIG_POSTFIX_LEN,
|
|
|
|
|
- SIG_POSTFIX, SIG_POSTFIX_LEN))
|
|
|
|
|
+ if (memcmp (sig.data + sig.len - SIG_POSTFIX_LEN, SIG_POSTFIX, SIG_POSTFIX_LEN))
|
|
|
|
|
+ if (memcmp (sig.data + sig.len - SIG_POSTFIX_LEN, SIG_POSTFIX,
|
|
|
|
|
+ SIG_POSTFIX_LEN))
|
|
|
|
|
return gpg_error (GPG_ERR_BAD_SIGNATURE);
|
|
|
|
|
- memcpy (sig_result, sig.data + SIG_PREFIX_LEN, SIG_LEN);
|
|
|
|
|
- *sig_len = SIG_LEN;
|
|
|
|
|
+
|
|
|
|
|
+ if ( *sig_begin == 0 && *(sig_begin+1) & 0x80 )
|
|
|
|
|
+ if ( *sig_val == 0 && *(sig_val+1) & 0x80 )
|
|
|
|
|
+ {
|
|
|
|
|
+ /* Remove the extra nul byte that was added to prevent
|
|
|
|
|
+ * the signature from being interpreted as a negative value. */
|
|
|
|
|
+ sig_begin += 1;
|
|
|
|
|
+ data_len -= 1;
|
|
|
|
|
+ sig_val += 1;
|
|
|
|
|
+ sig_val_len -= 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ memcpy (sig_result, sig_begin, data_len);
|
|
|
|
|
+ *sig_len = data_len;
|
|
|
|
|
+ if ( sig_val_len > *sig_len )
|
|
|
|
|
+ return gpg_error (GPG_ERR_TOO_LARGE);
|
|
|
|
|
+
|
|
|
|
|
+ memcpy (sig_result, sig_val, sig_val_len);
|
|
|
|
|
+ *sig_len = sig_val_len;
|
|
|
|
|
}
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
+ else
|
|
|
|
|
+ return gpg_error( GPG_ERR_BAD_SIGNATURE ); /* Unexpected signature prefix. */
|
|
|
|
|
+ return gpg_error( GPG_ERR_BAD_SIGNATURE ); /* Unexpected prefix. */
|
|
|
|
|
+
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
|
1.8.4
|
|
|
|
|
|