From aa68a60301e719be3df7e08250bbc9152abd511a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 16 Jun 2008 15:48:33 +0000 Subject: [PATCH] Add controlo statement %ask-passphrase --- NEWS | 3 ++ common/homedir.c | 3 ++ doc/ChangeLog | 4 ++ doc/DETAILS | 10 +++++ g10/ChangeLog | 6 +++ g10/keygen.c | 95 ++++++++++++++++++++++++++++++++++-------------- 6 files changed, 93 insertions(+), 28 deletions(-) diff --git a/NEWS b/NEWS index efce67dea..ec7e2358d 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,9 @@ Noteworthy changes in version 2.0.10 (unreleased) * The gpg2 option --fixed-list-mode is now implicitly used and obsolete. + * New control statement %ask-passphrase for the unattended key + generation of gpg2. + Noteworthy changes in version 2.0.9 (2008-03-26) ------------------------------------------------ diff --git a/common/homedir.c b/common/homedir.c index 616565ef0..b21646c78 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -30,6 +30,9 @@ #ifndef CSIDL_LOCAL_APPDATA #define CSIDL_LOCAL_APPDATA 0x001c #endif +#ifndef CSIDL_COMMON_APPDATA +#define CSIDL_COMMON_APPDATA 0x0023 +#endif #ifndef CSIDL_FLAG_CREATE #define CSIDL_FLAG_CREATE 0x8000 #endif diff --git a/doc/ChangeLog b/doc/ChangeLog index 0eae30b77..4ee8dc450 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2008-06-16 Werner Koch + + * DETAILS (group): Document %ask-passphrase. + 2008-05-26 Werner Koch * gpgv.texi: Minor fixes. Fixes bug#918. diff --git a/doc/DETAILS b/doc/DETAILS index 720b23bad..fd47f19c1 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -789,6 +789,16 @@ The format of this file is as follows: and all keys are written to that file. If a new filename is given, this file is created (and overwrites an existing one). Both control statements must be given. + %ask-passphrase + Enable a mode where the command "passphrase" is ignored and + instead the usual passphrase dialog is used. This does not + make sense for batch key generation; however the unattended + key generation feature is also used by GUIs and this feature + relinquishes the GUI from implementing its own passphrase + entry code. This is a global option. + %no-ask-passphrase + Disable the ask-passphrase mode. + o The order of the parameters does not matter except for "Key-Type" which must be the first parameter. The parameters are only for the generated keyblock and parameters from previous key generations are not diff --git a/g10/ChangeLog b/g10/ChangeLog index 4d7c92fa5..ed1499588 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,9 @@ +2008-06-16 Werner Koch + + * keygen.c (output_control_s): Add ASK_PASSPHRASE. + (read_parameter_file): Add commands %ask-passphrase and + %no-ask-passphrase. + 2008-06-11 Werner Koch * gpg.c: Make --fixed-list-mode a dummy. diff --git a/g10/keygen.c b/g10/keygen.c index a89970003..4e8dd50b4 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -92,6 +92,7 @@ struct para_data_s { struct output_control_s { int lnr; int dryrun; + int ask_passphrase; int use_files; struct { char *fname; @@ -2527,36 +2528,70 @@ proc_parameter_file( struct para_data_s *para, const char *fname, if (parse_revocation_key (fname, para, pREVOKER)) return -1; - /* 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 because we do this always, why not here */ - STRING2KEY *s2k; - DEK *dek; + /* Make DEK and S2K from the Passphrase. */ + if (outctrl->ask_passphrase) + { + /* %ask-passphrase is active - ignore pPASSPRASE and ask. This + feature is required so that GUIs are able to do a key + creation but have gpg-agent ask for the passphrase. */ + int canceled = 0; + STRING2KEY *s2k; + DEK *dek; - s2k = xmalloc_secure( sizeof *s2k ); - s2k->mode = opt.s2k_mode; - s2k->hash_algo = S2K_DIGEST_ALGO; - set_next_passphrase( r->u.value ); - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2, - NULL, NULL); - set_next_passphrase( NULL ); - assert( dek ); - memset( r->u.value, 0, strlen(r->u.value) ); + dek = do_ask_passphrase ( &s2k, &canceled ); + if (dek) + { + r = xmalloc_clear( sizeof *r ); + r->key = pPASSPHRASE_DEK; + r->u.dek = dek; + r->next = para; + para = r; + r = xmalloc_clear( sizeof *r ); + r->key = pPASSPHRASE_S2K; + r->u.s2k = s2k; + r->next = para; + para = r; + } - r = xmalloc_clear( sizeof *r ); - r->key = pPASSPHRASE_S2K; - r->u.s2k = s2k; - r->next = para; - para = r; - r = xmalloc_clear( sizeof *r ); - r->key = pPASSPHRASE_DEK; - r->u.dek = dek; - r->next = para; - para = r; - } + if (canceled) + { + log_error ("%s:%d: key generation canceled\n", fname, r->lnr ); + return -1; + } + } + else + { + 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 in secure memory + * but because we do this always, why not here. */ + STRING2KEY *s2k; + DEK *dek; + + s2k = xmalloc_secure ( sizeof *s2k ); + s2k->mode = opt.s2k_mode; + s2k->hash_algo = S2K_DIGEST_ALGO; + set_next_passphrase ( r->u.value ); + dek = passphrase_to_dek (NULL, 0, opt.s2k_cipher_algo, s2k, 2, + NULL, NULL); + set_next_passphrase (NULL ); + assert (dek); + memset (r->u.value, 0, strlen(r->u.value)); + + r = xmalloc_clear (sizeof *r); + r->key = pPASSPHRASE_S2K; + r->u.s2k = s2k; + r->next = para; + para = r; + r = xmalloc_clear (sizeof *r); + r->key = pPASSPHRASE_DEK; + r->u.dek = dek; + r->next = para; + para = r; + } + } /* Make KEYCREATIONDATE from Creation-Date. */ r = get_parameter (para, pCREATIONDATE); @@ -2696,6 +2731,10 @@ read_parameter_file( const char *fname ) log_info("%s\n", value ); else if( !ascii_strcasecmp( keyword, "%dry-run" ) ) outctrl.dryrun = 1; + else if( !ascii_strcasecmp( keyword, "%ask-passphrase" ) ) + outctrl.ask_passphrase = 1; + else if( !ascii_strcasecmp( keyword, "%no-ask-passphrase" ) ) + outctrl.ask_passphrase = 0; else if( !ascii_strcasecmp( keyword, "%commit" ) ) { outctrl.lnr = lnr; if (proc_parameter_file( para, fname, &outctrl, 0 ))