1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-11-11 21:48:50 +01:00

Backport of Creation-Date parameter for unattended key generation.

This commit is contained in:
Werner Koch 2009-05-05 11:44:56 +00:00
parent a4fd67937c
commit 631a0de335
5 changed files with 185 additions and 51 deletions

View File

@ -1,5 +1,16 @@
2009-05-05 Werner Koch <wk@g10code.com>
* keygen.c (output_control_s): s/create/creation/.
(enum para_name): Add pCREATIONDATE, pKEYCREATIONDATE. Remove
pCREATETIME.
(generate_keypair): Do not set old pCREATETIME.
(parse_creation_string): New.
(proc_parameter_file): Set pCREATIONDATE.
(read_parameter_file): Add keyword "Creation-Date".
(do_generate_keypair): Remove arg TIMESTAMP. Set it using
pKEYCREATIONDATE.
(get_parameter_u32): Set a default pKEYCREATIONDATE.
* tdbio.c (lookup_hashtable): Add const to function args.
(cmp_trec_fpr): Ditto.
(tdbio_search_trust_byfpr): Remove cast.

View File

@ -57,8 +57,9 @@ enum para_name {
pPREFERENCES,
pREVOKER,
pUSERID,
pCREATIONDATE,
pKEYCREATIONDATE, /* Same in seconds since epoch. */
pEXPIREDATE,
pCREATETIME, /* in n seconds */
pKEYEXPIRE, /* in n seconds */
pSUBKEYEXPIRE, /* in n seconds */
pPASSPHRASE,
@ -77,8 +78,8 @@ struct para_data_s {
union {
DEK *dek;
STRING2KEY *s2k;
u32 create;
u32 expire;
u32 creation;
unsigned int usage;
struct revocation_key revkey;
char value[1];
@ -119,9 +120,9 @@ static byte zip_prefs[MAX_PREFS];
static int nzip_prefs;
static int mdc_available,ks_modify;
static void do_generate_keypair( struct para_data_s *para,
static void do_generate_keypair (struct para_data_s *para,
struct output_control_s *outctrl,
u32 timestamp, int card );
int card);
static int write_keyblock( IOBUF out, KBNODE node );
static int gen_card_key (int algo, int keyno, int is_primary,
KBNODE pub_root, KBNODE sec_root,
@ -1595,12 +1596,13 @@ ask_keysize( int algo )
* similar.
*/
u32
parse_expire_string(u32 timestamp,const char *string)
parse_expire_string (u32 timestamp, const char *string)
{
int mult;
u32 seconds,abs_date=0;
u32 seconds;
u32 abs_date = 0;
if( !*string )
if ( !*string )
seconds = 0;
else if ( !strncmp (string, "seconds=", 8) )
seconds = atoi (string+8);
@ -1614,6 +1616,23 @@ parse_expire_string(u32 timestamp,const char *string)
return seconds;
}
/* Parse an Creation-Date string which is either "1986-04-26" or
"19860426T042640". Returns 0 on error. */
static u32
parse_creation_string (const char *string)
{
u32 seconds;
if (!*string)
seconds = 0;
else if ( !strncmp (string, "seconds=", 8) )
seconds = atoi (string+8);
else if ( !(seconds = scan_isodatestr (string)))
seconds = isotime2seconds (string);
return seconds;
}
/* object == 0 for a key, and 1 for a sig */
u32
ask_expire_interval(u32 timestamp,int object,const char *def_expire)
@ -1678,7 +1697,7 @@ ask_expire_interval(u32 timestamp,int object,const char *def_expire)
}
cpr_kill_prompt();
trim_spaces(answer);
interval = parse_expire_string( timestamp, answer );
interval = parse_expire_string (timestamp, answer);
if( interval == (u32)-1 )
{
tty_printf(_("invalid value\n"));
@ -2121,16 +2140,56 @@ parse_revocation_key (const char *fname,
static u32
get_parameter_u32( struct para_data_s *para, enum para_name key )
{
struct para_data_s *r = get_parameter( para, key );
struct para_data_s *r;
if( !r )
r = get_parameter (para, key);
if (!r && key == pKEYCREATIONDATE)
{
/* Return a default for the creation date if it has not yet been
set. We need to set this into the parameter list so that a
second call for pKEYCREATIONDATE returns the same value. The
default is the current time unless an explicit creation date
has been specified. Checking the creation date here is only
for the case that it has not yet been parsed. */
r = get_parameter (para, pCREATIONDATE);
if (r && *r->u.value)
{
u32 seconds;
seconds = parse_creation_string (r->u.value);
if (!seconds)
log_error ("invalid creation date in line %d\n", r->lnr );
else /* Okay: Change this parameter. */
{
r->u.creation = seconds;
r->key = pKEYCREATIONDATE;
}
}
r = get_parameter (para, key);
if (!r)
{
/* Create a new parameter. */
r = xmalloc_clear (sizeof *r);
r->key = key;
r->u.creation = make_timestamp ();
r->next = para;
para = r;
}
r = get_parameter (para, key);
assert (r);
}
if (!r)
return 0;
if( r->key == pKEYCREATIONDATE )
return r->u.creation;
if( r->key == pKEYEXPIRE || r->key == pSUBKEYEXPIRE )
return r->u.expire;
if( r->key == pKEYUSAGE || r->key == pSUBKEYUSAGE )
return r->u.usage;
if( r->key == pCREATETIME )
return r->u.create;
return (unsigned int)strtoul( r->u.value, NULL, 10 );
}
@ -2171,13 +2230,6 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
size_t n;
char *p;
int have_user_id=0,err,algo;
u32 timestamp;
/* If we were told a creation time from outside, use it. Otherwise
look at the clock. */
timestamp=get_parameter_u32( para, pCREATETIME );
if(!timestamp)
timestamp=make_timestamp();
/* Check that we have all required parameters. */
r = get_parameter( para, pKEYTYPE );
@ -2315,9 +2367,9 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
/* make DEK and S2K from the Passphrase */
r = get_parameter( para, pPASSPHRASE );
if( r && *r->u.value ) {
/* we have a plain text passphrase - create a DEK from it.
* It is a little bit ridiculous to keep it ih secure memory
* but becuase we do this alwasy, why not here */
/* We have a plain text passphrase - create a DEK from it.
* It is a little bit ridiculous to keep it in secure memory
* but because we do this alwasy, why not here. */
STRING2KEY *s2k;
DEK *dek;
@ -2343,14 +2395,31 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
para = r;
}
/* make KEYEXPIRE from Expire-Date */
/* Make KEYCREATIONDATE from Creation-Date. */
r = get_parameter (para, pCREATIONDATE);
if (r && *r->u.value)
{
u32 seconds;
seconds = parse_creation_string (r->u.value);
if (!seconds)
{
log_error ("%s:%d: invalid creation date\n", fname, r->lnr );
return -1;
}
r->u.creation = seconds;
r->key = pKEYCREATIONDATE; /* Change that entry. */
}
/* Make KEYEXPIRE from Expire-Date. */
r = get_parameter( para, pEXPIREDATE );
if( r && *r->u.value )
{
u32 seconds;
seconds = parse_expire_string( timestamp, r->u.value );
if( seconds == (u32)-1 )
seconds = parse_expire_string
(get_parameter_u32 (para, pKEYCREATIONDATE), r->u.value);
if (seconds == (u32)(-1))
{
log_error("%s:%d: invalid expire date\n", fname, r->lnr );
return -1;
@ -2370,7 +2439,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
return -1;
}
do_generate_keypair( para, outctrl, timestamp, card );
do_generate_keypair (para, outctrl, card);
return 0;
}
@ -2396,6 +2465,7 @@ read_parameter_file( const char *fname )
{ "Name-Email", pNAMEEMAIL },
{ "Name-Comment", pNAMECOMMENT },
{ "Expire-Date", pEXPIREDATE },
{ "Creation-Date", pCREATIONDATE },
{ "Passphrase", pPASSPHRASE },
{ "Preferences", pPREFERENCES },
{ "Revoker", pREVOKER },
@ -2600,7 +2670,7 @@ generate_keypair (const char *fname, const char *card_serialno,
int algo;
unsigned int use;
int both = 0;
u32 timestamp,expire;
u32 expire;
struct para_data_s *para = NULL;
struct para_data_s *r;
struct output_control_s outctrl;
@ -2620,13 +2690,6 @@ generate_keypair (const char *fname, const char *card_serialno,
return;
}
timestamp=make_timestamp();
r = xmalloc_clear( sizeof *r );
r->key = pCREATETIME;
r->u.create = timestamp;
r->next = para;
para = r;
if (card_serialno)
{
#ifdef ENABLE_CARD_SUPPORT
@ -2741,7 +2804,8 @@ generate_keypair (const char *fname, const char *card_serialno,
para = r;
}
expire = ask_expire_interval(timestamp,0,NULL);
expire = ask_expire_interval (get_parameter_u32 (para, pKEYCREATIONDATE),
0, NULL);
r = xmalloc_clear( sizeof *r + 20 );
r->key = pKEYEXPIRE;
r->u.expire = expire;
@ -2878,8 +2942,8 @@ start_tree(KBNODE *tree)
}
static void
do_generate_keypair( struct para_data_s *para,struct output_control_s *outctrl,
u32 timestamp,int card )
do_generate_keypair (struct para_data_s *para,struct output_control_s *outctrl,
int card)
{
KBNODE pub_root = NULL;
KBNODE sec_root = NULL;
@ -2888,6 +2952,7 @@ do_generate_keypair( struct para_data_s *para,struct output_control_s *outctrl,
struct revocation_key *revkey;
int rc;
int did_sub = 0;
u32 timestamp;
if( outctrl->dryrun )
{
@ -2965,7 +3030,7 @@ do_generate_keypair( struct para_data_s *para,struct output_control_s *outctrl,
}
/* we create the packets as a tree of kbnodes. Because the
/* We create the packets as a tree of kbnodes. Because the
* structure we create is known in advance we simply generate a
* linked list. The first packet is a dummy packet which we flag
* as deleted. The very first packet must always be a KEY packet.
@ -2974,6 +3039,8 @@ do_generate_keypair( struct para_data_s *para,struct output_control_s *outctrl,
start_tree(&pub_root);
start_tree(&sec_root);
timestamp = get_parameter_u32 (para, pKEYCREATIONDATE);
if (!card)
{
rc = do_create( get_parameter_algo( para, pKEYTYPE ),

View File

@ -149,6 +149,7 @@ int is_file_compressed(const char *s, int *r_status);
/*-- miscutil.c --*/
u32 make_timestamp(void);
u32 scan_isodatestr( const char *string );
u32 isotime2seconds (const char *string);
const char *strtimevalue( u32 stamp );
const char *strtimestamp( u32 stamp ); /* GMT */
const char *isotimestamp( u32 stamp ); /* GMT with hh:mm:ss */

View File

@ -1,3 +1,7 @@
2009-05-05 Werner Koch <wk@g10code.com>
* miscutil.c (isotime2seconds): New.
2009-04-05 David Shaw <dshaw@jabberwocky.com>
* srv.h: Move to include/srv.h.

View File

@ -152,6 +152,57 @@ isotimestamp (u32 stamp)
return buffer;
}
/* Scan am ISO timestamp and return an Epoch based timestamp. The only
supported format is "yyyymmddThhmmss" delimited by white space, nul, a
colon or a comma. Returns 0 for an invalid string. */
u32
isotime2seconds (const char *string)
{
const char *s;
int year, month, day, hour, minu, sec;
struct tm tmbuf;
int i;
time_t result;
if (!*string)
return 0;
for (s=string, i=0; i < 8; i++, s++)
if (!digitp (s))
return 0;
if (*s != 'T')
return 0;
for (s++, i=9; i < 15; i++, s++)
if (!digitp (s))
return 0;
if ( !(!*s || (isascii (*s) && isspace(*s)) || *s == ':' || *s == ','))
return 0; /* 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 0;
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;
result = timegm (&tmbuf);
return (result == (time_t)(-1))? 0 : (u32)result;
}
/****************
* Note: this function returns local time
*/