mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
Avoid using the protect-tool to import pkcs#12.
This commit is contained in:
parent
28b3b74cbb
commit
006fd75aea
24 changed files with 1167 additions and 414 deletions
|
@ -1,3 +1,29 @@
|
|||
2010-06-15 Werner Koch <wk@g10code.com>
|
||||
|
||||
* command.c (cmd_keywrap_key, cmd_import_key): New.
|
||||
|
||||
* genkey.c (agent_genkey, agent_protect_and_store): Factor common
|
||||
code out to...
|
||||
(agent_ask_new_passphrase): .. new.
|
||||
|
||||
* findkey.c (agent_write_private_key): Return GPG_ERR_EEXIST
|
||||
instead of GPG_ERR_GENERAL.
|
||||
|
||||
2010-06-14 Werner Koch <wk@g10code.com>
|
||||
|
||||
* protect-tool.c: Remove commands --p12-import and --p12-export.
|
||||
* minip12.c, minip12.h: Move to ../sm.
|
||||
* Makefile.am (gpg_protect_tool_SOURCES): Remove them.
|
||||
* preset-passphrase.c: Remove unneeded minip12.h.
|
||||
|
||||
* command.c (cmd_keywrap_key): New.
|
||||
|
||||
* command.c (leave_cmd): New.
|
||||
(cmd_istrusted, cmd_listtrusted, cmd_marktrusted, cmd_pksign)
|
||||
(cmd_pkdecrypt, cmd_genkey, cmd_readkey, cmd_keyinfo)
|
||||
(cmd_get_passphrase, cmd_get_confirmation, cmd_learn)
|
||||
(cmd_passwd, cmd_preset_passphrase, cmd_getval, cmd_putval): Use it.
|
||||
|
||||
2010-05-12 Werner Koch <wk@g10code.com>
|
||||
|
||||
* preset-passphrase.c (forget_passphrase): Actually implement
|
||||
|
|
|
@ -79,8 +79,7 @@ gpg_agent_DEPENDENCIES = $(gpg_agent_res_deps)
|
|||
|
||||
gpg_protect_tool_SOURCES = \
|
||||
protect-tool.c \
|
||||
protect.c \
|
||||
minip12.c minip12.h
|
||||
protect.c
|
||||
|
||||
gpg_protect_tool_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS)
|
||||
gpg_protect_tool_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) \
|
||||
|
|
|
@ -284,6 +284,8 @@ int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
|||
|
||||
/*-- genkey.c --*/
|
||||
int check_passphrase_constraints (ctrl_t ctrl, const char *pw, int silent);
|
||||
gpg_error_t agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
|
||||
char **r_passphrase);
|
||||
int agent_genkey (ctrl_t ctrl,
|
||||
const char *keyparam, size_t keyparmlen, membuf_t *outbuf);
|
||||
int agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey);
|
||||
|
|
278
agent/command.c
278
agent/command.c
|
@ -38,10 +38,14 @@
|
|||
#include <assuan.h>
|
||||
#include "i18n.h"
|
||||
|
||||
/* maximum allowed size of the inquired ciphertext */
|
||||
/* Maximum allowed size of the inquired ciphertext. */
|
||||
#define MAXLEN_CIPHERTEXT 4096
|
||||
/* maximum allowed size of the key parameters */
|
||||
/* Maximum allowed size of the key parameters. */
|
||||
#define MAXLEN_KEYPARAM 1024
|
||||
/* Maximum allowed size of key data as used in inquiries (bytes). */
|
||||
#define MAXLEN_KEYDATA 4096
|
||||
/* The size of the import/export KEK key (in bytes). */
|
||||
#define KEYWRAP_KEYSIZE (128/8)
|
||||
|
||||
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
|
||||
|
||||
|
@ -63,6 +67,8 @@ struct server_local_s
|
|||
the end of this session. */
|
||||
int allow_pinentry_notify; /* Set if pinentry notifications should
|
||||
be done. */
|
||||
void *import_key; /* Malloced KEK for the import_key command. */
|
||||
void *export_key; /* Malloced KEK for the export_key command. */
|
||||
};
|
||||
|
||||
|
||||
|
@ -340,6 +346,26 @@ agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid)
|
|||
}
|
||||
|
||||
|
||||
/* Helper to print a message while leaving a command. */
|
||||
static gpg_error_t
|
||||
leave_cmd (assuan_context_t ctx, gpg_error_t err)
|
||||
{
|
||||
if (err)
|
||||
{
|
||||
const char *name = assuan_get_command_name (ctx);
|
||||
if (!name)
|
||||
name = "?";
|
||||
if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
|
||||
log_error ("command '%s' failed: %s\n", name,
|
||||
gpg_strerror (err));
|
||||
else
|
||||
log_error ("command '%s' failed: %s <%s>\n", name,
|
||||
gpg_strerror (err), gpg_strsource (err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char hlp_geteventcounter[] =
|
||||
"GETEVENTCOUNTER\n"
|
||||
|
@ -432,10 +458,7 @@ cmd_istrusted (assuan_context_t ctx, char *line)
|
|||
else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
|
||||
return gpg_error (GPG_ERR_NOT_TRUSTED);
|
||||
else
|
||||
{
|
||||
log_error ("command is_trusted failed: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -451,9 +474,7 @@ cmd_listtrusted (assuan_context_t ctx, char *line)
|
|||
(void)line;
|
||||
|
||||
rc = agent_listtrusted (ctx);
|
||||
if (rc)
|
||||
log_error ("command listtrusted failed: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -494,9 +515,7 @@ cmd_marktrusted (assuan_context_t ctx, char *line)
|
|||
p++;
|
||||
|
||||
rc = agent_marktrusted (ctrl, p, fpr, flag);
|
||||
if (rc)
|
||||
log_error ("command marktrusted failed: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -695,11 +714,9 @@ cmd_pksign (assuan_context_t ctx, char *line)
|
|||
clear_outbuf (&outbuf);
|
||||
else
|
||||
rc = write_and_clear_outbuf (ctx, &outbuf);
|
||||
if (rc)
|
||||
log_error ("command pksign failed: %s\n", gpg_strerror (rc));
|
||||
xfree (ctrl->server_local->keydesc);
|
||||
ctrl->server_local->keydesc = NULL;
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -734,11 +751,9 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
|
|||
clear_outbuf (&outbuf);
|
||||
else
|
||||
rc = write_and_clear_outbuf (ctx, &outbuf);
|
||||
if (rc)
|
||||
log_error ("command pkdecrypt failed: %s\n", gpg_strerror (rc));
|
||||
xfree (ctrl->server_local->keydesc);
|
||||
ctrl->server_local->keydesc = NULL;
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -780,9 +795,7 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
|||
clear_outbuf (&outbuf);
|
||||
else
|
||||
rc = write_and_clear_outbuf (ctx, &outbuf);
|
||||
if (rc)
|
||||
log_error ("command genkey failed: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -825,9 +838,7 @@ cmd_readkey (assuan_context_t ctx, char *line)
|
|||
gcry_sexp_release (s_pkey);
|
||||
}
|
||||
|
||||
if (rc)
|
||||
log_error ("command readkey failed: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -967,7 +978,7 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
|
|||
if (dir)
|
||||
closedir (dir);
|
||||
if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
|
||||
log_error ("command keyinfo failed: %s\n", gpg_strerror (err));
|
||||
leave_cmd (ctx, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1167,9 +1178,7 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
|
|||
}
|
||||
}
|
||||
|
||||
if (rc)
|
||||
log_error ("command get_passphrase failed: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1240,9 +1249,7 @@ cmd_get_confirmation (assuan_context_t ctx, char *line)
|
|||
plus_to_blank (desc);
|
||||
|
||||
rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
|
||||
if (rc)
|
||||
log_error ("command get_confirmation failed: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1259,9 +1266,7 @@ cmd_learn (assuan_context_t ctx, char *line)
|
|||
int rc;
|
||||
|
||||
rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
|
||||
if (rc)
|
||||
log_error ("command learn failed: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1304,9 +1309,7 @@ cmd_passwd (assuan_context_t ctx, char *line)
|
|||
leave:
|
||||
gcry_sexp_release (s_skey);
|
||||
xfree (shadow_info);
|
||||
if (rc)
|
||||
log_error ("command passwd failed: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1371,10 +1374,7 @@ cmd_preset_passphrase (assuan_context_t ctx, char *line)
|
|||
if (!rc)
|
||||
rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
|
||||
|
||||
if (rc)
|
||||
log_error ("command preset_passphrase failed: %s\n", gpg_strerror (rc));
|
||||
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1396,6 +1396,186 @@ cmd_scd (assuan_context_t ctx, char *line)
|
|||
}
|
||||
|
||||
|
||||
|
||||
static const char hlp_keywrap_key[] =
|
||||
"KEYWRAP_KEY [--clear] <mode>\n"
|
||||
"\n"
|
||||
"Return a key to wrap another key. For now the key is returned\n"
|
||||
"verbatim and and thus makes not much sense because an eavesdropper on\n"
|
||||
"the gpg-agent connection will see the key as well as the wrapped key.\n"
|
||||
"However, this function may either be equipped with a public key\n"
|
||||
"mechanism or not used at all if the key is a pre-shared key. In any\n"
|
||||
"case wrapping the import and export of keys is a requirement for\n"
|
||||
"certain cryptographic validations and thus useful. The key persists\n"
|
||||
"a RESET command but may be cleared using the option --clear.\n"
|
||||
"\n"
|
||||
"Supported modes are:\n"
|
||||
" --import - Return a key to import a key into gpg-agent\n"
|
||||
" --export - Return a key to export a key from gpg-agent";
|
||||
static gpg_error_t
|
||||
cmd_keywrap_key (assuan_context_t ctx, char *line)
|
||||
{
|
||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||
gpg_error_t err = 0;
|
||||
int clearopt = has_option (line, "--clear");
|
||||
|
||||
|
||||
assuan_begin_confidential (ctx);
|
||||
if (has_option (line, "--import"))
|
||||
{
|
||||
xfree (ctrl->server_local->import_key);
|
||||
if (clearopt)
|
||||
ctrl->server_local->import_key = NULL;
|
||||
else if (!(ctrl->server_local->import_key =
|
||||
gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
err = assuan_send_data (ctx, ctrl->server_local->import_key,
|
||||
KEYWRAP_KEYSIZE);
|
||||
}
|
||||
else if (has_option (line, "--export"))
|
||||
{
|
||||
xfree (ctrl->server_local->export_key);
|
||||
if (clearopt)
|
||||
ctrl->server_local->export_key = NULL;
|
||||
else if (!(ctrl->server_local->export_key =
|
||||
gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
err = assuan_send_data (ctx, ctrl->server_local->export_key,
|
||||
KEYWRAP_KEYSIZE);
|
||||
}
|
||||
else
|
||||
err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for MODE");
|
||||
assuan_end_confidential (ctx);
|
||||
|
||||
return leave_cmd (ctx, err);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char hlp_import_key[] =
|
||||
"IMPORT_KEY\n"
|
||||
"\n"
|
||||
"Import a secret key into the key store. The key is expected to be\n"
|
||||
"encrypted using the current session's key wrapping key (cf. command\n"
|
||||
"KEYWRAP_KEY) using the AESWRAP-128 algorithm. This function takes\n"
|
||||
"no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
|
||||
"key data. The unwrapped key must be a canonical S-expression.";
|
||||
static gpg_error_t
|
||||
cmd_import_key (assuan_context_t ctx, char *line)
|
||||
{
|
||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||
gpg_error_t err;
|
||||
unsigned char *wrappedkey = NULL;
|
||||
size_t wrappedkeylen;
|
||||
gcry_cipher_hd_t cipherhd = NULL;
|
||||
unsigned char *key = NULL;
|
||||
size_t keylen, realkeylen;
|
||||
char *passphrase = NULL;
|
||||
unsigned char *finalkey = NULL;
|
||||
size_t finalkeylen;
|
||||
unsigned char grip[20];
|
||||
|
||||
(void)line;
|
||||
|
||||
if (!ctrl->server_local->import_key)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_BAD_KEY);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
assuan_begin_confidential (ctx);
|
||||
err = assuan_inquire (ctx, "KEYDATA",
|
||||
&wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
|
||||
assuan_end_confidential (ctx);
|
||||
if (err)
|
||||
goto leave;
|
||||
if (wrappedkeylen < 24)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_INV_LENGTH);
|
||||
goto leave;
|
||||
}
|
||||
keylen = wrappedkeylen - 8;
|
||||
key = xtrymalloc_secure (keylen);
|
||||
if (!key)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
|
||||
err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
|
||||
GCRY_CIPHER_MODE_AESWRAP, 0);
|
||||
if (err)
|
||||
goto leave;
|
||||
err = gcry_cipher_setkey (cipherhd,
|
||||
ctrl->server_local->import_key, KEYWRAP_KEYSIZE);
|
||||
if (err)
|
||||
goto leave;
|
||||
err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
|
||||
if (err)
|
||||
goto leave;
|
||||
gcry_cipher_close (cipherhd);
|
||||
cipherhd = NULL;
|
||||
xfree (wrappedkey);
|
||||
wrappedkey = NULL;
|
||||
|
||||
realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
|
||||
if (!realkeylen)
|
||||
goto leave; /* Invalid canonical encoded S-expression. */
|
||||
|
||||
err = keygrip_from_canon_sexp (key, realkeylen, grip);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
if (!agent_key_available (grip))
|
||||
{
|
||||
err = gpg_error (GPG_ERR_EEXIST);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
err = agent_ask_new_passphrase
|
||||
(ctrl, _("Please enter the passphrase to protect the "
|
||||
"imported object within the GnuPG system."),
|
||||
&passphrase);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
if (passphrase)
|
||||
{
|
||||
err = agent_protect (key, passphrase, &finalkey, &finalkeylen);
|
||||
if (!err)
|
||||
err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
|
||||
}
|
||||
else
|
||||
err = agent_write_private_key (grip, key, realkeylen, 0);
|
||||
|
||||
leave:
|
||||
xfree (finalkey);
|
||||
xfree (passphrase);
|
||||
xfree (key);
|
||||
gcry_cipher_close (cipherhd);
|
||||
xfree (wrappedkey);
|
||||
return leave_cmd (ctx, err);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char hlp_export_key[] =
|
||||
"EXPORT_KEY\n"
|
||||
"\n";
|
||||
static gpg_error_t
|
||||
cmd_export_key (assuan_context_t ctx, char *line)
|
||||
{
|
||||
gpg_error_t err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
|
||||
|
||||
/* leave: */
|
||||
return leave_cmd (ctx, err);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static const char hlp_getval[] =
|
||||
"GETVAL <key>\n"
|
||||
|
@ -1435,9 +1615,7 @@ cmd_getval (assuan_context_t ctx, char *line)
|
|||
else
|
||||
return gpg_error (GPG_ERR_NO_DATA);
|
||||
|
||||
if (rc)
|
||||
log_error ("command getval failed: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1520,9 +1698,7 @@ cmd_putval (assuan_context_t ctx, char *line)
|
|||
}
|
||||
}
|
||||
|
||||
if (rc)
|
||||
log_error ("command putval failed: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
return leave_cmd (ctx, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1641,7 +1817,7 @@ static const char hlp_getinfo[] =
|
|||
" std_session_env - List the standard session environment.\n"
|
||||
" std_startup_env - List the standard startup environment.\n"
|
||||
" cmd_has_option\n"
|
||||
" - Returns OK if the command CMD implements the option OPT.";
|
||||
" - Returns OK if the command CMD implements the option OPT\n.";
|
||||
static gpg_error_t
|
||||
cmd_getinfo (assuan_context_t ctx, char *line)
|
||||
{
|
||||
|
@ -1910,6 +2086,9 @@ register_commands (assuan_context_t ctx)
|
|||
{ "INPUT", NULL },
|
||||
{ "OUTPUT", NULL },
|
||||
{ "SCD", cmd_scd, hlp_scd },
|
||||
{ "KEYWRAP_KEY", cmd_keywrap_key, hlp_keywrap_key },
|
||||
{ "IMPORT_KEY", cmd_import_key, hlp_import_key },
|
||||
{ "EXPORT_KEY", cmd_export_key, hlp_export_key },
|
||||
{ "GETVAL", cmd_getval, hlp_getval },
|
||||
{ "PUTVAL", cmd_putval, hlp_putval },
|
||||
{ "UPDATESTARTUPTTY", cmd_updatestartuptty, hlp_updatestartuptty },
|
||||
|
@ -2021,6 +2200,9 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
|
|||
|
||||
/* Cleanup. */
|
||||
assuan_release (ctx);
|
||||
xfree (ctrl->server_local->keydesc);
|
||||
xfree (ctrl->server_local->import_key);
|
||||
xfree (ctrl->server_local->export_key);
|
||||
if (ctrl->server_local->stopme)
|
||||
agent_exit (0);
|
||||
xfree (ctrl->server_local);
|
||||
|
|
|
@ -69,7 +69,7 @@ agent_write_private_key (const unsigned char *grip,
|
|||
{
|
||||
log_error ("secret key file `%s' already exists\n", fname);
|
||||
xfree (fname);
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
return gpg_error (GPG_ERR_EEXIST);
|
||||
}
|
||||
|
||||
/* FIXME: On POSIX systems we used include S_IRGRP as well. */
|
||||
|
@ -883,8 +883,8 @@ agent_public_key_from_file (ctrl_t ctrl,
|
|||
|
||||
|
||||
|
||||
/* Return the secret key as an S-Exp after locating it using the grip.
|
||||
Returns NULL if key is not available. 0 = key is available */
|
||||
/* Check whether the the secret key identified by GRIP is available.
|
||||
Returns 0 is the key is available. */
|
||||
int
|
||||
agent_key_available (const unsigned char *grip)
|
||||
{
|
||||
|
|
199
agent/genkey.c
199
agent/genkey.c
|
@ -1,5 +1,5 @@
|
|||
/* genkey.c - Generate a keypair
|
||||
* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2002, 2003, 2004, 2007, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -286,6 +286,69 @@ reenter_compare_cb (struct pin_entry_info_s *pi)
|
|||
}
|
||||
|
||||
|
||||
/* Ask the user for a new passphrase using PROMPT. On success the
|
||||
function returns 0 and store the passphrase at R_PASSPHRASE; if the
|
||||
user opted not to use a passphrase NULL will be stored there. The
|
||||
user needs to free the returned string. In case of an error and
|
||||
error code is returned and NULL stored at R_PASSPHRASE. */
|
||||
gpg_error_t
|
||||
agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
|
||||
char **r_passphrase)
|
||||
{
|
||||
gpg_error_t err;
|
||||
const char *text1 = prompt;
|
||||
const char *text2 = _("Please re-enter this passphrase");
|
||||
const char *initial_errtext = NULL;
|
||||
struct pin_entry_info_s *pi, *pi2;
|
||||
|
||||
*r_passphrase = NULL;
|
||||
|
||||
pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
|
||||
pi2 = pi + (sizeof *pi + 100);
|
||||
pi->max_length = 100;
|
||||
pi->max_tries = 3;
|
||||
pi->with_qualitybar = 1;
|
||||
pi2->max_length = 100;
|
||||
pi2->max_tries = 3;
|
||||
pi2->check_cb = reenter_compare_cb;
|
||||
pi2->check_cb_arg = pi->pin;
|
||||
|
||||
next_try:
|
||||
err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
|
||||
initial_errtext = NULL;
|
||||
if (!err)
|
||||
{
|
||||
if (check_passphrase_constraints (ctrl, pi->pin, 0))
|
||||
{
|
||||
pi->failed_tries = 0;
|
||||
pi2->failed_tries = 0;
|
||||
goto next_try;
|
||||
}
|
||||
/* Unless the passphrase is empty, ask to confirm it. */
|
||||
if (pi->pin && *pi->pin)
|
||||
{
|
||||
err = agent_askpin (ctrl, text2, NULL, NULL, pi2);
|
||||
if (err == -1)
|
||||
{ /* The re-entered one did not match and the user did not
|
||||
hit cancel. */
|
||||
initial_errtext = _("does not match - try again");
|
||||
goto next_try;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!err && *pi->pin)
|
||||
{
|
||||
/* User wants a passphrase. */
|
||||
*r_passphrase = xtrystrdup (pi->pin);
|
||||
if (!*r_passphrase)
|
||||
err = gpg_error_from_syserror ();
|
||||
}
|
||||
xfree (pi);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Generate a new keypair according to the parameters given in
|
||||
KEYPARAM */
|
||||
|
@ -294,7 +357,7 @@ agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
|
|||
membuf_t *outbuf)
|
||||
{
|
||||
gcry_sexp_t s_keyparam, s_key, s_private, s_public;
|
||||
struct pin_entry_info_s *pi, *pi2;
|
||||
char *passphrase = NULL;
|
||||
int rc;
|
||||
size_t len;
|
||||
char *buf;
|
||||
|
@ -307,63 +370,19 @@ agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
|
|||
}
|
||||
|
||||
/* Get the passphrase now, cause key generation may take a while. */
|
||||
{
|
||||
const char *text1 = _("Please enter the passphrase to%0A"
|
||||
"to protect your new key");
|
||||
const char *text2 = _("Please re-enter this passphrase");
|
||||
const char *initial_errtext = NULL;
|
||||
|
||||
pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
|
||||
pi2 = pi + (sizeof *pi + 100);
|
||||
pi->max_length = 100;
|
||||
pi->max_tries = 3;
|
||||
pi->with_qualitybar = 1;
|
||||
pi2->max_length = 100;
|
||||
pi2->max_tries = 3;
|
||||
pi2->check_cb = reenter_compare_cb;
|
||||
pi2->check_cb_arg = pi->pin;
|
||||
|
||||
next_try:
|
||||
rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
|
||||
initial_errtext = NULL;
|
||||
if (!rc)
|
||||
{
|
||||
if (check_passphrase_constraints (ctrl, pi->pin, 0))
|
||||
{
|
||||
pi->failed_tries = 0;
|
||||
pi2->failed_tries = 0;
|
||||
goto next_try;
|
||||
}
|
||||
if (pi->pin && *pi->pin)
|
||||
{
|
||||
rc = agent_askpin (ctrl, text2, NULL, NULL, pi2);
|
||||
if (rc == -1)
|
||||
{ /* The re-entered one did not match and the user did not
|
||||
hit cancel. */
|
||||
initial_errtext = _("does not match - try again");
|
||||
goto next_try;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
xfree (pi);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!*pi->pin)
|
||||
{
|
||||
xfree (pi);
|
||||
pi = NULL; /* User does not want a passphrase. */
|
||||
}
|
||||
}
|
||||
rc = agent_ask_new_passphrase (ctrl,
|
||||
_("Please enter the passphrase to%0A"
|
||||
"to protect your new key"),
|
||||
&passphrase);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = gcry_pk_genkey (&s_key, s_keyparam );
|
||||
gcry_sexp_release (s_keyparam);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("key generation failed: %s\n", gpg_strerror (rc));
|
||||
xfree (pi);
|
||||
xfree (passphrase);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -373,7 +392,7 @@ agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
|
|||
{
|
||||
log_error ("key generation failed: invalid return value\n");
|
||||
gcry_sexp_release (s_key);
|
||||
xfree (pi);
|
||||
xfree (passphrase);
|
||||
return gpg_error (GPG_ERR_INV_DATA);
|
||||
}
|
||||
s_public = gcry_sexp_find_token (s_key, "public-key", 0);
|
||||
|
@ -382,7 +401,7 @@ agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
|
|||
log_error ("key generation failed: invalid return value\n");
|
||||
gcry_sexp_release (s_private);
|
||||
gcry_sexp_release (s_key);
|
||||
xfree (pi);
|
||||
xfree (passphrase);
|
||||
return gpg_error (GPG_ERR_INV_DATA);
|
||||
}
|
||||
gcry_sexp_release (s_key); s_key = NULL;
|
||||
|
@ -390,8 +409,9 @@ agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
|
|||
/* store the secret key */
|
||||
if (DBG_CRYPTO)
|
||||
log_debug ("storing private key\n");
|
||||
rc = store_key (s_private, pi? pi->pin:NULL, 0);
|
||||
xfree (pi); pi = NULL;
|
||||
rc = store_key (s_private, passphrase, 0);
|
||||
xfree (passphrase);
|
||||
passphrase = NULL;
|
||||
gcry_sexp_release (s_private);
|
||||
if (rc)
|
||||
{
|
||||
|
@ -423,65 +443,20 @@ agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen,
|
|||
|
||||
|
||||
|
||||
/* Apply a new passpahrse to the key S_SKEY and store it. */
|
||||
/* Apply a new passphrase to the key S_SKEY and store it. */
|
||||
int
|
||||
agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey)
|
||||
{
|
||||
struct pin_entry_info_s *pi, *pi2;
|
||||
int rc;
|
||||
char *passphrase;
|
||||
|
||||
{
|
||||
const char *text1 = _("Please enter the new passphrase");
|
||||
const char *text2 = _("Please re-enter this passphrase");
|
||||
const char *initial_errtext = NULL;
|
||||
|
||||
pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
|
||||
pi2 = pi + (sizeof *pi + 100);
|
||||
pi->max_length = 100;
|
||||
pi->max_tries = 3;
|
||||
pi->with_qualitybar = 1;
|
||||
pi2->max_length = 100;
|
||||
pi2->max_tries = 3;
|
||||
pi2->check_cb = reenter_compare_cb;
|
||||
pi2->check_cb_arg = pi->pin;
|
||||
|
||||
next_try:
|
||||
rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
|
||||
initial_errtext = NULL;
|
||||
if (!rc)
|
||||
{
|
||||
if (check_passphrase_constraints (ctrl, pi->pin, 0))
|
||||
{
|
||||
pi->failed_tries = 0;
|
||||
pi2->failed_tries = 0;
|
||||
goto next_try;
|
||||
}
|
||||
/* Unless the passphrase is empty, ask to confirm it. */
|
||||
if (pi->pin && *pi->pin)
|
||||
{
|
||||
rc = agent_askpin (ctrl, text2, NULL, NULL, pi2);
|
||||
if (rc == -1)
|
||||
{ /* The re-entered one did not match and the user did not
|
||||
hit cancel. */
|
||||
initial_errtext = _("does not match - try again");
|
||||
goto next_try;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
xfree (pi);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!*pi->pin)
|
||||
{
|
||||
xfree (pi);
|
||||
pi = NULL; /* User does not want a passphrase. */
|
||||
}
|
||||
}
|
||||
|
||||
rc = store_key (s_skey, pi? pi->pin:NULL, 1);
|
||||
xfree (pi);
|
||||
rc = agent_ask_new_passphrase (ctrl,
|
||||
_("Please enter the new passphrase"),
|
||||
&passphrase);
|
||||
if (!rc)
|
||||
{
|
||||
rc = store_key (s_skey, passphrase, 1);
|
||||
xfree (passphrase);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
2360
agent/minip12.c
2360
agent/minip12.c
File diff suppressed because it is too large
Load diff
|
@ -1,36 +0,0 @@
|
|||
/* minip12.h - Global definitions for the minimal pkcs-12 implementation.
|
||||
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MINIP12_H
|
||||
#define MINIP12_H
|
||||
|
||||
#include <gcrypt.h>
|
||||
|
||||
gcry_mpi_t *p12_parse (const unsigned char *buffer, size_t length,
|
||||
const char *pw,
|
||||
void (*certcb)(void*, const unsigned char*, size_t),
|
||||
void *certcbarg);
|
||||
|
||||
unsigned char *p12_build (gcry_mpi_t *kparms,
|
||||
unsigned char *cert, size_t certlen,
|
||||
const char *pw, const char *charset,
|
||||
size_t *r_length);
|
||||
|
||||
|
||||
#endif /*MINIP12_H*/
|
|
@ -43,7 +43,6 @@
|
|||
|
||||
#define JNLIB_NEED_LOG_LOGV
|
||||
#include "agent.h"
|
||||
#include "minip12.h"
|
||||
#include "simple-pwquery.h"
|
||||
#include "i18n.h"
|
||||
#include "sysutils.h"
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
|
||||
#define JNLIB_NEED_LOG_LOGV
|
||||
#include "agent.h"
|
||||
#include "minip12.h"
|
||||
#include "i18n.h"
|
||||
#include "get-passphrase.h"
|
||||
#include "sysutils.h"
|
||||
|
@ -63,8 +62,6 @@ enum cmd_and_opt_values
|
|||
oS2Kcalibration,
|
||||
oCanonical,
|
||||
|
||||
oP12Import,
|
||||
oP12Export,
|
||||
oP12Charset,
|
||||
oStore,
|
||||
oForce,
|
||||
|
@ -116,11 +113,6 @@ static ARGPARSE_OPTS opts[] = {
|
|||
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"),
|
||||
|
||||
ARGPARSE_c (oS2Kcalibration, "s2k-calibration", "@"),
|
||||
|
||||
ARGPARSE_group (301, N_("@\nOptions:\n ")),
|
||||
|
@ -635,7 +627,7 @@ rsa_key_check (struct rsa_secret_key_s *skey)
|
|||
return err? -1:0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* A callback used by p12_parse to return a certificate. */
|
||||
static void
|
||||
import_p12_cert_cb (void *opaque, const unsigned char *cert, size_t certlen)
|
||||
|
@ -793,6 +785,7 @@ import_p12_file (const char *fname)
|
|||
|
||||
xfree (result);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -865,6 +858,7 @@ is_keygrip (const char *string)
|
|||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void
|
||||
export_p12_file (const char *fname)
|
||||
{
|
||||
|
@ -1009,6 +1003,7 @@ export_p12_file (const char *fname)
|
|||
fwrite (key, keylen, 1, stdout);
|
||||
xfree (key);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -1059,8 +1054,6 @@ main (int argc, char **argv )
|
|||
case oShadow: cmd = oShadow; break;
|
||||
case oShowShadowInfo: cmd = oShowShadowInfo; break;
|
||||
case oShowKeygrip: cmd = oShowKeygrip; break;
|
||||
case oP12Import: cmd = oP12Import; break;
|
||||
case oP12Export: cmd = oP12Export; break;
|
||||
case oP12Charset: opt_p12_charset = pargs.r.ret_str; break;
|
||||
|
||||
case oS2Kcalibration: cmd = oS2Kcalibration; break;
|
||||
|
@ -1105,10 +1098,6 @@ main (int argc, char **argv )
|
|||
show_shadow_info (fname);
|
||||
else if (cmd == oShowKeygrip)
|
||||
show_keygrip (fname);
|
||||
else if (cmd == oP12Import)
|
||||
import_p12_file (fname);
|
||||
else if (cmd == oP12Export)
|
||||
export_p12_file (fname);
|
||||
else if (cmd == oS2Kcalibration)
|
||||
{
|
||||
if (!opt.verbose)
|
||||
|
|
|
@ -415,7 +415,7 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
|
|||
unsigned char *p;
|
||||
gcry_md_hd_t md;
|
||||
|
||||
/* Create an S-expression with the procted-at timestamp. */
|
||||
/* Create an S-expression with the protected-at timestamp. */
|
||||
memcpy (timestamp_exp, "(12:protected-at15:", 19);
|
||||
gnupg_get_isotime (timestamp_exp+19);
|
||||
timestamp_exp[19+15] = ')';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue