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:
Werner Koch 2010-02-02 14:06:19 +00:00
parent 7e97da9127
commit 8459bcf95a
23 changed files with 1123 additions and 1082 deletions

View File

@ -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

View File

@ -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.

View File

@ -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 ();
}

View File

@ -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 )

View File

@ -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*/

View File

@ -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

View File

@ -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;

View File

@ -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 );

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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));

View File

@ -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 );

View File

@ -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);

View File

@ -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 );

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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. */

View File

@ -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;

View File

@ -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.

View File

@ -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>