aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/ChangeLog21
-rw-r--r--g10/Makefile.am2
-rw-r--r--g10/gpg.c8
-rw-r--r--g10/keydb.h13
-rw-r--r--g10/parse-packet.c14
-rw-r--r--g10/pkclist.c21
-rw-r--r--g10/sign.c101
7 files changed, 115 insertions, 65 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 2fba9c488..7f204cde9 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,24 @@
+2006-07-27 Werner Koch <[email protected]>
+
+ * parse-packet.c (parse_comment): Cap comments at 65k.
+ (parse_gpg_control): Skip too large control packets.
+
+2006-07-24 David Shaw <[email protected]> (wk)
+
+ * keydb.h, pkclist.c (select_algo_from_prefs, algo_available):
+ Pass a union for preference hints rather than doing void * games.
+
+ * sign.c (sign_file): Use it here.
+
+ * sign.c (sign_file): When signing with multiple DSA keys, one
+ being DSA1 and one being DSA2 and encrypting at the same time, if
+ the recipient preferences give a hash that can work with the DSA2
+ key, then allow the DSA1 key to be promoted rather than giving up
+ and using hash_for().
+
+ * pkclist.c (algo_available): Automatically enable DSA2 mode when
+ handling a key that clearly isn't DSA1 (i.e. q!=160).
+
2006-06-30 Werner Koch <[email protected]>
* misc.c (checksum_mpi): No need for nbits as they are alredy
diff --git a/g10/Makefile.am b/g10/Makefile.am
index fb54dd9f0..a9847cfa7 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -27,7 +27,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common \
include $(top_srcdir)/am/cmacros.am
-AM_CFLAGS = $(LIBGCRYPT_CFLAGS) -Wno-pointer-sign
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS)
needed_libs = ../gl/libgnu.a ../common/libcommon.a ../jnlib/libjnlib.a
diff --git a/g10/gpg.c b/g10/gpg.c
index c1a0be50f..c558b7246 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -357,7 +357,6 @@ enum cmd_and_opt_values
oAllowMultisigVerification,
oEnableDSA2,
oDisableDSA2,
- oDebugAllowRun,
oNoop
};
@@ -705,7 +704,6 @@ static ARGPARSE_OPTS opts[] = {
{ oAutoKeyLocate, "auto-key-locate", 2, "@"},
{ oNoAutoKeyLocate, "no-auto-key-locate", 0, "@"},
- { oDebugAllowRun, "debug_allow_run", 0, "@"},
{0,NULL,0,NULL}
};
@@ -1761,7 +1759,6 @@ main (int argc, char **argv )
int with_fpr = 0; /* make an option out of --fingerprint */
int any_explicit_recipient = 0;
int require_secmem=0,got_secmem=0;
- int allow_run = 0;
#ifdef __riscos__
opt.lock_once = 1;
@@ -2754,8 +2751,6 @@ main (int argc, char **argv )
case oEnableDSA2: opt.flags.dsa2=1; break;
case oDisableDSA2: opt.flags.dsa2=0; break;
- case oDebugAllowRun: allow_run = 1; break;
-
case oNoop: break;
default : pargs.err = configfp? 1:2; break;
@@ -2809,8 +2804,7 @@ main (int argc, char **argv )
}
#endif
- if (!allow_run)
- log_fatal ("This version of gpg is not ready for use, use gpg 1.4.x\n");
+ log_info ("WARNING: This version of gpg is not ready for use, use gpg 1.4.x\n");
/* FIXME: We should use logging to a file only in server mode;
however we have not yet implemetyed that. Thus we try to get
diff --git a/g10/keydb.h b/g10/keydb.h
index f8be6efb9..2aab31cfa 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -144,6 +144,14 @@ struct keydb_search_desc {
int exact;
};
+
+/* Helper type for preference fucntions. */
+union pref_hint
+{
+ int digest_length;
+};
+
+
/*-- keydb.c --*/
/*
@@ -175,9 +183,10 @@ void show_revocation_reason( PKT_public_key *pk, int mode );
int check_signatures_trust( PKT_signature *sig );
void release_pk_list( PK_LIST pk_list );
int build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use );
-int algo_available( preftype_t preftype, int algo, void *hint );
+int algo_available( preftype_t preftype, int algo,
+ const union pref_hint *hint );
int select_algo_from_prefs( PK_LIST pk_list, int preftype,
- int request, void *hint );
+ int request, const union pref_hint *hint);
int select_mdc_from_pklist (PK_LIST pk_list);
/*-- skclist.c --*/
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index d9a87f108..33472da4d 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -2147,6 +2147,16 @@ parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
{
byte *p;
+ /* Cap comment packet at a reasonable value to avoid an integer
+ overflow in the malloc below. Comment packets are actually not
+ anymore define my OpenPGP and we even stopped to use our
+ private comment packet. */
+ if (pktlen>65536)
+ {
+ log_error ("packet(%d) too large\n", pkttype);
+ iobuf_skip_rest (inp, pktlen, 0);
+ return G10ERR_INVALID_PACKET;
+ }
packet->pkt.comment = xmalloc(sizeof *packet->pkt.comment + pktlen - 1);
packet->pkt.comment->len = pktlen;
p = packet->pkt.comment->data;
@@ -2220,6 +2230,7 @@ parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
}
mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
+ /* Note that namelen will never exceed 255 bytes. */
pt = pkt->pkt.plaintext = xmalloc(sizeof *pkt->pkt.plaintext + namelen -1);
pt->new_ctb = new_ctb;
pt->mode = mode;
@@ -2399,6 +2410,9 @@ parse_gpg_control( IOBUF inp, int pkttype,
if ( sesmark[i] != iobuf_get_noeof(inp) )
goto skipit;
}
+ if (pktlen > 4096)
+ goto skipit; /* Definitely too large. We skip it to avoid an
+ overflow in the malloc. */
if ( list_mode )
puts ("- gpg control packet");
diff --git a/g10/pkclist.c b/g10/pkclist.c
index d3cda144f..f90137aff 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -1186,7 +1186,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use )
preference list, so I'm including it. -dms */
int
-algo_available( preftype_t preftype, int algo, void *hint )
+algo_available( preftype_t preftype, int algo, const union pref_hint *hint)
{
if( preftype == PREFTYPE_SYM )
{
@@ -1210,18 +1210,18 @@ algo_available( preftype_t preftype, int algo, void *hint )
}
else if( preftype == PREFTYPE_HASH )
{
- if(hint)
+ if (hint && hint->digest_length)
{
- if(opt.flags.dsa2)
+ if (hint->digest_length!=20 || opt.flags.dsa2)
{
- /* If --enable-dsa2 is set, then we'll accept a hash
- that is larger than we need. If --enable-dsa2 is not
- set, then we won't accept any hash that isn't exactly
- the right size. */
- if ((*(int *)hint) > gcry_md_get_algo_dlen (algo))
+ /* If --enable-dsa2 is set or the hash isn't 160 bits
+ (which implies DSA2), then we'll accept a hash that
+ is larger than we need. Otherwise we won't accept
+ any hash that isn't exactly the right size. */
+ if (hint->digest_length > gcry_md_get_algo_dlen (algo))
return 0;
}
- else if (((*(int *)hint) != gcry_md_get_algo_dlen (algo)))
+ else if (hint->digest_length != gcry_md_get_algo_dlen (algo))
return 0;
}
@@ -1259,7 +1259,8 @@ algo_available( preftype_t preftype, int algo, void *hint )
* Return -1 if we could not find an algorithm.
*/
int
-select_algo_from_prefs(PK_LIST pk_list, int preftype, int request, void *hint)
+select_algo_from_prefs(PK_LIST pk_list, int preftype, int request,
+ const union pref_hint *hint)
{
PK_LIST pkr;
u32 bits[8];
diff --git a/g10/sign.c b/g10/sign.c
index 0538f0020..7b6a81e10 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -320,27 +320,6 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
}
else
{
-#if 0 /* disabled *.
- /* Disabled for now. It seems reasonable to accept a
- truncated hash for a DSA1 key, even though we don't
- generate it without --enable-dsa2. Be liberal in what you
- accept, etc. */
-
- /* If it's a DSA key, and q is 160 bits, it might be an
- old-style DSA key. If the hash doesn't match the q, fail
- unless --enable-dsa2 is set. If the q isn't 160 bits, then
- allow any hash since it must be a DSA2 key (if the hash is
- too small, we'll fail in encode_md_value). */
- if (sk->pubkey_algo==PUBKEY_ALGO_DSA
- && (gcry_mpi_get_nbits (sk->skey[1])/8)==20
- && !opt.flags.dsa2
- && gcry_md_get_algo_dlen (digest_algo)!=20)
- {
- log_error(_("DSA requires the use of a 160 bit hash algorithm\n"));
- return G10ERR_GENERAL;
- }
-#endif /* disabled */
-
frame = encode_md_value( NULL, sk, md, digest_algo );
if (!frame)
return G10ERR_GENERAL;
@@ -869,8 +848,13 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
if (DBG_HASHING)
gcry_md_start_debug (mfx.md, "sign");
- /* If we're encrypting and signing, it is reasonable to pick the
- hash algorithm to use out of the recepient key prefs. */
+ /* If we're encrypting and signing, it is reasonable to pick the
+ hash algorithm to use out of the recepient key prefs. This is
+ best effort only, as in a DSA2 and smartcard world there are
+ cases where we cannot please everyone with a single hash (DSA2
+ wants >160 and smartcards want =160). In the future this could
+ be more complex with different hashes for each sk, but the
+ current design requires a single hash for all SKs. */
if(pk_list)
{
if(opt.def_digest_algo)
@@ -886,30 +870,57 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
}
else
{
- int hashlen=0,algo;
+ int algo, smartcard=0;
+ union pref_hint hint;
+
+ hint.digest_length = 0;
/* Of course, if the recipient asks for something
- unreasonable (like a non-160-bit hash for DSA, for
- example), then don't do it. Check all sk's - if any
- are DSA, then the hash must be 160-bit. In the future
- this can be more complex with different hashes for each
- sk, but so long as there is only one signing algorithm
- with hash restrictions, this is ok. -dms */
-
- /* Current smartcards only do 160-bit hashes as well.
- Note that this may well have to change as the cards add
- algorithms. */
-
- for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
- if(sk_rover->sk->pubkey_algo==PUBKEY_ALGO_DSA
- || (sk_rover->sk->is_protected
- && sk_rover->sk->protect.s2k.mode==1002))
- hashlen=20;
-
- if((algo=
- select_algo_from_prefs(pk_list,PREFTYPE_HASH,-1,
- hashlen?&hashlen:NULL))>0)
- recipient_digest_algo=algo;
+ unreasonable (like the wrong hash for a DSA key) then
+ don't do it. Check all sk's - if any are DSA or live
+ on a smartcard, then the hash has restrictions and we
+ may not be able to give the recipient what they want.
+ For DSA, pass a hint for the largest q we have. Note
+ that this means that a q>160 key will override a q=160
+ key and force the use of truncation for the q=160 key.
+ The alternative would be to ignore the recipient prefs
+ completely and get a different hash for each DSA key in
+ hash_for(). The override behavior here is more or less
+ reasonable as it is under the control of the user which
+ keys they sign with for a given message and the fact
+ that the message with multiple signatures won't be
+ usable on an implementation that doesn't understand
+ DSA2 anyway. */
+
+ for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
+ {
+ if (sk_rover->sk->pubkey_algo == PUBKEY_ALGO_DSA)
+ {
+ int temp_hashlen = gcry_mpi_get_nbits
+ (sk_rover->sk->skey[1])+7/8;
+
+ /* Pick a hash that is large enough for our
+ largest q */
+
+ 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;
+ }
+
+ /* Current smartcards only do 160-bit hashes. If we have
+ to have a >160-bit hash, then we can't use the
+ recipient prefs as we'd need both =160 and >160 at the
+ same time and recipient prefs currently require a
+ single hash for all signatures. All this may well have
+ to change as the cards add algorithms. */
+
+ if (!smartcard || (smartcard && hint.digest_length==20))
+ if ( (algo=
+ select_algo_from_prefs(pk_list,PREFTYPE_HASH,-1,&hint)) > 0)
+ recipient_digest_algo=algo;
}
}