mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-21 14:47:03 +01:00
agent: Make --disable-extended-key-format a dummy option.
* agent/agent.h (opt): Remove enable_extended_key_format. * agent/gpg-agent.c (enum cmd_and_opt_values): Turn oDisableExtendedKeyFormat and oEnableExtendedKeyFormat into dummy options. * agent/protect.c (do_encryption): Remove arg use_ocb and corresponding code. (agent_protect): Ditto. Change all callers. * agent/command.c (cmd_readkey): Do not test for key availability here but defer that agent_write_shadow_key. * agent/findkey.c (agent_write_private_key): Simplify due to the removal of disable-extended-key-format. (write_extended_private_key): Fold into agent_write_private_key. Remove the maybe_update arg. (agent_write_shadow_key): Ditto. Simplify. -- GnuPG-bug-id: 6386 Backported-from-master: 6d792ae2eb46b3c411d36a87f0d08fbfc1b65cc9 But with large changes to get 2.2 more aligned with master again. This is not finished; in particular the bug is not fixed; this comes wit the next patch.
This commit is contained in:
parent
db73f17f0c
commit
4f754caad8
@ -132,13 +132,6 @@ struct
|
||||
passphrase change. */
|
||||
int enable_passphrase_history;
|
||||
|
||||
/* If set the extended key format is used for new keys. Note that
|
||||
* this may have the value 2 in which case
|
||||
* --disable-extended-key-format won't have any effect and thus
|
||||
* effectivley locking it. This is required to support existing
|
||||
* profiles which lock the use of --enable-extended-key-format. */
|
||||
int enable_extended_key_format;
|
||||
|
||||
int running_detached; /* We are running detached from the tty. */
|
||||
|
||||
/* If this global option is true, the passphrase cache is ignored
|
||||
@ -430,9 +423,8 @@ gpg_error_t agent_modify_description (const char *in, const char *comment,
|
||||
const gcry_sexp_t key, char **result);
|
||||
int agent_write_private_key (const unsigned char *grip,
|
||||
const void *buffer, size_t length, int force,
|
||||
time_t timestamp,
|
||||
const char *serialno, const char *keyref,
|
||||
const char *dispserialno);
|
||||
const char *dispserialno, time_t timestamp);
|
||||
gpg_error_t agent_key_from_file (ctrl_t ctrl,
|
||||
const char *cache_nonce,
|
||||
const char *desc_text,
|
||||
@ -533,7 +525,7 @@ unsigned char get_standard_s2k_count_rfc4880 (void);
|
||||
unsigned long get_standard_s2k_time (void);
|
||||
int agent_protect (const unsigned char *plainkey, const char *passphrase,
|
||||
unsigned char **result, size_t *resultlen,
|
||||
unsigned long s2k_count, int use_ocb);
|
||||
unsigned long s2k_count);
|
||||
gpg_error_t agent_unprotect (ctrl_t ctrl,
|
||||
const unsigned char *protectedkey, const char *passphrase,
|
||||
gnupg_isotime_t protected_at,
|
||||
@ -552,8 +544,7 @@ gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo,
|
||||
const unsigned char *s2ksalt,
|
||||
unsigned int s2kcount,
|
||||
unsigned char *key, size_t keylen);
|
||||
gpg_error_t agent_write_shadow_key (int maybe_update,
|
||||
const unsigned char *grip,
|
||||
gpg_error_t agent_write_shadow_key (const unsigned char *grip,
|
||||
const char *serialno, const char *keyid,
|
||||
const unsigned char *pkbuf, int force,
|
||||
const char *dispserialno);
|
||||
|
@ -2499,7 +2499,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
|
||||
|
||||
/* (Shadow)-key is not available in our key storage. */
|
||||
agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno);
|
||||
err = agent_write_shadow_key (0, grip, serialno, authkeyid, pkbuf, 0,
|
||||
err = agent_write_shadow_key (grip, serialno, authkeyid, pkbuf, 0,
|
||||
dispserialno);
|
||||
xfree (dispserialno);
|
||||
if (err)
|
||||
@ -3028,7 +3028,7 @@ ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
|
||||
buffer_new, buffer_new_n);
|
||||
|
||||
if (*passphrase)
|
||||
err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0, -1);
|
||||
err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0);
|
||||
else
|
||||
{
|
||||
/* The key derivation function does not support zero length
|
||||
@ -3159,8 +3159,8 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
|
||||
|
||||
/* Store this key to our key storage. We do not store a creation
|
||||
* timestamp because we simply do not know. */
|
||||
err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0, 0,
|
||||
NULL, NULL, NULL);
|
||||
err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0,
|
||||
NULL, NULL, NULL, 0);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
|
@ -975,7 +975,6 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static const char hlp_readkey[] =
|
||||
"READKEY [--no-data] <hexstring_with_keygrip>\n"
|
||||
@ -1040,20 +1039,11 @@ cmd_readkey (assuan_context_t ctx, char *line)
|
||||
}
|
||||
|
||||
agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno);
|
||||
if (agent_key_available (grip))
|
||||
{
|
||||
/* Shadow-key is not available in our key storage. */
|
||||
rc = agent_write_shadow_key (0, grip, serialno, keyid, pkbuf, 0,
|
||||
dispserialno);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Shadow-key is available in our key storage but ne check
|
||||
* whether we need to update it with a new display-s/n or
|
||||
* whatever. */
|
||||
rc = agent_write_shadow_key (1, grip, serialno, keyid, pkbuf, 0,
|
||||
dispserialno);
|
||||
}
|
||||
/* Shadow-key is or is not available in our key storage. In
|
||||
* any case we need to check whether we need to update with
|
||||
* a new display-s/n or whatever. */
|
||||
rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0,
|
||||
dispserialno);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
@ -2435,14 +2425,14 @@ cmd_import_key (assuan_context_t ctx, char *line)
|
||||
if (passphrase)
|
||||
{
|
||||
err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
|
||||
ctrl->s2k_count, -1);
|
||||
ctrl->s2k_count);
|
||||
if (!err)
|
||||
err = agent_write_private_key (grip, finalkey, finalkeylen, force,
|
||||
opt_timestamp, NULL, NULL, NULL);
|
||||
NULL, NULL, NULL, opt_timestamp);
|
||||
}
|
||||
else
|
||||
err = agent_write_private_key (grip, key, realkeylen, force,
|
||||
opt_timestamp, NULL, NULL, NULL);
|
||||
NULL, NULL, NULL, opt_timestamp);
|
||||
|
||||
leave:
|
||||
gcry_sexp_release (openpgp_sexp);
|
||||
|
@ -1068,9 +1068,9 @@ convert_from_openpgp_native (ctrl_t ctrl,
|
||||
|
||||
if (!agent_protect (*r_key, passphrase,
|
||||
&protectedkey, &protectedkeylen,
|
||||
ctrl->s2k_count, -1))
|
||||
ctrl->s2k_count))
|
||||
agent_write_private_key (grip, protectedkey, protectedkeylen,
|
||||
1, 0, NULL, NULL, NULL);
|
||||
1/*force*/, NULL, NULL, NULL, 0);
|
||||
xfree (protectedkey);
|
||||
}
|
||||
else
|
||||
@ -1079,7 +1079,7 @@ convert_from_openpgp_native (ctrl_t ctrl,
|
||||
agent_write_private_key (grip,
|
||||
*r_key,
|
||||
gcry_sexp_canon_len (*r_key, 0, NULL,NULL),
|
||||
1, 0, NULL, NULL, NULL);
|
||||
1/*force*/, NULL, NULL, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
418
agent/findkey.c
418
agent/findkey.c
@ -1,7 +1,8 @@
|
||||
/* findkey.c - Locate the secret key
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
|
||||
* 2010, 2011 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2014 Werner Koch
|
||||
* Copyright (C) 2014, 2019 Werner Koch
|
||||
* Copyright (C) 2023 g10 Code GmbH
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -67,20 +68,23 @@ fname_from_keygrip (const unsigned char *grip)
|
||||
}
|
||||
|
||||
|
||||
/* Note: Ownership of FNAME and FP are moved to this function.
|
||||
* OLD_FORMAT is true if the file exists but is still in the
|
||||
* non-extended mode format. If MAYBE_UPDATE is set the function
|
||||
* assumes that the file exists but writes it only if it figures that
|
||||
* an update is required. */
|
||||
static gpg_error_t
|
||||
write_extended_private_key (int maybe_update,
|
||||
char *fname, estream_t fp,
|
||||
int old_format, int newkey,
|
||||
const void *buf, size_t len, time_t timestamp,
|
||||
const char *serialno, const char *keyref,
|
||||
const char *dispserialno)
|
||||
/* Write the S-expression formatted key (BUFFER,LENGTH) to our key
|
||||
* storage. With FORCE passed as true an existing key with the given
|
||||
* GRIP will get overwritten. If SERIALNO and KEYREF are given a
|
||||
* Token line is added to the key if the extended format is used. If
|
||||
* TIMESTAMP is not zero and the key doies not yet exists it will be
|
||||
* recorded as creation date. */
|
||||
int
|
||||
agent_write_private_key (const unsigned char *grip,
|
||||
const void *buffer, size_t length, int force,
|
||||
const char *serialno, const char *keyref,
|
||||
const char *dispserialno,
|
||||
time_t timestamp)
|
||||
{
|
||||
gpg_error_t err;
|
||||
char *fname;
|
||||
estream_t fp;
|
||||
int update, newkey;
|
||||
nvc_t pk = NULL;
|
||||
gcry_sexp_t key = NULL;
|
||||
int remove = 0;
|
||||
@ -89,54 +93,122 @@ write_extended_private_key (int maybe_update,
|
||||
char *dispserialno_buffer = NULL;
|
||||
char **tokenfields = NULL;
|
||||
|
||||
if (old_format || newkey)
|
||||
fname = fname_from_keygrip (grip);
|
||||
if (!fname)
|
||||
return out_of_core ();
|
||||
|
||||
/* FIXME: Write to a temp file first so that write failures during
|
||||
key updates won't lead to a key loss. */
|
||||
|
||||
if (!force && !gnupg_access (fname, F_OK))
|
||||
{
|
||||
/* We must create a new NVC if the key is still in the old
|
||||
* format and of course if it is a new key. */
|
||||
pk = nvc_new_private_key ();
|
||||
if (!pk)
|
||||
log_error ("secret key file '%s' already exists\n", fname);
|
||||
xfree (fname);
|
||||
return gpg_error (GPG_ERR_EEXIST);
|
||||
}
|
||||
|
||||
fp = es_fopen (fname, force? "rb+,mode=-rw" : "wbx,mode=-rw");
|
||||
if (!fp)
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error_from_syserror ();
|
||||
|
||||
if (force && gpg_err_code (tmperr) == GPG_ERR_ENOENT)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
fp = es_fopen (fname, "wbx,mode=-rw");
|
||||
if (!fp)
|
||||
tmperr = gpg_error_from_syserror ();
|
||||
}
|
||||
if (!fp)
|
||||
{
|
||||
log_error ("can't create '%s': %s\n", fname, gpg_strerror (tmperr));
|
||||
xfree (fname);
|
||||
return tmperr;
|
||||
}
|
||||
update = 0;
|
||||
newkey = 1;
|
||||
}
|
||||
else if (force)
|
||||
{
|
||||
gpg_error_t rc;
|
||||
char first;
|
||||
|
||||
/* See if an existing key is in extended format. */
|
||||
if (es_fread (&first, 1, 1, fp) != 1)
|
||||
{
|
||||
rc = gpg_error_from_syserror ();
|
||||
log_error ("error reading first byte from '%s': %s\n",
|
||||
fname, strerror (errno));
|
||||
xfree (fname);
|
||||
es_fclose (fp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = es_fseek (fp, 0, SEEK_SET);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error seeking in '%s': %s\n", fname, strerror (errno));
|
||||
xfree (fname);
|
||||
es_fclose (fp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (first == '(')
|
||||
{
|
||||
/* Key is still in the old format - force it into extended
|
||||
* format. We do not request an update here because an
|
||||
* existing key is not yet in extended key format and no
|
||||
* extended infos are yet available. */
|
||||
update = 0;
|
||||
newkey = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Key is already in the extended format. */
|
||||
update = 1;
|
||||
newkey = 0;
|
||||
}
|
||||
maybe_update = 0; /* Always write. */
|
||||
}
|
||||
else
|
||||
{ /* Parse the existing NVC. */
|
||||
{
|
||||
/* The key file did not exist: we assume this is a new key and
|
||||
* write the Created: entry. */
|
||||
update = 0;
|
||||
newkey = 1;
|
||||
}
|
||||
|
||||
|
||||
if (update)
|
||||
{
|
||||
int lineno = 0;
|
||||
|
||||
err = nvc_parse_private_key (&pk, &lineno, fp);
|
||||
if (err)
|
||||
if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
|
||||
{
|
||||
log_error ("error parsing '%s' line %d: %s\n",
|
||||
fname, lineno, gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pk = nvc_new_private_key ();
|
||||
if (!pk)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
es_clearerr (fp);
|
||||
|
||||
err = gcry_sexp_sscan (&key, NULL, buf, len);
|
||||
/* Turn (BUFFER,LENGTH) into a gcrypt s-expression and set it into
|
||||
* our name value container. */
|
||||
err = gcry_sexp_sscan (&key, NULL, buffer, length);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
err = nvc_set_private_key (pk, key);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
/* If a timestamp has been supplied and the key is new write a
|
||||
* creation timestamp. Note that we can't add this item if we are
|
||||
* still in the old format. We also add an extra check that there
|
||||
* is no Created item yet. */
|
||||
if (timestamp && newkey && !nvc_lookup (pk, "Created:"))
|
||||
{
|
||||
gnupg_isotime_t timebuf;
|
||||
|
||||
epoch2isotime (timebuf, timestamp);
|
||||
err = nvc_add (pk, "Created:", timebuf);
|
||||
if (err)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* If requested write a Token line. */
|
||||
if (serialno && keyref)
|
||||
{
|
||||
@ -179,13 +251,12 @@ write_extended_private_key (int maybe_update,
|
||||
err = nvc_add (pk, "Token:", token);
|
||||
if (err)
|
||||
goto leave;
|
||||
maybe_update = 0; /* Force write. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Token exists: Update the display s/n. It may have
|
||||
* changed due to changes in a newer software version. */
|
||||
if (maybe_update && s && (tokenfields = strtokenize (s, " \t\n"))
|
||||
if (s && (tokenfields = strtokenize (s, " \t\n"))
|
||||
&& tokenfields[0] && tokenfields[1] && tokenfields[2]
|
||||
&& tokenfields[3]
|
||||
&& !strcmp (tokenfields[3], dispserialno))
|
||||
@ -195,34 +266,44 @@ write_extended_private_key (int maybe_update,
|
||||
err = nve_set (item, token);
|
||||
if (err)
|
||||
goto leave;
|
||||
maybe_update = 0; /* Force write. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If a timestamp has been supplied and the key is new, write a
|
||||
* creation timestamp. (We douple check that there is no Created
|
||||
* item yet.)*/
|
||||
if (timestamp && newkey && !nvc_lookup (pk, "Created:"))
|
||||
{
|
||||
gnupg_isotime_t timebuf;
|
||||
|
||||
epoch2isotime (timebuf, timestamp);
|
||||
err = nvc_add (pk, "Created:", timebuf);
|
||||
if (err)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Back to start and write. */
|
||||
err = es_fseek (fp, 0, SEEK_SET);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
if (!maybe_update)
|
||||
err = nvc_write (pk, fp);
|
||||
if (!err)
|
||||
err = es_fflush (fp);
|
||||
if (err)
|
||||
{
|
||||
err = nvc_write (pk, fp);
|
||||
if (!err)
|
||||
err = es_fflush (fp);
|
||||
if (err)
|
||||
{
|
||||
log_error ("error writing '%s': %s\n", fname, gpg_strerror (err));
|
||||
remove = 1;
|
||||
goto leave;
|
||||
}
|
||||
log_error ("error writing '%s': %s\n", fname, gpg_strerror (err));
|
||||
remove = 1;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (ftruncate (es_fileno (fp), es_ftello (fp)))
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("error truncating '%s': %s\n", fname, gpg_strerror (err));
|
||||
remove = 1;
|
||||
goto leave;
|
||||
}
|
||||
if (ftruncate (es_fileno (fp), es_ftello (fp)))
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("error truncating '%s': %s\n", fname, gpg_strerror (err));
|
||||
remove = 1;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (es_fclose (fp))
|
||||
@ -235,8 +316,7 @@ write_extended_private_key (int maybe_update,
|
||||
else
|
||||
fp = NULL;
|
||||
|
||||
if (!maybe_update)
|
||||
bump_key_eventcounter ();
|
||||
bump_key_eventcounter ();
|
||||
|
||||
leave:
|
||||
es_fclose (fp);
|
||||
@ -252,136 +332,6 @@ write_extended_private_key (int maybe_update,
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Write an S-expression formatted key to our key storage. With FORCE
|
||||
* passed as true an existing key with the given GRIP will get
|
||||
* overwritten. If TIMESTAMP is not zero and the key does not yet
|
||||
* exists it will be recorded as creation date. If SERIALNO, KEYREF,
|
||||
* of DISPSERIALNO are not NULL they will be recorded as well. */
|
||||
int
|
||||
agent_write_private_key (const unsigned char *grip,
|
||||
const void *buffer, size_t length,
|
||||
int force, time_t timestamp,
|
||||
const char *serialno, const char *keyref,
|
||||
const char *dispserialno)
|
||||
{
|
||||
char *fname;
|
||||
estream_t fp;
|
||||
|
||||
fname = fname_from_keygrip (grip);
|
||||
if (!fname)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
/* FIXME: Write to a temp file first so that write failures during
|
||||
key updates won't lead to a key loss. */
|
||||
|
||||
if (!force && !gnupg_access (fname, F_OK))
|
||||
{
|
||||
log_error ("secret key file '%s' already exists\n", fname);
|
||||
xfree (fname);
|
||||
return gpg_error (GPG_ERR_EEXIST);
|
||||
}
|
||||
|
||||
fp = es_fopen (fname, force? "rb+,mode=-rw" : "wbx,mode=-rw");
|
||||
if (!fp)
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error_from_syserror ();
|
||||
|
||||
if (force && gpg_err_code (tmperr) == GPG_ERR_ENOENT)
|
||||
{
|
||||
fp = es_fopen (fname, "wbx,mode=-rw");
|
||||
if (!fp)
|
||||
tmperr = gpg_error_from_syserror ();
|
||||
}
|
||||
if (!fp)
|
||||
{
|
||||
log_error ("can't create '%s': %s\n", fname, gpg_strerror (tmperr));
|
||||
xfree (fname);
|
||||
return tmperr;
|
||||
}
|
||||
}
|
||||
else if (force)
|
||||
{
|
||||
gpg_error_t rc;
|
||||
char first;
|
||||
|
||||
/* See if an existing key is in extended format. */
|
||||
if (es_fread (&first, 1, 1, fp) != 1)
|
||||
{
|
||||
rc = gpg_error_from_syserror ();
|
||||
log_error ("error reading first byte from '%s': %s\n",
|
||||
fname, strerror (errno));
|
||||
xfree (fname);
|
||||
es_fclose (fp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = es_fseek (fp, 0, SEEK_SET);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error seeking in '%s': %s\n", fname, strerror (errno));
|
||||
xfree (fname);
|
||||
es_fclose (fp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (first != '(')
|
||||
{
|
||||
/* Key is already in the extended format. */
|
||||
return write_extended_private_key (0, fname, fp, 0, 0,
|
||||
buffer, length,
|
||||
timestamp, serialno, keyref,
|
||||
dispserialno);
|
||||
}
|
||||
if (first == '(' && opt.enable_extended_key_format)
|
||||
{
|
||||
/* Key is in the old format - but we want the extended format. */
|
||||
return write_extended_private_key (0, fname, fp, 1, 0,
|
||||
buffer, length,
|
||||
timestamp, serialno, keyref,
|
||||
dispserialno);
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.enable_extended_key_format)
|
||||
return write_extended_private_key (0, fname, fp, 0, 1,
|
||||
buffer, length,
|
||||
timestamp, serialno, keyref,
|
||||
dispserialno);
|
||||
|
||||
if (es_fwrite (buffer, length, 1, fp) != 1)
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error_from_syserror ();
|
||||
log_error ("error writing '%s': %s\n", fname, gpg_strerror (tmperr));
|
||||
es_fclose (fp);
|
||||
gnupg_remove (fname);
|
||||
xfree (fname);
|
||||
return tmperr;
|
||||
}
|
||||
|
||||
/* When force is given, the file might have to be truncated. */
|
||||
if (force && ftruncate (es_fileno (fp), es_ftello (fp)))
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error_from_syserror ();
|
||||
log_error ("error truncating '%s': %s\n", fname, gpg_strerror (tmperr));
|
||||
es_fclose (fp);
|
||||
gnupg_remove (fname);
|
||||
xfree (fname);
|
||||
return tmperr;
|
||||
}
|
||||
|
||||
if (es_fclose (fp))
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error_from_syserror ();
|
||||
log_error ("error closing '%s': %s\n", fname, gpg_strerror (tmperr));
|
||||
gnupg_remove (fname);
|
||||
xfree (fname);
|
||||
return tmperr;
|
||||
}
|
||||
bump_key_eventcounter ();
|
||||
xfree (fname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Callback function to try the unprotection from the passphrase query
|
||||
code. */
|
||||
@ -837,19 +787,14 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta)
|
||||
unsigned char *buf;
|
||||
size_t buflen, erroff;
|
||||
gcry_sexp_t s_skey;
|
||||
char hexgrip[40+4+1];
|
||||
char first;
|
||||
|
||||
*result = NULL;
|
||||
if (r_keymeta)
|
||||
*r_keymeta = NULL;
|
||||
|
||||
bin2hex (grip, 20, hexgrip);
|
||||
strcpy (hexgrip+40, ".key");
|
||||
|
||||
fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
|
||||
hexgrip, NULL);
|
||||
fp = es_fopen (fname, "rb");
|
||||
fname = fname_from_keygrip (grip);
|
||||
fp = fname? es_fopen (fname, "rb") : NULL;
|
||||
if (!fp)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
@ -1722,15 +1667,13 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text,
|
||||
|
||||
|
||||
/* Write an S-expression formatted shadow key to our key storage.
|
||||
Shadow key is created by an S-expression public key in PKBUF and
|
||||
card's SERIALNO and the IDSTRING. With FORCE passed as true an
|
||||
existing key with the given GRIP will get overwritten. If
|
||||
DISPSERIALNO is not NULL the human readable s/n will also be
|
||||
recorded in the key file. If MAYBE_UPDATE is set it is assumed that
|
||||
the shadow key already exists and we test whether we should update
|
||||
it (FORCE is ignored in this case). */
|
||||
* Shadow key is created by an S-expression public key in PKBUF and
|
||||
* card's SERIALNO and the IDSTRING. With FORCE passed as true an
|
||||
* existing key with the given GRIP will get overwritten. If
|
||||
* DISPSERIALNO is not NULL the human readable s/n will also be
|
||||
* recorded in the key file. */
|
||||
gpg_error_t
|
||||
agent_write_shadow_key (int maybe_update, const unsigned char *grip,
|
||||
agent_write_shadow_key (const unsigned char *grip,
|
||||
const char *serialno, const char *keyid,
|
||||
const unsigned char *pkbuf, int force,
|
||||
const char *dispserialno)
|
||||
@ -1739,12 +1682,6 @@ agent_write_shadow_key (int maybe_update, const unsigned char *grip,
|
||||
unsigned char *shadow_info;
|
||||
unsigned char *shdkey;
|
||||
size_t len;
|
||||
char *fname = NULL;
|
||||
estream_t fp = NULL;
|
||||
char first;
|
||||
|
||||
if (maybe_update && !opt.enable_extended_key_format)
|
||||
return 0; /* Silently ignore. */
|
||||
|
||||
/* Just in case some caller did not parse the stuff correctly, skip
|
||||
* leading spaces. */
|
||||
@ -1766,62 +1703,11 @@ agent_write_shadow_key (int maybe_update, const unsigned char *grip,
|
||||
}
|
||||
|
||||
len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
|
||||
|
||||
if (maybe_update) /* Update mode. */
|
||||
{
|
||||
fname = fname_from_keygrip (grip);
|
||||
if (!fname)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
|
||||
fp = es_fopen (fname, "rb+,mode=-rw");
|
||||
if (!fp)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("shadow key file '%s' disappeared\n", fname);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* See if an existing key is in extended format. */
|
||||
if (es_fread (&first, 1, 1, fp) != 1)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("error reading first byte from '%s': %s\n",
|
||||
fname, gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (es_fseek (fp, 0, SEEK_SET))
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("error seeking in '%s': %s\n", fname, gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* "(first == '(')" indicates that the key is in the old format. */
|
||||
err = write_extended_private_key (maybe_update,
|
||||
fname, fp, (first == '('), 0,
|
||||
shdkey, len,
|
||||
0, serialno, keyid,
|
||||
dispserialno);
|
||||
fname = NULL; /* Ownership was transferred. */
|
||||
fp = NULL; /* Ditto. */
|
||||
}
|
||||
else /* Standard mode */
|
||||
{
|
||||
err = agent_write_private_key (grip, shdkey, len, force, 0,
|
||||
serialno, keyid, dispserialno);
|
||||
}
|
||||
|
||||
leave:
|
||||
xfree (fname);
|
||||
es_fclose (fp);
|
||||
err = agent_write_private_key (grip, shdkey, len, force,
|
||||
serialno, keyid, dispserialno, 0);
|
||||
xfree (shdkey);
|
||||
if (err)
|
||||
log_error ("error %s key: %s\n", maybe_update? "updating":"writing",
|
||||
gpg_strerror (err));
|
||||
log_error ("error writing key: %s\n", gpg_strerror (err));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ store_key (gcry_sexp_t private, const char *passphrase, int force,
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
rc = agent_protect (buf, passphrase, &p, &len, s2k_count, -1);
|
||||
rc = agent_protect (buf, passphrase, &p, &len, s2k_count);
|
||||
if (rc)
|
||||
{
|
||||
xfree (buf);
|
||||
@ -69,8 +69,8 @@ store_key (gcry_sexp_t private, const char *passphrase, int force,
|
||||
buf = p;
|
||||
}
|
||||
|
||||
rc = agent_write_private_key (grip, buf, len, force, timestamp,
|
||||
NULL, NULL, NULL);
|
||||
rc = agent_write_private_key (grip, buf, len, force,
|
||||
NULL, NULL, NULL, timestamp);
|
||||
xfree (buf);
|
||||
return rc;
|
||||
}
|
||||
|
@ -116,8 +116,6 @@ enum cmd_and_opt_values
|
||||
oCheckSymPassphrasePattern,
|
||||
oMaxPassphraseDays,
|
||||
oEnablePassphraseHistory,
|
||||
oDisableExtendedKeyFormat,
|
||||
oEnableExtendedKeyFormat,
|
||||
oStealSocket,
|
||||
oUseStandardSocket,
|
||||
oNoUseStandardSocket,
|
||||
@ -227,8 +225,6 @@ static ARGPARSE_OPTS opts[] = {
|
||||
/* */ "@"
|
||||
#endif
|
||||
),
|
||||
ARGPARSE_s_n (oDisableExtendedKeyFormat, "disable-extended-key-format", "@"),
|
||||
ARGPARSE_s_n (oEnableExtendedKeyFormat, "enable-extended-key-format", "@"),
|
||||
ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
|
||||
ARGPARSE_op_u (oAutoExpandSecmem, "auto-expand-secmem", "@"),
|
||||
ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
|
||||
@ -303,7 +299,8 @@ static ARGPARSE_OPTS opts[] = {
|
||||
ARGPARSE_s_n (oNoUseStandardSocket, "no-use-standard-socket", "@"),
|
||||
|
||||
/* Dummy options. */
|
||||
|
||||
ARGPARSE_s_n (oNoop, "disable-extended-key-format", "@"),
|
||||
ARGPARSE_s_n (oNoop, "enable-extended-key-format", "@"),
|
||||
|
||||
ARGPARSE_end () /* End of list */
|
||||
};
|
||||
@ -874,7 +871,6 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
|
||||
opt.check_sym_passphrase_pattern = NULL;
|
||||
opt.max_passphrase_days = MAX_PASSPHRASE_DAYS;
|
||||
opt.enable_passphrase_history = 0;
|
||||
opt.enable_extended_key_format = 1;
|
||||
opt.ignore_cache_for_signing = 0;
|
||||
opt.allow_mark_trusted = 1;
|
||||
opt.sys_trustlist_name = NULL;
|
||||
@ -956,14 +952,6 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
|
||||
opt.enable_passphrase_history = 1;
|
||||
break;
|
||||
|
||||
case oEnableExtendedKeyFormat:
|
||||
opt.enable_extended_key_format = 2;
|
||||
break;
|
||||
case oDisableExtendedKeyFormat:
|
||||
if (opt.enable_extended_key_format != 2)
|
||||
opt.enable_extended_key_format = 0;
|
||||
break;
|
||||
|
||||
case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break;
|
||||
|
||||
case oAllowMarkTrusted: opt.allow_mark_trusted = 1; break;
|
||||
|
@ -413,7 +413,7 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force)
|
||||
char *dispserialno;
|
||||
|
||||
agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno);
|
||||
rc = agent_write_shadow_key (0, grip, serialno, item->id, pubkey,
|
||||
rc = agent_write_shadow_key (grip, serialno, item->id, pubkey,
|
||||
force, dispserialno);
|
||||
xfree (dispserialno);
|
||||
}
|
||||
|
@ -98,7 +98,6 @@ static const char *opt_passphrase;
|
||||
static char *opt_prompt;
|
||||
static int opt_status_msg;
|
||||
static const char *opt_agent_program;
|
||||
static int opt_debug_use_ocb;
|
||||
|
||||
static char *get_passphrase (int promptno);
|
||||
static void release_passphrase (char *pw);
|
||||
@ -345,8 +344,7 @@ read_and_protect (const char *fname)
|
||||
return;
|
||||
|
||||
pw = get_passphrase (1);
|
||||
rc = agent_protect (key, pw, &result, &resultlen, 0,
|
||||
opt_debug_use_ocb? 1 : -1);
|
||||
rc = agent_protect (key, pw, &result, &resultlen, 0);
|
||||
release_passphrase (pw);
|
||||
xfree (key);
|
||||
if (rc)
|
||||
@ -605,7 +603,7 @@ main (int argc, char **argv )
|
||||
case oHaveCert: opt_have_cert = 1; break;
|
||||
case oPrompt: opt_prompt = pargs.r.ret_str; break;
|
||||
case oStatusMsg: opt_status_msg = 1; break;
|
||||
case oDebugUseOCB: opt_debug_use_ocb = 1; break;
|
||||
case oDebugUseOCB: /* dummy */; break;
|
||||
|
||||
default: pargs.err = ARGPARSE_PRINT_ERROR; break;
|
||||
}
|
||||
@ -810,9 +808,8 @@ agent_askpin (ctrl_t ctrl,
|
||||
int
|
||||
agent_write_private_key (const unsigned char *grip,
|
||||
const void *buffer, size_t length, int force,
|
||||
time_t timestamp,
|
||||
const char *serialno, const char *keyref,
|
||||
const char *dispserialno)
|
||||
const char *dispserialno, time_t timestamp)
|
||||
{
|
||||
char hexgrip[40+4+1];
|
||||
char *p;
|
||||
|
154
agent/protect.c
154
agent/protect.c
@ -366,12 +366,11 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
|
||||
const char *passphrase,
|
||||
const char *timestamp_exp, size_t timestamp_exp_len,
|
||||
unsigned char **result, size_t *resultlen,
|
||||
unsigned long s2k_count, int use_ocb)
|
||||
unsigned long s2k_count)
|
||||
{
|
||||
gcry_cipher_hd_t hd;
|
||||
const char *modestr;
|
||||
unsigned char hashvalue[20];
|
||||
int blklen, enclen, outlen;
|
||||
int enclen, outlen;
|
||||
unsigned char *iv = NULL;
|
||||
unsigned int ivsize; /* Size of the buffer allocated for IV. */
|
||||
const unsigned char *s2ksalt; /* Points into IV. */
|
||||
@ -385,44 +384,26 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
|
||||
*resultlen = 0;
|
||||
*result = NULL;
|
||||
|
||||
modestr = (use_ocb? "openpgp-s2k3-ocb-aes"
|
||||
/* */: "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc");
|
||||
modestr = "openpgp-s2k3-ocb-aes";
|
||||
|
||||
rc = gcry_cipher_open (&hd, PROT_CIPHER,
|
||||
use_ocb? GCRY_CIPHER_MODE_OCB :
|
||||
GCRY_CIPHER_MODE_CBC,
|
||||
GCRY_CIPHER_MODE_OCB,
|
||||
GCRY_CIPHER_SECURE);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* We need to work on a copy of the data because this makes it
|
||||
* easier to add the trailer and the padding and more important we
|
||||
* have to prefix the text with 2 parenthesis. In CBC mode we
|
||||
* have to allocate enough space for:
|
||||
*
|
||||
* ((<parameter_list>)(4:hash4:sha120:<hashvalue>)) + padding
|
||||
*
|
||||
* we always append a full block of random bytes as padding but
|
||||
* encrypt only what is needed for a full blocksize. In OCB mode we
|
||||
* have to prefix the text with 2 parenthesis. Due to OCB mode we
|
||||
* have to allocate enough space for just:
|
||||
*
|
||||
* ((<parameter_list>))
|
||||
*/
|
||||
blklen = gcry_cipher_get_algo_blklen (PROT_CIPHER);
|
||||
if (use_ocb)
|
||||
{
|
||||
/* (( )) */
|
||||
outlen = 2 + protlen + 2 ;
|
||||
enclen = outlen + 16 /* taglen */;
|
||||
outbuf = gcry_malloc_secure (enclen);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* (( )( 4:hash 4:sha1 20:<hash> )) <padding> */
|
||||
outlen = 2 + protlen + 2 + 6 + 6 + 23 + 2 + blklen;
|
||||
enclen = outlen/blklen * blklen;
|
||||
outbuf = gcry_malloc_secure (outlen);
|
||||
}
|
||||
|
||||
/* (( )) */
|
||||
outlen = 2 + protlen + 2 ;
|
||||
enclen = outlen + 16 /* taglen */;
|
||||
outbuf = gcry_malloc_secure (enclen);
|
||||
if (!outbuf)
|
||||
{
|
||||
rc = out_of_core ();
|
||||
@ -432,10 +413,10 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
|
||||
/* Allocate a buffer for the nonce and the salt. */
|
||||
if (!rc)
|
||||
{
|
||||
/* Allocate random bytes to be used as IV, padding and s2k salt
|
||||
* or in OCB mode for a nonce and the s2k salt. The IV/nonce is
|
||||
* set later because for OCB we need to set the key first. */
|
||||
ivsize = (use_ocb? 12 : (blklen*2)) + 8;
|
||||
/* Allocate random bytes to be used as nonce and s2k salt. The
|
||||
* nonce is set later because for OCB we need to set the key
|
||||
* first. */
|
||||
ivsize = 12 + 8;
|
||||
iv = xtrymalloc (ivsize);
|
||||
if (!iv)
|
||||
rc = gpg_error_from_syserror ();
|
||||
@ -471,40 +452,17 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
|
||||
goto leave;
|
||||
|
||||
/* Set the IV/nonce. */
|
||||
rc = gcry_cipher_setiv (hd, iv, use_ocb? 12 : blklen);
|
||||
rc = gcry_cipher_setiv (hd, iv, 12);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
if (use_ocb)
|
||||
{
|
||||
/* In OCB Mode we use only the public key parameters as AAD. */
|
||||
rc = gcry_cipher_authenticate (hd, hashbegin, protbegin - hashbegin);
|
||||
if (!rc)
|
||||
rc = gcry_cipher_authenticate (hd, timestamp_exp, timestamp_exp_len);
|
||||
if (!rc)
|
||||
rc = gcry_cipher_authenticate
|
||||
(hd, protbegin+protlen, hashlen - (protbegin+protlen - hashbegin));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Hash the entire expression for CBC mode. Because
|
||||
* TIMESTAMP_EXP won't get protected, we can't simply hash a
|
||||
* continuous buffer but need to call md_write several times. */
|
||||
gcry_md_hd_t md;
|
||||
|
||||
rc = gcry_md_open (&md, GCRY_MD_SHA1, 0 );
|
||||
if (!rc)
|
||||
{
|
||||
gcry_md_write (md, hashbegin, protbegin - hashbegin);
|
||||
gcry_md_write (md, protbegin, protlen);
|
||||
gcry_md_write (md, timestamp_exp, timestamp_exp_len);
|
||||
gcry_md_write (md, protbegin+protlen,
|
||||
hashlen - (protbegin+protlen - hashbegin));
|
||||
memcpy (hashvalue, gcry_md_read (md, GCRY_MD_SHA1), 20);
|
||||
gcry_md_close (md);
|
||||
}
|
||||
}
|
||||
|
||||
/* In OCB Mode we use only the public key parameters as AAD. */
|
||||
rc = gcry_cipher_authenticate (hd, hashbegin, protbegin - hashbegin);
|
||||
if (!rc)
|
||||
rc = gcry_cipher_authenticate (hd, timestamp_exp, timestamp_exp_len);
|
||||
if (!rc)
|
||||
rc = gcry_cipher_authenticate
|
||||
(hd, protbegin+protlen, hashlen - (protbegin+protlen - hashbegin));
|
||||
|
||||
/* Encrypt. */
|
||||
if (!rc)
|
||||
@ -514,36 +472,15 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
|
||||
*p++ = '(';
|
||||
memcpy (p, protbegin, protlen);
|
||||
p += protlen;
|
||||
if (use_ocb)
|
||||
*p++ = ')';
|
||||
*p++ = ')';
|
||||
log_assert ( p - outbuf == outlen);
|
||||
gcry_cipher_final (hd);
|
||||
rc = gcry_cipher_encrypt (hd, outbuf, outlen, NULL, 0);
|
||||
if (!rc)
|
||||
{
|
||||
*p++ = ')';
|
||||
*p++ = ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (p, ")(4:hash4:sha120:", 17);
|
||||
p += 17;
|
||||
memcpy (p, hashvalue, 20);
|
||||
p += 20;
|
||||
*p++ = ')';
|
||||
*p++ = ')';
|
||||
memcpy (p, iv+blklen, blklen); /* Add padding. */
|
||||
p += blklen;
|
||||
}
|
||||
assert ( p - outbuf == outlen);
|
||||
if (use_ocb)
|
||||
{
|
||||
gcry_cipher_final (hd);
|
||||
rc = gcry_cipher_encrypt (hd, outbuf, outlen, NULL, 0);
|
||||
if (!rc)
|
||||
{
|
||||
log_assert (outlen + 16 == enclen);
|
||||
rc = gcry_cipher_gettag (hd, outbuf + outlen, 16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = gcry_cipher_encrypt (hd, outbuf, enclen, NULL, 0);
|
||||
log_assert (outlen + 16 == enclen);
|
||||
rc = gcry_cipher_gettag (hd, outbuf + outlen, 16);
|
||||
}
|
||||
}
|
||||
|
||||
@ -554,24 +491,24 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
|
||||
gcry_cipher_close (hd);
|
||||
|
||||
/* Now allocate the buffer we want to return. This is
|
||||
|
||||
(protected openpgp-s2k3-sha1-aes-cbc
|
||||
((sha1 salt no_of_iterations) 16byte_iv)
|
||||
encrypted_octet_string)
|
||||
|
||||
in canoncical format of course. We use asprintf and %n modifier
|
||||
and dummy values as placeholders. */
|
||||
*
|
||||
* (protected openpgp-s2k3-ocb-aes
|
||||
* ((sha1 salt no_of_iterations) 12byte_nonce)
|
||||
* encrypted_octet_string)
|
||||
*
|
||||
* in canoncical format of course. We use asprintf and %n modifier
|
||||
* and dummy values as placeholders. */
|
||||
{
|
||||
char countbuf[35];
|
||||
|
||||
snprintf (countbuf, sizeof countbuf, "%lu",
|
||||
s2k_count ? s2k_count : get_standard_s2k_count ());
|
||||
s2k_count ? s2k_count : get_standard_s2k_count ());
|
||||
p = xtryasprintf
|
||||
("(9:protected%d:%s((4:sha18:%n_8bytes_%u:%s)%d:%n%*s)%d:%n%*s)",
|
||||
(int)strlen (modestr), modestr,
|
||||
&saltpos,
|
||||
(unsigned int)strlen (countbuf), countbuf,
|
||||
use_ocb? 12 : blklen, &ivpos, use_ocb? 12 : blklen, "",
|
||||
12, &ivpos, 12, "",
|
||||
enclen, &encpos, enclen, "");
|
||||
if (!p)
|
||||
{
|
||||
@ -585,7 +522,7 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
|
||||
*resultlen = strlen (p);
|
||||
*result = (unsigned char*)p;
|
||||
memcpy (p+saltpos, s2ksalt, 8);
|
||||
memcpy (p+ivpos, iv, use_ocb? 12 : blklen);
|
||||
memcpy (p+ivpos, iv, 12);
|
||||
memcpy (p+encpos, outbuf, enclen);
|
||||
xfree (iv);
|
||||
xfree (outbuf);
|
||||
@ -601,13 +538,11 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
|
||||
|
||||
|
||||
/* Protect the key encoded in canonical format in PLAINKEY. We assume
|
||||
a valid S-Exp here. With USE_UCB set to -1 the default scheme is
|
||||
used (ie. either CBC or OCB), set to 0 the old CBC mode is used,
|
||||
and set to 1 OCB is used. */
|
||||
* a valid S-Exp here. */
|
||||
int
|
||||
agent_protect (const unsigned char *plainkey, const char *passphrase,
|
||||
unsigned char **result, size_t *resultlen,
|
||||
unsigned long s2k_count, int use_ocb)
|
||||
unsigned long s2k_count)
|
||||
{
|
||||
int rc;
|
||||
const char *parmlist;
|
||||
@ -624,9 +559,6 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
|
||||
unsigned char *p;
|
||||
int have_curve = 0;
|
||||
|
||||
if (use_ocb == -1)
|
||||
use_ocb = !!opt.enable_extended_key_format;
|
||||
|
||||
/* Create an S-expression with the protected-at timestamp. */
|
||||
memcpy (timestamp_exp, "(12:protected-at15:", 19);
|
||||
gnupg_get_isotime (timestamp_exp+19);
|
||||
@ -730,7 +662,7 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
|
||||
rc = do_encryption (hash_begin, hash_end - hash_begin + 1,
|
||||
prot_begin, prot_end - prot_begin + 1,
|
||||
passphrase, timestamp_exp, sizeof (timestamp_exp),
|
||||
&protected, &protectedlen, s2k_count, use_ocb);
|
||||
&protected, &protectedlen, s2k_count);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
@ -196,7 +196,7 @@ test_agent_protect (void)
|
||||
{
|
||||
ret = agent_protect ((const unsigned char*)specs[i].key,
|
||||
specs[i].passphrase,
|
||||
&specs[i].result, &specs[i].resultlen, 0, -1);
|
||||
&specs[i].result, &specs[i].resultlen, 0);
|
||||
if (gpg_err_code (ret) != specs[i].ret_expected)
|
||||
{
|
||||
printf ("agent_protect(%d) returned '%i/%s'; expected '%i/%s'\n",
|
||||
|
@ -632,16 +632,10 @@ remote machine.
|
||||
@itemx --disable-extended-key-format
|
||||
@opindex enable-extended-key-format
|
||||
@opindex disable-extended-key-format
|
||||
Since version 2.2.22 keys are created in the extended private key
|
||||
format by default. Changing the passphrase of a key will also convert
|
||||
the key to that new format. This key format is supported since GnuPG
|
||||
version 2.1.12 and thus there should be no need to disable it.
|
||||
Anyway, the disable option still allows to revert to the old behavior
|
||||
for new keys; be aware that keys are never migrated back to the old
|
||||
format. If the enable option has been used the disable option won't
|
||||
have an effect. The advantage of the extended private key format is
|
||||
that it is text based and can carry additional meta data. In extended
|
||||
key format the OCB mode is used for key protection.
|
||||
These options are obsolete and have no effect. The extended key format
|
||||
is used for years now and has been supported since 2.1.12. Existing
|
||||
keys in the old format are migrated to the new format as soon as they
|
||||
are touched.
|
||||
|
||||
@anchor{option --enable-ssh-support}
|
||||
@item --enable-ssh-support
|
||||
|
Loading…
x
Reference in New Issue
Block a user