From cvs at cvs.gnupg.org Mon May 4 05:03:39 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Mon, 04 May 2009 05:03:39 +0200 Subject: [svn] GnuPG - r4988 - branches/STABLE-BRANCH-1-4/keyserver Message-ID: Author: dshaw Date: 2009-05-04 05:03:38 +0200 (Mon, 04 May 2009) New Revision: 4988 Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_mailto.in Log: * gpgkeys_mailto.in: Set 'mail-from' as a keyserver-option, rather than the ugly ?from= syntax. Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-04-21 03:04:08 UTC (rev 4987) +++ branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-05-04 03:03:38 UTC (rev 4988) @@ -1,3 +1,8 @@ +2009-05-03 David Shaw + + * gpgkeys_mailto.in: Set 'mail-from' as a keyserver-option, rather + than the ugly ?from= syntax. + 2009-04-20 David Shaw * gpgkeys_hkp.c (srv_replace): New function to transform a SRV Modified: branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_mailto.in =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_mailto.in 2009-04-21 03:04:08 UTC (rev 4987) +++ branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_mailto.in 2009-05-04 03:03:38 UTC (rev 4988) @@ -52,10 +52,6 @@ open(STDIN,$ARGV[0]) || die "Can't open input file $ARGV[0]\n"; } -($login,$name)=(getpwuid($<))[0,6]; - -$from="$name <$login>"; - while() { last if($_ eq "\n"); @@ -85,9 +81,24 @@ { $verbose--; } + elsif($1=~/^mail-from=(.+)$/i) + { + $from=$1; + } + elsif($1=~/^no-mail-from$/i) + { + undef $from; + } + } } +if(!defined($from)) +{ + ($login,$name)=(getpwuid($<))[0,6]; + $from="$name <$login>"; +} + $program="(unknown)" if(!defined($program)); if(!defined($address)) @@ -96,29 +107,6 @@ exit(1); } -# decode $address - -($address,$args)=split(/\?/,$address); - -if(defined($args)) -{ - @pairs = split(/&/, $args); - foreach $pair (@pairs) - { - ($hdr, $val) = split(/=/, $pair); - $hdr =~ tr/+/ /; - $hdr =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; - $val =~ tr/+/ /; - $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; -# we only handle "from" right now - if($hdr=~/^from$/i) - { - $from=$val; - last; - } - } -} - while() { last if($_ eq "\n"); From cvs at cvs.gnupg.org Mon May 4 16:06:31 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 04 May 2009 16:06:31 +0200 Subject: [svn] pinentry - r204 - in trunk: . qt4 Message-ID: Author: marcus Date: 2009-05-04 16:06:30 +0200 (Mon, 04 May 2009) New Revision: 204 Modified: trunk/ChangeLog trunk/qt4/main.cpp Log: 2009-05-04 Till Adam * qt4/main.cpp (qt_cmd_handler): Use WId instead of HWND. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-14 19:27:15 UTC (rev 203) +++ trunk/ChangeLog 2009-05-04 14:06:30 UTC (rev 204) @@ -1,3 +1,7 @@ +2009-05-04 Till Adam + + * qt4/main.cpp (qt_cmd_handler): Use WId instead of HWND. + 2009-04-14 Marcus Brinkmann * pinentry/pinentry.h (struct pinentry): New member NOTOK. Modified: trunk/qt4/main.cpp =================================================================== --- trunk/qt4/main.cpp 2009-04-14 19:27:15 UTC (rev 203) +++ trunk/qt4/main.cpp 2009-05-04 14:06:30 UTC (rev 204) @@ -68,7 +68,7 @@ { /* FIXME: Add parent window ID to pinentry and GTK. */ if (pe->parent_wid) - parent = new ForeignWidget ((HWND) pe->parent_wid); + parent = new ForeignWidget ((WId) pe->parent_wid); PinEntryDialog pinentry (parent, 0, true, !!pe->quality_bar); From cvs at cvs.gnupg.org Tue May 5 05:29:56 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Tue, 05 May 2009 05:29:56 +0200 Subject: [svn] GnuPG - r4989 - trunk/keyserver Message-ID: Author: dshaw Date: 2009-05-05 05:29:56 +0200 (Tue, 05 May 2009) New Revision: 4989 Modified: trunk/keyserver/ChangeLog trunk/keyserver/gpg2keys_mailto.in Log: * gpgkeys_mailto.in: Set 'mail-from' as a keyserver-option, rather than the ugly ?from= syntax. Modified: trunk/keyserver/ChangeLog =================================================================== --- trunk/keyserver/ChangeLog 2009-05-04 03:03:38 UTC (rev 4988) +++ trunk/keyserver/ChangeLog 2009-05-05 03:29:56 UTC (rev 4989) @@ -1,3 +1,8 @@ +2009-05-04 David Shaw + + * gpgkeys_mailto.in: Set 'mail-from' as a keyserver-option, rather + than the ugly ?from= syntax. + 2009-01-22 Werner Koch * Makefile.am (gpg2keys_curl_LDADD, gpg2keys_hkp_LDADD): Add all Modified: trunk/keyserver/gpg2keys_mailto.in =================================================================== --- trunk/keyserver/gpg2keys_mailto.in 2009-05-04 03:03:38 UTC (rev 4988) +++ trunk/keyserver/gpg2keys_mailto.in 2009-05-05 03:29:56 UTC (rev 4989) @@ -52,10 +52,6 @@ open(STDIN,$ARGV[0]) || die "Can't open input file $ARGV[0]\n"; } -($login,$name)=(getpwuid($<))[0,6]; - -$from="$name <$login>"; - while() { last if($_ eq "\n"); @@ -85,9 +81,24 @@ { $verbose--; } + elsif($1=~/^mail-from=(.+)$/i) + { + $from=$1; + } + elsif($1=~/^no-mail-from$/i) + { + undef $from; + } + } } +if(!defined($from)) +{ + ($login,$name)=(getpwuid($<))[0,6]; + $from="$name <$login>"; +} + $program="(unknown)" if(!defined($program)); if(!defined($address)) @@ -96,29 +107,6 @@ exit(1); } -# decode $address - -($address,$args)=split(/\?/,$address); - -if(defined($args)) -{ - @pairs = split(/&/, $args); - foreach $pair (@pairs) - { - ($hdr, $val) = split(/=/, $pair); - $hdr =~ tr/+/ /; - $hdr =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; - $val =~ tr/+/ /; - $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; -# we only handle "from" right now - if($hdr=~/^from$/i) - { - $from=$val; - last; - } - } -} - while() { last if($_ eq "\n"); From cvs at cvs.gnupg.org Tue May 5 11:30:35 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 05 May 2009 11:30:35 +0200 Subject: [svn] GnuPG - r4990 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2009-05-05 11:30:34 +0200 (Tue, 05 May 2009) New Revision: 4990 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/parse-packet.c branches/STABLE-BRANCH-1-4/g10/tdbio.c Log: Fix bug#931. Silent a compiler warning. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-05 03:29:56 UTC (rev 4989) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-05 09:30:34 UTC (rev 4990) @@ -1,3 +1,12 @@ +2009-05-05 Werner Koch + + * tdbio.c (lookup_hashtable): Add const to function args. + (cmp_trec_fpr): Ditto. + (tdbio_search_trust_byfpr): Remove cast. + + * parse-packet.c (parse): Remove special treatment for compressed + new style packets. Fixes bug#931. + 2009-04-03 Werner Koch * gpgv.c (main): Pass readonly flag to keydb_add_resource. Modified: branches/STABLE-BRANCH-1-4/g10/parse-packet.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/parse-packet.c 2009-05-05 03:29:56 UTC (rev 4989) +++ branches/STABLE-BRANCH-1-4/g10/parse-packet.c 2009-05-05 09:30:34 UTC (rev 4990) @@ -346,12 +346,19 @@ rc = G10ERR_INVALID_PACKET; goto leave; } - if (pkttype == PKT_COMPRESSED) { - iobuf_set_partial_block_mode(inp, c & 0xff); - pktlen = 0;/* to indicate partial length */ - partial=1; - } - else { +/* The follwing code has been here for ages (2002-08-30) but it is + clearly wrong: For example passing a 0 as second argument to + iobuf_set_partial_block_mode stops the partial block mode which we + definitely do not want. Also all values < 224 or 255 are not + valid. Let's disable it and put PKT_COMPRESSED into the list of + allowed packets with partial header until someone complains. */ +/* if (pkttype == PKT_COMPRESSED) { */ +/* iobuf_set_partial_block_mode(inp, c & 0xff); */ +/* pktlen = 0;/\* to indicate partial length *\/ */ +/* partial=1; */ +/* } */ +/* else { */ + { hdr[hdrlen++] = c; if( c < 192 ) pktlen = c; @@ -384,20 +391,22 @@ } else { - /* Partial body length. Note that we handled - PKT_COMPRESSED earlier. */ - if(pkttype==PKT_PLAINTEXT || pkttype==PKT_ENCRYPTED - || pkttype==PKT_ENCRYPTED_MDC) - { - iobuf_set_partial_block_mode(inp, c & 0xff); - pktlen = 0;/* to indicate partial length */ - partial=1; - } - else - { - log_error("%s: partial length for invalid" - " packet type %d\n",iobuf_where(inp),pkttype); - rc=G10ERR_INVALID_PACKET; + /* Partial body length. */ + switch (pkttype) + { + case PKT_PLAINTEXT: + case PKT_ENCRYPTED: + case PKT_ENCRYPTED_MDC: + case PKT_COMPRESSED: + iobuf_set_partial_block_mode (inp, (c & 0xff)); + pktlen = 0; /* Indicate partial length. */ + partial= 1; + break; + + default: + log_error ("%s: partial length for invalid" + " packet type %d\n", iobuf_where(inp),pkttype); + rc = G10ERR_INVALID_PACKET; goto leave; } } Modified: branches/STABLE-BRANCH-1-4/g10/tdbio.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/tdbio.c 2009-05-05 03:29:56 UTC (rev 4989) +++ branches/STABLE-BRANCH-1-4/g10/tdbio.c 2009-05-05 09:30:34 UTC (rev 4990) @@ -1007,8 +1007,8 @@ */ static int lookup_hashtable( ulong table, const byte *key, size_t keylen, - int (*cmpfnc)(void*, const TRUSTREC *), void *cmpdata, - TRUSTREC *rec ) + int (*cmpfnc)(const void*, const TRUSTREC *), + const void *cmpdata, TRUSTREC *rec ) { int rc; ulong hashrec, item; @@ -1464,10 +1464,10 @@ static int -cmp_trec_fpr ( void *fpr, const TRUSTREC *rec ) +cmp_trec_fpr (const void *fpr, const TRUSTREC *rec ) { - return rec->rectype == RECTYPE_TRUST - && !memcmp( rec->r.trust.fingerprint, fpr, 20); + return (rec->rectype == RECTYPE_TRUST + && !memcmp( rec->r.trust.fingerprint, fpr, 20)); } @@ -1476,9 +1476,9 @@ { int rc; - /* locate the trust record using the hash table */ - rc = lookup_hashtable( get_trusthashrec(), fingerprint, 20, - cmp_trec_fpr, (void*)fingerprint, rec ); + /* Locate the trust record using the hash table. */ + rc = lookup_hashtable (get_trusthashrec(), fingerprint, 20, + cmp_trec_fpr, fingerprint, rec); return rc; } From cvs at cvs.gnupg.org Tue May 5 13:44:56 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 05 May 2009 13:44:56 +0200 Subject: [svn] GnuPG - r4991 - in branches/STABLE-BRANCH-1-4: g10 include util Message-ID: Author: wk Date: 2009-05-05 13:44:56 +0200 (Tue, 05 May 2009) New Revision: 4991 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/keygen.c branches/STABLE-BRANCH-1-4/include/util.h branches/STABLE-BRANCH-1-4/util/ChangeLog branches/STABLE-BRANCH-1-4/util/miscutil.c Log: Backport of Creation-Date parameter for unattended key generation. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-05 09:30:34 UTC (rev 4990) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-05 11:44:56 UTC (rev 4991) @@ -1,5 +1,16 @@ 2009-05-05 Werner Koch + * keygen.c (output_control_s): s/create/creation/. + (enum para_name): Add pCREATIONDATE, pKEYCREATIONDATE. Remove + pCREATETIME. + (generate_keypair): Do not set old pCREATETIME. + (parse_creation_string): New. + (proc_parameter_file): Set pCREATIONDATE. + (read_parameter_file): Add keyword "Creation-Date". + (do_generate_keypair): Remove arg TIMESTAMP. Set it using + pKEYCREATIONDATE. + (get_parameter_u32): Set a default pKEYCREATIONDATE. + * tdbio.c (lookup_hashtable): Add const to function args. (cmp_trec_fpr): Ditto. (tdbio_search_trust_byfpr): Remove cast. Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-05-05 09:30:34 UTC (rev 4990) +++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-05-05 11:44:56 UTC (rev 4991) @@ -1,3 +1,7 @@ +2009-05-05 Werner Koch + + * miscutil.c (isotime2seconds): New. + 2009-04-05 David Shaw * srv.h: Move to include/srv.h. Modified: branches/STABLE-BRANCH-1-4/g10/keygen.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keygen.c 2009-05-05 09:30:34 UTC (rev 4990) +++ branches/STABLE-BRANCH-1-4/g10/keygen.c 2009-05-05 11:44:56 UTC (rev 4991) @@ -57,8 +57,9 @@ pPREFERENCES, pREVOKER, pUSERID, + pCREATIONDATE, + pKEYCREATIONDATE, /* Same in seconds since epoch. */ pEXPIREDATE, - pCREATETIME, /* in n seconds */ pKEYEXPIRE, /* in n seconds */ pSUBKEYEXPIRE, /* in n seconds */ pPASSPHRASE, @@ -77,8 +78,8 @@ union { DEK *dek; STRING2KEY *s2k; - u32 create; u32 expire; + u32 creation; unsigned int usage; struct revocation_key revkey; char value[1]; @@ -119,9 +120,9 @@ static int nzip_prefs; static int mdc_available,ks_modify; -static void do_generate_keypair( struct para_data_s *para, +static void do_generate_keypair (struct para_data_s *para, struct output_control_s *outctrl, - u32 timestamp, int card ); + int card); static int write_keyblock( IOBUF out, KBNODE node ); static int gen_card_key (int algo, int keyno, int is_primary, KBNODE pub_root, KBNODE sec_root, @@ -1595,25 +1596,43 @@ * similar. */ u32 -parse_expire_string(u32 timestamp,const char *string) +parse_expire_string (u32 timestamp, const char *string) { - int mult; - u32 seconds,abs_date=0; + int mult; + u32 seconds; + u32 abs_date = 0; - if( !*string ) - seconds = 0; - else if ( !strncmp (string, "seconds=", 8) ) - seconds = atoi (string+8); - else if( (abs_date = scan_isodatestr(string)) && abs_date > timestamp ) - seconds = abs_date - timestamp; - else if( (mult=check_valid_days(string)) ) - seconds = atoi(string) * 86400L * mult; - else - seconds=(u32)-1; + if ( !*string ) + seconds = 0; + else if ( !strncmp (string, "seconds=", 8) ) + seconds = atoi (string+8); + else if( (abs_date = scan_isodatestr(string)) && abs_date > timestamp ) + seconds = abs_date - timestamp; + else if( (mult=check_valid_days(string)) ) + seconds = atoi(string) * 86400L * mult; + else + seconds=(u32)-1; + + return seconds; +} - return seconds; +/* Parse an Creation-Date string which is either "1986-04-26" or + "19860426T042640". Returns 0 on error. */ +static u32 +parse_creation_string (const char *string) +{ + u32 seconds; + + if (!*string) + seconds = 0; + else if ( !strncmp (string, "seconds=", 8) ) + seconds = atoi (string+8); + else if ( !(seconds = scan_isodatestr (string))) + seconds = isotime2seconds (string); + return seconds; } + /* object == 0 for a key, and 1 for a sig */ u32 ask_expire_interval(u32 timestamp,int object,const char *def_expire) @@ -1678,7 +1697,7 @@ } cpr_kill_prompt(); trim_spaces(answer); - interval = parse_expire_string( timestamp, answer ); + interval = parse_expire_string (timestamp, answer); if( interval == (u32)-1 ) { tty_printf(_("invalid value\n")); @@ -2121,16 +2140,56 @@ static u32 get_parameter_u32( struct para_data_s *para, enum para_name key ) { - struct para_data_s *r = get_parameter( para, key ); + struct para_data_s *r; - if( !r ) - return 0; + r = get_parameter (para, key); + if (!r && key == pKEYCREATIONDATE) + { + /* Return a default for the creation date if it has not yet been + set. We need to set this into the parameter list so that a + second call for pKEYCREATIONDATE returns the same value. The + default is the current time unless an explicit creation date + has been specified. Checking the creation date here is only + for the case that it has not yet been parsed. */ + r = get_parameter (para, pCREATIONDATE); + if (r && *r->u.value) + { + u32 seconds; + + seconds = parse_creation_string (r->u.value); + if (!seconds) + log_error ("invalid creation date in line %d\n", r->lnr ); + else /* Okay: Change this parameter. */ + { + r->u.creation = seconds; + r->key = pKEYCREATIONDATE; + } + } + + r = get_parameter (para, key); + if (!r) + { + /* Create a new parameter. */ + r = xmalloc_clear (sizeof *r); + r->key = key; + r->u.creation = make_timestamp (); + r->next = para; + para = r; + } + + r = get_parameter (para, key); + assert (r); + } + + + if (!r) + return 0; + if( r->key == pKEYCREATIONDATE ) + return r->u.creation; if( r->key == pKEYEXPIRE || r->key == pSUBKEYEXPIRE ) return r->u.expire; if( r->key == pKEYUSAGE || r->key == pSUBKEYUSAGE ) return r->u.usage; - if( r->key == pCREATETIME ) - return r->u.create; return (unsigned int)strtoul( r->u.value, NULL, 10 ); } @@ -2171,14 +2230,7 @@ size_t n; char *p; int have_user_id=0,err,algo; - u32 timestamp; - /* If we were told a creation time from outside, use it. Otherwise - look at the clock. */ - timestamp=get_parameter_u32( para, pCREATETIME ); - if(!timestamp) - timestamp=make_timestamp(); - /* Check that we have all required parameters. */ r = get_parameter( para, pKEYTYPE ); if(r) @@ -2315,9 +2367,9 @@ /* make DEK and S2K from the Passphrase */ r = get_parameter( para, pPASSPHRASE ); if( r && *r->u.value ) { - /* we have a plain text passphrase - create a DEK from it. - * It is a little bit ridiculous to keep it ih secure memory - * but becuase we do this alwasy, why not here */ + /* We have a plain text passphrase - create a DEK from it. + * It is a little bit ridiculous to keep it in secure memory + * but because we do this alwasy, why not here. */ STRING2KEY *s2k; DEK *dek; @@ -2343,14 +2395,31 @@ para = r; } - /* make KEYEXPIRE from Expire-Date */ + /* Make KEYCREATIONDATE from Creation-Date. */ + r = get_parameter (para, pCREATIONDATE); + if (r && *r->u.value) + { + u32 seconds; + + seconds = parse_creation_string (r->u.value); + if (!seconds) + { + log_error ("%s:%d: invalid creation date\n", fname, r->lnr ); + return -1; + } + r->u.creation = seconds; + r->key = pKEYCREATIONDATE; /* Change that entry. */ + } + + /* Make KEYEXPIRE from Expire-Date. */ r = get_parameter( para, pEXPIREDATE ); if( r && *r->u.value ) { u32 seconds; - seconds = parse_expire_string( timestamp, r->u.value ); - if( seconds == (u32)-1 ) + seconds = parse_expire_string + (get_parameter_u32 (para, pKEYCREATIONDATE), r->u.value); + if (seconds == (u32)(-1)) { log_error("%s:%d: invalid expire date\n", fname, r->lnr ); return -1; @@ -2370,7 +2439,7 @@ return -1; } - do_generate_keypair( para, outctrl, timestamp, card ); + do_generate_keypair (para, outctrl, card); return 0; } @@ -2396,6 +2465,7 @@ { "Name-Email", pNAMEEMAIL }, { "Name-Comment", pNAMECOMMENT }, { "Expire-Date", pEXPIREDATE }, + { "Creation-Date", pCREATIONDATE }, { "Passphrase", pPASSPHRASE }, { "Preferences", pPREFERENCES }, { "Revoker", pREVOKER }, @@ -2600,7 +2670,7 @@ int algo; unsigned int use; int both = 0; - u32 timestamp,expire; + u32 expire; struct para_data_s *para = NULL; struct para_data_s *r; struct output_control_s outctrl; @@ -2620,13 +2690,6 @@ return; } - timestamp=make_timestamp(); - r = xmalloc_clear( sizeof *r ); - r->key = pCREATETIME; - r->u.create = timestamp; - r->next = para; - para = r; - if (card_serialno) { #ifdef ENABLE_CARD_SUPPORT @@ -2741,7 +2804,8 @@ para = r; } - expire = ask_expire_interval(timestamp,0,NULL); + expire = ask_expire_interval (get_parameter_u32 (para, pKEYCREATIONDATE), + 0, NULL); r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYEXPIRE; r->u.expire = expire; @@ -2878,8 +2942,8 @@ } static void -do_generate_keypair( struct para_data_s *para,struct output_control_s *outctrl, - u32 timestamp,int card ) +do_generate_keypair (struct para_data_s *para,struct output_control_s *outctrl, + int card) { KBNODE pub_root = NULL; KBNODE sec_root = NULL; @@ -2888,6 +2952,7 @@ struct revocation_key *revkey; int rc; int did_sub = 0; + u32 timestamp; if( outctrl->dryrun ) { @@ -2965,7 +3030,7 @@ } - /* we create the packets as a tree of kbnodes. Because the + /* We create the packets as a tree of kbnodes. Because the * structure we create is known in advance we simply generate a * linked list. The first packet is a dummy packet which we flag * as deleted. The very first packet must always be a KEY packet. @@ -2974,6 +3039,8 @@ start_tree(&pub_root); start_tree(&sec_root); + timestamp = get_parameter_u32 (para, pKEYCREATIONDATE); + if (!card) { rc = do_create( get_parameter_algo( para, pKEYTYPE ), Modified: branches/STABLE-BRANCH-1-4/include/util.h =================================================================== --- branches/STABLE-BRANCH-1-4/include/util.h 2009-05-05 09:30:34 UTC (rev 4990) +++ branches/STABLE-BRANCH-1-4/include/util.h 2009-05-05 11:44:56 UTC (rev 4991) @@ -149,6 +149,7 @@ /*-- miscutil.c --*/ u32 make_timestamp(void); u32 scan_isodatestr( const char *string ); +u32 isotime2seconds (const char *string); const char *strtimevalue( u32 stamp ); const char *strtimestamp( u32 stamp ); /* GMT */ const char *isotimestamp( u32 stamp ); /* GMT with hh:mm:ss */ Modified: branches/STABLE-BRANCH-1-4/util/miscutil.c =================================================================== --- branches/STABLE-BRANCH-1-4/util/miscutil.c 2009-05-05 09:30:34 UTC (rev 4990) +++ branches/STABLE-BRANCH-1-4/util/miscutil.c 2009-05-05 11:44:56 UTC (rev 4991) @@ -152,6 +152,57 @@ return buffer; } + +/* Scan am ISO timestamp and return an Epoch based timestamp. The only + supported format is "yyyymmddThhmmss" delimited by white space, nul, a + colon or a comma. Returns 0 for an invalid string. */ +u32 +isotime2seconds (const char *string) +{ + const char *s; + int year, month, day, hour, minu, sec; + struct tm tmbuf; + int i; + time_t result; + + if (!*string) + return 0; + for (s=string, i=0; i < 8; i++, s++) + if (!digitp (s)) + return 0; + if (*s != 'T') + return 0; + for (s++, i=9; i < 15; i++, s++) + if (!digitp (s)) + return 0; + if ( !(!*s || (isascii (*s) && isspace(*s)) || *s == ':' || *s == ',')) + return 0; /* Wrong delimiter. */ + + year = atoi_4 (string); + month = atoi_2 (string + 4); + day = atoi_2 (string + 6); + hour = atoi_2 (string + 9); + minu = atoi_2 (string + 11); + sec = atoi_2 (string + 13); + + /* Basic checks. */ + if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 + || hour > 23 || minu > 59 || sec > 61 ) + return 0; + + memset (&tmbuf, 0, sizeof tmbuf); + tmbuf.tm_sec = sec; + tmbuf.tm_min = minu; + tmbuf.tm_hour = hour; + tmbuf.tm_mday = day; + tmbuf.tm_mon = month-1; + tmbuf.tm_year = year - 1900; + tmbuf.tm_isdst = -1; + result = timegm (&tmbuf); + return (result == (time_t)(-1))? 0 : (u32)result; +} + + /**************** * Note: this function returns local time */ From cvs at cvs.gnupg.org Tue May 5 17:32:17 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 05 May 2009 17:32:17 +0200 Subject: [svn] GnuPG - r4992 - in branches/STABLE-BRANCH-1-4: . g10 util Message-ID: Author: wk Date: 2009-05-05 17:32:16 +0200 (Tue, 05 May 2009) New Revision: 4992 Modified: branches/STABLE-BRANCH-1-4/NEWS branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/util/ChangeLog branches/STABLE-BRANCH-1-4/util/dotlock.c Log: Improve dotlocking. Implement locking for W32. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-05 11:44:56 UTC (rev 4991) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-05 15:32:16 UTC (rev 4992) @@ -1,12 +1,12 @@ 2009-05-05 Werner Koch - * keygen.c (output_control_s): s/create/creation/. + * keygen.c (read_parameter_file): Add keyword "Creation-Date". + (output_control_s): s/create/creation/. (enum para_name): Add pCREATIONDATE, pKEYCREATIONDATE. Remove pCREATETIME. (generate_keypair): Do not set old pCREATETIME. (parse_creation_string): New. (proc_parameter_file): Set pCREATIONDATE. - (read_parameter_file): Add keyword "Creation-Date". (do_generate_keypair): Remove arg TIMESTAMP. Set it using pKEYCREATIONDATE. (get_parameter_u32): Set a default pKEYCREATIONDATE. Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-05-05 11:44:56 UTC (rev 4991) +++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-05-05 15:32:16 UTC (rev 4992) @@ -1,5 +1,8 @@ 2009-05-05 Werner Koch + * dotlock.c: Merged changes from GnuPG-2. Better detection of + stale lockfiles and actual locking support on W32. Fixes bug#1028. + * miscutil.c (isotime2seconds): New. 2009-04-05 David Shaw Modified: branches/STABLE-BRANCH-1-4/NEWS =================================================================== --- branches/STABLE-BRANCH-1-4/NEWS 2009-05-05 11:44:56 UTC (rev 4991) +++ branches/STABLE-BRANCH-1-4/NEWS 2009-05-05 15:32:16 UTC (rev 4992) @@ -4,7 +4,9 @@ * The algorithm to compute the SIG_ID status has been changed to match the one from 2.0.10. + * Improved file locking. Implemented it for W32. + Noteworthy changes in version 1.4.9 (2008-03-26) ------------------------------------------------ Modified: branches/STABLE-BRANCH-1-4/util/dotlock.c =================================================================== --- branches/STABLE-BRANCH-1-4/util/dotlock.c 2009-05-05 11:44:56 UTC (rev 4991) +++ branches/STABLE-BRANCH-1-4/util/dotlock.c 2009-05-05 15:32:16 UTC (rev 4992) @@ -1,6 +1,6 @@ /* dotlock.c - dotfile locking * Copyright (C) 1998, 1999, 2000, 2001, 2004, - * 2005 Free Software Foundation, Inc. + * 2005, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -25,8 +25,11 @@ #include #include #include -#if !defined (HAVE_DOSISH_SYSTEM) -#include +#ifdef HAVE_DOSISH_SYSTEM +# define WIN32_LEAN_AND_MEAN +# include +#else +# include #endif #include #ifndef _WIN32 @@ -38,25 +41,50 @@ #include "types.h" #include "util.h" #include "memory.h" +#include "i18n.h" + +/* The object describing a lock. */ struct dotlock_handle { struct dotlock_handle *next; char *tname; /* name of lockfile template */ char *lockname; /* name of the real lockfile */ int locked; /* lock status */ int disable; /* locking */ +#ifdef HAVE_DOSISH_SYSTEM + HANDLE lockhd; /* The W32 handle of the lock file. */ +#else + size_t nodename_off; /* Offset in TNAME to the nodename part. */ + size_t nodename_len; /* Length of the nodename part. */ +#endif }; +/* A list of of all lock handles. */ static volatile DOTLOCK all_lockfiles; + +/* If this has the value true all locking is disabled. */ static int never_lock; + +#ifdef _REENTRANT + /* fixme: acquire mutex on all_lockfiles */ +# define lock_all_lockfiles(h) do { } while (0) +# define unlock_all_lockfiles(h) do { } while (0) +#else +# define lock_all_lockfiles(h) do { } while (0) +# define unlock_all_lockfiles(h) do { } while (0) +#endif + + + void disable_dotlock(void) { - never_lock = 1; + never_lock = 1; } + /**************** * Create a lockfile with the given name and return an object of * type DOTLOCK which may be used later to actually do the lock. @@ -78,14 +106,16 @@ { static int initialized; DOTLOCK h; -#if !defined (HAVE_DOSISH_SYSTEM) +#ifndef HAVE_DOSISH_SYSTEM int fd = -1; char pidstr[16]; struct utsname utsbuf; const char *nodename; const char *dirpart; int dirpartlen; -#endif + size_t tnamelen; + int n; +#endif /*!HAVE_DOSISH_SYSTEM*/ if( !initialized ) { atexit( remove_lockfiles ); @@ -97,18 +127,15 @@ h = xmalloc_clear( sizeof *h ); if( never_lock ) { h->disable = 1; -#ifdef _REENTRANT - /* fixme: aquire mutex on all_lockfiles */ -#endif + lock_all_lockfiles (h); h->next = all_lockfiles; all_lockfiles = h; return h; } -#if !defined (HAVE_DOSISH_SYSTEM) - sprintf( pidstr, "%10d\n", (int)getpid() ); - /* fixme: add the hostname to the second line (FQDN or IP addr?) */ +#ifndef HAVE_DOSISH_SYSTEM + snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() ); /* create a temporary file */ if( uname( &utsbuf ) ) @@ -116,14 +143,14 @@ else nodename = utsbuf.nodename; -#ifdef __riscos__ +# ifdef __riscos__ { char *iter = (char *) nodename; for (; iter[0]; iter++) if (iter[0] == '.') iter[0] = '/'; } -#endif /* __riscos__ */ +# endif /* __riscos__ */ if( !(dirpart = strrchr( file_to_lock, DIRSEP_C )) ) { dirpart = EXTSEP_S; @@ -134,25 +161,27 @@ dirpart = file_to_lock; } -#ifdef _REENTRANT - /* fixme: aquire mutex on all_lockfiles */ -#endif + lock_all_lockfiles (h); h->next = all_lockfiles; all_lockfiles = h; - h->tname = xmalloc( dirpartlen + 6+30+ strlen(nodename) + 11 ); -#ifndef __riscos__ - sprintf( h->tname, "%.*s/.#lk%p.%s.%d", - dirpartlen, dirpart, (void *)h, nodename, (int)getpid() ); -#else /* __riscos__ */ - sprintf( h->tname, "%.*s.lk%p/%s/%d", - dirpartlen, dirpart, (void *)h, nodename, (int)getpid() ); -#endif /* __riscos__ */ + tnamelen = dirpartlen + 6+30+ strlen(nodename) + 10; + h->tname = xmalloc (tnamelen + 1); + h->nodename_len = strlen (nodename); +# ifndef __riscos__ + snprintf (h->tname, tnamelen, "%.*s/.#lk%p.%n%s.%d", + dirpartlen, dirpart, (void *)h, &n, nodename, (int)getpid ()); +# else /* __riscos__ */ + snprintf (h->tname, tnamelen, "%.*s.lk%p/%n%s/%d", + dirpartlen, dirpart, (void *)h, &n, nodename, (int)getpid ()); +# endif /* __riscos__ */ + h->nodename_off = n; + do { errno = 0; - fd = open( h->tname, O_WRONLY|O_CREAT|O_EXCL, - S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR ); + fd = open (h->tname, O_WRONLY|O_CREAT|O_EXCL, + S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR); } while( fd == -1 && errno == EINTR ); if( fd == -1 ) { all_lockfiles = h->next; @@ -162,78 +191,110 @@ xfree(h); return NULL; } - if( write(fd, pidstr, 11 ) != 11 ) { - all_lockfiles = h->next; -#ifdef _REENTRANT - /* release mutex */ -#endif - log_fatal( "error writing to `%s': %s\n", h->tname, strerror(errno) ); - close(fd); - unlink(h->tname); - xfree(h->tname); - xfree(h); - return NULL; - } - if( close(fd) ) { - all_lockfiles = h->next; -#ifdef _REENTRANT - /* release mutex */ -#endif - log_error( "error closing `%s': %s\n", h->tname, strerror(errno)); - unlink(h->tname); - xfree(h->tname); - xfree(h); - return NULL; - } + if (write (fd, pidstr, 11) != 11) + goto write_failed; + if (write (fd, nodename, strlen (nodename)) != strlen (nodename)) + goto write_failed; + if (write (fd, "\n", 1 ) != 1) + goto write_failed; + if (close (fd)) + goto write_failed; -#ifdef _REENTRANT - /* release mutex */ -#endif -#endif + unlock_all_lockfiles (h); h->lockname = xmalloc( strlen(file_to_lock) + 6 ); strcpy(stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock"); return h; + + write_failed: + all_lockfiles = h->next; + unlock_all_lockfiles (h); + log_error ("error writing to `%s': %s\n", h->tname, strerror(errno)); + close (fd); + unlink (h->tname); + xfree (h->tname); + xfree (h); + return NULL; + +#else /* HAVE_DOSISH_SYSTEM */ + + /* The Windows version does not need a temporary file but uses the + plain lock file along with record locking. We create this file + here so that we later do only need to do the file locking. For + error reporting it is useful to keep the name of the file in the + handle. */ + h->next = all_lockfiles; + all_lockfiles = h; + + h->lockname = xmalloc ( strlen (file_to_lock) + 6 ); + strcpy (stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock"); + + /* If would be nice if we would use the FILE_FLAG_DELETE_ON_CLOSE + along with FILE_SHARE_DELETE but that does not work due to a race + condition: Despite the OPEN_ALWAYS flag CreateFile may return an + error and we can't reliable create/open the lock file unless we + would wait here until it works - however there are other valid + reasons why a lock file can't be created and thus the process + would not stop as expected but spin until Windows crashes. Our + solution is to keep the lock file open; that does not harm. */ + h->lockhd = CreateFile (h->lockname, + GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, OPEN_ALWAYS, 0, NULL); + if (h->lockhd == INVALID_HANDLE_VALUE) + { + log_error (_("can't create `%s': %s\n"), h->lockname, w32_strerror (-1)); + all_lockfiles = h->next; + xfree (h->lockname); + xfree (h); + return NULL; + } + return h; + +#endif /* HAVE_DOSISH_SYSTEM */ } void destroy_dotlock ( DOTLOCK h ) { -#if !defined (HAVE_DOSISH_SYSTEM) - if ( h ) - { - DOTLOCK hprev, htmp; + DOTLOCK hprev, htmp; - /* First remove the handle from our global list of all locks. */ - for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next) - if (htmp == h) - { - if (hprev) - hprev->next = htmp->next; - else - all_lockfiles = htmp->next; - h->next = NULL; - break; - } + if (!h) + return; - /* Second destroy the lock. */ - if (!h->disable) - { - if (h->locked && h->lockname) - unlink (h->lockname); - if (h->tname) - unlink (h->tname); - xfree (h->tname); - xfree (h->lockname); - } - xfree(h); + /* First remove the handle from our global list of all locks. */ + for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next) + if (htmp == h) + { + if (hprev) + hprev->next = htmp->next; + else + all_lockfiles = htmp->next; + h->next = NULL; + break; + } - } + /* Second destroy the lock. */ + if (!h->disable) + { +#ifdef HAVE_DOSISH_SYSTEM + if (h->locked) + UnlockFile (h->lockhd, 0, 0, 1, 0); + CloseHandle (h->lockhd); +#else + if (h->locked && h->lockname) + unlink (h->lockname); + if (h->tname) + unlink (h->tname); + xfree (h->tname); #endif + xfree (h->lockname); + } + xfree(h); } + #ifndef HAVE_DOSISH_SYSTEM - static int maybe_deadlock( DOTLOCK h ) { @@ -245,44 +306,101 @@ } return 0; } +#endif /* !HAVE_DOSISH_SYSTEM */ -/**************** - * Read the lock file and return the pid, returns -1 on error. - */ + +/* Read the lock file and return the pid, returns -1 on error. True + will be stored in the integer at address SAME_NODE if the lock file + has been created on the same node. */ +#ifndef HAVE_DOSISH_SYSTEM static int -read_lockfile( const char *name ) +read_lockfile (DOTLOCK h, int *same_node ) { - int fd, pid; - char pidstr[16]; + char buffer_space[10+1+70+1]; /* 70 is just an estimated value; node + names are usually shorter. */ + int fd; + int pid = -1; + char *buffer, *p; + size_t expected_len; + int res, nread; + + *same_node = 0; + expected_len = 10 + 1 + h->nodename_len + 1; + if ( expected_len >= sizeof buffer_space) + buffer = xmalloc (expected_len); + else + buffer = buffer_space; - if( (fd = open(name, O_RDONLY)) == -1 ) { - int e = errno; - log_debug("error opening lockfile `%s': %s\n", name, strerror(errno) ); - errno = e; - return -1; + if ( (fd = open (h->lockname, O_RDONLY)) == -1 ) + { + int e = errno; + log_info ("error opening lockfile `%s': %s\n", + h->lockname, strerror(errno) ); + if (buffer != buffer_space) + xfree (buffer); + errno = e; /* Need to return ERRNO here. */ + return -1; } - if( read(fd, pidstr, 10 ) != 10 ) { /* Read 10 digits w/o newline */ - log_debug("error reading lockfile `%s'", name ); - close(fd); - errno = 0; - return -1; + + p = buffer; + nread = 0; + do + { + res = read (fd, p, expected_len - nread); + if (res == -1 && errno == EINTR) + continue; + if (res < 0) + { + log_info ("error reading lockfile `%s'", h->lockname ); + close (fd); + if (buffer != buffer_space) + xfree (buffer); + errno = 0; /* Do not return an inappropriate ERRNO. */ + return -1; + } + p += res; + nread += res; } - pidstr[10] = 0; /* terminate pid string */ - close(fd); - pid = atoi(pidstr); + while (res && nread != expected_len); + close (fd); + + if (nread < 11) + { + log_info ("invalid size of lockfile `%s'", h->lockname ); + if (buffer != buffer_space) + xfree (buffer); + errno = 0; /* Better don't return an inappropriate ERRNO. */ + return -1; + } + + if (buffer[10] != '\n' + || (buffer[10] = 0, pid = atoi (buffer)) == -1 #ifndef __riscos__ - if( !pid || pid == -1 ) { + || !pid #else /* __riscos__ */ - if( (!pid && riscos_getpid()) || pid == -1 ) { + || (!pid && riscos_getpid()) #endif /* __riscos__ */ - log_error("invalid pid %d in lockfile `%s'", pid, name ); - errno = 0; - return -1; + ) + { + log_error ("invalid pid %d in lockfile `%s'", pid, h->lockname ); + if (buffer != buffer_space) + xfree (buffer); + errno = 0; + return -1; } - return pid; + + if (nread == expected_len + && !memcmp (h->tname+h->nodename_off, buffer+11, h->nodename_len) + && buffer[11+h->nodename_len] == '\n') + *same_node = 1; + + if (buffer != buffer_space) + xfree (buffer); + return pid; } #endif /* !HAVE_DOSISH_SYSTEM */ + /**************** * Do a lock on H. A TIMEOUT of 0 returns immediately, * -1 waits forever (hopefully not), other @@ -292,90 +410,129 @@ int make_dotlock( DOTLOCK h, long timeout ) { -#if defined (HAVE_DOSISH_SYSTEM) + int backoff=0; +#ifndef HAVE_DOSISH_SYSTEM + int pid; + const char *maybe_dead=""; + int same_node; +#endif + + if (h->disable) return 0; -#else - int pid; - const char *maybe_dead=""; - int backoff=0; - if( h->disable ) { - return 0; - } - - if( h->locked ) { + if (h->locked) + { #ifndef __riscos__ - log_debug("oops, `%s' is already locked\n", h->lockname ); + log_debug ("oops, `%s' is already locked\n", h->lockname); #endif /* !__riscos__ */ - return 0; + return 0; } - - for(;;) { -#ifndef __riscos__ - if( !link(h->tname, h->lockname) ) { - /* fixme: better use stat to check the link count */ - h->locked = 1; - return 0; /* okay */ + + for (;;) + { +#ifndef HAVE_DOSISH_SYSTEM +# ifndef __riscos__ + if( !link(h->tname, h->lockname) ) + { + /* fixme: better use stat to check the link count */ + h->locked = 1; + return 0; /* okay */ } - if( errno != EEXIST ) { - log_error( "lock not made: link() failed: %s\n", strerror(errno) ); - return -1; + if (errno != EEXIST) + { + log_error ("lock not made: link() failed: %s\n", strerror(errno)); + return -1; } -#else /* __riscos__ */ - if( !riscos_renamefile(h->tname, h->lockname) ) { - h->locked = 1; - return 0; /* okay */ +# else /* __riscos__ */ + if ( !riscos_renamefile(h->tname, h->lockname) ) + { + h->locked = 1; + return 0; /* okay */ } - if( errno != EEXIST ) { - log_error( "lock not made: rename() failed: %s\n", strerror(errno) ); - return -1; + if (errno != EEXIST) + { + log_error ("lock not made: rename() failed: %s\n", strerror(errno)); + return -1; } -#endif /* __riscos__ */ - if( (pid = read_lockfile(h->lockname)) == -1 ) { - if( errno != ENOENT ) { - log_info("cannot read lockfile\n"); - return -1; +# endif /* __riscos__ */ + + if ((pid = read_lockfile (h, &same_node)) == -1 ) + { + if (errno != ENOENT) + { + log_info ("cannot read lockfile\n"); + return -1; } - log_info( "lockfile disappeared\n"); - continue; + log_info ("lockfile disappeared\n"); + continue; } - else if( pid == getpid() ) { - log_info( "Oops: lock already held by us\n"); - h->locked = 1; - return 0; /* okay */ + else if (pid == getpid ()) + { + log_info ("Oops: lock already held by us\n"); + h->locked = 1; + return 0; /* okay */ } - else if( kill(pid, 0) && errno == ESRCH ) { -#ifndef __riscos__ - maybe_dead = " - probably dead"; -#if 0 /* we should not do this without checking the permissions */ - /* and the hostname */ - log_info( "removing stale lockfile (created by %d)", pid ); -#endif -#else /* __riscos__ */ - /* we are *pretty* sure that the other task is dead and therefore - we remove the other lock file */ - maybe_dead = " - probably dead - removing lock"; - unlink(h->lockname); -#endif /* __riscos__ */ + else if (same_node && kill(pid, 0) && errno == ESRCH) + { +# ifndef __riscos__ + log_info (_("removing stale lockfile (created by %d)\n"), pid ); + unlink (h->lockname); + continue; +# else /* __riscos__ */ + /* We are *pretty* sure that the other task is dead and + therefore we remove the other lock file. */ + maybe_dead = " - probably dead - removing lock"; + unlink (h->lockname); +# endif /* __riscos__ */ } - if( timeout == -1 ) { - struct timeval tv; - log_info( "waiting for lock (held by %d%s) %s...\n", - pid, maybe_dead, maybe_deadlock(h)? "(deadlock?) ":""); + if (timeout == -1) + { + struct timeval tv; - /* can't use sleep, cause signals may be blocked */ + log_info ("waiting for lock (held by %d%s) %s...\n", + pid, maybe_dead, maybe_deadlock(h)? "(deadlock?) ":""); + + + /* We can't use sleep, because signals may be blocked. */ tv.tv_sec = 1 + backoff; tv.tv_usec = 0; - select(0, NULL, NULL, NULL, &tv); - if( backoff < 10 ) - backoff++ ; + select (0, NULL, NULL, NULL, &tv); + if (backoff < 10) + backoff++ ; } - else - return -1; + else + return -1; + +#else /*HAVE_DOSISH_SYSTEM*/ + int w32err; + + if (LockFile (h->lockhd, 0, 0, 1, 0)) + { + h->locked = 1; + return 0; /* okay */ + } + w32err = GetLastError (); + if (w32err != ERROR_LOCK_VIOLATION) + { + log_error (_("lock `%s' not made: %s\n"), + h->lockname, w32_strerror (w32err)); + return -1; + } + + if (timeout == -1) + { + /* Wait until lock has been released. */ + log_info (_("waiting for lock %s...\n"), h->lockname); + Sleep ((1 + backoff)*1000); + if ( backoff < 10 ) + backoff++ ; + } + else + return -1; +#endif /*HAVE_DOSISH_SYSTEM*/ } - /*not reached */ -#endif + /*NOTREACHED */ } @@ -384,56 +541,71 @@ * Returns: 0 := success */ int -release_dotlock( DOTLOCK h ) +release_dotlock (DOTLOCK h) { -#if defined (HAVE_DOSISH_SYSTEM) +#ifndef HAVE_DOSISH_SYSTEM + int pid, same_node; +#endif + + /* To avoid atexit race conditions we first check whether there are + any locks left. It might happen that another atexit handler + tries to release the lock while the atexit handler of this module + already ran and thus H is undefined. */ + if (!all_lockfiles) return 0; -#else - int pid; - /* To avoid atexit race conditions we first check whether there - are any locks left. It might happen that another atexit - handler tries to release the lock while the atexit handler of - this module already ran and thus H is undefined. */ - if(!all_lockfiles) - return 0; + if (h->disable) + return 0; - if( h->disable ) - return 0; - - if( !h->locked ) { - log_debug("oops, `%s' is not locked\n", h->lockname ); - return 0; + if (!h->locked) + { + log_debug("oops, `%s' is not locked\n", h->lockname ); + return 0; } - pid = read_lockfile( h->lockname ); - if( pid == -1 ) { - log_error( "release_dotlock: lockfile error\n"); - return -1; +#ifndef HAVE_DOSISH_SYSTEM + pid = read_lockfile (h, &same_node); + if (pid == -1) + { + log_error ("release_dotlock: lockfile error\n"); + return -1; } - if( pid != getpid() ) { - log_error( "release_dotlock: not our lock (pid=%d)\n", pid); - return -1; + if (pid != getpid () || !same_node) + { + log_error ("release_dotlock: not our lock (pid=%d)\n", pid); + return -1; } -#ifndef __riscos__ - if( unlink( h->lockname ) ) { - log_error( "release_dotlock: error removing lockfile `%s'", - h->lockname); - return -1; +# ifndef __riscos__ + if (unlink (h->lockname)) + { + log_error ("release_dotlock: error removing lockfile `%s'", + h->lockname); + return -1; } -#else /* __riscos__ */ - if( riscos_renamefile(h->lockname, h->tname) ) { - log_error( "release_dotlock: error renaming lockfile `%s' to `%s'", - h->lockname, h->tname); - return -1; +# else /* __riscos__ */ + if( riscos_renamefile(h->lockname, h->tname) ) + { + log_error( "release_dotlock: error renaming lockfile `%s' to `%s'", + h->lockname, h->tname); + return -1; } -#endif /* __riscos__ */ - /* fixme: check that the link count is now 1 */ - h->locked = 0; - return 0; -#endif +# endif /* __riscos__ */ + +#else /*HAVE_DOSISH_SYSTEM*/ + + if (!UnlockFile (h->lockhd, 0, 0, 1, 0)) + { + log_error ("release_dotlock: error removing lockfile `%s': %s\n", + h->lockname, w32_strerror (-1)); + return -1; + } +#endif /*HAVE_DOSISH_SYSTEM*/ + + h->locked = 0; + return 0; } + void remove_lockfiles() { From cvs at cvs.gnupg.org Tue May 5 19:03:34 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 05 May 2009 19:03:34 +0200 Subject: [svn] gpgme - r1365 - in trunk: . src Message-ID: Author: marcus Date: 2009-05-05 19:03:33 +0200 (Tue, 05 May 2009) New Revision: 1365 Modified: trunk/ChangeLog trunk/configure.ac trunk/src/ChangeLog trunk/src/gpgme.h.in Log: 2009-05-05 Marcus Brinkmann * configure.ac: Add infrastructure for compile time check of _FILE_OFFSET_BITS. src/ 2009-05-05 Marcus Brinkmann * gpgme.h.in: Add compile time check for _FILE_OFFSET_BITS. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-19 18:03:49 UTC (rev 1364) +++ trunk/ChangeLog 2009-05-05 17:03:33 UTC (rev 1365) @@ -1,3 +1,8 @@ +2009-05-05 Marcus Brinkmann + + * configure.ac: Add infrastructure for compile time check of + _FILE_OFFSET_BITS. + 2009-04-19 Moritz * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Specify --with-gpg. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-04-19 18:03:49 UTC (rev 1364) +++ trunk/src/ChangeLog 2009-05-05 17:03:33 UTC (rev 1365) @@ -1,3 +1,7 @@ +2009-05-05 Marcus Brinkmann + + * gpgme.h.in: Add compile time check for _FILE_OFFSET_BITS. + 2009-04-15 Marcus Brinkmann * posix-io.c (_gpgme_io_socket, _gpgme_io_connect): New functions. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-04-19 18:03:49 UTC (rev 1364) +++ trunk/configure.ac 2009-05-05 17:03:33 UTC (rev 1365) @@ -198,6 +198,18 @@ AC_SYS_LARGEFILE AC_TYPE_OFF_T +# A simple compile time check in gpgme.h for GNU/Linux systems that +# prevents a file offset bits mismatch between gpgme and the application. +NEED__FILE_OFFSET_BITS=0 +case $ac_cv_sys_file_offset_bits in + no | unknown) ;; + *) + NEED__FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits + ;; +esac +AC_SUBST(NEED__FILE_OFFSET_BITS) + + # Checks for compiler features. if test "$GCC" = yes; then CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" Modified: trunk/src/gpgme.h.in =================================================================== --- trunk/src/gpgme.h.in 2009-04-19 18:03:49 UTC (rev 1364) +++ trunk/src/gpgme.h.in 2009-05-05 17:03:33 UTC (rev 1365) @@ -74,7 +74,18 @@ library. */ #define GPGME_VERSION "@PACKAGE_VERSION@" +/* Check for a matching _FILE_OFFSET_BITS definition. */ +#if @NEED__FILE_OFFSET_BITS@ +#ifndef _FILE_OFFSET_BITS +#error GPGME was compiled with _FILE_OFFSET_BITS = @NEED__FILE_OFFSET_BITS@, please see the section "Largefile support (LFS)" in the GPGME manual. +#else +#if (_FILE_OFFSET_BITS) != (@NEED__FILE_OFFSET_BITS@) +#error GPGME was compiled with a different value for _FILE_OFFSET_BITS, namely @NEED__FILE_OFFSET_BITS@, please see the section "Largefile support (LFS)" in the GPGME manual. +#endif +#endif +#endif + /* Some opaque data types used by GPGME. */ From cvs at cvs.gnupg.org Tue May 5 19:19:17 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 05 May 2009 19:19:17 +0200 Subject: [svn] gpgme - r1366 - trunk/doc Message-ID: Author: marcus Date: 2009-05-05 19:19:17 +0200 (Tue, 05 May 2009) New Revision: 1366 Modified: trunk/doc/ChangeLog trunk/doc/gpgme.texi Log: 2009-05-05 Marcus Brinkmann * gpgme.texi (Engine Information): Replace path by file_name. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-05-05 17:03:33 UTC (rev 1365) +++ trunk/doc/ChangeLog 2009-05-05 17:19:17 UTC (rev 1366) @@ -1,3 +1,7 @@ +2009-05-05 Marcus Brinkmann + + * gpgme.texi (Engine Information): Replace path by file_name. + 2008-11-28 Werner Koch * gpgme.texi (Listing Keys): Change description of the return Modified: trunk/doc/gpgme.texi =================================================================== --- trunk/doc/gpgme.texi 2009-05-05 17:03:33 UTC (rev 1365) +++ trunk/doc/gpgme.texi 2009-05-05 17:19:17 UTC (rev 1366) @@ -874,12 +874,12 @@ if (!info) fprintf (stderr, "GPGME compiled without support for protocol %s", gpgme_get_protocol_name (info->protocol)); - else if (info->path && !info->version) + else if (info->file_name && !info->version) fprintf (stderr, "Engine %s not installed properly", - info->path); - else if (info->path && info->version && info->req_version) + info->file_name); + else if (info->file_name && info->version && info->req_version) fprintf (stderr, "Engine %s version %s installed, " - "but at least version %s required", info->path, + "but at least version %s required", info->file_name, info->version, info->req_version); else fprintf (stderr, "Unknown problem with engine for protocol %s", From cvs at cvs.gnupg.org Wed May 6 11:31:16 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 06 May 2009 11:31:16 +0200 Subject: [svn] GnuPG - r4993 - in branches/STABLE-BRANCH-1-4: . g10 Message-ID: Author: wk Date: 2009-05-06 11:31:15 +0200 (Wed, 06 May 2009) New Revision: 4993 Modified: branches/STABLE-BRANCH-1-4/NEWS branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/getkey.c branches/STABLE-BRANCH-1-4/g10/keyring.c Log: Fix for bug#1034. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-05 15:32:16 UTC (rev 4992) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-06 09:31:15 UTC (rev 4993) @@ -1,3 +1,10 @@ +2009-05-06 Werner Koch + + * keyring.c (keyring_get_keyblock): Fix memory leak due to + ring_trust packets. Fixes bug#1034. + + * getkey.c (finish_lookup): Remove dead code. + 2009-05-05 Werner Koch * keygen.c (read_parameter_file): Add keyword "Creation-Date". Modified: branches/STABLE-BRANCH-1-4/NEWS =================================================================== --- branches/STABLE-BRANCH-1-4/NEWS 2009-05-05 15:32:16 UTC (rev 4992) +++ branches/STABLE-BRANCH-1-4/NEWS 2009-05-06 09:31:15 UTC (rev 4993) @@ -6,7 +6,9 @@ * Improved file locking. Implemented it for W32. + * Fixed a memory leak which made imports of many keys very slow. + Noteworthy changes in version 1.4.9 (2008-03-26) ------------------------------------------------ Modified: branches/STABLE-BRANCH-1-4/g10/getkey.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/getkey.c 2009-05-05 15:32:16 UTC (rev 4992) +++ branches/STABLE-BRANCH-1-4/g10/getkey.c 2009-05-06 09:31:15 UTC (rev 4993) @@ -2541,17 +2541,7 @@ latest_key = foundk? foundk:keyblock; goto found; } - - if (!req_usage) { - PKT_public_key *pk = foundk->pkt->pkt.public_key; - if (pk->user_id) - free_user_id (pk->user_id); - pk->user_id = scopy_user_id (foundu); - ctx->found_key = foundk; - cache_user_id( keyblock ); - return 1; /* found */ - } - + latest_date = 0; latest_key = NULL; /* do not look at subkeys if a certification key is requested */ Modified: branches/STABLE-BRANCH-1-4/g10/keyring.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keyring.c 2009-05-05 15:32:16 UTC (rev 4992) +++ branches/STABLE-BRANCH-1-4/g10/keyring.c 2009-05-06 09:31:15 UTC (rev 4993) @@ -419,38 +419,43 @@ if ( lastnode && lastnode->pkt->pkttype == PKT_SIGNATURE && (pkt->pkt.ring_trust->sigcache & 1) ) { - /* this is a ring trust packet with a checked signature + /* This is a ring trust packet with a checked signature * status cache following directly a signature paket. - * Set the cache status into that signature packet */ + * Set the cache status into that signature packet. */ PKT_signature *sig = lastnode->pkt->pkt.signature; sig->flags.checked = 1; sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); } - /* reset lastnode, so that we set the cache status only from - * the ring trust packet immediately folling a signature */ + /* Reset LASTNODE, so that we set the cache status only + * from the ring trust packets immediately following + * signature packets. */ lastnode = NULL; + free_packet(pkt); + init_packet(pkt); + continue; } - else { - node = lastnode = new_kbnode (pkt); - if (!keyblock) - keyblock = node; - else - add_kbnode (keyblock, node); - if ( pkt->pkttype == PKT_PUBLIC_KEY - || pkt->pkttype == PKT_PUBLIC_SUBKEY - || pkt->pkttype == PKT_SECRET_KEY - || pkt->pkttype == PKT_SECRET_SUBKEY) { - if (++pk_no == hd->found.pk_no) - node->flag |= 1; - } - else if ( pkt->pkttype == PKT_USER_ID) { - if (++uid_no == hd->found.uid_no) - node->flag |= 2; - } - } - + node = lastnode = new_kbnode (pkt); + if (!keyblock) + keyblock = node; + else + add_kbnode (keyblock, node); + + if ( pkt->pkttype == PKT_PUBLIC_KEY + || pkt->pkttype == PKT_PUBLIC_SUBKEY + || pkt->pkttype == PKT_SECRET_KEY + || pkt->pkttype == PKT_SECRET_SUBKEY) + { + if (++pk_no == hd->found.pk_no) + node->flag |= 1; + } + else if ( pkt->pkttype == PKT_USER_ID) + { + if (++uid_no == hd->found.uid_no) + node->flag |= 2; + } + pkt = xmalloc (sizeof *pkt); init_packet(pkt); } From cvs at cvs.gnupg.org Wed May 6 11:36:07 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 06 May 2009 11:36:07 +0200 Subject: [svn] GnuPG - r4994 - trunk/g10 Message-ID: Author: wk Date: 2009-05-06 11:36:06 +0200 (Wed, 06 May 2009) New Revision: 4994 Modified: trunk/g10/ChangeLog trunk/g10/getkey.c trunk/g10/keyring.c Log: Fix bug#1034. Remove dead code. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-06 09:31:15 UTC (rev 4993) +++ trunk/g10/ChangeLog 2009-05-06 09:36:06 UTC (rev 4994) @@ -1,3 +1,10 @@ +2009-05-06 Werner Koch + + * getkey.c (finish_lookup): Remove dead code. + + * keyring.c (keyring_get_keyblock): Fix memory leak due to ring + trust packets. Fixes bug#1034. + 2009-04-03 Werner Koch * gpgv.c (main): Open keyrings readonly. Modified: trunk/g10/getkey.c =================================================================== --- trunk/g10/getkey.c 2009-05-06 09:31:15 UTC (rev 4993) +++ trunk/g10/getkey.c 2009-05-06 09:36:06 UTC (rev 4994) @@ -2640,16 +2640,6 @@ goto found; } - if (!req_usage) { - PKT_public_key *pk = foundk->pkt->pkt.public_key; - if (pk->user_id) - free_user_id (pk->user_id); - pk->user_id = scopy_user_id (foundu); - ctx->found_key = foundk; - cache_user_id( keyblock ); - return 1; /* found */ - } - latest_date = 0; latest_key = NULL; /* do not look at subkeys if a certification key is requested */ Modified: trunk/g10/keyring.c =================================================================== --- trunk/g10/keyring.c 2009-05-06 09:31:15 UTC (rev 4993) +++ trunk/g10/keyring.c 2009-05-06 09:36:06 UTC (rev 4994) @@ -426,43 +426,53 @@ } in_cert = 1; - if (pkt->pkttype == PKT_RING_TRUST) { + if (pkt->pkttype == PKT_RING_TRUST) + { /*(this code is duplicated after the loop)*/ if ( lastnode && lastnode->pkt->pkttype == PKT_SIGNATURE && (pkt->pkt.ring_trust->sigcache & 1) ) { - /* this is a ring trust packet with a checked signature + /* This is a ring trust packet with a checked signature * status cache following directly a signature paket. - * Set the cache status into that signature packet */ + * Set the cache status into that signature packet. */ PKT_signature *sig = lastnode->pkt->pkt.signature; sig->flags.checked = 1; sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); } - /* reset lastnode, so that we set the cache status only from - * the ring trust packet immediately folling a signature */ + /* Reset LASTNODE, so that we set the cache status only from + * the ring trust packet immediately following a signature. */ lastnode = NULL; - } - else { - node = lastnode = new_kbnode (pkt); - if (!keyblock) - keyblock = node; - else - add_kbnode (keyblock, node); + free_packet(pkt); + init_packet(pkt); + continue; + } - if ( pkt->pkttype == PKT_PUBLIC_KEY - || pkt->pkttype == PKT_PUBLIC_SUBKEY - || pkt->pkttype == PKT_SECRET_KEY - || pkt->pkttype == PKT_SECRET_SUBKEY) { - if (++pk_no == hd->found.pk_no) - node->flag |= 1; - } - else if ( pkt->pkttype == PKT_USER_ID) { - if (++uid_no == hd->found.uid_no) - node->flag |= 2; - } - } + node = lastnode = new_kbnode (pkt); + if (!keyblock) + keyblock = node; + else + add_kbnode (keyblock, node); + switch (pkt->pkttype) + { + case PKT_PUBLIC_KEY: + case PKT_PUBLIC_SUBKEY: + case PKT_SECRET_KEY: + case PKT_SECRET_SUBKEY: + if (++pk_no == hd->found.pk_no) + node->flag |= 1; + break; + + case PKT_USER_ID: + if (++uid_no == hd->found.uid_no) + node->flag |= 2; + break; + + default: + break; + } + pkt = xmalloc (sizeof *pkt); init_packet(pkt); } From cvs at cvs.gnupg.org Wed May 6 12:57:10 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 06 May 2009 12:57:10 +0200 Subject: [svn] GnuPG - r4995 - trunk/doc Message-ID: Author: wk Date: 2009-05-06 12:57:10 +0200 (Wed, 06 May 2009) New Revision: 4995 Modified: trunk/doc/gpgv.texi Log: Fix example. Modified: trunk/doc/gpgv.texi =================================================================== --- trunk/doc/gpgv.texi 2009-05-06 09:36:06 UTC (rev 4994) +++ trunk/doc/gpgv.texi 2009-05-06 10:57:10 UTC (rev 4995) @@ -123,13 +123,14 @@ @table @asis @item @gpgvname @code{pgpfile} - at itemx @gpgvname @code{sigfile} -Verify the signature of the file. The second form -is used for detached signatures, where @code{sigfile} is the detached -signature (either ASCII-armored or binary) and are the signed -data; if this is not given the name of the file holding the signed data is -constructed by cutting off the extension (".asc", ".sig" or ".sign") from - at code{sigfile}. + at itemx @gpgvname @code{sigfile} [@code{datafile}] +Verify the signature of the file. The second form is used for detached +signatures, where @code{sigfile} is the detached signature (either +ASCII-armored or binary) and @code{datafile} contains the signed data; +if @code{datafile} is "-" the signed data is expected on + at code{stdin}; if @code{datafile} is not given the name of the file +holding the signed data is constructed by cutting off the extension +(".asc", ".sig" or ".sign") from @code{sigfile}. @end table From cvs at cvs.gnupg.org Thu May 7 17:01:47 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 07 May 2009 17:01:47 +0200 Subject: [svn] GnuPG - r4996 - trunk/common Message-ID: Author: wk Date: 2009-05-07 17:01:47 +0200 (Thu, 07 May 2009) New Revision: 4996 Modified: trunk/common/ChangeLog trunk/common/sexputil.c trunk/common/t-sexputil.c trunk/common/util.h Log: New helper function factored out of ../scd and equipped with test code. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-05-06 10:57:10 UTC (rev 4995) +++ trunk/common/ChangeLog 2009-05-07 15:01:47 UTC (rev 4996) @@ -1,3 +1,13 @@ +2009-05-07 Werner Koch + + * sexputil.c (get_rsa_pk_from_canon_sexp): New. + * t-sexputil.c (test_make_canon_sexp_from_rsa_pk): Extend the test. + +2009-04-28 Werner Koch + + * sexputil.c (make_canon_sexp_from_rsa_pk): New. + * t-sexputil.c (test_make_canon_sexp_from_rsa_pk): New. + 2009-04-01 Werner Koch * iobuf.c: Port David's changes from 1.4: Modified: trunk/common/sexputil.c =================================================================== --- trunk/common/sexputil.c 2009-05-06 10:57:10 UTC (rev 4995) +++ trunk/common/sexputil.c 2009-05-07 15:01:47 UTC (rev 4996) @@ -32,6 +32,7 @@ #endif #include "util.h" +#include "tlv.h" #include "sexp-parse.h" @@ -225,3 +226,163 @@ return gcry_md_map_name (buffer); } + +/* Create a public key S-expression for an RSA public key from the + modulus M with length MLEN and the public exponent E with length + ELEN. Returns a newly allocated buffer of NULL in case of a memory + allocation problem. If R_LEN is not NULL, the length of the + canonical S-expression is stored there. */ +unsigned char * +make_canon_sexp_from_rsa_pk (const void *m_arg, size_t mlen, + const void *e_arg, size_t elen, + size_t *r_len) +{ + const unsigned char *m = m_arg; + const unsigned char *e = e_arg; + int m_extra = 0; + int e_extra = 0; + char mlen_str[35]; + char elen_str[35]; + unsigned char *keybuf, *p; + const char const part1[] = "(10:public-key(3:rsa(1:n"; + const char const part2[] = ")(1:e"; + const char const part3[] = ")))"; + + /* Remove leading zeroes. */ + for (; mlen && !*m; mlen--, m++) + ; + for (; elen && !*e; elen--, e++) + ; + + /* Insert a leading zero if the number would be zero or interpreted + as negative. */ + if (!mlen || (m[0] & 0x80)) + m_extra = 1; + if (!elen || (e[0] & 0x80)) + e_extra = 1; + + /* Build the S-expression. */ + snprintf (mlen_str, sizeof mlen_str, "%u:", (unsigned int)mlen+m_extra); + snprintf (elen_str, sizeof elen_str, "%u:", (unsigned int)elen+e_extra); + + keybuf = xtrymalloc (strlen (part1) + strlen (mlen_str) + mlen + m_extra + + strlen (part2) + strlen (elen_str) + elen + e_extra + + strlen (part3) + 1); + if (!keybuf) + return NULL; + + p = stpcpy (keybuf, part1); + p = stpcpy (p, mlen_str); + if (m_extra) + *p++ = 0; + memcpy (p, m, mlen); + p += mlen; + p = stpcpy (p, part2); + p = stpcpy (p, elen_str); + if (e_extra) + *p++ = 0; + memcpy (p, e, elen); + p += elen; + p = stpcpy (p, part3); + + if (r_len) + *r_len = p - keybuf; + + return keybuf; +} + + +/* Return the so called "keygrip" which is the SHA-1 hash of the + public key parameters expressed in a way depended on the algorithm. + + KEY is expected to be an canonical encoded S-expression with a + public or private key. KEYLEN is the length of that buffer. + + GRIP must be at least 20 bytes long. On success 0 is returned, on + error an error code. */ +gpg_error_t +get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, + unsigned char const **r_n, size_t *r_nlen, + unsigned char const **r_e, size_t *r_elen) +{ + gpg_error_t err; + const unsigned char *buf, *tok; + size_t buflen, toklen; + int depth, last_depth1, last_depth2; + const unsigned char *rsa_n = NULL; + const unsigned char *rsa_e = NULL; + size_t rsa_n_len, rsa_e_len; + + *r_n = NULL; + *r_nlen = 0; + *r_e = NULL; + *r_elen = 0; + + buf = keydata; + buflen = keydatalen; + depth = 0; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen)) + return gpg_error (GPG_ERR_BAD_PUBKEY); + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen)) + return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); + + last_depth1 = depth; + while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)) + && depth && depth >= last_depth1) + { + if (tok) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (tok && toklen == 1) + { + const unsigned char **mpi; + size_t *mpi_len; + + switch (*tok) + { + case 'n': mpi = &rsa_n; mpi_len = &rsa_n_len; break; + case 'e': mpi = &rsa_e; mpi_len = &rsa_e_len; break; + default: mpi = NULL; mpi_len = NULL; break; + } + if (mpi && *mpi) + return gpg_error (GPG_ERR_DUP_VALUE); + + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (tok && mpi) + { + /* Strip off leading zero bytes and save. */ + for (;toklen && !*tok; toklen--, tok++) + ; + *mpi = tok; + *mpi_len = toklen; + } + } + + /* Skip to the end of the list. */ + last_depth2 = depth; + while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)) + && depth && depth >= last_depth2) + ; + if (err) + return err; + } + + if (!rsa_n || !rsa_n_len || !rsa_e || !rsa_e_len) + return gpg_error (GPG_ERR_BAD_PUBKEY); + + *r_n = rsa_n; + *r_nlen = rsa_n_len; + *r_e = rsa_e; + *r_elen = rsa_e_len; + return 0; +} Modified: trunk/common/t-sexputil.c =================================================================== --- trunk/common/t-sexputil.c 2009-05-06 10:57:10 UTC (rev 4995) +++ trunk/common/t-sexputil.c 2009-05-07 15:01:47 UTC (rev 4996) @@ -69,8 +69,115 @@ } +static void +test_make_canon_sexp_from_rsa_pk (void) +{ + struct { + unsigned char *m; + size_t mlen; + unsigned char *e; + size_t elen; + unsigned char *result; + size_t resultlen; + gpg_err_code_t reverr; /* Expected error from the reverse fucntion. */ + } tests[] = { + { + "\x82\xB4\x12\x48\x08\x48\xC0\x76\xAA\x8E\xF1\xF8\x7F\x5E\x9B\x89" + "\xA9\x62\x92\xA2\x16\x1B\xF5\x9F\xE1\x41\xF3\xF0\x42\xB5\x5C\x46" + "\xB8\x83\x9F\x39\x97\x73\xFF\xC5\xB2\xF4\x59\x5F\xBA\xC7\x0E\x03" + "\x9D\x27\xC0\x86\x37\x31\x46\xE0\xA1\xFE\xA1\x41\xD4\xE3\xE9\xB3" + "\x9B\xD5\x84\x65\xA5\x37\x35\x34\x07\x58\xB6\xBA\x21\xCA\x21\x72" + "\x4C\xF3\xFC\x91\x47\xD1\x3C\x1D\xA5\x9C\x38\x4D\x58\x39\x92\x16" + "\xB1\xE5\x43\xFE\xB5\x46\x4B\x43\xD1\x47\xB0\xE8\x2A\xDB\xF8\x34" + "\xB0\x5A\x22\x3D\x14\xBB\xEA\x63\x65\xA7\xF1\xF2\xF8\x97\x74\xA7", + 128, + "\x40\x00\x00\x81", + 4, + "\x28\x31\x30\x3a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\x28\x33" + "\x3a\x72\x73\x61\x28\x31\x3a\x6e\x31\x32\x39\x3a\x00\x82\xb4\x12" + "\x48\x08\x48\xc0\x76\xaa\x8e\xf1\xf8\x7f\x5e\x9b\x89\xa9\x62\x92" + "\xa2\x16\x1b\xf5\x9f\xe1\x41\xf3\xf0\x42\xb5\x5c\x46\xb8\x83\x9f" + "\x39\x97\x73\xff\xc5\xb2\xf4\x59\x5f\xba\xc7\x0e\x03\x9d\x27\xc0" + "\x86\x37\x31\x46\xe0\xa1\xfe\xa1\x41\xd4\xe3\xe9\xb3\x9b\xd5\x84" + "\x65\xa5\x37\x35\x34\x07\x58\xb6\xba\x21\xca\x21\x72\x4c\xf3\xfc" + "\x91\x47\xd1\x3c\x1d\xa5\x9c\x38\x4d\x58\x39\x92\x16\xb1\xe5\x43" + "\xfe\xb5\x46\x4b\x43\xd1\x47\xb0\xe8\x2a\xdb\xf8\x34\xb0\x5a\x22" + "\x3d\x14\xbb\xea\x63\x65\xa7\xf1\xf2\xf8\x97\x74\xa7\x29\x28\x31" + "\x3a\x65\x34\x3a\x40\x00\x00\x81\x29\x29\x29", + 171 + }, + { + "\x63\xB4\x12\x48\x08\x48\xC0\x76\xAA\x8E\xF1\xF8\x7F\x5E\x9B\x89", + 16, + "\x03", + 1, + "\x28\x31\x30\x3a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\x28\x33" + "\x3a\x72\x73\x61\x28\x31\x3a\x6e\x31\x36\x3a\x63\xb4\x12\x48\x08" + "\x48\xc0\x76\xaa\x8e\xf1\xf8\x7f\x5e\x9b\x89\x29\x28\x31\x3a\x65" + "\x31\x3a\x03\x29\x29\x29", + 54, + }, + { + "", + 0, + "", + 0, + "\x28\x31\x30\x3a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\x28\x33" + "\x3a\x72\x73\x61\x28\x31\x3a\x6e\x31\x3a\x00\x29\x28\x31\x3a\x65" + "\x31\x3a\x00\x29\x29\x29", + 38, + GPG_ERR_BAD_PUBKEY + }, + { + NULL + } + }; + int idx; + gpg_error_t err; + unsigned char *sexp; + size_t length; + const unsigned char *rsa_n, *rsa_e; + size_t rsa_n_len, rsa_e_len; + for (idx=0; tests[idx].m; idx++) + { + sexp = make_canon_sexp_from_rsa_pk (tests[idx].m, tests[idx].mlen, + tests[idx].e, tests[idx].elen, + &length); + if (!sexp) + { + fprintf (stderr, "%s:%d: out of core\n", __FILE__, __LINE__); + exit (1); + } + + if (length != tests[idx].resultlen) + fail (idx); + if (memcmp (sexp, tests[idx].result, tests[idx].resultlen)) + fail (idx); + /* Test the reverse function. */ + err = get_rsa_pk_from_canon_sexp (sexp, length, + &rsa_n, &rsa_n_len, + &rsa_e, &rsa_e_len); + if (gpg_err_code (err) != tests[idx].reverr) + fail (idx); + if (!err) + { + if (tests[idx].mlen != rsa_n_len) + fail (idx); + if (memcmp (tests[idx].m, rsa_n, rsa_n_len)) + fail (idx); + if (tests[idx].elen != rsa_e_len) + fail (idx); + if (memcmp (tests[idx].e, rsa_e, rsa_e_len)) + fail (idx); + } + + xfree (sexp); + } +} + + int main (int argc, char **argv) { @@ -78,6 +185,7 @@ (void)argv; test_hash_algo_from_sigval (); + test_make_canon_sexp_from_rsa_pk (); return 0; } Modified: trunk/common/util.h =================================================================== --- trunk/common/util.h 2009-05-06 10:57:10 UTC (rev 4995) +++ trunk/common/util.h 2009-05-07 15:01:47 UTC (rev 4996) @@ -192,6 +192,15 @@ unsigned char *make_simple_sexp_from_hexstr (const char *line, size_t *nscanned); int hash_algo_from_sigval (const unsigned char *sigval); +unsigned char *make_canon_sexp_from_rsa_pk (const void *m, size_t mlen, + const void *e, size_t elen, + size_t *r_len); +gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata, + size_t keydatalen, + unsigned char const **r_n, + size_t *r_nlen, + unsigned char const **r_e, + size_t *r_elen); /*-- convert.c --*/ int hex2bin (const char *string, void *buffer, size_t length); From cvs at cvs.gnupg.org Fri May 8 17:07:46 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 08 May 2009 17:07:46 +0200 Subject: [svn] GnuPG - r4997 - trunk/scd Message-ID: Author: wk Date: 2009-05-08 17:07:45 +0200 (Fri, 08 May 2009) New Revision: 4997 Modified: trunk/scd/ChangeLog trunk/scd/apdu.c trunk/scd/app-common.h trunk/scd/app-help.c trunk/scd/app-nks.c trunk/scd/app-openpgp.c trunk/scd/ccid-driver.c trunk/scd/iso7816.c trunk/scd/iso7816.h Log: More support for Netkey cards. Small changes to teh CCID driver. Support 2048 bit OpenPGP cards. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-05-07 15:01:47 UTC (rev 4996) +++ trunk/scd/ChangeLog 2009-05-08 15:07:45 UTC (rev 4997) @@ -1,3 +1,26 @@ +2009-05-08 Werner Koch + + * app-openpgp.c (do_genkey): Allow larger key sizes. + (do_decipher): Ditto. + * iso7816.c (do_generate_keypair): Add arg EXTENDED_MODE an LE. + (iso7816_generate_keypair, iso7816_read_public_key): Ditto. + Changed all callers. + * apdu.c (send_le): Implement extended length return values. + + * ccid-driver.c (bulk_in): Retry on EAGAIN. + (abort_cmd): Change seqno handling. + +2009-04-28 Werner Koch + + * app-help.c (app_help_count_bits): New. + + * app-nks.c (switch_application): Detect mass signature cards. + Take care of new NEED_APP_SELECT flag. + (do_sign): Don't allow mass signature cards. + (all_zero_p): New. + (do_readkey): New. + (app_select_nks): Register do_readkey. + 2009-04-01 Werner Koch * app-openpgp.c (do_setattr, do_writekey): Prepare for extended Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2009-05-07 15:01:47 UTC (rev 4996) +++ trunk/scd/apdu.c 2009-05-08 15:07:45 UTC (rev 4997) @@ -2817,8 +2817,6 @@ length limit. n > 1 := Use extended length with up to N bytes. - FIXME: We don't support extended length return values larger - than 256 bytes due to a static buffer. */ static int send_le (int slot, int class, int ins, int p0, int p1, @@ -2826,9 +2824,12 @@ unsigned char **retbuf, size_t *retbuflen, struct pininfo_s *pininfo, int extended_mode) { -#define RESULTLEN 258 - unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in - the driver. */ +#define SHORT_RESULT_BUFFER_SIZE 258 + /* We allocate 8 extra bytes as a safety margin towards a driver bug. */ + unsigned char short_result_buffer[SHORT_RESULT_BUFFER_SIZE+10]; + unsigned char *result_buffer = NULL; + size_t result_buffer_size; + unsigned char *result; size_t resultlen; unsigned char short_apdu_buffer[5+256+1]; unsigned char *apdu_buffer = NULL; @@ -2873,8 +2874,22 @@ else if (lc == -1 && extended_mode > 0) use_extended_length = 1; - if (le != -1 && (le > 256 || le < 0)) - return SW_WRONG_LENGTH; + if (le != -1 && (le > (extended_mode > 0? 255:256) || le < 0)) + { + /* Expected Data does not fit into an APDU. What we do now + depends on the EXTENDED_MODE parameter. Note that a check + for command chaining does not make sense because we are + looking at Le. */ + if (!extended_mode) + return SW_WRONG_LENGTH; /* No way to send such an APDU. */ + else if (use_extended_length) + ; /* We are already using extended length. */ + else if (extended_mode > 0) + use_extended_length = 1; + else + return SW_HOST_INV_VALUE; + } + if ((!data && lc != -1) || (data && lc == -1)) return SW_HOST_INV_VALUE; @@ -2885,7 +2900,7 @@ /* Space for: cls/ins/p1/p2+Z+2_byte_Lc+Lc+2_byte_Le. */ apdu_buffer_size = 4 + 1 + (lc >= 0? (2+lc):0) + 2; - apdu_buffer = xtrymalloc (apdu_buffer_size); + apdu_buffer = xtrymalloc (apdu_buffer_size + 10); if (!apdu_buffer) return SW_HOST_OUT_OF_CORE; apdu = apdu_buffer; @@ -2896,6 +2911,24 @@ apdu = short_apdu_buffer; } + if (use_extended_length && (le > 256 || le < 0)) + { + result_buffer_size = le < 0? 4096 : le; + result_buffer = xtrymalloc (result_buffer_size + 10); + if (!result_buffer) + { + xfree (apdu_buffer); + return SW_HOST_OUT_OF_CORE; + } + result = result_buffer; + } + else + { + result_buffer_size = SHORT_RESULT_BUFFER_SIZE; + result = short_result_buffer; + } +#undef SHORT_RESULT_BUFFER_SIZE + if ((sw = lock_slot (slot))) return sw; @@ -2963,7 +2996,7 @@ /* As a safeguard don't pass any garbage to the driver. */ assert (apdulen <= apdu_buffer_size); memset (apdu+apdulen, 0, apdu_buffer_size - apdulen); - resultlen = RESULTLEN; + resultlen = result_buffer_size; rc = send_apdu (slot, apdu, apdulen, result, &resultlen, pininfo); if (rc || resultlen < 2) { @@ -3051,7 +3084,7 @@ apdu[apdulen++] = len; assert (apdulen <= apdu_buffer_size); memset (apdu+apdulen, 0, apdu_buffer_size - apdulen); - resultlen = RESULTLEN; + resultlen = result_buffer_size; rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL); if (rc || resultlen < 2) { @@ -3114,7 +3147,6 @@ log_printhex (" dump: ", *retbuf, *retbuflen); return sw; -#undef RESULTLEN } /* Send an APDU to the card in SLOT. The APDU is created from all @@ -3210,6 +3242,7 @@ unsigned char **retbuf, size_t *retbuflen) { #define RESULTLEN 258 + /* FIXME: Implement dynamic result buffer and extended Le. */ unsigned char apdu[5+256+1]; size_t apdulen; unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in Modified: trunk/scd/app-common.h =================================================================== --- trunk/scd/app-common.h 2009-05-07 15:01:47 UTC (rev 4996) +++ trunk/scd/app-common.h 2009-05-08 15:07:45 UTC (rev 4997) @@ -135,6 +135,7 @@ void *pincb_arg); #else /*-- app-help.c --*/ +unsigned int app_help_count_bits (const unsigned char *a, size_t len); gpg_error_t app_help_get_keygrip_string (ksba_cert_t cert, char *hexkeygrip); size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff); Modified: trunk/scd/app-help.c =================================================================== --- trunk/scd/app-help.c 2009-05-07 15:01:47 UTC (rev 4996) +++ trunk/scd/app-help.c 2009-05-08 15:07:45 UTC (rev 4997) @@ -1,5 +1,5 @@ /* app-help.c - Application helper functions - * Copyright (C) 2004 Free Software Foundation, Inc. + * Copyright (C) 2004, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -28,6 +28,30 @@ #include "iso7816.h" #include "tlv.h" + +/* Count the number of bits, assuming the A represents an unsigned big + integer of length LEN bytes. If A is NULL a length of 0 is + returned. */ +unsigned int +app_help_count_bits (const unsigned char *a, size_t len) +{ + unsigned int n = len * 8; + int i; + + if (!a) + return 0; + + for (; len && !*a; len--, a++, n -=8) + ; + if (len) + { + for (i=7; i && !(*a & (1<app_local->nks_version >= 3) + ; + else /* Return the error code expected by cmd_readkey. */ + return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); + + /* Access the KEYD file which is always in the master directory. */ + err = iso7816_select_path (app->slot, path, DIM (path), NULL, NULL); + if (err) + return err; + /* Due to the above select we need to re-select our application. */ + app->app_local->need_app_select = 1; + /* Get the two records. */ + err = iso7816_read_record (app->slot, 5, 1, 0, &buffer[0], &buflen[0]); + if (err) + return err; + if (all_zero_p (buffer[0], buflen[0])) + { + xfree (buffer[0]); + return gpg_error (GPG_ERR_NOT_FOUND); + } + err = iso7816_read_record (app->slot, 6, 1, 0, &buffer[1], &buflen[1]); + if (err) + { + xfree (buffer[0]); + return err; + } + + if (pk && pklen) + { + *pk = make_canon_sexp_from_rsa_pk (buffer[0], buflen[0], + buffer[1], buflen[1], + pklen); + if (!*pk) + err = gpg_error_from_syserror (); + } + + xfree (buffer[0]); + xfree (buffer[1]); + return err; +} + + +static gpg_error_t basic_pin_checks (const char *pinvalue, int minlen, int maxlen) { if (strlen (pinvalue) < minlen) @@ -673,7 +749,6 @@ } - /* Create the signature and return the allocated result in OUTDATA. If a PIN is required the PINCB will be used to ask for the PIN; that callback should return the PIN in an allocated buffer and @@ -723,6 +798,12 @@ if (rc) return rc; + if (is_sigg && app->app_local->sigg_is_msig) + { + log_info ("mass signature cards are not allowed\n"); + return gpg_error (GPG_ERR_NOT_SUPPORTED); + } + if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1) || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) || keyidstr[4]) @@ -1147,8 +1228,9 @@ { gpg_error_t err; - if ((app->app_local->sigg_active && enable_sigg) - || (!app->app_local->sigg_active && !enable_sigg) ) + if (((app->app_local->sigg_active && enable_sigg) + || (!app->app_local->sigg_active && !enable_sigg)) + && !app->app_local->need_app_select) return 0; /* Already switched. */ log_info ("app-nks: switching to %s\n", enable_sigg? "SigG":"NKS"); @@ -1156,9 +1238,40 @@ err = iso7816_select_application (app->slot, aid_sigg, sizeof aid_sigg, 0); else err = iso7816_select_application (app->slot, aid_nks, sizeof aid_nks, 0); + + if (!err && enable_sigg && app->app_local->nks_version >= 3 + && !app->app_local->sigg_msig_checked) + { + /* Check whether this card is a mass signature card. */ + unsigned char *buffer; + size_t buflen; + const unsigned char *tmpl; + size_t tmpllen; + + app->app_local->sigg_msig_checked = 1; + app->app_local->sigg_is_msig = 1; + err = iso7816_select_file (app->slot, 0x5349, 0, NULL, NULL); + if (!err) + err = iso7816_read_record (app->slot, 1, 1, 0, &buffer, &buflen); + if (!err) + { + tmpl = find_tlv (buffer, buflen, 0x7a, &tmpllen); + if (tmpl && tmpllen == 12 + && !memcmp (tmpl, + "\x93\x02\x00\x01\xA4\x06\x83\x01\x81\x83\x01\x83", + 12)) + app->app_local->sigg_is_msig = 0; + xfree (buffer); + } + if (app->app_local->sigg_is_msig) + log_info ("This is a mass signature card\n"); + } if (!err) - app->app_local->sigg_active = enable_sigg; + { + app->app_local->need_app_select = 0; + app->app_local->sigg_active = enable_sigg; + } else log_error ("app-nks: error switching to %s: %s\n", enable_sigg? "SigG":"NKS", gpg_strerror (err)); @@ -1193,8 +1306,10 @@ app->fnc.deinit = do_deinit; app->fnc.learn_status = do_learn_status; app->fnc.readcert = do_readcert; + app->fnc.readkey = do_readkey; app->fnc.getattr = do_getattr; app->fnc.setattr = NULL; + app->fnc.writekey = NULL; app->fnc.genkey = NULL; app->fnc.sign = do_sign; app->fnc.auth = NULL; Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2009-05-07 15:01:47 UTC (rev 4996) +++ trunk/scd/app-openpgp.c 2009-05-08 15:07:45 UTC (rev 4997) @@ -1095,9 +1095,9 @@ { /* We may simply read the public key out of these cards. */ err = iso7816_read_public_key - (app->slot, (const unsigned char*)(keyno == 0? "\xB6" : - keyno == 1? "\xB8" : "\xA4"), - 2, + (app->slot, 0, (const unsigned char*)(keyno == 0? "\xB6" : + keyno == 1? "\xB8" : "\xA4"), 2, + 0, &buffer, &buflen); if (err) { @@ -2530,6 +2530,9 @@ int keyno = atoi (keynostr); int force = (flags & 1); time_t start_at; + int exmode; + int le_value; + unsigned int keybits; if (keyno < 1 || keyno > 3) return gpg_error (GPG_ERR_INV_ID); @@ -2550,22 +2553,44 @@ if (rc) return rc; + /* Because we send the key parameter back via status lines we need + to put a limit on the max. allowed keysize. 2048 bit will + already lead to a 527 byte long status line and thus a 4096 bit + key would exceed the Assuan line length limit. */ + keybits = app->app_local->keyattr[keyno].n_bits; + if (keybits > 3072) + return gpg_error (GPG_ERR_TOO_LARGE); + /* Prepare for key generation by verifying the Admin PIN. */ rc = verify_chv3 (app, pincb, pincb_arg); if (rc) goto leave; - -#if 1 + + /* Test whether we will need extended length mode. (1900 is an + arbitrary length which for sure fits into a short apdu.) */ + if (app->app_local->cardcap.ext_lc_le && keybits > 1900) + { + exmode = 1; /* Use extended length w/o a limit. */ + le_value = app->app_local->extcap.max_rsp_data; + /* No need to check le_value because it comes from a 16 bit + value and thus can't create an overflow on a 32 bit + system. */ + } + else + { + exmode = 0; + le_value = 256; /* Use legacy value. */ + } + log_info (_("please wait while key is being generated ...\n")); start_at = time (NULL); rc = iso7816_generate_keypair -#else -# warning key generation temporary replaced by reading an existing key. - rc = iso7816_read_public_key -#endif - (app->slot, (const unsigned char*)(keyno == 0? "\xB6" : - keyno == 1? "\xB8" : "\xA4"), - 2, +/* # warning key generation temporary replaced by reading an existing key. */ +/* rc = iso7816_read_public_key */ + (app->slot, exmode, + (const unsigned char*)(keyno == 0? "\xB6" : + keyno == 1? "\xB8" : "\xA4"), 2, + le_value, &buffer, &buflen); if (rc) { @@ -2575,6 +2600,7 @@ } log_info (_("key generation completed (%d seconds)\n"), (int)(time (NULL) - start_at)); + keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen); if (!keydata) { @@ -2590,7 +2616,7 @@ log_error (_("response does not contain the RSA modulus\n")); goto leave; } -/* log_printhex ("RSA n:", m, mlen); */ + /* log_printhex ("RSA n:", m, mlen); */ send_key_data (ctrl, "n", m, mlen); e = find_tlv (keydata, keydatalen, 0x0082, &elen); @@ -2600,7 +2626,7 @@ log_error (_("response does not contain the RSA public exponent\n")); goto leave; } -/* log_printhex ("RSA e:", e, elen); */ + /* log_printhex ("RSA e:", e, elen); */ send_key_data (ctrl, "e", e, elen); created_at = createtime? createtime : gnupg_get_time (); @@ -2995,6 +3021,7 @@ const char *s; int n; const char *fpr = NULL; + int exmode; if (!keyidstr || !*keyidstr || !indatalen) return gpg_error (GPG_ERR_INV_VALUE); @@ -3030,7 +3057,7 @@ the card. This is allows for a meaningful error message in case the key on the card has been replaced but the shadow information known to gpg was not updated. If there is no fingerprint, the - decryption will won't produce the right plaintext anyway. */ + decryption won't produce the right plaintext anyway. */ rc = fpr? check_against_given_fingerprint (app, fpr, 2) : 0; if (rc) return rc; @@ -3039,6 +3066,8 @@ if (!rc) { size_t fixuplen; + unsigned char *fixbuf = NULL; + int padind = 0; /* We might encounter a couple of leading zeroes in the cryptogram. Due to internal use of MPIs thease leading @@ -3049,39 +3078,46 @@ probability anyway broken. */ if (indatalen >= (128-16) && indatalen < 128) /* 1024 bit key. */ fixuplen = 128 - indatalen; + else if (indatalen >= (192-16) && indatalen < 192) /* 1536 bit key. */ + fixuplen = 192 - indatalen; else if (indatalen >= (256-16) && indatalen < 256) /* 2048 bit key. */ fixuplen = 256 - indatalen; - else if (indatalen >= (192-16) && indatalen < 192) /* 1536 bit key. */ - fixuplen = 192 - indatalen; + else if (indatalen >= (384-16) && indatalen < 384) /* 3072 bit key. */ + fixuplen = 384 - indatalen; else fixuplen = 0; + if (fixuplen) { - unsigned char *fixbuf; - /* While we have to prepend stuff anyway, we can also include the padding byte here so that iso1816_decipher - does not need to do yet another data mangling. */ + does not need to do another data mangling. */ fixuplen++; + fixbuf = xtrymalloc (fixuplen + indatalen); if (!fixbuf) - rc = gpg_error_from_syserror (); - else - { - memset (fixbuf, 0, fixuplen); - memcpy (fixbuf+fixuplen, indata, indatalen); - rc = iso7816_decipher (app->slot, 0, - fixbuf, fixuplen+indatalen, -1, - outdata, outdatalen); - xfree (fixbuf); - } - + return gpg_error_from_syserror (); + + memset (fixbuf, 0, fixuplen); + memcpy (fixbuf+fixuplen, indata, indatalen); + indata = fixbuf; + indatalen = fixuplen + indatalen; + padind = -1; /* Already padded. */ } + + if (app->app_local->cardcap.ext_lc_le && indatalen > 254 ) + exmode = 1; /* Extended length w/o a limit. */ + else if (app->app_local->cardcap.cmd_chaining && indatalen > 254) + exmode = -254; /* Command chaining with max. 254 bytes. */ else - rc = iso7816_decipher (app->slot, 0, - indata, indatalen, 0, - outdata, outdatalen); + exmode = 0; + + rc = iso7816_decipher (app->slot, exmode, + indata, indatalen, padind, + outdata, outdatalen); + xfree (fixbuf); } + return rc; } Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2009-05-07 15:01:47 UTC (rev 4996) +++ trunk/scd/ccid-driver.c 2009-05-08 15:07:45 UTC (rev 4997) @@ -159,7 +159,12 @@ #endif /* This source not used by scdaemon. */ +#ifndef EAGAIN +#define EAGAIN EWOULDBLOCK +#endif + + enum { RDR_to_PC_NotifySlotChange= 0x50, RDR_to_PC_HardwareError = 0x51, @@ -1811,6 +1816,7 @@ { int rc; size_t msglen; + int eagain_retries = 0; /* Fixme: The next line for the current Valgrind without support for USB IOCTLs. */ @@ -1824,7 +1830,13 @@ timeout); if (rc < 0) { - DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (errno)); + rc = errno; + DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (rc)); + if (rc == EAGAIN && eagain_retries++ < 5) + { + gnupg_sleep (1); + goto retry; + } return CCID_DRIVER_ERR_CARD_IO_ERROR; } *nread = msglen = rc; @@ -1834,12 +1846,19 @@ rc = read (handle->dev_fd, buffer, length); if (rc < 0) { + rc = errno; DEBUGOUT_2 ("read from %d failed: %s\n", - handle->dev_fd, strerror (errno)); + handle->dev_fd, strerror (rc)); + if (rc == EAGAIN && eagain_retries++ < 5) + { + gnupg_sleep (1); + goto retry; + } return CCID_DRIVER_ERR_CARD_IO_ERROR; } *nread = msglen = rc; } + eagain_retries = 0; if (msglen < 10) { @@ -1942,6 +1961,7 @@ /* Send the abort command to the control pipe. Note that we don't need to keep track of sent abort commands because there should never be another thread using the same slot concurrently. */ + handle->seqno--; /* Restore the last one sent. */ seqno = (handle->seqno & 0xff); rc = usb_control_msg (handle->idev, 0x21,/* bmRequestType: host-to-device, @@ -1958,34 +1978,36 @@ } /* Now send the abort command to the bulk out pipe using the same - SEQNO and SLOT. */ - msg[0] = PC_to_RDR_Abort; - msg[5] = 0; /* slot */ - msg[6] = seqno; - msg[7] = 0; /* RFU */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - msglen = 10; - set_msg_len (msg, 0); - handle->seqno++; /* Bumb up for the next use. */ + SEQNO and SLOT. Do this in a loop to so that all seqno are + tried. */ + seqno--; /* Adjust for next increment. */ + do + { + seqno++; + msg[0] = PC_to_RDR_Abort; + msg[5] = 0; /* slot */ + msg[6] = seqno; + msg[7] = 0; /* RFU */ + msg[8] = 0; /* RFU */ + msg[9] = 0; /* RFU */ + msglen = 10; + set_msg_len (msg, 0); - rc = usb_bulk_write (handle->idev, - handle->ep_bulk_out, - (char*)msg, msglen, - 5000 /* ms timeout */); - if (rc == msglen) - rc = 0; - else if (rc == -1) - DEBUGOUT_1 ("usb_bulk_write error in abort_cmd: %s\n", strerror (errno)); - else - DEBUGOUT_1 ("usb_bulk_write failed in abort_cmd: %d\n", rc); + rc = usb_bulk_write (handle->idev, + handle->ep_bulk_out, + (char*)msg, msglen, + 5000 /* ms timeout */); + if (rc == msglen) + rc = 0; + else if (rc == -1) + DEBUGOUT_1 ("usb_bulk_write error in abort_cmd: %s\n", + strerror (errno)); + else + DEBUGOUT_1 ("usb_bulk_write failed in abort_cmd: %d\n", rc); - if (rc) - return rc; - - /* Wait for the expected response. */ - do - { + if (rc) + return rc; + rc = usb_bulk_read (handle->idev, handle->ep_bulk_in, (char*)msg, sizeof msg, @@ -2017,6 +2039,7 @@ } while (msg[0] != RDR_to_PC_SlotStatus && msg[5] != 0 && msg[6] != seqno); + handle->seqno = seqno; DEBUGOUT ("sending abort sequence succeeded\n"); return 0; @@ -2430,12 +2453,13 @@ size_t *nresp) { int rc; - unsigned char send_buffer[10+261], recv_buffer[10+261]; + unsigned char send_buffer[10+261+300], recv_buffer[10+261+300]; const unsigned char *apdu; size_t apdulen; unsigned char *msg; size_t msglen; unsigned char seqno; + int bwi = 4; msg = send_buffer; @@ -2448,11 +2472,11 @@ extended APDU exchange level is not yet supported. */ if (apdulen > 261) return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */ - + msg[0] = PC_to_RDR_XfrBlock; msg[5] = 0; /* slot */ msg[6] = seqno = handle->seqno++; - msg[7] = 4; /* bBWI */ + msg[7] = bwi; /* bBWI */ msg[8] = 0; /* RFU */ msg[9] = 0; /* RFU */ memcpy (msg+10, apdu, apdulen); @@ -3274,6 +3298,13 @@ return 0; } +static coid +gnupg_sleep (int seconds) +{ + sleep (seconds); +} + + /* * Local Variables: * compile-command: "gcc -DTEST -Wall -I/usr/local/include -lusb -g ccid-driver.c" Modified: trunk/scd/iso7816.c =================================================================== --- trunk/scd/iso7816.c 2009-05-07 15:01:47 UTC (rev 4996) +++ trunk/scd/iso7816.c 2009-05-08 15:07:45 UTC (rev 4997) @@ -605,10 +605,15 @@ } +/* LE is the expected return length. This is usually 0 except if + extended length mode is used and more than 256 byte will be + returned. In that case a value of -1 uses a large default + (e.g. 4096 bytes), a value larger 256 used that value. */ static gpg_error_t -do_generate_keypair (int slot, int readonly, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) +do_generate_keypair (int slot, int extended_mode, int readonly, + const unsigned char *data, size_t datalen, + int le, + unsigned char **result, size_t *resultlen) { int sw; @@ -617,9 +622,11 @@ *result = NULL; *resultlen = 0; - sw = apdu_send (slot, 0, - 0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0, - datalen, (const char*)data, result, resultlen); + sw = apdu_send_le (slot, extended_mode, + 0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0, + datalen, (const char*)data, + le >= 0 && le < 256? 256:le, + result, resultlen); if (sw != SW_SUCCESS) { /* Make sure that pending buffers are released. */ @@ -634,20 +641,24 @@ gpg_error_t -iso7816_generate_keypair (int slot, +iso7816_generate_keypair (int slot, int extended_mode, const unsigned char *data, size_t datalen, + int le, unsigned char **result, size_t *resultlen) { - return do_generate_keypair (slot, 0, data, datalen, result, resultlen); + return do_generate_keypair (slot, extended_mode, 0, + data, datalen, le, result, resultlen); } gpg_error_t -iso7816_read_public_key (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) +iso7816_read_public_key (int slot, int extended_mode, + const unsigned char *data, size_t datalen, + int le, + unsigned char **result, size_t *resultlen) { - return do_generate_keypair (slot, 1, data, datalen, result, resultlen); + return do_generate_keypair (slot, extended_mode, 1, + data, datalen, le, result, resultlen); } Modified: trunk/scd/iso7816.h =================================================================== --- trunk/scd/iso7816.h 2009-05-07 15:01:47 UTC (rev 4996) +++ trunk/scd/iso7816.h 2009-05-08 15:07:45 UTC (rev 4997) @@ -103,12 +103,14 @@ gpg_error_t iso7816_internal_authenticate (int slot, const unsigned char *data, size_t datalen, unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_generate_keypair (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_read_public_key (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen); +gpg_error_t iso7816_generate_keypair (int slot, int extended_mode, + const unsigned char *data, size_t datalen, + int le, + unsigned char **result, size_t *resultlen); +gpg_error_t iso7816_read_public_key (int slot, int extended_mode, + const unsigned char *data, size_t datalen, + int le, + unsigned char **result, size_t *resultlen); gpg_error_t iso7816_get_challenge (int slot, int length, unsigned char *buffer); From cvs at cvs.gnupg.org Fri May 8 17:08:37 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 08 May 2009 17:08:37 +0200 Subject: [svn] GnuPG - r4998 - in trunk: doc jnlib Message-ID: Author: wk Date: 2009-05-08 17:08:37 +0200 (Fri, 08 May 2009) New Revision: 4998 Modified: trunk/doc/gpg.texi trunk/jnlib/dotlock.c Log: Doc fixes. Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2009-05-08 15:07:45 UTC (rev 4997) +++ trunk/doc/gpg.texi 2009-05-08 15:08:37 UTC (rev 4998) @@ -1949,7 +1949,7 @@ and use @code{none} to set no preference at all. This allows the user to factor in their own preferred algorithms when algorithms are chosen via recipient key preferences. The most highly ranked digest -algorithm in this list is algo used when signing without encryption +algorithm in this list is also used when signing without encryption (e.g. @option{--clearsign} or @option{--sign}). The default value is SHA-1. @@ -1959,7 +1959,7 @@ algorithms, and use @code{none} to set no preference at all. This allows the user to factor in their own preferred algorithms when algorithms are chosen via recipient key preferences. The most highly -ranked compression algorithm in this list is algo used when there are +ranked compression algorithm in this list is also used when there are no recipient keys to consider (e.g. @option{--symmetric}). @item --s2k-cipher-algo @code{name} Modified: trunk/jnlib/dotlock.c =================================================================== --- trunk/jnlib/dotlock.c 2009-05-08 15:07:45 UTC (rev 4997) +++ trunk/jnlib/dotlock.c 2009-05-08 15:08:37 UTC (rev 4998) @@ -165,7 +165,6 @@ */ snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() ); - /* fixme: add the hostname to the second line (FQDN or IP addr?) */ /* Create a temporary file. */ if ( uname ( &utsbuf ) ) From cvs at cvs.gnupg.org Sun May 10 18:27:32 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Sun, 10 May 2009 18:27:32 +0200 Subject: [svn] gcry - r1394 - in trunk: . cipher doc src Message-ID: Author: wk Date: 2009-05-10 18:27:32 +0200 (Sun, 10 May 2009) New Revision: 1394 Modified: trunk/ChangeLog trunk/README trunk/cipher/ChangeLog trunk/cipher/rsa.c trunk/doc/ChangeLog trunk/doc/gcrypt.texi trunk/src/gcrypt.h.in Log: Doc fixes. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-02 10:25:57 UTC (rev 1393) +++ trunk/ChangeLog 2009-05-10 16:27:32 UTC (rev 1394) @@ -1,3 +1,7 @@ +2009-04-23 Werner Koch + + * README: Add a section on build problems. + 2009-01-22 Werner Koch * configure.ac: Bump LT version to C17/A7/R0 to mark the start of Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2009-04-02 10:25:57 UTC (rev 1393) +++ trunk/cipher/ChangeLog 2009-05-10 16:27:32 UTC (rev 1394) @@ -1,3 +1,8 @@ +2009-03-31 Werner Koch + + * rsa.c (rsa_check_secret_key): Return GPG_ERR_BAD_SECKEY and not + GPG_ERR_PUBKEY_ALGO. + 2009-02-16 Werner Koch * rsa.c (generate_x931): Do not initialize TBL with automatic Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-04-02 10:25:57 UTC (rev 1393) +++ trunk/doc/ChangeLog 2009-05-10 16:27:32 UTC (rev 1394) @@ -1,3 +1,12 @@ +2009-05-10 Werner Koch + + * gcrypt.texi (Working with cipher handles): Clarified that + keylengths are in bytes. + +2009-04-02 Werner Koch + + * gcrypt.texi (Self-Tests): Fix register fucntion names. + 2009-02-22 Werner Koch * gcrypt.texi (Memory allocation): Fix describion of gcry-calloc. Modified: trunk/README =================================================================== --- trunk/README 2009-04-02 10:25:57 UTC (rev 1393) +++ trunk/README 2009-05-10 16:27:32 UTC (rev 1394) @@ -73,8 +73,8 @@ cd doc make pdf + - Mailing List ------------ @@ -132,7 +132,7 @@ time. This is helpful to create OS X fat binaries. --enable-random-daemon - Include support for a global random damon and + Include support for a global random daemon and build the daemon. This is an experimental feature. --enable-mpi-path=EXTRA_PATH @@ -170,9 +170,54 @@ available. Try this if you get problems with assembler code. - + Build Problems + -------------- + We can't check all assembler files, so if you have problems + assembling them (or the program crashes) use --disable-asm with + ./configure. If you opt to delete individual replacement files in + hopes of using the remaining ones, be aware that the configure + scripts may consider several subdirectories to get all available + assembler files; be sure to delete the correct ones. Never delete + udiv-qrnnd.S in any CPU directory, because there may be no C + substitute (in mpi/genereic). Don't forget to delete + "config.cache" and run "./config.status --recheck". We got a few + reports about problems using versions of gcc earlier than 2.96 + along with a non-GNU assembler (as). If this applies to your + platform, you can either upgrade gcc to a more recent version, or + use the GNU assembler. + + Some make tools are broken - the best solution is to use GNU's + make. Try gmake or grab the sources from a GNU archive and + install them. + + If you are cross-compiling and you get an error either building a + tool called "yat2m" or running that tool, the problem is most + likely a bad or missing native compiler. We require a standard + C-89 compiler to produce an executable to be run on the build + platform. You can explicitly set such a compiler with configure + arguments. On HP/UX you might want to try: "CC_FOR_BUILD=c89". + + Specific problems on some machines: + + * IBM RS/6000 running AIX + + Due to a change in gcc (since version 2.8) the MPI stuff may + not build. In this case try to run configure using: + CFLAGS="-g -O2 -mcpu=powerpc" ./configure + + * SVR4.2 (ESIX V4.2 cc) + + Due to problems with the ESIX as(1), you probably want to do: + CFLAGS="-O -K pentium" ./configure --disable-asm + + * SunOS 4.1.4 + + ./configure ac_cv_sys_symbol_underscore=yes + + + License ------- Modified: trunk/cipher/rsa.c =================================================================== --- trunk/cipher/rsa.c 2009-04-02 10:25:57 UTC (rev 1393) +++ trunk/cipher/rsa.c 2009-05-10 16:27:32 UTC (rev 1394) @@ -886,7 +886,7 @@ err = GPG_ERR_NO_OBJ; /* To check the key we need the optional parameters. */ else if (!check_secret_key (&sk)) - err = GPG_ERR_PUBKEY_ALGO; + err = GPG_ERR_BAD_SECKEY; return err; } Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2009-04-02 10:25:57 UTC (rev 1393) +++ trunk/doc/gcrypt.texi 2009-05-10 16:27:32 UTC (rev 1394) @@ -12,7 +12,7 @@ (version @value{VERSION}, @value{UPDATED}), which is GNU's library of cryptographic building blocks. -Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -1703,11 +1703,11 @@ @deftypefun gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t @var{h}, const void *@var{k}, size_t @var{l}) Set the key @var{k} used for encryption or decryption in the context -denoted by the handle @var{h}. The length @var{l} of the key @var{k} -must match the required length of the algorithm set for this context or -be in the allowed range for algorithms with variable key size. The -function checks this and returns an error if there is a problem. A -caller should always check for an error. +denoted by the handle @var{h}. The length @var{l} (in bytes) of the +key @var{k} must match the required length of the algorithm set for +this context or be in the allowed range for algorithms with variable +key size. The function checks this and returns an error if there is a +problem. A caller should always check for an error. @end deftypefun @@ -1719,18 +1719,18 @@ @deftypefun gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t @var{h}, const void *@var{k}, size_t @var{l}) Set the initialization vector used for encryption or decryption. The -vector is passed as the buffer @var{K} of length @var{l} and copied to -internal data structures. The function checks that the IV matches the -requirement of the selected algorithm and mode. +vector is passed as the buffer @var{K} of length @var{l} bytes and +copied to internal data structures. The function checks that the IV +matches the requirement of the selected algorithm and mode. @end deftypefun @deftypefun gcry_error_t gcry_cipher_setctr (gcry_cipher_hd_t @var{h}, const void *@var{c}, size_t @var{l}) Set the counter vector used for encryption or decryption. The counter -is passed as the buffer @var{c} of length @var{l} and copied to +is passed as the buffer @var{c} of length @var{l} bytes and copied to internal data structures. The function checks that the counter matches the requirement of the selected algorithm (i.e., it must be -the same size as the block size). +the same size as the block size). @end deftypefun @deftypefun gcry_error_t gcry_cipher_reset (gcry_cipher_hd_t @var{h}) @@ -3639,8 +3639,9 @@ @deftypefun gcry_error_t gcry_md_setkey (gcry_md_hd_t @var{h}, const void *@var{key}, size_t @var{keylen}) -For use with the HMAC feature, set the MAC key to the value of @var{key} -of length @var{keylen}. There is no restriction on the length of the key. +For use with the HMAC feature, set the MAC key to the value of + at var{key} of length @var{keylen} bytes. There is no restriction on +the length of the key. @end deftypefun @@ -5401,9 +5402,9 @@ Loading of extra modules into libgcrypt is disabled in FIPS mode and thus no tests are -implemented. (@code{cipher/@/cipher.c:@/gcry_cipher_register}, - at code{cipher/@/md.c:@/gcry_md_register}, - at code{cipher/@/md.c:@/gcry_pk_register}) +implemented. (@code{cipher/@/cipher.c:@/_gcry_cipher_register}, + at code{cipher/@/md.c:@/_gcry_md_register}, + at code{cipher/@/pubkey.c:@/_gcry_pk_register}) @subsection Manual Key Entry Tests Modified: trunk/src/gcrypt.h.in =================================================================== --- trunk/src/gcrypt.h.in 2009-04-02 10:25:57 UTC (rev 1393) +++ trunk/src/gcrypt.h.in 2009-05-10 16:27:32 UTC (rev 1394) @@ -909,7 +909,7 @@ void *out, size_t outsize, const void *in, size_t inlen); -/* Set KEY of length KEYLEN for the cipher handle HD. */ +/* Set KEY of length KEYLEN bytes for the cipher handle HD. */ gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen); @@ -935,10 +935,10 @@ gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen); -/* Retrieved the key length used with algorithm A. */ +/* Retrieved the key length in bytes used with algorithm A. */ size_t gcry_cipher_get_algo_keylen (int algo); -/* Retrieve the block length used with algorithm A. */ +/* Retrieve the block length in bytes used with algorithm A. */ size_t gcry_cipher_get_algo_blklen (int algo); /* Return 0 if the algorithm A is available for use. */ @@ -1174,7 +1174,7 @@ int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE; /* For use with the HMAC feature, the set MAC key to the KEY of - KEYLEN. */ + KEYLEN bytes. */ gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen); /* Start or stop debugging for digest handle HD; i.e. create a file From cvs at cvs.gnupg.org Mon May 11 05:21:42 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Mon, 11 May 2009 05:21:42 +0200 Subject: [svn] GnuPG - r4999 - trunk/keyserver Message-ID: Author: dshaw Date: 2009-05-11 05:21:41 +0200 (Mon, 11 May 2009) New Revision: 4999 Modified: trunk/keyserver/ChangeLog trunk/keyserver/curl-shim.h trunk/keyserver/gpgkeys_curl.c trunk/keyserver/gpgkeys_finger.c trunk/keyserver/gpgkeys_hkp.c trunk/keyserver/gpgkeys_ldap.c Log: >From 1.4: * curl-shim.h (curl_version): No need to provide a version for curl-shim as it always matches the GnuPG version. * gpgkeys_curl.c, gpgkeys_hkp.c (main): Show which version of curl we're using as part of --version. * gpgkeys_curl.c, gpgkeys_finger.c, gpgkeys_hkp.c, gpgkeys_ldap.c (show_help): Document --version. Modified: trunk/keyserver/ChangeLog =================================================================== --- trunk/keyserver/ChangeLog 2009-05-08 15:08:37 UTC (rev 4998) +++ trunk/keyserver/ChangeLog 2009-05-11 03:21:41 UTC (rev 4999) @@ -1,3 +1,16 @@ +2009-05-10 David Shaw + + From 1.4: + + * curl-shim.h (curl_version): No need to provide a version for + curl-shim as it always matches the GnuPG version. + + * gpgkeys_curl.c, gpgkeys_hkp.c (main): Show which version of curl + we're using as part of --version. + + * gpgkeys_curl.c, gpgkeys_finger.c, gpgkeys_hkp.c, + gpgkeys_ldap.c (show_help): Document --version. + 2009-05-04 David Shaw * gpgkeys_mailto.in: Set 'mail-from' as a keyserver-option, rather Modified: trunk/keyserver/curl-shim.h =================================================================== --- trunk/keyserver/curl-shim.h 2009-05-08 15:08:37 UTC (rev 4998) +++ trunk/keyserver/curl-shim.h 2009-05-11 03:21:41 UTC (rev 4999) @@ -1,5 +1,5 @@ /* curl-shim.h - * Copyright (C) 2005, 2006 Free Software Foundation, Inc. + * Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. * * This file is part of GNUPG. * @@ -91,7 +91,7 @@ void curl_easy_cleanup(CURL *curl); char *curl_escape(char *str,int len); #define curl_free(x) free(x) -#define curl_version() "GnuPG curl-shim "VERSION +#define curl_version() "GnuPG curl-shim" curl_version_info_data *curl_version_info(int type); #endif /* !_CURL_SHIM_H_ */ Modified: trunk/keyserver/gpgkeys_curl.c =================================================================== --- trunk/keyserver/gpgkeys_curl.c 2009-05-08 15:08:37 UTC (rev 4998) +++ trunk/keyserver/gpgkeys_curl.c 2009-05-11 03:21:41 UTC (rev 4999) @@ -102,9 +102,10 @@ static void show_help (FILE *fp) { - fprintf (fp,"-h\thelp\n"); - fprintf (fp,"-V\tversion\n"); - fprintf (fp,"-o\toutput to this file\n"); + fprintf (fp,"-h, --help\thelp\n"); + fprintf (fp,"-V\t\tmachine readable version\n"); + fprintf (fp,"--version\thuman readable version\n"); + fprintf (fp,"-o\t\toutput to this file\n"); } int @@ -122,7 +123,8 @@ /* Kludge to implement standard GNU options. */ if (argc > 1 && !strcmp (argv[1], "--version")) { - fputs ("gpgkeys_curl (GnuPG) " VERSION"\n", stdout); + printf ("gpgkeys_curl (GnuPG) %s\n", VERSION); + printf ("Uses: %s\n", curl_version()); return 0; } else if (argc > 1 && !strcmp (argv[1], "--help")) Modified: trunk/keyserver/gpgkeys_finger.c =================================================================== --- trunk/keyserver/gpgkeys_finger.c 2009-05-08 15:08:37 UTC (rev 4998) +++ trunk/keyserver/gpgkeys_finger.c 2009-05-11 03:21:41 UTC (rev 4999) @@ -319,9 +319,10 @@ static void show_help (FILE *fp) { - fprintf (fp,"-h\thelp\n"); - fprintf (fp,"-V\tversion\n"); - fprintf (fp,"-o\toutput to this file\n"); + fprintf (fp,"-h, --help\thelp\n"); + fprintf (fp,"-V\t\tmachine readable version\n"); + fprintf (fp,"--version\thuman readable version\n"); + fprintf (fp,"-o\t\toutput to this file\n"); } int Modified: trunk/keyserver/gpgkeys_hkp.c =================================================================== --- trunk/keyserver/gpgkeys_hkp.c 2009-05-08 15:08:37 UTC (rev 4998) +++ trunk/keyserver/gpgkeys_hkp.c 2009-05-11 03:21:41 UTC (rev 4999) @@ -492,9 +492,10 @@ static void show_help (FILE *fp) { - fprintf (fp,"-h\thelp\n"); - fprintf (fp,"-V\tversion\n"); - fprintf (fp,"-o\toutput to this file\n"); + fprintf (fp,"-h, --help\thelp\n"); + fprintf (fp,"-V\t\tmachine readable version\n"); + fprintf (fp,"--version\thuman readable version\n"); + fprintf (fp,"-o\t\toutput to this file\n"); } int @@ -511,7 +512,8 @@ /* Kludge to implement standard GNU options. */ if (argc > 1 && !strcmp (argv[1], "--version")) { - fputs ("gpgkeys_hkp (GnuPG) " VERSION"\n", stdout); + printf ("gpgkeys_hkp (GnuPG) %s\n", VERSION); + printf ("Uses: %s\n", curl_version()); return 0; } else if (argc > 1 && !strcmp (argv[1], "--help")) Modified: trunk/keyserver/gpgkeys_ldap.c =================================================================== --- trunk/keyserver/gpgkeys_ldap.c 2009-05-08 15:08:37 UTC (rev 4998) +++ trunk/keyserver/gpgkeys_ldap.c 2009-05-11 03:21:41 UTC (rev 4999) @@ -1773,9 +1773,10 @@ static void show_help (FILE *fp) { - fprintf (fp,"-h\thelp\n"); - fprintf (fp,"-V\tversion\n"); - fprintf (fp,"-o\toutput to this file\n"); + fprintf (fp,"-h, --help\thelp\n"); + fprintf (fp,"-V\t\tmachine readable version\n"); + fprintf (fp,"--version\thuman readable version\n"); + fprintf (fp,"-o\t\toutput to this file\n"); } int From cvs at cvs.gnupg.org Mon May 11 05:52:34 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Mon, 11 May 2009 05:52:34 +0200 Subject: [svn] GnuPG - r5000 - trunk/keyserver Message-ID: Author: dshaw Date: 2009-05-11 05:52:34 +0200 (Mon, 11 May 2009) New Revision: 5000 Modified: trunk/keyserver/ChangeLog trunk/keyserver/gpgkeys_hkp.c Log: * gpgkeys_hkp.c (send_key, get_key, get_name, search_key, main): Add support for SSLized HKP. Modified: trunk/keyserver/ChangeLog =================================================================== --- trunk/keyserver/ChangeLog 2009-05-11 03:21:41 UTC (rev 4999) +++ trunk/keyserver/ChangeLog 2009-05-11 03:52:34 UTC (rev 5000) @@ -1,7 +1,10 @@ 2009-05-10 David Shaw From 1.4: - + + * gpgkeys_hkp.c (send_key, get_key, get_name, search_key, main): + Add support for SSLized HKP. + * curl-shim.h (curl_version): No need to provide a version for curl-shim as it always matches the GnuPG version. Modified: trunk/keyserver/gpgkeys_hkp.c =================================================================== --- trunk/keyserver/gpgkeys_hkp.c 2009-05-11 03:21:41 UTC (rev 4999) +++ trunk/keyserver/gpgkeys_hkp.c 2009-05-11 03:52:34 UTC (rev 5000) @@ -1,6 +1,6 @@ /* gpgkeys_hkp.c - talk to an HKP keyserver - * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 - * 2008 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + * 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -53,6 +53,7 @@ static CURL *curl; static struct ks_options *opt; static char errorbuffer[CURL_ERROR_SIZE]; +static char *proto,*port; static size_t curl_mrindex_writer(const void *ptr,size_t size,size_t nmemb,void *stream) @@ -181,13 +182,10 @@ strcpy(key,"keytext="); strcat(key,encoded_key); - strcpy(request,"http://"); + strcpy(request,proto); strcat(request,opt->host); strcat(request,":"); - if(opt->port) - strcat(request,opt->port); - else - strcat(request,"11371"); + strcat(request,port); strcat(request,opt->path); /* request is MAX_URL+15 bytes long - MAX_URL covers the whole URL, including any supplied path. The 15 covers /pks/add. */ @@ -248,13 +246,10 @@ return KEYSERVER_NOT_SUPPORTED; } - strcpy(request,"http://"); + strcpy(request,proto); strcat(request,opt->host); strcat(request,":"); - if(opt->port) - strcat(request,opt->port); - else - strcat(request,"11371"); + strcat(request,port); strcat(request,opt->path); /* request is MAX_URL+55 bytes long - MAX_URL covers the whole URL, including any supplied path. The 60 overcovers this /pks/... etc @@ -329,13 +324,10 @@ fprintf(output,"NAME %s BEGIN\n",getkey); - strcpy(request,"http://"); + strcpy(request,proto); strcat(request,opt->host); strcat(request,":"); - if(opt->port) - strcat(request,opt->port); - else - strcat(request,"11371"); + strcat(request,port); strcat(request,opt->path); append_path(request,"/pks/lookup?op=get&options=mr&search="); strcat(request,searchkey_encoded); @@ -415,13 +407,10 @@ fprintf(output,"SEARCH %s BEGIN\n",searchkey); - strcpy(request,"http://"); + strcpy(request,proto); strcat(request,opt->host); strcat(request,":"); - if(opt->port) - strcat(request,opt->port); - else - strcat(request,"11371"); + strcat(request,port); strcat(request,opt->path); append_path(request,"/pks/lookup?op=index&options=mr&search="); @@ -628,6 +617,27 @@ } } + if(!opt->scheme) + { + fprintf(console,"gpgkeys: no scheme supplied!\n"); + ret=KEYSERVER_SCHEME_NOT_FOUND; + goto fail; + } + + if(ks_strcasecmp(opt->scheme,"hkps")==0) + { + proto="https://"; + port="443"; + } + else + { + proto="http://"; + port="11371"; + } + + if(opt->port) + port=opt->port; + if(!opt->host) { fprintf(console,"gpgkeys: no keyserver host provided\n"); @@ -661,6 +671,9 @@ curl_easy_setopt(curl,CURLOPT_VERBOSE,1L); } + curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert); + curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file); + if(proxy) curl_easy_setopt(curl,CURLOPT_PROXY,proxy); From cvs at cvs.gnupg.org Mon May 11 05:56:35 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Mon, 11 May 2009 05:56:35 +0200 Subject: [svn] GnuPG - r5001 - trunk/g10 Message-ID: Author: dshaw Date: 2009-05-11 05:56:34 +0200 (Mon, 11 May 2009) New Revision: 5001 Modified: trunk/g10/ChangeLog trunk/g10/keyserver.c Log: * keyserver.c (keyserver_typemap): gpgkeys_hkp handles hkps as well. >From 1.4. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-11 03:52:34 UTC (rev 5000) +++ trunk/g10/ChangeLog 2009-05-11 03:56:34 UTC (rev 5001) @@ -1,3 +1,8 @@ +2009-05-10 David Shaw + + * keyserver.c (keyserver_typemap): gpgkeys_hkp handles hkps as + well. From 1.4. + 2009-05-06 Werner Koch * getkey.c (finish_lookup): Remove dead code. Modified: trunk/g10/keyserver.c =================================================================== --- trunk/g10/keyserver.c 2009-05-11 03:52:34 UTC (rev 5000) +++ trunk/g10/keyserver.c 2009-05-11 03:56:34 UTC (rev 5001) @@ -1,6 +1,6 @@ /* keyserver.c - generic keyserver code - * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + * 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -941,6 +941,8 @@ { if(strcmp(type,"ldaps")==0) return "ldap"; + else if(strcmp(type,"hkps")==0) + return "hkp"; else return type; } From cvs at cvs.gnupg.org Mon May 11 11:20:40 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 11 May 2009 11:20:40 +0200 Subject: [svn] GnuPG - r5002 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2009-05-11 11:20:39 +0200 (Mon, 11 May 2009) New Revision: 5002 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/encode.c branches/STABLE-BRANCH-1-4/g10/sign.c Log: Print 'empty file' warning only with --verbose. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-11 03:56:34 UTC (rev 5001) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-11 09:20:39 UTC (rev 5002) @@ -1,3 +1,9 @@ +2009-05-11 Werner Koch + + * encode.c (encode_simple, encode_crypt): Print empty file warning + only in verbose mode. Closes bug#1039. + * sign.c (write_plaintext_packet): + 2009-05-06 Werner Koch * keyring.c (keyring_get_keyblock): Fix memory leak due to Modified: branches/STABLE-BRANCH-1-4/g10/encode.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/encode.c 2009-05-11 03:56:34 UTC (rev 5001) +++ branches/STABLE-BRANCH-1-4/g10/encode.c 2009-05-11 09:20:39 UTC (rev 5002) @@ -286,7 +286,7 @@ int overflow; if ( !(tmpsize = iobuf_get_filelength(inp, &overflow)) - && !overflow ) + && !overflow && opt.verbose) log_info(_("WARNING: `%s' is an empty file\n"), filename ); /* We can't encode the length of very large files because OpenPGP uses only 32 bit for file sizes. So if the the @@ -564,7 +564,7 @@ int overflow; if ( !(tmpsize = iobuf_get_filelength(inp, &overflow)) - && !overflow ) + && !overflow && opt.verbose) log_info(_("WARNING: `%s' is an empty file\n"), filename ); /* We can't encode the length of very large files because OpenPGP uses only 32 bit for file sizes. So if the the Modified: branches/STABLE-BRANCH-1-4/g10/sign.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/sign.c 2009-05-11 03:56:34 UTC (rev 5001) +++ branches/STABLE-BRANCH-1-4/g10/sign.c 2009-05-11 09:20:39 UTC (rev 5002) @@ -555,7 +555,7 @@ int overflow; if( !(tmpsize = iobuf_get_filelength(inp, &overflow)) - && !overflow ) + && !overflow && opt.verbose) log_info (_("WARNING: `%s' is an empty file\n"), fname); /* We can't encode the length of very large files because From cvs at cvs.gnupg.org Mon May 11 11:20:58 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 11 May 2009 11:20:58 +0200 Subject: [svn] GnuPG - r5003 - trunk/g10 Message-ID: Author: wk Date: 2009-05-11 11:20:57 +0200 (Mon, 11 May 2009) New Revision: 5003 Modified: trunk/g10/ChangeLog trunk/g10/encode.c trunk/g10/sign.c Log: Print 'empty file' warning only with --verbose. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-11 09:20:39 UTC (rev 5002) +++ trunk/g10/ChangeLog 2009-05-11 09:20:57 UTC (rev 5003) @@ -1,3 +1,10 @@ +2009-05-11 Werner Koch + + * encode.c (encode_simple): Print empty file warning only in + verbose mode. Closes bug#1039. + (encode_crypt): Ditto. + * sign.c (write_plaintext_packet): Ditto. + 2009-05-10 David Shaw * keyserver.c (keyserver_typemap): gpgkeys_hkp handles hkps as Modified: trunk/g10/encode.c =================================================================== --- trunk/g10/encode.c 2009-05-11 09:20:39 UTC (rev 5002) +++ trunk/g10/encode.c 2009-05-11 09:20:57 UTC (rev 5003) @@ -307,7 +307,7 @@ int overflow; if ( !(tmpsize = iobuf_get_filelength(inp, &overflow)) - && !overflow ) + && !overflow && opt.verbose) log_info(_("WARNING: `%s' is an empty file\n"), filename ); /* We can't encode the length of very large files because OpenPGP uses only 32 bit for file sizes. So if the the @@ -607,7 +607,7 @@ int overflow; if ( !(tmpsize = iobuf_get_filelength(inp, &overflow)) - && !overflow ) + && !overflow && opt.verbose) log_info(_("WARNING: `%s' is an empty file\n"), filename ); /* We can't encode the length of very large files because OpenPGP uses only 32 bit for file sizes. So if the the Modified: trunk/g10/sign.c =================================================================== --- trunk/g10/sign.c 2009-05-11 09:20:39 UTC (rev 5002) +++ trunk/g10/sign.c 2009-05-11 09:20:57 UTC (rev 5003) @@ -557,7 +557,7 @@ int overflow; if( !(tmpsize = iobuf_get_filelength(inp, &overflow)) - && !overflow ) + && !overflow && opt.verbose) log_info (_("WARNING: `%s' is an empty file\n"), fname); /* We can't encode the length of very large files because From cvs at cvs.gnupg.org Mon May 11 11:36:51 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 11 May 2009 11:36:51 +0200 Subject: [svn] GnuPG - r5004 - trunk/g10 Message-ID: Author: wk Date: 2009-05-11 11:36:51 +0200 (Mon, 11 May 2009) New Revision: 5004 Modified: trunk/g10/ChangeLog trunk/g10/skclist.c Log: Fix bug 1045. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-11 09:20:57 UTC (rev 5003) +++ trunk/g10/ChangeLog 2009-05-11 09:36:51 UTC (rev 5004) @@ -1,5 +1,8 @@ 2009-05-11 Werner Koch + * skclist.c (build_sk_list): Use log_info for "duplicated entry". + Fixes bug#1045. + * encode.c (encode_simple): Print empty file warning only in verbose mode. Closes bug#1039. (encode_crypt): Ditto. Modified: trunk/g10/skclist.c =================================================================== --- trunk/g10/skclist.c 2009-05-11 09:20:57 UTC (rev 5003) +++ trunk/g10/skclist.c 2009-05-11 09:36:51 UTC (rev 5004) @@ -166,7 +166,7 @@ */ if ( is_duplicated_entry ( locusr_orig, locusr ) ) { - log_error(_("skipped \"%s\": duplicated\n"), locusr->d ); + log_info (_("skipped \"%s\": duplicated\n"), locusr->d ); continue; } sk = xmalloc_clear( sizeof *sk ); From cvs at cvs.gnupg.org Mon May 11 11:37:26 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 11 May 2009 11:37:26 +0200 Subject: [svn] GnuPG - r5005 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2009-05-11 11:37:25 +0200 (Mon, 11 May 2009) New Revision: 5005 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/skclist.c Log: Fix bug 1045. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-11 09:36:51 UTC (rev 5004) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-11 09:37:25 UTC (rev 5005) @@ -1,5 +1,8 @@ 2009-05-11 Werner Koch + * skclist.c (build_sk_list): Use log_info for "duplicated entry". + Fixes bug#1045. + * encode.c (encode_simple, encode_crypt): Print empty file warning only in verbose mode. Closes bug#1039. * sign.c (write_plaintext_packet): Modified: branches/STABLE-BRANCH-1-4/g10/skclist.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/skclist.c 2009-05-11 09:36:51 UTC (rev 5004) +++ branches/STABLE-BRANCH-1-4/g10/skclist.c 2009-05-11 09:37:25 UTC (rev 5005) @@ -154,7 +154,7 @@ */ if ( is_duplicated_entry ( locusr_orig, locusr ) ) { - log_error(_("skipped \"%s\": duplicated\n"), locusr->d ); + log_info (_("skipped \"%s\": duplicated\n"), locusr->d ); continue; } sk = xmalloc_clear( sizeof *sk ); From cvs at cvs.gnupg.org Mon May 11 12:01:12 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 11 May 2009 12:01:12 +0200 Subject: [svn] GnuPG - r5006 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2009-05-11 12:01:11 +0200 (Mon, 11 May 2009) New Revision: 5006 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/apdu.c Log: Fix bug 1045 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-11 09:37:25 UTC (rev 5005) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-11 10:01:11 UTC (rev 5006) @@ -1,5 +1,7 @@ 2009-05-11 Werner Koch + * apdu.c (send_le): Replace log_error by log_info. Fixes bug#1043. + * skclist.c (build_sk_list): Use log_info for "duplicated entry". Fixes bug#1045. Modified: branches/STABLE-BRANCH-1-4/g10/apdu.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/apdu.c 2009-05-11 09:37:25 UTC (rev 5005) +++ branches/STABLE-BRANCH-1-4/g10/apdu.c 2009-05-11 10:01:11 UTC (rev 5006) @@ -2632,8 +2632,11 @@ rc = send_apdu (slot, apdu, apdulen, result, &resultlen, pininfo); if (rc || resultlen < 2) { - log_error ("apdu_send_simple(%d) failed: %s\n", - slot, apdu_strerror (rc)); + /* We use log_info here so that in case of a transient error, and + if this module is used by gpg standalone, the error counter + isn't incremented. */ + log_info ("apdu_send_simple(%d) failed: %s\n", + slot, apdu_strerror (rc)); unlock_slot (slot); return rc? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE; } From cvs at cvs.gnupg.org Wed May 13 13:42:35 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 13 May 2009 13:42:35 +0200 Subject: [svn] GnuPG - r5007 - in trunk: g10 scd Message-ID: Author: wk Date: 2009-05-13 13:42:34 +0200 (Wed, 13 May 2009) New Revision: 5007 Modified: trunk/g10/ChangeLog trunk/g10/keygen.c trunk/g10/parse-packet.c trunk/scd/ChangeLog trunk/scd/apdu.c trunk/scd/app-nks.c Log: Print keyid in gpg --list-packets. Add some not yet code to app-nks.c Changed batch mode expiration time computation Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-11 10:01:11 UTC (rev 5006) +++ trunk/g10/ChangeLog 2009-05-13 11:42:34 UTC (rev 5007) @@ -1,5 +1,12 @@ +2009-05-13 Werner Koch + + * keygen.c (parse_expire_string): Base ISO date string at noon. + Also allow full ISO timestamp. + 2009-05-11 Werner Koch + * parse-packet.c (parse_key): Print the key id in list mode. + * skclist.c (build_sk_list): Use log_info for "duplicated entry". Fixes bug#1045. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-05-11 10:01:11 UTC (rev 5006) +++ trunk/scd/ChangeLog 2009-05-13 11:42:34 UTC (rev 5007) @@ -1,3 +1,7 @@ +2009-05-11 Werner Koch + + * apdu.c (send_le): Replace log_error by log_info. + 2009-05-08 Werner Koch * app-openpgp.c (do_genkey): Allow larger key sizes. Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2009-05-11 10:01:11 UTC (rev 5006) +++ trunk/g10/keygen.c 2009-05-13 11:42:34 UTC (rev 5007) @@ -1799,13 +1799,17 @@ u32 seconds; u32 abs_date = 0; u32 curtime = make_timestamp (); + time_t tt; if (!*string) seconds = 0; else if (!strncmp (string, "seconds=", 8)) seconds = atoi (string+8); - else if ((abs_date = scan_isodatestr(string)) && abs_date > curtime) - seconds = abs_date - curtime; + else if ((abs_date = scan_isodatestr(string)) + && (abs_date+86400/2) > curtime) + seconds = (abs_date+86400/2) - curtime; + else if ((tt = isotime2epoch (string)) != (time_t)(-1)) + seconds = (u32)tt - curtime; else if ((mult = check_valid_days (string))) seconds = atoi (string) * 86400L * mult; else Modified: trunk/g10/parse-packet.c =================================================================== --- trunk/g10/parse-packet.c 2009-05-11 10:01:11 UTC (rev 5006) +++ trunk/g10/parse-packet.c 2009-05-13 11:42:34 UTC (rev 5007) @@ -1672,6 +1672,7 @@ int npkey, nskey; int is_v4=0; int rc=0; + u32 keyid[2]; (void)hdr; @@ -1997,6 +1998,9 @@ fprintf (listfp, "\tchecksum: %04hx\n", sk->csum); } } + + if (list_mode) + keyid_from_sk (sk, keyid); } else { PKT_public_key *pk = pkt->pkt.public_key; @@ -2021,8 +2025,14 @@ } if (rc) goto leave; + if (list_mode) + keyid_from_pk (pk, keyid); } + if (list_mode) + fprintf (listfp, "\tkeyid: %08lX%08lX\n", + (ulong)keyid[0], (ulong)keyid[1]); + leave: iobuf_skip_rest(inp, pktlen, 0); return rc; Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2009-05-11 10:01:11 UTC (rev 5006) +++ trunk/scd/apdu.c 2009-05-13 11:42:34 UTC (rev 5007) @@ -3000,8 +3000,8 @@ rc = send_apdu (slot, apdu, apdulen, result, &resultlen, pininfo); if (rc || resultlen < 2) { - log_error ("apdu_send_simple(%d) failed: %s\n", - slot, apdu_strerror (rc)); + log_info ("apdu_send_simple(%d) failed: %s\n", + slot, apdu_strerror (rc)); unlock_slot (slot); return rc? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE; } Modified: trunk/scd/app-nks.c =================================================================== --- trunk/scd/app-nks.c 2009-05-11 10:01:11 UTC (rev 5006) +++ trunk/scd/app-nks.c 2009-05-13 11:42:34 UTC (rev 5007) @@ -666,7 +666,98 @@ } +/* Handle the WRITEKEY command for NKS. This function expects a + canonical encoded S-expression with the public key in KEYDATA and + its length in KEYDATALEN. The only supported KEYID is + "$IFDAUTHKEY" to store the terminal key on the card. Bit 0 of + FLAGS indicates whether an existing key shall get overwritten. + PINCB and PINCB_ARG are the usual arguments for the pinentry + callback. */ static gpg_error_t +do_writekey (app_t app, ctrl_t ctrl, + const char *keyid, unsigned int flags, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg, + const unsigned char *keydata, size_t keydatalen) +{ + gpg_error_t err; + int force = (flags & 1); + const unsigned char *rsa_n = NULL; + const unsigned char *rsa_e = NULL; + size_t rsa_n_len, rsa_e_len; + unsigned int nbits; + + (void)ctrl; + (void)pincb; + (void)pincb_arg; + + if (!strcmp (keyid, "$IFDAUTHKEY") && app->app_local->nks_version >= 3) + ; + else + return gpg_error (GPG_ERR_INV_ID); + + if (!force && !do_readkey (app, keyid, NULL, NULL)) + return gpg_error (GPG_ERR_EEXIST); + + /* Parse the S-expression. */ + err = get_rsa_pk_from_canon_sexp (keydata, keydatalen, + &rsa_n, &rsa_n_len, &rsa_e, &rsa_e_len); + if (err) + goto leave; + + /* Check that the parameters match the requirements. */ + nbits = app_help_count_bits (rsa_n, rsa_n_len); + if (nbits != 1024) + { + log_error (_("RSA modulus missing or not of size %d bits\n"), 1024); + err = gpg_error (GPG_ERR_BAD_PUBKEY); + goto leave; + } + + nbits = app_help_count_bits (rsa_e, rsa_e_len); + if (nbits < 2 || nbits > 32) + { + log_error (_("RSA public exponent missing or larger than %d bits\n"), + 32); + err = gpg_error (GPG_ERR_BAD_PUBKEY); + goto leave; + } + +/* /\* Store them. *\/ */ +/* err = verify_pin (app, 0, NULL, pincb, pincb_arg); */ +/* if (err) */ +/* goto leave; */ + + /* Send the MSE:Store_Public_Key. */ + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); +/* mse = xtrymalloc (1000); */ + +/* mse[0] = 0x80; /\* Algorithm reference. *\/ */ +/* mse[1] = 1; */ +/* mse[2] = 0x17; */ +/* mse[3] = 0x84; /\* Private key reference. *\/ */ +/* mse[4] = 1; */ +/* mse[5] = 0x77; */ +/* mse[6] = 0x7F; /\* Public key parameter. *\/ */ +/* mse[7] = 0x49; */ +/* mse[8] = 0x81; */ +/* mse[9] = 3 + 0x80 + 2 + rsa_e_len; */ +/* mse[10] = 0x81; /\* RSA modulus of 128 byte. *\/ */ +/* mse[11] = 0x81; */ +/* mse[12] = rsa_n_len; */ +/* memcpy (mse+12, rsa_n, rsa_n_len); */ +/* mse[10] = 0x82; /\* RSA public exponent of up to 4 bytes. *\/ */ +/* mse[12] = rsa_e_len; */ +/* memcpy (mse+12, rsa_e, rsa_e_len); */ +/* err = iso7816_manage_security_env (app->slot, 0x81, 0xB6, */ +/* mse, sizeof mse); */ + + leave: + return err; +} + + +static gpg_error_t basic_pin_checks (const char *pinvalue, int minlen, int maxlen) { if (strlen (pinvalue) < minlen) @@ -1309,7 +1400,7 @@ app->fnc.readkey = do_readkey; app->fnc.getattr = do_getattr; app->fnc.setattr = NULL; - app->fnc.writekey = NULL; + app->fnc.writekey = do_writekey; app->fnc.genkey = NULL; app->fnc.sign = do_sign; app->fnc.auth = NULL; From cvs at cvs.gnupg.org Wed May 13 19:12:05 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 13 May 2009 19:12:05 +0200 Subject: [svn] GnuPG - r5008 - in trunk: . doc po scd Message-ID: Author: wk Date: 2009-05-13 19:12:00 +0200 (Wed, 13 May 2009) New Revision: 5008 Modified: trunk/NEWS trunk/doc/scdaemon.texi trunk/po/be.po trunk/po/ca.po trunk/po/cs.po trunk/po/da.po trunk/po/de.po trunk/po/el.po trunk/po/eo.po trunk/po/es.po trunk/po/et.po trunk/po/fi.po trunk/po/fr.po trunk/po/gl.po trunk/po/hu.po trunk/po/id.po trunk/po/it.po trunk/po/ja.po trunk/po/nb.po trunk/po/pl.po trunk/po/pt.po trunk/po/pt_BR.po trunk/po/ro.po trunk/po/ru.po trunk/po/sk.po trunk/po/sv.po trunk/po/tr.po trunk/po/zh_CN.po trunk/po/zh_TW.po trunk/scd/ChangeLog trunk/scd/apdu.c trunk/scd/apdu.h trunk/scd/ccid-driver.c trunk/scd/command.c Log: Improved smartcard robustness. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-05-13 11:42:34 UTC (rev 5007) +++ trunk/scd/ChangeLog 2009-05-13 17:12:00 UTC (rev 5008) @@ -1,3 +1,12 @@ +2009-05-13 Werner Koch + + * ccid-driver.c (abort_cmd): Add arg SEQNO and change callers. + (bulk_in): Retry on seqno mismatch. + + * apdu.c (send_le): Release result_buffer. + (apdu_send_direct): Implemend extended length. + * command.c (cmd_apdu): Add option "--exlen". + 2009-05-11 Werner Koch * apdu.c (send_le): Replace log_error by log_info. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-05-13 11:42:34 UTC (rev 5007) +++ trunk/NEWS 2009-05-13 17:12:00 UTC (rev 5008) @@ -15,13 +15,16 @@ * Changed order of the confirmation questions for root certificates and stores negative answers in trustlist.txt. - * Better synchronization of several smartcard sessions. + * Better synchronization of concurrent smartcard sessions. - * Support for the Telesec Netkey 3 cards. + * Support 2048 bit OpenPGP cards. + * Support Telesec Netkey 3 cards. + * The gpg-protect-tool now uses gpg-agent via libassuan. Under Windows the Pinentry will now be put into the foreground. + Noteworthy changes in version 2.0.11 (2009-03-03) ------------------------------------------------- Modified: trunk/doc/scdaemon.texi =================================================================== --- trunk/doc/scdaemon.texi 2009-05-13 11:42:34 UTC (rev 5007) +++ trunk/doc/scdaemon.texi 2009-05-13 17:12:00 UTC (rev 5008) @@ -670,7 +670,7 @@ @subsection Send a verbatim APDU to the card. @example - APDU [--atr] [--more] [@var{hexstring}] + APDU [--atr] [--more] [--exlen[=@var{n}]] [@var{hexstring}] @end example @@ -689,8 +689,12 @@ Using the option @code{--more} handles the card status word MORE_DATA (61xx) and concatenate all reponses to one block. +Using the option @code{--exlen} the returned APDU may use extended +length up to N bytes. If N is not given a default value is used +(currently 4096). + @mansect see also @ifset isman @command{gpg-agent}(1), Modified: trunk/po/be.po [not shown] Modified: trunk/po/ca.po [not shown] Modified: trunk/po/cs.po [not shown] Modified: trunk/po/da.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/el.po [not shown] Modified: trunk/po/eo.po [not shown] Modified: trunk/po/es.po [not shown] Modified: trunk/po/et.po [not shown] Modified: trunk/po/fi.po [not shown] Modified: trunk/po/fr.po [not shown] Modified: trunk/po/gl.po [not shown] Modified: trunk/po/hu.po [not shown] Modified: trunk/po/id.po [not shown] Modified: trunk/po/it.po [not shown] Modified: trunk/po/ja.po [not shown] Modified: trunk/po/nb.po [not shown] Modified: trunk/po/pl.po [not shown] Modified: trunk/po/pt.po [not shown] Modified: trunk/po/pt_BR.po [not shown] Modified: trunk/po/ro.po [not shown] Modified: trunk/po/ru.po [not shown] Modified: trunk/po/sk.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/po/tr.po [not shown] Modified: trunk/po/zh_CN.po [not shown] Modified: trunk/po/zh_TW.po [not shown] Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2009-05-13 11:42:34 UTC (rev 5007) +++ trunk/scd/apdu.c 2009-05-13 17:12:00 UTC (rev 5008) @@ -2930,7 +2930,11 @@ #undef SHORT_RESULT_BUFFER_SIZE if ((sw = lock_slot (slot))) - return sw; + { + xfree (apdu_buffer); + xfree (result_buffer); + return sw; + } do { @@ -3003,6 +3007,8 @@ log_info ("apdu_send_simple(%d) failed: %s\n", slot, apdu_strerror (rc)); unlock_slot (slot); + xfree (apdu_buffer); + xfree (result_buffer); return rc? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE; } sw = (result[resultlen-2] << 8) | result[resultlen-1]; @@ -3041,6 +3047,7 @@ if (!*retbuf) { unlock_slot (slot); + xfree (result_buffer); return SW_HOST_OUT_OF_CORE; } *retbuflen = resultlen; @@ -3060,6 +3067,7 @@ if (!*retbuf) { unlock_slot (slot); + xfree (result_buffer); return SW_HOST_OUT_OF_CORE; } assert (resultlen < bufsize); @@ -3091,6 +3099,7 @@ log_error ("apdu_send_simple(%d) for get response failed: %s\n", slot, apdu_strerror (rc)); unlock_slot (slot); + xfree (result_buffer); return rc? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE; } sw = (result[resultlen-2] << 8) | result[resultlen-1]; @@ -3116,6 +3125,7 @@ if (!tmp) { unlock_slot (slot); + xfree (result_buffer); return SW_HOST_OUT_OF_CORE; } p = tmp + (p - *retbuf); @@ -3142,6 +3152,7 @@ } unlock_slot (slot); + xfree (result_buffer); if (DBG_CARD_IO && retbuf && sw == SW_SUCCESS) log_printhex (" dump: ", *retbuf, *retbuflen); @@ -3231,23 +3242,27 @@ and returns with an APDU including the status word. With HANDLE_MORE set to true this function will handle the MORE DATA status and return all APDUs concatenated with one status word at - the end. If EXTENDED_MODE is not 0 command chaining or extended - length will be used; see send_le for details. The function does - not return a regular status word but 0 on success. If the slot is - locked, the function returns immediately with an error. */ + the end. If EXTENDED_LENGTH is != 0 extended lengths are allowed + with a max. result data length of EXTENDED_LENGTH bytes. The + function does not return a regular status word but 0 on success. + If the slot is locked, the function returns immediately with an + error. */ int -apdu_send_direct (int slot, int extended_mode, +apdu_send_direct (int slot, size_t extended_length, const unsigned char *apdudata, size_t apdudatalen, int handle_more, unsigned char **retbuf, size_t *retbuflen) { -#define RESULTLEN 258 - /* FIXME: Implement dynamic result buffer and extended Le. */ - unsigned char apdu[5+256+1]; +#define SHORT_RESULT_BUFFER_SIZE 258 + unsigned char short_result_buffer[SHORT_RESULT_BUFFER_SIZE+10]; + unsigned char *result_buffer = NULL; + size_t result_buffer_size; + unsigned char *result; + size_t resultlen; + unsigned char short_apdu_buffer[5+256+10]; + unsigned char *apdu_buffer = NULL; + unsigned char *apdu; size_t apdulen; - unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in - the driver. */ - size_t resultlen; int sw; long rc; /* we need a long here due to PC/SC. */ int class; @@ -3255,26 +3270,59 @@ if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; - if (extended_mode) - return SW_HOST_NOT_SUPPORTED; /* FIXME. */ + if (apdudatalen > 65535) + return SW_HOST_INV_VALUE; - if ((sw = trylock_slot (slot))) - return sw; - - /* We simply trunctate a too long APDU. */ - if (apdudatalen > sizeof apdu) - apdudatalen = sizeof apdu; + if (apdudatalen > sizeof short_apdu_buffer - 5) + { + apdu_buffer = xtrymalloc (apdudatalen + 5); + if (!apdu_buffer) + return SW_HOST_OUT_OF_CORE; + apdu = apdu_buffer; + } + else + { + apdu = short_apdu_buffer; + } apdulen = apdudatalen; memcpy (apdu, apdudata, apdudatalen); class = apdulen? *apdu : 0; - resultlen = RESULTLEN; + if (extended_length >= 256 && extended_length <= 65536) + { + result_buffer_size = extended_length; + result_buffer = xtrymalloc (result_buffer_size + 10); + if (!result_buffer) + { + xfree (apdu_buffer); + return SW_HOST_OUT_OF_CORE; + } + result = result_buffer; + } + else + { + result_buffer_size = SHORT_RESULT_BUFFER_SIZE; + result = short_result_buffer; + } +#undef SHORT_RESULT_BUFFER_SIZE + + if ((sw = trylock_slot (slot))) + { + xfree (apdu_buffer); + xfree (result_buffer); + return sw; + } + + resultlen = result_buffer_size; rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL); + xfree (apdu_buffer); + apdu_buffer = NULL; if (rc || resultlen < 2) { log_error ("apdu_send_direct(%d) failed: %s\n", slot, apdu_strerror (rc)); unlock_slot (slot); + xfree (result_buffer); return rc? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE; } sw = (result[resultlen-2] << 8) | result[resultlen-1]; @@ -3301,6 +3349,7 @@ if (!*retbuf) { unlock_slot (slot); + xfree (result_buffer); return SW_HOST_OUT_OF_CORE; } assert (resultlen < bufsize); @@ -3315,20 +3364,22 @@ if (DBG_CARD_IO) log_debug ("apdu_send_direct(%d): %d more bytes available\n", slot, len); + apdu = short_apdu_buffer; apdulen = 0; apdu[apdulen++] = class; apdu[apdulen++] = 0xC0; apdu[apdulen++] = 0; apdu[apdulen++] = 0; apdu[apdulen++] = len; - memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); - resultlen = RESULTLEN; + memset (apdu+apdulen, 0, sizeof (short_apdu_buffer) - apdulen); + resultlen = result_buffer_size; rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL); if (rc || resultlen < 2) { log_error ("apdu_send_direct(%d) for get response failed: %s\n", slot, apdu_strerror (rc)); unlock_slot (slot); + xfree (result_buffer); return rc ? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE; } sw = (result[resultlen-2] << 8) | result[resultlen-1]; @@ -3354,6 +3405,7 @@ if (!tmp) { unlock_slot (slot); + xfree (result_buffer); return SW_HOST_OUT_OF_CORE; } p = tmp + (p - *retbuf); @@ -3386,6 +3438,7 @@ if (!*retbuf) { unlock_slot (slot); + xfree (result_buffer); return SW_HOST_OUT_OF_CORE; } *retbuflen = resultlen; @@ -3394,6 +3447,7 @@ } unlock_slot (slot); + xfree (result_buffer); /* Append the status word. Note that we reserved the two extra bytes while allocating the buffer. */ @@ -3407,5 +3461,4 @@ log_printhex (" dump: ", *retbuf, *retbuflen); return 0; -#undef RESULTLEN } Modified: trunk/scd/apdu.h =================================================================== --- trunk/scd/apdu.h 2009-05-13 11:42:34 UTC (rev 5007) +++ trunk/scd/apdu.h 2009-05-13 17:12:00 UTC (rev 5008) @@ -125,7 +125,7 @@ int class, int ins, int p0, int p1, int lc, const char *data, int le, unsigned char **retbuf, size_t *retbuflen); -int apdu_send_direct (int slot, int extended_mode, +int apdu_send_direct (int slot, size_t extended_length, const unsigned char *apdudata, size_t apdudatalen, int handle_more, unsigned char **retbuf, size_t *retbuflen); Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2009-05-13 11:42:34 UTC (rev 5007) +++ trunk/scd/ccid-driver.c 2009-05-13 17:12:00 UTC (rev 5008) @@ -271,7 +271,7 @@ static int bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, size_t *nread, int expected_type, int seqno, int timeout, int no_debug); -static int abort_cmd (ccid_driver_t handle); +static int abort_cmd (ccid_driver_t handle, int seqno); /* Convert a little endian stored 4 byte value into an unsigned integer. */ @@ -1832,9 +1832,11 @@ { rc = errno; DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (rc)); - if (rc == EAGAIN && eagain_retries++ < 5) + if (rc == EAGAIN && eagain_retries++ < 3) { +#ifndef TEST gnupg_sleep (1); +#endif goto retry; } return CCID_DRIVER_ERR_CARD_IO_ERROR; @@ -1851,7 +1853,9 @@ handle->dev_fd, strerror (rc)); if (rc == EAGAIN && eagain_retries++ < 5) { +#ifndef TEST gnupg_sleep (1); +#endif goto retry; } return CCID_DRIVER_ERR_CARD_IO_ERROR; @@ -1863,21 +1867,20 @@ if (msglen < 10) { DEBUGOUT_1 ("bulk-in msg too short (%u)\n", (unsigned int)msglen); - abort_cmd (handle); + abort_cmd (handle, seqno); return CCID_DRIVER_ERR_INV_VALUE; } if (buffer[5] != 0) { DEBUGOUT_1 ("unexpected bulk-in slot (%d)\n", buffer[5]); - abort_cmd (handle); return CCID_DRIVER_ERR_INV_VALUE; } if (buffer[6] != seqno) { DEBUGOUT_2 ("bulk-in seqno does not match (%d/%d)\n", seqno, buffer[6]); - abort_cmd (handle); - return CCID_DRIVER_ERR_INV_VALUE; + /* Retry until we are synced again. */ + goto retry; } /* We need to handle the time extension request before we check that @@ -1895,7 +1898,7 @@ if (buffer[0] != expected_type) { DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]); - abort_cmd (handle); + abort_cmd (handle, seqno); return CCID_DRIVER_ERR_INV_VALUE; } @@ -1943,11 +1946,10 @@ /* Send an abort sequence and wait until everything settled. */ static int -abort_cmd (ccid_driver_t handle) +abort_cmd (ccid_driver_t handle, int seqno) { int rc; char dummybuf[8]; - unsigned char seqno; unsigned char msg[100]; size_t msglen; @@ -1957,12 +1959,11 @@ rc = CCID_DRIVER_ERR_NOT_SUPPORTED; } - DEBUGOUT ("sending abort sequence\n"); + seqno &= 0xff; + DEBUGOUT_1 ("sending abort sequence for seqno %d\n", seqno); /* Send the abort command to the control pipe. Note that we don't need to keep track of sent abort commands because there should never be another thread using the same slot concurrently. */ - handle->seqno--; /* Restore the last one sent. */ - seqno = (handle->seqno & 0xff); rc = usb_control_msg (handle->idev, 0x21,/* bmRequestType: host-to-device, class specific, to interface. */ @@ -2039,7 +2040,7 @@ } while (msg[0] != RDR_to_PC_SlotStatus && msg[5] != 0 && msg[6] != seqno); - handle->seqno = seqno; + handle->seqno = ((seqno + 1) & 0xff); DEBUGOUT ("sending abort sequence succeeded\n"); return 0; @@ -2178,7 +2179,7 @@ } -/* Note that this fucntion won't return the error codes NO_CARD or +/* Note that this function won't return the error codes NO_CARD or CARD_INACTIVE */ int ccid_slot_status (ccid_driver_t handle, int *statusbits) @@ -3298,13 +3299,6 @@ return 0; } -static coid -gnupg_sleep (int seconds) -{ - sleep (seconds); -} - - /* * Local Variables: * compile-command: "gcc -DTEST -Wall -I/usr/local/include -lusb -g ccid-driver.c" Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2009-05-13 11:42:34 UTC (rev 5007) +++ trunk/scd/command.c 2009-05-13 17:12:00 UTC (rev 5008) @@ -202,7 +202,7 @@ /* Same as has_option but does only test for the name of the option and ignores an argument, i.e. with NAME being "--hash" it would return a pointer for "--hash" as well as for "--hash=foo". If - thhere is no such option NULL is returned. The pointer returned + there is no such option NULL is returned. The pointer returned points right behind the option name, this may be an equal sign, Nul or a space. */ static const char * @@ -1722,7 +1722,7 @@ -/* APDU [--atr] [--more] [hexstring] +/* APDU [--atr] [--more] [--exlen[=N]] [hexstring] Send an APDU to the current reader. This command bypasses the high level functions and sends the data directly to the card. HEXSTRING @@ -1735,8 +1735,11 @@ S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1 Using the option --more handles the card status word MORE_DATA - (61xx) and concatenate all reponses to one block. + (61xx) and concatenates all reponses to one block. + Using the option "--exlen" the returned APDU may use extended + length up to N bytes. If N is not given a default value is used + (currently 4096). */ static int cmd_apdu (assuan_context_t ctx, char *line) @@ -1747,10 +1750,22 @@ size_t apdulen; int with_atr; int handle_more; + const char *s; + size_t exlen; with_atr = has_option (line, "--atr"); handle_more = has_option (line, "--more"); + if ((s=has_option_name (line, "--exlen"))) + { + if (*s == '=') + exlen = strtoul (s+1, NULL, 0); + else + exlen = 4096; + } + else + exlen = 0; + line = skip_options (line); if ( IS_LOCKED (ctrl) ) @@ -1787,7 +1802,8 @@ unsigned char *result = NULL; size_t resultlen; - rc = apdu_send_direct (ctrl->reader_slot, 0, apdu, apdulen, handle_more, + rc = apdu_send_direct (ctrl->reader_slot, exlen, + apdu, apdulen, handle_more, &result, &resultlen); if (rc) log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc)); From cvs at cvs.gnupg.org Thu May 14 09:40:51 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 14 May 2009 09:40:51 +0200 Subject: [svn] gpgme - r1367 - trunk/src Message-ID: Author: wk Date: 2009-05-14 09:40:51 +0200 (Thu, 14 May 2009) New Revision: 1367 Modified: trunk/src/ChangeLog trunk/src/gpgme.h.in Log: * gpgme.h.in (gpgme_status_code_t): Explicitly initialize for better maintainability and to help debugging. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-05-05 17:19:17 UTC (rev 1366) +++ trunk/src/ChangeLog 2009-05-14 07:40:51 UTC (rev 1367) @@ -1,3 +1,8 @@ +2009-05-14 Werner Koch + + * gpgme.h.in (gpgme_status_code_t): Explicitly initialize for + better maintainability and to help debugging. + 2009-05-05 Marcus Brinkmann * gpgme.h.in: Add compile time check for _FILE_OFFSET_BITS. Modified: trunk/src/gpgme.h.in =================================================================== --- trunk/src/gpgme.h.in 2009-05-05 17:19:17 UTC (rev 1366) +++ trunk/src/gpgme.h.in 2009-05-14 07:40:51 UTC (rev 1367) @@ -377,98 +377,98 @@ /* The possible stati for the edit operation. */ typedef enum { - GPGME_STATUS_EOF, + GPGME_STATUS_EOF = 0, /* mkstatus processing starts here */ - GPGME_STATUS_ENTER, - GPGME_STATUS_LEAVE, - GPGME_STATUS_ABORT, + GPGME_STATUS_ENTER = 1, + GPGME_STATUS_LEAVE = 2, + GPGME_STATUS_ABORT = 3, - GPGME_STATUS_GOODSIG, - GPGME_STATUS_BADSIG, - GPGME_STATUS_ERRSIG, + GPGME_STATUS_GOODSIG = 4, + GPGME_STATUS_BADSIG = 5, + GPGME_STATUS_ERRSIG = 6, - GPGME_STATUS_BADARMOR, + GPGME_STATUS_BADARMOR = 7, - GPGME_STATUS_RSA_OR_IDEA, - GPGME_STATUS_KEYEXPIRED, - GPGME_STATUS_KEYREVOKED, + GPGME_STATUS_RSA_OR_IDEA = 8, + GPGME_STATUS_KEYEXPIRED = 9, + GPGME_STATUS_KEYREVOKED = 10, - GPGME_STATUS_TRUST_UNDEFINED, - GPGME_STATUS_TRUST_NEVER, - GPGME_STATUS_TRUST_MARGINAL, - GPGME_STATUS_TRUST_FULLY, - GPGME_STATUS_TRUST_ULTIMATE, + GPGME_STATUS_TRUST_UNDEFINED = 11, + GPGME_STATUS_TRUST_NEVER = 12, + GPGME_STATUS_TRUST_MARGINAL = 13, + GPGME_STATUS_TRUST_FULLY = 14, + GPGME_STATUS_TRUST_ULTIMATE = 15, - GPGME_STATUS_SHM_INFO, - GPGME_STATUS_SHM_GET, - GPGME_STATUS_SHM_GET_BOOL, - GPGME_STATUS_SHM_GET_HIDDEN, + GPGME_STATUS_SHM_INFO = 16, + GPGME_STATUS_SHM_GET = 17, + GPGME_STATUS_SHM_GET_BOOL = 18, + GPGME_STATUS_SHM_GET_HIDDEN = 19, - GPGME_STATUS_NEED_PASSPHRASE, - GPGME_STATUS_VALIDSIG, - GPGME_STATUS_SIG_ID, - GPGME_STATUS_ENC_TO, - GPGME_STATUS_NODATA, - GPGME_STATUS_BAD_PASSPHRASE, - GPGME_STATUS_NO_PUBKEY, - GPGME_STATUS_NO_SECKEY, - GPGME_STATUS_NEED_PASSPHRASE_SYM, - GPGME_STATUS_DECRYPTION_FAILED, - GPGME_STATUS_DECRYPTION_OKAY, - GPGME_STATUS_MISSING_PASSPHRASE, - GPGME_STATUS_GOOD_PASSPHRASE, - GPGME_STATUS_GOODMDC, - GPGME_STATUS_BADMDC, - GPGME_STATUS_ERRMDC, - GPGME_STATUS_IMPORTED, - GPGME_STATUS_IMPORT_OK, - GPGME_STATUS_IMPORT_PROBLEM, - GPGME_STATUS_IMPORT_RES, - GPGME_STATUS_FILE_START, - GPGME_STATUS_FILE_DONE, - GPGME_STATUS_FILE_ERROR, + GPGME_STATUS_NEED_PASSPHRASE = 20, + GPGME_STATUS_VALIDSIG = 21, + GPGME_STATUS_SIG_ID = 22, + GPGME_STATUS_ENC_TO = 23, + GPGME_STATUS_NODATA = 24, + GPGME_STATUS_BAD_PASSPHRASE = 25, + GPGME_STATUS_NO_PUBKEY = 26, + GPGME_STATUS_NO_SECKEY = 27, + GPGME_STATUS_NEED_PASSPHRASE_SYM = 28, + GPGME_STATUS_DECRYPTION_FAILED = 29, + GPGME_STATUS_DECRYPTION_OKAY = 30, + GPGME_STATUS_MISSING_PASSPHRASE = 31, + GPGME_STATUS_GOOD_PASSPHRASE = 32, + GPGME_STATUS_GOODMDC = 33, + GPGME_STATUS_BADMDC = 34, + GPGME_STATUS_ERRMDC = 35, + GPGME_STATUS_IMPORTED = 36, + GPGME_STATUS_IMPORT_OK = 37, + GPGME_STATUS_IMPORT_PROBLEM = 38, + GPGME_STATUS_IMPORT_RES = 39, + GPGME_STATUS_FILE_START = 40, + GPGME_STATUS_FILE_DONE = 41, + GPGME_STATUS_FILE_ERROR = 42, - GPGME_STATUS_BEGIN_DECRYPTION, - GPGME_STATUS_END_DECRYPTION, - GPGME_STATUS_BEGIN_ENCRYPTION, - GPGME_STATUS_END_ENCRYPTION, + GPGME_STATUS_BEGIN_DECRYPTION = 43, + GPGME_STATUS_END_DECRYPTION = 44, + GPGME_STATUS_BEGIN_ENCRYPTION = 45, + GPGME_STATUS_END_ENCRYPTION = 46, - GPGME_STATUS_DELETE_PROBLEM, - GPGME_STATUS_GET_BOOL, - GPGME_STATUS_GET_LINE, - GPGME_STATUS_GET_HIDDEN, - GPGME_STATUS_GOT_IT, - GPGME_STATUS_PROGRESS, - GPGME_STATUS_SIG_CREATED, - GPGME_STATUS_SESSION_KEY, - GPGME_STATUS_NOTATION_NAME, - GPGME_STATUS_NOTATION_DATA, - GPGME_STATUS_POLICY_URL, - GPGME_STATUS_BEGIN_STREAM, - GPGME_STATUS_END_STREAM, - GPGME_STATUS_KEY_CREATED, - GPGME_STATUS_USERID_HINT, - GPGME_STATUS_UNEXPECTED, - GPGME_STATUS_INV_RECP, - GPGME_STATUS_NO_RECP, - GPGME_STATUS_ALREADY_SIGNED, - GPGME_STATUS_SIGEXPIRED, - GPGME_STATUS_EXPSIG, - GPGME_STATUS_EXPKEYSIG, - GPGME_STATUS_TRUNCATED, - GPGME_STATUS_ERROR, - GPGME_STATUS_NEWSIG, - GPGME_STATUS_REVKEYSIG, - GPGME_STATUS_SIG_SUBPACKET, - GPGME_STATUS_NEED_PASSPHRASE_PIN, - GPGME_STATUS_SC_OP_FAILURE, - GPGME_STATUS_SC_OP_SUCCESS, - GPGME_STATUS_CARDCTRL, - GPGME_STATUS_BACKUP_KEY_CREATED, - GPGME_STATUS_PKA_TRUST_BAD, - GPGME_STATUS_PKA_TRUST_GOOD, + GPGME_STATUS_DELETE_PROBLEM = 47, + GPGME_STATUS_GET_BOOL = 48, + GPGME_STATUS_GET_LINE = 49, + GPGME_STATUS_GET_HIDDEN = 50, + GPGME_STATUS_GOT_IT = 51, + GPGME_STATUS_PROGRESS = 52, + GPGME_STATUS_SIG_CREATED = 53, + GPGME_STATUS_SESSION_KEY = 54, + GPGME_STATUS_NOTATION_NAME = 55, + GPGME_STATUS_NOTATION_DATA = 56, + GPGME_STATUS_POLICY_URL = 57, + GPGME_STATUS_BEGIN_STREAM = 58, + GPGME_STATUS_END_STREAM = 59, + GPGME_STATUS_KEY_CREATED = 60, + GPGME_STATUS_USERID_HINT = 61, + GPGME_STATUS_UNEXPECTED = 62, + GPGME_STATUS_INV_RECP = 63, + GPGME_STATUS_NO_RECP = 64, + GPGME_STATUS_ALREADY_SIGNED = 65, + GPGME_STATUS_SIGEXPIRED = 66, + GPGME_STATUS_EXPSIG = 67, + GPGME_STATUS_EXPKEYSIG = 68, + GPGME_STATUS_TRUNCATED = 69, + GPGME_STATUS_ERROR = 70, + GPGME_STATUS_NEWSIG = 71, + GPGME_STATUS_REVKEYSIG = 72, + GPGME_STATUS_SIG_SUBPACKET = 73, + GPGME_STATUS_NEED_PASSPHRASE_PIN = 74, + GPGME_STATUS_SC_OP_FAILURE = 75, + GPGME_STATUS_SC_OP_SUCCESS = 76, + GPGME_STATUS_CARDCTRL = 77, + GPGME_STATUS_BACKUP_KEY_CREATED = 78, + GPGME_STATUS_PKA_TRUST_BAD = 79, + GPGME_STATUS_PKA_TRUST_GOOD = 80, - GPGME_STATUS_PLAINTEXT + GPGME_STATUS_PLAINTEXT = 81 } gpgme_status_code_t; From cvs at cvs.gnupg.org Fri May 15 13:16:29 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 15 May 2009 13:16:29 +0200 Subject: [svn] GnuPG - r5009 - trunk/agent Message-ID: Author: wk Date: 2009-05-15 13:16:28 +0200 (Fri, 15 May 2009) New Revision: 5009 Modified: trunk/agent/ChangeLog trunk/agent/agent.h trunk/agent/cache.c trunk/agent/call-pinentry.c trunk/agent/command-ssh.c trunk/agent/command.c trunk/agent/findkey.c trunk/agent/pkdecrypt.c trunk/agent/pksign.c Log: Fix bug #1053 Add option --qualitybar to command GET_PASSPHRASE. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2009-05-13 17:12:00 UTC (rev 5008) +++ trunk/agent/ChangeLog 2009-05-15 11:16:28 UTC (rev 5009) @@ -1,3 +1,22 @@ +2009-05-15 Werner Koch + + Fix bug #1053. + + * agent.h (lookup_ttl_t): New. + * findkey.c (unprotect): Add arg LOOKUP_TTL. + (agent_key_from_file): Ditto. + * pksign.c (agent_pksign_do): Ditto. + * command-ssh.c (ttl_from_sshcontrol): New. + (data_sign): Pass new function to agent_pksign_do. + (search_control_file): Add new arg R_TTL. + +2009-05-14 Werner Koch + + * command.c (cmd_get_passphrase): Add option --qualitybar. + * call-pinentry.c (agent_askpin): Factor some code out to ... + (setup_qualitybar): .. new. + (agent_get_passphrase): Add arg WITH_QUALITYBAR and implement it. + 2009-04-14 Marcus Brinkmann * call-pinentry.c (agent_get_confirmation): Try SETNOTOK command Modified: trunk/agent/agent.h =================================================================== --- trunk/agent/agent.h 2009-05-13 17:12:00 UTC (rev 5008) +++ trunk/agent/agent.h 2009-05-15 11:16:28 UTC (rev 5009) @@ -201,6 +201,10 @@ cache_mode_t; +/* The type of a function to lookup a TTL by a keygrip. */ +typedef int (*lookup_ttl_t)(const char *hexgrip); + + /*-- gpg-agent.c --*/ void agent_exit (int rc) JNLIB_GCC_A_NR; /* Also implemented in other tools */ const char *get_agent_socket_name (void); @@ -229,6 +233,7 @@ const unsigned char *grip, unsigned char **shadow_info, cache_mode_t cache_mode, + lookup_ttl_t lookup_ttl, gcry_sexp_t *result); gpg_error_t agent_public_key_from_file (ctrl_t ctrl, const unsigned char *grip, @@ -249,7 +254,7 @@ struct pin_entry_info_s *pininfo); int agent_get_passphrase (ctrl_t ctrl, char **retpass, const char *desc, const char *prompt, - const char *errtext); + const char *errtext, int with_qualitybar); int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok, const char *cancel); int agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn); @@ -270,7 +275,7 @@ /*-- pksign.c --*/ int agent_pksign_do (ctrl_t ctrl, const char *desc_text, gcry_sexp_t *signature_sexp, - cache_mode_t cache_mode); + cache_mode_t cache_mode, lookup_ttl_t lookup_ttl); int agent_pksign (ctrl_t ctrl, const char *desc_text, membuf_t *outbuf, cache_mode_t cache_mode); Modified: trunk/agent/cache.c =================================================================== --- trunk/agent/cache.c 2009-05-13 17:12:00 UTC (rev 5008) +++ trunk/agent/cache.c 2009-05-15 11:16:28 UTC (rev 5009) @@ -194,8 +194,8 @@ with a maximum lifetime of TTL seconds. If there is already data under this key, it will be replaced. Using a DATA of NULL deletes the entry. A TTL of 0 is replaced by the default TTL and a TTL of - -1 set infinite timeout. CACHE_MODE is stored with the cache entry - and used t select different timeouts. */ + -1 set infinite timeout. CACHE_MODE is stored with the cache entry + and used to select different timeouts. */ int agent_put_cache (const char *key, cache_mode_t cache_mode, const char *data, int ttl) Modified: trunk/agent/call-pinentry.c =================================================================== --- trunk/agent/call-pinentry.c 2009-05-13 17:12:00 UTC (rev 5008) +++ trunk/agent/call-pinentry.c 2009-05-15 11:16:28 UTC (rev 5009) @@ -570,8 +570,61 @@ } +/* Helper for agent_askpin and agent_get_passphrase. */ +static int +setup_qualitybar (void) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + char *tmpstr, *tmpstr2; + const char *tooltip; + + /* TRANSLATORS: This string is displayed by Pinentry as the label + for the quality bar. */ + tmpstr = try_percent_escape (_("Quality:"), "\t\r\n\f\v"); + snprintf (line, DIM(line)-1, "SETQUALITYBAR %s", tmpstr? tmpstr:""); + line[DIM(line)-1] = 0; + xfree (tmpstr); + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc == 103 /*(Old assuan error code)*/ + || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD) + ; /* Ignore Unknown Command from old Pinentry versions. */ + else if (rc) + return rc; + + tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0); + if (tmpstr2) + tooltip = tmpstr2; + else + { + /* TRANSLATORS: This string is a tooltip, shown by pinentry when + hovering over the quality bar. Please use an appropriate + string to describe what this is about. The length of the + tooltip is limited to about 900 characters. If you do not + translate this entry, a default english text (see source) + will be used. */ + tooltip = _("pinentry.qualitybar.tooltip"); + if (!strcmp ("pinentry.qualitybar.tooltip", tooltip)) + tooltip = ("The quality of the text entered above.\n" + "Please ask your administrator for " + "details about the criteria."); + } + tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v"); + xfree (tmpstr2); + snprintf (line, DIM(line)-1, "SETQUALITYBAR_TT %s", tmpstr? tmpstr:""); + line[DIM(line)-1] = 0; + xfree (tmpstr); + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc == 103 /*(Old assuan error code)*/ + || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD) + ; /* Ignore Unknown Command from old pinentry versions. */ + else if (rc) + return rc; + return 0; +} + /* Call the Entry and ask for the PIN. We do check for a valid PIN number here and repeat it as long as we have invalid formed @@ -627,52 +680,9 @@ to the pinentry. */ if (pininfo->with_qualitybar && opt.min_passphrase_len ) { - char *tmpstr, *tmpstr2; - const char *tooltip; - - /* TRANSLATORS: This string is displayed by pinentry as the - label for the quality bar. */ - tmpstr = try_percent_escape (_("Quality:"), "\t\r\n\f\v"); - snprintf (line, DIM(line)-1, "SETQUALITYBAR %s", tmpstr? tmpstr:""); - line[DIM(line)-1] = 0; - xfree (tmpstr); - rc = assuan_transact (entry_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc == 103 /*(Old assuan error code)*/ - || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD) - ; /* Ignore Unknown Command from old pinentry versions. */ - else if (rc) + rc = setup_qualitybar (); + if (rc) return unlock_pinentry (rc); - - tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0); - if (tmpstr2) - tooltip = tmpstr2; - else - { - /* TRANSLATORS: This string is a tooltip, shown by pinentry - when hovering over the quality bar. Please use an - appropriate string to describe what this is about. The - length of the tooltip is limited to about 900 characters. - If you do not translate this entry, a default english - text (see source) will be used. */ - tooltip = _("pinentry.qualitybar.tooltip"); - if (!strcmp ("pinentry.qualitybar.tooltip", tooltip)) - tooltip = ("The quality of the text entered above.\n" - "Please ask your administrator for " - "details about the criteria."); - } - tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v"); - xfree (tmpstr2); - snprintf (line, DIM(line)-1, "SETQUALITYBAR_TT %s", tmpstr? tmpstr:""); - line[DIM(line)-1] = 0; - xfree (tmpstr); - rc = assuan_transact (entry_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc == 103 /*(Old assuan error code)*/ - || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD) - ; /* Ignore Unknown Command from old pinentry versions. */ - else if (rc) - return unlock_pinentry (rc); } if (initial_errtext) @@ -764,7 +774,7 @@ int agent_get_passphrase (ctrl_t ctrl, char **retpass, const char *desc, const char *prompt, - const char *errtext) + const char *errtext, int with_qualitybar) { int rc; @@ -798,6 +808,13 @@ if (rc) return unlock_pinentry (rc); + if (with_qualitybar && opt.min_passphrase_len) + { + rc = setup_qualitybar (); + if (rc) + return unlock_pinentry (rc); + } + if (errtext) { snprintf (line, DIM(line)-1, "SETERROR %s", errtext); @@ -815,7 +832,7 @@ assuan_begin_confidential (entry_ctx); rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, - NULL, NULL, NULL, NULL); + inq_quality, entry_ctx, NULL, NULL); /* Most pinentries out in the wild return the old Assuan error code for canceled which gets translated to an assuan Cancel error and not to the code for a user cancel. Fix this here. */ Modified: trunk/agent/command-ssh.c =================================================================== --- trunk/agent/command-ssh.c 2009-05-13 17:12:00 UTC (rev 5008) +++ trunk/agent/command-ssh.c 2009-05-15 11:16:28 UTC (rev 5009) @@ -1,5 +1,5 @@ /* command-ssh.c - gpg-agent's ssh-agent emulation layer - * Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. + * Copyright (C) 2004, 2005, 2006, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -710,17 +710,20 @@ /* Search the file at stream FP from the beginning until a matching HEXGRIP is found; return success in this case and store true at - DISABLED if the found key has been disabled. */ + DISABLED if the found key has been disabled. If R_TTL is not NULL + a specified TTL for that key is stored there. */ static gpg_error_t -search_control_file (FILE *fp, const char *hexgrip, int *disabled) +search_control_file (FILE *fp, const char *hexgrip, + int *r_disabled, int *r_ttl) { int c, i; - char *p, line[256]; - + char *p, *pend, line[256]; + long ttl; + assert (strlen (hexgrip) == 40 ); rewind (fp); - *disabled = 0; + *r_disabled = 0; next_line: do { @@ -746,10 +749,10 @@ } while (!*p || *p == '\n' || *p == '#'); - *disabled = 0; + *r_disabled = 0; if (*p == '!') { - *disabled = 1; + *r_disabled = 1; for (p++; spacep (p); p++) ; } @@ -763,8 +766,18 @@ return gpg_error (GPG_ERR_BAD_DATA); } - /* Fixme: Get TTL and flags. */ + ttl = strtol (p, &pend, 10); + p = pend; + if (!(spacep (p) || *p == '\n') || ttl < -1) + { + log_error ("invalid TTL value in ssh control file; assuming 0\n"); + ttl = 0; + } + if (r_ttl) + *r_ttl = ttl; + /* Here is the place to parse flags if we need them. */ + return 0; /* Okay: found it. */ } @@ -788,7 +801,7 @@ if (err) return err; - err = search_control_file (fp, hexgrip, &disabled); + err = search_control_file (fp, hexgrip, &disabled, NULL); if (err && gpg_err_code(err) == GPG_ERR_EOF) { struct tm *tp; @@ -808,7 +821,30 @@ } +/* Scan the sshcontrol file and return the TTL. */ +static int +ttl_from_sshcontrol (const char *hexgrip) +{ + FILE *fp; + int disabled, ttl; + if (!hexgrip || strlen (hexgrip) != 40) + return 0; /* Wrong input: Use global default. */ + + if (open_control_file (&fp, 0)) + return 0; /* Error: Use the global default TTL. */ + + if (search_control_file (fp, hexgrip, &disabled, &ttl) + || disabled) + ttl = 0; /* Use the global default if not found or disabled. */ + + fclose (fp); + + return ttl; +} + + + /* @@ -1875,7 +1911,7 @@ hexgrip[40] = 0; if ( strlen (hexgrip) != 40 ) continue; - if (search_control_file (ctrl_fp, hexgrip, &disabled) + if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL) || disabled) continue; @@ -1972,6 +2008,7 @@ return ret_err; } + /* This function hashes the data contained in DATA of size DATA_N according to the message digest algorithm specified by MD_ALGORITHM and writes the message digest to HASH, which needs to large enough @@ -2017,7 +2054,7 @@ err = agent_pksign_do (ctrl, _("Please enter the passphrase " "for the ssh key%0A %c"), &signature_sexp, - CACHE_MODE_SSH); + CACHE_MODE_SSH, ttl_from_sshcontrol); ctrl->use_auth_call = 0; if (err) goto out; Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2009-05-13 17:12:00 UTC (rev 5008) +++ trunk/agent/command.c 2009-05-15 11:16:28 UTC (rev 5009) @@ -986,7 +986,8 @@ } -/* GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]] +/* GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]] + [--qualitybar] [ ] This function is usually used to ask for a passphrase to be used @@ -1007,6 +1008,10 @@ If the option "--no-ask" is used and the passphrase is not in the cache the user will not be asked to enter a passphrase but the error code GPG_ERR_NO_DATA is returned. + + If the option "--qualitybar" is used a visual indication of the + entered passphrase quality is shown. (Unless no minimum passphrase + length has been configured.) */ static int @@ -1020,7 +1025,8 @@ const char *desc2 = _("Please re-enter this passphrase"); char *p; void *cache_marker; - int opt_data, opt_check, opt_no_ask, opt_repeat = 0; + int opt_data, opt_check, opt_no_ask, opt_qualbar; + int opt_repeat = 0; char *repeat_errtext = NULL; opt_data = has_option (line, "--data"); @@ -1034,6 +1040,7 @@ else opt_repeat = 1; } + opt_qualbar = has_option (line, "--qualitybar"); line = skip_options (line); cacheid = line; @@ -1102,7 +1109,8 @@ next_try: rc = agent_get_passphrase (ctrl, &response, desc, prompt, - repeat_errtext? repeat_errtext:errtext); + repeat_errtext? repeat_errtext:errtext, + opt_qualbar); xfree (repeat_errtext); repeat_errtext = NULL; if (!rc) @@ -1119,7 +1127,7 @@ char *response2; rc = agent_get_passphrase (ctrl, &response2, desc2, prompt, - errtext); + errtext, 0); if (rc) break; if (strcmp (response2, response)) @@ -1265,7 +1273,8 @@ ctrl->in_passwd++; rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc, - grip, &shadow_info, CACHE_MODE_IGNORE, &s_skey); + grip, &shadow_info, CACHE_MODE_IGNORE, NULL, + &s_skey); if (rc) ; else if (!s_skey) Modified: trunk/agent/findkey.c =================================================================== --- trunk/agent/findkey.c 2009-05-13 17:12:00 UTC (rev 5008) +++ trunk/agent/findkey.c 2009-05-15 11:16:28 UTC (rev 5009) @@ -297,11 +297,12 @@ /* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP should be the hex encoded keygrip of that key to be used with the caching mechanism. DESC_TEXT may be set to override the default - description used for the pinentry. */ + description used for the pinentry. If LOOKUP_TTL is given this + function is used to lookup the default ttl. */ static int unprotect (ctrl_t ctrl, const char *desc_text, unsigned char **keybuf, const unsigned char *grip, - cache_mode_t cache_mode) + cache_mode_t cache_mode, lookup_ttl_t lookup_ttl) { struct pin_entry_info_s *pi; struct try_unprotect_arg_s arg; @@ -406,7 +407,8 @@ return rc; } } - agent_put_cache (hexgrip, cache_mode, pi->pin, 0); + agent_put_cache (hexgrip, cache_mode, pi->pin, + lookup_ttl? lookup_ttl (hexgrip) : 0); xfree (*keybuf); *keybuf = arg.unprotected_key; } @@ -488,11 +490,16 @@ to a token; in this case an allocated S-expression with the shadow_info part from the file is stored at SHADOW_INFO. CACHE_MODE defines now the cache shall be used. DESC_TEXT may be - set to present a custom description for the pinentry. */ + set to present a custom description for the pinentry. LOOKUP_TTL + is an optional function to convey a TTL to the cache manager; we do + not simply pass the TTL value because the value is only needed if an + unprotect action was needed and looking up the TTL may have some + overhead (e.g. scanning the sshcontrol file). */ gpg_error_t agent_key_from_file (ctrl_t ctrl, const char *desc_text, const unsigned char *grip, unsigned char **shadow_info, - cache_mode_t cache_mode, gcry_sexp_t *result) + cache_mode_t cache_mode, lookup_ttl_t lookup_ttl, + gcry_sexp_t *result) { int rc; unsigned char *buf; @@ -502,7 +509,7 @@ *result = NULL; if (shadow_info) - *shadow_info = NULL; + *shadow_info = NULL; rc = read_key_file (grip, &s_skey); if (rc) @@ -563,7 +570,8 @@ if (!rc) { - rc = unprotect (ctrl, desc_text_final, &buf, grip, cache_mode); + rc = unprotect (ctrl, desc_text_final, &buf, grip, + cache_mode, lookup_ttl); if (rc) log_error ("failed to unprotect the secret key: %s\n", gpg_strerror (rc)); Modified: trunk/agent/pkdecrypt.c =================================================================== --- trunk/agent/pkdecrypt.c 2009-05-13 17:12:00 UTC (rev 5008) +++ trunk/agent/pkdecrypt.c 2009-05-15 11:16:28 UTC (rev 5009) @@ -66,7 +66,7 @@ } rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip, &shadow_info, - CACHE_MODE_NORMAL, &s_skey); + CACHE_MODE_NORMAL, NULL, &s_skey); if (rc) { if (gpg_err_code (rc) == GPG_ERR_ENOENT) Modified: trunk/agent/pksign.c =================================================================== --- trunk/agent/pksign.c 2009-05-13 17:12:00 UTC (rev 5008) +++ trunk/agent/pksign.c 2009-05-15 11:16:28 UTC (rev 5009) @@ -125,10 +125,12 @@ /* SIGN whatever information we have accumulated in CTRL and return - the signature S-Expression. */ + the signature S-expression. LOOKUP is an optional function to + provide a way for lower layers to ask for the caching TTL. */ int agent_pksign_do (ctrl_t ctrl, const char *desc_text, - gcry_sexp_t *signature_sexp, cache_mode_t cache_mode) + gcry_sexp_t *signature_sexp, + cache_mode_t cache_mode, lookup_ttl_t lookup_ttl) { gcry_sexp_t s_skey = NULL, s_sig = NULL; unsigned char *shadow_info = NULL; @@ -138,7 +140,8 @@ return gpg_error (GPG_ERR_NO_SECKEY); rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip, - &shadow_info, cache_mode, &s_skey); + &shadow_info, cache_mode, lookup_ttl, + &s_skey); if (rc) { log_error ("failed to read the secret key\n"); @@ -238,7 +241,7 @@ size_t len = 0; int rc = 0; - rc = agent_pksign_do (ctrl, desc_text, &s_sig, cache_mode); + rc = agent_pksign_do (ctrl, desc_text, &s_sig, cache_mode, NULL); if (rc) goto leave; From cvs at cvs.gnupg.org Fri May 15 14:11:47 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 15 May 2009 14:11:47 +0200 Subject: [svn] GnuPG - r5010 - trunk/g10 Message-ID: Author: marcus Date: 2009-05-15 14:11:46 +0200 (Fri, 15 May 2009) New Revision: 5010 Modified: trunk/g10/ChangeLog trunk/g10/gpg.c Log: 2009-05-15 Marcus Brinkmann * gpg.c (gpgconf_list): Remove dead entry "allow-pka-lookup" (a verify option for a couple of years now). Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-15 11:16:28 UTC (rev 5009) +++ trunk/g10/ChangeLog 2009-05-15 12:11:46 UTC (rev 5010) @@ -1,3 +1,8 @@ +2009-05-15 Marcus Brinkmann + + * gpg.c (gpgconf_list): Remove dead entry "allow-pka-lookup" (a + verify option for a couple of years now). + 2009-05-13 Werner Koch * keygen.c (parse_expire_string): Base ISO date string at noon. Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2009-05-15 11:16:28 UTC (rev 5009) +++ trunk/g10/gpg.c 2009-05-15 12:11:46 UTC (rev 5010) @@ -1572,7 +1572,6 @@ printf ("default-key:%lu:\n", GC_OPT_FLAG_NONE); printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE); printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE); - printf ("allow-pka-lookup:%lu:\n", GC_OPT_FLAG_NONE); printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE); printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT); printf ("group:%lu:\n", GC_OPT_FLAG_NONE); From cvs at cvs.gnupg.org Fri May 15 21:26:47 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 15 May 2009 21:26:47 +0200 Subject: [svn] GnuPG - r5011 - in trunk: doc g10 scd Message-ID: Author: wk Date: 2009-05-15 21:26:46 +0200 (Fri, 15 May 2009) New Revision: 5011 Modified: trunk/doc/gpg-agent.texi trunk/g10/ChangeLog trunk/g10/call-agent.c trunk/g10/call-agent.h trunk/g10/card-util.c trunk/g10/keydb.h trunk/g10/keygen.c trunk/g10/passphrase.c trunk/scd/app-openpgp.c Log: Made card key generate with backup key work for 2048 bit. Improved card key generation prompts. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-15 12:11:46 UTC (rev 5010) +++ trunk/g10/ChangeLog 2009-05-15 19:26:46 UTC (rev 5011) @@ -1,3 +1,11 @@ +2009-05-15 Werner Koch + + * keygen.c (gen_card_key_with_backup): Get the size of the key + from the card. + * call-agent.h (struct agent_card_info_s): Add field KEY_ATTR. + * call-agent.c (learn_status_cb): Support KEY-ATTR. + * card-util.c (card_status): Print key attributes. + 2009-05-15 Marcus Brinkmann * gpg.c (gpgconf_list): Remove dead entry "allow-pka-lookup" (a @@ -3,4 +11,17 @@ verify option for a couple of years now). +2009-05-14 Werner Koch + + * call-agent.c (agent_get_passphrase): Add arg CHECK. + * passphrase.c (passphrase_get): Pass new arg. + + * keygen.c (gen_card_key_with_backup): Print a status error. + (do_generate_keypair): Ditto. + (do_ask_passphrase): Add arg MODE. + (generate_raw_key): Call with mode 1. + * passphrase.c (ask_passphrase): Remove becuase it is not used. + (passphrase_to_dek): Factor code out to ... + (passphrase_to_dek_ext): .. New. Add args CUSTDESC and CUSTPROMPT. + 2009-05-13 Werner Koch Modified: trunk/doc/gpg-agent.texi =================================================================== --- trunk/doc/gpg-agent.texi 2009-05-15 12:11:46 UTC (rev 5010) +++ trunk/doc/gpg-agent.texi 2009-05-15 19:26:46 UTC (rev 5011) @@ -579,8 +579,10 @@ empty lines are ignored. An entry starts with optional whitespace, followed by the keygrip of the key given as 40 hex digits, optionally followed by the caching TTL in seconds and another optional field for -arbitrary flags. The keygrip may be prefixed with a @code{!} to -disable this entry. +arbitrary flags. A non-zero TTL overrides the global default as +set by @option{--default-cache-ttl-ssh}. + +The keygrip may be prefixed with a @code{!} to disable an entry entry. The following example lists exactly one key. Note that keys available through a OpenPGP smartcard in the active smartcard reader are @@ -1054,7 +1056,7 @@ clients to use the agent with minimum effort. @example - GET_PASSPHRASE [--data] [--check] [--no-ask] @var{cache_id} [@var{error_message} @var{prompt} @var{description}] + GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]] [--qualitybar] @var{cache_id} [@var{error_message} @var{prompt} @var{description}] @end example @var{cache_id} is expected to be a string used to identify a cached @@ -1089,6 +1091,9 @@ cache the user will not be asked to enter a passphrase but the error code @code{GPG_ERR_NO_DATA} is returned. +If the option @option{--qualitybar} is used and a minimum passphrase +length has been configured, a visual indication of the entered +passphrase quality is shown. @example CLEAR_PASSPHRASE @var{cache_id} Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2009-05-15 12:11:46 UTC (rev 5010) +++ trunk/g10/call-agent.c 2009-05-15 19:26:46 UTC (rev 5011) @@ -325,7 +325,19 @@ else if (no == 3) parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3); } - + else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen)) + { + int keyno, algo, nbits; + + sscanf (line, "%d %d %d", &keyno, &algo, &nbits); + keyno--; + if (keyno >= 0 && keyno < DIM (parm->key_attr)) + { + parm->key_attr[keyno].algo = algo; + parm->key_attr[keyno].nbits = nbits; + } + } + return 0; } @@ -343,6 +355,9 @@ rc = assuan_transact (agent_ctx, "LEARN --send", dummy_data_cb, NULL, default_inq_cb, NULL, learn_status_cb, info); + /* Also try to get the key attributes. */ + if (!rc) + agent_scd_getattr ("KEY-ATTR", info); return rc; } @@ -535,7 +550,6 @@ int keywordlen; gpg_error_t rc; - log_debug ("got status line `%s'\n", line); for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) ; while (spacep (line)) @@ -827,6 +841,7 @@ const char *prompt, const char *desc_msg, int repeat, + int check, char **r_passphrase) { int rc; @@ -863,8 +878,9 @@ goto no_mem; snprintf (line, DIM(line)-1, - "GET_PASSPHRASE --data --repeat=%d -- %s %s %s %s", + "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s", repeat, + check? " --check --qualitybar":"", arg1? arg1:"X", arg2? arg2:"X", arg3? arg3:"X", Modified: trunk/g10/call-agent.h =================================================================== --- trunk/g10/call-agent.h 2009-05-15 12:11:46 UTC (rev 5010) +++ trunk/g10/call-agent.h 2009-05-15 19:26:46 UTC (rev 5011) @@ -53,6 +53,10 @@ int is_v2; /* True if this is a v2 card. */ int chvmaxlen[3]; /* Maximum allowed length of a CHV. */ int chvretry[3]; /* Allowed retries for the CHV; 0 = blocked. */ + struct { /* Array with key attributes. */ + int algo; /* Algorithm identifier. */ + unsigned int nbits; /* Supported keysize. */ + } key_attr[3]; }; struct agent_card_genkey_s { @@ -116,6 +120,7 @@ const char *prompt, const char *desc_msg, int repeat, + int check, char **r_passphrase); /* Send the CLEAR_PASSPHRASE command to the agent. */ Modified: trunk/g10/card-util.c =================================================================== --- trunk/g10/card-util.c 2009-05-15 12:11:46 UTC (rev 5010) +++ trunk/g10/card-util.c 2009-05-15 19:26:46 UTC (rev 5011) @@ -443,6 +443,10 @@ fputs (":\n", fp); fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached); + for (i=0; i < DIM (info.key_attr); i++) + if (info.key_attr[0].algo) + fprintf (fp, "keyattr:%d:%d:%u:\n", i+1, + info.key_attr[i].algo, info.key_attr[i].nbits); fprintf (fp, "maxpinlen:%d:%d:%d:\n", info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]); fprintf (fp, "pinretry:%d:%d:%d:\n", @@ -518,6 +522,16 @@ } tty_fprintf (fp, "Signature PIN ....: %s\n", info.chv1_cached? _("not forced"): _("forced")); + if (info.key_attr[0].algo) + { + tty_fprintf (fp, "Key attributes ...:"); + for (i=0; i < DIM (info.key_attr); i++) + tty_fprintf (fp, " %u%c", + info.key_attr[i].nbits, + info.key_attr[i].algo == 1? 'R': + info.key_attr[i].algo == 17? 'D': '?'); + tty_fprintf (fp, "\n"); + } tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n", info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]); tty_fprintf (fp, "PIN retry counter : %d %d %d\n", @@ -1077,7 +1091,7 @@ *forced_chv1 = !info->chv1_cached; if (*forced_chv1) - { /* Switch of the forced mode so that during key generation we + { /* Switch off the forced mode so that during key generation we don't get bothered with PIN queries for each self-signature. */ rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno); Modified: trunk/g10/keydb.h =================================================================== --- trunk/g10/keydb.h 2009-05-15 12:11:46 UTC (rev 5010) +++ trunk/g10/keydb.h 2009-05-15 19:26:46 UTC (rev 5011) @@ -202,11 +202,11 @@ void set_passphrase_from_string(const char *pass); void read_passphrase_from_fd( int fd ); void passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo ); -char *ask_passphrase (const char *description, - const char *tryagain_text, - const char *promptid, - const char *prompt, - const char *cacheid, int *canceled); +DEK *passphrase_to_dek_ext(u32 *keyid, int pubkey_algo, + int cipher_algo, STRING2KEY *s2k, int mode, + const char *tryagain_text, + const char *custdesc, const char *custprompt, + int *canceled); DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo, int cipher_algo, STRING2KEY *s2k, int mode, const char *tryagain_text, int *canceled); Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2009-05-15 12:11:46 UTC (rev 5010) +++ trunk/g10/keygen.c 2009-05-15 19:26:46 UTC (rev 5011) @@ -2153,21 +2153,28 @@ } +/* MODE 0 - standard + 1 - Ask for passphrase of the card backup key. */ static DEK * -do_ask_passphrase ( STRING2KEY **ret_s2k, int *r_canceled ) +do_ask_passphrase (STRING2KEY **ret_s2k, int mode, int *r_canceled) { DEK *dek = NULL; STRING2KEY *s2k; const char *errtext = NULL; + const char *custdesc = NULL; tty_printf(_("You need a Passphrase to protect your secret key.\n\n") ); + if (mode == 1) + custdesc = _("Please enter a passphrase to protect the off-card " + "backup of the new encryption key."); + s2k = xmalloc_secure( sizeof *s2k ); for(;;) { s2k->mode = opt.s2k_mode; s2k->hash_algo = S2K_DIGEST_ALGO; - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k,2, - errtext, r_canceled); + dek = passphrase_to_dek_ext (NULL, 0, opt.s2k_cipher_algo, s2k, 2, + errtext, custdesc, NULL, r_canceled); if (!dek && *r_canceled) { xfree(dek); dek = NULL; xfree(s2k); s2k = NULL; @@ -2587,7 +2594,7 @@ STRING2KEY *s2k; DEK *dek; - dek = do_ask_passphrase ( &s2k, &canceled ); + dek = do_ask_passphrase (&s2k, 0, &canceled); if (dek) { r = xmalloc_clear( sizeof *r ); @@ -3085,7 +3092,7 @@ para = r; canceled = 0; - dek = card_serialno? NULL : do_ask_passphrase ( &s2k, &canceled ); + dek = card_serialno? NULL : do_ask_passphrase (&s2k, 0, &canceled); if( dek ) { r = xmalloc_clear( sizeof *r ); @@ -3143,7 +3150,7 @@ log_info(_("keysize rounded up to %u bits\n"), nbits ); } - dek = do_ask_passphrase (&s2k, &canceled); + dek = do_ask_passphrase (&s2k, 1, &canceled); if (canceled) { rc = gpg_error (GPG_ERR_CANCELED); @@ -3547,6 +3554,7 @@ log_error ("key generation failed: %s\n", g10_errstr(rc) ); else tty_printf (_("Key generation failed: %s\n"), g10_errstr(rc) ); + write_status_error (card? "card_key_generate":"key_generate", rc); print_status_key_not_created ( get_parameter_value (para, pHANDLE) ); } else @@ -3660,7 +3668,7 @@ canceled = 0; if (ask_pass) - dek = do_ask_passphrase (&s2k, &canceled); + dek = do_ask_passphrase (&s2k, 0, &canceled); else if (passphrase) { s2k = xmalloc_secure ( sizeof *s2k ); @@ -3951,19 +3959,35 @@ PKT_public_key *pk; size_t n; int i; + unsigned int nbits; + + /* Get the size of the key directly from the card. */ + { + struct agent_card_info_s info; + + memset (&info, 0, sizeof info); + if (!agent_scd_getattr ("KEY-ATTR", &info) + && info.key_attr[1].algo) + nbits = info.key_attr[1].nbits; + else + nbits = 1024; /* All pre-v2.0 cards. */ + agent_release_card_info (&info); + } - rc = generate_raw_key (algo, 1024, timestamp, + /* Create a key of this size in memory. */ + rc = generate_raw_key (algo, nbits, timestamp, &sk_unprotected, &sk_protected); if (rc) return rc; - /* First, store the key to the card. */ + /* Store the key to the card. */ rc = save_unprotected_key_to_card (sk_unprotected, keyno); if (rc) { log_error (_("storing key onto card failed: %s\n"), g10_errstr (rc)); free_secret_key (sk_unprotected); free_secret_key (sk_protected); + write_status_error ("save_key_to_card", rc); return rc; } Modified: trunk/g10/passphrase.c =================================================================== --- trunk/g10/passphrase.c 2009-05-15 12:11:46 UTC (rev 5010) +++ trunk/g10/passphrase.c 2009-05-15 19:26:46 UTC (rev 5011) @@ -236,7 +236,8 @@ /* * Ask the GPG Agent for the passphrase. * Mode 0: Allow cached passphrase - * 1: No cached passphrase FIXME: Not really implemented + * 1: No cached passphrase; that is we are asking for a new passphrase + * FIXME: Only partially implemented * * Note that TRYAGAIN_TEXT must not be translated. If CANCELED is not * NULL, the function does set it to 1 if the user canceled the @@ -260,6 +261,7 @@ char *my_prompt; char hexfprbuf[20*2+1]; const char *my_cacheid; + int check = (mode == 1); if (canceled) *canceled = 0; @@ -347,7 +349,7 @@ my_prompt = custom_prompt ? native_to_utf8 (custom_prompt): NULL; rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext, - repeat, &pw); + repeat, check, &pw); xfree (my_prompt); xfree (atext); atext = NULL; @@ -432,54 +434,6 @@ } -/**************** - * Ask for a passphrase and return that string. - */ -char * -ask_passphrase (const char *description, - const char *tryagain_text, - const char *promptid, - const char *prompt, - const char *cacheid, int *canceled) -{ - char *pw = NULL; - - (void)promptid; - - if (canceled) - *canceled = 0; - - if (!opt.batch && description) - { - if (strchr (description, '%')) - { - char *tmp = percent_plus_unescape (description, 0xff); - if (!tmp) - log_fatal(_("out of core\n")); - tty_printf ("\n%s\n", tmp); - xfree (tmp); - } - else - tty_printf ("\n%s\n",description); - } - - if (have_static_passphrase ()) - { - pw = xmalloc_secure (strlen(fd_passwd)+1); - strcpy (pw, fd_passwd); - } - else - pw = passphrase_get (NULL, 0, cacheid, 0, - tryagain_text, description, prompt, - canceled ); - - if (!pw || !*pw) - write_status( STATUS_MISSING_PASSPHRASE ); - - return pw; -} - - /* Return a new DEK object Using the string-to-key sepcifier S2K. Use KEYID and PUBKEY_ALGO to prompt the user. Returns NULL is the user selected to cancel the passphrase entry and if CANCELED is not @@ -490,9 +444,11 @@ 2: Ditto, but change the text to "repeat entry" */ DEK * -passphrase_to_dek (u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, - const char *tryagain_text, int *canceled) +passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, + int cipher_algo, STRING2KEY *s2k, int mode, + const char *tryagain_text, + const char *custdesc, const char *custprompt, + int *canceled) { char *pw = NULL; DEK *dek; @@ -612,7 +568,7 @@ /* Divert to the gpg-agent. */ pw = passphrase_get ( keyid, mode == 2, NULL, mode == 2? opt.passwd_repeat: 0, - tryagain_text, NULL, NULL, canceled ); + tryagain_text, custdesc, custprompt, canceled); if (*canceled) { xfree (pw); @@ -637,3 +593,14 @@ last_pw = pw; return dek; } + + +DEK * +passphrase_to_dek (u32 *keyid, int pubkey_algo, + int cipher_algo, STRING2KEY *s2k, int mode, + const char *tryagain_text, int *canceled) +{ + return passphrase_to_dek_ext (keyid, pubkey_algo, cipher_algo, + s2k, mode, tryagain_text, NULL, NULL, + canceled); +} Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2009-05-15 12:11:46 UTC (rev 5010) +++ trunk/scd/app-openpgp.c 2009-05-15 19:26:46 UTC (rev 5011) @@ -2368,6 +2368,9 @@ maxbits = app->app_local->keyattr[keyno].n_bits; nbits = rsa_n? count_bits (rsa_n, rsa_n_len) : 0; + if (opt.verbose) + log_info ("RSA modulus size is %u bits (%u bytes)\n", + nbits, (unsigned int)rsa_n_len); if (nbits != maxbits) { log_error (_("RSA modulus missing or not of size %d bits\n"), From cvs at cvs.gnupg.org Sun May 17 15:08:19 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Sun, 17 May 2009 15:08:19 +0200 Subject: [svn] GnuPG - r5012 - trunk/g10 Message-ID: Author: wk Date: 2009-05-17 15:08:18 +0200 (Sun, 17 May 2009) New Revision: 5012 Modified: trunk/g10/ChangeLog trunk/g10/keygen.c Log: Changed default algo and size. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-15 19:26:46 UTC (rev 5011) +++ trunk/g10/ChangeLog 2009-05-17 13:08:18 UTC (rev 5012) @@ -1,3 +1,12 @@ +2009-05-17 Werner Koch + + * keygen.c (ask_algo): Add arg R_SUBKEY_ALGO. Change return value + semantics. Change presented order of algorithms. Make RSA+RSA + the default. + (generate_keypair): Adjust for change. + (ask_keysize): Add arg PRIMARY_KEYSIZE for subkey creation. + Change callers. + 2009-05-15 Werner Koch * keygen.c (gen_card_key_with_backup): Get the size of the key Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2009-05-15 19:26:46 UTC (rev 5011) +++ trunk/g10/keygen.c 2009-05-17 13:08:18 UTC (rev 5012) @@ -1636,94 +1636,141 @@ } -/**************** - * Returns: 0 to create both a DSA and a Elgamal key. - * and only if key flags are to be written the desired usage. - */ +/* Ask for an algorithm. The function returns the algorithm id to + * create. If ADDMODE is false the function won't show an option to + * create the primary and subkey combined and won't set R_USAGE + * either. If a combined algorithm has been selected, the subkey + * algorithm is stored at R_SUBKEY_ALGO. */ static int -ask_algo (int addmode, unsigned int *r_usage) +ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) { - char *answer; - int algo; + char *answer; + int algo; + int dummy_algo; - *r_usage = 0; - tty_printf(_("Please select what kind of key you want:\n")); - if( !addmode ) - tty_printf(_(" (%d) DSA and Elgamal (default)\n"), 1 ); - tty_printf( _(" (%d) DSA (sign only)\n"), 2 ); - if (opt.expert) - tty_printf( _(" (%d) DSA (set your own capabilities)\n"), 3 ); - if( addmode ) - tty_printf(_(" (%d) Elgamal (encrypt only)\n"), 4 ); - tty_printf( _(" (%d) RSA (sign only)\n"), 5 ); - if (addmode) - tty_printf(_(" (%d) RSA (encrypt only)\n"), 6 ); - if (opt.expert) - tty_printf( _(" (%d) RSA (set your own capabilities)\n"), 7 ); + if (!r_subkey_algo) + r_subkey_algo = &dummy_algo; + + tty_printf (_("Please select what kind of key you want:\n")); - for(;;) { - answer = cpr_get("keygen.algo",_("Your selection? ")); - cpr_kill_prompt(); - algo = *answer? atoi(answer): 1; - xfree(answer); - if( algo == 1 && !addmode ) { - algo = 0; /* create both keys */ - break; + if (!addmode) + tty_printf (_(" (%d) RSA and RSA (default)\n"), 1 ); + if (!addmode) + tty_printf (_(" (%d) DSA and Elgamal\n"), 2 ); + + tty_printf (_(" (%d) DSA (sign only)\n"), 3 ); + tty_printf (_(" (%d) RSA (sign only)\n"), 4 ); + + if (addmode) + { + tty_printf (_(" (%d) Elgamal (encrypt only)\n"), 5 ); + tty_printf (_(" (%d) RSA (encrypt only)\n"), 6 ); + } + if (opt.expert) + { + tty_printf (_(" (%d) DSA (set your own capabilities)\n"), 7 ); + tty_printf (_(" (%d) RSA (set your own capabilities)\n"), 8 ); + } + + for(;;) + { + *r_usage = 0; + *r_subkey_algo = 0; + answer = cpr_get ("keygen.algo", _("Your selection? ")); + cpr_kill_prompt (); + algo = *answer? atoi (answer) : 1; + xfree(answer); + if (algo == 1 && !addmode) + { + algo = PUBKEY_ALGO_RSA; + *r_subkey_algo = PUBKEY_ALGO_RSA; + break; } - else if( algo == 7 && opt.expert ) { - algo = PUBKEY_ALGO_RSA; - *r_usage=ask_key_flags(algo,addmode); - break; + else if (algo == 2 && !addmode) + { + algo = PUBKEY_ALGO_DSA; + *r_subkey_algo = PUBKEY_ALGO_ELGAMAL_E; + break; } - else if( algo == 6 && addmode ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_ENC; - break; + else if (algo == 3) + { + algo = PUBKEY_ALGO_DSA; + *r_usage = PUBKEY_USAGE_SIG; + break; } - else if( algo == 5 ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_SIG; - break; + else if (algo == 4) + { + algo = PUBKEY_ALGO_RSA; + *r_usage = PUBKEY_USAGE_SIG; + break; } - else if( algo == 4 && addmode ) { - algo = PUBKEY_ALGO_ELGAMAL_E; - *r_usage = PUBKEY_USAGE_ENC; - break; + else if (algo == 5 && addmode) + { + algo = PUBKEY_ALGO_ELGAMAL_E; + *r_usage = PUBKEY_USAGE_ENC; + break; } - else if( algo == 3 && opt.expert ) { - algo = PUBKEY_ALGO_DSA; - *r_usage=ask_key_flags(algo,addmode); - break; + else if (algo == 6 && addmode) + { + algo = PUBKEY_ALGO_RSA; + *r_usage = PUBKEY_USAGE_ENC; + break; } - else if( algo == 2 ) { - algo = PUBKEY_ALGO_DSA; - *r_usage = PUBKEY_USAGE_SIG; - break; + else if (algo == 7 && opt.expert) + { + algo = PUBKEY_ALGO_DSA; + *r_usage = ask_key_flags (algo, addmode); + break; } - else - tty_printf(_("Invalid selection.\n")); + else if (algo == 8 && opt.expert) + { + algo = PUBKEY_ALGO_RSA; + *r_usage = ask_key_flags (algo, addmode); + break; + } + else + tty_printf (_("Invalid selection.\n")); } - - return algo; + + return algo; } +/* Ask for the key size. ALGO is the algorithjm. If PRIMARY_KEYSIZE + is not 0, the function asks for the size of the encryption + subkey. */ static unsigned -ask_keysize( int algo ) +ask_keysize (int algo, unsigned int primary_keysize) { unsigned int nbits, min, def=2048, max=4096; + int for_subkey = !!primary_keysize; + int autocomp = 0; if(opt.expert) min=512; else min=1024; + if (primary_keysize && !opt.expert) + { + /* Deduce the subkey size from the primary key size. */ + if (algo == PUBKEY_ALGO_DSA && primary_keysize > 3072) + nbits = 3072; /* For performance reasons we don't support more + than 3072 bit DSA. However we won't see this + case anyway because DSA can't be used as an + encryption subkey ;-). */ + else + nbits = primary_keysize; + autocomp = 1; + goto leave; + } + switch(algo) { case PUBKEY_ALGO_DSA: if(opt.flags.dsa2) { - def=1024; + def=2048; max=3072; } else @@ -1743,18 +1790,16 @@ for(;;) { - char *prompt,*answer; + char *prompt, *answer; -#define PROMPTSTRING _("What keysize do you want? (%u) ") - - prompt=xmalloc(strlen(PROMPTSTRING)+20); - sprintf(prompt,PROMPTSTRING,def); - -#undef PROMPTSTRING - - answer = cpr_get("keygen.size",prompt); - cpr_kill_prompt(); - nbits = *answer? atoi(answer): def; + if (for_subkey) + prompt = xasprintf (_("What keysize do you want " + "for the subkey? (%u) "), def); + else + prompt = xasprintf (_("What keysize do you want? (%u) "), def); + answer = cpr_get ("keygen.size", prompt); + cpr_kill_prompt (); + nbits = *answer? atoi (answer): def; xfree(prompt); xfree(answer); @@ -1767,15 +1812,18 @@ tty_printf(_("Requested keysize is %u bits\n"), nbits ); + leave: if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) { nbits = ((nbits + 63) / 64) * 64; - tty_printf(_("rounded up to %u bits\n"), nbits ); + if (!autocomp) + tty_printf(_("rounded up to %u bits\n"), nbits ); } else if( (nbits % 32) ) { nbits = ((nbits + 31) / 32) * 32; - tty_printf(_("rounded up to %u bits\n"), nbits ); + if (!autocomp) + tty_printf(_("rounded up to %u bits\n"), nbits ); } return nbits; @@ -3003,16 +3051,19 @@ } else { - algo = ask_algo( 0, &use ); - if( !algo ) - { /* default: DSA with ElG subkey of the specified size */ + int subkey_algo; + + algo = ask_algo (0, &subkey_algo, &use); + if (subkey_algo) + { + /* Create primary and subkey at once. */ both = 1; r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYTYPE; - sprintf( r->u.value, "%d", PUBKEY_ALGO_DSA ); + sprintf( r->u.value, "%d", algo ); r->next = para; para = r; - nbits = ask_keysize( PUBKEY_ALGO_DSA ); + nbits = ask_keysize (algo, 0); r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYLENGTH; sprintf( r->u.value, "%u", nbits); @@ -3024,10 +3075,9 @@ r->next = para; para = r; - algo = PUBKEY_ALGO_ELGAMAL_E; r = xmalloc_clear( sizeof *r + 20 ); r->key = pSUBKEYTYPE; - sprintf( r->u.value, "%d", algo ); + sprintf( r->u.value, "%d", subkey_algo); r->next = para; para = r; r = xmalloc_clear( sizeof *r + 20 ); @@ -3055,10 +3105,10 @@ r->next = para; para = r; } - + nbits = 0; } - nbits = ask_keysize( algo ); + nbits = ask_keysize (algo, nbits); r = xmalloc_clear( sizeof *r + 20 ); r->key = both? pSUBKEYLENGTH : pKEYLENGTH; sprintf( r->u.value, "%u", nbits); @@ -3658,9 +3708,9 @@ if (rc) goto leave; - algo = ask_algo (1, &use); + algo = ask_algo (1, NULL, &use); assert (algo); - nbits = ask_keysize (algo); + nbits = ask_keysize (algo, 0); expire = ask_expire_interval (0, NULL); if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay", _("Really create? (y/N) "))) @@ -4017,8 +4067,8 @@ mode_t oldmask; keyid_from_sk (sk, NULL); - sprintf (name_buffer,"sk_%08lX%08lX.gpg", - (ulong)sk->keyid[0], (ulong)sk->keyid[1]); + snprintf (name_buffer, sizeof name_buffer, "sk_%08lX%08lX.gpg", + (ulong)sk->keyid[0], (ulong)sk->keyid[1]); fname = make_filename (backup_dir, name_buffer, NULL); oldmask = umask (077); From cvs at cvs.gnupg.org Mon May 18 19:38:34 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 18 May 2009 19:38:34 +0200 Subject: [svn] gpgme - r1368 - in trunk: . doc src Message-ID: Author: marcus Date: 2009-05-18 19:38:31 +0200 (Mon, 18 May 2009) New Revision: 1368 Modified: trunk/NEWS trunk/doc/ChangeLog trunk/doc/gpgme.texi trunk/src/ChangeLog trunk/src/engine-gpg.c trunk/src/engine-gpgsm.c trunk/src/gpgme.h.in Log: doc/ 2009-05-18 Marcus Brinkmann * gpgme.texi (Encrypting a Plaintext): Document GPGME_ENCRYPT_NO_ENCRYPT_TO. src/ 2009-05-18 Marcus Brinkmann * gpgme.h.in (gpgme_encrypt_flags_t): Add GPGME_ENCRYPT_NO_ENCRYPT_TO. * engine-gpg.c (gpg_encrypt): Pass --no-encrypt-to to gpg if GPGME_ENCRYPT_NO_ENCRYPT_TO flag is set. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-05-14 07:40:51 UTC (rev 1367) +++ trunk/doc/ChangeLog 2009-05-18 17:38:31 UTC (rev 1368) @@ -1,3 +1,8 @@ +2009-05-18 Marcus Brinkmann + + * gpgme.texi (Encrypting a Plaintext): Document + GPGME_ENCRYPT_NO_ENCRYPT_TO. + 2009-05-05 Marcus Brinkmann * gpgme.texi (Engine Information): Replace path by file_name. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-05-14 07:40:51 UTC (rev 1367) +++ trunk/src/ChangeLog 2009-05-18 17:38:31 UTC (rev 1368) @@ -1,3 +1,10 @@ +2009-05-18 Marcus Brinkmann + + * gpgme.h.in (gpgme_encrypt_flags_t): Add + GPGME_ENCRYPT_NO_ENCRYPT_TO. + * engine-gpg.c (gpg_encrypt): Pass --no-encrypt-to to gpg if + GPGME_ENCRYPT_NO_ENCRYPT_TO flag is set. + 2009-05-14 Werner Koch * gpgme.h.in (gpgme_status_code_t): Explicitly initialize for Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-05-14 07:40:51 UTC (rev 1367) +++ trunk/NEWS 2009-05-18 17:38:31 UTC (rev 1368) @@ -1,6 +1,9 @@ Noteworthy changes in version 1.1.9 ------------------------------------------------ + * New encryption flag GPGME_ENCRYPT_NO_ENCRYPT_TO to disable default + recipients. + * Interface changes relative to the 1.1.7 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GPGME_KEYLIST_MODE_EPHEMERAL NEW. @@ -12,6 +15,7 @@ gpgme_op_assuan_transact NEW. gpgme_op_assuan_result NEW. gpgme_subkey_t EXTENDED: New fields is_cardkey, card_number. + GPGME_ENCRYPT_NO_ENCRYPT_TO NEW. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Modified: trunk/doc/gpgme.texi =================================================================== --- trunk/doc/gpgme.texi 2009-05-14 07:40:51 UTC (rev 1367) +++ trunk/doc/gpgme.texi 2009-05-18 17:38:31 UTC (rev 1368) @@ -4723,6 +4723,12 @@ recipients in @var{recp} should be trusted, even if the keys do not have a high enough validity in the keyring. This flag should be used with care; in general it is not a good idea to use any untrusted keys. + + at item GPGME_ENCRYPT_NO_ENCRYPT_TO +The @code{GPGME_ENCRYPT_NO_ENCRYPT_TO} symbol specifies that no +default or hidden default recipients as configured in the crypto +backend should be included. This can be useful for managing different +user profiles. @end table If @code{GPG_ERR_UNUSABLE_PUBKEY} is returned, some recipients in Modified: trunk/src/engine-gpg.c =================================================================== --- trunk/src/engine-gpg.c 2009-05-14 07:40:51 UTC (rev 1367) +++ trunk/src/engine-gpg.c 2009-05-18 17:38:31 UTC (rev 1368) @@ -1611,9 +1611,12 @@ { /* If we know that all recipients are valid (full or ultimate trust) we can suppress further checks. */ - if (!err && !symmetric && (flags & GPGME_ENCRYPT_ALWAYS_TRUST)) + if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST)) err = add_arg (gpg, "--always-trust"); + if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO)) + err = add_arg (gpg, "--no-encrypt-to"); + if (!err) err = append_args_from_recipients (gpg, recp); } Modified: trunk/src/engine-gpgsm.c =================================================================== --- trunk/src/engine-gpgsm.c 2009-05-14 07:40:51 UTC (rev 1367) +++ trunk/src/engine-gpgsm.c 2009-05-18 17:38:31 UTC (rev 1368) @@ -1349,6 +1349,14 @@ if (!recp) return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + if (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO) + { + err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, + "OPTION no-encrypt-to", NULL, NULL); + if (err) + return err; + } + gpgsm->input_cb.data = plain; err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data)); if (err) Modified: trunk/src/gpgme.h.in =================================================================== --- trunk/src/gpgme.h.in 2009-05-14 07:40:51 UTC (rev 1367) +++ trunk/src/gpgme.h.in 2009-05-18 17:38:31 UTC (rev 1368) @@ -1168,7 +1168,8 @@ /* The valid encryption flags. */ typedef enum { - GPGME_ENCRYPT_ALWAYS_TRUST = 1 + GPGME_ENCRYPT_ALWAYS_TRUST = 1, + GPGME_ENCRYPT_NO_ENCRYPT_TO = 2 } gpgme_encrypt_flags_t; From cvs at cvs.gnupg.org Mon May 18 19:38:37 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 18 May 2009 19:38:37 +0200 Subject: [svn] GnuPG - r5013 - in trunk: . g10 po sm Message-ID: Author: wk Date: 2009-05-18 19:38:34 +0200 (Mon, 18 May 2009) New Revision: 5013 Modified: trunk/AUTHORS trunk/Makefile.am trunk/TODO trunk/configure.ac trunk/g10/ChangeLog trunk/g10/encode.c trunk/g10/mainproc.c trunk/g10/passphrase.c trunk/po/POTFILES.in trunk/sm/ChangeLog trunk/sm/gpgsm.c trunk/sm/server.c Log: New gpgsm server option no-encrypt-to. Add caching for symkey encryption. Minor cleanups. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/g10/ChangeLog 2009-05-18 17:38:34 UTC (rev 5013) @@ -1,3 +1,15 @@ +2009-05-18 Daiki Ueno (wk) + + * encode.c (encode_simple): Tell passphrase_to_dek to cache + the passphrase. + (setup_symkey): Ditto. + * mainproc.c (proc_symkey_enc): Tell passphrase_to_dek to cache + the passphrase. + (proc_encrypted): Ditto. + * passphrase.c (hash_passphrase): Remove arg CREATE. + (passphrase_to_dek): New mode 3 and 4 for caching passphrase for + symmetric encryption. + 2009-05-17 Werner Koch * keygen.c (ask_algo): Add arg R_SUBKEY_ALGO. Change return value Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/sm/ChangeLog 2009-05-18 17:38:34 UTC (rev 5013) @@ -1,3 +1,10 @@ +2009-05-18 Werner Koch + + * server.c (option_handler): New option "no-encrypt-to". + (cmd_encrypt): Make use of it. + + * gpgsm.c: Remove not implemented --verify-files. + 2009-04-02 Werner Koch * keylist.c (list_cert_std): Print card serial number. Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/AUTHORS 2009-05-18 17:38:34 UTC (rev 5013) @@ -20,6 +20,7 @@ Daniel Nylander Translations [sv] Daiki Ueno Assigns Past and Future Changes. + (changed:passphrase.c and related code) David Shaw Assigns past and future changes. (all in keyserver/, Modified: trunk/Makefile.am =================================================================== --- trunk/Makefile.am 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/Makefile.am 2009-05-18 17:38:34 UTC (rev 5013) @@ -54,6 +54,11 @@ else scd = endif +#if BUILD_G13 +#g13 = g13 +#else +#g13 = +#endif if BUILD_TOOLS tools = tools else @@ -72,7 +77,7 @@ endif SUBDIRS = m4 gl include jnlib common ${kbx} \ - ${gpg} ${keyserver} ${sm} ${agent} ${scd} ${tools} po ${doc} ${tests} + ${gpg} ${keyserver} ${sm} ${agent} ${scd} ${g13} ${tools} po ${doc} ${tests} dist_doc_DATA = README Modified: trunk/TODO =================================================================== --- trunk/TODO 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/TODO 2009-05-18 17:38:34 UTC (rev 5013) @@ -20,7 +20,6 @@ ** replace leading zero in integer hack by a cleaner solution * sm/gpgsm.c -** mark all unimplemented commands and options. ** Implement --default-key ** support the anyPolicy semantic ** Should we prefer nonRepudiation certs over plain signing certs? Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/configure.ac 2009-05-18 17:38:34 UTC (rev 5013) @@ -1453,6 +1453,7 @@ sm/Makefile agent/Makefile scd/Makefile +g13/Makefile keyserver/Makefile keyserver/gpg2keys_mailto keyserver/gpg2keys_test Modified: trunk/g10/encode.c =================================================================== --- trunk/g10/encode.c 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/g10/encode.c 2009-05-18 17:38:34 UTC (rev 5013) @@ -216,7 +216,7 @@ s2k->mode = RFC1991? 0:opt.s2k_mode; s2k->hash_algo=S2K_DIGEST_ALGO; cfx.dek = passphrase_to_dek( NULL, 0, - default_cipher_algo(), s2k, 2, + default_cipher_algo(), s2k, 4, NULL, &canceled); if( !cfx.dek || !cfx.dek->keylen ) { rc = gpg_error (canceled? GPG_ERR_CANCELED:GPG_ERR_INV_PASSPHRASE); @@ -397,7 +397,7 @@ (*symkey_s2k)->hash_algo = S2K_DIGEST_ALGO; *symkey_dek=passphrase_to_dek(NULL,0,opt.s2k_cipher_algo, - *symkey_s2k,2,NULL, &canceled); + *symkey_s2k, 4, NULL, &canceled); if(!*symkey_dek || !(*symkey_dek)->keylen) { xfree(*symkey_dek); Modified: trunk/g10/mainproc.c =================================================================== --- trunk/g10/mainproc.c 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/g10/mainproc.c 2009-05-18 17:38:34 UTC (rev 5013) @@ -311,7 +311,7 @@ } else { - c->dek = passphrase_to_dek (NULL, 0, algo, &enc->s2k, 0, + c->dek = passphrase_to_dek (NULL, 0, algo, &enc->s2k, 3, NULL, NULL); if(c->dek) { @@ -548,7 +548,7 @@ log_info (_("assuming %s encrypted data\n"), "IDEA"); } - c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 0, NULL, NULL ); + c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 3, NULL, NULL ); if (c->dek) c->dek->algo_info_printed = 1; } Modified: trunk/g10/passphrase.c =================================================================== --- trunk/g10/passphrase.c 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/g10/passphrase.c 2009-05-18 17:38:34 UTC (rev 5013) @@ -50,11 +50,10 @@ static char *last_pw = NULL; -/* Hash a passphrase using the supplied s2k. If create is true, create - a new salt or what else must be filled into the s2k for a new key. - always needs: dek->algo, s2k->mode, s2k->hash_algo. */ +/* Hash a passphrase using the supplied s2k. + Always needs: dek->algo, s2k->mode, s2k->hash_algo. */ static void -hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k, int create ) +hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k) { gcry_md_hd_t md; int pass, i; @@ -82,13 +81,6 @@ int len2 = pwlen + 8; ulong count = len2; - if ( create && !pass ) - { - gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM); - if ( s2k->mode == 3 ) - s2k->count = opt.s2k_count; - } - if ( s2k->mode == 3 ) { count = S2K_DECODE_COUNT(s2k->count); @@ -441,7 +433,9 @@ MODE 0: Allow cached passphrase 1: Ignore cached passphrase - 2: Ditto, but change the text to "repeat entry" + 2: Ditto, but create a new key + 3: Allow cached passphrase; use the S2K salt as the cache ID + 4: Ditto, but create a new key */ DEK * passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, @@ -461,6 +455,7 @@ if ( !s2k ) { + assert (mode != 3 && mode != 4); /* This is used for the old rfc1991 mode * Note: This must match the code in encode.c with opt.rfc1991 set */ s2k = &help_s2k; @@ -468,6 +463,15 @@ s2k->hash_algo = S2K_DIGEST_ALGO; } + /* Create a new salt or what else to be filled into the s2k for a + new key. */ + if ((mode == 2 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3)) + { + gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM); + if ( s2k->mode == 3 ) + s2k->count = opt.s2k_count; + } + /* If we do not have a passphrase available in NEXT_PW and status information are request, we print them now. */ if ( !next_pw && is_status_enabled() ) @@ -565,10 +569,21 @@ } else { + char *cacheid = NULL; + char buf[1+16+1]; + + if ((mode == 3 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3)) + { + memset (buf, 0, sizeof buf); + *buf = 'S'; + bin2hex (s2k->salt, 8, buf + 1); + cacheid = buf; + } + /* Divert to the gpg-agent. */ - pw = passphrase_get ( keyid, mode == 2, NULL, - mode == 2? opt.passwd_repeat: 0, - tryagain_text, custdesc, custprompt, canceled); + pw = passphrase_get (keyid, mode == 2, cacheid, + (mode == 2 || mode == 4)? opt.passwd_repeat : 0, + tryagain_text, custdesc, custprompt, canceled); if (*canceled) { xfree (pw); @@ -585,10 +600,10 @@ get_last_passphrase(). */ dek = xmalloc_secure_clear ( sizeof *dek ); dek->algo = cipher_algo; - if ( !*pw && mode == 2 ) + if ( !*pw && (mode == 2 || mode == 4)) dek->keylen = 0; else - hash_passphrase( dek, pw, s2k, mode==2 ); + hash_passphrase (dek, pw, s2k); xfree(last_pw); last_pw = pw; return dek; Modified: trunk/po/POTFILES.in =================================================================== --- trunk/po/POTFILES.in 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/po/POTFILES.in 2009-05-18 17:38:34 UTC (rev 5013) @@ -19,6 +19,7 @@ common/asshelp.c common/audit.c common/helpfile.c +common/gettime.c g10/armor.c g10/build-packet.c Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/sm/gpgsm.c 2009-05-18 17:38:34 UTC (rev 5013) @@ -66,7 +66,6 @@ aDeleteKey, aImport, aVerify, - aVerifyFiles, aListExternalKeys, aListChain, aSendKeys, @@ -191,7 +190,6 @@ ARGPARSE_c (aSym, "symmetric", N_("encryption only with symmetric cipher")), ARGPARSE_c (aDecrypt, "decrypt", N_("decrypt data (default)")), ARGPARSE_c (aVerify, "verify", N_("verify a signature")), - ARGPARSE_c (aVerifyFiles, "verify-files", "@"), ARGPARSE_c (aListKeys, "list-keys", N_("list keys")), ARGPARSE_c (aListExternalKeys, "list-external-keys", N_("list external keys")), @@ -1711,10 +1709,6 @@ } break; - case aVerifyFiles: - log_error (_("this command has not yet been implemented\n")); - break; - case aDecrypt: { FILE *fp = open_fwrite (opt.outfile?opt.outfile:"-"); Modified: trunk/sm/server.c =================================================================== --- trunk/sm/server.c 2009-05-17 13:08:18 UTC (rev 5012) +++ trunk/sm/server.c 2009-05-18 17:38:34 UTC (rev 5013) @@ -51,6 +51,7 @@ certlist_t default_recplist; /* As set by main() - don't release. */ int allow_pinentry_notify; /* Set if pinentry notifications should be passed back to the client. */ + int no_encrypt_to; /* Local version of option. */ }; @@ -301,6 +302,10 @@ int i = *value? atoi (value) : 0; ctrl->with_ephemeral_keys = i; } + else if (!strcmp (key, "no-encrypt-to")) + { + ctrl->server_local->no_encrypt_to = 1; + } else return gpg_error (GPG_ERR_UNKNOWN_OPTION); @@ -486,7 +491,7 @@ /* Now add all encrypt-to marked recipients from the default list. */ rc = 0; - if (!opt.no_encrypt_to) + if (!opt.no_encrypt_to && !ctrl->server_local->no_encrypt_to) { for (cl=ctrl->server_local->default_recplist; !rc && cl; cl = cl->next) if (cl->is_encrypt_to) From cvs at cvs.gnupg.org Tue May 19 11:26:17 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 19 May 2009 11:26:17 +0200 Subject: [svn] GnuPG - r5014 - in trunk: . jnlib Message-ID: Author: wk Date: 2009-05-19 11:26:17 +0200 (Tue, 19 May 2009) New Revision: 5014 Modified: trunk/Makefile.am trunk/configure.ac trunk/jnlib/logging.c Log: Remove testing cruft. Typo fixes. Modified: trunk/Makefile.am =================================================================== --- trunk/Makefile.am 2009-05-18 17:38:34 UTC (rev 5013) +++ trunk/Makefile.am 2009-05-19 09:26:17 UTC (rev 5014) @@ -54,11 +54,6 @@ else scd = endif -#if BUILD_G13 -#g13 = g13 -#else -#g13 = -#endif if BUILD_TOOLS tools = tools else @@ -77,7 +72,7 @@ endif SUBDIRS = m4 gl include jnlib common ${kbx} \ - ${gpg} ${keyserver} ${sm} ${agent} ${scd} ${g13} ${tools} po ${doc} ${tests} + ${gpg} ${keyserver} ${sm} ${agent} ${scd} ${tools} po ${doc} ${tests} dist_doc_DATA = README Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-05-18 17:38:34 UTC (rev 5013) +++ trunk/configure.ac 2009-05-19 09:26:17 UTC (rev 5014) @@ -1453,7 +1453,6 @@ sm/Makefile agent/Makefile scd/Makefile -g13/Makefile keyserver/Makefile keyserver/gpg2keys_mailto keyserver/gpg2keys_test Modified: trunk/jnlib/logging.c =================================================================== --- trunk/jnlib/logging.c 2009-05-18 17:38:34 UTC (rev 5013) +++ trunk/jnlib/logging.c 2009-05-19 09:26:17 UTC (rev 5014) @@ -171,9 +171,9 @@ if (!running_detached) { /* Due to all the problems with apps not running - detahced but beeing caled with stderr closed or + detached but being called with stderr closed or used for a different purposes, it does not make - sense to switch to stderr. We tehrefore disable it. */ + sense to switch to stderr. We therefore disable it. */ if (!cookie->quiet) { /* fputs ("switching logging to stderr\n", stderr);*/ From cvs at cvs.gnupg.org Wed May 20 00:39:45 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 20 May 2009 00:39:45 +0200 Subject: [svn] GnuPG - r5015 - in trunk: . agent common jnlib scd tools Message-ID: Author: wk Date: 2009-05-20 00:39:45 +0200 (Wed, 20 May 2009) New Revision: 5015 Modified: trunk/NEWS trunk/agent/ChangeLog trunk/agent/gpg-agent.c trunk/common/ChangeLog trunk/common/simple-pwquery.c trunk/common/sysutils.h trunk/jnlib/ChangeLog trunk/jnlib/logging.c trunk/jnlib/mischelp.h trunk/scd/ChangeLog trunk/scd/scdaemon.c trunk/tools/ChangeLog trunk/tools/sockprox.c trunk/tools/watchgnupg.c Log: Fix possible system freeze on Mac OS X. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/agent/ChangeLog 2009-05-19 22:39:45 UTC (rev 5015) @@ -1,3 +1,8 @@ +2009-05-19 Werner Koch + + * gpg-agent.c (JNLIB_NEED_AFLOCAL): Define. + (create_server_socket): Use SUN_LEN macro. + 2009-05-15 Werner Koch Fix bug #1053. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/common/ChangeLog 2009-05-19 22:39:45 UTC (rev 5015) @@ -1,3 +1,8 @@ +2009-05-19 Werner Koch + + * simple-pwquery.c (agent_open): Use SUN_LEN + (JNLIB_NEED_AFLOCAL): Define and include mischelp.h. + 2009-05-07 Werner Koch * sexputil.c (get_rsa_pk_from_canon_sexp): New. Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/jnlib/ChangeLog 2009-05-19 22:39:45 UTC (rev 5015) @@ -1,3 +1,8 @@ +2009-05-19 Werner Koch + + * mischelp.h: Define PF_LOCAL, AF_LOCAL and SUN_LEN if requested. + * logging.c (fun_writer): Use SUN_LEN to fix a Mac OS X freeze. + 2009-03-25 Werner Koch * logging.c (fun_closer): Never close fd 2. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/scd/ChangeLog 2009-05-19 22:39:45 UTC (rev 5015) @@ -1,3 +1,8 @@ +2009-05-19 Werner Koch + + * scdaemon.c (create_server_socket): Use SUN_LEN. + (JNLIB_NEED_AFLOCAL): Define. + 2009-05-13 Werner Koch * ccid-driver.c (abort_cmd): Add arg SEQNO and change callers. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/tools/ChangeLog 2009-05-19 22:39:45 UTC (rev 5015) @@ -1,3 +1,8 @@ +2009-05-19 Werner Koch + + * watchgnupg.c: Include jnlib/mischelp.h if required. + (main): Use SUN_LEN. + 2009-04-17 Werner Koch * ccidmon.c: New. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/NEWS 2009-05-19 22:39:45 UTC (rev 5015) @@ -24,8 +24,9 @@ * The gpg-protect-tool now uses gpg-agent via libassuan. Under Windows the Pinentry will now be put into the foreground. - + * Changed code to avoid a possible Mac OS X system freeze. + Noteworthy changes in version 2.0.11 (2009-03-03) ------------------------------------------------- Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/agent/gpg-agent.c 2009-05-19 22:39:45 UTC (rev 5015) @@ -39,6 +39,7 @@ #include #define JNLIB_NEED_LOG_LOGV +#define JNLIB_NEED_AFLOCAL #include "agent.h" #include /* Malloc hooks and socket wrappers. */ @@ -1457,9 +1458,7 @@ agent_exit (2); } strcpy (serv_addr->sun_path, name); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen (serv_addr->sun_path) + 1); - + len = SUN_LEN (serv_addr); rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len); if (use_standard_socket && rc == -1 && errno == EADDRINUSE) { Modified: trunk/common/simple-pwquery.c =================================================================== --- trunk/common/simple-pwquery.c 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/common/simple-pwquery.c 2009-05-19 22:39:45 UTC (rev 5015) @@ -39,6 +39,9 @@ #ifdef HAVE_LOCALE_H #include #endif + +#define JNLIB_NEED_AFLOCAL +#include "../jnlib/mischelp.h" #ifdef HAVE_W32_SYSTEM #include "../jnlib/w32-afunix.h" #endif @@ -379,8 +382,7 @@ memset (&client_addr, 0, sizeof client_addr); client_addr.sun_family = AF_UNIX; strcpy (client_addr.sun_path, infostr); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen(client_addr.sun_path) + 1); + len = SUN_LEN (&client_addr); #ifdef HAVE_W32_SYSTEM rc = _w32_sock_connect (fd, (struct sockaddr*)&client_addr, len ); Modified: trunk/common/sysutils.h =================================================================== --- trunk/common/sysutils.h 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/common/sysutils.h 2009-05-19 22:39:45 UTC (rev 5015) @@ -56,7 +56,4 @@ #endif /*HAVE_W32_SYSTEM*/ - - - #endif /*GNUPG_COMMON_SYSUTILS_H*/ Modified: trunk/jnlib/logging.c =================================================================== --- trunk/jnlib/logging.c 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/jnlib/logging.c 2009-05-19 22:39:45 UTC (rev 5015) @@ -39,6 +39,7 @@ #define JNLIB_NEED_LOG_LOGV 1 +#define JNLIB_NEED_AFLOCAL 1 #include "libjnlib-config.h" #include "logging.h" @@ -152,8 +153,7 @@ addr.sun_family = PF_LOCAL; strncpy (addr.sun_path, cookie->name, sizeof (addr.sun_path)-1); addr.sun_path[sizeof (addr.sun_path)-1] = 0; - addrlen = (offsetof (struct sockaddr_un, sun_path) - + strlen (addr.sun_path) + 1); + addrlen = SUN_LEN (&addr); if (connect (cookie->fd, (struct sockaddr *) &addr, addrlen) == -1) { Modified: trunk/jnlib/mischelp.h =================================================================== --- trunk/jnlib/mischelp.h 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/jnlib/mischelp.h 2009-05-19 22:39:45 UTC (rev 5015) @@ -1,6 +1,6 @@ /* mischelp.h - Miscellaneous helper macros and functions * Copyright (C) 1999, 2000, 2001, 2002, 2003, - * 2006, 2007 Free Software Foundation, Inc. + * 2006, 2007, 2009 Free Software Foundation, Inc. * * This file is part of JNLIB. * @@ -60,5 +60,35 @@ #define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) +/* Include hacks which are mainly required for Slowaris. */ +#if defined(JNLIB_NEED_AFLOCAL) && !defined(HAVE_W32_SYSTEM) +#include +#include +#ifndef PF_LOCAL +# ifdef PF_UNIX +# define PF_LOCAL PF_UNIX +# else +# define PF_LOCAL AF_UNIX +# endif +#endif /*PF_LOCAL*/ +#ifndef AF_LOCAL +# define AF_LOCAL AF_UNIX +#endif /*AF_UNIX*/ + +/* We used to avoid this macro in GnuPG and inlined the AF_LOCAL name + length computation directly with the little twist of adding 1 extra + byte. It seems that this was needed once on an old HP/UX box and + there are also rumours that 4.3 Reno and DEC systems need it. This + one-off buglet did not harm any current system until it came to Mac + OS X where the kernel (as of May 2009) exhibited a strange bug: The + systems basically froze in the connect call if the passed name + contained an invalid directory part. Ignore the old Unices. */ +#ifndef SUN_LEN +# define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \ + + strlen ((ptr)->sun_path)) +#endif /*SUN_LEN*/ +#endif /*JNLIB_NEED_AFLOCAL && !HAVE_W32_SYSTEM*/ + + #endif /*LIBJNLIB_MISCHELP_H*/ Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/scd/scdaemon.c 2009-05-19 22:39:45 UTC (rev 5015) @@ -38,6 +38,7 @@ #include #define JNLIB_NEED_LOG_LOGV +#define JNLIB_NEED_AFLOCAL #include "scdaemon.h" #include #include @@ -1032,8 +1033,7 @@ serv_addr->sun_family = AF_UNIX; assert (strlen (name) + 1 < sizeof (serv_addr->sun_path)); strcpy (serv_addr->sun_path, name); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen (serv_addr->sun_path) + 1); + len = SUN_LEN (serv_addr); rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len); if (is_standard_name && rc == -1 && errno == EADDRINUSE) Modified: trunk/tools/sockprox.c =================================================================== --- trunk/tools/sockprox.c 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/tools/sockprox.c 2009-05-19 22:39:45 UTC (rev 5015) @@ -86,7 +86,6 @@ name.sun_family = AF_LOCAL; strncpy (name.sun_path, filename, sizeof (name.sun_path)); name.sun_path[sizeof (name.sun_path) - 1] = '\0'; - size = SUN_LEN (&name); remove (filename); Modified: trunk/tools/watchgnupg.c =================================================================== --- trunk/tools/watchgnupg.c 2009-05-19 09:26:17 UTC (rev 5014) +++ trunk/tools/watchgnupg.c 2009-05-19 22:39:45 UTC (rev 5015) @@ -35,7 +35,7 @@ #define PGM "watchgnupg" -/* Allow for a standalone build. */ +/* Allow for a standalone build on most systems. */ #ifdef VERSION #define MYVERSION_LINE PGM " (GnuPG) " VERSION #define BUGREPORT_LINE "\nReport bugs to .\n" @@ -43,16 +43,9 @@ #define MYVERSION_LINE PGM #define BUGREPORT_LINE "" #endif - -#ifndef PF_LOCAL -# ifdef PF_UNIX -# define PF_LOCAL PF_UNIX -# else -# define PF_LOCAL AF_UNIX -# endif -# ifndef AF_LOCAL -# define AF_LOCAL AF_UNIX -# endif +#if !defined(SUN_LEN) || !defined(PF_LOCAL) || !defined(AF_LOCAL) +#define JNLIB_NEED_AFLOCAL +#include "../jnlib/mischelp.h" #endif @@ -285,8 +278,7 @@ srvr_addr.sun_family = AF_LOCAL; strncpy (srvr_addr.sun_path, *argv, sizeof (srvr_addr.sun_path) - 1); srvr_addr.sun_path[sizeof (srvr_addr.sun_path) - 1] = 0; - addrlen = (offsetof (struct sockaddr_un, sun_path) - + strlen (srvr_addr.sun_path) + 1); + addrlen = SUN_LEN (&srvr_addr); again: From cvs at cvs.gnupg.org Wed May 20 11:08:49 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 20 May 2009 11:08:49 +0200 Subject: [svn] GnuPG - r5016 - trunk/g10 Message-ID: Author: wk Date: 2009-05-20 11:08:48 +0200 (Wed, 20 May 2009) New Revision: 5016 Modified: trunk/g10/ChangeLog trunk/g10/keygen.c Log: Fix bug#1056. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-19 22:39:45 UTC (rev 5015) +++ trunk/g10/ChangeLog 2009-05-20 09:08:48 UTC (rev 5016) @@ -1,3 +1,8 @@ +2009-05-20 Werner Koch + + * keygen.c (ask_key_flags): Fix bug in the translation check. + Fixes bug#1056. + 2009-05-18 Daiki Ueno (wk) * encode.c (encode_simple): Tell passphrase_to_dek to cache Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2009-05-19 22:39:45 UTC (rev 5015) +++ trunk/g10/keygen.c 2009-05-20 09:08:48 UTC (rev 5016) @@ -1555,7 +1555,7 @@ unsigned int current=0; unsigned int possible=openpgp_pk_algo_usage(algo); - if ( strlen(togglers) != 7 ) + if ( strlen(togglers) != 8 ) { tty_printf ("NOTE: Bad translation at %s:%d. " "Please report.\n", __FILE__, __LINE__); From cvs at cvs.gnupg.org Wed May 20 11:57:10 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 20 May 2009 11:57:10 +0200 Subject: [svn] GnuPG - r5017 - in trunk: doc g10 Message-ID: Author: wk Date: 2009-05-20 11:57:10 +0200 (Wed, 20 May 2009) New Revision: 5017 Modified: trunk/doc/ChangeLog trunk/doc/gpg.texi trunk/g10/ChangeLog trunk/g10/keygen.c Log: Allow generation of DSA2 keys without --enable-dsa2. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-05-20 09:08:48 UTC (rev 5016) +++ trunk/doc/ChangeLog 2009-05-20 09:57:10 UTC (rev 5017) @@ -1,3 +1,8 @@ +2009-05-20 Werner Koch + + * gpg.texi (GPG Configuration Options): Explain new meaning of + --enable-dsa2. + 2009-03-16 David Shaw * gpg.texi (GPG Configuration Options): Document keyserver-options Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-20 09:08:48 UTC (rev 5016) +++ trunk/g10/ChangeLog 2009-05-20 09:57:10 UTC (rev 5017) @@ -1,8 +1,12 @@ 2009-05-20 Werner Koch + * keygen.c (ask_keysize): Allow selection of DSA key size even + without --enable-dsa2. + (gen_dsa): Remove size check. + * keygen.c (ask_key_flags): Fix bug in the translation check. Fixes bug#1056. - + 2009-05-18 Daiki Ueno (wk) * encode.c (encode_simple): Tell passphrase_to_dek to cache Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2009-05-20 09:08:48 UTC (rev 5016) +++ trunk/doc/gpg.texi 2009-05-20 09:57:10 UTC (rev 5017) @@ -1093,10 +1093,10 @@ @item --enable-dsa2 @itemx --disable-dsa2 -Enables new-style DSA keys which (unlike the old style) may be larger -than 1024 bit and use hashes other than SHA-1 and RIPEMD/160. Note -that very few programs currently support these keys and signatures -from them. +Enable hash truncation for all DSA keys even for old DSA Keys up to +1024 bit. This is also the default with @option{--openpgp}. Note +that older versions of GnuPG also required this flag to allow the +generation of DSA larger than 1024 bit. @item --photo-viewer @code{string} This is the command line that should be run to view a photo ID. "%i" Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2009-05-20 09:08:48 UTC (rev 5016) +++ trunk/g10/keygen.c 2009-05-20 09:57:10 UTC (rev 5017) @@ -1263,7 +1263,7 @@ gcry_sexp_t misc_key_info; unsigned int qbits; - if ( nbits < 512 || (!opt.flags.dsa2 && nbits > 1024)) + if ( nbits < 512) { nbits = 1024; log_info(_("keysize invalid; using %u bits\n"), nbits ); @@ -1768,16 +1768,8 @@ switch(algo) { case PUBKEY_ALGO_DSA: - if(opt.flags.dsa2) - { - def=2048; - max=3072; - } - else - { - tty_printf(_("DSA keypair will have %u bits.\n"),1024); - return 1024; - } + def=2048; + max=3072; break; case PUBKEY_ALGO_RSA: From cvs at cvs.gnupg.org Wed May 20 12:23:34 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 20 May 2009 12:23:34 +0200 Subject: [svn] GnuPG - r5018 - trunk/g10 Message-ID: Author: wk Date: 2009-05-20 12:23:33 +0200 (Wed, 20 May 2009) New Revision: 5018 Modified: trunk/g10/ChangeLog trunk/g10/gpg.c Log: Fixed bug#1044. Use of --fingerprint with --with-fingerprint. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-20 09:57:10 UTC (rev 5017) +++ trunk/g10/ChangeLog 2009-05-20 10:23:33 UTC (rev 5018) @@ -1,5 +1,8 @@ 2009-05-20 Werner Koch + * gpg.c (main): Fix --fingerprint/--with-fingerprint command + detection. Fixes bug#1044. + * keygen.c (ask_keysize): Allow selection of DSA key size even without --enable-dsa2. (gen_dsa): Remove size check. Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2009-05-20 09:57:10 UTC (rev 5017) +++ trunk/g10/gpg.c 2009-05-20 10:23:33 UTC (rev 5018) @@ -1892,7 +1892,7 @@ int eyes_only=0; int multifile=0; int pwfd = -1; - int with_fpr = 0; /* make an option out of --fingerprint */ + int fpr_maybe_cmd = 0; /* --fingerprint maybe a command. */ int any_explicit_recipient = 0; int require_secmem=0,got_secmem=0; @@ -2241,8 +2241,13 @@ case oWithFingerprint: opt.with_fingerprint = 1; - with_fpr=1; /*fall thru*/ - case oFingerprint: opt.fingerprint++; break; + opt.fingerprint++; + break; + case oFingerprint: + opt.fingerprint++; + fpr_maybe_cmd = 1; + break; + case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break; @@ -3299,9 +3304,12 @@ xfree(p); } - if( !cmd && opt.fingerprint && !with_fpr ) { - set_cmd( &cmd, aListKeys); - } + /* If there is no command but the --fingerprint is given, default + to the --list-keys command. */ + if (!cmd && fpr_maybe_cmd) + { + set_cmd (&cmd, aListKeys); + } if( opt.verbose > 1 ) From cvs at cvs.gnupg.org Wed May 20 12:25:59 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 20 May 2009 12:25:59 +0200 Subject: [svn] GnuPG - r5019 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2009-05-20 12:25:58 +0200 (Wed, 20 May 2009) New Revision: 5019 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/gpg.c Log: Fix bug#1044. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-20 10:23:33 UTC (rev 5018) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-20 10:25:58 UTC (rev 5019) @@ -1,3 +1,8 @@ +2009-05-20 Werner Koch + + * gpg.c (main): Fix --fingerprint/--with-fingerprint command + detection. Fixes bug#1044. + 2009-05-11 Werner Koch * apdu.c (send_le): Replace log_error by log_info. Fixes bug#1043. Modified: branches/STABLE-BRANCH-1-4/g10/gpg.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/gpg.c 2009-05-20 10:23:33 UTC (rev 5018) +++ branches/STABLE-BRANCH-1-4/g10/gpg.c 2009-05-20 10:25:58 UTC (rev 5019) @@ -1859,7 +1859,7 @@ int eyes_only=0; int multifile=0; int pwfd = -1; - int with_fpr = 0; /* make an option out of --fingerprint */ + int fpr_maybe_cmd = 0; /* --fingerprint maybe a command. */ int any_explicit_recipient = 0; int require_secmem=0,got_secmem=0; #ifdef USE_SHM_COPROCESSING @@ -2228,8 +2228,13 @@ case oWithFingerprint: opt.with_fingerprint = 1; - with_fpr=1; /*fall thru*/ - case oFingerprint: opt.fingerprint++; break; + opt.fingerprint++; + break; + case oFingerprint: + opt.fingerprint++; + fpr_maybe_cmd = 1; + break; + case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break; @@ -3268,9 +3273,12 @@ xfree(p); } - if( !cmd && opt.fingerprint && !with_fpr ) { - set_cmd( &cmd, aListKeys); - } + /* If there is no command but the --fingerprint is given, default + to the --list-keys command. */ + if (!cmd && fpr_maybe_cmd) + { + set_cmd (&cmd, aListKeys); + } if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */ if( cmd == aKModeC ) { From cvs at cvs.gnupg.org Wed May 20 18:12:25 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 20 May 2009 18:12:25 +0200 Subject: [svn] GnuPG - r5020 - trunk/scd Message-ID: Author: wk Date: 2009-05-20 18:12:25 +0200 (Wed, 20 May 2009) New Revision: 5020 Modified: trunk/scd/ChangeLog trunk/scd/apdu.c trunk/scd/app-openpgp.c Log: Make PIN changing code work for v2 cards. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-05-20 10:25:58 UTC (rev 5019) +++ trunk/scd/ChangeLog 2009-05-20 16:12:25 UTC (rev 5020) @@ -1,3 +1,10 @@ +2009-05-20 Werner Koch + + * app-openpgp.c (verify_chv2): Add case for v2 cards. + (verify_chv3): Factor some code out to .. + (build_enter_admin_pin_prompt): .. new. + (do_change_pin): Properly handle v2 cards. + 2009-05-19 Werner Koch * scdaemon.c (create_server_socket): Use SUN_LEN. Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2009-05-20 10:25:58 UTC (rev 5019) +++ trunk/scd/apdu.c 2009-05-20 16:12:25 UTC (rev 5020) @@ -1869,7 +1869,7 @@ return err; if (DBG_CARD_IO) - log_printhex (" APDU_data:", apdu, apdulen); + log_printhex (" raw apdu:", apdu, apdulen); maxbuflen = *buflen; if (pininfo) @@ -2847,7 +2847,7 @@ return SW_HOST_NO_DRIVER; if (DBG_CARD_IO) - log_debug ("send apdu: c=%02X i=%02X p0=%02X p1=%02X lc=%d le=%d em=%d\n", + log_debug ("send apdu: c=%02X i=%02X p1=%02X p2=%02X lc=%d le=%d em=%d\n", class, ins, p0, p1, lc, le, extended_mode); if (lc != -1 && (lc > 255 || lc < 0)) @@ -3036,7 +3036,7 @@ log_debug (" response: sw=%04X datalen=%d\n", sw, (unsigned int)resultlen); if ( !retbuf && (sw == SW_SUCCESS || (sw & 0xff00) == SW_MORE_DATA)) - log_printhex (" dump: ", result, resultlen); + log_printhex (" dump: ", result, resultlen); } if (sw == SW_SUCCESS || sw == SW_EOF_REACHED) Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2009-05-20 10:25:58 UTC (rev 5019) +++ trunk/scd/app-openpgp.c 2009-05-20 16:12:25 UTC (rev 5020) @@ -1420,7 +1420,7 @@ for the pinentry. CHVNO must be either 1 or 2. SIGCOUNT is only used with CHV1. PINVALUE is the address of a pointer which will receive a newly allocated block with the actual PIN (this is useful - in case that PIN shall be used for another verifiy operation). The + in case that PIN shall be used for another verify operation). The caller needs to free this value. If the function returns with success and NULL is stored at PINVALUE, the caller should take this as an indication that the keypad has been used. @@ -1553,30 +1553,42 @@ char *pinvalue; if (app->did_chv2) - return 0; /* We already verified CHV2. */ + return 0; /* We already verified CHV2 (PW1 for v2 cards). */ - rc = verify_a_chv (app, pincb, pincb_arg, 2, 0, &pinvalue); - if (rc) - return rc; - - app->did_chv2 = 1; - - if (!app->did_chv1 && !app->force_chv1 && pinvalue) + if (app->app_local->extcap.is_v2) { - /* For convenience we verify CHV1 here too. We do this only if - the card is not configured to require a verification before - each CHV1 controlled operation (force_chv1) and if we are not - using the keypad (PINVALUE == NULL). */ - rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); - if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) - rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); + /* Version two cards don't have a CHV2 anymore. We need to + verify CHV1 (now called PW1) instead. */ + rc = verify_a_chv (app, pincb, pincb_arg, 1, 0, &pinvalue); if (rc) + return rc; + app->did_chv2 = 1; + } + else + { + /* Version 1 cards only. */ + rc = verify_a_chv (app, pincb, pincb_arg, 2, 0, &pinvalue); + if (rc) + return rc; + app->did_chv2 = 1; + + if (!app->did_chv1 && !app->force_chv1 && pinvalue) { - log_error (_("verify CHV%d failed: %s\n"), 1, gpg_strerror (rc)); - flush_cache_after_error (app); + /* For convenience we verify CHV1 here too. We do this only + if the card is not configured to require a verification + before each CHV1 controlled operation (force_chv1) and if + we are not using the keypad (PINVALUE == NULL). */ + rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); + if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) + rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); + if (rc) + { + log_error (_("verify CHV%d failed: %s\n"), 1, gpg_strerror (rc)); + flush_cache_after_error (app); + } + else + app->did_chv1 = 1; } - else - app->did_chv1 = 1; } xfree (pinvalue); @@ -1584,6 +1596,56 @@ } +/* Build the prompt to enter the Admin PIN. The prompt depends on the + current sdtate of the card. */ +static gpg_error_t +build_enter_admin_pin_prompt (app_t app, char **r_prompt) +{ + void *relptr; + unsigned char *value; + size_t valuelen; + int remaining; + char *prompt; + + *r_prompt = NULL; + + relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL); + if (!relptr || valuelen < 7) + { + log_error (_("error retrieving CHV status from card\n")); + xfree (relptr); + return gpg_error (GPG_ERR_CARD); + } + if (value[6] == 0) + { + log_info (_("card is permanently locked!\n")); + xfree (relptr); + return gpg_error (GPG_ERR_BAD_PIN); + } + remaining = value[6]; + xfree (relptr); + + log_info(_("%d Admin PIN attempts remaining before card" + " is permanently locked\n"), remaining); + + if (remaining < 3) + { + /* TRANSLATORS: Do not translate the "|A|" prefix but keep it at + the start of the string. Use %%0A to force a linefeed. */ + prompt = xtryasprintf (_("|A|Please enter the Admin PIN%%0A" + "[remaining attempts: %d]"), remaining); + } + else + prompt = xtrystrdup (_("|A|Please enter the Admin PIN")); + + if (!prompt) + return gpg_error_from_syserror (); + + *r_prompt = prompt; + return 0; +} + + /* Verify CHV3 if required. */ static gpg_error_t verify_chv3 (app_t app, @@ -1602,65 +1664,25 @@ if (!app->did_chv3) { - void *relptr; - unsigned char *value; - size_t valuelen; iso7816_pininfo_t pininfo; int minlen = 8; - int remaining; - char *prompt_buffer = NULL; - const char *prompt; + char *prompt; memset (&pininfo, 0, sizeof pininfo); pininfo.mode = 1; pininfo.minlen = minlen; - relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL); - if (!relptr || valuelen < 7) - { - log_error (_("error retrieving CHV status from card\n")); - xfree (relptr); - return gpg_error (GPG_ERR_CARD); - } - if (value[6] == 0) - { - log_info (_("card is permanently locked!\n")); - xfree (relptr); - return gpg_error (GPG_ERR_BAD_PIN); - } - remaining = value[6]; - xfree (relptr); + rc = build_enter_admin_pin_prompt (app, &prompt); + if (rc) + return rc; - log_info(_("%d Admin PIN attempts remaining before card" - " is permanently locked\n"), remaining); - - if (remaining < 3) - { - /* TRANSLATORS: Do not translate the "|A|" prefix but keep - it at the start of the string. Use %%0A to force a - lienfeed. */ -#define PROMPTSTRING _("|A|Please enter the Admin PIN%%0A" \ - "[remaining attempts: %d]") - size_t promptsize = strlen (PROMPTSTRING) + 50; - - prompt_buffer = xtrymalloc (promptsize); - if (!prompt_buffer) - return gpg_error_from_syserror (); - snprintf (prompt_buffer, promptsize-1, PROMPTSTRING, remaining); - prompt = prompt_buffer; -#undef PROMPTSTRING - } - else - prompt = _("|A|Please enter the Admin PIN"); - if (!opt.disable_keypad && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) ) { /* The reader supports the verify command through the keypad. */ rc = pincb (pincb_arg, prompt, NULL); + xfree (prompt); prompt = NULL; - xfree (prompt_buffer); - prompt_buffer = NULL; if (rc) { log_info (_("PIN callback returned error: %s\n"), @@ -1676,9 +1698,8 @@ char *pinvalue; rc = pincb (pincb_arg, prompt, &pinvalue); + xfree (prompt); prompt = NULL; - xfree (prompt_buffer); - prompt_buffer = NULL; if (rc) { log_info (_("PIN callback returned error: %s\n"), @@ -1821,7 +1842,21 @@ -/* Handle the PASSWD command. */ +/* Handle the PASSWD command. The following combinations are + possible: + + Flags CHVNO Vers. Description + RESET 1 1 Verify CHV3 and set a new CHV1 and CHV2 + RESET 1 2 Verify PW3 and set a new PW1. + RESET 2 1 Verify CHV3 and set a new CHV1 and CHV2. + RESET 2 2 Verify PW3 and set a new Reset Code. + RESET 3 any Returns GPG_ERR_INV_ID. + - 1 1 Verify CHV2 and set a new CHV1 and CHV2. + - 1 2 Verify PW1 and set a new PW1. + - 2 1 Verify CHV2 and set a new CHV1 and CHV2. + - 2 2 Verify Reset Code and set a new PW1. + - 3 any Verify CHV3/PW3 and set a new CHV3/PW3. + */ static gpg_error_t do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, unsigned int flags, @@ -1831,6 +1866,7 @@ int rc = 0; int chvno = atoi (chvnostr); char *resetcode = NULL; + char *oldpinvalue = NULL; char *pinvalue; int reset_mode = !!(flags & APP_CHANGE_FLAG_RESET); int set_resetcode = 0; @@ -1842,77 +1878,138 @@ rc = gpg_error (GPG_ERR_INV_ID); goto leave; } - else if (reset_mode || chvno == 3) + + if (!app->app_local->extcap.is_v2) { - /* We always require that the PIN is entered. */ - app->did_chv3 = 0; - rc = verify_chv3 (app, pincb, pincb_arg); - if (rc) - goto leave; - - if (chvno == 2 && app->app_local->extcap.is_v2) - set_resetcode = 1; + /* Version 1 cards. */ + + if (reset_mode || chvno == 3) + { + /* We always require that the PIN is entered. */ + app->did_chv3 = 0; + rc = verify_chv3 (app, pincb, pincb_arg); + if (rc) + goto leave; + } + else if (chvno == 1 || chvno == 2) + { + /* On a v1.x card CHV1 and CVH2 should always have the same + value, thus we enforce it here. */ + int save_force = app->force_chv1; + + app->force_chv1 = 0; + app->did_chv1 = 0; + app->did_chv2 = 0; + rc = verify_chv2 (app, pincb, pincb_arg); + app->force_chv1 = save_force; + if (rc) + goto leave; + } + else + { + rc = gpg_error (GPG_ERR_INV_ID); + goto leave; + } } - else if (chvno == 2 && app->app_local->extcap.is_v2) + else { - /* There is no PW2 for v2 cards. We use this condition to allow - a PW reset using the Reset Code. */ - void *relptr; - unsigned char *value; - size_t valuelen; - int remaining; + /* Version 2 cards. */ - relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL); - if (!relptr || valuelen < 7) + if (reset_mode) { - log_error (_("error retrieving CHV status from card\n")); - xfree (relptr); - rc = gpg_error (GPG_ERR_CARD); - goto leave; + /* To reset a PIN the Admin PIN is required. */ + app->did_chv3 = 0; + rc = verify_chv3 (app, pincb, pincb_arg); + if (rc) + goto leave; + + if (chvno == 2) + set_resetcode = 1; } - remaining = value[5]; - xfree (relptr); - if (!remaining) + else if (chvno == 1 || chvno == 3) { - log_error (_("Reset Code not or not anymore available\n")); - rc = gpg_error (GPG_ERR_BAD_PIN); - goto leave; - } + int minlen = (chvno ==3)? 8 : 6; + char *promptbuf = NULL; + const char *prompt; - rc = pincb (pincb_arg, _("||Please enter the Reset Code for the card"), - &resetcode); - if (rc) + if (chvno == 3) + { + rc = build_enter_admin_pin_prompt (app, &promptbuf); + if (rc) + goto leave; + prompt = promptbuf; + } + else + prompt = _("||Please enter the PIN"); + rc = pincb (pincb_arg, prompt, &oldpinvalue); + xfree (promptbuf); + promptbuf = NULL; + if (rc) + { + log_info (_("PIN callback returned error: %s\n"), + gpg_strerror (rc)); + goto leave; + } + + if (strlen (oldpinvalue) < minlen) + { + log_info (_("PIN for CHV%d is too short;" + " minimum length is %d\n"), chvno, minlen); + rc = gpg_error (GPG_ERR_BAD_PIN); + goto leave; + } + } + else if (chvno == 2) { - log_info (_("PIN callback returned error: %s\n"), gpg_strerror (rc)); - goto leave; + /* There is no PW2 for v2 cards. We use this condition to + allow a PW reset using the Reset Code. */ + void *relptr; + unsigned char *value; + size_t valuelen; + int remaining; + int minlen = 8; + + relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL); + if (!relptr || valuelen < 7) + { + log_error (_("error retrieving CHV status from card\n")); + xfree (relptr); + rc = gpg_error (GPG_ERR_CARD); + goto leave; + } + remaining = value[5]; + xfree (relptr); + if (!remaining) + { + log_error (_("Reset Code not or not anymore available\n")); + rc = gpg_error (GPG_ERR_BAD_PIN); + goto leave; + } + + rc = pincb (pincb_arg, + _("||Please enter the Reset Code for the card"), + &resetcode); + if (rc) + { + log_info (_("PIN callback returned error: %s\n"), + gpg_strerror (rc)); + goto leave; + } + if (strlen (resetcode) < minlen) + { + log_info (_("Reset Code is too short; minimum length is %d\n"), + minlen); + rc = gpg_error (GPG_ERR_BAD_PIN); + goto leave; + } } - if (strlen (resetcode) < 8) + else { - log_error (_("Reset Code is too short; minimum length is %d\n"), 8); - rc = gpg_error (GPG_ERR_BAD_PIN); + rc = gpg_error (GPG_ERR_INV_ID); goto leave; } } - else if (chvno == 1 || chvno == 2) - { - /* CHV1 and CVH2 should always have the same value, thus we - enforce it here. */ - int save_force = app->force_chv1; - app->force_chv1 = 0; - app->did_chv1 = 0; - app->did_chv2 = 0; - rc = verify_chv2 (app, pincb, pincb_arg); - app->force_chv1 = save_force; - if (rc) - goto leave; - } - else - { - rc = gpg_error (GPG_ERR_INV_ID); - goto leave; - } - if (chvno == 3) app->did_chv3 = 0; else @@ -1931,6 +2028,7 @@ goto leave; } + if (resetcode) { char *buffer; @@ -1966,20 +2064,33 @@ rc = iso7816_reset_retry_counter (app->slot, 0x82, pinvalue, strlen (pinvalue)); } - else + else if (!app->app_local->extcap.is_v2) { + /* Version 1 cards. */ if (chvno == 1 || chvno == 2) { rc = iso7816_change_reference_data (app->slot, 0x81, NULL, 0, pinvalue, strlen (pinvalue)); - if (!rc && !app->app_local->extcap.is_v2) + if (!rc) rc = iso7816_change_reference_data (app->slot, 0x82, NULL, 0, pinvalue, strlen (pinvalue)); } - else - rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, NULL, 0, - pinvalue, strlen (pinvalue)); + else /* CHVNO == 3 */ + { + rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, NULL, 0, + pinvalue, strlen (pinvalue)); + } } + else + { + /* Version 2 cards. */ + assert (chvno == 1 || chvno == 3); + + rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, + oldpinvalue, strlen (oldpinvalue), + pinvalue, strlen (pinvalue)); + } + if (pinvalue) { wipememory (pinvalue, strlen (pinvalue)); @@ -1994,6 +2105,11 @@ wipememory (resetcode, strlen (resetcode)); xfree (resetcode); } + if (oldpinvalue) + { + wipememory (oldpinvalue, strlen (oldpinvalue)); + xfree (oldpinvalue); + } return rc; } From cvs at cvs.gnupg.org Fri May 22 17:38:50 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 22 May 2009 17:38:50 +0200 Subject: [svn] GnuPG - r5021 - in branches/STABLE-BRANCH-1-4: g10 include util Message-ID: Author: wk Date: 2009-05-22 17:38:49 +0200 (Fri, 22 May 2009) New Revision: 5021 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/signal.c branches/STABLE-BRANCH-1-4/include/ttyio.h branches/STABLE-BRANCH-1-4/util/ChangeLog branches/STABLE-BRANCH-1-4/util/ttyio.c Log: Fixed bug1058. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-20 16:12:25 UTC (rev 5020) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-22 15:38:49 UTC (rev 5021) @@ -1,3 +1,7 @@ +2009-05-22 Werner Koch + + * signal.c (got_fatal_signal): Call tty_cleanup_after_signal. + 2009-05-20 Werner Koch * gpg.c (main): Fix --fingerprint/--with-fingerprint command Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-05-20 16:12:25 UTC (rev 5020) +++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-05-22 15:38:49 UTC (rev 5021) @@ -1,3 +1,7 @@ +2009-05-22 Werner Koch + + * ttyio.c (tty_cleanup_after_signal): New. + 2009-05-05 Werner Koch * dotlock.c: Merged changes from GnuPG-2. Better detection of Modified: branches/STABLE-BRANCH-1-4/g10/signal.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/signal.c 2009-05-20 16:12:25 UTC (rev 5020) +++ branches/STABLE-BRANCH-1-4/g10/signal.c 2009-05-22 15:38:49 UTC (rev 5021) @@ -88,6 +88,7 @@ rl_free_line_state (); rl_cleanup_after_signal (); #endif + tty_cleanup_after_signal (); /* Better don't translate these messages. */ write(2, "\n", 1 ); Modified: branches/STABLE-BRANCH-1-4/include/ttyio.h =================================================================== --- branches/STABLE-BRANCH-1-4/include/ttyio.h 2009-05-20 16:12:25 UTC (rev 5020) +++ branches/STABLE-BRANCH-1-4/include/ttyio.h 2009-05-22 15:38:49 UTC (rev 5021) @@ -53,5 +53,6 @@ #define tty_enable_completion(x) #define tty_disable_completion() #endif +void tty_cleanup_after_signal (void); #endif /*G10_TTYIO_H*/ Modified: branches/STABLE-BRANCH-1-4/util/ttyio.c =================================================================== --- branches/STABLE-BRANCH-1-4/util/ttyio.c 2009-05-20 16:12:25 UTC (rev 5020) +++ branches/STABLE-BRANCH-1-4/util/ttyio.c 2009-05-22 15:38:49 UTC (rev 5021) @@ -122,6 +122,14 @@ } #endif +void +tty_cleanup_after_signal (void) +{ +#ifdef HAVE_TCGETATTR + cleanup (); +#endif +} + static void init_ttyfp(void) { From cvs at cvs.gnupg.org Tue May 26 11:29:03 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 26 May 2009 11:29:03 +0200 Subject: [svn] GnuPG - r5022 - trunk/g10 Message-ID: Author: wk Date: 2009-05-26 11:29:02 +0200 (Tue, 26 May 2009) New Revision: 5022 Modified: trunk/g10/ChangeLog trunk/g10/parse-packet.c trunk/g10/signal.c Log: Fix a signal cleanup problem. Fix zero length MPI reading. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-05-22 15:38:49 UTC (rev 5021) +++ trunk/g10/ChangeLog 2009-05-26 09:29:02 UTC (rev 5022) @@ -1,3 +1,13 @@ +2009-05-26 Werner Koch + + * parse-packet.c (mpi_read): Workaround for zero-length MPI bug in + libgcrypt<1.5.0. + +2009-05-22 Werner Koch + + * signal.c (got_fatal_signal): Call new function + tty_cleanup_after_signal. + 2009-05-20 Werner Koch * gpg.c (main): Fix --fingerprint/--with-fingerprint command Modified: trunk/g10/parse-packet.c =================================================================== --- trunk/g10/parse-packet.c 2009-05-22 15:38:49 UTC (rev 5021) +++ trunk/g10/parse-packet.c 2009-05-26 09:29:02 UTC (rev 5022) @@ -139,9 +139,19 @@ p[i+2] = iobuf_get(inp) & 0xff; nread++; } - if ( gcry_mpi_scan( &a, GCRYMPI_FMT_PGP, buf, nread, &nread ) ) - a = NULL; - + + if (nread >= 2 && !(buf[0] << 8 | buf[1])) + { + /* Libgcrypt < 1.5.0 accidently rejects zero-length (i.e. zero) + MPIs. We fix this here. */ + a = gcry_mpi_new (0); + } + else + { + if ( gcry_mpi_scan( &a, GCRYMPI_FMT_PGP, buf, nread, &nread ) ) + a = NULL; + } + leave: gcry_free(buf); if ( nread > *ret_nread ) Modified: trunk/g10/signal.c =================================================================== --- trunk/g10/signal.c 2009-05-22 15:38:49 UTC (rev 5021) +++ trunk/g10/signal.c 2009-05-26 09:29:02 UTC (rev 5022) @@ -81,6 +81,7 @@ gcry_control (GCRYCTL_TERM_SECMEM ); tty_cleanup_rl_after_signal (); + tty_cleanup_after_signal (); /* Better don't translate these messages. */ write(2, "\n", 1 ); From cvs at cvs.gnupg.org Tue May 26 11:29:33 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 26 May 2009 11:29:33 +0200 Subject: [svn] GnuPG - r5023 - trunk/common Message-ID: Author: wk Date: 2009-05-26 11:29:33 +0200 (Tue, 26 May 2009) New Revision: 5023 Modified: trunk/common/ChangeLog trunk/common/ttyio.c trunk/common/ttyio.h Log: signal cleanup fix Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-05-26 09:29:02 UTC (rev 5022) +++ trunk/common/ChangeLog 2009-05-26 09:29:33 UTC (rev 5023) @@ -1,3 +1,7 @@ +2009-05-22 Werner Koch + + * ttyio.c (tty_cleanup_after_signal): New. + 2009-05-19 Werner Koch * simple-pwquery.c (agent_open): Use SUN_LEN Modified: trunk/common/ttyio.c =================================================================== --- trunk/common/ttyio.c 2009-05-26 09:29:02 UTC (rev 5022) +++ trunk/common/ttyio.c 2009-05-26 09:29:33 UTC (rev 5023) @@ -674,6 +674,14 @@ void +tty_cleanup_after_signal (void) +{ +#ifdef HAVE_TCGETATTR + cleanup (); +#endif +} + +void tty_cleanup_rl_after_signal (void) { if (my_rl_cleanup_after_signal) Modified: trunk/common/ttyio.h =================================================================== --- trunk/common/ttyio.h 2009-05-26 09:29:02 UTC (rev 5022) +++ trunk/common/ttyio.h 2009-05-26 09:29:33 UTC (rev 5023) @@ -47,6 +47,7 @@ void tty_enable_completion (rl_completion_func_t *completer); void tty_disable_completion (void); +void tty_cleanup_after_signal (void); void tty_cleanup_rl_after_signal (void); From cvs at cvs.gnupg.org Tue May 26 11:41:53 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 26 May 2009 11:41:53 +0200 Subject: [svn] gcry - r1395 - in trunk: . mpi Message-ID: Author: wk Date: 2009-05-26 11:41:53 +0200 (Tue, 26 May 2009) New Revision: 1395 Modified: trunk/AUTHORS trunk/mpi/ChangeLog trunk/mpi/mpicoder.c Log: Fix reading of a zero MPIs. Modified: trunk/mpi/ChangeLog =================================================================== --- trunk/mpi/ChangeLog 2009-05-10 16:27:32 UTC (rev 1394) +++ trunk/mpi/ChangeLog 2009-05-26 09:41:53 UTC (rev 1395) @@ -1,3 +1,8 @@ +2009-05-26 Werner Koch + + * mpicoder.c (mpi_read_from_buffer): Allow zero-sized MPIs (i.e a + zero). + 2009-02-16 Werner Koch * mpiutil.c: Remove memory.h. Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2009-05-10 16:27:32 UTC (rev 1394) +++ trunk/AUTHORS 2009-05-26 09:41:53 UTC (rev 1395) @@ -81,7 +81,8 @@ perky at freebsd.org (SEED cipher) -LIBGCRYPT Werner Dittmann ** pending ** +LIBGCRYPT Werner Dittmann 2009-05-20 +Assigns Past and Future Changes werner.dittmann at t-online.de (mpi/amd64, tests/mpitests.c) Modified: trunk/mpi/mpicoder.c =================================================================== --- trunk/mpi/mpicoder.c 2009-05-10 16:27:32 UTC (rev 1394) +++ trunk/mpi/mpicoder.c 2009-05-26 09:41:53 UTC (rev 1395) @@ -46,11 +46,6 @@ /* log_debug ("mpi too large (%u bits)\n", nbits); */ goto leave; } - else if( !nbits ) - { -/* log_debug ("an mpi of size 0 is not allowed\n"); */ - goto leave; - } buffer += 2; nread = 2; From cvs at cvs.gnupg.org Tue May 26 16:15:56 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Tue, 26 May 2009 16:15:56 +0200 Subject: [svn] GnuPG - r5024 - in branches/STABLE-BRANCH-1-4: include keyserver util Message-ID: Author: dshaw Date: 2009-05-26 16:15:56 +0200 (Tue, 26 May 2009) New Revision: 5024 Modified: branches/STABLE-BRANCH-1-4/include/ChangeLog branches/STABLE-BRANCH-1-4/include/http.h branches/STABLE-BRANCH-1-4/keyserver/ChangeLog branches/STABLE-BRANCH-1-4/keyserver/curl-shim.c branches/STABLE-BRANCH-1-4/keyserver/curl-shim.h branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_curl.c branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c branches/STABLE-BRANCH-1-4/util/ChangeLog branches/STABLE-BRANCH-1-4/util/http.c Log: Avoid caches to get the most recent copy of the key. This is bug #1061 Modified: branches/STABLE-BRANCH-1-4/include/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/include/ChangeLog 2009-05-26 09:29:33 UTC (rev 5023) +++ branches/STABLE-BRANCH-1-4/include/ChangeLog 2009-05-26 14:15:56 UTC (rev 5024) @@ -1,3 +1,8 @@ +2009-05-26 David Shaw + + * http.h: Pass in a STRLIST for additional headers on http_open + and http_open_document. + 2009-04-05 David Shaw * srv.h: Move from util/srv.h. Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-05-26 09:29:33 UTC (rev 5023) +++ branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-05-26 14:15:56 UTC (rev 5024) @@ -1,3 +1,13 @@ +2009-05-26 David Shaw + + * curl-shim.c (curl_slist_append, curl_slist_free_all): New. + Simple wrappers around STRLIST to emulate the curl way of doing + string lists. + (curl_easy_setopt): Handle the curl HTTPHEADER option. + + * gpgkeys_curl.c, gpgkeys_hkp.c (main): Avoid caches to get the + most recent copy of the key. This is bug #1061. + 2009-05-03 David Shaw * gpgkeys_mailto.in: Set 'mail-from' as a keyserver-option, rather Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-05-26 09:29:33 UTC (rev 5023) +++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-05-26 14:15:56 UTC (rev 5024) @@ -1,3 +1,8 @@ +2009-05-26 David Shaw + + * http.c (send_request): Pass in a STRLIST for additional headers. + Change all callers. + 2009-05-22 Werner Koch * ttyio.c (tty_cleanup_after_signal): New. Modified: branches/STABLE-BRANCH-1-4/include/http.h =================================================================== --- branches/STABLE-BRANCH-1-4/include/http.h 2009-05-26 09:29:33 UTC (rev 5023) +++ branches/STABLE-BRANCH-1-4/include/http.h 2009-05-26 14:15:56 UTC (rev 5024) @@ -75,12 +75,12 @@ int http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url, char *auth, unsigned int flags, const char *proxy, - const char *srvtag ); + const char *srvtag, STRLIST headers ); void http_start_data( HTTP_HD hd ); int http_wait_response( HTTP_HD hd, unsigned int *ret_status ); void http_close( HTTP_HD hd ); int http_open_document( HTTP_HD hd, const char *document, char *auth, unsigned int flags, const char *proxy, - const char *srvtag ); + const char *srvtag, STRLIST headers ); #endif /*G10_HTTP_H*/ Modified: branches/STABLE-BRANCH-1-4/keyserver/curl-shim.c =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/curl-shim.c 2009-05-26 09:29:33 UTC (rev 5023) +++ branches/STABLE-BRANCH-1-4/keyserver/curl-shim.c 2009-05-26 14:15:56 UTC (rev 5024) @@ -146,6 +146,9 @@ case CURLOPT_STDERR: curl->errors=va_arg(ap,FILE *); break; + case CURLOPT_HTTPHEADER: + curl->headers=va_arg(ap,struct curl_slist *); + break; default: /* We ignore the huge majority of curl options */ break; @@ -186,7 +189,7 @@ if(curl->flags.post) { rc=http_open(&curl->hd,HTTP_REQ_POST,curl->url,curl->auth,0,proxy, - curl->srvtag); + curl->srvtag,curl->headers?curl->headers->list:NULL); if(rc==0) { char content_len[50]; @@ -208,7 +211,7 @@ else { rc=http_open(&curl->hd,HTTP_REQ_GET,curl->url,curl->auth,0,proxy, - curl->srvtag); + curl->srvtag,curl->headers?curl->headers->list:NULL); if(rc==0) { rc=http_wait_response(&curl->hd,&curl->status); @@ -335,3 +338,28 @@ return &data; } + +struct curl_slist * +curl_slist_append(struct curl_slist *list,const char *string) +{ + if(!list) + { + list=calloc(1,sizeof(*list)); + if(!list) + return NULL; + } + + add_to_strlist(&list->list,string); + + return list; +} + +void +curl_slist_free_all(struct curl_slist *list) +{ + if(list) + { + free_strlist(list->list); + free(list); + } +} Modified: branches/STABLE-BRANCH-1-4/keyserver/curl-shim.h =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/curl-shim.h 2009-05-26 09:29:33 UTC (rev 5023) +++ branches/STABLE-BRANCH-1-4/keyserver/curl-shim.h 2009-05-26 14:15:56 UTC (rev 5024) @@ -49,6 +49,7 @@ CURLOPT_POST, CURLOPT_POSTFIELDS, CURLOPT_FAILONERROR, + CURLOPT_HTTPHEADER, CURLOPT_SRVTAG_GPG_HACK } CURLoption; @@ -67,6 +68,7 @@ char *srvtag; unsigned int status; FILE *errors; + struct curl_slist *headers; struct { unsigned int post:1; @@ -96,4 +98,13 @@ #define curl_version() "GnuPG curl-shim" curl_version_info_data *curl_version_info(int type); +struct curl_slist +{ + STRLIST list; +}; + +struct curl_slist *curl_slist_append(struct curl_slist *list, + const char *string); +void curl_slist_free_all(struct curl_slist *list); + #endif /* !_CURL_SHIM_H_ */ Modified: branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_curl.c =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_curl.c 2009-05-26 09:29:33 UTC (rev 5023) +++ branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_curl.c 2009-05-26 14:15:56 UTC (rev 5024) @@ -118,6 +118,7 @@ long follow_redirects=5; char *proxy=NULL; curl_version_info_data *curldata; + struct curl_slist *headers=NULL; console=stderr; @@ -306,6 +307,26 @@ curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert); curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file); + /* Avoid caches to get the most recent copy of the key. This is bug + #1061. In pre-curl versions of the code, we didn't do it. Then + we did do it (as a curl default) until curl changed the default. + Now we're doing it again, but in such a way that changing + defaults in the future won't impact us. We set both the Pragma + and Cache-Control versions of the header, so we're good with both + HTTP 1.0 and 1.1. */ + headers=curl_slist_append(headers,"Pragma: no-cache"); + if(headers) + headers=curl_slist_append(headers,"Cache-Control: no-cache"); + + if(!headers) + { + fprintf(console,"gpgkeys: out of memory when building HTTP headers\n"); + ret=KEYSERVER_NO_MEMORY; + goto fail; + } + + curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers); + if(proxy) curl_easy_setopt(curl,CURLOPT_PROXY,proxy); @@ -386,6 +407,8 @@ free_ks_options(opt); + curl_slist_free_all(headers); + if(curl) curl_easy_cleanup(curl); Modified: branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-05-26 09:29:33 UTC (rev 5023) +++ branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-05-26 14:15:56 UTC (rev 5024) @@ -550,6 +550,7 @@ int failed=0; struct keylist *keylist=NULL,*keyptr=NULL; char *proxy=NULL; + struct curl_slist *headers=NULL; console=stderr; @@ -746,6 +747,26 @@ curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert); curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file); + /* Avoid caches to get the most recent copy of the key. This is bug + #1061. In pre-curl versions of the code, we didn't do it. Then + we did do it (as a curl default) until curl changed the default. + Now we're doing it again, but in such a way that changing + defaults in the future won't impact us. We set both the Pragma + and Cache-Control versions of the header, so we're good with both + HTTP 1.0 and 1.1. */ + headers=curl_slist_append(headers,"Pragma: no-cache"); + if(headers) + headers=curl_slist_append(headers,"Cache-Control: no-cache"); + + if(!headers) + { + fprintf(console,"gpgkeys: out of memory when building HTTP headers\n"); + ret=KEYSERVER_NO_MEMORY; + goto fail; + } + + curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers); + if(proxy) curl_easy_setopt(curl,CURLOPT_PROXY,proxy); @@ -923,6 +944,8 @@ free_ks_options(opt); + curl_slist_free_all(headers); + if(curl) curl_easy_cleanup(curl); Modified: branches/STABLE-BRANCH-1-4/util/http.c =================================================================== --- branches/STABLE-BRANCH-1-4/util/http.c 2009-05-26 09:29:33 UTC (rev 5023) +++ branches/STABLE-BRANCH-1-4/util/http.c 2009-05-26 14:15:56 UTC (rev 5024) @@ -69,7 +69,7 @@ const byte *special ); static URI_TUPLE parse_tuple( byte *string ); static int send_request( HTTP_HD hd, const char *auth, const char *proxy, - const char *srvtag); + const char *srvtag, STRLIST headers); static byte *build_rel_path( PARSED_URI uri ); static int parse_response( HTTP_HD hd ); @@ -150,7 +150,7 @@ int http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url, char *auth, unsigned int flags, const char *proxy, - const char *srvtag ) + const char *srvtag, STRLIST headers ) { int rc; @@ -166,7 +166,7 @@ rc = parse_uri( &hd->uri, url ); if( !rc ) { - rc = send_request( hd, auth, proxy, srvtag ); + rc = send_request( hd, auth, proxy, srvtag, headers ); if( !rc ) { hd->fp_write = iobuf_sockopen( hd->sock , "w" ); if( hd->fp_write ) @@ -234,11 +234,13 @@ int http_open_document( HTTP_HD hd, const char *document, char *auth, - unsigned int flags, const char *proxy, const char *srvtag ) + unsigned int flags, const char *proxy, const char *srvtag, + STRLIST headers ) { int rc; - rc = http_open(hd, HTTP_REQ_GET, document, auth, flags, proxy, srvtag ); + rc = http_open(hd, HTTP_REQ_GET, document, auth, flags, proxy, srvtag, + headers ); if( rc ) return rc; @@ -521,7 +523,7 @@ */ static int send_request( HTTP_HD hd, const char *auth, const char *proxy, - const char *srvtag ) + const char *srvtag, STRLIST headers ) { const byte *server; byte *request, *p; @@ -613,6 +615,19 @@ xfree(p); rc = write_server( hd->sock, request, strlen(request) ); + + if(rc==0) + for(;headers;headers=headers->next) + { + rc = write_server( hd->sock, headers->d, strlen(headers->d) ); + if(rc) + break; + + rc = write_server( hd->sock, "\r\n", 2 ); + if(rc) + break; + } + xfree( request ); xfree(proxy_authstr); xfree(authstr); @@ -1078,7 +1093,7 @@ } release_parsed_uri( uri ); uri = NULL; - rc = http_open_document( &hd, *argv, NULL, 0, NULL ); + rc = http_open_document( &hd, *argv, NULL, 0, NULL, NULL, NULL ); if( rc ) { log_error("can't get `%s': %s\n", *argv, g10_errstr(rc)); return 1; From cvs at cvs.gnupg.org Tue May 26 17:12:56 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 26 May 2009 17:12:56 +0200 Subject: [svn] dirmngr - r313 - trunk/src Message-ID: Author: wk Date: 2009-05-26 17:12:55 +0200 (Tue, 26 May 2009) New Revision: 313 Modified: trunk/src/ChangeLog trunk/src/crlcache.c trunk/src/dirmngr_ldap.c trunk/src/ldap.c Log: Changed some diagnostics. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-04-03 09:26:08 UTC (rev 312) +++ trunk/src/ChangeLog 2009-05-26 15:12:55 UTC (rev 313) @@ -1,3 +1,10 @@ +2009-05-26 Werner Koch + + * ldap.c (ldap_wrapper): Show reader object in diagnostics. + * crlcache.c (crl_cache_reload_crl): Ditto. Change debug messages + to regular diagnostics. + * dirmngr_ldap.c (print_ldap_entries): Add extra diagnostics. + 2009-04-03 Werner Koch * dirmngr.h (struct server_local_s): Move back to ... Modified: trunk/src/crlcache.c =================================================================== --- trunk/src/crlcache.c 2009-04-03 09:26:08 UTC (rev 312) +++ trunk/src/crlcache.c 2009-05-26 15:12:55 UTC (rev 313) @@ -2402,8 +2402,8 @@ /* Loop over all distribution points, get the CRLs and put them into the cache. */ - if (DBG_X509) - log_debug ("checking distribution points\n"); + if (opt.verbose) + log_info ("checking distribution points\n"); seq = 0; while ( !(err = ksba_cert_get_crl_dist_point (cert, seq++, &distpoint, @@ -2414,8 +2414,8 @@ if (!distpoint && !issuername) { - if (DBG_X509) - log_debug ("no issuer name and no distribution point\n"); + if (opt.verbose) + log_info ("no issuer name and no distribution point\n"); break; /* Not allowed; i.e. an invalid certificate. We give up here and hope that the default method returns a suitable CRL. */ @@ -2449,8 +2449,8 @@ any_dist_point = 1; - if (DBG_X509) - log_debug ("fetching CRL from `%s'\n", distpoint_uri); + if (opt.verbose) + log_info ("fetching CRL from `%s'\n", distpoint_uri); err = crl_fetch (ctrl, distpoint_uri, &reader); if (err) { @@ -2460,8 +2460,8 @@ continue; /* with the next name. */ } - if (DBG_X509) - log_debug ("inserting CRL\n"); + if (opt.verbose) + log_info ("inserting CRL (reader %p)\n", reader); err = crl_cache_insert (ctrl, distpoint_uri, reader); if (err) { @@ -2493,8 +2493,8 @@ /* If we did not found any distpoint, try something reasonable. */ if (!any_dist_point ) { - if (DBG_X509) - log_debug ("no distribution point - trying issuer name\n"); + if (opt.verbose) + log_info ("no distribution point - trying issuer name\n"); if (reader) { @@ -2510,18 +2510,18 @@ goto leave; } - if (DBG_X509) - log_debug ("fetching CRL from default location\n"); + if (opt.verbose) + log_info ("fetching CRL from default location\n"); err = crl_fetch_default (ctrl, issuer, &reader); if (err) { - log_error (_("crl_fetch via issuer failed: %s\n"), + log_error ("crl_fetch via issuer failed: %s\n", gpg_strerror (err)); goto leave; } - if (DBG_X509) - log_debug ("inserting CRL\n"); + if (opt.verbose) + log_info ("inserting CRL (reader %p)\n", reader); err = crl_cache_insert (ctrl, "default location(s)", reader); if (err) { Modified: trunk/src/dirmngr_ldap.c =================================================================== --- trunk/src/dirmngr_ldap.c 2009-04-03 09:26:08 UTC (rev 312) +++ trunk/src/dirmngr_ldap.c 2009-05-26 15:12:55 UTC (rev 313) @@ -388,7 +388,14 @@ } if (opt.verbose) - log_info (_("found attribute `%s'\n"), attr); + { + log_info (_("found attribute `%s'\n"), attr); + if (opt.verbose > 1) + for (idx=0; values[idx]; idx++) + log_info (" length[%d]=%d\n", + idx, (int)values[0]->bv_len); + + } if (opt.multi) { /* Write attribute marker. */ @@ -488,6 +495,9 @@ ber_free (berctx, 0); } + if (opt.verbose > 1 && any) + log_info ("result has been printed\n"); + return any?0:-1; } Modified: trunk/src/ldap.c =================================================================== --- trunk/src/ldap.c 2009-04-03 09:26:08 UTC (rev 312) +++ trunk/src/ldap.c 2009-05-26 15:12:55 UTC (rev 313) @@ -466,7 +466,7 @@ size_t nleft = count; /* FIXME: We might want to add some internal buffering because the - ksba code does not not any buffering for itself (because a ksba + ksba code does not do any buffering for itself (because a ksba reader may be detached from another stream to read other data and the it would be cumbersome to get back already buffered stuff). */ @@ -590,7 +590,7 @@ only viable solutions are either to have another thread responsible for logging the messages or to add an option to the wrapper modules to the logging on its own. Given that we anyway - need a way to rip the child process and is best done using a + need a way to rip the child process and this best done using a general ripping thread, that thread can do the logging too. */ *reader = NULL; @@ -666,7 +666,8 @@ ctx->next = wrapper_list; wrapper_list = ctx; if (opt.verbose) - log_info (_("ldap wrapper %d started\n"), (int)ctx->pid); + log_info ("ldap wrapper %d started (reader %p)\n", + (int)ctx->pid, ctx->reader); /* Need to wait for the first byte so we are able to detect an empty output and not let the consumer see an EOF without further error @@ -696,7 +697,7 @@ /* Perform an LDAP query. Returns an gpg error code or 0 on success. - The function returns a new stream at R_FP. */ + The function returns a new reader object at READER. */ static gpg_error_t run_ldap_wrapper (ctrl_t ctrl, int ignore_timeout, @@ -780,7 +781,7 @@ /* Perform a LDAP query using a given URL. On success a new ksba - reader is returned. If HOST or PORT ar not 0, they are used to + reader is returned. If HOST or PORT are not 0, they are used to override the values from the URL. */ gpg_error_t url_fetch_ldap (ctrl_t ctrl, const char *url, const char *host, int port, @@ -789,7 +790,7 @@ gpg_error_t err; err = run_ldap_wrapper (ctrl, - 1, /* Ignore explicit timeout because CRLS + 1, /* Ignore explicit timeout because CRLs might be very large. */ 0, opt.ldap_proxy, From cvs at cvs.gnupg.org Thu May 28 05:24:54 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Thu, 28 May 2009 05:24:54 +0200 Subject: [svn] GnuPG - r5025 - trunk/common Message-ID: Author: dshaw Date: 2009-05-28 05:24:54 +0200 (Thu, 28 May 2009) New Revision: 5025 Modified: trunk/common/ChangeLog trunk/common/srv.c Log: * srv.c (getsrv): Raise maximum packet size to 2048, as PACKETSZ is too small these days. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-05-26 14:15:56 UTC (rev 5024) +++ trunk/common/ChangeLog 2009-05-28 03:24:54 UTC (rev 5025) @@ -1,3 +1,8 @@ +2009-05-27 David Shaw + + * srv.c (getsrv): Raise maximum packet size to 2048, as PACKETSZ + is too small these days. + 2009-05-22 Werner Koch * ttyio.c (tty_cleanup_after_signal): New. Modified: trunk/common/srv.c =================================================================== --- trunk/common/srv.c 2009-05-26 14:15:56 UTC (rev 5024) +++ trunk/common/srv.c 2009-05-28 03:24:54 UTC (rev 5025) @@ -1,5 +1,5 @@ /* srv.c - DNS SRV code - * Copyright (C) 2003 Free Software Foundation, Inc. + * Copyright (C) 2003, 2009 Free Software Foundation, Inc. * * This file is part of GNUPG. * @@ -55,15 +55,15 @@ int getsrv(const char *name,struct srventry **list) { - unsigned char answer[PACKETSZ]; + unsigned char answer[2048]; int r,srvcount=0; unsigned char *pt,*emsg; u16 count,dlen; *list=NULL; - r=res_query(name,C_IN,T_SRV,answer,PACKETSZ); - if(rPACKETSZ) + r=res_query(name,C_IN,T_SRV,answer,2048); + if(r2048) return -1; if((((HEADER *)answer)->rcode)==NOERROR && From cvs at cvs.gnupg.org Thu May 28 06:25:26 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Thu, 28 May 2009 06:25:26 +0200 Subject: [svn] GnuPG - r5026 - in trunk: common keyserver Message-ID: Author: dshaw Date: 2009-05-28 06:25:25 +0200 (Thu, 28 May 2009) New Revision: 5026 Modified: trunk/common/ChangeLog trunk/common/http.c trunk/common/http.h trunk/keyserver/ChangeLog trunk/keyserver/curl-shim.c trunk/keyserver/curl-shim.h trunk/keyserver/gpgkeys_hkp.c Log: * http.h, http.c (send_request): Pass in srvtag and make its presence sufficient to turn the feature on. (http_open): From here. (http_document): And here. * gpgkeys_hkp.c (srv_replace): New function to transform a SRV hostname to a real hostname. (main): Call it from here for the HAVE_LIBCURL case (without libcurl is handled via the curl-shim). * curl-shim.h, curl-shim.c (curl_easy_setopt, curl_easy_perform): Add a CURLOPT_SRVTAG_GPG_HACK (passed through the the http engine). Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-05-28 03:24:54 UTC (rev 5025) +++ trunk/common/ChangeLog 2009-05-28 04:25:25 UTC (rev 5026) @@ -1,5 +1,12 @@ 2009-05-27 David Shaw + From 1.4: + + * http.h, http.c (send_request): Pass in srvtag and make its + presence sufficient to turn the feature on. + (http_open): From here. + (http_document): And here. + * srv.c (getsrv): Raise maximum packet size to 2048, as PACKETSZ is too small these days. Modified: trunk/keyserver/ChangeLog =================================================================== --- trunk/keyserver/ChangeLog 2009-05-28 03:24:54 UTC (rev 5025) +++ trunk/keyserver/ChangeLog 2009-05-28 04:25:25 UTC (rev 5026) @@ -1,3 +1,16 @@ +2009-05-27 David Shaw + + From 1.4: + + * gpgkeys_hkp.c (srv_replace): New function to transform a SRV + hostname to a real hostname. + (main): Call it from here for the HAVE_LIBCURL case (without + libcurl is handled via the curl-shim). + + * curl-shim.h, curl-shim.c (curl_easy_setopt, curl_easy_perform): + Add a CURLOPT_SRVTAG_GPG_HACK (passed through the the http + engine). + 2009-05-10 David Shaw From 1.4: Modified: trunk/common/http.c =================================================================== --- trunk/common/http.c 2009-05-28 03:24:54 UTC (rev 5025) +++ trunk/common/http.c 2009-05-28 04:25:25 UTC (rev 5026) @@ -128,8 +128,8 @@ static int insert_escapes (char *buffer, const char *string, const char *special); static uri_tuple_t parse_tuple (char *string); -static gpg_error_t send_request (http_t hd, - const char *auth, const char *proxy); +static gpg_error_t send_request (http_t hd, const char *auth, + const char *proxy, const char *srvtag); static char *build_rel_path (parsed_uri_t uri); static gpg_error_t parse_response (http_t hd); @@ -317,7 +317,7 @@ gpg_error_t http_open (http_t *r_hd, http_req_t reqtype, const char *url, const char *auth, unsigned int flags, const char *proxy, - void *tls_context) + void *tls_context, const char *srvtag) { gpg_error_t err; http_t hd; @@ -338,7 +338,7 @@ err = http_parse_uri (&hd->uri, url); if (!err) - err = send_request (hd, auth, proxy); + err = send_request (hd, auth, proxy, srvtag); if (err) { @@ -457,12 +457,12 @@ gpg_error_t http_open_document (http_t *r_hd, const char *document, const char *auth, unsigned int flags, const char *proxy, - void *tls_context) + void *tls_context, const char *srvtag) { gpg_error_t err; err = http_open (r_hd, HTTP_REQ_GET, document, auth, flags, - proxy, tls_context); + proxy, tls_context, srvtag); if (err) return err; @@ -835,7 +835,7 @@ * Returns 0 if the request was successful */ static gpg_error_t -send_request (http_t hd, const char *auth, const char *proxy) +send_request (http_t hd, const char *auth, const char *proxy,const char *srvtag) { gnutls_session_t tls_session; gpg_error_t err; @@ -893,13 +893,13 @@ hd->sock = connect_server (*uri->host ? uri->host : "localhost", uri->port ? uri->port : 80, - hd->flags, hd->uri->scheme); + hd->flags, srvtag); save_errno = errno; http_release_parsed_uri (uri); } else { - hd->sock = connect_server (server, port, hd->flags, hd->uri->scheme); + hd->sock = connect_server (server, port, hd->flags, srvtag); save_errno = errno; } @@ -1524,6 +1524,9 @@ int last_errno = 0; struct srventry *serverlist = NULL; + /* Not currently using the flags */ + (void)flags; + #ifdef HAVE_W32_SYSTEM unsigned long inaddr; @@ -1559,7 +1562,7 @@ #ifdef USE_DNS_SRV /* Do the SRV thing */ - if ((flags & HTTP_FLAG_TRY_SRV) && srvtag) + if (srvtag) { /* We're using SRV, so append the tags. */ if (1+strlen (srvtag) + 6 + strlen (server) + 1 <= MAXDNAME) Modified: trunk/common/http.h =================================================================== --- trunk/common/http.h 2009-05-28 03:24:54 UTC (rev 5025) +++ trunk/common/http.h 2009-05-28 04:25:25 UTC (rev 5026) @@ -63,9 +63,8 @@ { HTTP_FLAG_TRY_PROXY = 1, HTTP_FLAG_NO_SHUTDOWN = 2, - HTTP_FLAG_TRY_SRV = 4, - HTTP_FLAG_LOG_RESP = 8, - HTTP_FLAG_NEED_HEADER = 16 + HTTP_FLAG_LOG_RESP = 4, + HTTP_FLAG_NEED_HEADER = 8 }; struct http_context_s; @@ -82,7 +81,8 @@ const char *auth, unsigned int flags, const char *proxy, - void *tls_context); + void *tls_context, + const char *srvtag); void http_start_data (http_t hd); @@ -95,7 +95,8 @@ const char *auth, unsigned int flags, const char *proxy, - void *tls_context); + void *tls_context, + const char *srvtag); #ifdef HTTP_USE_ESTREAM estream_t http_get_read_ptr (http_t hd); Modified: trunk/keyserver/curl-shim.c =================================================================== --- trunk/keyserver/curl-shim.c 2009-05-28 03:24:54 UTC (rev 5025) +++ trunk/keyserver/curl-shim.c 2009-05-28 04:25:25 UTC (rev 5026) @@ -144,6 +144,9 @@ case CURLOPT_POSTFIELDS: curl->postfields=va_arg(ap,char *); break; + case CURLOPT_SRVTAG_GPG_HACK: + curl->srvtag=va_arg(ap,char *); + break; case CURLOPT_FAILONERROR: curl->flags.failonerror=va_arg(ap,long)?1:0; break; @@ -193,7 +196,7 @@ if(curl->flags.post) { rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, curl->auth, - 0, proxy, NULL); + 0, proxy, NULL, curl->srvtag); if (!rc) { unsigned int post_len = strlen(curl->postfields); @@ -216,7 +219,7 @@ else { rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, curl->auth, - 0, proxy, NULL); + 0, proxy, NULL, curl->srvtag); if (!rc) { rc = http_wait_response (curl->hd); Modified: trunk/keyserver/curl-shim.h =================================================================== --- trunk/keyserver/curl-shim.h 2009-05-28 03:24:54 UTC (rev 5025) +++ trunk/keyserver/curl-shim.h 2009-05-28 04:25:25 UTC (rev 5026) @@ -48,7 +48,8 @@ CURLOPT_CAINFO, CURLOPT_POST, CURLOPT_POSTFIELDS, - CURLOPT_FAILONERROR + CURLOPT_FAILONERROR, + CURLOPT_SRVTAG_GPG_HACK } CURLoption; typedef size_t (*write_func)(char *buffer,size_t size, @@ -63,6 +64,7 @@ write_func writer; void *file; char *postfields; + char *srvtag; unsigned int status; FILE *errors; struct Modified: trunk/keyserver/gpgkeys_hkp.c =================================================================== --- trunk/keyserver/gpgkeys_hkp.c 2009-05-28 03:24:54 UTC (rev 5025) +++ trunk/keyserver/gpgkeys_hkp.c 2009-05-28 04:25:25 UTC (rev 5026) @@ -43,6 +43,9 @@ #else #include "curl-shim.h" #endif +#ifdef USE_DNS_SRV +#include "srv.h" +#endif #include "keyserver.h" #include "ksutil.h" @@ -183,6 +186,7 @@ strcat(key,encoded_key); strcpy(request,proto); + strcat(request,"://"); strcat(request,opt->host); strcat(request,":"); strcat(request,port); @@ -247,6 +251,7 @@ } strcpy(request,proto); + strcat(request,"://"); strcat(request,opt->host); strcat(request,":"); strcat(request,port); @@ -325,6 +330,7 @@ fprintf(output,"NAME %s BEGIN\n",getkey); strcpy(request,proto); + strcat(request,"://"); strcat(request,opt->host); strcat(request,":"); strcat(request,port); @@ -408,6 +414,7 @@ fprintf(output,"SEARCH %s BEGIN\n",searchkey); strcpy(request,proto); + strcat(request,"://"); strcat(request,opt->host); strcat(request,":"); strcat(request,port); @@ -478,6 +485,51 @@ } } +#ifdef HAVE_LIBCURL +/* If there is a SRV record, take the highest ranked possibility. + This is a hack, as we don't proceed downwards. */ +static void +srv_replace(void) +{ +#ifdef USE_DNS_SRV + struct srventry *srvlist=NULL; + int srvcount; + + if(1+strlen(opt->scheme)+6+strlen(opt->host)+1<=MAXDNAME) + { + char srvname[MAXDNAME]; + + strcpy(srvname,"_"); + strcat(srvname,opt->scheme); + strcat(srvname,"._tcp."); + strcat(srvname,opt->host); + srvcount=getsrv(srvname,&srvlist); + } + + if(srvlist) + { + char *newname,*newport; + + newname=strdup(srvlist->target); + newport=malloc(MAX_PORT); + if(newname && newport) + { + free(opt->host); + free(opt->port); + opt->host=newname; + snprintf(newport,MAX_PORT,"%u",srvlist->port); + opt->port=newport; + } + else + { + free(newname); + free(newport); + } + } +#endif +} +#endif + static void show_help (FILE *fp) { @@ -490,7 +542,7 @@ int main(int argc,char *argv[]) { - int arg,ret=KEYSERVER_INTERNAL_ERROR; + int arg,ret=KEYSERVER_INTERNAL_ERROR,try_srv=1; char line[MAX_LINE]; int failed=0; struct keylist *keylist=NULL,*keyptr=NULL; @@ -604,15 +656,14 @@ } } } -#if 0 else if(strcasecmp(start,"try-dns-srv")==0) { if(no) - http_flags&=~HTTP_FLAG_TRY_SRV; + try_srv=0; else - http_flags|=HTTP_FLAG_TRY_SRV; + try_srv=1; } -#endif + continue; } } @@ -626,18 +677,15 @@ if(ks_strcasecmp(opt->scheme,"hkps")==0) { - proto="https://"; + proto="https"; port="443"; } else { - proto="http://"; + proto="http"; port="11371"; } - if(opt->port) - port=opt->port; - if(!opt->host) { fprintf(console,"gpgkeys: no keyserver host provided\n"); @@ -659,6 +707,26 @@ goto fail; } + /* If the user gives a :port, then disable SRV. The semantics of a + specified port and SRV do not play well together. */ + if(opt->port) + port=opt->port; + else if(try_srv) + { +#ifdef HAVE_LIBCURL + /* We're using libcurl, so fake SRV support via our wrapper. + This isn't as good as true SRV support, as we do not try all + possible targets at one particular level and work our way + down the list, but it's better than nothing. */ + srv_replace(); +#else + /* We're using our internal curl shim, so we can use its (true) + SRV support. Obviously, CURLOPT_SRVTAG_GPG_HACK isn't a real + libcurl option. It's specific to our shim. */ + curl_easy_setopt(curl,CURLOPT_SRVTAG_GPG_HACK,opt->scheme); +#endif + } + curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errorbuffer); if(opt->auth) @@ -677,13 +745,6 @@ if(proxy) curl_easy_setopt(curl,CURLOPT_PROXY,proxy); -#if 0 - /* By suggested convention, if the user gives a :port, then disable - SRV. */ - if(opt->port) - http_flags&=~HTTP_FLAG_TRY_SRV; -#endif - /* If it's a GET or a SEARCH, the next thing to come in is the keyids. If it's a SEND, then there are no keyids. */ From cvs at cvs.gnupg.org Thu May 28 06:33:12 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Thu, 28 May 2009 06:33:12 +0200 Subject: [svn] GnuPG - r5027 - branches/STABLE-BRANCH-1-4/keyserver Message-ID: Author: dshaw Date: 2009-05-28 06:33:10 +0200 (Thu, 28 May 2009) New Revision: 5027 Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c Log: * gpgkeys_hkp.c (srv_replace): Fix build warning. Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-05-28 04:25:25 UTC (rev 5026) +++ branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-05-28 04:33:10 UTC (rev 5027) @@ -1,3 +1,7 @@ +2009-05-27 David Shaw + + * gpgkeys_hkp.c (srv_replace): Fix build warning. + 2009-05-26 David Shaw * curl-shim.c (curl_slist_append, curl_slist_free_all): New. Modified: branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-05-28 04:25:25 UTC (rev 5026) +++ branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-05-28 04:33:10 UTC (rev 5027) @@ -490,6 +490,7 @@ } } +#ifdef HAVE_LIBCURL /* If there is a SRV record, take the highest ranked possibility. This is a hack, as we don't proceed downwards. */ static void @@ -532,6 +533,7 @@ } #endif } +#endif static void show_help (FILE *fp) From cvs at cvs.gnupg.org Thu May 28 10:07:17 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 28 May 2009 10:07:17 +0200 Subject: [svn] ksba - r303 - in trunk: . src Message-ID: Author: wk Date: 2009-05-28 10:07:16 +0200 (Thu, 28 May 2009) New Revision: 303 Modified: trunk/NEWS trunk/src/ChangeLog trunk/src/cms.c trunk/src/der-encoder.c Log: Use an explicit NULL in an RSA algorithmIdentifier sequence. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-03-26 19:27:46 UTC (rev 302) +++ trunk/src/ChangeLog 2009-05-28 08:07:16 UTC (rev 303) @@ -1,3 +1,8 @@ +2009-05-28 Werner Koch + + * der-encoder.c (_ksba_der_store_null, sum_up_lengths): Actually + write out NULL tags. + 2009-03-26 Werner Koch * cms.h (struct certlist_s): Allow for SHA-512. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-03-26 19:27:46 UTC (rev 302) +++ trunk/NEWS 2009-05-28 08:07:16 UTC (rev 303) @@ -3,7 +3,12 @@ * Support SHA-{384,512} based signature generation. + * The RSA algorithmIdentifier ASN.1 sequence is now emitted with an + explicit NULL parameter. Despite all the interop testing we did in + the past, some software still requires this and thus we follow the + best current practise now. + Noteworthy changes in version 1.0.5 (2009-01-09) ------------------------------------------------ @@ -367,7 +372,8 @@ * Nearly all stuff needed for the Aegypten project is now in place. - Copyright 2002, 2003, 2004, 2005, 2006 g10 Code GmbH + Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, + 2009 g10 Code GmbH This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/src/cms.c =================================================================== --- trunk/src/cms.c 2009-03-26 19:27:46 UTC (rev 302) +++ trunk/src/cms.c 2009-05-28 08:07:16 UTC (rev 303) @@ -3091,6 +3091,32 @@ err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND); goto leave; } + + /* Now store NULL for the optional parameters. From Peter + * Gutmann's X.509 style guide: + * + * Another pitfall to be aware of is that algorithms which + * have no parameters have this specified as a NULL value + * rather than omitting the parameters field entirely. The + * reason for this is that when the 1988 syntax for + * AlgorithmIdentifier was translated into the 1997 syntax, + * the OPTIONAL associated with the AlgorithmIdentifier + * parameters got lost. Later it was recovered via a defect + * report, but by then everyone thought that algorithm + * parameters were mandatory. Because of this the algorithm + * parameters should be specified as NULL, regardless of what + * you read elsewhere. + * + * The trouble is that things *never* get better, they just + * stay the same, only more so + * -- Terry Pratchett, "Eric" + * + * Although this is about signing, we always do it. Versions of + * Libksba before 1.0.6 had a bug writing out the NULL tag here, + * thus in reality we used to be correct according to the + * standards despite we didn't intended so. + */ + err = _ksba_der_store_null (n); if (err) goto leave; Modified: trunk/src/der-encoder.c =================================================================== --- trunk/src/der-encoder.c 2009-03-26 19:27:46 UTC (rev 302) +++ trunk/src/der-encoder.c 2009-05-28 08:07:16 UTC (rev 303) @@ -382,7 +382,8 @@ if (node->type == TYPE_NULL) { - return store_value (node, "", 0); + clear_value (node); + return 0; } else return gpg_error (GPG_ERR_INV_VALUE); @@ -508,6 +509,9 @@ AsnNode n; unsigned long len = 0; + if (root->type == TYPE_NULL) + return root->nhdr; + if (!(n=root->down) || _ksba_asn_is_primitive (root->type)) len = root->len; else @@ -555,9 +559,9 @@ for (n=root; n ; n = _ksba_asn_walk_tree (root, n)) { if (_ksba_asn_is_primitive (n->type) - && n->valuetype == VALTYPE_MEM - && n->value.v_mem.len - && !n->flags.is_implicit) + && !n->flags.is_implicit + && ((n->valuetype == VALTYPE_MEM && n->value.v_mem.len) + || n->type == TYPE_NULL)) set_nhdr_and_len (n, n->value.v_mem.len); } From cvs at cvs.gnupg.org Thu May 28 17:16:02 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Thu, 28 May 2009 17:16:02 +0200 Subject: [svn] gpgme - r1369 - in trunk: . doc src Message-ID: Author: marcus Date: 2009-05-28 17:16:01 +0200 (Thu, 28 May 2009) New Revision: 1369 Modified: trunk/NEWS trunk/doc/ChangeLog trunk/doc/gpgme.texi trunk/src/ChangeLog trunk/src/context.h trunk/src/gpgme.c trunk/src/gpgme.def trunk/src/gpgme.h.in trunk/src/libgpgme.vers trunk/src/version.c Log: doc/ 2009-05-28 Marcus Brinkmann * gpgme.texi (Library Version Check): Document selftest error. (Creating Contexts): Likewise. src/ 2009-05-28 Marcus Brinkmann * gpgme.h.in (gpgme_check_version_internal): New prototype. (gpgme_check_version): New macro, overriding function of the same name. * libgpgme.vers, gpgme.def: Add gpgme_check_version_internal.o * context.h (_gpgme_selftest): New variable declaration. * version.c: Include "context.h". (gpgme_check_version): Set _gpgme_selftest on success. (gpgme_check_version_internal): New function. * gpgme.c (_gpgme_selftest): Define it. (gpgme_new): Check the selftest result. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-05-18 17:38:31 UTC (rev 1368) +++ trunk/doc/ChangeLog 2009-05-28 15:16:01 UTC (rev 1369) @@ -1,3 +1,8 @@ +2009-05-28 Marcus Brinkmann + + * gpgme.texi (Library Version Check): Document selftest error. + (Creating Contexts): Likewise. + 2009-05-18 Marcus Brinkmann * gpgme.texi (Encrypting a Plaintext): Document Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-05-18 17:38:31 UTC (rev 1368) +++ trunk/src/ChangeLog 2009-05-28 15:16:01 UTC (rev 1369) @@ -1,3 +1,16 @@ +2009-05-28 Marcus Brinkmann + + * gpgme.h.in (gpgme_check_version_internal): New prototype. + (gpgme_check_version): New macro, overriding function of the same + name. + * libgpgme.vers, gpgme.def: Add gpgme_check_version_internal.o + * context.h (_gpgme_selftest): New variable declaration. + * version.c: Include "context.h". + (gpgme_check_version): Set _gpgme_selftest on success. + (gpgme_check_version_internal): New function. + * gpgme.c (_gpgme_selftest): Define it. + (gpgme_new): Check the selftest result. + 2009-05-18 Marcus Brinkmann * gpgme.h.in (gpgme_encrypt_flags_t): Add Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-05-18 17:38:31 UTC (rev 1368) +++ trunk/NEWS 2009-05-28 15:16:01 UTC (rev 1369) @@ -4,6 +4,10 @@ * New encryption flag GPGME_ENCRYPT_NO_ENCRYPT_TO to disable default recipients. + * gpgme_new will fail if gpgme_check_version was not called, or a + selftest failed (for example, if -mms-bitfields was not used on + MingW32 targets). + * Interface changes relative to the 1.1.7 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GPGME_KEYLIST_MODE_EPHEMERAL NEW. @@ -16,6 +20,8 @@ gpgme_op_assuan_result NEW. gpgme_subkey_t EXTENDED: New fields is_cardkey, card_number. GPGME_ENCRYPT_NO_ENCRYPT_TO NEW. + gpgme_check_version CHANGED: Is now a macro. + gpgme_new EXTENDED: More failure codes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Modified: trunk/doc/gpgme.texi =================================================================== --- trunk/doc/gpgme.texi 2009-05-18 17:38:31 UTC (rev 1368) +++ trunk/doc/gpgme.texi 2009-05-28 15:16:01 UTC (rev 1369) @@ -577,13 +577,13 @@ @cindex version check, of the library @deftypefun {const char *} gpgme_check_version (@w{const char *@var{required_version}}) -The function @code{gpgme_check_version} has three purposes. It can be +The function @code{gpgme_check_version} has four purposes. It can be used to retrieve the version number of the library. In addition it can verify that the version number is higher than a certain required version number. In either case, the function initializes some sub-systems, and for this reason alone it must be invoked early in your program, before you make use of the other functions in - at acronym{GPGME}. + at acronym{GPGME}. The last purpose is to run selftests. As a side effect for W32 based systems, the socket layer will get initialized. @@ -606,6 +606,11 @@ older releases, but contains additional interfaces which your program uses, this function provides a run-time check if the necessary features are provided by the installed version of the library. + +If a selftest fails, the function may still succeed. Selftest errors +are returned later when invoking @code{gpgme_new}, so that a detailed +error code can be returned (historically, @code{gpgme_check_version} +does not return a detailed error code). @end deftypefun @@ -1985,7 +1990,11 @@ The function returns the error code @code{GPG_ERR_NO_ERROR} if the context was successfully created, @code{GPG_ERR_INV_VALUE} if @var{ctx} is not a valid pointer, and @code{GPG_ERR_ENOMEM} if not -enough memory is available. +enough memory is available. Also, it returns + at code{GPG_ERR_NOT_OPERATIONAL} if @code{gpgme_check_version} was not +called to initialize GPGME, and @code{GPG_ERR_SELFTEST_FAILED} if a +selftest failed. Currently, the only selftest is for Windows MingW32 +targets to see if @code{-mms-bitfields} was used (as required). @end deftypefun Modified: trunk/src/context.h =================================================================== --- trunk/src/context.h 2009-05-18 17:38:31 UTC (rev 1368) +++ trunk/src/context.h 2009-05-28 15:16:01 UTC (rev 1369) @@ -28,6 +28,8 @@ #include "sema.h" +extern gpgme_error_t _gpgme_selftest; + /* Operations might require to remember arbitrary information and data objects during invocations of the status handler. The ctx_op_data structure provides a generic framework to hook in Modified: trunk/src/gpgme.c =================================================================== --- trunk/src/gpgme.c 2009-05-18 17:38:31 UTC (rev 1368) +++ trunk/src/gpgme.c 2009-05-28 15:16:01 UTC (rev 1369) @@ -42,6 +42,9 @@ static char *def_lc_messages; +gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL; + + /* Create a new context as an environment for GPGME crypto operations. */ gpgme_error_t @@ -50,6 +53,9 @@ gpgme_ctx_t ctx; TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx); + if (_gpgme_selftest) + return TRACE_ERR (gpgme_error (_gpgme_selftest)); + ctx = calloc (1, sizeof *ctx); if (!ctx) return TRACE_ERR (gpg_error_from_errno (errno)); Modified: trunk/src/gpgme.def =================================================================== --- trunk/src/gpgme.def 2009-05-18 17:38:31 UTC (rev 1368) +++ trunk/src/gpgme.def 2009-05-28 15:16:01 UTC (rev 1369) @@ -171,5 +171,8 @@ gpgme_op_assuan_result @132 gpgme_op_assuan_transact_start @133 gpgme_op_assuan_transact @134 + + gpgme_check_version_internal @135 + ; END Modified: trunk/src/gpgme.h.in =================================================================== --- trunk/src/gpgme.h.in 2009-05-18 17:38:31 UTC (rev 1368) +++ trunk/src/gpgme.h.in 2009-05-28 15:16:01 UTC (rev 1369) @@ -1894,9 +1894,21 @@ /* Various functions. */ -/* Check that the library fulfills the version requirement. */ +/* Check that the library fulfills the version requirement. Note: + This is here only for the case where a user takes a pointer from + the old version of this function. The new version and macro for + run-time checks are below. */ const char *gpgme_check_version (const char *req_version); +/* Check that the library fulfills the version requirement and check + for struct layout mismatch involving bitfields. */ +const char *gpgme_check_version_internal (const char *req_version, + size_t offset_sig_validity); + +#define gpgme_check_version(req_version) \ + gpgme_check_version_internal (req_version, \ + offsetof (struct _gpgme_signature, validity)) + /* Get the information about the configured and installed engines. A pointer to the first engine in the statically allocated linked list is returned in *INFO. If an error occurs, it is returned. The Modified: trunk/src/libgpgme.vers =================================================================== --- trunk/src/libgpgme.vers 2009-05-18 17:38:31 UTC (rev 1368) +++ trunk/src/libgpgme.vers 2009-05-28 15:16:01 UTC (rev 1369) @@ -51,6 +51,8 @@ gpgme_op_assuan_result; gpgme_op_assuan_transact; gpgme_op_assuan_transact_start; + + gpgme_check_version_internal; }; Modified: trunk/src/version.c =================================================================== --- trunk/src/version.c 2009-05-18 17:38:31 UTC (rev 1368) +++ trunk/src/version.c 2009-05-28 15:16:01 UTC (rev 1369) @@ -32,6 +32,7 @@ #include "gpgme.h" #include "priv-io.h" #include "debug.h" +#include "context.h" /* For _gpgme_sema_subsystem_init (). */ #include "sema.h" @@ -44,6 +45,10 @@ #include "windows.h" #endif +/* We implement this function, so we have to disable the overriding + macro. */ +#undef gpgme_check_version + /* Bootstrap the subsystems needed for concurrent operation. This must be done once at startup. We can not guarantee this using a @@ -183,6 +188,7 @@ const char * gpgme_check_version (const char *req_version) { + char *result; do_subsystem_inits (); /* Catch-22: We need to get at least the debug subsystem ready @@ -193,9 +199,41 @@ "req_version=%s, VERSION=%s", req_version? req_version:"(null)", VERSION); - return _gpgme_compare_versions (VERSION, req_version) ? VERSION : NULL; + result = _gpgme_compare_versions (VERSION, req_version) ? VERSION : NULL; + if (result != NULL) + _gpgme_selftest = 0; + + return result; } +/* Check the version and also at runtime if the struct layout of the + library matches the one of the user. This is particular useful for + Windows targets (-mms-bitfields). */ +const char * +gpgme_check_version_internal (const char *req_version, + size_t offset_sig_validity) +{ + char *result; + + TRACE2 (DEBUG_INIT, "gpgme_check_version_internal: ", 0, + "req_version=%s, offset_sig_validity=%i", + req_version ? req_version : "(null)", offset_sig_validity); + + result = gpgme_check_version (req_version); + if (result == NULL) + return result; + + if (offset_sig_validity != offsetof (struct _gpgme_signature, validity)) + { + TRACE1 (DEBUG_INIT, "gpgme_check_version_internal: ", 0, + "offset_sig_validity mismatch: expected %i", + offsetof (struct _gpgme_signature, validity)); + _gpgme_selftest = GPG_ERR_SELFTEST_FAILED; + } + + return result; +} + #define LINELENGTH 80 From cvs at cvs.gnupg.org Thu May 28 18:20:50 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Thu, 28 May 2009 18:20:50 +0200 Subject: [svn] GnuPG - r5028 - in trunk: common keyserver Message-ID: Author: dshaw Date: 2009-05-28 18:20:49 +0200 (Thu, 28 May 2009) New Revision: 5028 Modified: trunk/common/ChangeLog trunk/common/http.c trunk/common/http.h trunk/keyserver/ChangeLog trunk/keyserver/curl-shim.c trunk/keyserver/curl-shim.h trunk/keyserver/gpgkeys_curl.c trunk/keyserver/gpgkeys_hkp.c Log: Avoid caches to get the most recent copy of the key. This is bug #1061 Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-05-28 04:33:10 UTC (rev 5027) +++ trunk/common/ChangeLog 2009-05-28 16:20:49 UTC (rev 5028) @@ -1,3 +1,10 @@ +2009-05-28 David Shaw + + From 1.4: + + * http.h, http.c (send_request) Pass in a STRLIST for additional + headers. Change all callers. + 2009-05-27 David Shaw From 1.4: Modified: trunk/keyserver/ChangeLog =================================================================== --- trunk/keyserver/ChangeLog 2009-05-28 04:33:10 UTC (rev 5027) +++ trunk/keyserver/ChangeLog 2009-05-28 16:20:49 UTC (rev 5028) @@ -1,3 +1,15 @@ +2009-05-28 David Shaw + + From 1.4: + + * curl-shim.c (curl_slist_append, curl_slist_free_all): New. + Simple wrappers around strlist_t to emulate the curl way of doing + string lists. + (curl_easy_setopt): Handle the curl HTTPHEADER option. + + * gpgkeys_curl.c, gpgkeys_hkp.c (main): Avoid caches to get the + most recent copy of the key. This is bug #1061. + 2009-05-27 David Shaw From 1.4: Modified: trunk/common/http.c =================================================================== --- trunk/common/http.c 2009-05-28 04:33:10 UTC (rev 5027) +++ trunk/common/http.c 2009-05-28 16:20:49 UTC (rev 5028) @@ -128,8 +128,8 @@ static int insert_escapes (char *buffer, const char *string, const char *special); static uri_tuple_t parse_tuple (char *string); -static gpg_error_t send_request (http_t hd, const char *auth, - const char *proxy, const char *srvtag); +static gpg_error_t send_request (http_t hd, const char *auth,const char *proxy, + const char *srvtag,strlist_t headers); static char *build_rel_path (parsed_uri_t uri); static gpg_error_t parse_response (http_t hd); @@ -317,7 +317,7 @@ gpg_error_t http_open (http_t *r_hd, http_req_t reqtype, const char *url, const char *auth, unsigned int flags, const char *proxy, - void *tls_context, const char *srvtag) + void *tls_context, const char *srvtag,strlist_t headers) { gpg_error_t err; http_t hd; @@ -338,7 +338,7 @@ err = http_parse_uri (&hd->uri, url); if (!err) - err = send_request (hd, auth, proxy, srvtag); + err = send_request (hd, auth, proxy, srvtag, headers); if (err) { @@ -457,12 +457,12 @@ gpg_error_t http_open_document (http_t *r_hd, const char *document, const char *auth, unsigned int flags, const char *proxy, - void *tls_context, const char *srvtag) + void *tls_context, const char *srvtag,strlist_t headers) { gpg_error_t err; err = http_open (r_hd, HTTP_REQ_GET, document, auth, flags, - proxy, tls_context, srvtag); + proxy, tls_context, srvtag, headers); if (err) return err; @@ -835,7 +835,8 @@ * Returns 0 if the request was successful */ static gpg_error_t -send_request (http_t hd, const char *auth, const char *proxy,const char *srvtag) +send_request (http_t hd, const char *auth, + const char *proxy,const char *srvtag,strlist_t headers) { gnutls_session_t tls_session; gpg_error_t err; @@ -1051,6 +1052,17 @@ err = gpg_error_from_syserror (); else err = 0; + + if(err==0) + for(;headers;headers=headers->next) + { + if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write)) + || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write))) + { + err = gpg_error_from_syserror (); + break; + } + } } leave: @@ -1060,12 +1072,25 @@ function and only then assign a stdio stream. This allows for better error reporting that through standard stdio means. */ err = write_server (hd->sock, request, strlen (request)); + + if(err==0) + for(;headers;headers=headers->next) + { + err = write_server( hd->sock, headers->d, strlen(headers->d) ); + if(err) + break; + err = write_server( hd->sock, "\r\n", 2 ); + if(err) + break; + } + if (!err) { hd->fp_write = fdopen (hd->sock, "w"); if (!hd->fp_write) err = gpg_error_from_syserror (); } + #endif /*!HTTP_USE_ESTREAM*/ xfree (request); Modified: trunk/common/http.h =================================================================== --- trunk/common/http.h 2009-05-28 04:33:10 UTC (rev 5027) +++ trunk/common/http.h 2009-05-28 16:20:49 UTC (rev 5028) @@ -82,7 +82,8 @@ unsigned int flags, const char *proxy, void *tls_context, - const char *srvtag); + const char *srvtag, + strlist_t headers); void http_start_data (http_t hd); @@ -96,7 +97,8 @@ unsigned int flags, const char *proxy, void *tls_context, - const char *srvtag); + const char *srvtag, + strlist_t headers); #ifdef HTTP_USE_ESTREAM estream_t http_get_read_ptr (http_t hd); Modified: trunk/keyserver/curl-shim.c =================================================================== --- trunk/keyserver/curl-shim.c 2009-05-28 04:33:10 UTC (rev 5027) +++ trunk/keyserver/curl-shim.c 2009-05-28 16:20:49 UTC (rev 5028) @@ -1,7 +1,7 @@ /* curl-shim.c - Implement a small subset of the curl API in terms of * the iobuf HTTP API * - * Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -26,8 +26,8 @@ #include #include +#include "util.h" #include "http.h" -#include "util.h" #include "ksutil.h" #include "curl-shim.h" @@ -156,6 +156,9 @@ case CURLOPT_STDERR: curl->errors=va_arg(ap,FILE *); break; + case CURLOPT_HTTPHEADER: + curl->headers=va_arg(ap,struct curl_slist *); + break; default: /* We ignore the huge majority of curl options */ break; @@ -196,7 +199,8 @@ if(curl->flags.post) { rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, curl->auth, - 0, proxy, NULL, curl->srvtag); + 0, proxy, NULL, curl->srvtag, + curl->headers?curl->headers->list:NULL); if (!rc) { unsigned int post_len = strlen(curl->postfields); @@ -219,7 +223,8 @@ else { rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, curl->auth, - 0, proxy, NULL, curl->srvtag); + 0, proxy, NULL, curl->srvtag, + curl->headers?curl->headers->list:NULL); if (!rc) { rc = http_wait_response (curl->hd); @@ -350,3 +355,28 @@ return &data; } + +struct curl_slist * +curl_slist_append(struct curl_slist *list,const char *string) +{ + if(!list) + { + list=calloc(1,sizeof(*list)); + if(!list) + return NULL; + } + + add_to_strlist(&list->list,string); + + return list; +} + +void +curl_slist_free_all(struct curl_slist *list) +{ + if(list) + { + free_strlist(list->list); + free(list); + } +} Modified: trunk/keyserver/curl-shim.h =================================================================== --- trunk/keyserver/curl-shim.h 2009-05-28 04:33:10 UTC (rev 5027) +++ trunk/keyserver/curl-shim.h 2009-05-28 16:20:49 UTC (rev 5028) @@ -1,5 +1,5 @@ /* curl-shim.h - * Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This file is part of GNUPG. * @@ -20,6 +20,7 @@ #ifndef _CURL_SHIM_H_ #define _CURL_SHIM_H_ +#include "util.h" #include "http.h" typedef enum @@ -49,6 +50,7 @@ CURLOPT_POST, CURLOPT_POSTFIELDS, CURLOPT_FAILONERROR, + CURLOPT_HTTPHEADER, CURLOPT_SRVTAG_GPG_HACK } CURLoption; @@ -67,6 +69,7 @@ char *srvtag; unsigned int status; FILE *errors; + struct curl_slist *headers; struct { unsigned int post:1; @@ -96,4 +99,13 @@ #define curl_version() "GnuPG curl-shim" curl_version_info_data *curl_version_info(int type); +struct curl_slist +{ + strlist_t list; +}; + +struct curl_slist *curl_slist_append(struct curl_slist *list, + const char *string); +void curl_slist_free_all(struct curl_slist *list); + #endif /* !_CURL_SHIM_H_ */ Modified: trunk/keyserver/gpgkeys_curl.c =================================================================== --- trunk/keyserver/gpgkeys_curl.c 2009-05-28 04:33:10 UTC (rev 5027) +++ trunk/keyserver/gpgkeys_curl.c 2009-05-28 16:20:49 UTC (rev 5028) @@ -117,6 +117,7 @@ long follow_redirects=5; char *proxy=NULL; curl_version_info_data *curldata; + struct curl_slist *headers=NULL; console=stderr; @@ -305,6 +306,26 @@ curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert); curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file); + /* Avoid caches to get the most recent copy of the key. This is bug + #1061. In pre-curl versions of the code, we didn't do it. Then + we did do it (as a curl default) until curl changed the default. + Now we're doing it again, but in such a way that changing + defaults in the future won't impact us. We set both the Pragma + and Cache-Control versions of the header, so we're good with both + HTTP 1.0 and 1.1. */ + headers=curl_slist_append(headers,"Pragma: no-cache"); + if(headers) + headers=curl_slist_append(headers,"Cache-Control: no-cache"); + + if(!headers) + { + fprintf(console,"gpgkeys: out of memory when building HTTP headers\n"); + ret=KEYSERVER_NO_MEMORY; + goto fail; + } + + curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers); + if(proxy) curl_easy_setopt(curl,CURLOPT_PROXY,proxy); @@ -385,6 +406,8 @@ free_ks_options(opt); + curl_slist_free_all(headers); + if(curl) curl_easy_cleanup(curl); Modified: trunk/keyserver/gpgkeys_hkp.c =================================================================== --- trunk/keyserver/gpgkeys_hkp.c 2009-05-28 04:33:10 UTC (rev 5027) +++ trunk/keyserver/gpgkeys_hkp.c 2009-05-28 16:20:49 UTC (rev 5028) @@ -547,6 +547,7 @@ int failed=0; struct keylist *keylist=NULL,*keyptr=NULL; char *proxy=NULL; + struct curl_slist *headers=NULL; console=stderr; @@ -742,6 +743,26 @@ curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert); curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file); + /* Avoid caches to get the most recent copy of the key. This is bug + #1061. In pre-curl versions of the code, we didn't do it. Then + we did do it (as a curl default) until curl changed the default. + Now we're doing it again, but in such a way that changing + defaults in the future won't impact us. We set both the Pragma + and Cache-Control versions of the header, so we're good with both + HTTP 1.0 and 1.1. */ + headers=curl_slist_append(headers,"Pragma: no-cache"); + if(headers) + headers=curl_slist_append(headers,"Cache-Control: no-cache"); + + if(!headers) + { + fprintf(console,"gpgkeys: out of memory when building HTTP headers\n"); + ret=KEYSERVER_NO_MEMORY; + goto fail; + } + + curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers); + if(proxy) curl_easy_setopt(curl,CURLOPT_PROXY,proxy); @@ -919,6 +940,8 @@ free_ks_options(opt); + curl_slist_free_all(headers); + if(curl) curl_easy_cleanup(curl);