Merged recent changes from 1.4

This commit is contained in:
Werner Koch 2006-04-28 14:31:29 +00:00
parent 4459fcb032
commit 00ffc478de
15 changed files with 341 additions and 148 deletions

View File

@ -1,3 +1,59 @@
2006-04-28 David Shaw <dshaw@jabberwocky.com> (wk)
* keyserver.c (direct_uri_map): New.
(keyserver_spawn): Used here to add "_uri" to certain gpgkeys_xxx
helpers when the meaning is different if a path is provided (i.e.
ldap).
(keyserver_import_cert): Show warning if there is a CERT
fingerprint, but no --keyserver set.
* keyserver.c: Fix build problem with platforms that stick libcurl
in a place not in the regular include search path.
* options.h, gpg.c (main): Add --enable-dsa2 and --disable-dsa2.
Defaults to disable.
* pkclist.c (algo_available): If --enable-dsa2 is set, we're
allowed to truncate hashes to fit DSA keys.
* sign.c (match_dsa_hash): New. Return the best match hash for a
given q size.
(do_sign, hash_for, sign_file): When signing with a DSA key, if it
has q==160, assume it is an old DSA key and don't allow truncation
unless --enable-dsa2 is also set. q!=160 always allows truncation
since they must be DSA2 keys.
(make_keysig_packet): If the user doesn't specify a
--cert-digest-algo, use match_dsa_hash to pick the best hash for
key signatures.
* gpg.c (print_mds): Add SHA-224.
* armor.c (armor_filter, parse_hash_header): Add SHA-224.
* sign.c (write_plaintext_packet):
Factor common literal packet setup code from here, to...
* encode.c (encode_simple): .. there.
* main.h, plaintext.c (setup_plaintext_name): Here. New. Make sure
the literal packet filename field is UTF-8 encoded.
* options.h, gpg.c (main): Make sure --set-filename is UTF-8
encoded and note when filenames are already UTF-8.
* keyedit.c (menu_backsign): Give some more verbose errors when we
have no need to backsign.
* getkey.c (parse_auto_key_locate): Fix dupe-removal code.
* keyedit.c (menu_backsign): Allow backsigning even if the secret
subkey doesn't have a binding signature.
* armor.c (radix64_read): Don't report EOF when reading only a pad
(=) character. The EOF actually starts after the pad.
* gpg.c (main): Make --export, --send-keys, --recv-keys,
--refresh-keys, and --fetch-keys follow their arguments from left
to right. Suggested by Peter Palfrader.
2006-04-18 Werner Koch <wk@g10code.com>
* tdbio.c (open_db, migrate_from_v2): Removed feature to migration

View File

