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:
parent
a4fd67937c
commit
631a0de335
@ -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.
|
||||
|
143
g10/keygen.c
143
g10/keygen.c
@ -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 ),
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user