gpg: Add command --quick-gen-key

* g10/gpg.c (aQuickKeygen): New.
* g10/misc.c (is_valid_user_id): New stub.
* g10/keygen.c (quickgen_set_para): New.
(quick_generate_keypair): New.
--

Note that the validation of the specified user id has not yet been
implemented.
This commit is contained in:
Werner Koch 2014-07-23 15:12:43 +02:00
parent 75127bc456
commit ea186540db
5 changed files with 171 additions and 3 deletions

View File

@ -592,14 +592,29 @@ This section explains the main commands for key management
@table @gnupgtabopt
@ifset gpgtwoone
@item --quick-gen-key @code{user-id}
@opindex quick-gen-key
This is simple command to generate a standard key with one user id.
In contrast to @option{--gen-key} the key is generated directly
without the need to answer a bunch of prompts. Unless the option
@option{--yes} is given, the key creation will be canceled if the
given user id already exists in the key ring.
If invoked directly on the console without any special options an
answer to a ``Continue?'' style confirmation prompt is required. In
case the user id already exists in the key ring a second prompt to
force the creation of the key will show up.
@end ifset
@item --gen-key
@opindex gen-key
Generate a new key pair. This command is normally only used
interactively.
There is an experimental feature which allows you to create keys in
batch mode. See the file @file{doc/DETAILS} in the source distribution
on how to use this.
There is also a feature which allows you to create keys in batch
mode. See the file @file{doc/DETAILS} in the source distribution on
how to use this.
@item --gen-revoke @code{name}
@opindex gen-revoke

View File

