aboutsummaryrefslogtreecommitdiffstats
path: root/agent/protect-tool.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2009-04-01 10:51:53 +0000
committerWerner Koch <[email protected]>2009-04-01 10:51:53 +0000
commitf8b4cd76501824d56d3cf78a8ba85291a62f0e6d (patch)
treecec902ba7d3dd1a38846805cf491a65b95bb79cd /agent/protect-tool.c
parentImplement decryption for TCOS 3 cards. (diff)
downloadgnupg-f8b4cd76501824d56d3cf78a8ba85291a62f0e6d.tar.gz
gnupg-f8b4cd76501824d56d3cf78a8ba85291a62f0e6d.zip
Import/export of pkcs#12 now uses the gpg-agent directly.
Removed duplicated code (percent unescaping).
Diffstat (limited to 'agent/protect-tool.c')
-rw-r--r--agent/protect-tool.c274
1 files changed, 97 insertions, 177 deletions
diff --git a/agent/protect-tool.c b/agent/protect-tool.c
index 848ad9f4b..d0b68a1fa 100644
--- a/agent/protect-tool.c
+++ b/agent/protect-tool.c
@@ -41,13 +41,14 @@
#define JNLIB_NEED_LOG_LOGV
#include "agent.h"
#include "minip12.h"
-#include "simple-pwquery.h"
#include "i18n.h"
+#include "get-passphrase.h"
#include "sysutils.h"
enum cmd_and_opt_values
-{ aNull = 0,
+{
+ aNull = 0,
oVerbose = 'v',
oArmor = 'a',
oPassphrase = 'P',
@@ -72,17 +73,19 @@ enum cmd_and_opt_values
oPrompt,
oStatusMsg,
-aTest };
+ oAgentProgram
+};
+
struct rsa_secret_key_s
- {
- gcry_mpi_t n; /* public modulus */
- gcry_mpi_t e; /* public exponent */
- gcry_mpi_t d; /* exponent */
- gcry_mpi_t p; /* prime p. */
- gcry_mpi_t q; /* prime q. */
- gcry_mpi_t u; /* inverse of p mod q. */
- };
+{
+ gcry_mpi_t n; /* public modulus */
+ gcry_mpi_t e; /* public exponent */
+ gcry_mpi_t d; /* exponent */
+ gcry_mpi_t p; /* prime p. */
+ gcry_mpi_t q; /* prime q. */
+ gcry_mpi_t u; /* inverse of p mod q. */
+};
static const char *opt_homedir;
@@ -96,41 +99,51 @@ static const char *opt_passphrase;
static char *opt_prompt;
static int opt_status_msg;
static const char *opt_p12_charset;
+static const char *opt_agent_program;
-static char *get_passphrase (int promptno, int opt_check);
-static char *get_new_passphrase (int promptno);
+static char *get_passphrase (int promptno);
static void release_passphrase (char *pw);
static int store_private_key (const unsigned char *grip,
const void *buffer, size_t length, int force);
static ARGPARSE_OPTS opts[] = {
+ ARGPARSE_group (300, N_("@Commands:\n ")),
+
+ ARGPARSE_c (oProtect, "protect", "protect a private key"),
+ ARGPARSE_c (oUnprotect, "unprotect", "unprotect a private key"),
+ ARGPARSE_c (oShadow, "shadow", "create a shadow entry for a public key"),
+ ARGPARSE_c (oShowShadowInfo, "show-shadow-info", "return the shadow info"),
+ ARGPARSE_c (oShowKeygrip, "show-keygrip", "show the \"keygrip\""),
+ ARGPARSE_c (oP12Import, "p12-import",
+ "import a pkcs#12 encoded private key"),
+ ARGPARSE_c (oP12Export, "p12-export",
+ "export a private key pkcs#12 encoded"),
- { 301, NULL, 0, N_("@Options:\n ") },
-
- { oVerbose, "verbose", 0, "verbose" },
- { oArmor, "armor", 0, "write output in advanced format" },
- { oCanonical, "canonical", 0, "write output in canonical format" },
- { oPassphrase, "passphrase", 2, "|STRING|use passphrase STRING" },
- { oProtect, "protect", 256, "protect a private key"},
- { oUnprotect, "unprotect", 256, "unprotect a private key"},
- { oShadow, "shadow", 256, "create a shadow entry for a public key"},
- { oShowShadowInfo, "show-shadow-info", 256, "return the shadow info"},
- { oShowKeygrip, "show-keygrip", 256, "show the \"keygrip\""},
-
- { oP12Import, "p12-import", 256, "import a pkcs#12 encoded private key"},
- { oP12Export, "p12-export", 256, "export a private key pkcs#12 encoded"},
- { oP12Charset,"p12-charset", 2,
- "|NAME|set charset for a new PKCS#12 passphrase to NAME" },
- { oHaveCert, "have-cert", 0, "certificate to export provided on STDIN"},
- { oStore, "store", 0, "store the created key in the appropriate place"},
- { oForce, "force", 0, "force overwriting"},
- { oNoFailOnExist, "no-fail-on-exist", 0, "@" },
- { oHomedir, "homedir", 2, "@" },
- { oPrompt, "prompt", 2, "|ESCSTRING|use ESCSTRING as prompt in pinentry"},
- { oStatusMsg, "enable-status-msg", 0, "@"},
-
- {0}
+ ARGPARSE_group (301, N_("@\nOptions:\n ")),
+
+ ARGPARSE_s_n (oVerbose, "verbose", "verbose"),
+ ARGPARSE_s_n (oArmor, "armor", "write output in advanced format"),
+ ARGPARSE_s_n (oCanonical, "canonical", "write output in canonical format"),
+
+ ARGPARSE_s_s (oPassphrase, "passphrase", "|STRING|use passphrase STRING"),
+ ARGPARSE_s_s (oP12Charset,"p12-charset",
+ "|NAME|set charset for a new PKCS#12 passphrase to NAME"),
+ ARGPARSE_s_n (oHaveCert, "have-cert",
+ "certificate to export provided on STDIN"),
+ ARGPARSE_s_n (oStore, "store",
+ "store the created key in the appropriate place"),
+ ARGPARSE_s_n (oForce, "force",
+ "force overwriting"),
+ ARGPARSE_s_n (oNoFailOnExist, "no-fail-on-exist", "@"),
+ ARGPARSE_s_s (oHomedir, "homedir", "@"),
+ ARGPARSE_s_s (oPrompt, "prompt",
+ "|ESCSTRING|use ESCSTRING as prompt in pinentry"),
+ ARGPARSE_s_n (oStatusMsg, "enable-status-msg", "@"),
+
+ ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
+
+ ARGPARSE_end ()
};
static const char *
@@ -158,9 +171,6 @@ my_strusage (int level)
}
-/* Include the implementation of map_spwq_error. */
-MAP_SPWQ_ERROR_IMPL
-
/* static void */
/* print_mpi (const char *text, gcry_mpi_t a) */
/* { */
@@ -333,7 +343,7 @@ read_and_protect (const char *fname)
if (!key)
return;
- pw = get_passphrase (1, 0);
+ pw = get_passphrase (1);
rc = agent_protect (key, pw, &result, &resultlen);
release_passphrase (pw);
xfree (key);
@@ -372,7 +382,7 @@ read_and_unprotect (const char *fname)
if (!key)
return;
- rc = agent_unprotect (key, (pw=get_passphrase (1, 0)),
+ rc = agent_unprotect (key, (pw=get_passphrase (1)),
protected_at, &result, &resultlen);
release_passphrase (pw);
xfree (key);
@@ -678,7 +688,7 @@ import_p12_file (const char *fname)
buf_off = 0;
kparms = p12_parse ((unsigned char*)buf+buf_off, buflen-buf_off,
- (pw=get_passphrase (2, 0)),
+ (pw=get_passphrase (2)),
import_p12_cert_cb, NULL);
release_passphrase (pw);
xfree (buf);
@@ -753,12 +763,8 @@ import_p12_file (const char *fname)
assert (buflen);
gcry_sexp_release (s_key);
-
- pw = get_new_passphrase (4);
- if (!pw)
- rc = gpg_error (GPG_ERR_CANCELED);
- else
- rc = agent_protect (key, pw, &result, &resultlen);
+ pw = get_passphrase (4);
+ rc = agent_protect (key, pw, &result, &resultlen);
release_passphrase (pw);
xfree (key);
if (rc)
@@ -896,7 +902,7 @@ export_p12_file (const char *fname)
unsigned char *tmpkey;
size_t tmplen;
- rc = agent_unprotect (key, (pw=get_passphrase (1, 0)),
+ rc = agent_unprotect (key, (pw=get_passphrase (1)),
NULL, &tmpkey, &tmplen);
release_passphrase (pw);
if (rc)
@@ -985,11 +991,8 @@ export_p12_file (const char *fname)
kparms[7] = sk.u;
kparms[8] = NULL;
- pw = get_new_passphrase (3);
- if (!pw)
- key = NULL;
- else
- key = p12_build (kparms, cert, certlen, pw, opt_p12_charset, &keylen);
+ pw = get_passphrase (3);
+ key = p12_build (kparms, cert, certlen, pw, opt_p12_charset, &keylen);
release_passphrase (pw);
xfree (cert);
for (i=0; i < 8; i++)
@@ -1005,54 +1008,6 @@ export_p12_file (const char *fname)
}
-
-/* Do the percent and plus/space unescaping in place and return the
- length of the valid buffer. */
-static size_t
-percent_plus_unescape (unsigned char *string)
-{
- unsigned char *p = string;
- size_t n = 0;
-
- while (*string)
- {
- if (*string == '%' && string[1] && string[2])
- {
- string++;
- *p++ = xtoi_2 (string);
- n++;
- string+= 2;
- }
- else if (*string == '+')
- {
- *p++ = ' ';
- n++;
- string++;
- }
- else
- {
- *p++ = *string++;
- n++;
- }
- }
-
- return n;
-}
-
-/* Remove percent and plus escaping and make sure that the reuslt is a
- string. This is done in place. Returns STRING. */
-static char *
-percent_plus_unescape_string (char *string)
-{
- unsigned char *p = (unsigned char*)string;
- size_t n;
-
- n = percent_plus_unescape (p);
- p[n] = 0;
-
- return string;
-}
-
int
main (int argc, char **argv )
@@ -1094,6 +1049,8 @@ main (int argc, char **argv )
case oCanonical: opt_canonical=1; break;
case oHomedir: opt_homedir = pargs.r.ret_str; break;
+ case oAgentProgram: opt_agent_program = pargs.r.ret_str; break;
+
case oProtect: cmd = oProtect; break;
case oUnprotect: cmd = oUnprotect; break;
case oShadow: cmd = oShadow; break;
@@ -1111,11 +1068,11 @@ main (int argc, char **argv )
case oPrompt: opt_prompt = pargs.r.ret_str; break;
case oStatusMsg: opt_status_msg = 1; break;
- default : pargs.err = 2; break;
+ default: pargs.err = ARGPARSE_PRINT_ERROR; break;
}
}
- if (log_get_errorcount(0))
- exit(2);
+ if (log_get_errorcount (0))
+ exit (2);
fname = "-";
if (argc == 1)
@@ -1123,15 +1080,15 @@ main (int argc, char **argv )
else if (argc > 1)
usage (1);
- /* Tell simple-pwquery about the the standard socket name. */
- {
- char *tmp = make_filename (opt_homedir, "S.gpg-agent", NULL);
- simple_pw_set_socket (tmp);
- xfree (tmp);
- }
+ /* Set the information which can't be taken from envvars. */
+ gnupg_prepare_get_passphrase (GPG_ERR_SOURCE_DEFAULT,
+ opt.verbose,
+ opt_homedir,
+ opt_agent_program,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL);
if (opt_prompt)
- opt_prompt = percent_plus_unescape_string (xstrdup (opt_prompt));
+ opt_prompt = percent_plus_unescape (opt_prompt, 0);
if (cmd == oProtect)
read_and_protect (fname);
@@ -1169,102 +1126,65 @@ agent_exit (int rc)
2 = for unprotecting a pkcs#12 object
3 = for protecting a new pkcs#12 object
4 = for protecting an imported pkcs#12 in our system
- 5 = reenter the passphrase
- When adding 100 to the values, a "does not match - try again" error
- message is shown.
*/
static char *
-get_passphrase (int promptno, int opt_check)
+get_passphrase (int promptno)
{
char *pw;
int err;
const char *desc;
char *orig_codeset;
- int error_msgno;
+ int repeat = 0;
if (opt_passphrase)
return xstrdup (opt_passphrase);
- error_msgno = promptno / 100;
- promptno %= 100;
-
orig_codeset = i18n_switchto_utf8 ();
if (promptno == 1 && opt_prompt)
- desc = opt_prompt;
+ {
+ desc = opt_prompt;
+ }
else if (promptno == 2)
- desc = _("Please enter the passphrase to unprotect the "
- "PKCS#12 object.");
+ {
+ desc = _("Please enter the passphrase to unprotect the "
+ "PKCS#12 object.");
+ }
else if (promptno == 3)
- desc = _("Please enter the passphrase to protect the "
- "new PKCS#12 object.");
+ {
+ desc = _("Please enter the passphrase to protect the "
+ "new PKCS#12 object.");
+ repeat = 1;
+ }
else if (promptno == 4)
- desc = _("Please enter the passphrase to protect the "
- "imported object within the GnuPG system.");
- else if (promptno == 5)
- desc = _("Please re-enter this passphrase");
+ {
+ desc = _("Please enter the passphrase to protect the "
+ "imported object within the GnuPG system.");
+ repeat = 1;
+ }
else
desc = _("Please enter the passphrase or the PIN\n"
"needed to complete this operation.");
- pw = simple_pwquery (NULL,
- error_msgno == 1? _("does not match - try again"):NULL,
- _("Passphrase:"), desc, opt_check, &err);
- err = map_spwq_error (err);
-
i18n_switchback (orig_codeset);
- if (!pw)
+ err = gnupg_get_passphrase (NULL, NULL, _("Passphrase:"), desc,
+ repeat, repeat, 1, &pw);
+ if (err)
{
- if (err)
+ if (gpg_err_code (err) == GPG_ERR_CANCELED)
+ log_info (_("cancelled\n"));
+ else
log_error (_("error while asking for the passphrase: %s\n"),
gpg_strerror (err));
- else
- log_info (_("cancelled\n"));
agent_exit (0);
}
+ assert (pw);
return pw;
}
-/* Same as get_passphrase but requests it a second time and compares
- it to the one entered the first time. */
-static char *
-get_new_passphrase (int promptno)
-{
- char *pw;
- int i, secondpromptno;
-
- pw = get_passphrase (promptno, 1);
- if (!pw)
- return NULL; /* Canceled. */
- if (!*pw)
- return pw; /* Empty passphrase - no need to ask for repeating it. */
-
- secondpromptno = 5;
- for (i=0; i < 3; i++)
- {
- char *pw2 = get_passphrase (secondpromptno, 0);
- if (!pw2)
- {
- xfree (pw);
- return NULL; /* Canceled. */
- }
- if (!strcmp (pw, pw2))
- {
- xfree (pw2);
- return pw; /* Okay. */
- }
- secondpromptno = 105;
- xfree (pw2);
- }
- xfree (pw);
- return NULL; /* 3 times repeated wrong - cancel. */
-}
-
-
-
static void
release_passphrase (char *pw)
{