1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-10-31 20:08:43 +01:00

Ported patches from 1.4.x

This commit is contained in:
Werner Koch 2006-06-27 14:30:59 +00:00
parent 91a4be3126
commit f081ad529d
10 changed files with 323 additions and 59 deletions

View File

@ -1,3 +1,63 @@
2006-06-27 Werner Koch <wk@g10code.com>
Applied patches from 1.4.x (2006-05-22 to 2006-06-23) from David:
* keygen.c (keygen_upd_std_prefs, keygen_add_std_prefs)
(proc_parameter_file): Add --default-keyserver-url to specify a
keyserver URL at key generation time, and "Keyserver:" keyword for
doing the same through a batch file.
* options.h, gpg.c (main): Ditto.
* sign.c (do_sign): For now don't accept a truncated hash even
for DSA1 keys (be liberal in what you accept, etc).
* import.c (import_one): Add a flag (from_sk) so we don't check
prefs on an autoconverted public key. The check should only
happen on the sk side. Noted by Dirk Traulsen.
* keygen.c (gen_card_key): Add optional argument to return a
pointer (not a copy) of the stub secret key for the secret key we
just generated on the card.
(generate_card_subkeypair): Use it here so that the signing key on
the card can use the card to generate the 0x19 backsig on the
primary key. Noted by Janko Heilgeist and Jonas Oberg.
* parse-packet.c (parse_user_id): Cap the user ID size at 2048
bytes. This prevents a memory allocation attack with a very large
user ID. A very large packet length could even cause the
allocation (a u32) to wrap around to a small number. Noted by
Evgeny Legerov on full-disclosure.
* keygen.c (gen_dsa): Allow generating DSA2 keys. Allow
specifying sizes > 1024 when --enable-dsa2 is set. The size of q
is set automatically based on the key size.
(ask_keysize, generate_keypair): Ask for DSA size when
--enable-dsa2 is set.
* exec.c (make_tempdir) [W32]: Fix bug with a temporary directory
on W32 that is over 256 bytes long. Noted by Israel G. Lugo.
* gpg.c (reopen_std): New function to reopen fd 0, 1, or 2 if we
are called with them closed. This is to protect our
keyring/trustdb files from corruption if they get attached to one
of the standard fds. Print a warning if possible that this has
happened, and fail completely if we cannot reopen (should never
happen).
(main): Call it here.
* parse-packet.c (dump_sig_subpkt, parse_signature): Fix meaning
of key expiration and sig expiration subpackets - zero means
"never expire" according to 2440, not "expire instantly".
* build-packet.c (build_sig_subpkt_from_sig): Ditto.
* getkey.c (fixup_uidnode, merge_selfsigs_main)
(merge_selfsigs_subkey): Ditto.
* keygen.c (keygen_add_key_expire): Ditto.
* getkey.c (get_pubkey_byname)
* import.c (import_one): Fix key selection problem when
auto-key-locate returns a list of keys, not all of which are
usable (revoked, expired, etc). Noted by Simon Josefsson.
2006-05-24 Werner Koch <wk@g10code.com> 2006-05-24 Werner Koch <wk@g10code.com>
* keyid.c (hash_public_key): Do not double hash the length bytes, * keyid.c (hash_public_key): Do not double hash the length bytes,

View File

@ -841,7 +841,8 @@ build_sig_subpkt_from_sig( PKT_signature *sig )
if(sig->expiredate>sig->timestamp) if(sig->expiredate>sig->timestamp)
u=sig->expiredate-sig->timestamp; u=sig->expiredate-sig->timestamp;
else else
u=0; u=1; /* A 1-second expiration time is the shortest one
OpenPGP has */
buf[0] = (u >> 24) & 0xff; buf[0] = (u >> 24) & 0xff;
buf[1] = (u >> 16) & 0xff; buf[1] = (u >> 16) & 0xff;

View File

