1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

Alow batch ode for gpgsm --gen-key.

Allow CSR generation using an existing key with gpgsm.
This commit is contained in:
Werner Koch 2009-07-01 18:30:33 +00:00
parent 5505a81a19
commit 1925cb37f9
10 changed files with 197 additions and 34 deletions

View file

@ -1,3 +1,11 @@
2009-07-01 Werner Koch <wk@g10code.com>
* certreqgen-ui.c (check_keygrip): New.
(gpgsm_gencertreq_tty): Allow using an existing key.
* gpgsm.c (open_es_fread): New.
(main) <aKeygen>: Implement --batch mode.
2009-06-24 Werner Koch <wk@g10code.com>
* call-dirmngr.c (pattern_from_strlist): Remove dead assignment of N.

View file

@ -86,6 +86,39 @@ store_mb_lines (membuf_t *mb, membuf_t *lines)
}
/* Chech whether we have a key for the key with HEXGRIP. Returns NULL
if not or a string describing the type of the key (RSA, ELG, DSA,
etc..). */
static const char *
check_keygrip (ctrl_t ctrl, const char *hexgrip)
{
gpg_error_t err;
ksba_sexp_t public;
size_t publiclen;
int algo;
if (hexgrip[0] == '0' && hexgrip[1] == 'x')
hexgrip += 2;
err = gpgsm_agent_readkey (ctrl, 0, hexgrip, &public);
if (err)
return NULL;
publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
get_pk_algo_from_canon_sexp (public, publiclen, &algo);
xfree (public);
switch (algo)
{
case GCRY_PK_RSA: return "RSA";
case GCRY_PK_DSA: return "DSA";
case GCRY_PK_ELG: return "ELG";
case GCRY_PK_ECDSA: return "ECDSA";
default: return NULL;
}
}
/* This function is used to create a certificate request from the
command line. In the past the similar gpgsm-gencert.sh script has
been used for it; however that scripts requires a full Unix shell
@ -99,7 +132,7 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
int selection;
estream_t fp = NULL;
int method;
char *keytype;
const char *keytype;
char *keygrip = NULL;
unsigned int nbits;
int minbits = 1024;
@ -112,11 +145,13 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
int i;
const char *s, *s2;
answer = NULL;
init_membuf (&mb_email, 100);
init_membuf (&mb_dns, 100);
init_membuf (&mb_uri, 100);
init_membuf (&mb_result, 512);
again:
/* Get the type of the key. */
tty_printf (_("Please select what kind of key you want:\n"));
tty_printf (_(" (%d) RSA\n"), 1 );
@ -125,10 +160,10 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
do
{
xfree (answer);
answer = tty_get (_("Your selection? "));
tty_kill_prompt ();
selection = *answer? atoi (answer): 1;
xfree (answer);
}
while (!(selection >= 1 && selection <= 3));
method = selection;
@ -136,13 +171,14 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
/* Get size of the key. */
if (method == 1)
{
keytype = xstrdup ("RSA");
keytype = "RSA";
for (;;)
{
xfree (answer);
answer = tty_getf (_("What keysize do you want? (%u) "), defbits);
tty_kill_prompt ();
trim_spaces (answer);
nbits = *answer? atoi (answer): defbits;
xfree (answer);
if (nbits < minbits || nbits > maxbits)
tty_printf(_("%s keysizes must be in the range %u-%u\n"),
"RSA", minbits, maxbits);
@ -159,17 +195,34 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
}
else if (method == 2)
{
tty_printf ("Not yet supported; "
"use the gpgsm-gencert.sh script instead\n");
keytype = xstrdup ("RSA");
nbits = defbits; /* We need a dummy value. */
for (;;)
{
xfree (answer);
answer = tty_get (_("Enter the keygrip: "));
tty_kill_prompt ();
trim_spaces (answer);
if (!*answer)
goto again;
else if (strlen (answer) != 40 &&
!(answer[0] == '0' && answer[1] == 'x'
&& strlen (answer+2) == 40))
tty_printf (_("Not a valid keygrip (expecting 40 hex digits)\n"));
else if (!(keytype = check_keygrip (ctrl, answer)) )
tty_printf (_("No key with this keygrip\n"));
else
break; /* Okay. */
}
nbits = 1024; /* A dummy value is sufficient. */
xfree (keygrip);
keygrip = answer;
answer = NULL;
}
else /* method == 3 */
{
tty_printf ("Not yet supported; "
"use the gpgsm-gencert.sh script instead\n");
keytype = xstrdup ("card:foobar");
nbits = defbits; /* We need a dummy value. */
goto again;
}
/* Ask for the key usage. */
@ -179,10 +232,11 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
tty_printf (_(" (%d) encrypt\n"), 3 );
do
{
xfree (answer);
answer = tty_get (_("Your selection? "));
tty_kill_prompt ();
trim_spaces (answer);
selection = *answer? atoi (answer): 1;
xfree (answer);
switch (selection)
{
case 1: keyusage = "sign, encrypt"; break;
@ -194,7 +248,6 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
while (!keyusage);
/* Get the subject name. */
answer = NULL;
do
{
size_t erroff, errlen;
@ -303,7 +356,7 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp)
log_error (_("resource problem: out of core\n"));
leave:
es_fclose (fp);
xfree (keytype);
xfree (answer);
xfree (subject_name);
xfree (keygrip);
xfree (get_membuf (&mb_email, NULL));

View file

@ -417,6 +417,7 @@ static void set_cmd (enum cmd_and_opt_values *ret_cmd,
static void emergency_cleanup (void);
static int check_special_filename (const char *fname, int for_write);
static int open_read (const char *filename);
static estream_t open_es_fread (const char *filename);
static FILE *open_fwrite (const char *filename);
static estream_t open_es_fwrite (const char *filename);
static void run_protect_tool (int argc, char **argv);
@ -1770,10 +1771,28 @@ main ( int argc, char **argv)
case aKeygen: /* Generate a key; well kind of. */
{
FILE *fp = open_fwrite (opt.outfile?opt.outfile:"-");
gpgsm_gencertreq_tty (&ctrl, fp);
if (fp != stdout)
fclose (fp);
estream_t fpin = NULL;
FILE *fpout;
if (opt.batch)
{
if (!argc) /* Create from stdin. */
fpin = open_es_fread ("-");
else if (argc == 1) /* From file. */
fpin = open_es_fread (*argv);
else
wrong_args ("--gen-key --batch [parmfile]");
}
fpout = open_fwrite (opt.outfile?opt.outfile:"-");
if (fpin)
gpgsm_genkey (&ctrl, fpin, fpout);
else
gpgsm_gencertreq_tty (&ctrl, fpout);
if (fpout != stdout)
fclose (fpout);
}
break;
@ -1976,6 +1995,37 @@ open_read (const char *filename)
return fd;
}
/* Same as open_read but return an estream_t. */
static estream_t
open_es_fread (const char *filename)
{
int fd;
estream_t fp;
if (filename[0] == '-' && !filename[1])
fd = fileno (stdin);
else
fd = check_special_filename (filename, 0);
if (fd != -1)
{
fp = es_fdopen_nc (fd, "rb");
if (!fp)
{
log_error ("es_fdopen(%d) failed: %s\n", fd, strerror (errno));
gpgsm_exit (2);
}
return fp;
}
fp = es_fopen (filename, "rb");
if (!fp)
{
log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
gpgsm_exit (2);
}
return fp;
}
/* Open FILENAME for fwrite and return the stream. Stop with an error
message in case of problems. "-" denotes stdout and if special
filenames are allowed the given fd is opened instead. Caller must