mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Fixed card key generation of gpg2.
Reveal less information about timings while generating a key.
This commit is contained in:
parent
fa84b8cd82
commit
4631bc8ddf
@ -1,3 +1,7 @@
|
||||
2007-07-05 Werner Koch <wk@g10code.com>
|
||||
|
||||
* configure.ac: Require libassuan 1.0.2.
|
||||
|
||||
2007-07-05 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* configure.ac: Invoke AM_LANGINFO_CODESET.
|
||||
|
3
NEWS
3
NEWS
@ -11,6 +11,9 @@ Noteworthy changes in version 2.0.5
|
||||
* The command --gen-key may now be used instead of the
|
||||
gpgsm-gencert.sh script.
|
||||
|
||||
* Changed key generation to reveal less information about the
|
||||
machine. Bug fixes for gpg2's card key generation.
|
||||
|
||||
|
||||
Noteworthy changes in version 2.0.4 (2007-05-09)
|
||||
------------------------------------------------
|
||||
|
@ -1,3 +1,8 @@
|
||||
2007-07-05 Werner Koch <wk@g10code.com>
|
||||
|
||||
* call-scd.c (struct inq_needpin_s): New.
|
||||
(inq_needpin): Pass unknown inquiries up.
|
||||
|
||||
2007-07-04 Werner Koch <wk@g10code.com>
|
||||
|
||||
* gpg-agent.c (TIMERTICK_INTERVAL): New.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* call-scd.c - fork of the scdaemon to do SC operations
|
||||
* Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2005, 2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -79,6 +79,8 @@ struct inq_needpin_s
|
||||
assuan_context_t ctx;
|
||||
int (*getpin_cb)(void *, const char *, char*, size_t);
|
||||
void *getpin_cb_arg;
|
||||
assuan_context_t passthru; /* If not NULL, pass unknown inquiries
|
||||
up to the caller. */
|
||||
};
|
||||
|
||||
|
||||
@ -731,6 +733,36 @@ inq_needpin (void *opaque, const char *line)
|
||||
{
|
||||
rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0);
|
||||
}
|
||||
else if (parm->passthru)
|
||||
{
|
||||
unsigned char *value;
|
||||
size_t valuelen;
|
||||
int rest;
|
||||
int needrest = !strncmp (line, "KEYDATA", 8);
|
||||
|
||||
/* Pass the inquiry up to our caller. We limit the maximum
|
||||
amount to an arbitrary value. As we know that the KEYDATA
|
||||
enquiry is pretty sensitive we disable logging then */
|
||||
if ((rest = (needrest
|
||||
&& !assuan_get_flag (parm->passthru, ASSUAN_CONFIDENTIAL))))
|
||||
assuan_begin_confidential (parm->passthru);
|
||||
rc = assuan_inquire (parm->passthru, line, &value, &valuelen, 8096);
|
||||
if (rest)
|
||||
assuan_end_confidential (parm->passthru);
|
||||
if (!rc)
|
||||
{
|
||||
if ((rest = (needrest
|
||||
&& !assuan_get_flag (parm->ctx, ASSUAN_CONFIDENTIAL))))
|
||||
assuan_begin_confidential (parm->ctx);
|
||||
rc = assuan_send_data (parm->ctx, value, valuelen);
|
||||
if (rest)
|
||||
assuan_end_confidential (parm->ctx);
|
||||
xfree (value);
|
||||
}
|
||||
else
|
||||
log_error ("error forwarding inquiry `%s': %s\n",
|
||||
line, gpg_strerror (rc));
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error ("unsupported inquiry `%s'\n", line);
|
||||
@ -780,6 +812,7 @@ agent_card_pksign (ctrl_t ctrl,
|
||||
inqparm.ctx = ctrl->scd_local->ctx;
|
||||
inqparm.getpin_cb = getpin_cb;
|
||||
inqparm.getpin_cb_arg = getpin_cb_arg;
|
||||
inqparm.passthru = 0;
|
||||
snprintf (line, DIM(line)-1,
|
||||
ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid);
|
||||
line[DIM(line)-1] = 0;
|
||||
@ -850,6 +883,7 @@ agent_card_pkdecrypt (ctrl_t ctrl,
|
||||
inqparm.ctx = ctrl->scd_local->ctx;
|
||||
inqparm.getpin_cb = getpin_cb;
|
||||
inqparm.getpin_cb_arg = getpin_cb_arg;
|
||||
inqparm.passthru = 0;
|
||||
snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (ctrl->scd_local->ctx, line,
|
||||
@ -1065,8 +1099,8 @@ pass_data_thru (void *opaque, const void *buffer, size_t length)
|
||||
|
||||
/* Send the line CMDLINE with command for the SCDdaemon to it and send
|
||||
all status messages back. This command is used as a general quoting
|
||||
mechanism to pass everything verbatim to SCDAEMOPN. The PIN
|
||||
inquirey is handled inside gpg-agent. */
|
||||
mechanism to pass everything verbatim to SCDAEMON. The PIN
|
||||
inquiry is handled inside gpg-agent. */
|
||||
int
|
||||
agent_card_scd (ctrl_t ctrl, const char *cmdline,
|
||||
int (*getpin_cb)(void *, const char *, char*, size_t),
|
||||
@ -1082,6 +1116,7 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline,
|
||||
inqparm.ctx = ctrl->scd_local->ctx;
|
||||
inqparm.getpin_cb = getpin_cb;
|
||||
inqparm.getpin_cb_arg = getpin_cb_arg;
|
||||
inqparm.passthru = assuan_context;
|
||||
rc = assuan_transact (ctrl->scd_local->ctx, cmdline,
|
||||
pass_data_thru, assuan_context,
|
||||
inq_needpin, &inqparm,
|
||||
|
@ -1,3 +1,8 @@
|
||||
2007-07-05 Werner Koch <wk@g10code.com>
|
||||
|
||||
* t-gettime.c: New.
|
||||
* gettime.c (isotime2epoch, epoch2isotime): New.
|
||||
|
||||
2007-07-04 Werner Koch <wk@g10code.com>
|
||||
|
||||
* estream.c (es_init_do): Do not throw an error if pth as already
|
||||
|
@ -81,13 +81,15 @@ libgpgrl_a_SOURCES = \
|
||||
#
|
||||
# Module tests
|
||||
#
|
||||
module_tests = t-convert
|
||||
module_tests = t-convert t-gettime
|
||||
|
||||
t_common_ldadd = ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a \
|
||||
t_common_ldadd = $(libcommon) ../jnlib/libjnlib.a ../gl/libgnu.a \
|
||||
$(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV)
|
||||
|
||||
t_convert_DEPENDENCIES = convert.c libcommon.a
|
||||
t_convert_LDADD = $(t_common_ldadd)
|
||||
t_gettime_DEPENDENCIES = gettime.c libcommon.a
|
||||
t_gettime_LDADD = $(t_common_ldadd)
|
||||
|
||||
|
||||
$(PROGRAMS): ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* gettime.c - Wrapper for time functions
|
||||
* Copyright (C) 1998, 2002 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 2002, 2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -20,6 +20,7 @@
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_LANGINFO_H
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
@ -64,7 +65,7 @@ gnupg_get_isotime (gnupg_isotime_t timebuf)
|
||||
#else
|
||||
tp = gmtime (&atime);
|
||||
#endif
|
||||
sprintf (timebuf,"%04d%02d%02dT%02d%02d%02d",
|
||||
snprintf (timebuf, 16, "%04d%02d%02dT%02d%02d%02d",
|
||||
1900 + tp->tm_year, tp->tm_mon+1, tp->tm_mday,
|
||||
tp->tm_hour, tp->tm_min, tp->tm_sec);
|
||||
}
|
||||
@ -164,6 +165,78 @@ scan_isodatestr( const char *string )
|
||||
return stamp;
|
||||
}
|
||||
|
||||
/* Scan am ISO timestamp and return a epoch based timestamp. The only
|
||||
supported format is "yyyymmddThhmmss" delimited by white space, nul, a
|
||||
colon or a comma. Returns (time_t)(-1) for an invalid string. */
|
||||
time_t
|
||||
isotime2epoch (const char *string)
|
||||
{
|
||||
const char *s;
|
||||
int year, month, day, hour, minu, sec;
|
||||
struct tm tmbuf;
|
||||
int i;
|
||||
|
||||
if (!*string)
|
||||
return (time_t)(-1);
|
||||
for (s=string, i=0; i < 8; i++, s++)
|
||||
if (!digitp (s))
|
||||
return (time_t)(-1);
|
||||
if (*s != 'T')
|
||||
return (time_t)(-1);
|
||||
for (s++, i=9; i < 15; i++, s++)
|
||||
if (!digitp (s))
|
||||
return (time_t)(-1);
|
||||
if ( !(!*s || (isascii (*s) && isspace(*s)) || *s == ':' || *s == ','))
|
||||
return (time_t)(-1); /* Wrong delimiter. */
|
||||
|
||||
year = atoi_4 (string);
|
||||
month = atoi_2 (string + 4);
|
||||
day = atoi_2 (string + 6);
|
||||
hour = atoi_2 (string + 9);
|
||||
minu = atoi_2 (string + 11);
|
||||
sec = atoi_2 (string + 13);
|
||||
|
||||
/* Basic checks. */
|
||||
if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31
|
||||
|| hour > 23 || minu > 59 || sec > 61 )
|
||||
return (time_t)(-1);
|
||||
|
||||
memset (&tmbuf, 0, sizeof tmbuf);
|
||||
tmbuf.tm_sec = sec;
|
||||
tmbuf.tm_min = minu;
|
||||
tmbuf.tm_hour = hour;
|
||||
tmbuf.tm_mday = day;
|
||||
tmbuf.tm_mon = month-1;
|
||||
tmbuf.tm_year = year - 1900;
|
||||
tmbuf.tm_isdst = -1;
|
||||
return timegm (&tmbuf);
|
||||
}
|
||||
|
||||
|
||||
/* Convert an Epoch time to an iso time stamp. */
|
||||
void
|
||||
epoch2isotime (gnupg_isotime_t timebuf, time_t atime)
|
||||
{
|
||||
if (atime < 0)
|
||||
*timebuf = 0;
|
||||
else
|
||||
{
|
||||
struct tm *tp;
|
||||
#ifdef HAVE_GMTIME_R
|
||||
struct tm tmbuf;
|
||||
|
||||
tp = gmtime_r (&atime, &tmbuf);
|
||||
#else
|
||||
tp = gmtime (&atime);
|
||||
#endif
|
||||
snprintf (timebuf, 16, "%04d%02d%02dT%02d%02d%02d",
|
||||
1900 + tp->tm_year, tp->tm_mon+1, tp->tm_mday,
|
||||
tp->tm_hour, tp->tm_min, tp->tm_sec);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
u32
|
||||
add_days_to_timestamp( u32 stamp, u16 days )
|
||||
|
98
common/t-gettime.c
Normal file
98
common/t-gettime.c
Normal file
@ -0,0 +1,98 @@
|
||||
/* t-gettime.c - Module test for gettime.c
|
||||
* Copyright (C) 2007 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/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define pass() do { ; } while(0)
|
||||
#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\
|
||||
__FILE__,__LINE__, (a)); \
|
||||
errcount++; \
|
||||
} while(0)
|
||||
|
||||
static int verbose;
|
||||
static int errcount;
|
||||
#define INVALID ((time_t)(-1))
|
||||
|
||||
|
||||
static void
|
||||
test_isotime2epoch (void)
|
||||
{
|
||||
struct { const char *string; time_t expected; } array [] = {
|
||||
{ "19700101T000001", 1 },
|
||||
{ "19700101T235959", 86399 },
|
||||
{ "19980815T143712", 903191832 },
|
||||
{ "19700101T000000", 0 },
|
||||
{ "19691231T235959", INVALID },
|
||||
{ "19000101T000000", INVALID },
|
||||
{ "", INVALID },
|
||||
{ "19000101T00000", INVALID },
|
||||
{ "20010101t123456", INVALID },
|
||||
{ "20010101T123456", 978352496 },
|
||||
{ "20070629T160000", 1183132800 },
|
||||
{ "20070629T160000:", 1183132800 },
|
||||
{ "20070629T160000,", 1183132800 },
|
||||
{ "20070629T160000 ", 1183132800 },
|
||||
{ "20070629T160000\n", 1183132800 },
|
||||
{ "20070629T160000.", INVALID },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
int idx;
|
||||
u32 val;
|
||||
gnupg_isotime_t tbuf;
|
||||
|
||||
for (idx=0; array[idx].string; idx++)
|
||||
{
|
||||
val = isotime2epoch (array[idx].string);
|
||||
if (val != array[idx].expected )
|
||||
{
|
||||
fail (idx);
|
||||
if (verbose)
|
||||
fprintf (stderr, "string `%s' exp: %ld got: %ld\n",
|
||||
array[idx].string, (long)array[idx].expected,
|
||||
(long)val);
|
||||
}
|
||||
if (array[idx].expected != INVALID)
|
||||
{
|
||||
epoch2isotime (tbuf, val);
|
||||
if (strlen (tbuf) != 15)
|
||||
fail (idx);
|
||||
if (strncmp (array[idx].string, tbuf, 15))
|
||||
fail (idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (argc > 1 && !strcmp (argv[1], "--verbose"))
|
||||
verbose = 1;
|
||||
|
||||
test_isotime2epoch ();
|
||||
|
||||
return !!errcount;
|
||||
}
|
||||
|
@ -103,6 +103,8 @@ void gnupg_set_time (time_t newtime, int freeze);
|
||||
int gnupg_faked_time_p (void);
|
||||
u32 make_timestamp (void);
|
||||
u32 scan_isodatestr (const char *string);
|
||||
time_t isotime2epoch (const char *string);
|
||||
void epoch2isotime (gnupg_isotime_t timebuf, time_t atime);
|
||||
u32 add_days_to_timestamp (u32 stamp, u16 days);
|
||||
const char *strtimevalue (u32 stamp);
|
||||
const char *strtimestamp (u32 stamp); /* GMT */
|
||||
|
@ -43,7 +43,7 @@ NEED_LIBGCRYPT_API=1
|
||||
NEED_LIBGCRYPT_VERSION=1.2.2
|
||||
|
||||
NEED_LIBASSUAN_API=1
|
||||
NEED_LIBASSUAN_VERSION=0.9.3
|
||||
NEED_LIBASSUAN_VERSION=1.0.2
|
||||
|
||||
NEED_KSBA_API=1
|
||||
NEED_KSBA_VERSION=1.0.2
|
||||
|
@ -819,6 +819,13 @@ The format of this file is as follows:
|
||||
may either be entered in ISO date format (2000-08-15) or as
|
||||
number of days, weeks, month or years. Without a letter days
|
||||
are assumed.
|
||||
Creation-Date: <iso-date>
|
||||
Set the creation date of the key as stored in the key
|
||||
information and which is also part of the fingerprint
|
||||
calculation. Either a date like "1986-04-26" or a full
|
||||
timestamp like "19860426T042640" may be used. The time is
|
||||
considered to be UTC. If it is not given the current time
|
||||
is used.
|
||||
Preferences: <string>
|
||||
Set the cipher, hash, and compression preference values for
|
||||
this key. This expects the same type of string as "setpref"
|
||||
|
@ -176,10 +176,10 @@ or other purposes and don't have a corresponding certificate.
|
||||
|
||||
|
||||
@menu
|
||||
* gpg 1.4 vs. 1.9:: Relationship between the two branches.
|
||||
* GnuPG-1 and GnuPG-2:: Relationship between the two branches.
|
||||
@end menu
|
||||
|
||||
@node gpg 1.4 vs. 1.9
|
||||
@node GnuPG-1 and GnuPG-2
|
||||
@subsection Relationship between the two branches.
|
||||
|
||||
Here is a little picture showing how the components work together:
|
||||
|
@ -1,3 +1,27 @@
|
||||
2007-07-05 Werner Koch <wk@g10code.com>
|
||||
|
||||
* card-util.c (card_generate_subkey, card_store_subkey): Enable
|
||||
the code also for GnuPG-2.
|
||||
|
||||
* keygen.c (make_backsig): Add arg TIMESTAMP.
|
||||
(write_keybinding): Add arg TIMESTAMP, pass it to make_backsig.
|
||||
(write_direct_sig, write_selfsigs): Add arg TIMESTAMP.
|
||||
(gen_elg, gen_dsa, gen_rsa): Add arg TIMESTAMP.
|
||||
(do_create): Ditto.
|
||||
(do_generate_keypair): Use the same timestamp for key creation
|
||||
time and all key signatures. Return an error if write_direct_sig
|
||||
for the secret key fails.
|
||||
(generate_subkeypair): Ditto.
|
||||
(gen_card_key): New arg TIMESTAMP.
|
||||
(generate_card_subkeypair): Pass current time to gen_card_key.
|
||||
(gen_card_key_with_backup): New arg TIMESTAMP.
|
||||
(read_parameter_file): Add option Creation-Date.
|
||||
(parse_creation_string): New.
|
||||
(do_generate_keypair): Use the Creation-Date if available.
|
||||
(save_unprotected_key_to_card): Use P for P and not D.
|
||||
* call-agent.c (agent_scd_genkey): Add arg CREATETIME.
|
||||
* keyedit.c (menu_backsign): Use the same timestamp for all backsigs.
|
||||
|
||||
2007-06-26 Werner Koch <wk@g10code.com>
|
||||
|
||||
* openfile.c (try_make_homedir): Support W32; use standard_homedir.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* call-agent.c - divert operations to the agent
|
||||
* Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -498,21 +498,32 @@ scd_genkey_cb (void *opaque, const char *line)
|
||||
}
|
||||
|
||||
/* Send a GENKEY command to the SCdaemon. SERIALNO is not used in
|
||||
this implementation. */
|
||||
this implementation. If CREATEDATE has been given, it will be
|
||||
passed to SCDAEMON so that the key can be created with this
|
||||
timestamp; note the user needs to use the returned timestamp as old
|
||||
versions of scddaemon don't support this option. */
|
||||
int
|
||||
agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
|
||||
const char *serialno)
|
||||
const char *serialno, u32 createtime)
|
||||
{
|
||||
int rc;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
gnupg_isotime_t tbuf;
|
||||
|
||||
rc = start_agent ();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (createtime)
|
||||
epoch2isotime (tbuf, createtime);
|
||||
else
|
||||
*tbuf = 0;
|
||||
|
||||
memset (info, 0, sizeof *info);
|
||||
snprintf (line, DIM(line)-1, "SCD GENKEY %s%d",
|
||||
force? "--force ":"", keyno);
|
||||
snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
|
||||
*tbuf? "--timestamp=":"", tbuf,
|
||||
force? "--force":"",
|
||||
keyno);
|
||||
line[DIM(line)-1] = 0;
|
||||
|
||||
memset (info, 0, sizeof *info);
|
||||
|
@ -82,7 +82,7 @@ int agent_scd_writekey (int keyno, const char *serialno,
|
||||
|
||||
/* Send a GENKEY command to the SCdaemon. */
|
||||
int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
|
||||
const char *serialno);
|
||||
const char *serialno, u32 createtime);
|
||||
|
||||
/* Send a PKSIGN command to the SCdaemon. */
|
||||
int agent_scd_pksign (const char *keyid, int hashalgo,
|
||||
|
@ -999,7 +999,7 @@ restore_forced_chv1 (int *forced_chv1)
|
||||
}
|
||||
}
|
||||
|
||||
#if GNUPG_MAJOR_VERSION == 1
|
||||
|
||||
/* Helper for the key generation/edit functions. */
|
||||
static void
|
||||
show_card_key_info (struct agent_card_info_s *info)
|
||||
@ -1012,9 +1012,8 @@ show_card_key_info (struct agent_card_info_s *info)
|
||||
print_sha1_fpr (NULL, info->fpr3valid? info->fpr3:NULL);
|
||||
tty_printf ("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GNUPG_MAJOR_VERSION == 1
|
||||
|
||||
/* Helper for the key generation/edit functions. */
|
||||
static int
|
||||
replace_existing_key_p (struct agent_card_info_s *info, int keyno)
|
||||
@ -1034,7 +1033,6 @@ replace_existing_key_p (struct agent_card_info_s *info, int keyno)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
@ -1104,7 +1102,6 @@ generate_card_keys (const char *serialno)
|
||||
int
|
||||
card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
|
||||
{
|
||||
#if GNUPG_MAJOR_VERSION == 1
|
||||
struct agent_card_info_s info;
|
||||
int okay = 0;
|
||||
int forced_chv1 = 0;
|
||||
@ -1151,9 +1148,6 @@ card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
|
||||
agent_release_card_info (&info);
|
||||
restore_forced_chv1 (&forced_chv1);
|
||||
return okay;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1164,7 +1158,6 @@ card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
|
||||
int
|
||||
card_store_subkey (KBNODE node, int use)
|
||||
{
|
||||
#if GNUPG_MAJOR_VERSION == 1
|
||||
struct agent_card_info_s info;
|
||||
int okay = 0;
|
||||
int rc;
|
||||
@ -1266,7 +1259,7 @@ card_store_subkey (KBNODE node, int use)
|
||||
n = pubkey_get_nskey (sk->pubkey_algo);
|
||||
for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; i++)
|
||||
{
|
||||
mpi_free (sk->skey[i]);
|
||||
gcry_mpi_release (sk->skey[i]);
|
||||
sk->skey[i] = NULL;
|
||||
}
|
||||
i = pubkey_get_npkey (sk->pubkey_algo);
|
||||
@ -1285,9 +1278,6 @@ card_store_subkey (KBNODE node, int use)
|
||||
free_secret_key (copied_sk);
|
||||
agent_release_card_info (&info);
|
||||
return okay;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -3652,6 +3652,7 @@ menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
|
||||
PKT_public_key *main_pk;
|
||||
PKT_secret_key *main_sk,*sub_sk=NULL;
|
||||
KBNODE node;
|
||||
u32 timestamp;
|
||||
|
||||
assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
|
||||
assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
|
||||
@ -3661,6 +3662,10 @@ menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
|
||||
main_sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
|
||||
keyid_from_pk(main_pk,NULL);
|
||||
|
||||
/* We use the same timestamp for all backsigs so that we don't
|
||||
reveal information about the used machine. */
|
||||
timestamp = make_timestamp ();
|
||||
|
||||
for(node=pub_keyblock;node;node=node->next)
|
||||
{
|
||||
PKT_public_key *sub_pk=NULL;
|
||||
@ -3748,7 +3753,8 @@ menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
|
||||
set_next_passphrase(passphrase);
|
||||
xfree(passphrase);
|
||||
|
||||
rc=make_backsig(sig_pk->pkt->pkt.signature,main_pk,sub_pk,sub_sk);
|
||||
rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_sk,
|
||||
timestamp);
|
||||
if(rc==0)
|
||||
{
|
||||
PKT_signature *newsig;
|
||||
|
587
g10/keygen.c
587
g10/keygen.c
File diff suppressed because it is too large
Load Diff
@ -198,7 +198,8 @@ int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
|
||||
int keygen_add_notations(PKT_signature *sig,void *opaque);
|
||||
int keygen_add_revkey(PKT_signature *sig, void *opaque);
|
||||
int make_backsig(PKT_signature *sig,PKT_public_key *pk,
|
||||
PKT_public_key *sub_pk,PKT_secret_key *sub_sk);
|
||||
PKT_public_key *sub_pk,PKT_secret_key *sub_sk,
|
||||
u32 timestamp);
|
||||
int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
||||
#ifdef ENABLE_CARD_SUPPORT
|
||||
int generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
|
||||
|
368
po/pt_BR.po
368
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
368
po/zh_CN.po
368
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
368
po/zh_TW.po
368
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,14 @@
|
||||
2007-07-05 Werner Koch <wk@g10code.com>
|
||||
|
||||
* command.c (has_option_name, skip_options): New.
|
||||
(cmd_genkey): Add option --timestamp.
|
||||
(cmd_writekey): Enter confidential mode while inquiring the key data.
|
||||
|
||||
* app.c (app_genkey): Add arg CREATETIME.
|
||||
* app-common.h (app_ctx_s): Likewise
|
||||
* app-openpgp.c (do_genkey): Ditto. Use it.
|
||||
|
||||
|
||||
2007-07-04 Werner Koch <wk@g10code.com>
|
||||
|
||||
* command.c (cmd_getinfo): New subcommand "version".
|
||||
|
@ -97,6 +97,7 @@ struct app_ctx_s {
|
||||
const unsigned char *pk, size_t pklen);
|
||||
gpg_error_t (*genkey) (app_t app, ctrl_t ctrl,
|
||||
const char *keynostr, unsigned int flags,
|
||||
time_t createtime,
|
||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg);
|
||||
gpg_error_t (*change_pin) (app_t app, ctrl_t ctrl,
|
||||
@ -167,6 +168,7 @@ gpg_error_t app_writekey (app_t app, ctrl_t ctrl,
|
||||
const unsigned char *keydata, size_t keydatalen);
|
||||
gpg_error_t app_genkey (app_t app, ctrl_t ctrl,
|
||||
const char *keynostr, unsigned int flags,
|
||||
time_t createtime,
|
||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg);
|
||||
gpg_error_t app_get_challenge (app_t app, size_t nbytes,
|
||||
|
@ -1981,6 +1981,7 @@ do_writekey (app_t app, ctrl_t ctrl,
|
||||
/* Handle the GENKEY command. */
|
||||
static gpg_error_t
|
||||
do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
|
||||
time_t createtime,
|
||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg)
|
||||
{
|
||||
@ -2014,7 +2015,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Prepare for key generation by verifying the ADmin PIN. */
|
||||
/* Prepare for key generation by verifying the Admin PIN. */
|
||||
rc = verify_chv3 (app, pincb, pincb_arg);
|
||||
if (rc)
|
||||
goto leave;
|
||||
@ -2067,7 +2068,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
|
||||
/* log_printhex ("RSA e:", e, elen); */
|
||||
send_key_data (ctrl, "e", e, elen);
|
||||
|
||||
created_at = gnupg_get_time ();
|
||||
created_at = createtime? createtime : gnupg_get_time ();
|
||||
sprintf (numbuf, "%lu", (unsigned long)created_at);
|
||||
send_status_info (ctrl, "KEY-CREATED-AT",
|
||||
numbuf, (size_t)strlen(numbuf), NULL, 0);
|
||||
|
@ -766,6 +766,7 @@ app_writekey (app_t app, ctrl_t ctrl,
|
||||
/* Perform a SETATTR operation. */
|
||||
gpg_error_t
|
||||
app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
|
||||
time_t createtime,
|
||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg)
|
||||
{
|
||||
@ -780,7 +781,8 @@ app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
|
||||
err = lock_reader (app->slot);
|
||||
if (err)
|
||||
return err;
|
||||
err = app->fnc.genkey (app, ctrl, keynostr, flags, pincb, pincb_arg);
|
||||
err = app->fnc.genkey (app, ctrl, keynostr, flags,
|
||||
createtime, pincb, pincb_arg);
|
||||
unlock_reader (app->slot);
|
||||
if (opt.verbose)
|
||||
log_info ("operation genkey result: %s\n", gpg_strerror (err));
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* command.c - SCdaemon command handler
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
|
||||
* 2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -178,6 +179,41 @@ has_option (const char *line, const char *name)
|
||||
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
|
||||
}
|
||||
|
||||
/* Same as has_option but does only test for the name of the option
|
||||
and ignores an argument, i.e. with NAME being "--hash" it would
|
||||
return a pointer for "--hash" as well as for "--hash=foo". If
|
||||
thhere is no such option NULL is returned. The pointer returned
|
||||
points right behind the option name, this may be an equal sign, Nul
|
||||
or a space. */
|
||||
static const char *
|
||||
has_option_name (const char *line, const char *name)
|
||||
{
|
||||
const char *s;
|
||||
int n = strlen (name);
|
||||
|
||||
s = strstr (line, name);
|
||||
return (s && (s == line || spacep (s-1))
|
||||
&& (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Skip over options. It is assumed that leading spaces have been
|
||||
removed (this is the case for lines passed to a handler from
|
||||
assuan). Blanks after the options are also removed. */
|
||||
static char *
|
||||
skip_options (char *line)
|
||||
{
|
||||
while ( *line == '-' && line[1] == '-' )
|
||||
{
|
||||
while (*line && !spacep (line))
|
||||
line++;
|
||||
while (spacep (line))
|
||||
line++;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Convert the STRING into a newly allocated buffer while translating
|
||||
the hex numbers. Stops at the first invalid character. Blanks and
|
||||
@ -1099,7 +1135,9 @@ cmd_writekey (assuan_context_t ctx, char *line)
|
||||
return out_of_core ();
|
||||
|
||||
/* Now get the actual keydata. */
|
||||
assuan_begin_confidential (ctx);
|
||||
rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
|
||||
assuan_end_confidential (ctx);
|
||||
if (rc)
|
||||
{
|
||||
xfree (keyid);
|
||||
@ -1118,7 +1156,7 @@ cmd_writekey (assuan_context_t ctx, char *line)
|
||||
|
||||
|
||||
|
||||
/* GENKEY [--force] <no>
|
||||
/* GENKEY [--force] [--timestamp=<isodate>] <no>
|
||||
|
||||
Generate a key on-card identified by NO, which is application
|
||||
specific. Return values are application specific. For OpenPGP
|
||||
@ -1128,11 +1166,14 @@ cmd_writekey (assuan_context_t ctx, char *line)
|
||||
S KEY-CREATED-AT <seconds_since_epoch>
|
||||
S KEY-DATA [p|n] <hexdata>
|
||||
|
||||
|
||||
--force is required to overwrite an already existing key. The
|
||||
KEY-CREATED-AT is required for further processing because it is
|
||||
part of the hashed key material for the fingerprint.
|
||||
|
||||
If --timestamp is given an OpenPGP key will be created using this
|
||||
value. The value needs to be in ISO Format; e.g.
|
||||
"--timestamp=20030316T120000" and after 1970-01-01 00:00:00.
|
||||
|
||||
The public part of the key can also later be retrieved using the
|
||||
READKEY command.
|
||||
|
||||
@ -1143,19 +1184,28 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||
int rc;
|
||||
char *keyno;
|
||||
int force = has_option (line, "--force");
|
||||
int force;
|
||||
const char *s;
|
||||
time_t timestamp;
|
||||
|
||||
if ( IS_LOCKED (ctrl) )
|
||||
return gpg_error (GPG_ERR_LOCKED);
|
||||
|
||||
/* Skip over options. */
|
||||
while ( *line == '-' && line[1] == '-' )
|
||||
force = has_option (line, "--force");
|
||||
|
||||
if ((s=has_option_name (line, "--timestamp")))
|
||||
{
|
||||
while (*line && !spacep (line))
|
||||
line++;
|
||||
while (spacep (line))
|
||||
line++;
|
||||
if (*s != '=')
|
||||
return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
|
||||
timestamp = isotime2epoch (s+1);
|
||||
if (timestamp < 1)
|
||||
return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
|
||||
}
|
||||
else
|
||||
timestamp = 0;
|
||||
|
||||
|
||||
line = skip_options (line);
|
||||
if (!*line)
|
||||
return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
|
||||
keyno = line;
|
||||
@ -1172,7 +1222,8 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
||||
keyno = xtrystrdup (keyno);
|
||||
if (!keyno)
|
||||
return out_of_core ();
|
||||
rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, pin_cb, ctx);
|
||||
rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
|
||||
timestamp, pin_cb, ctx);
|
||||
xfree (keyno);
|
||||
|
||||
TEST_CARD_REMOVAL (ctrl, rc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user