mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-21 14:47:03 +01:00
Allow generation of card keys up to 4096 bit.
This patch implementes a chunk mode to pass the key parameters from scdaemon to gpg. This allows to pass arbitrary long key paremeters; it is used for keys larger than 3072 bit.
This commit is contained in:
parent
3fe9938202
commit
fb44677c9f
4
NEWS
4
NEWS
@ -1,6 +1,10 @@
|
||||
Noteworthy changes in version 2.0.18 (unreleased)
|
||||
-------------------------------------------------
|
||||
|
||||
* Allow generation of card keys up to 4096 bit.
|
||||
|
||||
* Bug fix for newer versions of Libgcrypt.
|
||||
|
||||
|
||||
Noteworthy changes in version 2.0.17 (2011-01-13)
|
||||
-------------------------------------------------
|
||||
|
44
configure.ac
44
configure.ac
@ -1,19 +1,19 @@
|
||||
# configure.ac - for GnuPG 2.0
|
||||
# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
# 2006, 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
|
||||
#
|
||||
#
|
||||
# This file is part of GnuPG.
|
||||
#
|
||||
#
|
||||
# GnuPG 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.
|
||||
#
|
||||
#
|
||||
# GnuPG 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 General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
@ -31,7 +31,7 @@ m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \
|
||||
| sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)]))
|
||||
m4_define([git_revision], m4_esyscmd([git branch -v 2>/dev/null \
|
||||
| awk '/^\* / {printf "%s",$3}']))
|
||||
AC_INIT([gnupg],
|
||||
AC_INIT([gnupg],
|
||||
[my_version[]m4_if(my_issvn,[yes],
|
||||
[m4_if(git_revision,[],[-svn[]svn_revision],[-git[]git_revision])])],
|
||||
[http://bugs.gnupg.org])
|
||||
@ -67,7 +67,7 @@ AC_GNU_SOURCE
|
||||
|
||||
# Some status variables.
|
||||
have_gpg_error=no
|
||||
have_libgcrypt=no
|
||||
have_libgcrypt=no
|
||||
have_libassuan=no
|
||||
have_ksba=no
|
||||
have_pth=no
|
||||
@ -369,10 +369,10 @@ AH_BOTTOM([
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
#define GNUPG_DEFAULT_HOMEDIR "c:/gnupg"
|
||||
#elif defined(__VMS)
|
||||
#define GNUPG_DEFAULT_HOMEDIR "/SYS\$LOGIN/gnupg"
|
||||
#define GNUPG_DEFAULT_HOMEDIR "/SYS\$LOGIN/gnupg"
|
||||
#else
|
||||
#define GNUPG_DEFAULT_HOMEDIR "~/.gnupg"
|
||||
#endif
|
||||
#endif
|
||||
#define GNUPG_PRIVATE_KEYS_DIR "private-keys-v1.d"
|
||||
|
||||
/* For some systems (DOS currently), we hardcode the path here. For
|
||||
@ -380,7 +380,7 @@ AH_BOTTOM([
|
||||
the values may be overridden by the make invocations; this is to
|
||||
comply with the GNU coding standards. */
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
/* FIXME: We need to use a function to determine these values depending
|
||||
/* FIXME: We need to use a function to determine these values depending
|
||||
on the actual installation directory. */
|
||||
#define GNUPG_BINDIR "c:\\gnupg"
|
||||
#define GNUPG_LIBEXECDIR "c:\\gnupg"
|
||||
@ -574,7 +574,7 @@ esac
|
||||
|
||||
if test "$have_dosish_system" = yes; then
|
||||
AC_DEFINE(HAVE_DOSISH_SYSTEM,1,
|
||||
[Defined if we run on some of the PCDOS like systems
|
||||
[Defined if we run on some of the PCDOS like systems
|
||||
(DOS, Windoze. OS/2) with special properties like
|
||||
no file modes])
|
||||
fi
|
||||
@ -726,7 +726,7 @@ else
|
||||
*** To support concurrent access to the gpg-agent and the SCdaemon
|
||||
*** we need the support of the GNU Portable Threads Library.
|
||||
*** Download it from ftp://ftp.gnu.org/gnu/pth/
|
||||
*** On a Debian GNU/Linux system you might want to try
|
||||
*** On a Debian GNU/Linux system you might want to try
|
||||
*** apt-get install libpth-dev
|
||||
***]])
|
||||
fi
|
||||
@ -766,7 +766,7 @@ if test "$with_adns" != "no"; then
|
||||
[CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}])
|
||||
fi
|
||||
if test "$have_adns" = "yes"; then
|
||||
ADNSLIBS="-ladns"
|
||||
ADNSLIBS="-ladns"
|
||||
fi
|
||||
AC_SUBST(ADNSLIBS)
|
||||
# Newer adns versions feature a free function to be used under W32.
|
||||
@ -820,7 +820,7 @@ if test x"$use_dns_pka" = xyes || test x"$use_dns_srv" = xyes \
|
||||
#include <resolv.h>],
|
||||
[[unsigned char answer[PACKETSZ];
|
||||
res_query("foo.bar",C_IN,T_A,answer,PACKETSZ);
|
||||
dn_skipname(0,0);
|
||||
dn_skipname(0,0);
|
||||
dn_expand(0,0,0,0,0);
|
||||
]])],have_resolver=yes,have_resolver=no)
|
||||
AC_MSG_RESULT($have_resolver)
|
||||
@ -1155,7 +1155,7 @@ if test "$use_regex" = yes ; then
|
||||
CPPFLAGS="${CPPFLAGS} -I$withval/include"
|
||||
LDFLAGS="${LDFLAGS} -L$withval/lib"
|
||||
fi
|
||||
],withval="")
|
||||
],withval="")
|
||||
|
||||
# Does the system have regex functions at all?
|
||||
AC_SEARCH_LIBS([regcomp], [regex])
|
||||
@ -1215,7 +1215,7 @@ AC_CHECK_HEADER(zlib.h,
|
||||
|
||||
#
|
||||
# Check whether we can support bzip2
|
||||
#
|
||||
#
|
||||
if test "$use_bzip2" = yes ; then
|
||||
_cppflags="${CPPFLAGS}"
|
||||
_ldflags="${LDFLAGS}"
|
||||
@ -1229,7 +1229,7 @@ if test "$use_bzip2" = yes ; then
|
||||
],withval="")
|
||||
|
||||
# Checking alongside stdio.h as an early version of bzip2 (1.0)
|
||||
# required stdio.h to be included before bzlib.h, and Solaris 9 is
|
||||
# required stdio.h to be included before bzlib.h, and Solaris 9 is
|
||||
# woefully out of date.
|
||||
if test "$withval" != no ; then
|
||||
AC_CHECK_HEADER(bzlib.h,
|
||||
@ -1254,7 +1254,7 @@ GNUPG_CHECK_READLINE
|
||||
#
|
||||
# Allow users to append something to the version string without
|
||||
# flagging it as development version. The user version parts is
|
||||
# considered everything after a dash.
|
||||
# considered everything after a dash.
|
||||
#
|
||||
if test "$development_version" != yes; then
|
||||
changequote(,)dnl
|
||||
@ -1428,7 +1428,7 @@ die=no
|
||||
if test "$have_gpg_error" = "no"; then
|
||||
die=yes
|
||||
AC_MSG_NOTICE([[
|
||||
***
|
||||
***
|
||||
*** You need libgpg-error to build this program.
|
||||
** This library is for example available at
|
||||
*** ftp://ftp.gnupg.org/gcrypt/libgpg-error
|
||||
@ -1438,7 +1438,7 @@ fi
|
||||
if test "$have_libgcrypt" = "no"; then
|
||||
die=yes
|
||||
AC_MSG_NOTICE([[
|
||||
***
|
||||
***
|
||||
*** You need libgcrypt to build this program.
|
||||
** This library is for example available at
|
||||
*** ftp://ftp.gnupg.org/gcrypt/libgcrypt/
|
||||
@ -1471,7 +1471,7 @@ if test "$missing_pth" = "yes"; then
|
||||
*** GNU Portable Threads Library (Pth). Please install this
|
||||
*** library first. The library is for example available at
|
||||
*** ftp://ftp.gnu.org/gnu/pth/
|
||||
*** On a Debian GNU/Linux system you can install it using
|
||||
*** On a Debian GNU/Linux system you can install it using
|
||||
*** apt-get install libpth-dev
|
||||
*** To build GnuPG for Windows you need to use the W32PTH
|
||||
*** package; available at:
|
||||
@ -1490,7 +1490,7 @@ fi
|
||||
|
||||
|
||||
|
||||
AC_CONFIG_FILES([ m4/Makefile
|
||||
AC_CONFIG_FILES([ m4/Makefile
|
||||
Makefile
|
||||
po/Makefile.in
|
||||
gl/Makefile
|
||||
@ -1517,7 +1517,7 @@ AC_OUTPUT
|
||||
|
||||
echo "
|
||||
GnuPG v${VERSION} has been configured as follows:
|
||||
|
||||
|
||||
Platform: $PRINTABLE_OS_NAME ($host)
|
||||
|
||||
OpenPGP: $build_gpg
|
||||
|
180
g10/call-agent.c
180
g10/call-agent.c
@ -1,5 +1,5 @@
|
||||
/* call-agent.c - Divert GPG operations to the agent.
|
||||
* Copyright (C) 2001, 2002, 2003, 2006, 2007,
|
||||
* Copyright (C) 2001, 2002, 2003, 2006, 2007,
|
||||
* 2008, 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
@ -23,7 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_LOCALE_H
|
||||
@ -48,7 +48,7 @@
|
||||
static assuan_context_t agent_ctx = NULL;
|
||||
static int did_early_card_test;
|
||||
|
||||
struct cipher_parm_s
|
||||
struct cipher_parm_s
|
||||
{
|
||||
assuan_context_t ctx;
|
||||
const char *ciphertext;
|
||||
@ -69,13 +69,19 @@ struct writekey_parm_s
|
||||
size_t keydatalen;
|
||||
};
|
||||
|
||||
struct genkey_parm_s
|
||||
struct genkey_parm_s
|
||||
{
|
||||
assuan_context_t ctx;
|
||||
const char *sexp;
|
||||
size_t sexplen;
|
||||
};
|
||||
|
||||
struct scd_genkey_parm_s
|
||||
{
|
||||
struct agent_card_genkey_s *cgk;
|
||||
char *savedbytes; /* Malloced space to save key parameter chunks. */
|
||||
};
|
||||
|
||||
|
||||
static gpg_error_t learn_status_cb (void *opaque, const char *line);
|
||||
|
||||
@ -99,7 +105,7 @@ status_sc_op_failure (int rc)
|
||||
write_status (STATUS_SC_OP_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -162,7 +168,7 @@ start_agent (int for_card)
|
||||
if (!rc && is_status_enabled () && info.serialno)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
|
||||
buf = xasprintf ("3 %s", info.serialno);
|
||||
write_status_text (STATUS_CARDCTRL, buf);
|
||||
xfree (buf);
|
||||
@ -174,7 +180,7 @@ start_agent (int for_card)
|
||||
did_early_card_test = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -267,7 +273,7 @@ get_serialno_cb (void *opaque, const char *line)
|
||||
memcpy (*serialno, line, n);
|
||||
(*serialno)[n] = 0;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -329,7 +335,7 @@ learn_status_cb (void *opaque, const char *line)
|
||||
{
|
||||
xfree (parm->serialno);
|
||||
parm->serialno = store_serialno (line);
|
||||
parm->is_v2 = (strlen (parm->serialno) >= 16
|
||||
parm->is_v2 = (strlen (parm->serialno) >= 16
|
||||
&& xtoi_2 (parm->serialno+12) >= 2 );
|
||||
}
|
||||
else if (keywordlen == 7 && !memcmp (keyword, "APPTYPE", keywordlen))
|
||||
@ -510,7 +516,7 @@ agent_learn (struct agent_card_info_s *info)
|
||||
/* Also try to get the key attributes. */
|
||||
if (!rc)
|
||||
agent_scd_getattr ("KEY-ATTR", info);
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -529,7 +535,7 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info)
|
||||
/* We assume that NAME does not need escaping. */
|
||||
if (12 + strlen (name) > DIM(line)-1)
|
||||
return gpg_error (GPG_ERR_TOO_LARGE);
|
||||
stpcpy (stpcpy (line, "SCD GETATTR "), name);
|
||||
stpcpy (stpcpy (line, "SCD GETATTR "), name);
|
||||
|
||||
rc = start_agent (1);
|
||||
if (rc)
|
||||
@ -537,7 +543,7 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info)
|
||||
|
||||
rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, NULL,
|
||||
learn_status_cb, info);
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -562,8 +568,8 @@ agent_scd_setattr (const char *name,
|
||||
/* We assume that NAME does not need escaping. */
|
||||
if (12 + strlen (name) > DIM(line)-1)
|
||||
return gpg_error (GPG_ERR_TOO_LARGE);
|
||||
|
||||
p = stpcpy (stpcpy (line, "SCD SETATTR "), name);
|
||||
|
||||
p = stpcpy (stpcpy (line, "SCD SETATTR "), name);
|
||||
*p++ = ' ';
|
||||
for (; valuelen; value++, valuelen--)
|
||||
{
|
||||
@ -584,7 +590,7 @@ agent_scd_setattr (const char *name,
|
||||
rc = start_agent (1);
|
||||
if (!rc)
|
||||
{
|
||||
rc = assuan_transact (agent_ctx, line, NULL, NULL,
|
||||
rc = assuan_transact (agent_ctx, line, NULL, NULL,
|
||||
default_inq_cb, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
@ -601,7 +607,7 @@ static gpg_error_t
|
||||
inq_writecert_parms (void *opaque, const char *line)
|
||||
{
|
||||
int rc;
|
||||
struct writecert_parm_s *parm = opaque;
|
||||
struct writecert_parm_s *parm = opaque;
|
||||
|
||||
if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8]))
|
||||
{
|
||||
@ -615,7 +621,7 @@ inq_writecert_parms (void *opaque, const char *line)
|
||||
|
||||
|
||||
/* Send a WRITECERT command to the SCdaemon. */
|
||||
int
|
||||
int
|
||||
agent_scd_writecert (const char *certidstr,
|
||||
const unsigned char *certdata, size_t certdatalen)
|
||||
{
|
||||
@ -634,7 +640,7 @@ agent_scd_writecert (const char *certidstr,
|
||||
parms.ctx = agent_ctx;
|
||||
parms.certdata = certdata;
|
||||
parms.certdatalen = certdatalen;
|
||||
|
||||
|
||||
rc = assuan_transact (agent_ctx, line, NULL, NULL,
|
||||
inq_writecert_parms, &parms, NULL, NULL);
|
||||
|
||||
@ -649,7 +655,7 @@ static gpg_error_t
|
||||
inq_writekey_parms (void *opaque, const char *line)
|
||||
{
|
||||
int rc;
|
||||
struct writekey_parm_s *parm = opaque;
|
||||
struct writekey_parm_s *parm = opaque;
|
||||
|
||||
if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
|
||||
{
|
||||
@ -663,7 +669,7 @@ inq_writekey_parms (void *opaque, const char *line)
|
||||
|
||||
|
||||
/* Send a WRITEKEY command to the SCdaemon. */
|
||||
int
|
||||
int
|
||||
agent_scd_writekey (int keyno, const char *serialno,
|
||||
const unsigned char *keydata, size_t keydatalen)
|
||||
{
|
||||
@ -684,7 +690,7 @@ agent_scd_writekey (int keyno, const char *serialno,
|
||||
parms.ctx = agent_ctx;
|
||||
parms.keydata = keydata;
|
||||
parms.keydatalen = keydatalen;
|
||||
|
||||
|
||||
rc = assuan_transact (agent_ctx, line, NULL, NULL,
|
||||
inq_writekey_parms, &parms, NULL, NULL);
|
||||
|
||||
@ -694,14 +700,44 @@ agent_scd_writekey (int keyno, const char *serialno,
|
||||
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
scd_genkey_cb_append_savedbytes (struct scd_genkey_parm_s *parm,
|
||||
const char *line)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
char *p;
|
||||
|
||||
if (!parm->savedbytes)
|
||||
{
|
||||
parm->savedbytes = xtrystrdup (line);
|
||||
if (!parm->savedbytes)
|
||||
err = gpg_error_from_syserror ();
|
||||
}
|
||||
else
|
||||
{
|
||||
p = xtrymalloc (strlen (parm->savedbytes) + strlen (line) + 1);
|
||||
if (!p)
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
strcpy (stpcpy (p, parm->savedbytes), line);
|
||||
xfree (parm->savedbytes);
|
||||
parm->savedbytes = p;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Status callback for the SCD GENKEY command. */
|
||||
static gpg_error_t
|
||||
scd_genkey_cb (void *opaque, const char *line)
|
||||
{
|
||||
struct agent_card_genkey_s *parm = opaque;
|
||||
struct scd_genkey_parm_s *parm = opaque;
|
||||
const char *keyword = line;
|
||||
int keywordlen;
|
||||
gpg_error_t rc;
|
||||
gpg_error_t rc = 0;
|
||||
|
||||
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
|
||||
;
|
||||
@ -710,7 +746,7 @@ scd_genkey_cb (void *opaque, const char *line)
|
||||
|
||||
if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
|
||||
{
|
||||
parm->fprvalid = unhexify_fpr (line, parm->fpr);
|
||||
parm->cgk->fprvalid = unhexify_fpr (line, parm->cgk->fpr);
|
||||
}
|
||||
else if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
|
||||
{
|
||||
@ -722,29 +758,47 @@ scd_genkey_cb (void *opaque, const char *line)
|
||||
while (spacep (line))
|
||||
line++;
|
||||
|
||||
rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
|
||||
if (rc)
|
||||
log_error ("error parsing received key data: %s\n", gpg_strerror (rc));
|
||||
else if (*name == 'n' && spacep (name+1))
|
||||
parm->n = a;
|
||||
else if (*name == 'e' && spacep (name+1))
|
||||
parm->e = a;
|
||||
if (*name == '-' && spacep (name+1))
|
||||
rc = scd_genkey_cb_append_savedbytes (parm, line);
|
||||
else
|
||||
{
|
||||
log_info ("unknown parameter name in received key data\n");
|
||||
gcry_mpi_release (a);
|
||||
if (parm->savedbytes)
|
||||
{
|
||||
rc = scd_genkey_cb_append_savedbytes (parm, line);
|
||||
if (!rc)
|
||||
rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX,
|
||||
parm->savedbytes, 0, NULL);
|
||||
}
|
||||
else
|
||||
rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
|
||||
if (rc)
|
||||
log_error ("error parsing received key data: %s\n",
|
||||
gpg_strerror (rc));
|
||||
else if (*name == 'n' && spacep (name+1))
|
||||
parm->cgk->n = a;
|
||||
else if (*name == 'e' && spacep (name+1))
|
||||
parm->cgk->e = a;
|
||||
else
|
||||
{
|
||||
log_info ("unknown parameter name in received key data\n");
|
||||
gcry_mpi_release (a);
|
||||
rc = gpg_error (GPG_ERR_INV_PARAMETER);
|
||||
}
|
||||
|
||||
xfree (parm->savedbytes);
|
||||
parm->savedbytes = NULL;
|
||||
}
|
||||
}
|
||||
else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
|
||||
{
|
||||
parm->created_at = (u32)strtoul (line, NULL, 10);
|
||||
parm->cgk->created_at = (u32)strtoul (line, NULL, 10);
|
||||
}
|
||||
else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
|
||||
{
|
||||
write_status_text (STATUS_PROGRESS, line);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Send a GENKEY command to the SCdaemon. SERIALNO is not used in
|
||||
@ -759,9 +813,13 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
|
||||
int rc;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
gnupg_isotime_t tbuf;
|
||||
struct scd_genkey_parm_s parms;
|
||||
|
||||
(void)serialno;
|
||||
|
||||
memset (&parms, 0, sizeof parms);
|
||||
parms.cgk = info;
|
||||
|
||||
rc = start_agent (1);
|
||||
if (rc)
|
||||
return rc;
|
||||
@ -774,15 +832,17 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
|
||||
memset (info, 0, sizeof *info);
|
||||
snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
|
||||
*tbuf? "--timestamp=":"", tbuf,
|
||||
force? "--force":"",
|
||||
force? "--force":"",
|
||||
keyno);
|
||||
line[DIM(line)-1] = 0;
|
||||
|
||||
memset (info, 0, sizeof *info);
|
||||
rc = assuan_transact (agent_ctx, line,
|
||||
NULL, NULL, default_inq_cb, NULL,
|
||||
scd_genkey_cb, info);
|
||||
|
||||
scd_genkey_cb, &parms);
|
||||
|
||||
xfree (parms.savedbytes);
|
||||
|
||||
status_sc_op_failure (rc);
|
||||
return rc;
|
||||
}
|
||||
@ -800,7 +860,7 @@ select_openpgp (const char *serialno)
|
||||
/* Send the serialno command to initialize the connection. Without
|
||||
a given S/N we don't care about the data returned. If the card
|
||||
has already been initialized, this is a very fast command. We
|
||||
request the openpgp card because that is what we expect.
|
||||
request the openpgp card because that is what we expect.
|
||||
|
||||
Note that an opt.limit_card_insert_tries of 1 means: No tries at
|
||||
all whereas 0 means do not limit the number of tries. Due to the
|
||||
@ -816,7 +876,7 @@ select_openpgp (const char *serialno)
|
||||
int ask;
|
||||
char *want_sn;
|
||||
char *p;
|
||||
|
||||
|
||||
want_sn = xtrystrdup (serialno);
|
||||
if (!want_sn)
|
||||
return gpg_error_from_syserror ();
|
||||
@ -824,14 +884,14 @@ select_openpgp (const char *serialno)
|
||||
if (p)
|
||||
*p = 0;
|
||||
|
||||
do
|
||||
do
|
||||
{
|
||||
ask = 0;
|
||||
err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
get_serialno_cb, &this_sn);
|
||||
if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
|
||||
ask = 1;
|
||||
ask = 1;
|
||||
else if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
|
||||
ask = 2;
|
||||
else if (err)
|
||||
@ -844,19 +904,19 @@ select_openpgp (const char *serialno)
|
||||
|
||||
xfree (this_sn);
|
||||
this_sn = NULL;
|
||||
|
||||
|
||||
if (ask)
|
||||
{
|
||||
char *formatted = NULL;
|
||||
char *ocodeset = i18n_switchto_utf8 ();
|
||||
|
||||
if (!strncmp (want_sn, "D27600012401", 12)
|
||||
if (!strncmp (want_sn, "D27600012401", 12)
|
||||
&& strlen (want_sn) == 32 )
|
||||
formatted = xtryasprintf ("(%.4s) %.8s",
|
||||
want_sn + 16, want_sn + 20);
|
||||
|
||||
|
||||
err = 0;
|
||||
desc = xtryasprintf
|
||||
desc = xtryasprintf
|
||||
("%s:\n\n"
|
||||
" \"%s\"",
|
||||
ask == 1
|
||||
@ -891,7 +951,7 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length)
|
||||
put_membuf (data, buffer, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Helper returning a command option to describe the used hash
|
||||
algorithm. See scd/command.c:cmd_pksign. */
|
||||
@ -1004,7 +1064,7 @@ agent_scd_pkdecrypt (const char *serialno,
|
||||
rc = select_openpgp (serialno);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
||||
sprintf (line, "SCD SETDATA ");
|
||||
p = line + strlen (line);
|
||||
for (i=0; i < indatalen ; i++, p += 2 )
|
||||
@ -1037,7 +1097,7 @@ agent_scd_pkdecrypt (const char *serialno,
|
||||
|
||||
|
||||
/* Send a READCERT command to the SCdaemon. */
|
||||
int
|
||||
int
|
||||
agent_scd_readcert (const char *certidstr,
|
||||
void **r_buf, size_t *r_buflen)
|
||||
{
|
||||
@ -1157,8 +1217,8 @@ agent_get_passphrase (const char *cache_id,
|
||||
int rc;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
char *arg1 = NULL;
|
||||
char *arg2 = NULL;
|
||||
char *arg3 = NULL;
|
||||
char *arg2 = NULL;
|
||||
char *arg3 = NULL;
|
||||
char *arg4 = NULL;
|
||||
membuf_t data;
|
||||
|
||||
@ -1169,7 +1229,7 @@ agent_get_passphrase (const char *cache_id,
|
||||
return rc;
|
||||
|
||||
/* Check that the gpg-agent understands the repeat option. */
|
||||
if (assuan_transact (agent_ctx,
|
||||
if (assuan_transact (agent_ctx,
|
||||
"GETINFO cmd_has_option GET_PASSPHRASE repeat",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL))
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
@ -1187,9 +1247,9 @@ agent_get_passphrase (const char *cache_id,
|
||||
if (!(arg4 = percent_plus_escape (desc_msg)))
|
||||
goto no_mem;
|
||||
|
||||
snprintf (line, DIM(line)-1,
|
||||
"GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
|
||||
repeat,
|
||||
snprintf (line, DIM(line)-1,
|
||||
"GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
|
||||
repeat,
|
||||
check? " --check --qualitybar":"",
|
||||
arg1? arg1:"X",
|
||||
arg2? arg2:"X",
|
||||
@ -1202,13 +1262,13 @@ agent_get_passphrase (const char *cache_id,
|
||||
xfree (arg4);
|
||||
|
||||
init_membuf_secure (&data, 64);
|
||||
rc = assuan_transact (agent_ctx, line,
|
||||
rc = assuan_transact (agent_ctx, line,
|
||||
membuf_data_cb, &data,
|
||||
default_inq_cb, NULL, NULL, NULL);
|
||||
|
||||
if (rc)
|
||||
xfree (get_membuf (&data, NULL));
|
||||
else
|
||||
else
|
||||
{
|
||||
put_membuf (&data, "", 1);
|
||||
*r_passphrase = get_membuf (&data, NULL);
|
||||
@ -1287,12 +1347,12 @@ agent_get_s2k_count (unsigned long *r_count)
|
||||
return err;
|
||||
|
||||
init_membuf (&data, 32);
|
||||
err = assuan_transact (agent_ctx, "GETINFO s2k_count",
|
||||
err = assuan_transact (agent_ctx, "GETINFO s2k_count",
|
||||
membuf_data_cb, &data,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (err)
|
||||
xfree (get_membuf (&data, NULL));
|
||||
else
|
||||
else
|
||||
{
|
||||
put_membuf (&data, "", 1);
|
||||
buf = get_membuf (&data, NULL);
|
||||
|
@ -1284,7 +1284,7 @@ static unsigned int
|
||||
ask_card_keysize (int keyno, unsigned int nbits)
|
||||
{
|
||||
unsigned int min_nbits = 1024;
|
||||
unsigned int max_nbits = 3072; /* GnuPG limit due to Assuan. */
|
||||
unsigned int max_nbits = 4096;
|
||||
char *prompt, *answer;
|
||||
unsigned int req_nbits;
|
||||
|
||||
|
@ -756,20 +756,29 @@ static void
|
||||
send_key_data (ctrl_t ctrl, const char *name,
|
||||
const unsigned char *a, size_t alen)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
buf = bin2hex (a, alen, NULL);
|
||||
if (!buf)
|
||||
char *buffer, *buf;
|
||||
size_t buflen;
|
||||
|
||||
buffer = buf = bin2hex (a, alen, NULL);
|
||||
if (!buffer)
|
||||
{
|
||||
log_error ("memory allocation error in send_key_data\n");
|
||||
return;
|
||||
}
|
||||
buflen = strlen (buffer);
|
||||
|
||||
/* 768 is the hexified size for the modulus of an 3072 bit key. We
|
||||
use extra chunks to transmit larger data (i.e for 4096 bit). */
|
||||
for ( ;buflen > 768; buflen -= 768, buf += 768)
|
||||
send_status_info (ctrl, "KEY-DATA",
|
||||
"-", 1,
|
||||
buf, 768,
|
||||
NULL, 0);
|
||||
send_status_info (ctrl, "KEY-DATA",
|
||||
name, (size_t)strlen(name),
|
||||
buf, (size_t)strlen (buf),
|
||||
name, (size_t)strlen(name),
|
||||
buf, buflen,
|
||||
NULL, 0);
|
||||
xfree (buf);
|
||||
xfree (buffer);
|
||||
}
|
||||
|
||||
|
||||
@ -2365,7 +2374,7 @@ change_keyattr (app_t app, int keyno, unsigned int nbits,
|
||||
|
||||
assert (keyno >=0 && keyno <= 2);
|
||||
|
||||
if (nbits > 3072)
|
||||
if (nbits > 4096)
|
||||
return gpg_error (GPG_ERR_TOO_LARGE);
|
||||
|
||||
/* Read the current attributes into a buffer. */
|
||||
@ -2823,7 +2832,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
|
||||
already lead to a 527 byte long status line and thus a 4096 bit
|
||||
key would exceed the Assuan line length limit. */
|
||||
keybits = app->app_local->keyattr[keyno].n_bits;
|
||||
if (keybits > 3072)
|
||||
if (keybits > 4096)
|
||||
return gpg_error (GPG_ERR_TOO_LARGE);
|
||||
|
||||
/* Prepare for key generation by verifying the Admin PIN. */
|
||||
@ -3377,6 +3386,8 @@ do_decipher (app_t app, const char *keyidstr,
|
||||
fixuplen = 256 - indatalen;
|
||||
else if (indatalen >= (384-16) && indatalen < 384) /* 3072 bit key. */
|
||||
fixuplen = 384 - indatalen;
|
||||
else if (indatalen >= (512-16) && indatalen < 512) /* 4096 bit key. */
|
||||
fixuplen = 512 - indatalen;
|
||||
else
|
||||
fixuplen = 0;
|
||||
|
||||
|
@ -1287,11 +1287,15 @@ static const char hlp_genkey[] =
|
||||
"\n"
|
||||
"Generate a key on-card identified by NO, which is application\n"
|
||||
"specific. Return values are application specific. For OpenPGP\n"
|
||||
"cards 2 status lines are returned:\n"
|
||||
"cards 3 status lines are returned:\n"
|
||||
"\n"
|
||||
" S KEY-FPR <hexstring>\n"
|
||||
" S KEY-CREATED-AT <seconds_since_epoch>\n"
|
||||
" S KEY-DATA [p|n] <hexdata>\n"
|
||||
" S KEY-DATA [-|p|n] <hexdata>\n"
|
||||
"\n"
|
||||
" 'p' and 'n' are the names of the RSA parameters; '-' is used to\n"
|
||||
" indicate that HEXDATA is the first chunk of a parameter given\n"
|
||||
" by the next KEY-DATA.\n"
|
||||
"\n"
|
||||
"--force is required to overwrite an already existing key. The\n"
|
||||
"KEY-CREATED-AT is required for further processing because it is\n"
|
||||
|
Loading…
x
Reference in New Issue
Block a user