@ -127,8 +127,11 @@ static int make_tempdir(struct exec_info *info)
if(tmp==NULL) if(tmp==NULL)
{ {
#if defined (_WIN32) #if defined (_WIN32)
tmp=xmalloc(256); int err;
if(GetTempPath(256,tmp)==0)
tmp=xmalloc(MAX_PATH+2);
err=GetTempPath(MAX_PATH+1,tmp);
if(err==0 || err>MAX_PATH+1)
strcpy(tmp,"c:\\windows\\temp"); strcpy(tmp,"c:\\windows\\temp");
else else
{ {

View File

@ -935,7 +935,7 @@ get_pubkey_byname (PKT_public_key *pk,
for(akl=opt.auto_key_locate;akl;akl=akl->next) for(akl=opt.auto_key_locate;akl;akl=akl->next)
{ {
unsigned char *fpr; unsigned char *fpr=NULL;
size_t fpr_len; size_t fpr_len;
switch(akl->type) switch(akl->type)
@ -1507,12 +1507,12 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
/* store the key flags in the helper variable for later processing */ /* store the key flags in the helper variable for later processing */
uid->help_key_usage=parse_key_usage(sig); uid->help_key_usage=parse_key_usage(sig);
/* ditto or the key expiration */ /* ditto for the key expiration */
uid->help_key_expire = 0;
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
if ( p ) { if( p && buffer_to_u32(p) )
uid->help_key_expire = keycreated + buffer_to_u32(p); uid->help_key_expire = keycreated + buffer_to_u32(p);
} else
uid->help_key_expire = 0;
/* Set the primary user ID flag - we will later wipe out some /* Set the primary user ID flag - we will later wipe out some
* of them to only have one in our keyblock */ * of them to only have one in our keyblock */
@ -1724,7 +1724,7 @@ merge_selfsigs_main(KBNODE keyblock, int *r_revoked, struct revoke_info *rinfo)
key_usage=parse_key_usage(sig); key_usage=parse_key_usage(sig);
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
if ( p ) if( p && buffer_to_u32(p) )
{ {
key_expire = keytimestamp + buffer_to_u32(p); key_expire = keytimestamp + buffer_to_u32(p);
key_expire_seen = 1; key_expire_seen = 1;
@ -2128,7 +2128,7 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode )
subpk->pubkey_usage = key_usage; subpk->pubkey_usage = key_usage;
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
if ( p ) if ( p && buffer_to_u32(p) )
key_expire = keytimestamp + buffer_to_u32(p); key_expire = keytimestamp + buffer_to_u32(p);
else else
key_expire = 0; key_expire = 0;

View File

@ -328,6 +328,7 @@ enum cmd_and_opt_values
oNoAutoCheckTrustDB, oNoAutoCheckTrustDB,
oPreservePermissions, oPreservePermissions,
oDefaultPreferenceList, oDefaultPreferenceList,
oDefaultKeyserverURL,
oPersonalCipherPreferences, oPersonalCipherPreferences,
oPersonalDigestPreferences, oPersonalDigestPreferences,
oPersonalCompressPreferences, oPersonalCompressPreferences,
@ -659,6 +660,7 @@ static ARGPARSE_OPTS opts[] = {
{ aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"}, { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"},
{ oPreservePermissions, "preserve-permissions", 0, "@"}, { oPreservePermissions, "preserve-permissions", 0, "@"},
{ oDefaultPreferenceList, "default-preference-list", 2, "@"}, { oDefaultPreferenceList, "default-preference-list", 2, "@"},
{ oDefaultKeyserverURL, "default-keyserver-url", 2, "@"},
{ oPersonalCipherPreferences, "personal-cipher-preferences", 2, "@"}, { oPersonalCipherPreferences, "personal-cipher-preferences", 2, "@"},
{ oPersonalDigestPreferences, "personal-digest-preferences", 2, "@"}, { oPersonalDigestPreferences, "personal-digest-preferences", 2, "@"},
{ oPersonalCompressPreferences, "personal-compress-preferences", 2, "@"}, { oPersonalCompressPreferences, "personal-compress-preferences", 2, "@"},
@ -1643,6 +1645,78 @@ parse_trust_model(const char *model)
log_error("unknown trust model `%s'\n",model); log_error("unknown trust model `%s'\n",model);
} }
/* Make sure that the standard file descriptors are opened. Obviously
some folks close them before an exec and the next file we open will
get one of them assigned and thus any output (i.e. diagnostics) end
up in that file (e.g. the trustdb). Not actually a gpg problem as
this will hapenn with almost all utilities when called in a wrong
way. However we try to minimize the damage here and raise
awareness of the problem.
Must be called before we open any files! */
static void
reopen_std(void)
{
#if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
struct stat statbuf;
int did_stdin=0,did_stdout=0,did_stderr=0;
FILE *complain;
if(fstat(STDIN_FILENO,&statbuf)==-1 && errno==EBADF)
{
if(open("/dev/null",O_RDONLY)==STDIN_FILENO)
did_stdin=1;
else
did_stdin=2;
}
if(fstat(STDOUT_FILENO,&statbuf)==-1 && errno==EBADF)
{
if(open("/dev/null",O_WRONLY)==STDOUT_FILENO)
did_stdout=1;
else
did_stdout=2;
}
if(fstat(STDERR_FILENO,&statbuf)==-1 && errno==EBADF)
{
if(open("/dev/null",O_WRONLY)==STDERR_FILENO)
did_stderr=1;
else
did_stderr=2;
}
/* It's hard to log this sort of thing since the filehandle we would
complain to may be closed... */
if(did_stderr==0)
complain=stderr;
else if(did_stdout==0)
complain=stdout;
else
complain=NULL;
if(complain)
{
if(did_stdin==1)
fprintf(complain,"gpg: WARNING: standard input reopened\n");
if(did_stdout==1)
fprintf(complain,"gpg: WARNING: standard output reopened\n");
if(did_stderr==1)
fprintf(complain,"gpg: WARNING: standard error reopened\n");
if(did_stdin==2 || did_stdout==2 || did_stderr==2)
fprintf(complain,"gpg: fatal: unable to reopen standard input,"
" output, or error\n");
}
if(did_stdin==2 || did_stdout==2 || did_stderr==2)
exit(3);
#endif /* HAVE_STAT && !HAVE_W32_SYSTEM */
}
int int
main (int argc, char **argv ) main (int argc, char **argv )
{ {
@ -1697,7 +1771,7 @@ main (int argc, char **argv )
/* Please note that we may running SUID(ROOT), so be very CAREFUL /* Please note that we may running SUID(ROOT), so be very CAREFUL
when adding any stuff between here and the call to when adding any stuff between here and the call to
secmem_init() somewhere after the option parsing. */ secmem_init() somewhere after the option parsing. */
reopen_std ();
trap_unaligned(); trap_unaligned();
set_strusage (my_strusage); set_strusage (my_strusage);
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
@ -2586,6 +2660,19 @@ main (int argc, char **argv )
case oDefaultPreferenceList: case oDefaultPreferenceList:
opt.def_preference_list = pargs.r.ret_str; opt.def_preference_list = pargs.r.ret_str;
break; break;
case oDefaultKeyserverURL:
{
struct keyserver_spec *keyserver;
keyserver=parse_keyserver_uri(pargs.r.ret_str,1,
configname,configlineno);
if(!keyserver)
log_error(_("could not parse keyserver URL\n"));
else
free_keyserver_spec(keyserver);
opt.def_keyserver_url = pargs.r.ret_str;
}
break;
case oPersonalCipherPreferences: case oPersonalCipherPreferences:
pers_cipher_list=pargs.r.ret_str; pers_cipher_list=pargs.r.ret_str;
break; break;

View File

@ -66,7 +66,7 @@ static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
static void revocation_present(KBNODE keyblock); static void revocation_present(KBNODE keyblock);
static int import_one(const char *fname, KBNODE keyblock,struct stats_s *stats, static int import_one(const char *fname, KBNODE keyblock,struct stats_s *stats,
unsigned char **fpr,size_t *fpr_len, unsigned char **fpr,size_t *fpr_len,
unsigned int options); unsigned int options,int from_sk);
static int import_secret_one( const char *fname, KBNODE keyblock, static int import_secret_one( const char *fname, KBNODE keyblock,
struct stats_s *stats, unsigned int options); struct stats_s *stats, unsigned int options);
static int import_revoke_cert( const char *fname, KBNODE node, static int import_revoke_cert( const char *fname, KBNODE node,
@ -258,7 +258,7 @@ import( IOBUF inp, const char* fname,struct stats_s *stats,
while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) { while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) {
if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY ) if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
rc = import_one( fname, keyblock, stats, fpr, fpr_len, options ); rc = import_one( fname, keyblock, stats, fpr, fpr_len, options, 0);
else if( keyblock->pkt->pkttype == PKT_SECRET_KEY ) else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
rc = import_secret_one( fname, keyblock, stats, options ); rc = import_secret_one( fname, keyblock, stats, options );
else if( keyblock->pkt->pkttype == PKT_SIGNATURE else if( keyblock->pkt->pkttype == PKT_SIGNATURE
@ -679,7 +679,8 @@ check_prefs(KBNODE keyblock)
*/ */
static int static int
import_one( const char *fname, KBNODE keyblock, struct stats_s *stats, import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
unsigned char **fpr,size_t *fpr_len,unsigned int options ) unsigned char **fpr,size_t *fpr_len,unsigned int options,
int from_sk )
{ {
PKT_public_key *pk; PKT_public_key *pk;
PKT_public_key *pk_orig; PKT_public_key *pk_orig;
@ -698,9 +699,6 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
pk = node->pkt->pkt.public_key; pk = node->pkt->pkt.public_key;
if(fpr)
*fpr=fingerprint_from_pk(pk,NULL,fpr_len);
keyid_from_pk( pk, keyid ); keyid_from_pk( pk, keyid );
uidnode = find_next_kbnode( keyblock, PKT_USER_ID ); uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
@ -978,13 +976,31 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
if(mod_key) if(mod_key)
{ {
revocation_present(keyblock_orig); revocation_present(keyblock_orig);
if(seckey_available(keyid)==0) if(!from_sk && seckey_available(keyid)==0)
check_prefs(keyblock_orig); check_prefs(keyblock_orig);
} }
else if(new_key) else if(new_key)
{ {
/* A little explanation for this: we fill in the fingerprint
when importing keys as it can be useful to know the
fingerprint in certain keyserver-related cases (a keyserver
asked for a particular name, but the key doesn't have that
name). However, in cases where we're importing more than
one key at a time, we cannot know which key to fingerprint.
In these cases, rather than guessing, we do not fingerpring
at all, and we must hope the user ID on the keys are
useful. */
if(fpr)
{
xfree(*fpr);
if(stats->imported==1)
*fpr=fingerprint_from_pk(pk,NULL,fpr_len);
else
*fpr=NULL;
}
revocation_present(keyblock); revocation_present(keyblock);
if(seckey_available(keyid)==0) if(!from_sk && seckey_available(keyid)==0)
check_prefs(keyblock); check_prefs(keyblock);
} }
@ -1156,7 +1172,7 @@ import_secret_one( const char *fname, KBNODE keyblock,
if(pub_keyblock) if(pub_keyblock)
{ {
import_one(fname,pub_keyblock,stats, import_one(fname,pub_keyblock,stats,
NULL,NULL,opt.import_options); NULL,NULL,opt.import_options,1);
release_kbnode(pub_keyblock); release_kbnode(pub_keyblock);
} }
} }

View File

@ -42,6 +42,7 @@
#include "trustdb.h" #include "trustdb.h"
#include "status.h" #include "status.h"
#include "i18n.h" #include "i18n.h"
#include "keyserver-internal.h"
#include "call-agent.h" #include "call-agent.h"
@ -69,7 +70,8 @@ enum para_name {
pPASSPHRASE_S2K, pPASSPHRASE_S2K,
pSERIALNO, pSERIALNO,
pBACKUPENCDIR, pBACKUPENCDIR,
pHANDLE pHANDLE,
pKEYSERVER
}; };
struct para_data_s { struct para_data_s {
@ -125,6 +127,7 @@ static void do_generate_keypair( struct para_data_s *para,
static int write_keyblock( IOBUF out, KBNODE node ); static int write_keyblock( IOBUF out, KBNODE node );
static int gen_card_key (int algo, int keyno, int is_primary, static int gen_card_key (int algo, int keyno, int is_primary,
KBNODE pub_root, KBNODE sec_root, KBNODE pub_root, KBNODE sec_root,
PKT_secret_key **ret_sk,
u32 expireval, struct para_data_s *para); u32 expireval, struct para_data_s *para);
static int gen_card_key_with_backup (int algo, int keyno, int is_primary, static int gen_card_key_with_backup (int algo, int keyno, int is_primary,
KBNODE pub_root, KBNODE sec_root, KBNODE pub_root, KBNODE sec_root,
@ -224,7 +227,7 @@ keygen_add_key_expire( PKT_signature *sig, void *opaque )
if(pk->expiredate > pk->timestamp) if(pk->expiredate > pk->timestamp)
u= pk->expiredate - pk->timestamp; u= pk->expiredate - pk->timestamp;
else else
u= 0; u= 1;
buf[0] = (u >> 24) & 0xff; buf[0] = (u >> 24) & 0xff;
buf[1] = (u >> 16) & 0xff; buf[1] = (u >> 16) & 0xff;
@ -657,6 +660,7 @@ keygen_upd_std_prefs( PKT_signature *sig, void *opaque )
/* Make sure that the MDC feature flag is set if needed */ /* Make sure that the MDC feature flag is set if needed */
add_feature_mdc (sig,mdc_available); add_feature_mdc (sig,mdc_available);
add_keyserver_modify (sig,ks_modify); add_keyserver_modify (sig,ks_modify);
keygen_add_keyserver_url(sig,NULL);
return 0; return 0;
} }
@ -675,6 +679,7 @@ keygen_add_std_prefs( PKT_signature *sig, void *opaque )
do_add_key_flags (sig, pk->pubkey_usage); do_add_key_flags (sig, pk->pubkey_usage);
keygen_add_key_expire( sig, opaque ); keygen_add_key_expire( sig, opaque );
keygen_upd_std_prefs (sig, opaque); keygen_upd_std_prefs (sig, opaque);
keygen_add_keyserver_url(sig,NULL);
return 0; return 0;
} }
@ -684,6 +689,9 @@ keygen_add_keyserver_url(PKT_signature *sig, void *opaque)
{ {
const char *url=opaque; const char *url=opaque;
if(!url)
url=opt.def_keyserver_url;
if(url) if(url)
build_sig_subpkt(sig,SIGSUBPKT_PREF_KS,url,strlen(url)); build_sig_subpkt(sig,SIGSUBPKT_PREF_KS,url,strlen(url));
else else
@ -940,7 +948,6 @@ write_selfsigs( KBNODE sec_root, KBNODE pub_root, PKT_secret_key *sk,
return rc; return rc;
} }
/* sub_sk is currently unused (reserved for backsigs) */
static int static int
write_keybinding( KBNODE root, KBNODE pub_root, write_keybinding( KBNODE root, KBNODE pub_root,
PKT_secret_key *pri_sk, PKT_secret_key *sub_sk, PKT_secret_key *pri_sk, PKT_secret_key *sub_sk,
@ -1224,20 +1231,54 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
PKT_public_key *pk; PKT_public_key *pk;
gcry_sexp_t s_parms, s_key; gcry_sexp_t s_parms, s_key;
gcry_sexp_t misc_key_info; gcry_sexp_t misc_key_info;
unsigned int qbits;
if( nbits > 1024 || nbits < 512 ) { if ( nbits < 512 || (!opt.flags.dsa2 && nbits > 1024))
{
nbits = 1024; nbits = 1024;
log_info(_("keysize invalid; using %u bits\n"), nbits ); log_info(_("keysize invalid; using %u bits\n"), nbits );
} }
else if ( nbits > 3072 )
{
nbits = 3072;
log_info(_("keysize invalid; using %u bits\n"), nbits );
}
if( (nbits % 64) ) { if( (nbits % 64) )
{
nbits = ((nbits + 63) / 64) * 64; nbits = ((nbits + 63) / 64) * 64;
log_info(_("keysize rounded up to %u bits\n"), nbits ); log_info(_("keysize rounded up to %u bits\n"), nbits );
} }
/*
Figure out a q size based on the key size. FIPS 180-3 says:
L = 1024, N = 160
L = 2048, N = 224
L = 2048, N = 256
L = 3072, N = 256
2048/256 is an odd pair since there is also a 2048/224 and
3072/256. Matching sizes is not a very exact science.
We'll do 256 qbits for nbits over 2048, 224 for nbits over 1024
but less than 2048, and 160 for 1024 (DSA1).
*/
if (nbits > 2048)
qbits = 256;
else if ( nbits > 1024)
qbits = 224;
else
qbits = 160;
if (qbits != 160 )
log_info (_("WARNING: some OpenPGP programs can't"
" handle a DSA key with this digest size\n"));
rc = gcry_sexp_build (&s_parms, NULL, rc = gcry_sexp_build (&s_parms, NULL,
"(genkey(dsa(nbits %d)))", "(genkey(dsa(nbits %d)(qbits %d)))",
(int)nbits); (int)nbits, (int)qbits);
if (rc) if (rc)
log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc)); log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc));
@ -1253,9 +1294,8 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
pk = xmalloc_clear( sizeof *pk ); pk = xmalloc_clear( sizeof *pk );
sk->timestamp = pk->timestamp = make_timestamp(); sk->timestamp = pk->timestamp = make_timestamp();
sk->version = pk->version = 4; sk->version = pk->version = 4;
if( expireval ) { if (expireval)
sk->expiredate = pk->expiredate = sk->timestamp + expireval; sk->expiredate = pk->expiredate = sk->timestamp + expireval;
}
sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA; sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA;
rc = key_from_sexp (pk->pkey, s_key, "public-key", "pqgy"); rc = key_from_sexp (pk->pkey, s_key, "public-key", "pqgy");
@ -1633,10 +1673,10 @@ ask_keysize( int algo )
switch(algo) switch(algo)
{ {
case PUBKEY_ALGO_DSA: case PUBKEY_ALGO_DSA:
if(opt.expert) if(opt.flags.dsa2)
{ {
def=1024; def=1024;
max=1024; max=3072;
} }
else else
{ {
@ -2375,6 +2415,25 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
/* Set preferences, if any. */ /* Set preferences, if any. */
keygen_set_std_prefs(get_parameter_value( para, pPREFERENCES ), 0); keygen_set_std_prefs(get_parameter_value( para, pPREFERENCES ), 0);
/* Set keyserver, if any. */
s1=get_parameter_value( para, pKEYSERVER );
if(s1)
{
struct keyserver_spec *spec;
spec=parse_keyserver_uri(s1,1,NULL,0);
if(spec)
{
free_keyserver_spec(spec);
opt.def_keyserver_url=s1;
}
else
{
log_error("%s:%d: invalid keyserver url\n", fname, r->lnr );
return -1;
}
}
/* Set revoker, if any. */ /* Set revoker, if any. */
if (parse_revocation_key (fname, para, pREVOKER)) if (parse_revocation_key (fname, para, pREVOKER))
return -1; return -1;
@ -2467,6 +2526,7 @@ read_parameter_file( const char *fname )
{ "Preferences", pPREFERENCES }, { "Preferences", pPREFERENCES },
{ "Revoker", pREVOKER }, { "Revoker", pREVOKER },
{ "Handle", pHANDLE }, { "Handle", pHANDLE },
{ "Keyserver", pKEYSERVER },
{ NULL, 0 } { NULL, 0 }
}; };
IOBUF fp; IOBUF fp;
@ -2746,12 +2806,12 @@ generate_keypair (const char *fname, const char *card_serialno,
sprintf( r->u.value, "%d", PUBKEY_ALGO_DSA ); sprintf( r->u.value, "%d", PUBKEY_ALGO_DSA );
r->next = para; r->next = para;
para = r; para = r;
tty_printf(_("DSA keypair will have %u bits.\n"),1024); nbits = ask_keysize( PUBKEY_ALGO_DSA );
r = xmalloc_clear( sizeof *r + 20 ); r = xmalloc_clear( sizeof *r + 20 );
r->key = pKEYLENGTH; r->key = pKEYLENGTH;
strcpy( r->u.value, "1024" ); sprintf( r->u.value, "%u", nbits);
r->next = para; r->next = para;
para = r; para = r;
r = xmalloc_clear( sizeof *r + 20 ); r = xmalloc_clear( sizeof *r + 20 );
r->key = pKEYUSAGE; r->key = pKEYUSAGE;
strcpy( r->u.value, "sign" ); strcpy( r->u.value, "sign" );
@ -2791,7 +2851,7 @@ generate_keypair (const char *fname, const char *card_serialno,
} }
} }
nbits = ask_keysize( algo ); nbits = ask_keysize( algo );
r = xmalloc_clear( sizeof *r + 20 ); r = xmalloc_clear( sizeof *r + 20 );
r->key = both? pSUBKEYLENGTH : pKEYLENGTH; r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
@ -3057,7 +3117,7 @@ do_generate_keypair( struct para_data_s *para,
} }
else else
{ {
rc = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root, sec_root, rc = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root, sec_root, NULL,
get_parameter_u32 (para, pKEYEXPIRE), para); get_parameter_u32 (para, pKEYEXPIRE), para);
if (!rc) if (!rc)
{ {
@ -3093,7 +3153,7 @@ do_generate_keypair( struct para_data_s *para,
if (!rc && card && get_parameter (para, pAUTHKEYTYPE)) if (!rc && card && get_parameter (para, pAUTHKEYTYPE))
{ {
rc = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root, sec_root, rc = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root, sec_root, NULL,
get_parameter_u32 (para, pKEYEXPIRE), para); get_parameter_u32 (para, pKEYEXPIRE), para);
if (!rc) if (!rc)
@ -3129,6 +3189,7 @@ do_generate_keypair( struct para_data_s *para,
} }
else else
rc = gen_card_key (PUBKEY_ALGO_RSA, 2, 0, pub_root, sec_root, rc = gen_card_key (PUBKEY_ALGO_RSA, 2, 0, pub_root, sec_root,
NULL,
get_parameter_u32 (para, pKEYEXPIRE), para); get_parameter_u32 (para, pKEYEXPIRE), para);
} }
@ -3353,7 +3414,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
} }
rc = do_create( algo, nbits, pub_keyblock, sec_keyblock, rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
dek, s2k, &sub_sk, expire, 1 ); dek, s2k, &sub_sk, expire, 1 );
if( !rc ) if( !rc )
rc = write_keybinding(pub_keyblock, pub_keyblock, pri_sk, sub_sk, use); rc = write_keybinding(pub_keyblock, pub_keyblock, pri_sk, sub_sk, use);
if( !rc ) if( !rc )
@ -3387,7 +3448,7 @@ generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
{ {
int okay=0, rc=0; int okay=0, rc=0;
KBNODE node; KBNODE node;
PKT_secret_key *pri_sk = NULL; PKT_secret_key *pri_sk = NULL, *sub_sk;
int algo; int algo;
unsigned int use; unsigned int use;
u32 expire; u32 expire;
@ -3467,11 +3528,12 @@ generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
if (passphrase) if (passphrase)
set_next_passphrase (passphrase); set_next_passphrase (passphrase);
rc = gen_card_key (algo, keyno, 0, pub_keyblock, sec_keyblock, expire, para); rc = gen_card_key (algo, keyno, 0, pub_keyblock, sec_keyblock,
&sub_sk, expire, para);
if (!rc) if (!rc)
rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, NULL, use); rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk, use);
if (!rc) if (!rc)
rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, NULL, use); rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, sub_sk, use);
if (!rc) if (!rc)
{ {
okay = 1; okay = 1;
@ -3518,7 +3580,7 @@ write_keyblock( IOBUF out, KBNODE node )
static int static int
gen_card_key (int algo, int keyno, int is_primary, gen_card_key (int algo, int keyno, int is_primary,
KBNODE pub_root, KBNODE sec_root, KBNODE pub_root, KBNODE sec_root, PKT_secret_key **ret_sk,
u32 expireval, struct para_data_s *para) u32 expireval, struct para_data_s *para)
{ {
#ifdef ENABLE_CARD_SUPPORT #ifdef ENABLE_CARD_SUPPORT
@ -3579,6 +3641,9 @@ gen_card_key (int algo, int keyno, int is_primary,
sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s); sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
} }
if( ret_sk )
*ret_sk = sk;
pkt = xcalloc (1,sizeof *pkt); pkt = xcalloc (1,sizeof *pkt);
pkt->pkttype = is_primary ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY; pkt->pkttype = is_primary ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
pkt->pkt.public_key = pk; pkt->pkt.public_key = pk;

View File

@ -154,7 +154,8 @@ struct
unsigned int export_options; unsigned int export_options;
unsigned int list_options; unsigned int list_options;
unsigned int verify_options; unsigned int verify_options;
char *def_preference_list; const char *def_preference_list;
const char *def_keyserver_url;
prefitem_t *personal_cipher_prefs; prefitem_t *personal_cipher_prefs;
prefitem_t *personal_digest_prefs; prefitem_t *personal_digest_prefs;
prefitem_t *personal_compress_prefs; prefitem_t *personal_compress_prefs;

View File

@ -1,6 +1,6 @@
/* parse-packet.c - read packets /* parse-packet.c - read packets
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
* 2005 Free Software Foundation, Inc. * 2006 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -876,8 +876,13 @@ dump_sig_subpkt( int hashed, int type, int critical,
break; break;
case SIGSUBPKT_SIG_EXPIRE: case SIGSUBPKT_SIG_EXPIRE:
if( length >= 4 ) if( length >= 4 )
fprintf (listfp, "sig expires after %s", {
strtimevalue( buffer_to_u32(buffer) ) ); if(buffer_to_u32(buffer))
fprintf (listfp, "sig expires after %s",
strtimevalue( buffer_to_u32(buffer) ) );
else
fprintf (listfp, "sig does not expire");
}
break; break;
case SIGSUBPKT_EXPORTABLE: case SIGSUBPKT_EXPORTABLE:
if( length ) if( length )
@ -901,8 +906,13 @@ dump_sig_subpkt( int hashed, int type, int critical,
break; break;
case SIGSUBPKT_KEY_EXPIRE: case SIGSUBPKT_KEY_EXPIRE:
if( length >= 4 ) if( length >= 4 )
fprintf (listfp, "key expires after %s", {
strtimevalue( buffer_to_u32(buffer) ) ); if(buffer_to_u32(buffer))
fprintf (listfp, "key expires after %s",
strtimevalue( buffer_to_u32(buffer) ) );
else
fprintf (listfp, "key does not expire");
}
break; break;
case SIGSUBPKT_PREF_SYM: case SIGSUBPKT_PREF_SYM:
fputs("pref-sym-algos:", listfp ); fputs("pref-sym-algos:", listfp );
@ -1408,7 +1418,7 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
log_info ("signature packet without keyid\n"); log_info ("signature packet without keyid\n");
p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL); p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
if(p) if(p && buffer_to_u32(p))
sig->expiredate=sig->timestamp+buffer_to_u32(p); sig->expiredate=sig->timestamp+buffer_to_u32(p);
if(sig->expiredate && sig->expiredate<=make_timestamp()) if(sig->expiredate && sig->expiredate<=make_timestamp())
sig->flags.expired=1; sig->flags.expired=1;
@ -2027,6 +2037,20 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
{ {
byte *p; byte *p;
/* Cap the size of a user ID at 2k: a value absurdly large enough
that there is no sane user ID string (which is printable text
as of RFC2440bis) that won't fit in it, but yet small enough to
avoid allocation problems. A large pktlen may not be
allocatable, and a very large pktlen could actually cause our
allocation to wrap around in xmalloc to a small number. */
if (pktlen > 2048)
{
log_error ("packet(%d) too large\n", pkttype);
iobuf_skip_rest(inp, pktlen, 0);
return G10ERR_INVALID_PACKET;
}
packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id + pktlen); packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id + pktlen);
packet->pkt.user_id->len = pktlen; packet->pkt.user_id->len = pktlen;
packet->pkt.user_id->ref=1; packet->pkt.user_id->ref=1;

View File

@ -320,6 +320,12 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
} }
else 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 /* 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 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 unless --enable-dsa2 is set. If the q isn't 160 bits, then
@ -333,6 +339,7 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
log_error(_("DSA requires the use of a 160 bit hash algorithm\n")); log_error(_("DSA requires the use of a 160 bit hash algorithm\n"));
return G10ERR_GENERAL; return G10ERR_GENERAL;
} }
#endif /* disabled */
frame = encode_md_value( NULL, sk, md, digest_algo ); frame = encode_md_value( NULL, sk, md, digest_algo );
if (!frame) if (!frame)
@ -1539,7 +1546,7 @@ update_keysig_packet( PKT_signature **ret_sig,
} }
/* Note that already expired sigs will remain expired (with a /* Note that already expired sigs will remain expired (with a
duration of 0) since build-packet.c:build_sig_subpkt_from_sig duration of 1) since build-packet.c:build_sig_subpkt_from_sig
detects this case. */ detects this case. */
if( sig->version >= 4 ) if( sig->version >= 4 )