@ -1,6 +1,6 @@
/* armor.c - Armor flter
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
* 2005 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
* 2006 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -242,12 +242,14 @@ parse_hash_header( const char *line )
found |= 2;
else if( !strncmp( s, "MD5", s2-s ) )
found |= 4;
else if( !strncmp( s, "SHA256", s2-s ) )
else if( !strncmp( s, "SHA224", s2-s ) )
found |= 8;
else if( !strncmp( s, "SHA384", s2-s ) )
else if( !strncmp( s, "SHA256", s2-s ) )
found |= 16;
else if( !strncmp( s, "SHA512", s2-s ) )
else if( !strncmp( s, "SHA384", s2-s ) )
found |= 32;
else if( !strncmp( s, "SHA512", s2-s ) )
found |= 64;
else
return 0;
for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
@ -676,7 +678,7 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
int checkcrc=0;
int rc = 0;
size_t n = 0;
int idx, i;
int idx, i, onlypad=0;
u32 crc;
crc = afx->crc;
@ -720,6 +722,8 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
goto again;
}
}
else if(n==0)
onlypad=1;
if( idx == 1 )
buf[n++] = val;
@ -848,7 +852,7 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
}
}
if( !n )
if( !n && !onlypad )
rc = -1;
*retn = n;
@ -951,10 +955,12 @@ armor_filter( void *opaque, int control,
if( hashes & 4 )
buf[n++] = DIGEST_ALGO_MD5;
if( hashes & 8 )
buf[n++] = DIGEST_ALGO_SHA256;
buf[n++] = DIGEST_ALGO_SHA224;
if( hashes & 16 )
buf[n++] = DIGEST_ALGO_SHA384;
buf[n++] = DIGEST_ALGO_SHA256;
if( hashes & 32 )
buf[n++] = DIGEST_ALGO_SHA384;
if( hashes & 64 )
buf[n++] = DIGEST_ALGO_SHA512;
buf[1] = n - 2;

View File

@ -1,6 +1,6 @@
/* encode.c - encode data
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
* 2005 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
* 2006 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -278,22 +278,8 @@ encode_simple( const char *filename, int mode, int use_seskey )
xfree(enc);
}
if (!opt.no_literal) {
/* setup the inner packet */
if( filename || opt.set_filename ) {
char *s = make_basename( opt.set_filename ? opt.set_filename
: filename,
iobuf_get_real_fname( inp ) );
pt = xmalloc( sizeof *pt + strlen(s) - 1 );
pt->namelen = strlen(s);
memcpy(pt->name, s, pt->namelen );
xfree(s);
}
else { /* no filename */
pt = xmalloc( sizeof *pt - 1 );
pt->namelen = 0;
}
}
if (!opt.no_literal)
pt=setup_plaintext_name(filename,inp);
/* Note that PGP 5 has problems decrypting symmetrically encrypted
data if the file length is in the inner packet. It works when

View File

@ -2948,7 +2948,7 @@ parse_auto_key_locate(char *options)
while((tok=optsep(&options)))
{
struct akl *akl,*last;
struct akl *akl,*check,*last=NULL;
int dupe=0;
if(tok[0]=='\0')
@ -2977,13 +2977,13 @@ parse_auto_key_locate(char *options)
}
/* We must maintain the order the user gave us */
for(last=opt.auto_key_locate;last && last->next;last=last->next)
for(check=opt.auto_key_locate;check;last=check,check=check->next)
{
/* Check for duplicates */
if(last && last->type==akl->type
if(check->type==akl->type
&& (akl->type!=AKL_SPEC
|| (akl->type==AKL_SPEC
&& strcmp(last->spec->uri,akl->spec->uri)==0)))
&& strcmp(check->spec->uri,akl->spec->uri)==0)))
{
dupe=1;
free_akl(akl);

View File

@ -354,6 +354,8 @@ enum cmd_and_opt_values
oAutoKeyLocate,
oNoAutoKeyLocate,
oAllowMultisigVerification,
oEnableDSA2,
oDisableDSA2,
oNoop
};
@ -684,6 +686,8 @@ static ARGPARSE_OPTS opts[] = {
{ oLimitCardInsertTries, "limit-card-insert-tries", 1, "@"},
{ oAllowMultisigVerification, "allow-multisig-verification", 0, "@"},
{ oEnableDSA2, "enable-dsa2", 0, "@"},
{ oDisableDSA2, "disable-dsa2", 0, "@"},
/* These two are aliases to help users of the PGP command line
product use gpg with minimal pain. Many commands are common
@ -2169,7 +2173,12 @@ main (int argc, char **argv )
case oCompressSigs: opt.compress_sigs = 1; break;
case oRFC2440Text: opt.rfc2440_text=1; break;
case oNoRFC2440Text: opt.rfc2440_text=0; break;
case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
case oSetFilename:
if(utf8_strings)
opt.set_filename = pargs.r.ret_str;
else
opt.set_filename = native_to_utf8(pargs.r.ret_str);
break;
case oForYourEyesOnly: eyes_only = 1; break;
case oNoForYourEyesOnly: eyes_only = 0; break;
case oSetPolicyURL:
@ -2195,8 +2204,12 @@ main (int argc, char **argv )
opt.verify_options&=~VERIFY_SHOW_POLICY_URLS;
break;
case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break;
case oNoUseEmbeddedFilename: opt.use_embedded_filename = 0; break;
case oUseEmbeddedFilename:
opt.flags.use_embedded_filename=1;
break;
case oNoUseEmbeddedFilename:
opt.flags.use_embedded_filename=0;
break;
case oComment:
if(pargs.r.ret_str[0])
append_to_strlist(&opt.comments,pargs.r.ret_str);
@ -2639,6 +2652,9 @@ main (int argc, char **argv )
opt.allow_multisig_verification = 1;
break;
case oEnableDSA2: opt.flags.dsa2=1; break;
case oDisableDSA2: opt.flags.dsa2=0; break;
case oNoop: break;
default : pargs.err = configfp? 1:2; break;
@ -3086,6 +3102,9 @@ main (int argc, char **argv )
fname = argc? *argv : NULL;
if(fname && utf8_strings)
opt.flags.utf8_filename=1;
switch( cmd ) {
case aPrimegen:
case aPrintMD:
@ -3390,12 +3409,17 @@ main (int argc, char **argv )
import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
break;
/* TODO: There are a number of command that use this same
"make strlist, call function, report error, free strlist"
pattern. Join them together here and avoid all that
duplicated code. */
case aExport:
case aSendKeys:
case aRecvKeys:
sl = NULL;
for( ; argc; argc--, argv++ )
add_to_strlist2( &sl, *argv, utf8_strings );
append_to_strlist2( &sl, *argv, utf8_strings );
if( cmd == aSendKeys )
rc=keyserver_export( sl );
else if( cmd == aRecvKeys )
@ -3427,7 +3451,7 @@ main (int argc, char **argv )
case aRefreshKeys:
sl = NULL;
for( ; argc; argc--, argv++ )
add_to_strlist2( &sl, *argv, utf8_strings );
append_to_strlist2( &sl, *argv, utf8_strings );
rc=keyserver_refresh(sl);
if(rc)
log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
@ -3437,7 +3461,7 @@ main (int argc, char **argv )
case aFetchKeys:
sl = NULL;
for( ; argc; argc--, argv++ )
add_to_strlist2( &sl, *argv, utf8_strings );
append_to_strlist2( &sl, *argv, utf8_strings );
rc=keyserver_fetch(sl);
if(rc)
log_error("key fetch failed: %s\n",g10_errstr(rc));
@ -3913,6 +3937,7 @@ print_mds( const char *fname, int algo )
gcry_md_enable (md, GCRY_MD_SHA1);
gcry_md_enable (md, GCRY_MD_RMD160);
#ifdef USE_SHA256
gcry_md_enable (md, DIGEST_ALGO_SHA224);
gcry_md_enable (md, GCRY_MD_SHA256);
#endif
#ifdef USE_SHA512
@ -3935,6 +3960,8 @@ print_mds( const char *fname, int algo )
print_hashline( md, GCRY_MD_SHA1, fname );
print_hashline( md, GCRY_MD_RMD160, fname );
#ifdef USE_SHA256
if (!gcry_md_test_algo (DIGEST_ALGO_SHA224)
print_hashline (md, DIGEST_ALGO_SHA224, fname);
print_hashline( md, GCRY_MD_SHA256, fname );
#endif
#ifdef USE_SHA512
@ -3951,6 +3978,8 @@ print_mds( const char *fname, int algo )
print_hex( md, GCRY_MD_SHA1, fname );
print_hex( md, GCRY_MD_RMD160, fname );
#ifdef USE_SHA256
if (!gcry_md_test_algo (DIGEST_ALGO_SHA224)
print_hex (md, DIGEST_ALGO_SHA224, fname);
print_hex( md, GCRY_MD_SHA256, fname );
#endif
#ifdef USE_SHA512

View File

@ -3661,10 +3661,21 @@ menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
}
/* Find a signing subkey with no backsig */
if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY
&& (node->pkt->pkt.public_key->pubkey_usage&PUBKEY_USAGE_SIG)
&& !node->pkt->pkt.public_key->backsig)
sub_pk=node->pkt->pkt.public_key;
if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
{
if(node->pkt->pkt.public_key->pubkey_usage&PUBKEY_USAGE_SIG)
{
if(node->pkt->pkt.public_key->backsig)
tty_printf(_("signing subkey %s is already cross-certified\n"),
keystr_from_pk(node->pkt->pkt.public_key));
else
sub_pk=node->pkt->pkt.public_key;
}
else
tty_printf(_("subkey %s does not sign and so does"
" not need to be cross-certified\n"),
keystr_from_pk(node->pkt->pkt.public_key));
}
if(!sub_pk)
continue;
@ -3693,7 +3704,11 @@ menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
}
if(!sub_sk)
continue;
{
tty_printf(_("no secret subkey for public subkey %s - ignoring\n"),
keystr_from_pk(sub_pk));
continue;
}
/* Now finally find the matching selfsig on the secret subkey.
We can't use chosen_selfsig here (it's not set for secret
@ -3712,11 +3727,8 @@ menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
break;
}
if(!sig_sk)
continue;
/* Now we can get to work. We have a main key and secret part,
a signing subkey with signature and secret part with
a signing subkey with signature and secret part possibly with
signature. */
passphrase=get_last_passphrase();
@ -3745,13 +3757,16 @@ menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
xfree(sig_pk->pkt);
sig_pk->pkt=newpkt;
/* Put the new sig into place on the seckey */
newpkt=xmalloc_clear(sizeof(*newpkt));
newpkt->pkttype=PKT_SIGNATURE;
newpkt->pkt.signature=copy_signature(NULL,newsig);
free_packet(sig_sk->pkt);
xfree(sig_sk->pkt);
sig_sk->pkt=newpkt;
if(sig_sk)
{
/* Put the new sig into place on the seckey */
newpkt=xmalloc_clear(sizeof(*newpkt));
newpkt->pkttype=PKT_SIGNATURE;
newpkt->pkt.signature=copy_signature(NULL,newsig);
free_packet(sig_sk->pkt);
xfree(sig_sk->pkt);
sig_sk->pkt=newpkt;
}
modified=1;
}

