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>
|
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.
|
* tdbio.c (lookup_hashtable): Add const to function args.
|
||||||
(cmp_trec_fpr): Ditto.
|
(cmp_trec_fpr): Ditto.
|
||||||
(tdbio_search_trust_byfpr): Remove cast.
|
(tdbio_search_trust_byfpr): Remove cast.
|
||||||
|
169
g10/keygen.c
169
g10/keygen.c
@ -57,8 +57,9 @@ enum para_name {
|
|||||||
pPREFERENCES,
|
pPREFERENCES,
|
||||||
pREVOKER,
|
pREVOKER,
|
||||||
pUSERID,
|
pUSERID,
|
||||||
|
pCREATIONDATE,
|
||||||
|
pKEYCREATIONDATE, /* Same in seconds since epoch. */
|
||||||
pEXPIREDATE,
|
pEXPIREDATE,
|
||||||
pCREATETIME, /* in n seconds */
|
|
||||||
pKEYEXPIRE, /* in n seconds */
|
pKEYEXPIRE, /* in n seconds */
|
||||||
pSUBKEYEXPIRE, /* in n seconds */
|
pSUBKEYEXPIRE, /* in n seconds */
|
||||||
pPASSPHRASE,
|
pPASSPHRASE,
|
||||||
@ -77,8 +78,8 @@ struct para_data_s {
|
|||||||
union {
|
union {
|
||||||
DEK *dek;
|
DEK *dek;
|
||||||
STRING2KEY *s2k;
|
STRING2KEY *s2k;
|
||||||
u32 create;
|
|
||||||
u32 expire;
|
u32 expire;
|
||||||
|
u32 creation;
|
||||||
unsigned int usage;
|
unsigned int usage;
|
||||||
struct revocation_key revkey;
|
struct revocation_key revkey;
|
||||||
char value[1];
|
char value[1];
|
||||||
@ -119,9 +120,9 @@ static byte zip_prefs[MAX_PREFS];
|
|||||||
static int nzip_prefs;
|
static int nzip_prefs;
|
||||||
static int mdc_available,ks_modify;
|
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,
|
struct output_control_s *outctrl,
|
||||||
u32 timestamp, int card );
|
int card);
|
||||||
static int write_keyblock( IOBUF out, KBNODE node );
|
static int write_keyblock( IOBUF out, KBNODE node );
|
||||||
static int gen_card_key (int algo, int keyno, int is_primary,
|
static int gen_card_key (int algo, int keyno, int is_primary,
|
||||||
KBNODE pub_root, KBNODE sec_root,
|
KBNODE pub_root, KBNODE sec_root,
|
||||||
@ -1595,25 +1596,43 @@ ask_keysize( int algo )
|
|||||||
* similar.
|
* similar.
|
||||||
*/
|
*/
|
||||||
u32
|
u32
|
||||||
parse_expire_string(u32 timestamp,const char *string)
|
parse_expire_string (u32 timestamp, const char *string)
|
||||||
{
|
{
|
||||||
int mult;
|
int mult;
|
||||||
u32 seconds,abs_date=0;
|
u32 seconds;
|
||||||
|
u32 abs_date = 0;
|
||||||
|
|
||||||
if( !*string )
|
if ( !*string )
|
||||||
seconds = 0;
|
seconds = 0;
|
||||||
else if ( !strncmp (string, "seconds=", 8) )
|
else if ( !strncmp (string, "seconds=", 8) )
|
||||||
seconds = atoi (string+8);
|
seconds = atoi (string+8);
|
||||||
else if( (abs_date = scan_isodatestr(string)) && abs_date > timestamp )
|
else if( (abs_date = scan_isodatestr(string)) && abs_date > timestamp )
|
||||||
seconds = abs_date - timestamp;
|
seconds = abs_date - timestamp;
|
||||||
else if( (mult=check_valid_days(string)) )
|
else if( (mult=check_valid_days(string)) )
|
||||||
seconds = atoi(string) * 86400L * mult;
|
seconds = atoi(string) * 86400L * mult;
|
||||||
else
|
else
|
||||||
seconds=(u32)-1;
|
seconds=(u32)-1;
|
||||||
|
|
||||||
return seconds;
|
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 */
|
/* object == 0 for a key, and 1 for a sig */
|
||||||
u32
|
u32
|
||||||
ask_expire_interval(u32 timestamp,int object,const char *def_expire)
|
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();
|
cpr_kill_prompt();
|
||||||
trim_spaces(answer);
|
trim_spaces(answer);
|
||||||
interval = parse_expire_string( timestamp, answer );
|
interval = parse_expire_string (timestamp, answer);
|
||||||
if( interval == (u32)-1 )
|
if( interval == (u32)-1 )
|
||||||
{
|
{
|
||||||
tty_printf(_("invalid value\n"));
|
tty_printf(_("invalid value\n"));
|
||||||
@ -2121,16 +2140,56 @@ parse_revocation_key (const char *fname,
|
|||||||
static u32
|
static u32
|
||||||
get_parameter_u32( struct para_data_s *para, enum para_name key )
|
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);
|
||||||
return 0;
|
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 )
|
if( r->key == pKEYEXPIRE || r->key == pSUBKEYEXPIRE )
|
||||||
return r->u.expire;
|
return r->u.expire;
|
||||||
if( r->key == pKEYUSAGE || r->key == pSUBKEYUSAGE )
|
if( r->key == pKEYUSAGE || r->key == pSUBKEYUSAGE )
|
||||||
return r->u.usage;
|
return r->u.usage;
|
||||||
if( r->key == pCREATETIME )
|
|
||||||
return r->u.create;
|
|
||||||
|
|
||||||
return (unsigned int)strtoul( r->u.value, NULL, 10 );
|
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;
|
size_t n;
|
||||||
char *p;
|
char *p;
|
||||||
int have_user_id=0,err,algo;
|
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. */
|
/* Check that we have all required parameters. */
|
||||||
r = get_parameter( para, pKEYTYPE );
|
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 */
|
/* make DEK and S2K from the Passphrase */
|
||||||
r = get_parameter( para, pPASSPHRASE );
|
r = get_parameter( para, pPASSPHRASE );
|
||||||
if( r && *r->u.value ) {
|
if( r && *r->u.value ) {
|
||||||
/* we have a plain text passphrase - create a DEK from it.
|
/* We have a plain text passphrase - create a DEK from it.
|
||||||
* It is a little bit ridiculous to keep it ih secure memory
|
* It is a little bit ridiculous to keep it in secure memory
|
||||||
* but becuase we do this alwasy, why not here */
|
* but because we do this alwasy, why not here. */
|
||||||
STRING2KEY *s2k;
|
STRING2KEY *s2k;
|
||||||
DEK *dek;
|
DEK *dek;
|
||||||
|
|
||||||
@ -2343,14 +2395,31 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
|
|||||||
para = r;
|
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 );
|
r = get_parameter( para, pEXPIREDATE );
|
||||||
if( r && *r->u.value )
|
if( r && *r->u.value )
|
||||||
{
|
{
|
||||||
u32 seconds;
|
u32 seconds;
|
||||||
|
|
||||||
seconds = parse_expire_string( timestamp, r->u.value );
|
seconds = parse_expire_string
|
||||||
if( seconds == (u32)-1 )
|
(get_parameter_u32 (para, pKEYCREATIONDATE), r->u.value);
|
||||||
|
if (seconds == (u32)(-1))
|
||||||
{
|
{
|
||||||
log_error("%s:%d: invalid expire date\n", fname, r->lnr );
|
log_error("%s:%d: invalid expire date\n", fname, r->lnr );
|
||||||
return -1;
|
return -1;
|
||||||
@ -2370,7 +2439,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_generate_keypair( para, outctrl, timestamp, card );
|
do_generate_keypair (para, outctrl, card);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2396,6 +2465,7 @@ read_parameter_file( const char *fname )
|
|||||||
{ "Name-Email", pNAMEEMAIL },
|
{ "Name-Email", pNAMEEMAIL },
|
||||||
{ "Name-Comment", pNAMECOMMENT },
|
{ "Name-Comment", pNAMECOMMENT },
|
||||||
{ "Expire-Date", pEXPIREDATE },
|
{ "Expire-Date", pEXPIREDATE },
|
||||||
|
{ "Creation-Date", pCREATIONDATE },
|
||||||
{ "Passphrase", pPASSPHRASE },
|
{ "Passphrase", pPASSPHRASE },
|
||||||
{ "Preferences", pPREFERENCES },
|
{ "Preferences", pPREFERENCES },
|
||||||
{ "Revoker", pREVOKER },
|
{ "Revoker", pREVOKER },
|
||||||
@ -2600,7 +2670,7 @@ generate_keypair (const char *fname, const char *card_serialno,
|
|||||||
int algo;
|
int algo;
|
||||||
unsigned int use;
|
unsigned int use;
|
||||||
int both = 0;
|
int both = 0;
|
||||||
u32 timestamp,expire;
|
u32 expire;
|
||||||
struct para_data_s *para = NULL;
|
struct para_data_s *para = NULL;
|
||||||
struct para_data_s *r;
|
struct para_data_s *r;
|
||||||
struct output_control_s outctrl;
|
struct output_control_s outctrl;
|
||||||
@ -2620,13 +2690,6 @@ generate_keypair (const char *fname, const char *card_serialno,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
timestamp=make_timestamp();
|
|
||||||
r = xmalloc_clear( sizeof *r );
|
|
||||||
r->key = pCREATETIME;
|
|
||||||
r->u.create = timestamp;
|
|
||||||
r->next = para;
|
|
||||||
para = r;
|
|
||||||
|
|
||||||
if (card_serialno)
|
if (card_serialno)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_CARD_SUPPORT
|
#ifdef ENABLE_CARD_SUPPORT
|
||||||
@ -2741,7 +2804,8 @@ generate_keypair (const char *fname, const char *card_serialno,
|
|||||||
para = r;
|
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 = xmalloc_clear( sizeof *r + 20 );
|
||||||
r->key = pKEYEXPIRE;
|
r->key = pKEYEXPIRE;
|
||||||
r->u.expire = expire;
|
r->u.expire = expire;
|
||||||
@ -2878,8 +2942,8 @@ start_tree(KBNODE *tree)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_generate_keypair( struct para_data_s *para,struct output_control_s *outctrl,
|
do_generate_keypair (struct para_data_s *para,struct output_control_s *outctrl,
|
||||||
u32 timestamp,int card )
|
int card)
|
||||||
{
|
{
|
||||||
KBNODE pub_root = NULL;
|
KBNODE pub_root = NULL;
|
||||||
KBNODE sec_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;
|
struct revocation_key *revkey;
|
||||||
int rc;
|
int rc;
|
||||||
int did_sub = 0;
|
int did_sub = 0;
|
||||||
|
u32 timestamp;
|
||||||
|
|
||||||
if( outctrl->dryrun )
|
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
|
* structure we create is known in advance we simply generate a
|
||||||
* linked list. The first packet is a dummy packet which we flag
|
* linked list. The first packet is a dummy packet which we flag
|
||||||
* as deleted. The very first packet must always be a KEY packet.
|
* 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(&pub_root);
|
||||||
start_tree(&sec_root);
|
start_tree(&sec_root);
|
||||||
|
|
||||||
|
timestamp = get_parameter_u32 (para, pKEYCREATIONDATE);
|
||||||
|
|
||||||
if (!card)
|
if (!card)
|
||||||
{
|
{
|
||||||
rc = do_create( get_parameter_algo( para, pKEYTYPE ),
|
rc = do_create( get_parameter_algo( para, pKEYTYPE ),
|
||||||
|
@ -149,6 +149,7 @@ int is_file_compressed(const char *s, int *r_status);
|
|||||||
/*-- miscutil.c --*/
|
/*-- miscutil.c --*/
|
||||||
u32 make_timestamp(void);
|
u32 make_timestamp(void);
|
||||||
u32 scan_isodatestr( const char *string );
|
u32 scan_isodatestr( const char *string );
|
||||||
|
u32 isotime2seconds (const char *string);
|
||||||
const char *strtimevalue( u32 stamp );
|
const char *strtimevalue( u32 stamp );
|
||||||
const char *strtimestamp( u32 stamp ); /* GMT */
|
const char *strtimestamp( u32 stamp ); /* GMT */
|
||||||
const char *isotimestamp( u32 stamp ); /* GMT with hh:mm:ss */
|
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>
|
2009-04-05 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* srv.h: Move to include/srv.h.
|
* srv.h: Move to include/srv.h.
|
||||||
|
@ -152,6 +152,57 @@ isotimestamp (u32 stamp)
|
|||||||
return buffer;
|
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
|
* Note: this function returns local time
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user