mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-30 16:17:02 +01:00
Various changes to eventually support openpgp keys in pgp-agent.
Comment fixes. Minor chnages in preparation of a W32CE port.
This commit is contained in:
parent
7e97da9127
commit
8459bcf95a
@ -888,6 +888,13 @@ Signs a public key with your secret key but marks it as
|
||||
non-exportable. This is a shortcut version of the subcommand "lsign"
|
||||
from @option{--edit-key}.
|
||||
|
||||
@ifclear gpgone
|
||||
@item --passwd @var{user_id}
|
||||
@opindex passwd
|
||||
Change the passphrase of the secret key belonging to the certificate
|
||||
specified as @var{user_id}. This is a shortcut for the sub-command
|
||||
@code{passwd} of the edit key menu.
|
||||
@end ifclear
|
||||
|
||||
@end table
|
||||
|
||||
|
@ -1,3 +1,53 @@
|
||||
2010-02-02 Werner Koch <wk@g10code.com>
|
||||
|
||||
* keyedit.c (keyedit_menu): Change prompt to "gpg".
|
||||
* card-util.c (card_edit): Change prompt to "gpg/card".
|
||||
|
||||
2010-01-11 Werner Koch <wk@g10code.com>
|
||||
|
||||
* sign.c (only_old_style, write_onepass_sig_packets, hash_for)
|
||||
(write_signature_packets, print_status_sig_created)
|
||||
(clearsign_file, make_keysig_packet, mk_notation_policy_etc)
|
||||
(complete_sig, do_sign, update_keysig_packet): Replace all
|
||||
secret key access by the matching public key.
|
||||
* keylist.c (print_seckey_info): Ditto.
|
||||
* revoke.c (gen_desig_revoke): Ditto.
|
||||
* skclist.c (release_sk_list): Ditto.
|
||||
* keyedit.c (sign_uids): Ditto.
|
||||
* misc.c (get_signature_count): Ditto.
|
||||
* main.h (struct expand_args): s/sk/pksk/. Change all users.
|
||||
|
||||
* keyedit.c (keyedit_passwd): Finish implementation.
|
||||
|
||||
2010-01-10 Werner Koch <wk@g10code.com>
|
||||
|
||||
* skclist.c (GCRYCTL_FAKED_RANDOM_P): Remove because we require
|
||||
libgcrypt 1.4.
|
||||
(is_insecure, key_present_in_sk_list): Work with public keys.
|
||||
(build_sk_list): Change to work on public keys.
|
||||
* keydb.h (struct sk_list): Replace field SK by a PK field.
|
||||
|
||||
* keylist.c (list_keyblock_print): Always look for the public key
|
||||
and ignore all secret key packets.
|
||||
(list_keyblock_colon): Ditto.
|
||||
(print_capabilities): Remove arg SK and all secret key stuff.
|
||||
Adjust all callers.
|
||||
(dump_attribs): Ditto.
|
||||
|
||||
* getkey.c (getkey_bynames, getkey_next, get_pubkey_end): New.
|
||||
(getkey_byname): New.
|
||||
(getkey_ctx_s): Add WANT_SECRET.
|
||||
(key_byname): Set it.
|
||||
(merge_keys_and_selfsig): Remove all the secret key merging.
|
||||
(lookup): Simplify by removing secret key code.
|
||||
|
||||
* keylist.c (list_all): Scan public keys and use have_secret_key
|
||||
to filter secret keys.
|
||||
(list_one): Use the new get_key functions.
|
||||
|
||||
* gpg.h (kbnode_t): Add as alias for KBNODE.
|
||||
* keydb.h (getkey_ctx_t): Add as alias for GETKEY_CTX.
|
||||
|
||||
2010-01-09 Werner Koch <wk@g10code.com>
|
||||
|
||||
* getkey.c, keylist.c: Re-indent.
|
||||
|
@ -1817,7 +1817,7 @@ card_edit (strlist_t commands)
|
||||
if (!have_commands)
|
||||
{
|
||||
tty_enable_completion (card_edit_completion);
|
||||
answer = cpr_get_no_help("cardedit.prompt", _("Command> "));
|
||||
answer = cpr_get_no_help("cardedit.prompt", _("gpg/card> "));
|
||||
cpr_kill_prompt();
|
||||
tty_disable_completion ();
|
||||
}
|
||||
|
@ -471,6 +471,7 @@ cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b )
|
||||
{
|
||||
int n, i;
|
||||
|
||||
log_debug ("FIXME: %s Should not be used\n", __func__);
|
||||
if( a->timestamp != b->timestamp )
|
||||
return -1;
|
||||
if( a->version < 4 && a->expiredate != b->expiredate )
|
||||
|
607
g10/getkey.c
607
g10/getkey.c
@ -46,6 +46,7 @@
|
||||
struct getkey_ctx_s
|
||||
{
|
||||
int exact;
|
||||
int want_secret; /* The caller requested only secret keys. */
|
||||
KBNODE keyblock;
|
||||
KBPOS kbpos;
|
||||
KBNODE found_key; /* Pointer into some keyblock. */
|
||||
@ -101,8 +102,8 @@ typedef struct user_id_db
|
||||
static user_id_db_t user_id_db;
|
||||
static int uid_cache_entries; /* Number of entries in uid cache. */
|
||||
|
||||
static void merge_selfsigs (KBNODE keyblock);
|
||||
static int lookup (GETKEY_CTX ctx, KBNODE * ret_keyblock, int secmode);
|
||||
static void merge_selfsigs (kbnode_t keyblock);
|
||||
static int lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret);
|
||||
|
||||
#if 0
|
||||
static void
|
||||
@ -599,7 +600,7 @@ leave:
|
||||
|
||||
|
||||
/* Try to get the pubkey by the userid. This function looks for the
|
||||
* first pubkey certificate which has the given name in a user_id. if
|
||||
* first pubkey certificate which has the given name in a user_id. If
|
||||
* pk/sk has the pubkey algo set, the function will only return a
|
||||
* pubkey with that algo. If namelist is NULL, the first key is
|
||||
* returned. The caller should provide storage for either the pk or
|
||||
@ -608,7 +609,7 @@ leave:
|
||||
static int
|
||||
key_byname (GETKEY_CTX * retctx, strlist_t namelist,
|
||||
PKT_public_key * pk, PKT_secret_key * sk,
|
||||
int secmode, int include_unusable,
|
||||
int want_secret, int include_unusable,
|
||||
KBNODE * ret_kb, KEYDB_HANDLE * ret_kdbhd)
|
||||
{
|
||||
int rc = 0;
|
||||
@ -617,6 +618,8 @@ key_byname (GETKEY_CTX * retctx, strlist_t namelist,
|
||||
GETKEY_CTX ctx;
|
||||
KBNODE help_kb = NULL;
|
||||
|
||||
/* FIXME: Eventually remove the SK argument. */
|
||||
|
||||
if (retctx)
|
||||
{
|
||||
/* Reset the returned context in case of error. */
|
||||
@ -667,35 +670,25 @@ key_byname (GETKEY_CTX * retctx, strlist_t namelist,
|
||||
}
|
||||
}
|
||||
|
||||
ctx->kr_handle = keydb_new (secmode);
|
||||
ctx->want_secret = want_secret;
|
||||
ctx->kr_handle = keydb_new (0);
|
||||
if (!ret_kb)
|
||||
ret_kb = &help_kb;
|
||||
|
||||
if (secmode)
|
||||
if (pk)
|
||||
{
|
||||
if (sk)
|
||||
{
|
||||
ctx->req_algo = sk->req_algo;
|
||||
ctx->req_usage = sk->req_usage;
|
||||
}
|
||||
rc = lookup (ctx, ret_kb, 1);
|
||||
if (!rc && sk)
|
||||
{
|
||||
sk_from_block (ctx, sk, *ret_kb);
|
||||
}
|
||||
ctx->req_algo = pk->req_algo;
|
||||
ctx->req_usage = pk->req_usage;
|
||||
}
|
||||
else
|
||||
else if (sk) /* FIXME: We should remove this. */
|
||||
{
|
||||
if (pk)
|
||||
{
|
||||
ctx->req_algo = pk->req_algo;
|
||||
ctx->req_usage = pk->req_usage;
|
||||
}
|
||||
rc = lookup (ctx, ret_kb, 0);
|
||||
if (!rc && pk)
|
||||
{
|
||||
pk_from_block (ctx, pk, *ret_kb);
|
||||
}
|
||||
ctx->req_algo = sk->req_algo;
|
||||
ctx->req_usage = sk->req_usage;
|
||||
}
|
||||
rc = lookup (ctx, ret_kb, want_secret);
|
||||
if (!rc && pk)
|
||||
{
|
||||
pk_from_block (ctx, pk, *ret_kb);
|
||||
}
|
||||
|
||||
release_kbnode (help_kb);
|
||||
@ -1219,115 +1212,102 @@ get_seckeyblock_byfprint (KBNODE * ret_keyblock, const byte * fprint,
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The new function to return a key.
|
||||
FIXME: Document it. */
|
||||
gpg_error_t
|
||||
getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||
strlist_t names, int want_secret, kbnode_t *ret_keyblock)
|
||||
{
|
||||
return key_byname (retctx, names, pk, NULL, want_secret, 1,
|
||||
ret_keyblock, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Get a key by name and store it into PK. If RETCTX is not NULL
|
||||
* return the search context which needs to be released by the caller
|
||||
* using getkey_end. If NAME is NULL use the default key (see below).
|
||||
* On success and if RET_KEYBLOCK is not NULL the found keyblock is
|
||||
* stored at this address. WANT_SECRET passed as true requires that a
|
||||
* secret key is available for the selected key.
|
||||
*
|
||||
* If WANT_SECRET is true and NAME is NULL and a default key has been
|
||||
* defined that defined key is used. In all other cases the first
|
||||
* available key is used.
|
||||
*
|
||||
* FIXME: Explain what is up with unusable keys.
|
||||
*
|
||||
* FIXME: We also have the get_pubkey_byname fucntion which has a
|
||||
* different semantic. Should be merged with this one.
|
||||
*/
|
||||
gpg_error_t
|
||||
getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||
const char *name, int want_secret, kbnode_t *ret_keyblock)
|
||||
{
|
||||
gpg_error_t err;
|
||||
strlist_t namelist = NULL;
|
||||
int with_unusable = 1;
|
||||
|
||||
if (want_secret && !name && opt.def_secret_key && *opt.def_secret_key)
|
||||
add_to_strlist (&namelist, opt.def_secret_key);
|
||||
else if (name)
|
||||
add_to_strlist (&namelist, name);
|
||||
else
|
||||
with_unusable = 0;
|
||||
|
||||
err = key_byname (retctx, namelist, pk, NULL, want_secret, with_unusable,
|
||||
ret_keyblock, NULL);
|
||||
|
||||
/* FIXME: Check that we really return GPG_ERR_NO_SECKEY if
|
||||
WANT_SECRET has been used. */
|
||||
|
||||
free_strlist (namelist);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* The new function to return the next key. */
|
||||
gpg_error_t
|
||||
getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, kbnode_t *ret_keyblock)
|
||||
{
|
||||
int rc; /* Fixme: Make sure this is proper gpg_error */
|
||||
|
||||
rc = lookup (ctx, ret_keyblock, ctx->want_secret);
|
||||
if (!rc && pk && ret_keyblock)
|
||||
pk_from_block (ctx, pk, *ret_keyblock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* The new function to finish a key listing. */
|
||||
void
|
||||
getkey_end (getkey_ctx_t ctx)
|
||||
{
|
||||
get_pubkey_end (ctx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************
|
||||
************* Merging stuff ********************
|
||||
************************************************/
|
||||
|
||||
/* Merge all self-signatures with the keys.
|
||||
|
||||
* FIXME: replace this at least for the public key parts
|
||||
* by merge_selfsigs.
|
||||
* It is still used in keyedit.c and
|
||||
* at 2 or 3 other places - check whether it is really needed.
|
||||
* It might be needed by the key edit and import stuff because
|
||||
* the keylock is changed. */
|
||||
/* Merge all self-signatures with the keys. */
|
||||
void
|
||||
merge_keys_and_selfsig (KBNODE keyblock)
|
||||
{
|
||||
PKT_public_key *pk = NULL;
|
||||
PKT_secret_key *sk = NULL;
|
||||
PKT_signature *sig;
|
||||
KBNODE k;
|
||||
u32 kid[2] = { 0, 0 };
|
||||
u32 sigdate = 0;
|
||||
|
||||
if (keyblock && keyblock->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||
{
|
||||
/* Divert to our new function. */
|
||||
merge_selfsigs (keyblock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Still need the old one because the new one can't handle secret keys. */
|
||||
|
||||
for (k = keyblock; k; k = k->next)
|
||||
{
|
||||
if (k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
{
|
||||
pk = k->pkt->pkt.public_key;
|
||||
sk = NULL;
|
||||
if (pk->version < 4)
|
||||
pk = NULL; /* Not needed for old keys. */
|
||||
else if (k->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||
keyid_from_pk (pk, kid);
|
||||
else if (!pk->expiredate)
|
||||
{
|
||||
/* and subkey */
|
||||
/* insert the expiration date here */
|
||||
/*FIXME!!! pk->expiredate = subkeys_expiretime( k, kid ); */
|
||||
}
|
||||
sigdate = 0;
|
||||
}
|
||||
else if (k->pkt->pkttype == PKT_SECRET_KEY
|
||||
|| k->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
{
|
||||
pk = NULL;
|
||||
sk = k->pkt->pkt.secret_key;
|
||||
if (sk->version < 4)
|
||||
sk = NULL;
|
||||
else if (k->pkt->pkttype == PKT_SECRET_KEY)
|
||||
keyid_from_sk (sk, kid);
|
||||
sigdate = 0;
|
||||
}
|
||||
else if ((pk || sk) && k->pkt->pkttype == PKT_SIGNATURE
|
||||
&& (sig = k->pkt->pkt.signature)->sig_class >= 0x10
|
||||
&& sig->sig_class <= 0x30 && sig->version > 3
|
||||
&& !(sig->sig_class == 0x18 || sig->sig_class == 0x28)
|
||||
&& sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1])
|
||||
{
|
||||
/* okay this is a self-signature which can be used.
|
||||
* This is not used for subkey binding signature, becuase this
|
||||
* is done above.
|
||||
* FIXME: We should only use this if the signature is valid
|
||||
* but this is time consuming - we must provide another
|
||||
* way to handle this
|
||||
*/
|
||||
const byte *p;
|
||||
u32 ed;
|
||||
|
||||
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
|
||||
if (pk)
|
||||
{
|
||||
ed = p ? pk->timestamp + buffer_to_u32 (p) : 0;
|
||||
if (sig->timestamp > sigdate)
|
||||
{
|
||||
pk->expiredate = ed;
|
||||
sigdate = sig->timestamp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ed = p ? sk->timestamp + buffer_to_u32 (p) : 0;
|
||||
if (sig->timestamp > sigdate)
|
||||
{
|
||||
sk->expiredate = ed;
|
||||
sigdate = sig->timestamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pk && (pk->expiredate == 0 ||
|
||||
(pk->max_expiredate && pk->expiredate > pk->max_expiredate)))
|
||||
pk->expiredate = pk->max_expiredate;
|
||||
|
||||
if (sk && (sk->expiredate == 0 ||
|
||||
(sk->max_expiredate && sk->expiredate > sk->max_expiredate)))
|
||||
sk->expiredate = sk->max_expiredate;
|
||||
}
|
||||
if (!keyblock)
|
||||
;
|
||||
else if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||
merge_selfsigs (keyblock);
|
||||
else
|
||||
log_debug ("FIXME: merging secret key blocks is not anymore available\n");
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
parse_key_usage (PKT_signature * sig)
|
||||
{
|
||||
@ -2309,146 +2289,10 @@ merge_selfsigs (KBNODE keyblock)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Merge the secret keys from secblock into the pubblock thereby
|
||||
* replacing the public (sub)keys with their secret counterparts Hmmm:
|
||||
* It might be better to get away from the concept of entire secret
|
||||
* keys at all and have a way to store just the real secret parts
|
||||
* from the key.
|
||||
*/
|
||||
static void
|
||||
merge_public_with_secret (KBNODE pubblock, KBNODE secblock)
|
||||
{
|
||||
KBNODE pub;
|
||||
|
||||
assert (pubblock->pkt->pkttype == PKT_PUBLIC_KEY);
|
||||
assert (secblock->pkt->pkttype == PKT_SECRET_KEY);
|
||||
|
||||
for (pub = pubblock; pub; pub = pub->next)
|
||||
{
|
||||
if (pub->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||
{
|
||||
PKT_public_key *pk = pub->pkt->pkt.public_key;
|
||||
PKT_secret_key *sk = secblock->pkt->pkt.secret_key;
|
||||
assert (pub == pubblock); /* Only in the first node. */
|
||||
/* There is nothing to compare in this case, so just replace
|
||||
* some information. */
|
||||
copy_public_parts_to_secret_key (pk, sk);
|
||||
free_public_key (pk);
|
||||
pub->pkt->pkttype = PKT_SECRET_KEY;
|
||||
pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk);
|
||||
}
|
||||
else if (pub->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
{
|
||||
KBNODE sec;
|
||||
PKT_public_key *pk = pub->pkt->pkt.public_key;
|
||||
|
||||
/* This is more complicated: It may happen that the sequence
|
||||
* of the subkeys dosn't match, so we have to find the
|
||||
* appropriate secret key. */
|
||||
for (sec = secblock->next; sec; sec = sec->next)
|
||||
{
|
||||
if (sec->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
{
|
||||
PKT_secret_key *sk = sec->pkt->pkt.secret_key;
|
||||
if (!cmp_public_secret_key (pk, sk))
|
||||
{
|
||||
copy_public_parts_to_secret_key (pk, sk);
|
||||
free_public_key (pk);
|
||||
pub->pkt->pkttype = PKT_SECRET_SUBKEY;
|
||||
pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!sec)
|
||||
BUG (); /* Already checked in premerge. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This function checks that for every public subkey a corresponding
|
||||
* secret subkey is available and deletes the public subkey otherwise.
|
||||
* We need this function because we can't delete it later when we
|
||||
* actually merge the secret parts into the pubring.
|
||||
* The function also plays some games with the node flags. */
|
||||
static void
|
||||
premerge_public_with_secret (KBNODE pubblock, KBNODE secblock)
|
||||
{
|
||||
KBNODE last, pub;
|
||||
|
||||
assert (pubblock->pkt->pkttype == PKT_PUBLIC_KEY);
|
||||
assert (secblock->pkt->pkttype == PKT_SECRET_KEY);
|
||||
|
||||
for (pub = pubblock, last = NULL; pub; last = pub, pub = pub->next)
|
||||
{
|
||||
pub->flag &= ~3; /* Reset bits 0 and 1. */
|
||||
if (pub->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
{
|
||||
KBNODE sec;
|
||||
PKT_public_key *pk = pub->pkt->pkt.public_key;
|
||||
|
||||
for (sec = secblock->next; sec; sec = sec->next)
|
||||
{
|
||||
if (sec->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
{
|
||||
PKT_secret_key *sk = sec->pkt->pkt.secret_key;
|
||||
if (!cmp_public_secret_key (pk, sk))
|
||||
{
|
||||
if (sk->protect.s2k.mode == 1001)
|
||||
{
|
||||
/* The secret parts are not available so
|
||||
we can't use that key for signing etc.
|
||||
Fix the pubkey usage */
|
||||
pk->pubkey_usage &= ~(PUBKEY_USAGE_SIG
|
||||
| PUBKEY_USAGE_AUTH);
|
||||
}
|
||||
/* Transfer flag bits 0 and 1 to the pubblock. */
|
||||
pub->flag |= (sec->flag & 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!sec)
|
||||
{
|
||||
KBNODE next, ll;
|
||||
|
||||
if (opt.verbose)
|
||||
log_info (_("no secret subkey"
|
||||
" for public subkey %s - ignoring\n"),
|
||||
keystr_from_pk (pk));
|
||||
/* We have to remove the subkey in this case. */
|
||||
assert (last);
|
||||
/* Find the next subkey. */
|
||||
for (next = pub->next, ll = pub;
|
||||
next && next->pkt->pkttype != PKT_PUBLIC_SUBKEY;
|
||||
ll = next, next = next->next)
|
||||
;
|
||||
/* Make new link. */
|
||||
last->next = next;
|
||||
/* Release this public subkey with all sigs. */
|
||||
ll->next = NULL;
|
||||
release_kbnode (pub);
|
||||
/* Let the loop continue. */
|
||||
pub = last;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* We need to copy the found bits (0 and 1) from the secret key to
|
||||
the public key. This has already been done for the subkeys but
|
||||
got lost on the primary key - fix it here. */
|
||||
pubblock->flag |= (secblock->flag & 3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* See see whether the key fits our requirements and in case we do not
|
||||
* request the primary key, we should select a suitable subkey.
|
||||
/* See whether the key fits our requirements and in case we do not
|
||||
* request the primary key, select a suitable subkey.
|
||||
*
|
||||
* FIXME: Check against PGP 7 whether we still need a kludge
|
||||
* to favor type 16 keys over type 20 keys when type 20
|
||||
* has not been explitely requested.
|
||||
* Returns: True when a suitable key has been found.
|
||||
*
|
||||
* We have to distinguish four cases: FIXME!
|
||||
@ -2533,7 +2377,7 @@ finish_lookup (GETKEY_CTX ctx)
|
||||
if ((!foundk || foundk->pkt->pkttype == PKT_PUBLIC_SUBKEY) && !req_prim)
|
||||
{
|
||||
KBNODE nextk;
|
||||
/* ceither start a loop or check just this one subkey. */
|
||||
/* Either start a loop or check just this one subkey. */
|
||||
for (k = foundk ? foundk : keyblock; k; k = nextk)
|
||||
{
|
||||
PKT_public_key *pk;
|
||||
@ -2635,7 +2479,7 @@ finish_lookup (GETKEY_CTX ctx)
|
||||
{
|
||||
if (DBG_CACHE)
|
||||
log_debug ("\tno suitable key found - giving up\n");
|
||||
return 0;
|
||||
return 0; /* Not found. */
|
||||
}
|
||||
|
||||
found:
|
||||
@ -2668,11 +2512,13 @@ found:
|
||||
}
|
||||
|
||||
|
||||
/* The main function to lookup a key. On success the found keyblock
|
||||
is stored at RET_KEYBLOCK and also in CTX. If WANT_SECRET is true
|
||||
a corresponding secret key is required. */
|
||||
static int
|
||||
lookup (GETKEY_CTX ctx, KBNODE * ret_keyblock, int secmode)
|
||||
lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret)
|
||||
{
|
||||
int rc;
|
||||
KBNODE secblock = NULL; /* Helper. */
|
||||
int no_suitable_key = 0;
|
||||
|
||||
rc = 0;
|
||||
@ -2692,30 +2538,8 @@ lookup (GETKEY_CTX ctx, KBNODE * ret_keyblock, int secmode)
|
||||
goto skip;
|
||||
}
|
||||
|
||||
if (secmode)
|
||||
{
|
||||
/* Find the correspondig public key and use this
|
||||
* this one for the selection process. */
|
||||
u32 aki[2];
|
||||
KBNODE k = ctx->keyblock;
|
||||
|
||||
if (k->pkt->pkttype != PKT_SECRET_KEY)
|
||||
BUG ();
|
||||
|
||||
keyid_from_sk (k->pkt->pkt.secret_key, aki);
|
||||
k = get_pubkeyblock (aki);
|
||||
if (!k)
|
||||
{
|
||||
if (!opt.quiet)
|
||||
log_info (_("key %s: secret key without public key"
|
||||
" - skipped\n"), keystr (aki));
|
||||
goto skip;
|
||||
}
|
||||
secblock = ctx->keyblock;
|
||||
ctx->keyblock = k;
|
||||
|
||||
premerge_public_with_secret (ctx->keyblock, secblock);
|
||||
}
|
||||
if (want_secret && have_secret_key (ctx->keyblock))
|
||||
goto skip; /* No secret key available. */
|
||||
|
||||
/* Warning: node flag bits 0 and 1 should be preserved by
|
||||
* merge_selfsigs. For secret keys, premerge did tranfer the
|
||||
@ -2724,12 +2548,6 @@ lookup (GETKEY_CTX ctx, KBNODE * ret_keyblock, int secmode)
|
||||
if (finish_lookup (ctx))
|
||||
{
|
||||
no_suitable_key = 0;
|
||||
if (secmode)
|
||||
{
|
||||
merge_public_with_secret (ctx->keyblock, secblock);
|
||||
release_kbnode (secblock);
|
||||
secblock = NULL;
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
else
|
||||
@ -2737,15 +2555,10 @@ lookup (GETKEY_CTX ctx, KBNODE * ret_keyblock, int secmode)
|
||||
|
||||
skip:
|
||||
/* Release resources and continue search. */
|
||||
if (secmode)
|
||||
{
|
||||
release_kbnode (secblock);
|
||||
secblock = NULL;
|
||||
}
|
||||
release_kbnode (ctx->keyblock);
|
||||
ctx->keyblock = NULL;
|
||||
}
|
||||
|
||||
|
||||
found:
|
||||
if (rc && rc != -1)
|
||||
log_error ("keydb_search failed: %s\n", g10_errstr (rc));
|
||||
@ -2756,15 +2569,10 @@ found:
|
||||
ctx->keyblock = NULL;
|
||||
}
|
||||
else if (rc == -1 && no_suitable_key)
|
||||
rc = secmode ? G10ERR_UNU_SECKEY : G10ERR_UNU_PUBKEY;
|
||||
rc = want_secret? G10ERR_UNU_SECKEY : G10ERR_UNU_PUBKEY;
|
||||
else if (rc == -1)
|
||||
rc = secmode ? G10ERR_NO_SECKEY : G10ERR_NO_PUBKEY;
|
||||
rc = want_secret? G10ERR_NO_SECKEY : G10ERR_NO_PUBKEY;
|
||||
|
||||
if (secmode)
|
||||
{
|
||||
release_kbnode (secblock);
|
||||
secblock = NULL;
|
||||
}
|
||||
release_kbnode (ctx->keyblock);
|
||||
ctx->keyblock = NULL;
|
||||
|
||||
@ -3083,3 +2891,180 @@ parse_auto_key_locate (char *options)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Return 0 if a secret key is available for the key described by
|
||||
KEYBLOCK. FIXME: How do we handel subkeys? */
|
||||
gpg_error_t
|
||||
have_secret_key (kbnode_t keyblock)
|
||||
{
|
||||
gpg_error_t err;
|
||||
unsigned char fpr[MAX_FINGERPRINT_LEN];
|
||||
size_t fprlen;
|
||||
KEYDB_HANDLE kdh;
|
||||
|
||||
if (!keyblock || keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
|
||||
return gpg_error (GPG_ERR_NO_PUBKEY); /* Should not happen. */
|
||||
|
||||
fingerprint_from_pk (keyblock->pkt->pkt.public_key, fpr, &fprlen);
|
||||
while (fprlen < MAX_FINGERPRINT_LEN)
|
||||
fpr[fprlen++] = 0;
|
||||
|
||||
/* FIXME: Always allocating a new handle is too slow. However this
|
||||
entire implementation is anyway a temporary solution until we can
|
||||
ask gpg-agent for the secret key. */
|
||||
kdh = keydb_new (1);
|
||||
if (!kdh)
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
|
||||
err = keydb_search_fpr (kdh, fpr);
|
||||
if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF)
|
||||
err = gpg_error (GPG_ERR_NO_SECKEY);
|
||||
|
||||
keydb_release (kdh);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Merge the secret keys from secblock into the pubblock thereby
|
||||
* replacing the public (sub)keys with their secret counterparts Hmmm:
|
||||
* It might be better to get away from the concept of entire secret
|
||||
* keys at all and have a way to store just the real secret parts
|
||||
* from the key.
|
||||
*
|
||||
* FIXME: this is not anymore needed but we keep it as example code for the
|
||||
* new code we need to write for the import/export feature.
|
||||
*/
|
||||
static void
|
||||
merge_public_with_secret (KBNODE pubblock, KBNODE secblock)
|
||||
{
|
||||
KBNODE pub;
|
||||
|
||||
assert (pubblock->pkt->pkttype == PKT_PUBLIC_KEY);
|
||||
assert (secblock->pkt->pkttype == PKT_SECRET_KEY);
|
||||
|
||||
for (pub = pubblock; pub; pub = pub->next)
|
||||
{
|
||||
if (pub->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||
{
|
||||
PKT_public_key *pk = pub->pkt->pkt.public_key;
|
||||
PKT_secret_key *sk = secblock->pkt->pkt.secret_key;
|
||||
assert (pub == pubblock); /* Only in the first node. */
|
||||
/* There is nothing to compare in this case, so just replace
|
||||
* some information. */
|
||||
copy_public_parts_to_secret_key (pk, sk);
|
||||
free_public_key (pk);
|
||||
pub->pkt->pkttype = PKT_SECRET_KEY;
|
||||
pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk);
|
||||
}
|
||||
else if (pub->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
{
|
||||
KBNODE sec;
|
||||
PKT_public_key *pk = pub->pkt->pkt.public_key;
|
||||
|
||||
/* This is more complicated: It may happen that the sequence
|
||||
* of the subkeys dosn't match, so we have to find the
|
||||
* appropriate secret key. */
|
||||
for (sec = secblock->next; sec; sec = sec->next)
|
||||
{
|
||||
if (sec->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
{
|
||||
PKT_secret_key *sk = sec->pkt->pkt.secret_key;
|
||||
if (!cmp_public_secret_key (pk, sk))
|
||||
{
|
||||
copy_public_parts_to_secret_key (pk, sk);
|
||||
free_public_key (pk);
|
||||
pub->pkt->pkttype = PKT_SECRET_SUBKEY;
|
||||
pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!sec)
|
||||
BUG (); /* Already checked in premerge. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This function checks that for every public subkey a corresponding
|
||||
* secret subkey is available and deletes the public subkey otherwise.
|
||||
* We need this function because we can't delete it later when we
|
||||
* actually merge the secret parts into the pubring.
|
||||
* The function also plays some games with the node flags.
|
||||
*
|
||||
* FIXME: this is not anymore needed but we keep it as example code for the
|
||||
* new code we need to write for the import/export feature.
|
||||
*/
|
||||
static void
|
||||
premerge_public_with_secret (KBNODE pubblock, KBNODE secblock)
|
||||
{
|
||||
KBNODE last, pub;
|
||||
|
||||
assert (pubblock->pkt->pkttype == PKT_PUBLIC_KEY);
|
||||
assert (secblock->pkt->pkttype == PKT_SECRET_KEY);
|
||||
|
||||
for (pub = pubblock, last = NULL; pub; last = pub, pub = pub->next)
|
||||
{
|
||||
pub->flag &= ~3; /* Reset bits 0 and 1. */
|
||||
if (pub->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
{
|
||||
KBNODE sec;
|
||||
PKT_public_key *pk = pub->pkt->pkt.public_key;
|
||||
|
||||
for (sec = secblock->next; sec; sec = sec->next)
|
||||
{
|
||||
if (sec->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
{
|
||||
PKT_secret_key *sk = sec->pkt->pkt.secret_key;
|
||||
if (!cmp_public_secret_key (pk, sk))
|
||||
{
|
||||
if (sk->protect.s2k.mode == 1001)
|
||||
{
|
||||
/* The secret parts are not available so
|
||||
we can't use that key for signing etc.
|
||||
Fix the pubkey usage */
|
||||
pk->pubkey_usage &= ~(PUBKEY_USAGE_SIG
|
||||
| PUBKEY_USAGE_AUTH);
|
||||
}
|
||||
/* Transfer flag bits 0 and 1 to the pubblock. */
|
||||
pub->flag |= (sec->flag & 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!sec)
|
||||
{
|
||||
KBNODE next, ll;
|
||||
|
||||
if (opt.verbose)
|
||||
log_info (_("no secret subkey"
|
||||
" for public subkey %s - ignoring\n"),
|
||||
keystr_from_pk (pk));
|
||||
/* We have to remove the subkey in this case. */
|
||||
assert (last);
|
||||
/* Find the next subkey. */
|
||||
for (next = pub->next, ll = pub;
|
||||
next && next->pkt->pkttype != PKT_PUBLIC_SUBKEY;
|
||||
ll = next, next = next->next)
|
||||
;
|
||||
/* Make new link. */
|
||||
last->next = next;
|
||||
/* Release this public subkey with all sigs. */
|
||||
ll->next = NULL;
|
||||
release_kbnode (pub);
|
||||
/* Let the loop continue. */
|
||||
pub = last;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* We need to copy the found bits (0 and 1) from the secret key to
|
||||
the public key. This has already been done for the subkeys but
|
||||
got lost on the primary key - fix it here. */
|
||||
pubblock->flag |= (secblock->flag & 3);
|
||||
}
|
||||
#endif /*0*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* gpg.h - top level include file for gpg etc.
|
||||
* Copyright (C) 2003, 2006 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2003, 2006, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -50,6 +50,7 @@ struct server_local_s;
|
||||
|
||||
/* Object used to describe a keyblok node. */
|
||||
typedef struct kbnode_struct *KBNODE;
|
||||
typedef struct kbnode_struct *kbnode_t;
|
||||
|
||||
|
||||
/* Session control object. This object is passed to most functions to
|
||||
|
@ -353,8 +353,6 @@ keydb_new (int secret)
|
||||
KEYDB_HANDLE hd;
|
||||
int i, j;
|
||||
|
||||
if (secret)
|
||||
log_debug ("FIXME: keydb_new called for secret keys\n");
|
||||
hd = xmalloc_clear (sizeof *hd);
|
||||
hd->found = -1;
|
||||
|
||||
|
30
g10/keydb.h
30
g10/keydb.h
@ -1,6 +1,6 @@
|
||||
/* keydb.h - Key database
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
* 2006, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -40,6 +40,7 @@
|
||||
|
||||
struct getkey_ctx_s;
|
||||
typedef struct getkey_ctx_s *GETKEY_CTX;
|
||||
typedef struct getkey_ctx_s *getkey_ctx_t;
|
||||
|
||||
/****************
|
||||
* A Keyblock is all packets which form an entire certificate;
|
||||
@ -93,12 +94,13 @@ struct pk_list
|
||||
int flags; /* flag bit 1==throw_keyid */
|
||||
};
|
||||
|
||||
/* structure to hold a couple of secret key certificates */
|
||||
/* Structure to hold a list of secret key certificates. */
|
||||
typedef struct sk_list *SK_LIST;
|
||||
struct sk_list {
|
||||
SK_LIST next;
|
||||
PKT_secret_key *sk;
|
||||
int mark; /* not used */
|
||||
struct sk_list
|
||||
{
|
||||
SK_LIST next;
|
||||
PKT_public_key *pk;
|
||||
int mark; /* not used */
|
||||
};
|
||||
|
||||
/* structure to collect all information which can be used to
|
||||
@ -169,8 +171,8 @@ void warn_missing_aes_from_pklist (PK_LIST pk_list);
|
||||
/*-- skclist.c --*/
|
||||
int random_is_faked (void);
|
||||
void release_sk_list( SK_LIST sk_list );
|
||||
int build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list,
|
||||
int unlock, unsigned use );
|
||||
gpg_error_t build_sk_list (strlist_t locusr, SK_LIST *ret_sk_list,
|
||||
int unlock, unsigned use);
|
||||
|
||||
/*-- passphrase.h --*/
|
||||
unsigned char encode_s2k_iterations (int iterations);
|
||||
@ -226,6 +228,18 @@ int get_seckey_byfprint( PKT_secret_key *sk,
|
||||
int get_seckeyblock_byfprint (KBNODE *ret_keyblock, const byte *fprint,
|
||||
size_t fprint_len );
|
||||
|
||||
gpg_error_t getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||
strlist_t names, int want_secret,
|
||||
kbnode_t *ret_keyblock);
|
||||
gpg_error_t getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||
const char *name, int want_secret,
|
||||
kbnode_t *ret_keyblock);
|
||||
gpg_error_t getkey_next (getkey_ctx_t ctx, PKT_public_key *pk,
|
||||
kbnode_t *ret_keyblock);
|
||||
void getkey_end (getkey_ctx_t ctx);
|
||||
|
||||
gpg_error_t have_secret_key (kbnode_t keyblock);
|
||||
|
||||
|
||||
int enum_secret_keys( void **context, PKT_secret_key *sk,
|
||||
int with_subkeys, int with_spm );
|
||||
|
105
g10/keyedit.c
105
g10/keyedit.c
@ -511,7 +511,7 @@ sign_uids( KBNODE keyblock, strlist_t locusr, int *ret_modified,
|
||||
int rc = 0;
|
||||
SK_LIST sk_list = NULL;
|
||||
SK_LIST sk_rover = NULL;
|
||||
PKT_secret_key *sk = NULL;
|
||||
PKT_public_key *pk = NULL;
|
||||
KBNODE node, uidnode;
|
||||
PKT_public_key *primary_pk=NULL;
|
||||
int select_all = !count_selected_uids(keyblock) || interactive;
|
||||
@ -550,14 +550,16 @@ sign_uids( KBNODE keyblock, strlist_t locusr, int *ret_modified,
|
||||
opt.cert_policy_url || opt.cert_notations)
|
||||
force_v4=1;
|
||||
|
||||
/* we have to use a copy of the sk, because make_keysig_packet
|
||||
/* We have to use a copy of the pk, because make_keysig_packet
|
||||
* may remove the protection from sk and if we did other
|
||||
* changes to the secret key, we would save the unprotected
|
||||
* version */
|
||||
if( sk )
|
||||
free_secret_key(sk);
|
||||
sk = copy_secret_key( NULL, sk_rover->sk );
|
||||
keyid_from_sk( sk, sk_keyid );
|
||||
* version. FIXME: This can be removed because all protection
|
||||
* is now done by gpg-agent. */
|
||||
if (pk)
|
||||
free_public_key (pk);
|
||||
pk = copy_public_key (NULL, sk_rover->pk);
|
||||
keyid_from_pk (pk, sk_keyid);
|
||||
|
||||
/* set mark A for all selected user ids */
|
||||
for( node=keyblock; node; node = node->next ) {
|
||||
if( select_all || (node->flag & NODFLG_SELUID) )
|
||||
@ -777,10 +779,10 @@ sign_uids( KBNODE keyblock, strlist_t locusr, int *ret_modified,
|
||||
if (!node->pkt->pkt.signature->flags.exportable && local)
|
||||
tty_printf(_(
|
||||
"\"%s\" was already locally signed by key %s\n"),
|
||||
user,keystr_from_sk(sk));
|
||||
user,keystr_from_pk (pk));
|
||||
else
|
||||
tty_printf(_("\"%s\" was already signed by key %s\n"),
|
||||
user,keystr_from_sk(sk));
|
||||
user,keystr_from_pk (pk));
|
||||
|
||||
if(opt.expert
|
||||
&& cpr_get_answer_is_yes("sign_uid.dupe_okay",
|
||||
@ -793,8 +795,8 @@ sign_uids( KBNODE keyblock, strlist_t locusr, int *ret_modified,
|
||||
continue;
|
||||
}
|
||||
|
||||
sprintf (buf, "%08lX%08lX",
|
||||
(ulong)sk->keyid[0], (ulong)sk->keyid[1] );
|
||||
snprintf (buf, sizeof buf, "%08lX%08lX",
|
||||
(ulong)pk->keyid[0], (ulong)pk->keyid[1]);
|
||||
write_status_text (STATUS_ALREADY_SIGNED, buf);
|
||||
uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */
|
||||
|
||||
@ -806,7 +808,7 @@ sign_uids( KBNODE keyblock, strlist_t locusr, int *ret_modified,
|
||||
/* check whether any uids are left for signing */
|
||||
if( !count_uids_with_flag(keyblock, NODFLG_MARK_A) )
|
||||
{
|
||||
tty_printf(_("Nothing to sign with key %s\n"),keystr_from_sk(sk));
|
||||
tty_printf (_("Nothing to sign with key %s\n"), keystr_from_pk (pk));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -883,7 +885,7 @@ sign_uids( KBNODE keyblock, strlist_t locusr, int *ret_modified,
|
||||
currently v3 and we're about to sign it with a v4 sig? If
|
||||
so, danger! */
|
||||
if(PGP2 && all_v3 &&
|
||||
(sk->version>3 || force_v4) && primary_pk->version<=3)
|
||||
(pk->version > 3 || force_v4) && primary_pk->version <= 3)
|
||||
{
|
||||
tty_printf(_("You may not make an OpenPGP signature on a "
|
||||
"PGP 2.x key while in --pgp2 mode.\n"));
|
||||
@ -953,8 +955,8 @@ sign_uids( KBNODE keyblock, strlist_t locusr, int *ret_modified,
|
||||
}
|
||||
|
||||
p=get_user_id_native(sk_keyid);
|
||||
tty_printf(_("Are you sure that you want to sign this key with your\n"
|
||||
"key \"%s\" (%s)\n"),p,keystr_from_sk(sk));
|
||||
tty_printf (_("Are you sure that you want to sign this key with your\n"
|
||||
"key \"%s\" (%s)\n"), p, keystr_from_pk (pk));
|
||||
xfree(p);
|
||||
|
||||
if(selfsig)
|
||||
@ -1051,14 +1053,14 @@ sign_uids( KBNODE keyblock, strlist_t locusr, int *ret_modified,
|
||||
rc = make_keysig_packet( &sig, primary_pk,
|
||||
node->pkt->pkt.user_id,
|
||||
NULL,
|
||||
sk,
|
||||
pk,
|
||||
0x13, 0, force_v4?4:0, 0, 0,
|
||||
keygen_add_std_prefs, primary_pk);
|
||||
else
|
||||
rc = make_keysig_packet( &sig, primary_pk,
|
||||
node->pkt->pkt.user_id,
|
||||
NULL,
|
||||
sk,
|
||||
pk,
|
||||
class, 0, force_v4?4:0,
|
||||
timestamp, duration,
|
||||
sign_mk_attrib, &attrib );
|
||||
@ -1086,8 +1088,8 @@ sign_uids( KBNODE keyblock, strlist_t locusr, int *ret_modified,
|
||||
|
||||
leave:
|
||||
release_sk_list( sk_list );
|
||||
if( sk )
|
||||
free_secret_key(sk);
|
||||
if (pk)
|
||||
free_public_key (pk);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1653,7 +1655,7 @@ keyedit_menu( const char *username, strlist_t locusr,
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
tty_enable_completion(keyedit_completion);
|
||||
#endif
|
||||
answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
|
||||
answer = cpr_get_no_help ("keyedit.prompt", "gpg> ");
|
||||
cpr_kill_prompt();
|
||||
tty_disable_completion();
|
||||
}
|
||||
@ -2331,11 +2333,66 @@ keyedit_menu( const char *username, strlist_t locusr,
|
||||
void
|
||||
keyedit_passwd (const char *username)
|
||||
{
|
||||
gpg_error_t err = gpg_error (GPG_ERR_BUG); /* Not yet implemented. */
|
||||
gpg_error_t err;
|
||||
PKT_public_key *pk;
|
||||
unsigned char fpr[MAX_FINGERPRINT_LEN];
|
||||
size_t fprlen;
|
||||
KEYDB_HANDLE kdh = NULL;
|
||||
kbnode_t keyblock = NULL;
|
||||
|
||||
log_info ("error changing the passphrase for `%s': %s\n",
|
||||
username, gpg_strerror (err));
|
||||
write_status_error ("keyedit.passwd", err);
|
||||
pk = xtrycalloc (1, sizeof *pk);
|
||||
if (!pk)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
err = getkey_byname (NULL, pk, username, 1, NULL);
|
||||
if (err)
|
||||
goto leave;
|
||||
fingerprint_from_pk (pk, fpr, &fprlen);
|
||||
while (fprlen < MAX_FINGERPRINT_LEN)
|
||||
fpr[fprlen++] = 0;
|
||||
|
||||
/* FIXME: Call an agent function instead. */
|
||||
|
||||
kdh = keydb_new (1);
|
||||
if (!kdh)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
err = keydb_search_fpr (kdh, fpr);
|
||||
if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF)
|
||||
err = gpg_error (GPG_ERR_NO_SECKEY);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
err = keydb_get_keyblock (kdh, &keyblock);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
if (!change_passphrase (keyblock))
|
||||
{
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
err = keydb_update_keyblock (kdh, keyblock);
|
||||
if (err)
|
||||
log_error( _("update secret failed: %s\n"), gpg_strerror (err));
|
||||
|
||||
leave:
|
||||
release_kbnode (keyblock);
|
||||
if (pk)
|
||||
free_public_key (pk);
|
||||
keydb_release (kdh);
|
||||
if (err)
|
||||
{
|
||||
log_info ("error changing the passphrase for `%s': %s\n",
|
||||
username, gpg_strerror (err));
|
||||
write_status_error ("keyedit.passwd", err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
516
g10/keylist.c
516
g10/keylist.c
@ -127,18 +127,18 @@ secret_key_list (strlist_t list)
|
||||
}
|
||||
|
||||
void
|
||||
print_seckey_info (PKT_secret_key * sk)
|
||||
print_seckey_info (PKT_public_key *pk)
|
||||
{
|
||||
u32 keyid[2];
|
||||
char *p;
|
||||
|
||||
keyid_from_sk (sk, keyid);
|
||||
keyid_from_pk (pk, keyid);
|
||||
p = get_user_id_native (keyid);
|
||||
|
||||
tty_printf ("\nsec %4u%c/%s %s %s\n",
|
||||
nbits_from_sk (sk),
|
||||
pubkey_letter (sk->pubkey_algo),
|
||||
keystr (keyid), datestr_from_sk (sk), p);
|
||||
nbits_from_pk (pk),
|
||||
pubkey_letter (pk->pubkey_algo),
|
||||
keystr (keyid), datestr_from_pk (pk), p);
|
||||
|
||||
xfree (p);
|
||||
}
|
||||
@ -423,7 +423,7 @@ list_all (int secret)
|
||||
|
||||
memset (&stats, 0, sizeof (stats));
|
||||
|
||||
hd = keydb_new (secret);
|
||||
hd = keydb_new (0);
|
||||
if (!hd)
|
||||
rc = G10ERR_GENERAL;
|
||||
else
|
||||
@ -444,23 +444,28 @@ list_all (int secret)
|
||||
log_error ("keydb_get_keyblock failed: %s\n", g10_errstr (rc));
|
||||
goto leave;
|
||||
}
|
||||
if (!opt.with_colons)
|
||||
{
|
||||
resname = keydb_get_resource_name (hd);
|
||||
if (lastresname != resname)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf ("%s\n", resname);
|
||||
for (i = strlen (resname); i; i--)
|
||||
putchar ('-');
|
||||
putchar ('\n');
|
||||
lastresname = resname;
|
||||
}
|
||||
}
|
||||
merge_keys_and_selfsig (keyblock);
|
||||
list_keyblock (keyblock, secret, opt.fingerprint,
|
||||
opt.check_sigs ? &stats : NULL);
|
||||
if (secret && have_secret_key (keyblock))
|
||||
; /* Secret key listing requested but this isn't one. */
|
||||
else
|
||||
{
|
||||
if (!opt.with_colons)
|
||||
{
|
||||
resname = keydb_get_resource_name (hd);
|
||||
if (lastresname != resname)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf ("%s\n", resname);
|
||||
for (i = strlen (resname); i; i--)
|
||||
putchar ('-');
|
||||
putchar ('\n');
|
||||
lastresname = resname;
|
||||
}
|
||||
}
|
||||
merge_keys_and_selfsig (keyblock);
|
||||
list_keyblock (keyblock, secret, opt.fingerprint,
|
||||
opt.check_sigs ? &stats : NULL);
|
||||
}
|
||||
release_kbnode (keyblock);
|
||||
keyblock = NULL;
|
||||
}
|
||||
@ -499,58 +504,31 @@ list_one (strlist_t names, int secret)
|
||||
* functions) or to have the search function return indicators for
|
||||
* found names. Yet another way is to use the keydb search
|
||||
* facilities directly. */
|
||||
if (secret)
|
||||
rc = getkey_bynames (&ctx, NULL, names, secret, &keyblock);
|
||||
if (rc)
|
||||
{
|
||||
rc = get_seckey_bynames (&ctx, NULL, names, &keyblock);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error reading key: %s\n", g10_errstr (rc));
|
||||
get_seckey_end (ctx);
|
||||
return;
|
||||
}
|
||||
do
|
||||
{
|
||||
if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
|
||||
{
|
||||
resname = keydb_get_resource_name (get_ctx_handle (ctx));
|
||||
printf ("%s: %s\n", keyring_str, resname);
|
||||
for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
|
||||
putchar ('-');
|
||||
putchar ('\n');
|
||||
}
|
||||
list_keyblock (keyblock, 1, opt.fingerprint, NULL);
|
||||
release_kbnode (keyblock);
|
||||
}
|
||||
while (!get_seckey_next (ctx, NULL, &keyblock));
|
||||
get_seckey_end (ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = get_pubkey_bynames (&ctx, NULL, names, &keyblock);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error reading key: %s\n", g10_errstr (rc));
|
||||
get_pubkey_end (ctx);
|
||||
return;
|
||||
}
|
||||
do
|
||||
{
|
||||
if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
|
||||
{
|
||||
resname = keydb_get_resource_name (get_ctx_handle (ctx));
|
||||
printf ("%s: %s\n", keyring_str, resname);
|
||||
for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
|
||||
putchar ('-');
|
||||
putchar ('\n');
|
||||
}
|
||||
list_keyblock (keyblock, 0, opt.fingerprint,
|
||||
opt.check_sigs ? &stats : NULL);
|
||||
release_kbnode (keyblock);
|
||||
}
|
||||
while (!get_pubkey_next (ctx, NULL, &keyblock));
|
||||
log_error ("error reading key: %s\n", g10_errstr (rc));
|
||||
get_pubkey_end (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
|
||||
{
|
||||
resname = keydb_get_resource_name (get_ctx_handle (ctx));
|
||||
printf ("%s: %s\n", keyring_str, resname);
|
||||
for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
|
||||
putchar ('-');
|
||||
putchar ('\n');
|
||||
}
|
||||
list_keyblock (keyblock, secret, opt.fingerprint,
|
||||
(!secret && opt.check_sigs)? &stats : NULL);
|
||||
release_kbnode (keyblock);
|
||||
}
|
||||
while (!getkey_next (ctx, NULL, &keyblock));
|
||||
getkey_end (ctx);
|
||||
|
||||
if (opt.check_sigs && !opt.with_colons)
|
||||
print_signature_stats (&stats);
|
||||
}
|
||||
@ -610,39 +588,37 @@ print_key_data (PKT_public_key * pk)
|
||||
}
|
||||
|
||||
static void
|
||||
print_capabilities (PKT_public_key * pk, PKT_secret_key * sk, KBNODE keyblock)
|
||||
print_capabilities (PKT_public_key *pk, KBNODE keyblock)
|
||||
{
|
||||
if (pk || (sk && sk->protect.s2k.mode != 1001))
|
||||
unsigned int use = pk->pubkey_usage;
|
||||
int c_printed = 0;
|
||||
|
||||
if (use & PUBKEY_USAGE_ENC)
|
||||
putchar ('e');
|
||||
|
||||
if (use & PUBKEY_USAGE_SIG)
|
||||
{
|
||||
unsigned int use = pk ? pk->pubkey_usage : sk->pubkey_usage;
|
||||
int c_printed = 0;
|
||||
|
||||
if (use & PUBKEY_USAGE_ENC)
|
||||
putchar ('e');
|
||||
|
||||
if (use & PUBKEY_USAGE_SIG)
|
||||
{
|
||||
putchar ('s');
|
||||
if (pk ? pk->is_primary : sk->is_primary)
|
||||
{
|
||||
putchar ('c');
|
||||
/* The PUBKEY_USAGE_CERT flag was introduced later and
|
||||
we used to always print 'c' for a primary key. To
|
||||
avoid any regression here we better track whether we
|
||||
printed 'c' already. */
|
||||
c_printed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((use & PUBKEY_USAGE_CERT) && !c_printed)
|
||||
putchar ('c');
|
||||
|
||||
if ((use & PUBKEY_USAGE_AUTH))
|
||||
putchar ('a');
|
||||
putchar ('s');
|
||||
if (pk->is_primary)
|
||||
{
|
||||
putchar ('c');
|
||||
/* The PUBKEY_USAGE_CERT flag was introduced later and we
|
||||
used to always print 'c' for a primary key. To avoid any
|
||||
regression here we better track whether we printed 'c'
|
||||
already. */
|
||||
c_printed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((use & PUBKEY_USAGE_CERT) && !c_printed)
|
||||
putchar ('c');
|
||||
|
||||
if ((use & PUBKEY_USAGE_AUTH))
|
||||
putchar ('a');
|
||||
|
||||
if (keyblock)
|
||||
{ /* figure out the usable capabilities */
|
||||
{
|
||||
/* Figure out the usable capabilities. */
|
||||
KBNODE k;
|
||||
int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
|
||||
|
||||
@ -672,27 +648,6 @@ print_capabilities (PKT_public_key * pk, PKT_secret_key * sk, KBNODE keyblock)
|
||||
auth = 1;
|
||||
}
|
||||
}
|
||||
else if (k->pkt->pkttype == PKT_SECRET_KEY
|
||||
|| k->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
{
|
||||
sk = k->pkt->pkt.secret_key;
|
||||
if (sk->is_valid && !sk->is_revoked && !sk->has_expired
|
||||
&& sk->protect.s2k.mode != 1001)
|
||||
{
|
||||
if (sk->pubkey_usage & PUBKEY_USAGE_ENC)
|
||||
enc = 1;
|
||||
if (sk->pubkey_usage & PUBKEY_USAGE_SIG)
|
||||
{
|
||||
sign = 1;
|
||||
if (sk->is_primary)
|
||||
cert = 1;
|
||||
}
|
||||
if ((sk->pubkey_usage & PUBKEY_USAGE_CERT))
|
||||
cert = 1;
|
||||
if ((sk->pubkey_usage & PUBKEY_USAGE_AUTH))
|
||||
auth = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (enc)
|
||||
putchar ('E');
|
||||
@ -705,10 +660,11 @@ print_capabilities (PKT_public_key * pk, PKT_secret_key * sk, KBNODE keyblock)
|
||||
if (disabled)
|
||||
putchar ('D');
|
||||
}
|
||||
|
||||
|
||||
putchar (':');
|
||||
}
|
||||
|
||||
|
||||
/* FLAGS: 0x01 hashed
|
||||
0x02 critical */
|
||||
static void
|
||||
@ -731,6 +687,7 @@ print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
print_subpackets_colon (PKT_signature * sig)
|
||||
{
|
||||
@ -756,9 +713,9 @@ print_subpackets_colon (PKT_signature * sig)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dump_attribs (const PKT_user_id * uid, PKT_public_key * pk,
|
||||
PKT_secret_key * sk)
|
||||
dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -773,12 +730,9 @@ dump_attribs (const PKT_user_id * uid, PKT_public_key * pk,
|
||||
char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
|
||||
size_t j, n;
|
||||
|
||||
if (pk)
|
||||
fingerprint_from_pk (pk, array, &n);
|
||||
else if (sk)
|
||||
fingerprint_from_sk (sk, array, &n);
|
||||
else
|
||||
BUG ();
|
||||
if (!pk)
|
||||
BUG ();
|
||||
fingerprint_from_pk (pk, array, &n);
|
||||
|
||||
p = array;
|
||||
for (j = 0; j < n; j++, p++)
|
||||
@ -799,6 +753,7 @@ dump_attribs (const PKT_user_id * uid, PKT_public_key * pk,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
|
||||
{
|
||||
@ -806,12 +761,12 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
|
||||
KBNODE kbctx;
|
||||
KBNODE node;
|
||||
PKT_public_key *pk;
|
||||
PKT_secret_key *sk;
|
||||
struct sig_stats *stats = opaque;
|
||||
int skip_sigs = 0;
|
||||
int s2k_char;
|
||||
|
||||
/* get the keyid from the keyblock */
|
||||
node = find_kbnode (keyblock, secret ? PKT_SECRET_KEY : PKT_PUBLIC_KEY);
|
||||
/* Get the keyid from the keyblock. */
|
||||
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
|
||||
if (!node)
|
||||
{
|
||||
log_error ("Oops; key lost!\n");
|
||||
@ -819,81 +774,57 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
|
||||
return;
|
||||
}
|
||||
|
||||
if (secret)
|
||||
pk = node->pkt->pkt.public_key;
|
||||
|
||||
/* Fixme: Get s2k mode from the agent. */
|
||||
s2k_char = (/*(sk->protect.s2k.mode == 1001)? '#' :
|
||||
(sk->protect.s2k.mode == 1002)? '>' : */' ');
|
||||
|
||||
check_trustdb_stale ();
|
||||
|
||||
printf ("%s%c %4u%c/%s %s",
|
||||
secret? "sec":"pub",
|
||||
s2k_char,
|
||||
nbits_from_pk (pk), pubkey_letter (pk->pubkey_algo),
|
||||
keystr_from_pk (pk), datestr_from_pk (pk));
|
||||
|
||||
if (pk->is_revoked)
|
||||
{
|
||||
pk = NULL;
|
||||
sk = node->pkt->pkt.secret_key;
|
||||
|
||||
printf ("sec%c %4u%c/%s %s", (sk->protect.s2k.mode == 1001) ? '#' :
|
||||
(sk->protect.s2k.mode == 1002) ? '>' : ' ',
|
||||
nbits_from_sk (sk), pubkey_letter (sk->pubkey_algo),
|
||||
keystr_from_sk (sk), datestr_from_sk (sk));
|
||||
|
||||
if (sk->has_expired)
|
||||
{
|
||||
printf (" [");
|
||||
printf (_("expired: %s"), expirestr_from_sk (sk));
|
||||
printf ("]");
|
||||
}
|
||||
else if (sk->expiredate)
|
||||
{
|
||||
printf (" [");
|
||||
printf (_("expires: %s"), expirestr_from_sk (sk));
|
||||
printf ("]");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
printf (" [");
|
||||
printf (_("revoked: %s"), revokestr_from_pk (pk));
|
||||
printf ("]");
|
||||
}
|
||||
else
|
||||
else if (pk->has_expired)
|
||||
{
|
||||
pk = node->pkt->pkt.public_key;
|
||||
sk = NULL;
|
||||
|
||||
check_trustdb_stale ();
|
||||
|
||||
printf ("pub %4u%c/%s %s",
|
||||
nbits_from_pk (pk), pubkey_letter (pk->pubkey_algo),
|
||||
keystr_from_pk (pk), datestr_from_pk (pk));
|
||||
|
||||
/* We didn't include this before in the key listing, but there
|
||||
is room in the new format, so why not? */
|
||||
|
||||
if (pk->is_revoked)
|
||||
{
|
||||
printf (" [");
|
||||
printf (_("revoked: %s"), revokestr_from_pk (pk));
|
||||
printf ("]");
|
||||
}
|
||||
else if (pk->has_expired)
|
||||
{
|
||||
printf (" [");
|
||||
printf (_("expired: %s"), expirestr_from_pk (pk));
|
||||
printf ("]");
|
||||
}
|
||||
else if (pk->expiredate)
|
||||
{
|
||||
printf (" [");
|
||||
printf (_("expires: %s"), expirestr_from_pk (pk));
|
||||
printf ("]");
|
||||
}
|
||||
printf (" [");
|
||||
printf (_("expired: %s"), expirestr_from_pk (pk));
|
||||
printf ("]");
|
||||
}
|
||||
else if (pk->expiredate)
|
||||
{
|
||||
printf (" [");
|
||||
printf (_("expires: %s"), expirestr_from_pk (pk));
|
||||
printf ("]");
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* I need to think about this some more. It's easy enough to
|
||||
include, but it looks sort of confusing in the
|
||||
listing... */
|
||||
if (opt.list_options & LIST_SHOW_VALIDITY)
|
||||
{
|
||||
int validity = get_validity (pk, NULL);
|
||||
printf (" [%s]", trust_value_to_string (validity));
|
||||
}
|
||||
/* I need to think about this some more. It's easy enough to
|
||||
include, but it looks sort of confusing in the listing... */
|
||||
if (opt.list_options & LIST_SHOW_VALIDITY)
|
||||
{
|
||||
int validity = get_validity (pk, NULL);
|
||||
printf (" [%s]", trust_value_to_string (validity));
|
||||
}
|
||||
#endif
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
printf ("\n");
|
||||
|
||||
if (fpr)
|
||||
print_fingerprint (pk, sk, 0);
|
||||
print_card_serialno (sk);
|
||||
print_fingerprint (pk, NULL, 0);
|
||||
|
||||
/* FIXME: Change this function to take a PK and ask the agent: */
|
||||
/* if (secret) print_card_serialno (sk); */
|
||||
|
||||
if (opt.with_key_data)
|
||||
print_key_data (pk);
|
||||
|
||||
@ -913,7 +844,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
|
||||
skip_sigs = 0;
|
||||
|
||||
if (attrib_fp && uid->attrib_data != NULL)
|
||||
dump_attribs (uid, pk, sk);
|
||||
dump_attribs (uid, pk);
|
||||
|
||||
if ((uid->is_revoked || uid->is_expired)
|
||||
|| ((opt.list_options & LIST_SHOW_UID_VALIDITY) && pk))
|
||||
@ -938,7 +869,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
|
||||
putchar ('\n');
|
||||
|
||||
if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
|
||||
show_photos (uid->attribs, uid->numattribs, pk, sk, uid);
|
||||
show_photos (uid->attribs, uid->numattribs, pk, NULL, uid);
|
||||
}
|
||||
else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
{
|
||||
@ -953,7 +884,13 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
|
||||
else
|
||||
skip_sigs = 0;
|
||||
|
||||
printf ("sub %4u%c/%s %s",
|
||||
/* Fixme: Get s2k mode from the agent. */
|
||||
s2k_char = (/*(sk->protect.s2k.mode == 1001)? '#' :
|
||||
(sk->protect.s2k.mode == 1002)? '>' : */' ');
|
||||
|
||||
printf ("%s%c %4u%c/%s %s",
|
||||
secret? "ssb":"sub",
|
||||
s2k_char,
|
||||
nbits_from_pk (pk2), pubkey_letter (pk2->pubkey_algo),
|
||||
keystr_from_pk (pk2), datestr_from_pk (pk2));
|
||||
if (pk2->is_revoked)
|
||||
@ -976,32 +913,15 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
|
||||
}
|
||||
putchar ('\n');
|
||||
if (fpr > 1)
|
||||
print_fingerprint (pk2, NULL, 0);
|
||||
{
|
||||
print_fingerprint (pk2, NULL, 0);
|
||||
/* FIXME: (see above) */
|
||||
/* if (secret) */
|
||||
/* print_card_serialno (sk2); */
|
||||
}
|
||||
if (opt.with_key_data)
|
||||
print_key_data (pk2);
|
||||
}
|
||||
else if (node->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
{
|
||||
PKT_secret_key *sk2 = node->pkt->pkt.secret_key;
|
||||
|
||||
printf ("ssb%c %4u%c/%s %s",
|
||||
(sk2->protect.s2k.mode == 1001) ? '#' :
|
||||
(sk2->protect.s2k.mode == 1002) ? '>' : ' ',
|
||||
nbits_from_sk (sk2), pubkey_letter (sk2->pubkey_algo),
|
||||
keystr_from_sk (sk2), datestr_from_sk (sk2));
|
||||
if (sk2->expiredate)
|
||||
{
|
||||
printf (" [");
|
||||
printf (_("expires: %s"), expirestr_from_sk (sk2));
|
||||
printf ("]");
|
||||
}
|
||||
putchar ('\n');
|
||||
if (fpr > 1)
|
||||
{
|
||||
print_fingerprint (NULL, sk2, 0);
|
||||
print_card_serialno (sk2);
|
||||
}
|
||||
}
|
||||
else if (opt.list_sigs
|
||||
&& node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
|
||||
{
|
||||
@ -1142,14 +1062,13 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
|
||||
KBNODE kbctx;
|
||||
KBNODE node;
|
||||
PKT_public_key *pk;
|
||||
PKT_secret_key *sk;
|
||||
u32 keyid[2];
|
||||
int trustletter = 0;
|
||||
int ulti_hack = 0;
|
||||
int i;
|
||||
|
||||
/* get the keyid from the keyblock */
|
||||
node = find_kbnode (keyblock, secret ? PKT_SECRET_KEY : PKT_PUBLIC_KEY);
|
||||
/* Get the keyid from the keyblock. */
|
||||
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
|
||||
if (!node)
|
||||
{
|
||||
log_error ("Oops; key lost!\n");
|
||||
@ -1157,77 +1076,63 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
|
||||
return;
|
||||
}
|
||||
|
||||
if (secret)
|
||||
{
|
||||
pk = NULL;
|
||||
sk = node->pkt->pkt.secret_key;
|
||||
keyid_from_sk (sk, keyid);
|
||||
printf ("sec::%u:%d:%08lX%08lX:%s:%s:::",
|
||||
nbits_from_sk (sk),
|
||||
sk->pubkey_algo,
|
||||
(ulong) keyid[0], (ulong) keyid[1],
|
||||
colon_datestr_from_sk (sk), colon_strtime (sk->expiredate)
|
||||
/* fixme: add LID here */ );
|
||||
}
|
||||
pk = node->pkt->pkt.public_key;
|
||||
|
||||
keyid_from_pk (pk, keyid);
|
||||
fputs (secret? "sec:":"pub:", stdout);
|
||||
if (!pk->is_valid)
|
||||
putchar ('i');
|
||||
else if (pk->is_revoked)
|
||||
putchar ('r');
|
||||
else if (pk->has_expired)
|
||||
putchar ('e');
|
||||
else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
|
||||
;
|
||||
else
|
||||
{
|
||||
pk = node->pkt->pkt.public_key;
|
||||
sk = NULL;
|
||||
keyid_from_pk (pk, keyid);
|
||||
fputs ("pub:", stdout);
|
||||
if (!pk->is_valid)
|
||||
putchar ('i');
|
||||
else if (pk->is_revoked)
|
||||
putchar ('r');
|
||||
else if (pk->has_expired)
|
||||
putchar ('e');
|
||||
else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
|
||||
;
|
||||
else
|
||||
{
|
||||
trustletter = get_validity_info (pk, NULL);
|
||||
if (trustletter == 'u')
|
||||
ulti_hack = 1;
|
||||
putchar (trustletter);
|
||||
}
|
||||
printf (":%u:%d:%08lX%08lX:%s:%s::",
|
||||
nbits_from_pk (pk),
|
||||
pk->pubkey_algo,
|
||||
(ulong) keyid[0], (ulong) keyid[1],
|
||||
colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
|
||||
if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
|
||||
putchar (get_ownertrust_info (pk));
|
||||
putchar (':');
|
||||
trustletter = get_validity_info (pk, NULL);
|
||||
if (trustletter == 'u')
|
||||
ulti_hack = 1;
|
||||
putchar (trustletter);
|
||||
}
|
||||
|
||||
printf (":%u:%d:%08lX%08lX:%s:%s::",
|
||||
nbits_from_pk (pk),
|
||||
pk->pubkey_algo,
|
||||
(ulong) keyid[0], (ulong) keyid[1],
|
||||
colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
|
||||
|
||||
if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
|
||||
putchar (get_ownertrust_info (pk));
|
||||
putchar (':');
|
||||
|
||||
putchar (':');
|
||||
putchar (':');
|
||||
print_capabilities (pk, sk, keyblock);
|
||||
print_capabilities (pk, keyblock);
|
||||
if (secret)
|
||||
{
|
||||
putchar (':'); /* End of field 13. */
|
||||
putchar (':'); /* End of field 14. */
|
||||
if (sk->protect.s2k.mode == 1001)
|
||||
if (/*FIXME sk->protect.s2k.mode*/1 == 1001)
|
||||
putchar ('#'); /* Key is just a stub. */
|
||||
else if (sk->protect.s2k.mode == 1002)
|
||||
else if (/*FIXME sk->protect.s2k.mode*/1 == 1002)
|
||||
{
|
||||
/* Key is stored on an external token (card) or handled by
|
||||
the gpg-agent. Print the serial number of that token
|
||||
here. */
|
||||
for (i = 0; i < sk->protect.ivlen; i++)
|
||||
printf ("%02X", sk->protect.iv[i]);
|
||||
/* FIXME: for (i = 0; i < sk->protect.ivlen; i++) */
|
||||
/* printf ("%02X", sk->protect.iv[i]); */
|
||||
}
|
||||
putchar (':'); /* End of field 15. */
|
||||
}
|
||||
putchar ('\n');
|
||||
if (pk)
|
||||
print_revokers (pk);
|
||||
|
||||
print_revokers (pk);
|
||||
if (fpr)
|
||||
print_fingerprint (pk, sk, 0);
|
||||
print_fingerprint (pk, NULL, 0);
|
||||
if (opt.with_key_data)
|
||||
print_key_data (pk);
|
||||
|
||||
|
||||
|
||||
for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
|
||||
{
|
||||
if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
|
||||
@ -1236,16 +1141,12 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
|
||||
PKT_user_id *uid = node->pkt->pkt.user_id;
|
||||
|
||||
if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
|
||||
dump_attribs (node->pkt->pkt.user_id, pk, sk);
|
||||
dump_attribs (node->pkt->pkt.user_id, pk);
|
||||
/*
|
||||
* Fixme: We need a is_valid flag here too
|
||||
*/
|
||||
str = uid->attrib_data ? "uat" : "uid";
|
||||
/* If we're listing a secret key, leave out the validity
|
||||
values for now. This is handled better in 1.9. */
|
||||
if (sk)
|
||||
printf ("%s:::::", str);
|
||||
else if (uid->is_revoked)
|
||||
if (uid->is_revoked)
|
||||
printf ("%s:r::::", str);
|
||||
else if (uid->is_expired)
|
||||
printf ("%s:e::::", str);
|
||||
@ -1285,7 +1186,7 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
|
||||
PKT_public_key *pk2 = node->pkt->pkt.public_key;
|
||||
|
||||
keyid_from_pk (pk2, keyid2);
|
||||
fputs ("sub:", stdout);
|
||||
fputs (secret? "ssb:":"sub:", stdout);
|
||||
if (!pk2->is_valid)
|
||||
putchar ('i');
|
||||
else if (pk2->is_revoked)
|
||||
@ -1307,44 +1208,29 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
|
||||
colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
|
||||
/* fixme: add LID and ownertrust here */
|
||||
);
|
||||
print_capabilities (pk2, NULL, NULL);
|
||||
print_capabilities (pk2, NULL);
|
||||
if (secret)
|
||||
{
|
||||
putchar (':'); /* End of field 13. */
|
||||
putchar (':'); /* End of field 14. */
|
||||
if (/*FIXME:sk2->protect.s2k.mode*/1 == 1001)
|
||||
putchar ('#'); /* Key is just a stub. */
|
||||
else if (/*FIXME: sk2->protect.s2k.mode*/1 == 1002)
|
||||
{
|
||||
/* Key is stored on an external token (card) or
|
||||
handled by the gpg-agent. Print the serial
|
||||
number of that token here. */
|
||||
/* FIXME: for (i = 0; i < sk2->protect.ivlen; i++)
|
||||
printf ("%02X", sk2->protect.iv[i]); */
|
||||
}
|
||||
putchar (':'); /* End of field 15. */
|
||||
}
|
||||
putchar ('\n');
|
||||
if (fpr > 1)
|
||||
print_fingerprint (pk2, NULL, 0);
|
||||
if (opt.with_key_data)
|
||||
print_key_data (pk2);
|
||||
}
|
||||
else if (node->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
{
|
||||
u32 keyid2[2];
|
||||
PKT_secret_key *sk2 = node->pkt->pkt.secret_key;
|
||||
|
||||
keyid_from_sk (sk2, keyid2);
|
||||
printf ("ssb::%u:%d:%08lX%08lX:%s:%s:::::",
|
||||
nbits_from_sk (sk2),
|
||||
sk2->pubkey_algo,
|
||||
(ulong) keyid2[0], (ulong) keyid2[1],
|
||||
colon_datestr_from_sk (sk2), colon_strtime (sk2->expiredate)
|
||||
/* fixme: add LID */ );
|
||||
print_capabilities (NULL, sk2, NULL);
|
||||
putchar (':'); /* End of field 13. */
|
||||
putchar (':'); /* End of field 14. */
|
||||
if (sk2->protect.s2k.mode == 1001)
|
||||
putchar ('#'); /* Key is just a stub. */
|
||||
else if (sk2->protect.s2k.mode == 1002)
|
||||
{
|
||||
/* Key is stored on an external token (card) or handled by
|
||||
the gpg-agent. Print the serial number of that token
|
||||
here. */
|
||||
for (i = 0; i < sk2->protect.ivlen; i++)
|
||||
printf ("%02X", sk2->protect.iv[i]);
|
||||
}
|
||||
putchar (':'); /* End of field 15. */
|
||||
putchar ('\n');
|
||||
|
||||
if (fpr > 1)
|
||||
print_fingerprint (NULL, sk2, 0);
|
||||
}
|
||||
else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
|
||||
{
|
||||
PKT_signature *sig = node->pkt->pkt.signature;
|
||||
|
@ -103,7 +103,7 @@ void idea_cipher_warn( int show );
|
||||
struct expando_args
|
||||
{
|
||||
PKT_public_key *pk;
|
||||
PKT_secret_key *sk;
|
||||
PKT_public_key *pksk;
|
||||
byte imagetype;
|
||||
int validity_info;
|
||||
const char *validity_string;
|
||||
@ -195,7 +195,7 @@ int encrypt_filter (void *opaque, int control,
|
||||
|
||||
|
||||
/*-- sign.c --*/
|
||||
int complete_sig( PKT_signature *sig, PKT_secret_key *sk, gcry_md_hd_t md );
|
||||
int complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md);
|
||||
int sign_file( strlist_t filenames, int detached, strlist_t locusr,
|
||||
int do_encrypt, strlist_t remusr, const char *outfile );
|
||||
int clearsign_file( const char *fname, strlist_t locusr, const char *outfile );
|
||||
@ -306,10 +306,9 @@ void print_revokers(PKT_public_key *pk);
|
||||
void show_policy_url(PKT_signature *sig,int indent,int mode);
|
||||
void show_keyserver_url(PKT_signature *sig,int indent,int mode);
|
||||
void show_notation(PKT_signature *sig,int indent,int mode,int which);
|
||||
void dump_attribs(const PKT_user_id *uid,
|
||||
PKT_public_key *pk,PKT_secret_key *sk);
|
||||
void dump_attribs (const PKT_user_id *uid, PKT_public_key *pk);
|
||||
void set_attrib_fd(int fd);
|
||||
void print_seckey_info (PKT_secret_key *sk);
|
||||
void print_seckey_info (PKT_public_key *pk);
|
||||
void print_pubkey_info (FILE *fp, PKT_public_key *pk);
|
||||
void print_card_key_info (FILE *fp, KBNODE keyblock);
|
||||
|
||||
|
@ -1837,7 +1837,7 @@ check_sig_and_print( CTX c, KBNODE node )
|
||||
|
||||
if(un->pkt->pkt.user_id->attrib_data)
|
||||
{
|
||||
dump_attribs(un->pkt->pkt.user_id,pk,NULL);
|
||||
dump_attribs (un->pkt->pkt.user_id, pk);
|
||||
|
||||
if(opt.verify_options&VERIFY_SHOW_PHOTOS)
|
||||
show_photos(un->pkt->pkt.user_id->attribs,
|
||||
|
50
g10/misc.c
50
g10/misc.c
@ -510,15 +510,16 @@ idea_cipher_warn(int show)
|
||||
|
||||
|
||||
static unsigned long
|
||||
get_signature_count (PKT_secret_key *sk)
|
||||
get_signature_count (PKT_public_key *pk)
|
||||
{
|
||||
#ifdef ENABLE_CARD_SUPPORT
|
||||
if(sk && sk->is_protected && sk->protect.s2k.mode==1002)
|
||||
{
|
||||
struct agent_card_info_s info;
|
||||
if(agent_scd_getattr("SIG-COUNTER",&info)==0)
|
||||
return info.sig_counter;
|
||||
}
|
||||
/* FIXME: Need to call the agent. */
|
||||
/* if(sk && sk->is_protected && sk->protect.s2k.mode==1002) */
|
||||
/* { */
|
||||
/* struct agent_card_info_s info; */
|
||||
/* if(agent_scd_getattr("SIG-COUNTER",&info)==0) */
|
||||
/* return info.sig_counter; */
|
||||
/* } */
|
||||
#endif
|
||||
|
||||
/* How to do this without a card? */
|
||||
@ -539,13 +540,13 @@ pct_expando(const char *string,struct expando_args *args)
|
||||
if(args->pk)
|
||||
keyid_from_pk(args->pk,pk_keyid);
|
||||
|
||||
if(args->sk)
|
||||
keyid_from_sk(args->sk,sk_keyid);
|
||||
if(args->pksk)
|
||||
keyid_from_pk (args->pksk, sk_keyid);
|
||||
|
||||
/* This is used so that %k works in photoid command strings in
|
||||
--list-secret-keys (which of course has a sk, but no pk). */
|
||||
if(!args->pk && args->sk)
|
||||
keyid_from_sk(args->sk,pk_keyid);
|
||||
if(!args->pk && args->pksk)
|
||||
keyid_from_pk (args->pksk, pk_keyid);
|
||||
|
||||
while(*ch!='\0')
|
||||
{
|
||||
@ -606,7 +607,7 @@ pct_expando(const char *string,struct expando_args *args)
|
||||
case 'c': /* signature count from card, if any. */
|
||||
if(idx+10<maxlen)
|
||||
{
|
||||
sprintf(&ret[idx],"%lu",get_signature_count(args->sk));
|
||||
sprintf (&ret[idx],"%lu", get_signature_count (args->pksk));
|
||||
idx+=strlen(&ret[idx]);
|
||||
done=1;
|
||||
}
|
||||
@ -620,28 +621,31 @@ pct_expando(const char *string,struct expando_args *args)
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if((*(ch+1))=='p' && args->sk)
|
||||
if((*(ch+1))=='p' && args->pksk)
|
||||
{
|
||||
if(args->sk->is_primary)
|
||||
fingerprint_from_sk(args->sk,array,&len);
|
||||
else if(args->sk->main_keyid[0] || args->sk->main_keyid[1])
|
||||
if(args->pksk->is_primary)
|
||||
fingerprint_from_pk (args->pksk, array, &len);
|
||||
else if (args->pksk->main_keyid[0]
|
||||
|| args->pksk->main_keyid[1])
|
||||
{
|
||||
/* FIXME: Document teh code and check whether
|
||||
it is still needed. */
|
||||
PKT_public_key *pk=
|
||||
xmalloc_clear(sizeof(PKT_public_key));
|
||||
|
||||
if(get_pubkey_fast(pk,args->sk->main_keyid)==0)
|
||||
fingerprint_from_pk(pk,array,&len);
|
||||
if (!get_pubkey_fast (pk,args->pksk->main_keyid))
|
||||
fingerprint_from_pk (pk, array, &len);
|
||||
else
|
||||
memset(array,0,(len=MAX_FINGERPRINT_LEN));
|
||||
free_public_key(pk);
|
||||
memset (array, 0, (len=MAX_FINGERPRINT_LEN));
|
||||
free_public_key (pk);
|
||||
}
|
||||
else
|
||||
memset(array,0,(len=MAX_FINGERPRINT_LEN));
|
||||
}
|
||||
else if((*(ch+1))=='f' && args->pk)
|
||||
fingerprint_from_pk(args->pk,array,&len);
|
||||
else if((*(ch+1))=='g' && args->sk)
|
||||
fingerprint_from_sk(args->sk,array,&len);
|
||||
fingerprint_from_pk (args->pk, array, &len);
|
||||
else if((*(ch+1))=='g' && args->pksk)
|
||||
fingerprint_from_pk (args->pksk, array, &len);
|
||||
else
|
||||
memset(array,0,(len=MAX_FINGERPRINT_LEN));
|
||||
|
||||
|
@ -501,7 +501,7 @@ int ask_for_detached_datafile( gcry_md_hd_t md, gcry_md_hd_t md2,
|
||||
/*-- sign.c --*/
|
||||
int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
||||
PKT_user_id *uid, PKT_public_key *subpk,
|
||||
PKT_secret_key *sk, int sigclass, int digest_algo,
|
||||
PKT_public_key *pksk, int sigclass, int digest_algo,
|
||||
int sigversion, u32 timestamp, u32 duration,
|
||||
int (*mksubpkt)(PKT_signature *, void *),
|
||||
void *opaque );
|
||||
@ -510,7 +510,7 @@ int update_keysig_packet( PKT_signature **ret_sig,
|
||||
PKT_public_key *pk,
|
||||
PKT_user_id *uid,
|
||||
PKT_public_key *subpk,
|
||||
PKT_secret_key *sk,
|
||||
PKT_public_key *pksk,
|
||||
int (*mksubpkt)(PKT_signature *, void *),
|
||||
void *opaque );
|
||||
|
||||
|
@ -297,7 +297,7 @@ show_photos(const struct user_attribute *attrs,
|
||||
|
||||
memset(&args,0,sizeof(args));
|
||||
args.pk=pk;
|
||||
args.sk=sk;
|
||||
args.pksk=sk;
|
||||
args.validity_info=get_validity_info(pk,uid);
|
||||
args.validity_string=get_validity_string(pk,uid);
|
||||
|
||||
|
31
g10/revoke.c
31
g10/revoke.c
@ -200,7 +200,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
|
||||
int rc = 0;
|
||||
armor_filter_context_t *afx;
|
||||
PKT_public_key *pk = NULL;
|
||||
PKT_secret_key *sk = NULL;
|
||||
PKT_public_key *pk2 = NULL;
|
||||
PKT_signature *sig = NULL;
|
||||
IOBUF out = NULL;
|
||||
struct revocation_reason_info *reason = NULL;
|
||||
@ -262,8 +262,8 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
|
||||
{
|
||||
SK_LIST list;
|
||||
|
||||
if(sk)
|
||||
free_secret_key(sk);
|
||||
if (pk2)
|
||||
free_public_key (pk2);
|
||||
|
||||
if(sk_list)
|
||||
{
|
||||
@ -272,7 +272,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
|
||||
byte fpr[MAX_FINGERPRINT_LEN];
|
||||
size_t fprlen;
|
||||
|
||||
fingerprint_from_sk(list->sk,fpr,&fprlen);
|
||||
fingerprint_from_pk (list->pk, fpr, &fprlen);
|
||||
|
||||
/* Don't get involved with keys that don't have 160
|
||||
bit fingerprints */
|
||||
@ -283,18 +283,19 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
|
||||
break;
|
||||
}
|
||||
|
||||
if(list)
|
||||
sk=copy_secret_key(NULL,list->sk);
|
||||
if (list)
|
||||
pk2 = copy_public_key (NULL, list->pk);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
sk=xmalloc_secure_clear(sizeof(*sk));
|
||||
rc=get_seckey_byfprint(sk,pk->revkey[i].fpr,MAX_FINGERPRINT_LEN);
|
||||
pk2 = xmalloc_clear (sizeof *pk2);
|
||||
rc = get_pubkey_byfprint (pk2,
|
||||
pk->revkey[i].fpr, MAX_FINGERPRINT_LEN);
|
||||
}
|
||||
|
||||
/* We have the revocation key */
|
||||
/* We have the revocation key. */
|
||||
if(!rc)
|
||||
{
|
||||
PKT_signature *revkey = NULL;
|
||||
@ -305,7 +306,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
|
||||
tty_printf ("\n");
|
||||
|
||||
tty_printf (_("To be revoked by:\n"));
|
||||
print_seckey_info (sk);
|
||||
print_seckey_info (pk2);
|
||||
|
||||
if(pk->revkey[i].class&0x40)
|
||||
tty_printf(_("(This is a sensitive revocation key)\n"));
|
||||
@ -320,8 +321,8 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
|
||||
if( !reason )
|
||||
continue;
|
||||
|
||||
rc = check_secret_key( sk, 0 );
|
||||
if( rc )
|
||||
rc = -1;/*FIXME: check_secret_key (pk2, 0 );*/
|
||||
if (rc)
|
||||
continue;
|
||||
|
||||
if( !opt.armor )
|
||||
@ -336,7 +337,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
|
||||
push_armor_filter (afx, out);
|
||||
|
||||
/* create it */
|
||||
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
|
||||
rc = make_keysig_packet( &sig, pk, NULL, NULL, pk2, 0x20, 0,
|
||||
0, 0, 0,
|
||||
revocation_reason_build_cb, reason );
|
||||
if( rc ) {
|
||||
@ -414,8 +415,8 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
|
||||
leave:
|
||||
if( pk )
|
||||
free_public_key( pk );
|
||||
if( sk )
|
||||
free_secret_key( sk );
|
||||
if (pk2)
|
||||
free_public_key (pk2);
|
||||
if( sig )
|
||||
free_seckey_enc( sig );
|
||||
|
||||
|
@ -611,6 +611,7 @@ cmd_passwd (assuan_context_t ctx, char *line)
|
||||
/* ctrl_t ctrl = assuan_get_pointer (ctx); */
|
||||
gpg_error_t err;
|
||||
|
||||
(void)ctx;
|
||||
line = skip_options (line);
|
||||
|
||||
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
|
370
g10/sign.c
370
g10/sign.c
@ -1,6 +1,6 @@
|
||||
/* sign.c - sign data
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
* 2007 Free Software Foundation, Inc.
|
||||
* 2007, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -57,8 +57,8 @@ static int recipient_digest_algo=0;
|
||||
* a valid NAME=VALUE format.
|
||||
*/
|
||||
static void
|
||||
mk_notation_policy_etc( PKT_signature *sig,
|
||||
PKT_public_key *pk, PKT_secret_key *sk )
|
||||
mk_notation_policy_etc (PKT_signature *sig,
|
||||
PKT_public_key *pk, PKT_public_key *pksk)
|
||||
{
|
||||
const char *string;
|
||||
char *s=NULL;
|
||||
@ -70,7 +70,7 @@ mk_notation_policy_etc( PKT_signature *sig,
|
||||
|
||||
memset(&args,0,sizeof(args));
|
||||
args.pk=pk;
|
||||
args.sk=sk;
|
||||
args.pksk=pksk;
|
||||
|
||||
/* notation data */
|
||||
if(IS_SIG(sig) && opt.sig_notations)
|
||||
@ -229,15 +229,15 @@ hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig)
|
||||
|
||||
|
||||
static int
|
||||
do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
||||
gcry_md_hd_t md, int digest_algo )
|
||||
do_sign (PKT_public_key *pksk, PKT_signature *sig,
|
||||
gcry_md_hd_t md, int digest_algo)
|
||||
{
|
||||
gcry_mpi_t frame;
|
||||
byte *dp;
|
||||
int rc;
|
||||
|
||||
if( sk->timestamp > sig->timestamp ) {
|
||||
ulong d = sk->timestamp - sig->timestamp;
|
||||
if (pksk->timestamp > sig->timestamp ) {
|
||||
ulong d = pksk->timestamp - sig->timestamp;
|
||||
log_info( d==1 ? _("key has been created %lu second "
|
||||
"in future (time warp or clock problem)\n")
|
||||
: _("key has been created %lu seconds "
|
||||
@ -247,7 +247,7 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
||||
}
|
||||
|
||||
|
||||
print_pubkey_algo_note(sk->pubkey_algo);
|
||||
print_pubkey_algo_note (pksk->pubkey_algo);
|
||||
|
||||
if( !digest_algo )
|
||||
digest_algo = gcry_md_get_algo (md);
|
||||
@ -257,37 +257,39 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
||||
sig->digest_algo = digest_algo;
|
||||
sig->digest_start[0] = dp[0];
|
||||
sig->digest_start[1] = dp[1];
|
||||
if (sk->is_protected && sk->protect.s2k.mode == 1002)
|
||||
{
|
||||
#ifdef ENABLE_CARD_SUPPORT
|
||||
unsigned char *rbuf;
|
||||
size_t rbuflen;
|
||||
char *snbuf;
|
||||
|
||||
/* FIXME: Use agent. */
|
||||
/* if (pksk->is_protected && pksk->protect.s2k.mode == 1002) */
|
||||
/* { */
|
||||
/* #ifdef ENABLE_CARD_SUPPORT */
|
||||
/* unsigned char *rbuf; */
|
||||
/* size_t rbuflen; */
|
||||
/* char *snbuf; */
|
||||
|
||||
snbuf = serialno_and_fpr_from_sk (sk->protect.iv,
|
||||
sk->protect.ivlen, sk);
|
||||
rc = agent_scd_pksign (snbuf, digest_algo,
|
||||
gcry_md_read (md, digest_algo),
|
||||
gcry_md_get_algo_dlen (digest_algo),
|
||||
&rbuf, &rbuflen);
|
||||
xfree (snbuf);
|
||||
if (!rc)
|
||||
{
|
||||
if (gcry_mpi_scan (&sig->data[0], GCRYMPI_FMT_USG,
|
||||
rbuf, rbuflen, NULL))
|
||||
BUG ();
|
||||
xfree (rbuf);
|
||||
}
|
||||
#else
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
#endif /* ENABLE_CARD_SUPPORT */
|
||||
}
|
||||
else
|
||||
/* snbuf = serialno_and_fpr_from_sk (sk->protect.iv, */
|
||||
/* sk->protect.ivlen, sk); */
|
||||
/* rc = agent_scd_pksign (snbuf, digest_algo, */
|
||||
/* gcry_md_read (md, digest_algo), */
|
||||
/* gcry_md_get_algo_dlen (digest_algo), */
|
||||
/* &rbuf, &rbuflen); */
|
||||
/* xfree (snbuf); */
|
||||
/* if (!rc) */
|
||||
/* { */
|
||||
/* if (gcry_mpi_scan (&sig->data[0], GCRYMPI_FMT_USG, */
|
||||
/* rbuf, rbuflen, NULL)) */
|
||||
/* BUG (); */
|
||||
/* xfree (rbuf); */
|
||||
/* } */
|
||||
/* #else */
|
||||
/* return gpg_error (GPG_ERR_NOT_SUPPORTED); */
|
||||
/* #endif /\* ENABLE_CARD_SUPPORT *\/ */
|
||||
/* } */
|
||||
/* else */
|
||||
{
|
||||
frame = encode_md_value( NULL, sk, md, digest_algo );
|
||||
frame = encode_md_value (NULL, pksk, md, digest_algo );
|
||||
if (!frame)
|
||||
return G10ERR_GENERAL;
|
||||
rc = pk_sign( sk->pubkey_algo, sig->data, frame, sk->skey );
|
||||
rc = pk_sign (pksk->pubkey_algo, sig->data, frame, pksk->pkey );
|
||||
gcry_mpi_release (frame);
|
||||
}
|
||||
|
||||
@ -318,7 +320,7 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
||||
if( opt.verbose ) {
|
||||
char *ustr = get_user_id_string_native (sig->keyid);
|
||||
log_info(_("%s/%s signature from: \"%s\"\n"),
|
||||
gcry_pk_algo_name (sk->pubkey_algo),
|
||||
gcry_pk_algo_name (pksk->pubkey_algo),
|
||||
gcry_md_algo_name (sig->digest_algo),
|
||||
ustr );
|
||||
xfree(ustr);
|
||||
@ -329,13 +331,13 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
||||
|
||||
|
||||
int
|
||||
complete_sig( PKT_signature *sig, PKT_secret_key *sk, gcry_md_hd_t md )
|
||||
complete_sig( PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md )
|
||||
{
|
||||
int rc=0;
|
||||
int rc;
|
||||
|
||||
if( !(rc=check_secret_key( sk, 0 )) )
|
||||
rc = do_sign( sk, sig, md, 0 );
|
||||
return rc;
|
||||
if (!(rc = check_secret_key (pksk, 0)))
|
||||
rc = do_sign (pksk, sig, md, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -378,15 +380,19 @@ match_dsa_hash (unsigned int qbytes)
|
||||
list?
|
||||
*/
|
||||
static int
|
||||
hash_for(PKT_secret_key *sk)
|
||||
hash_for (PKT_public_key *pk)
|
||||
{
|
||||
if( opt.def_digest_algo )
|
||||
return opt.def_digest_algo;
|
||||
else if( recipient_digest_algo )
|
||||
return recipient_digest_algo;
|
||||
else if(sk->pubkey_algo==PUBKEY_ALGO_DSA)
|
||||
if (opt.def_digest_algo)
|
||||
{
|
||||
unsigned int qbytes = gcry_mpi_get_nbits (sk->skey[1]) / 8;
|
||||
return opt.def_digest_algo;
|
||||
}
|
||||
else if (recipient_digest_algo)
|
||||
{
|
||||
return recipient_digest_algo;
|
||||
}
|
||||
else if (pk->pubkey_algo == PUBKEY_ALGO_DSA)
|
||||
{
|
||||
unsigned int qbytes = gcry_mpi_get_nbits (pk->pkey[1]) / 8;
|
||||
|
||||
/* It's a DSA key, so find a hash that is the same size as q or
|
||||
larger. If q is 160, assume it is an old DSA key and use a
|
||||
@ -415,9 +421,10 @@ hash_for(PKT_secret_key *sk)
|
||||
|
||||
return match_dsa_hash(qbytes);
|
||||
}
|
||||
else if (sk->is_protected && sk->protect.s2k.mode==1002)
|
||||
else if (/*FIXME: call agent
|
||||
pk->is_protected && sk->protect.s2k.mode==1002*/ 0)
|
||||
{
|
||||
/* The sk lives on a smartcard, and current smartcards only
|
||||
/* The secret key lives on a smartcard, and current smartcards only
|
||||
handle SHA-1 and RIPEMD/160. This is correct now, but may
|
||||
need revision as the cards add algorithms. */
|
||||
|
||||
@ -433,12 +440,12 @@ hash_for(PKT_secret_key *sk)
|
||||
|
||||
return DIGEST_ALGO_SHA1;
|
||||
}
|
||||
else if (PGP2 && sk->pubkey_algo == PUBKEY_ALGO_RSA && sk->version < 4 )
|
||||
else if (PGP2 && pk->pubkey_algo == PUBKEY_ALGO_RSA && pk->version < 4 )
|
||||
{
|
||||
/* Old-style PGP only understands MD5 */
|
||||
return DIGEST_ALGO_MD5;
|
||||
}
|
||||
else if ( opt.personal_digest_prefs )
|
||||
else if (opt.personal_digest_prefs)
|
||||
{
|
||||
/* It's not DSA, so we can use whatever the first hash algorithm
|
||||
is in the pref list */
|
||||
@ -449,42 +456,40 @@ hash_for(PKT_secret_key *sk)
|
||||
}
|
||||
|
||||
|
||||
/* Return true iff all keys in SK_LIST are old style (v3 RSA). */
|
||||
static int
|
||||
only_old_style( SK_LIST sk_list )
|
||||
only_old_style (SK_LIST sk_list)
|
||||
{
|
||||
SK_LIST sk_rover = NULL;
|
||||
int old_style = 0;
|
||||
SK_LIST sk_rover = NULL;
|
||||
int old_style = 0;
|
||||
|
||||
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
|
||||
{
|
||||
PKT_public_key *pk = sk_rover->pk;
|
||||
|
||||
/* if there are only old style capable key we use the old sytle */
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
||||
PKT_secret_key *sk = sk_rover->sk;
|
||||
if( sk->pubkey_algo == PUBKEY_ALGO_RSA && sk->version < 4 )
|
||||
old_style = 1;
|
||||
else
|
||||
return 0;
|
||||
if (pk->pubkey_algo == PUBKEY_ALGO_RSA && pk->version < 4)
|
||||
old_style = 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return old_style;
|
||||
return old_style;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
print_status_sig_created ( PKT_secret_key *sk, PKT_signature *sig, int what )
|
||||
print_status_sig_created (PKT_public_key *pk, PKT_signature *sig, int what)
|
||||
{
|
||||
byte array[MAX_FINGERPRINT_LEN], *p;
|
||||
char buf[100+MAX_FINGERPRINT_LEN*2];
|
||||
size_t i, n;
|
||||
|
||||
sprintf(buf, "%c %d %d %02x %lu ",
|
||||
what, sig->pubkey_algo, sig->digest_algo, sig->sig_class,
|
||||
(ulong)sig->timestamp );
|
||||
|
||||
fingerprint_from_sk( sk, array, &n );
|
||||
p = buf + strlen(buf);
|
||||
for(i=0; i < n ; i++ )
|
||||
sprintf(p+2*i, "%02X", array[i] );
|
||||
|
||||
write_status_text( STATUS_SIG_CREATED, buf );
|
||||
byte array[MAX_FINGERPRINT_LEN];
|
||||
char buf[100+MAX_FINGERPRINT_LEN*2];
|
||||
size_t n;
|
||||
|
||||
snprintf (buf, sizeof buf - 2*MAX_FINGERPRINT_LEN, "%c %d %d %02x %lu ",
|
||||
what, sig->pubkey_algo, sig->digest_algo, sig->sig_class,
|
||||
(ulong)sig->timestamp );
|
||||
fingerprint_from_pk (pk, array, &n);
|
||||
bin2hex (array, n, buf + strlen (buf));
|
||||
|
||||
write_status_text( STATUS_SIG_CREATED, buf );
|
||||
}
|
||||
|
||||
|
||||
@ -504,7 +509,7 @@ write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
|
||||
skcount++;
|
||||
|
||||
for (; skcount; skcount--) {
|
||||
PKT_secret_key *sk;
|
||||
PKT_public_key *pk;
|
||||
PKT_onepass_sig *ops;
|
||||
PACKET pkt;
|
||||
int i, rc;
|
||||
@ -514,12 +519,12 @@ write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
|
||||
break;
|
||||
}
|
||||
|
||||
sk = sk_rover->sk;
|
||||
pk = sk_rover->pk;
|
||||
ops = xmalloc_clear (sizeof *ops);
|
||||
ops->sig_class = sigclass;
|
||||
ops->digest_algo = hash_for (sk);
|
||||
ops->pubkey_algo = sk->pubkey_algo;
|
||||
keyid_from_sk (sk, ops->keyid);
|
||||
ops->digest_algo = hash_for (pk);
|
||||
ops->pubkey_algo = pk->pubkey_algo;
|
||||
keyid_from_pk (pk, ops->keyid);
|
||||
ops->last = (skcount == 1);
|
||||
|
||||
init_packet(&pkt);
|
||||
@ -622,73 +627,76 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
|
||||
int sigclass, u32 timestamp, u32 duration,
|
||||
int status_letter)
|
||||
{
|
||||
SK_LIST sk_rover;
|
||||
SK_LIST sk_rover;
|
||||
|
||||
/* Loop over the certificates with secret keys. */
|
||||
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
|
||||
{
|
||||
PKT_public_key *pk;
|
||||
PKT_signature *sig;
|
||||
gcry_md_hd_t md;
|
||||
int rc;
|
||||
|
||||
/* loop over the secret certificates */
|
||||
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
|
||||
PKT_secret_key *sk;
|
||||
PKT_signature *sig;
|
||||
gcry_md_hd_t md;
|
||||
int rc;
|
||||
pk = sk_rover->pk;
|
||||
|
||||
sk = sk_rover->sk;
|
||||
/* Build the signature packet. */
|
||||
sig = xmalloc_clear (sizeof *sig);
|
||||
if (opt.force_v3_sigs || RFC1991)
|
||||
sig->version = 3;
|
||||
else if (duration || opt.sig_policy_url
|
||||
|| opt.sig_notations || opt.sig_keyserver_url)
|
||||
sig->version = 4;
|
||||
else
|
||||
sig->version = pk->version;
|
||||
|
||||
/* build the signature packet */
|
||||
sig = xmalloc_clear (sizeof *sig);
|
||||
if(opt.force_v3_sigs || RFC1991)
|
||||
sig->version=3;
|
||||
else if(duration || opt.sig_policy_url
|
||||
|| opt.sig_notations || opt.sig_keyserver_url)
|
||||
sig->version=4;
|
||||
else
|
||||
sig->version=sk->version;
|
||||
keyid_from_sk (sk, sig->keyid);
|
||||
sig->digest_algo = hash_for(sk);
|
||||
sig->pubkey_algo = sk->pubkey_algo;
|
||||
if(timestamp)
|
||||
sig->timestamp = timestamp;
|
||||
else
|
||||
sig->timestamp = make_timestamp();
|
||||
if(duration)
|
||||
sig->expiredate = sig->timestamp+duration;
|
||||
sig->sig_class = sigclass;
|
||||
keyid_from_pk (pk, sig->keyid);
|
||||
sig->digest_algo = hash_for (pk);
|
||||
sig->pubkey_algo = pk->pubkey_algo;
|
||||
if (timestamp)
|
||||
sig->timestamp = timestamp;
|
||||
else
|
||||
sig->timestamp = make_timestamp();
|
||||
if (duration)
|
||||
sig->expiredate = sig->timestamp + duration;
|
||||
sig->sig_class = sigclass;
|
||||
|
||||
if (gcry_md_copy (&md, hash))
|
||||
BUG ();
|
||||
if (gcry_md_copy (&md, hash))
|
||||
BUG ();
|
||||
|
||||
if (sig->version >= 4)
|
||||
{
|
||||
build_sig_subpkt_from_sig (sig);
|
||||
mk_notation_policy_etc (sig, pk, NULL);
|
||||
}
|
||||
|
||||
hash_sigversion_to_magic (md, sig);
|
||||
gcry_md_final (md);
|
||||
|
||||
if (sig->version >= 4)
|
||||
{
|
||||
build_sig_subpkt_from_sig (sig);
|
||||
mk_notation_policy_etc (sig, NULL, sk);
|
||||
}
|
||||
|
||||
hash_sigversion_to_magic (md, sig);
|
||||
gcry_md_final (md);
|
||||
|
||||
rc = do_sign( sk, sig, md, hash_for (sk) );
|
||||
gcry_md_close (md);
|
||||
if( !rc ) { /* and write it */
|
||||
PACKET pkt;
|
||||
|
||||
init_packet(&pkt);
|
||||
pkt.pkttype = PKT_SIGNATURE;
|
||||
pkt.pkt.signature = sig;
|
||||
rc = build_packet (out, &pkt);
|
||||
if (!rc && is_status_enabled()) {
|
||||
print_status_sig_created ( sk, sig, status_letter);
|
||||
}
|
||||
free_packet (&pkt);
|
||||
if (rc)
|
||||
log_error ("build signature packet failed: %s\n",
|
||||
g10_errstr(rc) );
|
||||
rc = do_sign (pk, sig, md, hash_for (pk));
|
||||
gcry_md_close (md);
|
||||
if (!rc)
|
||||
{
|
||||
/* Write the packet. */
|
||||
PACKET pkt;
|
||||
|
||||
init_packet (&pkt);
|
||||
pkt.pkttype = PKT_SIGNATURE;
|
||||
pkt.pkt.signature = sig;
|
||||
rc = build_packet (out, &pkt);
|
||||
if (!rc && is_status_enabled())
|
||||
print_status_sig_created (pk, sig, status_letter);
|
||||
free_packet (&pkt);
|
||||
if (rc)
|
||||
log_error ("build signature packet failed: %s\n", gpg_strerror (rc));
|
||||
}
|
||||
if( rc )
|
||||
return rc;;
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Sign the files whose names are in FILENAME.
|
||||
* If DETACHED has the value true,
|
||||
@ -863,10 +871,10 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
|
||||
|
||||
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
|
||||
{
|
||||
if (sk_rover->sk->pubkey_algo == PUBKEY_ALGO_DSA)
|
||||
if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA)
|
||||
{
|
||||
int temp_hashlen = gcry_mpi_get_nbits
|
||||
(sk_rover->sk->skey[1])+7/8;
|
||||
(sk_rover->pk->pkey[1])+7/8;
|
||||
|
||||
/* Pick a hash that is large enough for our
|
||||
largest q */
|
||||
@ -874,9 +882,10 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
|
||||
if (hint.digest_length<temp_hashlen)
|
||||
hint.digest_length=temp_hashlen;
|
||||
}
|
||||
else if (sk_rover->sk->is_protected
|
||||
&& sk_rover->sk->protect.s2k.mode == 1002)
|
||||
smartcard = 1;
|
||||
/* FIXME: need toall gpg-agent */
|
||||
/* else if (sk_rover->pk->is_protected */
|
||||
/* && sk_rover->pk->protect.s2k.mode == 1002) */
|
||||
/* smartcard = 1; */
|
||||
}
|
||||
|
||||
/* Current smartcards only do 160-bit hashes. If we have
|
||||
@ -893,10 +902,8 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
|
||||
}
|
||||
}
|
||||
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
||||
PKT_secret_key *sk = sk_rover->sk;
|
||||
gcry_md_enable (mfx.md, hash_for(sk));
|
||||
}
|
||||
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
|
||||
gcry_md_enable (mfx.md, hash_for (sk_rover->pk));
|
||||
|
||||
if( !multifile )
|
||||
iobuf_push_filter( inp, md_filter, &mfx );
|
||||
@ -1116,15 +1123,16 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
|
||||
|
||||
iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----" LF );
|
||||
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
||||
PKT_secret_key *sk = sk_rover->sk;
|
||||
if( hash_for(sk) == DIGEST_ALGO_MD5 )
|
||||
only_md5 = 1;
|
||||
else {
|
||||
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
|
||||
{
|
||||
if (hash_for (sk_rover->pk) == DIGEST_ALGO_MD5)
|
||||
only_md5 = 1;
|
||||
else
|
||||
{
|
||||
only_md5 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !(old_style && only_md5) ) {
|
||||
const char *s;
|
||||
@ -1134,8 +1142,7 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
|
||||
memset( hashs_seen, 0, sizeof hashs_seen );
|
||||
iobuf_writestr(out, "Hash: " );
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
||||
PKT_secret_key *sk = sk_rover->sk;
|
||||
int i = hash_for(sk);
|
||||
int i = hash_for (sk_rover->pk);
|
||||
|
||||
if( !hashs_seen[ i & 0xff ] ) {
|
||||
s = gcry_md_algo_name ( i );
|
||||
@ -1159,10 +1166,9 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
|
||||
|
||||
if ( gcry_md_open (&textmd, 0, 0) )
|
||||
BUG ();
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
||||
PKT_secret_key *sk = sk_rover->sk;
|
||||
gcry_md_enable (textmd, hash_for(sk));
|
||||
}
|
||||
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
|
||||
gcry_md_enable (textmd, hash_for(sk_rover->pk));
|
||||
|
||||
if ( DBG_HASHING )
|
||||
gcry_md_start_debug ( textmd, "clearsign" );
|
||||
|
||||
@ -1288,10 +1294,8 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
|
||||
if ( DBG_HASHING )
|
||||
gcry_md_start_debug (mfx.md, "symc-sign");
|
||||
|
||||
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
|
||||
PKT_secret_key *sk = sk_rover->sk;
|
||||
gcry_md_enable (mfx.md, hash_for (sk));
|
||||
}
|
||||
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
|
||||
gcry_md_enable (mfx.md, hash_for (sk_rover->pk));
|
||||
|
||||
iobuf_push_filter (inp, md_filter, &mfx);
|
||||
|
||||
@ -1376,7 +1380,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
|
||||
int
|
||||
make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
||||
PKT_user_id *uid, PKT_public_key *subpk,
|
||||
PKT_secret_key *sk,
|
||||
PKT_public_key *pksk,
|
||||
int sigclass, int digest_algo,
|
||||
int sigversion, u32 timestamp, u32 duration,
|
||||
int (*mksubpkt)(PKT_signature *, void *), void *opaque
|
||||
@ -1393,8 +1397,8 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
||||
if (opt.force_v4_certs)
|
||||
sigversion = 4;
|
||||
|
||||
if (sigversion < sk->version)
|
||||
sigversion = sk->version;
|
||||
if (sigversion < pksk->version)
|
||||
sigversion = pksk->version;
|
||||
|
||||
/* If you are making a signature on a v4 key using your v3 key, it
|
||||
doesn't make sense to generate a v3 sig. After all, no v3-only
|
||||
@ -1417,11 +1421,11 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
||||
|
||||
if(opt.cert_digest_algo)
|
||||
digest_algo=opt.cert_digest_algo;
|
||||
else if(sk->pubkey_algo==PUBKEY_ALGO_RSA
|
||||
else if(pksk->pubkey_algo==PUBKEY_ALGO_RSA
|
||||
&& pk->version<4 && sigversion<4)
|
||||
digest_algo = DIGEST_ALGO_MD5;
|
||||
else if(sk->pubkey_algo==PUBKEY_ALGO_DSA)
|
||||
digest_algo = match_dsa_hash (gcry_mpi_get_nbits (sk->skey[1])/8);
|
||||
else if(pksk->pubkey_algo==PUBKEY_ALGO_DSA)
|
||||
digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8);
|
||||
else
|
||||
digest_algo = DIGEST_ALGO_SHA1;
|
||||
}
|
||||
@ -1447,8 +1451,8 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
||||
sig->version = sigversion;
|
||||
sig->flags.exportable=1;
|
||||
sig->flags.revocable=1;
|
||||
keyid_from_sk( sk, sig->keyid );
|
||||
sig->pubkey_algo = sk->pubkey_algo;
|
||||
keyid_from_pk (pksk, sig->keyid);
|
||||
sig->pubkey_algo = pksk->pubkey_algo;
|
||||
sig->digest_algo = digest_algo;
|
||||
if(timestamp)
|
||||
sig->timestamp=timestamp;
|
||||
@ -1460,7 +1464,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
||||
if( sig->version >= 4 )
|
||||
{
|
||||
build_sig_subpkt_from_sig( sig );
|
||||
mk_notation_policy_etc( sig, pk, sk );
|
||||
mk_notation_policy_etc (sig, pk, pksk);
|
||||
}
|
||||
|
||||
/* Crucial that the call to mksubpkt comes LAST before the calls
|
||||
@ -1473,10 +1477,10 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
||||
hash_sigversion_to_magic (md, sig);
|
||||
gcry_md_final (md);
|
||||
|
||||
rc = complete_sig( sig, sk, md );
|
||||
rc = complete_sig (sig, pksk, md);
|
||||
}
|
||||
|
||||
gcry_md_close ( md );
|
||||
gcry_md_close (md);
|
||||
if( rc )
|
||||
free_seckey_enc( sig );
|
||||
else
|
||||
@ -1497,7 +1501,7 @@ update_keysig_packet( PKT_signature **ret_sig,
|
||||
PKT_public_key *pk,
|
||||
PKT_user_id *uid,
|
||||
PKT_public_key *subpk,
|
||||
PKT_secret_key *sk,
|
||||
PKT_public_key *pksk,
|
||||
int (*mksubpkt)(PKT_signature *, void *),
|
||||
void *opaque )
|
||||
{
|
||||
@ -1505,7 +1509,7 @@ update_keysig_packet( PKT_signature **ret_sig,
|
||||
int rc=0;
|
||||
gcry_md_hd_t md;
|
||||
|
||||
if ((!orig_sig || !pk || !sk)
|
||||
if ((!orig_sig || !pk || !pksk)
|
||||
|| (orig_sig->sig_class >= 0x10 && orig_sig->sig_class <= 0x13 && !uid)
|
||||
|| (orig_sig->sig_class == 0x18 && !subpk))
|
||||
return G10ERR_GENERAL;
|
||||
@ -1556,7 +1560,7 @@ update_keysig_packet( PKT_signature **ret_sig,
|
||||
hash_sigversion_to_magic (md, sig);
|
||||
gcry_md_final (md);
|
||||
|
||||
rc = complete_sig( sig, sk, md );
|
||||
rc = complete_sig (sig, pksk, md);
|
||||
}
|
||||
|
||||
gcry_md_close (md);
|
||||
|
375
g10/skclist.c
375
g10/skclist.c
@ -1,5 +1,6 @@
|
||||
/* skclist.c - Build a list of secret keys
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2006,
|
||||
* 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -33,224 +34,246 @@
|
||||
#include "i18n.h"
|
||||
#include "cipher.h"
|
||||
|
||||
#ifndef GCRYCTL_FAKED_RANDOM_P
|
||||
#define GCRYCTL_FAKED_RANDOM_P 51
|
||||
#endif
|
||||
|
||||
/* Return true if Libgcrypt's RNG is in faked mode. */
|
||||
int
|
||||
random_is_faked (void)
|
||||
{
|
||||
return !!gcry_control ( GCRYCTL_FAKED_RANDOM_P, 0);
|
||||
return !!gcry_control (GCRYCTL_FAKED_RANDOM_P, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
release_sk_list( SK_LIST sk_list )
|
||||
release_sk_list (SK_LIST sk_list)
|
||||
{
|
||||
SK_LIST sk_rover;
|
||||
SK_LIST sk_rover;
|
||||
|
||||
for( ; sk_list; sk_list = sk_rover ) {
|
||||
sk_rover = sk_list->next;
|
||||
free_secret_key( sk_list->sk );
|
||||
xfree( sk_list );
|
||||
for (; sk_list; sk_list = sk_rover)
|
||||
{
|
||||
sk_rover = sk_list->next;
|
||||
if (sk_list->pk)
|
||||
free_public_key (sk_list->pk);
|
||||
xfree (sk_list);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check that we are only using keys which don't have
|
||||
* the string "(insecure!)" or "not secure" or "do not use"
|
||||
* in one of the user ids
|
||||
*/
|
||||
* in one of the user ids. */
|
||||
static int
|
||||
is_insecure( PKT_secret_key *sk )
|
||||
is_insecure (PKT_public_key *pk)
|
||||
{
|
||||
u32 keyid[2];
|
||||
KBNODE node = NULL, u;
|
||||
int insecure = 0;
|
||||
u32 keyid[2];
|
||||
KBNODE node = NULL, u;
|
||||
int insecure = 0;
|
||||
|
||||
keyid_from_sk( sk, keyid );
|
||||
node = get_pubkeyblock( keyid );
|
||||
for ( u = node; u; u = u->next ) {
|
||||
if ( u->pkt->pkttype == PKT_USER_ID ) {
|
||||
PKT_user_id *id = u->pkt->pkt.user_id;
|
||||
if ( id->attrib_data )
|
||||
continue; /* skip attribute packets */
|
||||
if ( strstr( id->name, "(insecure!)" )
|
||||
|| strstr( id->name, "not secure" )
|
||||
|| strstr( id->name, "do not use" )
|
||||
|| strstr( id->name, "(INSECURE!)" ) ) {
|
||||
insecure = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
keyid_from_pk (pk, keyid);
|
||||
node = get_pubkeyblock (keyid);
|
||||
for (u = node; u; u = u->next)
|
||||
{
|
||||
if (u->pkt->pkttype == PKT_USER_ID)
|
||||
{
|
||||
PKT_user_id *id = u->pkt->pkt.user_id;
|
||||
if (id->attrib_data)
|
||||
continue; /* skip attribute packets */
|
||||
if (strstr (id->name, "(insecure!)")
|
||||
|| strstr (id->name, "not secure")
|
||||
|| strstr (id->name, "do not use")
|
||||
|| strstr (id->name, "(INSECURE!)"))
|
||||
{
|
||||
insecure = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
release_kbnode( node );
|
||||
|
||||
return insecure;
|
||||
release_kbnode (node);
|
||||
|
||||
return insecure;
|
||||
}
|
||||
|
||||
static int
|
||||
key_present_in_sk_list(SK_LIST sk_list, PKT_secret_key *sk)
|
||||
key_present_in_sk_list (SK_LIST sk_list, PKT_public_key *pk)
|
||||
{
|
||||
for (; sk_list; sk_list = sk_list->next) {
|
||||
if ( !cmp_secret_keys(sk_list->sk, sk) )
|
||||
return 0;
|
||||
for (; sk_list; sk_list = sk_list->next)
|
||||
{
|
||||
if (!cmp_public_keys (sk_list->pk, pk))
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
is_duplicated_entry (strlist_t list, strlist_t item)
|
||||
{
|
||||
for(; list && list != item; list = list->next) {
|
||||
if ( !strcmp (list->d, item->d) )
|
||||
return 1;
|
||||
for (; list && list != item; list = list->next)
|
||||
{
|
||||
if (!strcmp (list->d, item->d))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list,
|
||||
int unlock, unsigned int use )
|
||||
/* FIXME: We ignore the UNLOCK flag - should not be needed anymore. */
|
||||
gpg_error_t
|
||||
build_sk_list (strlist_t locusr, SK_LIST *ret_sk_list,
|
||||
int unlock, unsigned int use)
|
||||
{
|
||||
SK_LIST sk_list = NULL;
|
||||
int rc;
|
||||
gpg_error_t err;
|
||||
SK_LIST sk_list = NULL;
|
||||
|
||||
if( !locusr )
|
||||
{ /* use the default one */
|
||||
PKT_secret_key *sk;
|
||||
if (!locusr) /* No user ids given - use the default key. */
|
||||
{
|
||||
PKT_public_key *pk;
|
||||
|
||||
sk = xmalloc_clear( sizeof *sk );
|
||||
sk->req_usage = use;
|
||||
if( (rc = get_seckey_byname( sk, NULL, unlock )) ) {
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
log_error("no default secret key: %s\n", g10_errstr(rc) );
|
||||
write_status_text (STATUS_INV_SGNR,
|
||||
get_inv_recpsgnr_code (GPG_ERR_NO_SECKEY));
|
||||
pk = xmalloc_clear (sizeof *pk);
|
||||
pk->req_usage = use;
|
||||
if ((err = getkey_byname (NULL, pk, NULL, 1, NULL)))
|
||||
{
|
||||
free_public_key (pk);
|
||||
pk = NULL;
|
||||
log_error ("no default secret key: %s\n", gpg_strerror (err));
|
||||
write_status_text (STATUS_INV_SGNR, get_inv_recpsgnr_code (err));
|
||||
}
|
||||
else if( !(rc=openpgp_pk_test_algo2 (sk->pubkey_algo, use)) )
|
||||
{
|
||||
SK_LIST r;
|
||||
|
||||
if( random_is_faked() && !is_insecure( sk ) )
|
||||
{
|
||||
log_info(_("key is not flagged as insecure - "
|
||||
"can't use it with the faked RNG!\n"));
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
write_status_text (STATUS_INV_SGNR,
|
||||
get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED));
|
||||
}
|
||||
else
|
||||
{
|
||||
r = xmalloc( sizeof *r );
|
||||
r->sk = sk; sk = NULL;
|
||||
r->next = sk_list;
|
||||
r->mark = 0;
|
||||
sk_list = r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
log_error("invalid default secret key: %s\n", g10_errstr(rc) );
|
||||
write_status_text (STATUS_INV_SGNR, get_inv_recpsgnr_code (rc));
|
||||
}
|
||||
}
|
||||
else {
|
||||
strlist_t locusr_orig = locusr;
|
||||
for(; locusr; locusr = locusr->next ) {
|
||||
PKT_secret_key *sk;
|
||||
|
||||
rc = 0;
|
||||
/* Do an early check agains duplicated entries. However this
|
||||
* won't catch all duplicates because the user IDs may be
|
||||
* specified in different ways.
|
||||
*/
|
||||
if ( is_duplicated_entry ( locusr_orig, locusr ) )
|
||||
{
|
||||
log_info (_("skipped \"%s\": duplicated\n"), locusr->d );
|
||||
continue;
|
||||
}
|
||||
sk = xmalloc_clear( sizeof *sk );
|
||||
sk->req_usage = use;
|
||||
if( (rc = get_seckey_byname( sk, locusr->d, 0 )) )
|
||||
{
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
log_error(_("skipped \"%s\": %s\n"),
|
||||
locusr->d, g10_errstr(rc) );
|
||||
write_status_text_and_buffer
|
||||
(STATUS_INV_SGNR, get_inv_recpsgnr_code (rc),
|
||||
locusr->d, strlen (locusr->d), -1);
|
||||
}
|
||||
else if ( key_present_in_sk_list(sk_list, sk) == 0) {
|
||||
free_secret_key(sk); sk = NULL;
|
||||
log_info(_("skipped: secret key already present\n"));
|
||||
}
|
||||
else if ( unlock && (rc = check_secret_key( sk, 0 )) )
|
||||
{
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
log_error(_("skipped \"%s\": %s\n"),
|
||||
locusr->d, g10_errstr(rc) );
|
||||
write_status_text_and_buffer
|
||||
(STATUS_INV_SGNR, get_inv_recpsgnr_code (rc),
|
||||
locusr->d, strlen (locusr->d), -1);
|
||||
}
|
||||
else if( !(rc=openpgp_pk_test_algo2 (sk->pubkey_algo, use)) ) {
|
||||
SK_LIST r;
|
||||
|
||||
if( sk->version == 4 && (use & PUBKEY_USAGE_SIG)
|
||||
&& sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E )
|
||||
{
|
||||
log_info(_("skipped \"%s\": %s\n"),locusr->d,
|
||||
_("this is a PGP generated Elgamal key which"
|
||||
" is not secure for signatures!"));
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
write_status_text_and_buffer
|
||||
(STATUS_INV_SGNR,
|
||||
get_inv_recpsgnr_code (GPG_ERR_WRONG_KEY_USAGE),
|
||||
locusr->d, strlen (locusr->d), -1);
|
||||
}
|
||||
else if( random_is_faked() && !is_insecure( sk ) ) {
|
||||
log_info(_("key is not flagged as insecure - "
|
||||
"can't use it with the faked RNG!\n"));
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
write_status_text_and_buffer
|
||||
(STATUS_INV_SGNR,
|
||||
get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED),
|
||||
locusr->d, strlen (locusr->d), -1);
|
||||
}
|
||||
else {
|
||||
r = xmalloc( sizeof *r );
|
||||
r->sk = sk; sk = NULL;
|
||||
r->next = sk_list;
|
||||
r->mark = 0;
|
||||
sk_list = r;
|
||||
}
|
||||
else if ((err = openpgp_pk_test_algo2 (pk->pubkey_algo, use)))
|
||||
{
|
||||
free_public_key (pk);
|
||||
pk = NULL;
|
||||
log_error ("invalid default secret key: %s\n", gpg_strerror (err));
|
||||
write_status_text (STATUS_INV_SGNR, get_inv_recpsgnr_code (err));
|
||||
}
|
||||
else
|
||||
{
|
||||
SK_LIST r;
|
||||
|
||||
if (random_is_faked () && !is_insecure (pk))
|
||||
{
|
||||
log_info (_("key is not flagged as insecure - "
|
||||
"can't use it with the faked RNG!\n"));
|
||||
free_public_key (pk);
|
||||
pk = NULL;
|
||||
write_status_text (STATUS_INV_SGNR,
|
||||
get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED));
|
||||
}
|
||||
else {
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
log_error("skipped \"%s\": %s\n", locusr->d, g10_errstr(rc) );
|
||||
write_status_text_and_buffer
|
||||
(STATUS_INV_SGNR, get_inv_recpsgnr_code (rc),
|
||||
locusr->d, strlen (locusr->d), -1);
|
||||
else
|
||||
{
|
||||
r = xmalloc (sizeof *r);
|
||||
r->pk = pk;
|
||||
pk = NULL;
|
||||
r->next = sk_list;
|
||||
r->mark = 0;
|
||||
sk_list = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* Check the given user ids. */
|
||||
{
|
||||
strlist_t locusr_orig = locusr;
|
||||
|
||||
for (; locusr; locusr = locusr->next)
|
||||
{
|
||||
PKT_public_key *pk;
|
||||
|
||||
err = 0;
|
||||
/* Do an early check against duplicated entries. However
|
||||
* this won't catch all duplicates because the user IDs may
|
||||
* be specified in different ways. */
|
||||
if (is_duplicated_entry (locusr_orig, locusr))
|
||||
{
|
||||
log_info (_("skipped \"%s\": duplicated\n"), locusr->d);
|
||||
continue;
|
||||
}
|
||||
pk = xmalloc_clear (sizeof *pk);
|
||||
pk->req_usage = use;
|
||||
if ((err = getkey_byname (NULL, pk, locusr->d, 1, NULL)))
|
||||
{
|
||||
free_public_key (pk);
|
||||
pk = NULL;
|
||||
log_error (_("skipped \"%s\": %s\n"),
|
||||
locusr->d, gpg_strerror (err));
|
||||
write_status_text_and_buffer
|
||||
(STATUS_INV_SGNR, get_inv_recpsgnr_code (err),
|
||||
locusr->d, strlen (locusr->d), -1);
|
||||
}
|
||||
else if (!key_present_in_sk_list (sk_list, pk))
|
||||
{
|
||||
free_public_key (pk);
|
||||
pk = NULL;
|
||||
log_info (_("skipped: secret key already present\n"));
|
||||
}
|
||||
/* Fixme: We could change the next test by a call to gpg-agent which
|
||||
would then cache the passphrase. */
|
||||
/* else if (unlock && (rc = check_secret_key (sk, 0))) */
|
||||
/* { */
|
||||
/* free_secret_key (sk); */
|
||||
/* sk = NULL; */
|
||||
/* log_error (_("skipped \"%s\": %s\n"), */
|
||||
/* locusr->d, g10_errstr (rc)); */
|
||||
/* write_status_text_and_buffer */
|
||||
/* (STATUS_INV_SGNR, get_inv_recpsgnr_code (rc), */
|
||||
/* locusr->d, strlen (locusr->d), -1); */
|
||||
/* } */
|
||||
else if ((err = openpgp_pk_test_algo2 (pk->pubkey_algo, use)))
|
||||
{
|
||||
free_public_key (pk);
|
||||
pk = NULL;
|
||||
log_error ("skipped \"%s\": %s\n", locusr->d, gpg_strerror (err));
|
||||
write_status_text_and_buffer
|
||||
(STATUS_INV_SGNR, get_inv_recpsgnr_code (err),
|
||||
locusr->d, strlen (locusr->d), -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SK_LIST r;
|
||||
|
||||
if (pk->version == 4 && (use & PUBKEY_USAGE_SIG)
|
||||
&& pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E)
|
||||
{
|
||||
log_info (_("skipped \"%s\": %s\n"), locusr->d,
|
||||
_("this is a PGP generated Elgamal key which"
|
||||
" is not secure for signatures!"));
|
||||
free_public_key (pk);
|
||||
pk = NULL;
|
||||
write_status_text_and_buffer
|
||||
(STATUS_INV_SGNR,
|
||||
get_inv_recpsgnr_code (GPG_ERR_WRONG_KEY_USAGE),
|
||||
locusr->d, strlen (locusr->d), -1);
|
||||
}
|
||||
else if (random_is_faked () && !is_insecure (pk))
|
||||
{
|
||||
log_info (_("key is not flagged as insecure - "
|
||||
"can't use it with the faked RNG!\n"));
|
||||
free_public_key (pk);
|
||||
pk = NULL;
|
||||
write_status_text_and_buffer
|
||||
(STATUS_INV_SGNR,
|
||||
get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED),
|
||||
locusr->d, strlen (locusr->d), -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = xmalloc (sizeof *r);
|
||||
r->pk = pk;
|
||||
pk = NULL;
|
||||
r->next = sk_list;
|
||||
r->mark = 0;
|
||||
sk_list = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !rc && !sk_list ) {
|
||||
log_error("no valid signators\n");
|
||||
write_status_text (STATUS_NO_SGNR, "0");
|
||||
rc = G10ERR_NO_USER_ID;
|
||||
if (!err && !sk_list)
|
||||
{
|
||||
log_error ("no valid signators\n");
|
||||
write_status_text (STATUS_NO_SGNR, "0");
|
||||
err = gpg_error (GPG_ERR_NO_USER_ID);
|
||||
}
|
||||
|
||||
if( rc )
|
||||
release_sk_list( sk_list );
|
||||
else
|
||||
*ret_sk_list = sk_list;
|
||||
return rc;
|
||||
|
||||
if (err)
|
||||
release_sk_list (sk_list);
|
||||
else
|
||||
*ret_sk_list = sk_list;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* w32-gettext.h - A simple gettext implementation for Windows targets.
|
||||
Copyright (C) 1995, 1996, 1997, 1999, 2005, 2007,
|
||||
2008 Free Software Foundation, Inc.
|
||||
2008, 2010 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public License
|
||||
@ -612,6 +612,7 @@ my_nl_locale_name (const char *categoryname)
|
||||
|
||||
/* Let the user override the system settings through environment
|
||||
variables, as on POSIX systems. */
|
||||
#ifndef HAVE_W32CE_SYSTEM
|
||||
retval = getenv ("LC_ALL");
|
||||
if (retval != NULL && retval[0] != '\0')
|
||||
return retval;
|
||||
@ -621,9 +622,14 @@ my_nl_locale_name (const char *categoryname)
|
||||
retval = getenv ("LANG");
|
||||
if (retval != NULL && retval[0] != '\0')
|
||||
return retval;
|
||||
#endif /*!HAVE_W32CE_SYSTEM*/
|
||||
|
||||
/* Use native Win32 API locale ID. */
|
||||
#ifdef HAVE_W32CE_SYSTEM
|
||||
lcid = GetSystemDefaultLCID ();
|
||||
#else
|
||||
lcid = GetThreadLocale ();
|
||||
#endif
|
||||
|
||||
/* Strip off the sorting rules, keep only the language part. */
|
||||
langid = LANGIDFROMLCID (lcid);
|
||||
@ -1116,14 +1122,15 @@ struct loaded_domain
|
||||
char *data_native; /* Data mapped to the native version of the
|
||||
string. (Allocated along with DATA). */
|
||||
int must_swap;
|
||||
uint32_t nstrings;
|
||||
uint32_t *mapped; /* 0 := Not mapped (original utf8).
|
||||
uint32_t nstrings; /* Number of strings. */
|
||||
uint32_t *mapped; /* Array of mapping indicators:
|
||||
0 := Not mapped (original utf8).
|
||||
1 := Mapped to native encoding in overflow space.
|
||||
>=2 := Mapped to native encoding. The values
|
||||
>=2 := Mapped to native encoding. The value
|
||||
gives the length of the mapped string.
|
||||
becuase the 0 is included and an empty
|
||||
string is not allowed we will enver get
|
||||
values 0 and 1. */
|
||||
Because the terminating nul is included
|
||||
in the length and an empty string is
|
||||
not allowed, values are always > 1. */
|
||||
struct overflow_space_s *overflow_space;
|
||||
struct string_desc *orig_tab;
|
||||
struct string_desc *trans_tab;
|
||||
@ -1366,7 +1373,7 @@ bindtextdomain (const char *domainname, const char *dirname)
|
||||
catval = NULL;
|
||||
catval_full = my_nl_locale_name ("LC_MESSAGES");
|
||||
|
||||
/* Normally, we would have to loop over all returned locales, and
|
||||
/* Normally we would have to loop over all returned locales and
|
||||
search for the right file. See gettext intl/dcigettext.c for all
|
||||
the gory details. Here, we only support the basic category, and
|
||||
ignore everything else. */
|
||||
@ -1389,8 +1396,8 @@ bindtextdomain (const char *domainname, const char *dirname)
|
||||
/* Now build the filename string. The complete filename is this:
|
||||
DIRNAME + \ + CATVAL + \LC_MESSAGES\ + DOMAINNAME + .mo */
|
||||
{
|
||||
int len = strlen (dirname) + 1 + strlen (catval) + 13
|
||||
+ strlen (domainname) + 3 + 1;
|
||||
int len = (strlen (dirname) + 1 + strlen (catval) + 13
|
||||
+ strlen (domainname) + 3 + 1);
|
||||
char *p;
|
||||
|
||||
fname = jnlib_malloc (len);
|
||||
@ -1497,9 +1504,9 @@ get_string (struct loaded_domain *domain, uint32_t idx,
|
||||
else
|
||||
{
|
||||
/* There is not enough space for the translation (or for
|
||||
whatever reason an empry string is used): Store it in the
|
||||
whatever reason an empty string is used): Store it in the
|
||||
overflow_space and mark that in the mapped array.
|
||||
Because UTF-8 strings are in general longer than the
|
||||
Because UTF-8 strings are in general shorter than the
|
||||
Windows 2 byte encodings, we expect that this won't
|
||||
happen too often (if at all) and thus we use a linked
|
||||
list to manage this space. */
|
||||
|
@ -1428,7 +1428,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
|
||||
if (p)
|
||||
{
|
||||
rc = gpgsm_agent_havekey (ctrl, p);
|
||||
if (!rc)
|
||||
if (!rc)
|
||||
have_secret = 1;
|
||||
else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
|
||||
goto leave;
|
||||
|
@ -1,3 +1,7 @@
|
||||
2010-01-10 Werner Koch <wk@g10code.com>
|
||||
|
||||
* symcryptrun.c (utmp.h): Remove header; it is not used.
|
||||
|
||||
2009-12-18 Werner Koch <wk@g10code.com>
|
||||
|
||||
* applygnupgdefaults (errorfile): Use mktemp. Fixes bug#1146.
|
||||
|
@ -74,7 +74,6 @@
|
||||
#ifdef HAVE_PTY_H
|
||||
#include <pty.h>
|
||||
#endif
|
||||
#include <utmp.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
|
Loading…
x
Reference in New Issue
Block a user