View File

@ -341,7 +341,7 @@ keygen_set_std_prefs (const char *string,int personal)
/* SHA-1 */
strcat(dummy_string,"H2 ");
if(!check_digest_algo(DIGEST_ALGO_SHA256))
if (!openpgp_md_test_algo(DIGEST_ALGO_SHA256))
strcat(dummy_string,"H8 ");
/* RIPEMD160 */
@ -370,12 +370,12 @@ keygen_set_std_prefs (const char *string,int personal)
while((tok=strsep(&prefstring," ,")))
{
if((val=openpgp_cipher_map_name (tok)))
if((val=gcry_cipher_map_name (tok)))
{
if(set_one_pref(val,1,tok,sym,&nsym))
rc=-1;
}
else if((val=openpgp_md_map_name (tok)))
else if((val=gcry_md_map_name (tok)))
{
if(set_one_pref(val,2,tok,hash,&nhash))
rc=-1;
@ -2138,7 +2138,7 @@ get_parameter_algo( struct para_data_s *para, enum para_name key )
if( digitp( r->u.value ) )
i = atoi( r->u.value );
else
i = openpgp_pk_map_name (r->u.value);
i = gcry_pk_map_name (r->u.value);
if (i == PUBKEY_ALGO_RSA_E || i == PUBKEY_ALGO_RSA_S)
i = 0; /* we don't want to allow generation of these algorithms */
return i;
@ -2289,7 +2289,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
if(r)
{
algo=get_parameter_algo(para,pKEYTYPE);
if (openpgp_pk_test_algo (algo, PUBKEY_USAGE_SIG))
if (openpgp_pk_test_algo2 (algo, PUBKEY_USAGE_SIG))
{
log_error("%s:%d: invalid algorithm\n", fname, r->lnr );
return -1;

View File

@ -26,9 +26,7 @@
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#ifdef HAVE_LIBCURL
#include <curl/curl.h>
#endif
#include <errno.h>
#include "gpg.h"
#include "iobuf.h"
@ -45,18 +43,6 @@
#include "keyserver-internal.h"
#include "util.h"
#define GPGKEYS_PREFIX "gpgkeys_"
#if defined(HAVE_LIBCURL) || defined(FAKE_CURL)
#define GPGKEYS_CURL "gpgkeys_curl"
#endif
#ifdef GPGKEYS_CURL
#define GPGKEYS_PREFIX_LEN (strlen(GPGKEYS_PREFIX)+strlen(GPGKEYS_CURL))
#else
#define GPGKEYS_PREFIX_LEN (strlen(GPGKEYS_PREFIX))
#endif
struct keyrec
{
KEYDB_SEARCH_DESC desc;
@ -419,7 +405,7 @@ parse_keyserver_uri(const char *string,int require_scheme,
else
keyserver->path=xstrdup("/");
if(keyserver->path[1]!='\0')
if(keyserver->path[1])
keyserver->flags.direct_uri=1;
}
else if(uri[0]!='/')
@ -941,19 +927,20 @@ keyserver_typemap(const char *type)
return type;
}
#ifdef GPGKEYS_CURL
/* The PGP LDAP and the curl fetch-a-LDAP-object methodologies are
sufficiently different that we can't use curl to do LDAP. */
static int
curl_cant_handle(const char *scheme,unsigned int direct_uri)
direct_uri_map(const char *scheme,unsigned int is_direct)
{
if(!direct_uri && (strcmp(scheme,"ldap")==0 || strcmp(scheme,"ldaps")==0))
if(is_direct && strcmp(scheme,"ldap")==0)
return 1;
return 0;
}
#endif
#define GPGKEYS_PREFIX "gpgkeys_"
#define GPGKEYS_CURL GPGKEYS_PREFIX "curl" EXEEXT
#define GPGKEYS_PREFIX_LEN (strlen(GPGKEYS_CURL))
#define KEYSERVER_ARGS_KEEP " -o \"%O\" \"%I\""
#define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\""
@ -1021,19 +1008,29 @@ keyserver_spawn(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc,
end=command+strlen(command);
/* Build a path for the keyserver helper. If it is direct_uri
(i.e. an object fetch and not a keyserver), then add "_uri" to
the end to distinguish the keyserver helper from an object
fetcher that can speak that protocol (this is a problem for
LDAP). */
strcat(command,GPGKEYS_PREFIX);
strcat(command,scheme);
if(keyserver->flags.direct_uri)
strcat(command,"uri");
/* This "_uri" thing is in case we need to call a direct handler
instead of the keyserver handler. This lets us use gpgkeys_curl
or gpgkeys_ldap_uri (we don't provide it, but a user might)
instead of gpgkeys_ldap to fetch things like
ldap://keyserver.pgp.com/o=PGP%20keys?pgpkey?sub?pgpkeyid=99242560 */
if(direct_uri_map(scheme,keyserver->flags.direct_uri))
strcat(command,"_uri");
strcat(command,EXEEXT);
#ifdef GPGKEYS_CURL
if(!curl_cant_handle(scheme,keyserver->flags.direct_uri)
&& path_access(command,X_OK)!=0)
/* Can we execute it? If not, try curl as our catchall. */
if(path_access(command,X_OK)!=0)
strcpy(end,GPGKEYS_CURL);
#endif
if(opt.keyserver_options.options&KEYSERVER_USE_TEMP_FILES)
{
@ -1950,15 +1947,6 @@ keyserver_fetch(STRLIST urilist)
{
int rc;
/*
Set the direct_uri flag so we know later to call a direct
handler instead of the keyserver style. This lets us use
gpgkeys_curl or gpgkeys_ldapuri instead of gpgkeys_ldap to
fetch things like
ldap://keyserver.pgp.com/o=PGP%20keys?pgpkey?sub?pgpkeyid=99242560
*/
spec->flags.direct_uri=1;
rc=keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,spec);
if(rc)
log_info (_("WARNING: unable to fetch URI %s: %s\n"),
@ -2038,6 +2026,12 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
rc=keyserver_import_fprint(*fpr,*fpr_len,opt.keyserver);
}
else
log_info(_("no keyserver known (use option --keyserver)\n"));
/* Give a better string here? "CERT fingerprint for \"%s\"
found, but no keyserver" " known (use option
--keyserver)\n" ? */
xfree(url);
}

View File

@ -282,6 +282,7 @@ void decrypt_messages(int nfiles, char *files[]);
/*-- plaintext.c --*/
int hash_datafiles( gcry_md_hd_t md, gcry_md_hd_t md2,
STRLIST files, const char *sigfilename, int textmode );
PKT_plaintext *setup_plaintext_name(const char *filename,IOBUF iobuf);
/*-- signal.c --*/
void init_signals(void);

View File

@ -659,9 +659,9 @@ proc_plaintext( CTX c, PACKET *pkt )
often. There is no good way to specify what algorithms to
use in that case, so these three are the historical
answer. */
md_enable( c->mfx.md, DIGEST_ALGO_RMD160 );
md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
gcry_md_enable( c->mfx.md, DIGEST_ALGO_RMD160 );
gcry_md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
gcry_md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
}
if( opt.pgp2_workarounds && only_md5 && !opt.skip_verify ) {
/* This is a kludge to work around a bug in pgp2. It does only

View File

@ -170,7 +170,6 @@ struct
STRLIST sig_keyserver_url;
STRLIST cert_subpackets;
STRLIST sig_subpackets;
int use_embedded_filename;
int allow_non_selfsigned_uid;
int allow_freeform_uid;
int no_literal;
@ -222,6 +221,10 @@ struct
made by signing subkeys. If not set, a missing backsig is not
an error (but an invalid backsig still is). */
unsigned int require_cross_cert:1;
unsigned int use_embedded_filename:1;
unsigned int utf8_filename:1;
unsigned int dsa2:1;
} flags;
/* Linked list of ways to find a key if the key isn't on the local

View File

@ -1,6 +1,6 @@
/* pkclist.c - create a list of public keys
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
* 2004, 2005 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
* 2006 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -1210,8 +1210,20 @@ algo_available( preftype_t preftype, int algo, void *hint )
}
else if( preftype == PREFTYPE_HASH )
{
if(hint && ((*(int *)hint) != gcry_md_get_algo_dlen (algo)))
return 0;
if(hint)
{
if(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))
return 0;
}
else if (((*(int *)hint) != gcry_md_get_algo_dlen (algo)))
return 0;
}
if((PGP6 || PGP7) && (algo != DIGEST_ALGO_MD5
&& algo != DIGEST_ALGO_SHA1

View File

@ -1,6 +1,6 @@
/* plaintext.c - process plaintext packets
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
* 2005, 2006 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
* 2006 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -91,7 +91,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
log_info(_("data not saved; use option \"--output\" to save it\n"));
nooutput = 1;
}
else if( !opt.use_embedded_filename ) {
else if( !opt.flags.use_embedded_filename ) {
fname = make_outfile_name( iobuf_get_real_fname(pt->buf) );
if( !fname )
fname = ask_outfile_name( pt->name, pt->namelen );
@ -100,9 +100,8 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
goto leave;
}
}
else {
fname = make_printable_string( pt->name, pt->namelen, 0 );
}
else
fname=utf8_to_native(pt->name,pt->namelen,0);
if( nooutput )
;
@ -318,9 +317,10 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
goto leave;
}
else if( fwrite( buffer, 1, len, fp ) != len ) {
rc = (errno? gpg_error_from_errno (errno)
: gpg_error (GPG_ERR_INTERNAL));
log_error("Error writing to `%s': %s\n",
fname, strerror(errno) );
rc = G10ERR_WRITE_FILE;
xfree( buffer );
goto leave;
}
@ -554,3 +554,44 @@ hash_datafiles( gcry_md_hd_t md, gcry_md_hd_t md2, STRLIST files,
return 0;
}
/* Set up a plaintext packet with the appropriate filename. If there
is a --set-filename, use it (it's already UTF8). If there is a
regular filename, UTF8-ize it if necessary. If there is no
filenames at all, set the field empty. */
PKT_plaintext *
setup_plaintext_name(const char *filename,IOBUF iobuf)
{
PKT_plaintext *pt;
if(filename || opt.set_filename)
{
char *s;
if(opt.set_filename)
s=make_basename(opt.set_filename,iobuf_get_real_fname(iobuf));
else if(filename && !opt.flags.utf8_filename)
{
char *tmp=native_to_utf8(filename);
s=make_basename(tmp,iobuf_get_real_fname(iobuf));
xfree(tmp);
}
else
s=make_basename(filename,iobuf_get_real_fname(iobuf));
pt = xmalloc (sizeof *pt + strlen(s) - 1);
pt->namelen = strlen (s);
memcpy (pt->name, s, pt->namelen);
xfree (s);
}
else
{
/* no filename */
pt = xmalloc (sizeof *pt - 1);
pt->namelen = 0;
}
return pt;
}

View File

@ -320,11 +320,15 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
}
else
{
/* TODO: remove this check in the future once all the
variable-q DSA stuff makes it into the standard. */
if(!opt.expert
&& sk->pubkey_algo==PUBKEY_ALGO_DSA
&& gcry_md_get_algo_dlen (digest_algo)!=20)
/* 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;
@ -384,6 +388,32 @@ complete_sig( PKT_signature *sig, PKT_secret_key *sk, gcry_md_hd_t md )
return rc;
}
static int
match_dsa_hash (unsigned int qbytes)
{
if (qbytes <= 20)
return DIGEST_ALGO_SHA1;
#ifdef USE_SHA256
if (qbytes <= 28)
return DIGEST_ALGO_SHA224;
if (qbytes <= 32)
return DIGEST_ALGO_SHA256;
#endif
#ifdef USE_SHA512
if (qbytes <= 48)
return DIGEST_ALGO_SHA384;
if (qbytes <= 64)
return DIGEST_ALGO_SHA512;
#endif
return DEFAULT_DIGEST_ALGO;
/* DEFAULT_DIGEST_ALGO will certainly fail, but it's the best wrong
answer we have if the larger SHAs aren't there. */
}
/*
First try --digest-algo. If that isn't set, see if the recipient
has a preferred algorithm (which is also filtered through
@ -397,7 +427,6 @@ complete_sig( PKT_signature *sig, PKT_secret_key *sk, gcry_md_hd_t md )
the signing key prefs either before or after using the personal
list?
*/
static int
hash_for(PKT_secret_key *sk)
{
@ -405,32 +434,61 @@ hash_for(PKT_secret_key *sk)
return opt.def_digest_algo;
else if( recipient_digest_algo )
return recipient_digest_algo;
else if(sk->pubkey_algo==PUBKEY_ALGO_DSA
|| (sk->is_protected && sk->protect.s2k.mode==1002))
else if(sk->pubkey_algo==PUBKEY_ALGO_DSA)
{
/* The sk lives on a smartcard, or it's a DSA key. DSA requires
a 160-bit hash, and current smartcards only handle SHA-1 and
RIPEMD/160 (i.e. 160-bit hashes). This is correct now, but
may need revision as the cards add algorithms and/or DSA is
expanded to use larger hashes. */
unsigned int qbytes = gcry_mpi_get_nbits (sk->skey[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
160-bit hash unless --enable-dsa2 is set, in which case act
like a new DSA key that just happens to have a 160-bit q
(i.e. allow truncation). If q is not 160, by definition it
must be a new DSA key. */
if (opt.personal_digest_prefs)
{
prefitem_t *prefs;
if (qbytes != 20 || opt.flags.dsa2)
{
for (prefs=opt.personal_digest_prefs; prefs->type; prefs++)
if (gcry_md_get_algo_dlen (prefs->value) >= qbytes)
return prefs->value;
}
else
{
for (prefs=opt.personal_digest_prefs; prefs->type; prefs++)
if (gcry_md-get_algo_dlen (prefs->value) == qbytes)
return prefs->value;
}
}
return match_dsa_hash(qbytes);
}
else if (sk->is_protected && sk->protect.s2k.mode==1002)
{
/* The sk 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. */
if(opt.personal_digest_prefs)
{
prefitem_t *prefs;
for(prefs=opt.personal_digest_prefs;prefs->type;prefs++)
if (gcry_md_get_algo_dlen (prefs->value) == 20)
for (prefs=opt.personal_digest_prefs;prefs->type;prefs++)
if (prefs->value==DIGEST_ALGO_SHA1
|| prefs->value==DIGEST_ALGO_RMD160)
return prefs->value;
}
return DIGEST_ALGO_SHA1;
}
else if(PGP2 && sk->pubkey_algo == PUBKEY_ALGO_RSA && sk->version < 4 )
else if (PGP2 && sk->pubkey_algo == PUBKEY_ALGO_RSA && sk->version < 4 )
{
/* Old-style PGP only understands MD5. */
/* 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 */
@ -440,6 +498,7 @@ hash_for(PKT_secret_key *sk)
return DEFAULT_DIGEST_ALGO;
}
static int
only_old_style( SK_LIST sk_list )
{
@ -537,21 +596,8 @@ write_plaintext_packet (IOBUF out, IOBUF inp, const char *fname, int ptmode)
u32 filesize;
int rc = 0;
if (!opt.no_literal) {
if (fname || opt.set_filename) {
char *s = make_basename (opt.set_filename? opt.set_filename
: fname,
iobuf_get_real_fname(inp));
pt = xmalloc (sizeof *pt + strlen(s) - 1);
pt->namelen = strlen (s);
memcpy (pt->name, s, pt->namelen);
xfree (s);
}
else { /* no filename */
pt = xmalloc (sizeof *pt - 1);
pt->namelen = 0;
}
}
if (!opt.no_literal)
pt=setup_plaintext_name(fname,inp);
/* try to calculate the length of the data */
if ( !iobuf_is_pipe_filename (fname) && *fname )
@ -1367,16 +1413,19 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
{
/* Basically, this means use SHA1 always unless it's a v3 RSA
key making a v3 cert (use MD5), or the user specified
something (use whatever they said). They still must use a
160-bit hash with DSA, or the signature will fail. Note
that this still allows the caller of make_keysig_packet to
override the user setting if it must. */
something (use whatever they said), or it's DSA (use the
best match). They still can't pick an inappropriate hash
for DSA or the signature will fail. Note that this still
allows the caller of make_keysig_packet to override the
user setting if it must. */
if(opt.cert_digest_algo)
digest_algo=opt.cert_digest_algo;
else if(sk->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
digest_algo = DIGEST_ALGO_SHA1;
}

View File

@ -209,9 +209,10 @@ set_status_fd ( int fd )
fd, strerror(errno));
}
last_fd = fd;
register_primegen_progress ( progress_cb, "primegen" );
register_pk_dsa_progress ( progress_cb, "pk_dsa" );
register_pk_elg_progress ( progress_cb, "pk_elg" );
#warning Use libgrypt calls for progress indicators
/* register_primegen_progress ( progress_cb, "primegen" ); */
/* register_pk_dsa_progress ( progress_cb, "pk_dsa" ); */
/* register_pk_elg_progress ( progress_cb, "pk_elg" ); */
}
int