diff --git a/g10/ChangeLog b/g10/ChangeLog index 23b254ef2..22d239715 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,5 +1,19 @@ 2008-12-09 Werner Koch + * keygen.c (proc_parameter_file): Check that key and subkey usages + are allowed. + +2008-12-09 David Shaw (wk) + + * trustdb.c (validate_one_keyblock): Fix the trust signature + calculations so that we lower the trust depth of signatures to fit + within the current chain, rather than discarding any signature + that does not fit within the trust depth. + +2008-12-09 Werner Koch + + * keyserver.c (show_prompt): Flush stdout. + * gpg.c (open_info_file): Add arg BINARY and adjust callers. * gpg.c (main): Call i18n_init before init_common_subsystems. diff --git a/g10/keygen.c b/g10/keygen.c index 675acf603..f0de2fbf3 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2287,7 +2287,8 @@ get_parameter_algo( struct para_data_s *para, enum para_name key ) } /* - * parse the usage parameter and set the keyflags. Return true on error. + * Parse the usage parameter and set the keyflags. Returns -1 on + * error, 0 for no usage given or 1 for usage available. */ static int parse_parameter_usage (const char *fname, @@ -2435,54 +2436,75 @@ proc_parameter_file( struct para_data_s *para, const char *fname, algo=get_parameter_algo(para,pKEYTYPE); if (openpgp_pk_test_algo2 (algo, PUBKEY_USAGE_SIG)) { - log_error("%s:%d: invalid algorithm\n", fname, r->lnr ); + log_error ("%s:%d: invalid algorithm\n", fname, r->lnr ); return -1; } } else { - log_error("%s: no Key-Type specified\n",fname); + log_error ("%s: no Key-Type specified\n",fname); return -1; } - err=parse_parameter_usage (fname, para, pKEYUSAGE); - if(err==0) + err = parse_parameter_usage (fname, para, pKEYUSAGE); + if (!err) { /* Default to algo capabilities if key-usage is not provided */ - r=xmalloc_clear(sizeof(*r)); - r->key=pKEYUSAGE; - r->u.usage=openpgp_pk_algo_usage(algo); - r->next=para; - para=r; + r = xmalloc_clear(sizeof(*r)); + r->key = pKEYUSAGE; + r->u.usage = openpgp_pk_algo_usage(algo); + r->next = para; + para = r; } - else if(err==-1) + else if (err == -1) return -1; + else + { + r = get_parameter (para, pKEYUSAGE); + if (r && (r->u.usage & ~openpgp_pk_algo_usage (algo))) + { + log_error ("%s:%d: specified Key-Usage not allowed for algo %d\n", + fname, r->lnr, algo); + return -1; + } + } r = get_parameter( para, pSUBKEYTYPE ); if(r) { - algo=get_parameter_algo( para, pSUBKEYTYPE); + algo = get_parameter_algo (para, pSUBKEYTYPE); if (openpgp_pk_test_algo (algo)) { - log_error("%s:%d: invalid algorithm\n", fname, r->lnr ); + log_error ("%s:%d: invalid algorithm\n", fname, r->lnr ); return -1; } - err=parse_parameter_usage (fname, para, pSUBKEYUSAGE); - if(err==0) + err = parse_parameter_usage (fname, para, pSUBKEYUSAGE); + if (!err) { /* Default to algo capabilities if subkey-usage is not provided */ - r=xmalloc_clear(sizeof(*r)); - r->key=pSUBKEYUSAGE; - r->u.usage=openpgp_pk_algo_usage(algo); - r->next=para; - para=r; + r = xmalloc_clear (sizeof(*r)); + r->key = pSUBKEYUSAGE; + r->u.usage = openpgp_pk_algo_usage (algo); + r->next = para; + para = r; } - else if(err==-1) + else if (err == -1) return -1; + else + { + r = get_parameter (para, pSUBKEYUSAGE); + if (r && (r->u.usage & ~openpgp_pk_algo_usage (algo))) + { + log_error ("%s:%d: specified Subkey-Usage not allowed" + " for algo %d\n", fname, r->lnr, algo); + return -1; + } + } } + if( get_parameter_value( para, pUSERID ) ) have_user_id=1; else diff --git a/g10/keyserver.c b/g10/keyserver.c index a54f2d11c..f63ff8b83 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -731,6 +731,8 @@ show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search) { char *answer; + fflush (stdout); + if(count && opt.command_fd==-1) { static int from=1; diff --git a/g10/trustdb.c b/g10/trustdb.c index 265b8830d..902089c2d 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1,6 +1,6 @@ /* trustdb.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - * 2007 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, + * 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1935,54 +1935,78 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist, did not exist. This is safe for non-trust sigs as well since we don't accept a regexp on the sig unless it's a trust sig. */ - if (kr && (kr->trust_regexp==NULL || opt.trust_model!=TM_PGP || - (uidnode && check_regexp(kr->trust_regexp, - uidnode->pkt->pkt.user_id->name)))) + if (kr && (!kr->trust_regexp + || opt.trust_model != TM_PGP + || (uidnode + && check_regexp(kr->trust_regexp, + uidnode->pkt->pkt.user_id->name)))) { - if(DBG_TRUST && opt.trust_model==TM_PGP && sig->trust_depth) - log_debug("trust sig on %s, sig depth is %d, kr depth is %d\n", - uidnode->pkt->pkt.user_id->name,sig->trust_depth, - kr->trust_depth); - /* Are we part of a trust sig chain? We always favor the latest trust sig, rather than the greater or lesser trust sig or value. I could make a decent argument for any of these cases, but this seems to be what PGP does, and I'd like to be compatible. -dms */ - if(opt.trust_model==TM_PGP && sig->trust_depth - && pk->trust_timestamp<=sig->timestamp - && (sig->trust_depth<=kr->trust_depth - || kr->ownertrust==TRUST_ULTIMATE)) + if (opt.trust_model == TM_PGP + && sig->trust_depth + && pk->trust_timestamp <= sig->timestamp) { - /* If we got here, we know that: + unsigned char depth; - this is a trust sig. + /* If the depth on the signature is less than the + chain currently has, then use the signature depth + so we don't increase the depth beyond what the + signer wanted. If the depth on the signature is + more than the chain currently has, then use the + chain depth so we use as much of the signature + depth as the chain will permit. An ultimately + trusted signature can restart the depth to + whatever level it likes. */ - it's a newer trust sig than any previous trust - sig on this key (not uid). + if (sig->trust_depth < kr->trust_depth + || kr->ownertrust == TRUST_ULTIMATE) + depth = sig->trust_depth; + else + depth = kr->trust_depth; - it is legal in that it was either generated by an - ultimate key, or a key that was part of a trust - chain, and the depth does not violate the - original trust sig. + if (depth) + { + if(DBG_TRUST) + log_debug ("trust sig on %s, sig depth is %d," + " kr depth is %d\n", + uidnode->pkt->pkt.user_id->name, + sig->trust_depth, + kr->trust_depth); - if there is a regexp attached, it matched - successfully. - */ + /* If we got here, we know that: - if(DBG_TRUST) - log_debug("replacing trust value %d with %d and " - "depth %d with %d\n", - pk->trust_value,sig->trust_value, - pk->trust_depth,sig->trust_depth); + this is a trust sig. - pk->trust_value=sig->trust_value; - pk->trust_depth=sig->trust_depth-1; + it's a newer trust sig than any previous trust + sig on this key (not uid). - /* If the trust sig contains a regexp, record it - on the pk for the next round. */ - if(sig->trust_regexp) - pk->trust_regexp=sig->trust_regexp; + it is legal in that it was either generated by an + ultimate key, or a key that was part of a trust + chain, and the depth does not violate the + original trust sig. + + if there is a regexp attached, it matched + successfully. + */ + + if (DBG_TRUST) + log_debug ("replacing trust value %d with %d and " + "depth %d with %d\n", + pk->trust_value,sig->trust_value, + pk->trust_depth,depth); + + pk->trust_value = sig->trust_value; + pk->trust_depth = depth-1; + + /* If the trust sig contains a regexp, record it + on the pk for the next round. */ + if (sig->trust_regexp) + pk->trust_regexp = sig->trust_regexp; + } } if (kr->ownertrust == TRUST_ULTIMATE)