@ -106,6 +106,7 @@ enum cmd_and_opt_values
aDecryptFiles,
aClearsign,
aStore,
aQuickKeygen,
aKeygen,
aSignEncr,
aSignEncrSym,
@ -406,6 +407,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_c (aCheckKeys, "check-sigs",N_("list and check key signatures")),
ARGPARSE_c (oFingerprint, "fingerprint", N_("list keys and fingerprints")),
ARGPARSE_c (aListSecretKeys, "list-secret-keys", N_("list secret keys")),
ARGPARSE_c (aQuickKeygen, "quick-gen-key" ,
N_("quickly generate a new key pair")),
ARGPARSE_c (aKeygen, "gen-key", N_("generate a new key pair")),
ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
ARGPARSE_c (aDeleteKeys,"delete-keys",
@ -2279,6 +2282,7 @@ main (int argc, char **argv)
case aSignKey:
case aLSignKey:
case aStore:
case aQuickKeygen:
case aExportOwnerTrust:
case aImportOwnerTrust:
case aRebuildKeydbCaches:
@ -3612,6 +3616,7 @@ main (int argc, char **argv)
case aPasswd:
case aDeleteSecretKeys:
case aDeleteSecretAndPublicKeys:
case aQuickKeygen:
case aKeygen:
case aImport:
case aExportSecret:
@ -3895,6 +3900,14 @@ main (int argc, char **argv)
free_strlist (sl);
break;
case aQuickKeygen:
if (argc != 1 )
wrong_args("--gen-key user-id");
username = make_username (fname);
quick_generate_keypair (username);
xfree (username);
break;
case aKeygen: /* generate a key */
if( opt.batch ) {
if( argc > 1 )

View File

@ -1,6 +1,7 @@
/* keygen.c - generate a key pair
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
* 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
* Copyright (C) 2014 Werner Koch
*
* This file is part of GnuPG.
*
@ -3408,6 +3409,129 @@ read_parameter_file( const char *fname )
}
/* Helper for quick_generate_keypair. */
static struct para_data_s *
quickgen_set_para (struct para_data_s *para, int for_subkey,
int algo, int nbits, const char *curve)
{
struct para_data_s *r;
r = xmalloc_clear (sizeof *r + 20);
r->key = for_subkey? pSUBKEYUSAGE : pKEYUSAGE;
strcpy (r->u.value, for_subkey ? "encrypt" : "sign");
r->next = para;
para = r;
r = xmalloc_clear (sizeof *r + 20);
r->key = for_subkey? pSUBKEYTYPE : pKEYTYPE;
sprintf (r->u.value, "%d", algo);
r->next = para;
para = r;
if (curve)
{
r = xmalloc_clear (sizeof *r + strlen (curve));
r->key = for_subkey? pSUBKEYCURVE : pKEYCURVE;
strcpy (r->u.value, curve);
r->next = para;
para = r;
}
else
{
r = xmalloc_clear (sizeof *r + 20);
r->key = for_subkey? pSUBKEYLENGTH : pKEYLENGTH;
sprintf (r->u.value, "%u", nbits);
r->next = para;
para = r;
}
return para;
}
/*
* Unattended generaion of a standard key.
*/
void
quick_generate_keypair (const char *uid)
{
gpg_error_t err;
struct para_data_s *para = NULL;
struct para_data_s *r;
struct output_control_s outctrl;
int use_tty;
memset (&outctrl, 0, sizeof outctrl);
use_tty = (!opt.batch && !opt.answer_yes
&& !cpr_enabled ()
&& gnupg_isatty (fileno (stdin))
&& gnupg_isatty (fileno (stdout))
&& gnupg_isatty (fileno (stderr)));
r = xmalloc_clear (sizeof *r + strlen (uid));
r->key = pUSERID;
strcpy (r->u.value, uid);
r->next = para;
para = r;
uid = trim_spaces (r->u.value);
if (!*uid || (!opt.allow_freeform_uid && !is_valid_user_id (uid)))
{
log_error (_("Key generation failed: %s\n"),
gpg_strerror (GPG_ERR_INV_USER_ID));
goto leave;
}
/* If gpg is directly used on the console ask whether a key with the
given user id shall really be created. */
if (use_tty)
{
tty_printf (_("About to create a key for:\n \"%s\"\n\n"), uid);
if (!cpr_get_answer_is_yes_def ("quick_keygen.okay",
_("Continue? (Y/n) "), 1))
goto leave;
}
/* Check whether such a user ID already exists. */
{
KEYDB_HANDLE kdbhd;
KEYDB_SEARCH_DESC desc;
memset (&desc, 0, sizeof desc);
desc.mode = KEYDB_SEARCH_MODE_EXACT;
desc.u.name = uid;
kdbhd = keydb_new ();
err = keydb_search (kdbhd, &desc, 1, NULL);
keydb_release (kdbhd);
if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
{
log_info (_("A key for \"%s\" already exists\n"), uid);
if (opt.answer_yes)
;
else if (!use_tty
|| !cpr_get_answer_is_yes_def ("quick_keygen.force",
_("Create anyway? (y/N) "), 0))
{
log_inc_errorcount (); /* we used log_info */
goto leave;
}
log_info (_("creating anyway\n"));
}
}
para = quickgen_set_para (para, 0, PUBKEY_ALGO_RSA, 2048, NULL);
para = quickgen_set_para (para, 1, PUBKEY_ALGO_RSA, 2048, NULL);
/* para = quickgen_set_para (para, 0, PUBKEY_ALGO_EDDSA, 0, "Ed25519"); */
/* para = quickgen_set_para (para, 1, PUBKEY_ALGO_ECDH, 0, "Curve25519"); */
proc_parameter_file (para, "[internal]", &outctrl, 0);
leave:
release_parameter_list (para);
}
/*
* Generate a keypair (fname is only used in batch mode) If
* CARD_SERIALNO is not NULL the function will create the keys on an

View File

@ -154,6 +154,7 @@ int parse_options(char *str,unsigned int *options,
struct parse_options *opts,int noisy);
int has_invalid_email_chars (const char *s);
int is_valid_mailbox (const char *name);
int is_valid_user_id (const char *uid);
const char *get_libexecdir (void);
int path_access(const char *file,int mode);
@ -247,6 +248,7 @@ void show_basic_key_info (KBNODE keyblock);
u32 parse_expire_string(const char *string);
u32 ask_expire_interval(int object,const char *def_expire);
u32 ask_expiredate(void);
void quick_generate_keypair (const char *uid);
void generate_keypair (ctrl_t ctrl, const char *fname,
const char *card_serialno, int card_backup_key);
int keygen_set_std_prefs (const char *string,int personal);

View File

@ -1499,6 +1499,20 @@ is_valid_mailbox (const char *name)
}
/* Check whether UID is a valid standard user id of the form
"Heinrich Heine <heinrichh@duesseldorf.de>"
and return true if this is the case. */
int
is_valid_user_id (const char *uid)
{
if (!uid || !*uid)
return 0;
return 1;
}
/* Similar to access(2), but uses PATH to find the file. */
int
path_access(const char *file,int mode)