1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

* Makefile.am (pkglib_PROGRAMS): Put protect-tool there.

* findkey.c (agent_write_private_key,agent_key_from_file)
(agent_key_available): Use GNUPG_PRIVATE_KEYS_DIR constant.
* gpg-agent.c (main): Use GNUPG_DEFAULT_HOMEDIR constant.

* protect-tool.c (store_private_key): New.
(import_p12_file): Store the new file if requested.
(main): New options --force and --store.

* gpg-agent.c (main): Set a global flag when runing detached.
* query.c (start_pinentry): Pass the list of FD to keep in the
child when not running detached.
* call-scd.c (start_scd): Ditto.
This commit is contained in:
Werner Koch 2002-06-27 07:29:29 +00:00
parent 738e6d8212
commit 56b049686f
13 changed files with 769 additions and 41 deletions

View file

@ -35,6 +35,7 @@
#define JNLIB_NEED_LOG_LOGV
#include "agent.h"
#include "minip12.h"
#include "simple-pwquery.h"
#define N_(a) a
#define _(a) a
@ -55,6 +56,8 @@ enum cmd_and_opt_values
oShowKeygrip,
oP12Import,
oStore,
oForce,
aTest };
@ -70,7 +73,14 @@ struct rsa_secret_key_s
static int opt_armor;
static const char *passphrase = "abc";
static int opt_store;
static int opt_force;
static const char *passphrase;
static const char *get_passphrase (void);
static int store_private_key (const unsigned char *grip,
const void *buffer, size_t length, int force);
static ARGPARSE_OPTS opts[] = {
@ -86,6 +96,8 @@ static ARGPARSE_OPTS opts[] = {
{ oShowKeygrip, "show-keygrip", 256, "show the \"keygrip\""},
{ oP12Import, "p12-import", 256, "import a PKCS-12 encoded private key"},
{ oStore, "store", 0, "store the created key in the appropriate place"},
{ oForce, "force", 0, "force overwriting"},
{0}
};
@ -283,7 +295,7 @@ read_and_protect (const char *fname)
if (!key)
return;
rc = agent_protect (key, passphrase, &result, &resultlen);
rc = agent_protect (key, get_passphrase (), &result, &resultlen);
xfree (key);
if (rc)
{
@ -318,7 +330,7 @@ read_and_unprotect (const char *fname)
if (!key)
return;
rc = agent_unprotect (key, passphrase, &result, &resultlen);
rc = agent_unprotect (key, get_passphrase (), &result, &resultlen);
xfree (key);
if (rc)
{
@ -564,6 +576,7 @@ import_p12_file (const char *fname)
struct rsa_secret_key_s sk;
GcrySexp s_key;
unsigned char *key;
unsigned char grip[20];
/* fixme: we should release some stuff on error */
@ -571,7 +584,7 @@ import_p12_file (const char *fname)
if (!buf)
return;
kparms = p12_parse (buf, buflen, passphrase);
kparms = p12_parse (buf, buflen, get_passphrase ());
xfree (buf);
if (!kparms)
{
@ -626,18 +639,15 @@ import_p12_file (const char *fname)
}
/* Compute the keygrip. */
{
unsigned char grip[20];
if (!gcry_pk_get_keygrip (s_key, grip))
{
log_error ("can't calculate keygrip\n");
return;
}
log_info ("keygrip: ");
for (i=0; i < 20; i++)
log_printf ("%02X", grip[i]);
log_printf ("\n");
}
if (!gcry_pk_get_keygrip (s_key, grip))
{
log_error ("can't calculate keygrip\n");
return;
}
log_info ("keygrip: ");
for (i=0; i < 20; i++)
log_printf ("%02X", grip[i]);
log_printf ("\n");
/* convert to canonical encoding */
buflen = gcry_sexp_sprint (s_key, GCRYSEXP_FMT_CANON, NULL, 0);
@ -648,7 +658,7 @@ import_p12_file (const char *fname)
gcry_sexp_release (s_key);
rc = agent_protect (key, passphrase, &result, &resultlen);
rc = agent_protect (key, get_passphrase (), &result, &resultlen);
xfree (key);
if (rc)
{
@ -666,7 +676,11 @@ import_p12_file (const char *fname)
resultlen = strlen (p);
}
fwrite (result, resultlen, 1, stdout);
if (opt_store)
store_private_key (grip, result, resultlen, opt_force);
else
fwrite (result, resultlen, 1, stdout);
xfree (result);
}
@ -711,6 +725,8 @@ main (int argc, char **argv )
case oP12Import: cmd = oP12Import; break;
case oPassphrase: passphrase = pargs.r.ret_str; break;
case oStore: opt_store = 1; break;
case oForce: opt_force = 1; break;
default : pargs.err = 2; break;
}
@ -736,7 +752,8 @@ main (int argc, char **argv )
else
show_file (*argv);
return 0;
agent_exit (0);
return 8; /*NOTREACHED*/
}
void
@ -745,3 +762,95 @@ agent_exit (int rc)
rc = rc? rc : log_get_errorcount(0)? 2 : 0;
exit (rc);
}
/* Return the passphrase string and ask the agent if it has not been
set from the command line. */
static const char *
get_passphrase (void)
{
char *pw;
int err;
if (passphrase)
return passphrase;
pw = simple_pwquery (NULL,NULL,
_("Enter passphrase:"),
_("Please enter the passphrase or the PIN\n"
"needed to complete this operation."),
&err);
if (!pw)
{
if (err)
log_error ("error while asking for the passphrase\n");
else
log_info ("cancelled\n");
agent_exit (0);
}
passphrase = pw;
return passphrase;
}
static int
store_private_key (const unsigned char *grip,
const void *buffer, size_t length, int force)
{
int i;
const char *homedir;
char *fname;
FILE *fp;
char hexgrip[40+4+1];
for (i=0; i < 20; i++)
sprintf (hexgrip+2*i, "%02X", grip[i]);
strcpy (hexgrip+40, ".key");
homedir = getenv("GNUPGHOME");
if (!homedir || !*homedir)
homedir = GNUPG_DEFAULT_HOMEDIR;
fname = make_filename (homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
if (force)
fp = fopen (fname, "wb");
else
{
if (!access (fname, F_OK))
{
log_error ("secret key file `%s' already exists\n", fname);
xfree (fname);
return -1;
}
fp = fopen (fname, "wbx"); /* FIXME: the x is a GNU extension - let
configure check whether this actually
works */
}
if (!fp)
{
log_error ("can't create `%s': %s\n", fname, strerror (errno));
xfree (fname);
return -1;
}
if (fwrite (buffer, length, 1, fp) != 1)
{
log_error ("error writing `%s': %s\n", fname, strerror (errno));
fclose (fp);
remove (fname);
xfree (fname);
return -1;
}
if ( fclose (fp) )
{
log_error ("error closing `%s': %s\n", fname, strerror (errno));
remove (fname);
xfree (fname);
return -1;
}
log_info ("secret key stored as `%s'\n", fname);
xfree (fname);
return 0;
}