Patches gpg-agent + scute for ssl/tls auth using opengpg card with 2048 rsa key
Werner Koch
wk at gnupg.org
Fri Sep 12 15:50:17 CEST 2014
On Sun, 31 Aug 2014 12:04, oliverml1 at oli1170.net said:
> I prefer to leave the tuning of the details to the specialists ;).
Well, I coded something up but did not test it. Can you please apply
the attached patch to Scute and try it? No need for any GnuPG patches.
Salam-Shalom,
Werner
>From a797aae1476601cdde7152174c02c5cc4447bcc5 Mon Sep 17 00:00:00 2001
From: Werner Koch <wk at gnupg.org>
Date: Fri, 12 Sep 2014 15:46:41 +0200
Subject: [PATCH] Allow signing with other algorithms than MD5+SHA1.
* src/support.h (STR, STR2): NEw.
* src/agent.c (sha1_prefix, sha224_prefix, sha256_prefix)
(sha384_prefix, sha512_prefix): New.
(scute_agent_sign): Increase MAX_DATA_LEN to 64. Determine hash
algorithm by checking the ASN.1 prefixes.
---
src/agent.c | 105 ++++++++++++++++++++++++++++++++++++++++++---------------
src/support.h | 10 ++++--
2 files changed, 85 insertions(+), 30 deletions(-)
diff --git a/src/agent.c b/src/agent.c
index 9265ca2..edf8d2d 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -2,7 +2,7 @@
Copyright (C) 2006, 2007, 2008 g10 Code GmbH
This file is part of Scute.
-
+
Scute 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 2 of the License, or
@@ -65,7 +65,7 @@ static int agent_version_minor;
/* Hack required for Windows. */
-void
+void
gnupg_allow_set_foregound_window (pid_t pid)
{
if (!pid || pid == (pid_t)(-1))
@@ -111,7 +111,7 @@ build_w32_commandline_copy (char *buffer, const char *string)
/* Build a command line for use with W32's CreateProcess. On success
CMDLINE gets the address of a newly allocated string. */
static gpg_error_t
-build_w32_commandline (const char *pgmname, const char * const *argv,
+build_w32_commandline (const char *pgmname, const char * const *argv,
char **cmdline)
{
int i, n;
@@ -139,7 +139,7 @@ build_w32_commandline (const char *pgmname, const char * const *argv,
return gpg_error_from_syserror ();
p = build_w32_commandline_copy (p, pgmname);
- for (i=0; argv[i]; i++)
+ for (i=0; argv[i]; i++)
{
*p++ = ' ';
p = build_w32_commandline_copy (p, argv[i]);
@@ -161,7 +161,7 @@ spawn_process_detached (const char *pgmname, const char *argv[])
{
gpg_error_t err;
SECURITY_ATTRIBUTES sec_attr;
- PROCESS_INFORMATION pi =
+ PROCESS_INFORMATION pi =
{
NULL, /* Returns process handle. */
0, /* Returns primary thread handle. */
@@ -179,11 +179,11 @@ spawn_process_detached (const char *pgmname, const char *argv[])
memset (&sec_attr, 0, sizeof sec_attr );
sec_attr.nLength = sizeof sec_attr;
sec_attr.bInheritHandle = FALSE;
-
+
/* Build the command line. */
err = build_w32_commandline (pgmname, argv, &cmdline);
if (err)
- return err;
+ return err;
/* Start the process. */
memset (&si, 0, sizeof si);
@@ -194,7 +194,7 @@ spawn_process_detached (const char *pgmname, const char *argv[])
cr_flags = (CREATE_DEFAULT_ERROR_MODE
| GetPriorityClass (GetCurrentProcess ())
| CREATE_NEW_PROCESS_GROUP
- | DETACHED_PROCESS);
+ | DETACHED_PROCESS);
DEBUG (DBG_INFO, "CreateProcess(detached), path=`%s' cmdline=`%s'\n",
pgmname, cmdline);
if (!CreateProcess (pgmname, /* Program to start. */
@@ -221,7 +221,7 @@ spawn_process_detached (const char *pgmname, const char *argv[])
" dwProcessID=%d dwThreadId=%d\n", pi.hProcess, pi.hThread,
(int) pi.dwProcessId, (int) pi.dwThreadId);
- CloseHandle (pi.hThread);
+ CloseHandle (pi.hThread);
return 0;
}
@@ -280,8 +280,8 @@ agent_connect (assuan_context_t *ctx_r)
const char *argv[3];
argv[0] = "--daemon";
- argv[1] = "--use-standard-socket";
- argv[2] = NULL;
+ argv[1] = "--use-standard-socket";
+ argv[2] = NULL;
err = spawn_process_detached (agent_program, argv);
if (err)
@@ -306,15 +306,15 @@ agent_connect (assuan_context_t *ctx_r)
pgmname = agent_program;
else
pgmname++;
-
+
argv[0] = pgmname;
argv[1] = "--server";
argv[2] = NULL;
-
+
i=0;
no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
no_close_list[i] = -1;
-
+
/* Connect to the agent and perform initial handshaking. */
err = assuan_pipe_connect (ctx, agent_program, argv,
no_close_list, NULL, NULL, 0);
@@ -353,7 +353,7 @@ agent_connect (assuan_context_t *ctx_r)
force_pipe_server = 1;
goto restart;
}
-
+
err = assuan_socket_connect (ctx, infostr, pid, 0);
free (infostr);
if (err)
@@ -400,7 +400,7 @@ default_inq_cb (void *opaque, const char *line)
/* Send a simple command to the agent. */
-static gpg_error_t
+static gpg_error_t
agent_simple_cmd (assuan_context_t ctx, const char *fmt, ...)
{
gpg_error_t err;
@@ -421,7 +421,7 @@ agent_simple_cmd (assuan_context_t ctx, const char *fmt, ...)
DEBUG (DBG_CRIT, "gpg-agent command '%s' failed: %s", optstr,
gpg_strerror (err));
free (optstr);
-
+
return err;
}
@@ -432,7 +432,7 @@ read_version_cb (void *opaque, const void *buffer, size_t length)
{
char version[20];
const char *s;
-
+
if (length > sizeof (version) -1)
length = sizeof (version) - 1;
strncpy (version, buffer, length);
@@ -444,7 +444,7 @@ read_version_cb (void *opaque, const void *buffer, size_t length)
return 0;
}
-
+
/* Configure the GPG agent at connection CTX. */
static gpg_error_t
@@ -615,7 +615,7 @@ unescape_status_string (const unsigned char *src)
while (*src)
{
if (*src == '%' && src[1] && src[2])
- {
+ {
src++;
*dst = xtoi_2 (src);
if (*dst == '\0')
@@ -631,7 +631,7 @@ unescape_status_string (const unsigned char *src)
else
*(dst++) = *(src++);
}
- *dst = 0;
+ *dst = 0;
return buffer;
}
@@ -894,7 +894,7 @@ geteventcounter_status_cb (void *opaque, const char *line)
last_count = count;
}
}
-
+
return 0;
}
@@ -989,6 +989,28 @@ pksign_cb (void *opaque, const void *buffer, size_t length)
#define SIG_LEN 128
#define SIG_LEN_2 256
+
+static unsigned char sha1_prefix[15] = /* (1.3.14.3.2.26) */
+ { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
+ 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
+static unsigned char sha224_prefix[19] = /* (2.16.840.1.101.3.4.2.4) */
+ { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
+ 0x1C };
+static unsigned char sha256_prefix[19] = /* (2.16.840.1.101.3.4.2.1) */
+ { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+ 0x00, 0x04, 0x20 };
+static unsigned char sha384_prefix[19] = /* (2.16.840.1.101.3.4.2.2) */
+ { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
+ 0x00, 0x04, 0x30 };
+static unsigned char sha512_prefix[19] = /* (2.16.840.1.101.3.4.2.3) */
+ { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
+ 0x00, 0x04, 0x40 };
+
+
/* Call the agent to learn about a smartcard. */
gpg_error_t
scute_agent_sign (char *grip, unsigned char *data, int len,
@@ -996,10 +1018,12 @@ scute_agent_sign (char *grip, unsigned char *data, int len,
{
char cmd[150];
gpg_error_t err;
-#define MAX_DATA_LEN 36
+#define MAX_DATA_LEN 64 /* For SHA-512 - see below. */
unsigned char pretty_data[2 * MAX_DATA_LEN + 1];
int i;
struct signature sig;
+ const char *algostr;
+ int off;
sig.len = 0;
@@ -1025,11 +1049,38 @@ scute_agent_sign (char *grip, unsigned char *data, int len,
if (err)
return err;
+ /* Find out the digest algorithm and strip off the prefix. */
+#define X(a,b) \
+ (len == sizeof a ## _prefix + (b) \
+ && !memcmp (data, a ## _prefix, sizeof a ## _prefix)) \
+ { \
+ algostr = STR(a); \
+ off = sizeof a ## _prefix; \
+ len -= sizeof a ## _prefix; \
+ }
+
+ if (len == 36)
+ {
+ algostr = "tls-md5sha1";
+ off = 0;
+ }
+ else if X(sha1, 20)
+ else if X(sha224, 28)
+ else if X(sha256, 32)
+ else if X(sha384, 48)
+ else if X(sha512, 64) /* MAX_DATA_LEN must be at least this. */
+ else
+ {
+ DEBUG (DBG_INFO, "sign input data format is unknown, size=%d\n", len);
+ return gpg_error (GPG_ERR_DIGEST_ALGO);
+ }
+#undef X
+
for (i = 0; i < len; i++)
- snprintf (&pretty_data[2 * i], 3, "%02X", data[i]);
+ snprintf (&pretty_data[2 * i], 3, "%02X", data[off+i]);
pretty_data[2 * len] = '\0';
- snprintf (cmd, sizeof (cmd), "SETHASH --hash=tls-md5sha1 %s", pretty_data);
+ snprintf (cmd, sizeof (cmd), "SETHASH --hash=%s %s", algostr, pretty_data);
err = assuan_transact (agent_ctx, cmd, NULL, NULL, default_inq_cb,
NULL, NULL, NULL);
if (err)
@@ -1063,8 +1114,8 @@ scute_agent_sign (char *grip, unsigned char *data, int len,
memcpy (sig_result, sig.data + SIG_PREFIX_LEN, SIG_LEN);
*sig_len = SIG_LEN;
}
-
-
+
+
return 0;
}
diff --git a/src/support.h b/src/support.h
index 8f4d538..f6bb80c 100644
--- a/src/support.h
+++ b/src/support.h
@@ -2,7 +2,7 @@
Copyright (C) 2006 g10 Code GmbH
This file is part of Scute.
-
+
Scute 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 2 of the License, or
@@ -40,6 +40,10 @@
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
#define DIM(x) (sizeof (x) / sizeof (x[0]))
+#ifndef STR
+# define STR(v) #v
+#endif
+#define STR2(v) STR(v)
/* Copy a string into its location, with blank character padding. */
static inline void
@@ -64,7 +68,7 @@ scute_copy_string (char *dest, char *src, int max_len)
#ifndef HAVE_TTYNAME
/* Systems without ttyname (W32) will merely return NULL. */
static inline char *
-ttyname (int fd)
+ttyname (int fd)
{
return NULL;
}
@@ -96,5 +100,5 @@ const char *default_homedir (void);
char *make_filename (const char *first_part, ...);
-
+
#endif /* !SUPPORT_H */
--
1.7.7.1
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
More information about the Gnupg-devel
mailing list