--- pgp/src/keyadd.c 2018/04/24 16:40:30 1.1.1.4 +++ pgp/src/keyadd.c 2018/04/24 16:42:39 1.1.1.6 @@ -1,21 +1,22 @@ /* keyadd.c - Keyring merging routines for PGP. PGP: Pretty Good(tm) Privacy - public key cryptography for the masses. - (c) Copyright 1990-1992 by Philip Zimmermann. All rights reserved. + (c) Copyright 1990-1994 by Philip Zimmermann. All rights reserved. The author assumes no liability for damages resulting from the use of this software, even if the damage results from defects in this software. No warranty is expressed or implied. - All the source code Philip Zimmermann wrote for PGP is available for - free under the "Copyleft" General Public License from the Free - Software Foundation. A copy of that license agreement is included in - the source release package of PGP. Code developed by others for PGP - is also freely available. Other code that has been incorporated into - PGP from other sources was either originally published in the public - domain or was used with permission from the various authors. See the - PGP User's Guide for more complete information about licensing, - patent restrictions on certain algorithms, trademarks, copyrights, - and export controls. + Note that while most PGP source modules bear Philip Zimmermann's + copyright notice, many of them have been revised or entirely written + by contributors who frequently failed to put their names in their + code. Code that has been incorporated into PGP from other authors + was either originally published in the public domain or is used with + permission from the various authors. + + PGP is available for free to the public under certain restrictions. + See the PGP User's Guide (included in the release package) for + important information about licensing, patent restrictions on + certain algorithms, trademarks, copyrights, and export controls. */ #include @@ -29,6 +30,7 @@ #include "fileio.h" #include "keymgmt.h" #include "charset.h" +#include "mpiio.h" #include "language.h" #include "pgp.h" #include "exitpgp.h" @@ -48,6 +50,38 @@ static boolean publickey; /* if TRUE, ad static int newkeys, newsigs, newids, newrvks; static byte mykeyID[KEYFRAGSIZE]; +static struct sig_list { + struct sig_list *next; + long pos; +} *siglist; +static void +sig_list_add(long pos) +{ + struct sig_list *p; + p = xmalloc(sizeof *p); + p->pos = pos; + p->next = siglist; + siglist = p; +} +static int +sig_list_find(long pos) +{ + struct sig_list *p; + for (p = siglist; p; p = p->next) + if (p->pos == pos) + return 1; + return 0; +} +static void +sig_list_clear(void) +{ + struct sig_list *p, *n; + for (p = siglist; p; p = n) { + n = p->next; + free(p); + } + siglist = NULL; +} static int mergesigs (FILE *fkey, char *keyfile, long keypos, FILE *fring, char *ringfile, long *pringpos, FILE *out) /* Merge signatures from userid in fkey (which is keyfile) at keypos with @@ -59,6 +93,7 @@ static int mergesigs (FILE *fkey, char * int status; byte ctb; int copying; + word32 rstamp, kstamp, xstamp; byte keyID[KEYFRAGSIZE]; char userid[256]; @@ -70,8 +105,8 @@ static int mergesigs (FILE *fkey, char * PascalToC(userid); ringpktlen = ftell(fring) - ringpos; copyfilepos (fring, out, ringpktlen, ringpos); - for ( ; ; ) - { ringpos = ftell(fring); + for (;;) { + ringpos = ftell(fring); status = nextkeypacket (fring, &ctb); if (status < 0 || is_key_ctb(ctb) || ctb==CTB_USERID || is_ctb_type(ctb,CTB_SKE_TYPE)) @@ -85,8 +120,8 @@ static int mergesigs (FILE *fkey, char * /* Advance keypos to the analogous location. */ fseek (fkey, keypos, SEEK_SET); (void) nextkeypacket (fkey, &ctb); - for ( ; ; ) - { keypos = ftell(fkey); + for (;;) { + keypos = ftell(fkey); status = nextkeypacket (fkey, &ctb); if (status < 0 || is_key_ctb(ctb) || ctb==CTB_USERID || is_ctb_type(ctb,CTB_SKE_TYPE)) @@ -98,63 +133,116 @@ static int mergesigs (FILE *fkey, char * */ copying = FALSE; - for ( ; ; ) - { /* Read next sig from keyfile; see if it is in ringfile; - * set copying true/false accordingly. If copying is true - * and it is a signature, copy it. Loop till hit - * a new key or userid in keyfile, or EOF. + for (;;) { + /* Read next sig from keyfile; see if it is in ringfile; + * if it is not a signature, ignore it, + * if it is absent from ringfile, copy it, + * if it is present, and the timestamp is not newer, ignore it, + * if present and newer, replace old with new. + * Loop till hit a new key or userid in keyfile, or EOF. */ keypos = ftell(fkey); - status = readkeypacket(fkey,FALSE,&ctb,NULL,NULL,NULL,NULL, + status = readkeypacket(fkey,FALSE,&ctb,(byte *)&kstamp,NULL,NULL,NULL, NULL,NULL,NULL,NULL,keyID,NULL); if (status == -3) /* unrecoverable error: bad packet length etc. */ - return(status); + return status; keypktlen = ftell(fkey) - keypos; if (status == -1 || is_key_ctb (ctb) || ctb==CTB_USERID) break; /* EOF or next key/userid */ if (status < 0) continue; /* bad packet, skip it */ - if (is_ctb_type(ctb,CTB_SKE_TYPE)) - { long sig_pos; + if (is_ctb_type(ctb,CTB_SKE_TYPE)) { + long sig_pos; int sig_len; /* Set copying true if signature is not in the ringfile */ - copying = (getpubusersig (ringfile, ringuseridpos, keyID, &sig_pos, - &sig_len) < 0); - if (copying) - { char *signator; + copying = (getpubusersig (ringfile, ringuseridpos, + keyID, (byte *)&rstamp, + &sig_pos, + &sig_len) < 0); + if (!copying) { + long save_pos = ftell(fkey); + fseek(fkey, keypos+6, SEEK_SET); + fread(&kstamp,1,SIZEOF_TIMESTAMP,fkey); + fseek(fkey, save_pos, SEEK_SET); + convert_byteorder((byte *)&kstamp,SIZEOF_TIMESTAMP); + if (verbose) + fprintf(pgpout, "ring: %lx key: %lx\n", rstamp, kstamp); + if (kstamp > rstamp) { /* Update, Maybe*/ + char *signator; + if ((signator = user_from_keyID(keyID)) == NULL) { + fprintf(pgpout, LANG("Replacing signature from keyID %s on userid \"%s\"\n"), keyIDstring(keyID), LOCAL_CHARSET(userid)); + /* No pubkey for KeyID, no update! */ + } else { + long save_keypos; + long save_ringpos; + long KeyIDpos, KeyIDlen; + byte sigClass; + fprintf(pgpout, LANG("Verifying signature from %s\n"), LOCAL_CHARSET(signator)); + fprintf(pgpout, LANG("on userid \"%s\"\n"), LOCAL_CHARSET(userid)); + save_keypos = ftell(fkey); + save_ringpos = ftell(fring); + status = getpublickey(GPK_GIVEUP, ringfile, &KeyIDpos, &KeyIDlen, NULL, NULL, userid, NULL, NULL); + if (!status) + status = check_key_sig (fring, KeyIDpos, KeyIDlen, userid, fkey, keypos, ringfile, signator, (byte *)&xstamp, &sigClass); + PascalToC(userid); + PascalToC(signator); + if (!status) { + fprintf(pgpout, LANG("Replacing signature from %s\n"), LOCAL_CHARSET(signator)); + fprintf(pgpout, LANG("on userid \"%s\"\n"), LOCAL_CHARSET(userid)); + sig_list_add(sig_pos); + ++newsigs; + copying = 1; + } else + fprintf(pgpout, LANG("Verification Failed\n")); + fseek(fring, save_ringpos, SEEK_SET); + fseek(fkey, save_keypos, SEEK_SET); + } + } + } else { + char *signator; if ((signator = user_from_keyID(keyID)) == NULL) - fprintf(pgpout, PSTR("New signature from keyID %s on userid \"%s\"\n"), + fprintf(pgpout, LANG("New signature from keyID %s on userid \"%s\"\n"), keyIDstring(keyID), LOCAL_CHARSET(userid)); - else - { - fprintf(pgpout, PSTR("New signature from %s\n"), LOCAL_CHARSET(signator)); - fprintf(pgpout, PSTR("on userid \"%s\"\n"), LOCAL_CHARSET(userid)); + else { + + fprintf(pgpout, LANG("New signature from %s\n"), LOCAL_CHARSET(signator)); + fprintf(pgpout, LANG("on userid \"%s\"\n"), LOCAL_CHARSET(userid)); } ++newsigs; if (batchmode) show_update(keyIDstring(mykeyID)); } } - if (copying && is_ctb_type(ctb,CTB_SKE_TYPE)) - { copyfilepos (fkey, out, keypktlen, keypos); + if (copying && is_ctb_type(ctb,CTB_SKE_TYPE)) { + copyfilepos (fkey, out, keypktlen, keypos); if (publickey) write_trust (out, KC_SIGTRUST_UNDEFINED); } } - /* Third, for all ring sig's, copy to output */ + /* Third, for all ring sig's which are not replaced, copy to output */ fseek (fring, ringpos, SEEK_SET); - for ( ; ; ) - { ringpos = ftell(fring); + for (;;) { + ringpos = ftell(fring); + if (sig_list_find(ringpos)) { + /* skip signature packet */ + nextkeypacket (fring, &ctb); + ringpos = ftell(fring); + /* skip trust packet, if present */ + if (nextkeypacket (fring, &ctb) < 0 || ctb != CTB_KEYCTRL) + fseek(fring, ringpos, SEEK_SET); + continue; + } status = nextkeypacket (fring, &ctb); ringpktlen = ftell(fring) - ringpos; if (status < 0 || is_key_ctb (ctb) || ctb==CTB_USERID) break; copyfilepos (fring, out, ringpktlen, ringpos); - } /* End of loop for each sig in ringfile */ + } /* End of loop for each sig in ringfile */ + sig_list_clear(); fseek (fring, ringpos, SEEK_SET); *pringpos = ringpos; - return(0); + return 0; } /* mergesigs */ @@ -178,8 +266,8 @@ static int mergekeys (FILE *fkey, char * (void) nextkeypacket(fring, &ctb); ringpktlen = ftell(fring) - ringpos; copyfilepos (fring, out, ringpktlen, ringpos); - for ( ; ; ) - { ringpos = ftell(fring); + for (;;) { + ringpos = ftell(fring); status = nextkeypacket (fring, &ctb); if (status < 0 || is_key_ctb(ctb) || ctb==CTB_USERID) break; @@ -196,14 +284,14 @@ static int mergekeys (FILE *fkey, char * keykeypos = keypos; (void) nextkeypacket (fkey, &ctb); keypktlen = ftell(fkey) - keypos; /* for check_key_sig() */ - for ( ; ; ) - { keypos = ftell(fkey); + for (;;) { + keypos = ftell(fkey); status = nextkeypacket (fkey, &ctb); if (status < 0 || ctb == CTB_USERID || is_ctb_type(ctb, CTB_SKE_TYPE)) break; } - if (!ring_compromise && is_ctb_type(ctb, CTB_SKE_TYPE)) - { /* found a compromise cert on keyfile that is not in ringfile */ + if (!ring_compromise && is_ctb_type(ctb, CTB_SKE_TYPE)) { + /* found a compromise cert on keyfile that is not in ringfile */ word32 timestamp; byte sig_class; int cert_pktlen; @@ -214,7 +302,7 @@ static int mergekeys (FILE *fkey, char * sig_class == KC_SIGNATURE_BYTE) { PascalToC((char *)userid); - fprintf(pgpout, PSTR("Key revocation certificate from \"%s\".\n"), + fprintf(pgpout, LANG("Key revocation certificate from \"%s\".\n"), LOCAL_CHARSET((char *)userid)); copyfilepos (fkey, out, cert_pktlen, keypos); /* Show updates */ @@ -223,7 +311,7 @@ static int mergekeys (FILE *fkey, char * ++newrvks; } else - fprintf(pgpout, PSTR("\n\007WARNING: File '%s' contains bad revocation certificate.\n"), keyfile); + fprintf(pgpout, LANG("\n\007WARNING: File '%s' contains bad revocation certificate.\n"), keyfile); } fseek (fkey, keypos, SEEK_SET); @@ -232,36 +320,36 @@ static int mergekeys (FILE *fkey, char * */ copying = FALSE; - for ( ; ; ) - { /* Read next userid from keyfile; see if it is in ringfile; + for (;;) { + /* Read next userid from keyfile; see if it is in ringfile; * set copying true/false accordingly. If copying is true * and it is a userid or a signature, copy it. Loop till hit * a new key in keyfile, or EOF. */ keypos = ftell(fkey); - status = readkeypacket(fkey,FALSE,&ctb,NULL,(char *)userid,NULL,NULL, - NULL,NULL,NULL,NULL,NULL,NULL); - if (status == -3) /* unrecoverable error: bad packet length etc. */ - return(status); + status = readkeypacket(fkey,FALSE,&ctb,NULL,(char *)userid,NULL, + NULL, NULL,NULL,NULL,NULL,NULL,NULL); + if (status == -3) /* unrecoverable error: bad packet length etc. */ + return status; keypktlen = ftell(fkey) - keypos; if (status == -1 || is_key_ctb (ctb)) break; /* EOF or next key */ if (status < 0) continue; /* bad packet, skip it */ - if (ctb == CTB_USERID) - { long userid_pos; + if (ctb == CTB_USERID) { + long userid_pos; int userid_len; PascalToC ((char *)userid); /* Set copying true if userid is not in the ringfile */ copying = (getpubuserid (ringfile, ringkeypos, userid, &userid_pos, &userid_len, TRUE) < 0); - if (copying) - { putc('\n', pgpout); - fprintf (pgpout, PSTR("New userid: \"%s\".\n"), + if (copying) { + putc('\n', pgpout); + fprintf (pgpout, LANG("New userid: \"%s\".\n"), LOCAL_CHARSET((char *)userid)); - fprintf(pgpout, PSTR("\nWill be added to the following key:\n")); + fprintf(pgpout, LANG("\nWill be added to the following key:\n")); show_key(fring, *pringpos, 0); - fprintf(pgpout, PSTR("\nAdd this userid (y/N)? ")); + fprintf(pgpout, LANG("\nAdd this userid (y/N)? ")); if (batchmode || getyesno('n')) { ++newids; /* Show an update string */ @@ -269,14 +357,15 @@ static int mergekeys (FILE *fkey, char * fprintf(pgpout, "\n"); show_key(fring, *pringpos, SHOW_CHANGE); } - } - else + } else { copying = FALSE; + } } } - if (copying) - { if (ctb==CTB_USERID || is_ctb_type(ctb,CTB_SKE_TYPE)) - { copyfilepos (fkey, out, keypktlen, keypos); + if (copying) { + if (ctb==CTB_USERID || is_ctb_type(ctb,CTB_SKE_TYPE)) + { + copyfilepos (fkey, out, keypktlen, keypos); if (publickey) { if (is_ctb_type(ctb,CTB_SKE_TYPE)) write_trust (out, KC_SIGTRUST_UNDEFINED); @@ -295,44 +384,46 @@ static int mergekeys (FILE *fkey, char * readkeypacket(fring,FALSE,&ctb,NULL,(char *)userid,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL); fseek (fring, ringpos, SEEK_SET); - for ( ; ; ) - { ringpos = ftell(fring); + for (;;) { + ringpos = ftell(fring); status = readkeypacket(fring,FALSE,&ctb,NULL,(char *)userid,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL); ringpktlen = ftell(fring) - ringpos; if (status == -3) - return(status); + return status; if (status == -1 || is_key_ctb (ctb)) break; - if (ctb == CTB_USERID) - { long userid_pos; + if (ctb == CTB_USERID) { + long userid_pos; int userid_len; /* See if there is a match in keyfile */ PascalToC ((char *) userid); /* don't use substring match (exact_match = TRUE) */ - if (getpubuserid (keyfile, keykeypos, userid, &userid_pos, - &userid_len, TRUE) >= 0) - { if ((status = mergesigs (fkey,keyfile,userid_pos,fring,ringfile,&ringpos,out)) < 0) - return(status); + if (getpubuserid (keyfile, keykeypos, userid, + &userid_pos, &userid_len, TRUE) >= 0) + { + if ((status = mergesigs (fkey,keyfile,userid_pos,fring,ringfile,&ringpos,out)) < 0) + return status; copying = FALSE; - } - else + } else { copying = TRUE; + } } - if (copying) - { /* Copy ringfile userid and sigs to out */ + if (copying) { + /* Copy ringfile userid and sigs to out */ copyfilepos (fring, out, ringpktlen, ringpos); } - } /* End of loop for each key in ringfile */ + } /* End of loop for each key in ringfile */ fseek (fring, ringpos, SEEK_SET); *pringpos = ringpos; - return(0); + return 0; } /* mergekeys */ int _addto_keyring(char *keyfile, char *ringfile) -/* Adds (prepends) key file to key ring file. */ -{ FILE *f, *g, *h; +/* Adds (prepends) key file to key ring file. */ +{ + FILE *f, *g, *h; long file_position,fp; int pktlen; byte ctb; @@ -342,24 +433,21 @@ int _addto_keyring(char *keyfile, char * byte keyID[KEYFRAGSIZE]; byte userid[256]; /* key certificate userid */ byte userid1[256]; - word32 tstamp; byte *timestamp = (byte *) &tstamp; /* key certificate timestamp */ + word32 tstamp; + byte *timestamp = (byte *) &tstamp; /* key certificate timestamp */ boolean userid_seen = FALSE; int commonkeys = 0; int copying; - struct nkey { - byte keyID[KEYFRAGSIZE]; - struct nkey *next; - } *nkey, *nkeys = NULL; + struct newkey *nkey, *nkeys = NULL; char *scratchf; /* open file f for read, in binary (not text) mode...*/ - if ((f = fopen(keyfile,FOPRBIN)) == NULL) - { fprintf(pgpout,PSTR("\n\007Can't open key file '%s'\n"),keyfile); + if ((f = fopen(keyfile,FOPRBIN)) == NULL) { + fprintf(pgpout,LANG("\n\007Can't open key file '%s'\n"),keyfile); return -1; } ctb = 0; - if (fread(&ctb, 1, 1, f) != 1 || !is_key_ctb(ctb)) - { + if (fread(&ctb, 1, 1, f) != 1 || !is_key_ctb(ctb)) { fclose(f); return -1; } @@ -376,12 +464,12 @@ int _addto_keyring(char *keyfile, char * setkrent(keyfile); init_userhash(); - if (!file_exists(ringfile)) - { /* ringfile does not exist. Can it be created? */ + if (!file_exists(ringfile)) { + /* ringfile does not exist. Can it be created? */ /* open file g for writing, in binary (not text) mode...*/ g = fopen(ringfile,FOPWBIN); - if (g==NULL) - { fprintf(pgpout,PSTR("\nKey ring file '%s' cannot be created.\n"),ringfile); + if (g==NULL) { + fprintf(pgpout,LANG("\nKey ring file '%s' cannot be created.\n"),ringfile); fclose(f); goto err; } @@ -390,115 +478,108 @@ int _addto_keyring(char *keyfile, char * /* Create working output file */ /* open file g for writing, in binary (not text) mode...*/ - if ((g = fopen(scratchf,FOPWBIN)) == NULL) - { fclose(f); + if ((g = fopen(scratchf,FOPWBIN)) == NULL) { + fclose(f); goto err; } newkeys = newsigs = newids = newrvks = 0; /* Pass 1 - copy all keys from f which aren't in ring file */ /* Also copy userid and signature packets. */ - fprintf(pgpout, PSTR("\nLooking for new keys...\n")); + fprintf(pgpout, LANG("\nLooking for new keys...\n")); copying = FALSE; - if (gpk_open(ringfile) < 0) - { fclose(f); /* close key file */ + if (gpk_open(ringfile) < 0) { + fclose(f); /* close key file */ fclose(g); goto err; } - for ( ; ; ) - { file_position = ftell(f); + for (;;) { + file_position = ftell(f); status = readkeypacket(f,FALSE,&ctb,timestamp,(char *)userid,n,e, NULL,NULL,NULL,NULL,NULL,NULL); /* Note that readkeypacket has called set_precision */ if (status == -1) /* EOF */ break; - if (status == -2 || status == -3) - { fprintf(pgpout,PSTR("\n\007Could not read key from file '%s'.\n"), + if (status == -2 || status == -3) { + fprintf(pgpout,LANG("\n\007Could not read key from file '%s'.\n"), keyfile); fclose(f); /* close key file */ fclose(g); goto err; } - if (status < 0) - { + if (status < 0) { copying = FALSE; continue; /* don't merge keys from unrecognized version */ } /* Check to see if key is already on key ring */ - if (is_key_ctb(ctb)) - { + if (is_key_ctb(ctb)) { extract_keyID(keyID, n); /* from keyfile, not ringfile */ publickey = is_ctb_type(ctb, CTB_CERT_PUBKEY_TYPE); /* Check for duplicate key in key ring: */ status = get_publickey(&fp, NULL, keyID, timestamp, userid, n1, e); - if (status == 0) /* key in both keyring and keyfile */ - { if (mp_compare (n, n1) != 0) - { fprintf(pgpout, PSTR("\n\007Warning: Key ID %s matches key ID of key already on \n\ + if (status == 0) { + /* key in both keyring and keyfile */ + if (mp_compare (n, n1) != 0) { + fprintf(pgpout, LANG("\n\007Warning: Key ID %s matches key ID of key already on \n\ key ring '%s', but the keys themselves differ.\n\ This is highly suspicious. This key will not be added to ring.\n\ Acknowledge by pressing return: "), keyIDstring(keyID), ringfile); getyesno('n'); - } - else + } else { ++commonkeys; + } copying = FALSE; - } - else if (status == -1) /* key NOT in keyring */ - { + } else if (status == -1) { /* key NOT in keyring */ ++newkeys; - if (interactive_add) - { show_key(f, file_position, SHOW_ALL); - fprintf(pgpout, PSTR("\nDo you want to add this key to keyring '%s' (y/N)? "), ringfile); + if (interactive_add) { + show_key(f, file_position, SHOW_ALL); + fprintf(pgpout, LANG("\nDo you want to add this key to keyring '%s' (y/N)? "), ringfile); copying = getyesno('n'); - } - else - { - show_key(f, file_position, SHOW_LISTFMT); + } else { + show_key(f,file_position,SHOW_LISTFMT); copying = TRUE; } /* If batchmode, output an update message */ if (batchmode) show_key(f, file_position, SHOW_CHANGE); - if (copying) - { - nkey = xmalloc(sizeof(struct nkey)); + if (copying) { + nkey = xmalloc(sizeof(*nkey)); memcpy(nkey->keyID, keyID, KEYFRAGSIZE); nkey->next = nkeys; nkeys = nkey; } - } - else /* unknown version or bad key */ + } else { + /* unknown version or bad key */ copying = FALSE; + } } - /* Now, we copy according to the copying flag */ - /* The key is prepended to the ring to give it search precedence - over other keys with that same userid. */ - + /* + * Now, we copy according to the copying flag + * The key is prepended to the ring to give it search + * precedence over other keys with that same userid. + */ if (copying && (is_key_ctb(ctb) || ctb==CTB_USERID || - is_ctb_type(ctb,CTB_SKE_TYPE))) - { pktlen = (int) (ftell(f) - file_position); + is_ctb_type(ctb,CTB_SKE_TYPE))) + { + pktlen = (int) (ftell(f) - file_position); copyfilepos(f,g,pktlen,file_position); /* copy packet from f */ - if (publickey) - { /* Initialize trust packets after keys and signatures */ - if (is_key_ctb(ctb)) - { - write_trust (g, KC_OWNERTRUST_UNDEFINED); + if (publickey) { + /* Initialize trust packets after keys and signatures */ + if (is_key_ctb(ctb)) { + write_trust(g, KC_OWNERTRUST_UNDEFINED); userid_seen = FALSE; - } - else if (is_ctb_type(ctb,CTB_SKE_TYPE)) - { - if (userid_seen) + } else if (is_ctb_type(ctb,CTB_SKE_TYPE)) { + if (userid_seen) { write_trust (g, KC_SIGTRUST_UNDEFINED); - else - /* signature certificate before userid must be compromise cert. */ - fprintf(pgpout, PSTR("Key has been revoked.\n")); - } - else if (is_ctb_type(ctb,CTB_USERID_TYPE)) - { + } else { + /* signature certificate before userid must be compromise cert. */ + fprintf(pgpout, LANG("Key has been revoked.\n")); + } + } else if (is_ctb_type(ctb,CTB_USERID_TYPE)) { write_trust (g, KC_LEGIT_UNKNOWN); userid_seen = TRUE; } @@ -507,28 +588,29 @@ Acknowledge by pressing return: "), keyI } gpk_close(); - /* Now copy the remainder of the ringfile, h, to g. commonkeys tells - how many keys are common to keyfile and ringfile. As long as that is - nonzero we will check each key in ringfile to see if it has a match - in keyfile. - */ - if ((h = fopen(ringfile,FOPRBIN)) != NULL) - { - if (gpk_open(keyfile) < 0) - { fclose(f); + /* + * Now copy the remainder of the ringfile, h, to g. commonkeys tells + * how many keys are common to keyfile and ringfile. As long as that + * is nonzero we will check each key in ringfile to see if it has a + * match in keyfile. + */ + if ((h = fopen(ringfile,FOPRBIN)) != NULL) { + if (gpk_open(keyfile) < 0) { + fclose(f); fclose(g); fclose(h); goto err; } - while (commonkeys) /* Loop for each key in ringfile */ - { file_position = ftell(h); + while (commonkeys) { + /* Loop for each key in ringfile */ + file_position = ftell(h); status = readkeypacket(h,FALSE,&ctb,NULL,(char *)userid,n,e, - NULL,NULL,NULL,NULL,NULL,NULL); - if (status == -1 || status == -3) - { if (status == -1) /* hit EOF */ - fprintf(pgpout, PSTR("\n\007Key file contains duplicate keys: cannot be added to keyring\n")); + NULL,NULL,NULL,NULL,NULL,NULL); + if (status == -1 || status == -3) { + if (status == -1) /* hit EOF */ + fprintf(pgpout, LANG("\n\007Key file contains duplicate keys: cannot be added to keyring\n")); else - fprintf(pgpout,PSTR("\n\007Could not read key from file '%s'.\n"), + fprintf(pgpout,LANG("\n\007Could not read key from file '%s'.\n"), ringfile); fclose(f); fclose(g); @@ -537,12 +619,11 @@ Acknowledge by pressing return: "), keyI } PascalToC ((char *) userid); pktlen = ftell(h) - file_position; - if (is_key_ctb(ctb)) - { long tfp; + if (is_key_ctb(ctb)) { + long tfp; /* unknown version or bad data: copy (don't remove packets from ringfile) */ copying = TRUE; - if (status == 0) - { + if (status == 0) { /* See if there is a match in keyfile */ extract_keyID(keyID, n); /* from ringfile, not keyfile */ extract_keyID(mykeyID, n); /* save this */ @@ -552,7 +633,8 @@ Acknowledge by pressing return: "), keyI if (verbose) fprintf (pgpout, "Merging key ID: %s\n",keyIDstring(keyID)); if (mergekeys (f,keyfile,tfp, h,ringfile,&file_position, g) < 0) - { fclose(f); + { + fclose(f); fclose(g); fclose(h); goto err; @@ -562,8 +644,8 @@ Acknowledge by pressing return: "), keyI } } } - if (copying) - { /* Copy ringfile key to g, without its sigs */ + if (copying) { + /* Copy ringfile key to g, without its sigs */ copyfilepos (h,g,pktlen,file_position); file_position += pktlen; } @@ -573,61 +655,57 @@ Acknowledge by pressing return: "), keyI fclose(h); } fclose(f); - if (write_error(g)) - { fclose(g); + if (write_error(g)) { + fclose(g); goto err; } fclose(g); - if (newsigs == 0 && newkeys == 0 && newids == 0 && newrvks == 0) - { - fprintf(pgpout, PSTR("No new keys or signatures in keyfile.\n")); + if (newsigs == 0 && newkeys == 0 && newids == 0 && newrvks == 0) { + fprintf(pgpout, LANG("No new keys or signatures in keyfile.\n")); rmtemp(scratchf); endkrent(); - return(0); + return 0; } - if (status = dokeycheck(NULL, scratchf, CHECK_NEW)) - { if (verbose) + if (status = dokeycheck(NULL, scratchf, CHECK_NEW)) { + if (verbose) fprintf(pgpout, "addto_keyring: dokeycheck returned %d\n", status); goto err; } endkrent(); - fprintf(pgpout, PSTR("\nKeyfile contains:\n")); + fprintf(pgpout, LANG("\nKeyfile contains:\n")); if (newkeys) - fprintf(pgpout, PSTR("%4d new key(s)\n"), newkeys); + fprintf(pgpout, LANG("%4d new key(s)\n"), newkeys); if (newsigs) - fprintf(pgpout, PSTR("%4d new signatures(s)\n"), newsigs); + fprintf(pgpout, LANG("%4d new signatures(s)\n"), newsigs); if (newids) - fprintf(pgpout, PSTR("%4d new user ID(s)\n"), newids); + fprintf(pgpout, LANG("%4d new user ID(s)\n"), newids); if (newrvks) - fprintf(pgpout, PSTR("%4d new revocation(s)\n"), newrvks); + fprintf(pgpout, LANG("%4d new revocation(s)\n"), newrvks); ask_first = TRUE; - if ((status = maint_update(scratchf)) >= 0 && !filter_mode && !batchmode) + status = maint_update(scratchf, nkeys); + if (status >= 0 && !filter_mode && !batchmode) for (nkey = nkeys; nkey; nkey = nkey->next) if (ask_to_sign(nkey->keyID, scratchf) != 0) break; if (status && verbose) fprintf(pgpout, "addto_keyring: maint_update returned %d\n", status); - for (nkey = nkeys; nkey; ) - { nkey = nkey->next; - free(nkeys); - nkeys = nkey; - } + free_newkeys(nkeys); savetempbak(scratchf,ringfile); - return(0); /* normal return */ + return 0; /* normal return */ err: gpk_close(); /* save to call if not opened */ endkrent(); /* make sure we remove any garbage files we may have created */ rmtemp(scratchf); - return(-1); -} /* addto_keyring */ + return -1; +} /* addto_keyring */ int addto_keyring(char *keyfile, char *ringfile) @@ -639,24 +717,22 @@ int addto_keyring(char *keyfile, char *r if (_addto_keyring(keyfile, ringfile) == 0) return 0; /* check if the keyfile to be added is armored */ - while (is_armor_file(keyfile,armorline)) - { + while (is_armor_file(keyfile,armorline)) { tempf = tempfile(TMP_TMPDIR|TMP_WIPE); - if (de_armor_file(keyfile,tempf,&armorline)) - { rmtemp(tempf); + if (de_armor_file(keyfile,tempf,&armorline)) { + rmtemp(tempf); return -1; } if (_addto_keyring(tempf, ringfile) == 0) addflag = 1; rmtemp(tempf); } - if (!addflag) - { - fprintf(pgpout, PSTR("\nNo keys found in '%s'.\n"), keyfile); + if (!addflag) { + fprintf(pgpout, LANG("\nNo keys found in '%s'.\n"), keyfile); return -1; - } - else + } else { return 0; + } } @@ -673,48 +749,45 @@ static int ask_to_sign(byte *keyID, char if (getpublickey(GPK_GIVEUP, ringfile, &fpos, NULL, keyID, (byte *)×tamp, userid, n, e) < 0) - return(-1); + return -1; if ((f = fopen(ringfile, FOPRBIN)) == NULL) - return(-1); + return -1; fseek(f, fpos, SEEK_SET); - if (is_compromised(f)) - { fclose(f); - return(0); - } - if (nextkeypacket(f, &ctb) < 0) - { fclose(f); - return(-1); - } - if (ctb != CTB_CERT_PUBKEY) - { fclose(f); - return(0); /* don't ask to sign secret key */ + if (is_compromised(f)) { + fclose(f); + return 0; + } + if (nextkeypacket(f, &ctb) < 0) { + fclose(f); + return -1; + } + if (ctb != CTB_CERT_PUBKEY) { + fclose(f); + return 0; /* don't ask to sign secret key */ } while (nextkeypacket(f, &ctb) == 0 && !is_key_ctb(ctb)) if (ctb == CTB_USERID) /* check first userid */ break; - if (ctb != CTB_USERID) - { + if (ctb != CTB_USERID) { fclose(f); - return(-1); + return -1; } - if ((status = read_trust(f, &trust)) < 0) - { + if ((status = read_trust(f, &trust)) < 0) { fclose(f); - return(status); + return status; } - if ((trust & KC_LEGIT_MASK) == KC_LEGIT_COMPLETE) - { + if ((trust & KC_LEGIT_MASK) == KC_LEGIT_COMPLETE) { fclose(f); - return(0); + return 0; } - if (ask_first) /* shortcut for adding big keyfile */ - { fprintf(pgpout, PSTR("\nOne or more of the new keys are not fully certified.\n\ + if (ask_first) { + /* shortcut for adding big keyfile */ + fprintf(pgpout, LANG("\nOne or more of the new keys are not fully certified.\n\ Do you want to certify any of these keys yourself (y/N)? ")); - if (!getyesno('n')) - { + if (!getyesno('n')) { fclose(f); return 1; } @@ -723,13 +796,12 @@ Do you want to certify any of these keys show_key(f, fpos, SHOW_ALL|SHOW_HASH); fclose(f); PascalToC((char *)userid); - fprintf(pgpout, PSTR("\nDo you want to certify this key yourself (y/N)? ")); - if (getyesno('n')) - { + fprintf(pgpout, LANG("\nDo you want to certify this key yourself (y/N)? ")); + if (getyesno('n')) { if (signkey((char *)userid, my_name, ringfile) == 0) - maint_update(ringfile); + maint_update(ringfile, 0); } - return(0); + return 0; } @@ -746,8 +818,8 @@ static FILE *gpkf = NULL; * is set with gpk_open(). * only searches on keyID */ -int get_publickey(long *file_position, int *pktlen, byte *keyID, byte *timestamp, - byte *userid, unitptr n, unitptr e) +int get_publickey(long *file_position, int *pktlen, byte *keyID, + byte *timestamp, byte *userid, unitptr n, unitptr e) { byte ctb; /* returned by readkeypacket */ int status, keystatus = -1; @@ -757,19 +829,18 @@ int get_publickey(long *file_position, i return -1; fseek(gpkf, fpos, SEEK_SET); - while (TRUE) - { + for (;;) { fpos = ftell(gpkf); status = readkeypacket(gpkf,FALSE,&ctb,timestamp,(char *)userid,n,e, NULL,NULL,NULL,NULL,NULL,NULL); /* Note that readkeypacket has called set_precision */ if (status < 0 && status != -4 && status != -6) - return(status); + return status; /* Remember packet position and size for last key packet */ - if (is_key_ctb(ctb)) - { if (file_position) + if (is_key_ctb(ctb)) { + if (file_position) *file_position = fpos; if (pktlen) *pktlen = (int)(ftell(gpkf) - fpos); @@ -779,8 +850,7 @@ int get_publickey(long *file_position, i } if (ctb == CTB_USERID) return keystatus; - } /* while TRUE */ - return -1; + } } #define PK_HASHSIZE 256 /* must be power of 2 */ @@ -812,19 +882,19 @@ gpk_open(char *keyfile) } default_extension(keyfile,PGP_EXTENSION); if ((gpkf = fopen(keyfile,FOPRBIN)) == NULL) - return(-1); /* error return */ + return -1; /* error return */ hashtbl = allocbuf(PK_HASHSIZE * sizeof(struct hashent *)); memset(hashtbl, 0, PK_HASHSIZE * sizeof(struct hashent *)); while ((status = readkpacket(gpkf, &ctb, NULL, keyID, NULL)) != -1) { - if (status == -2 || status == -3) - { fprintf(pgpout,PSTR("\n\007Could not read key from file '%s'.\n"), + if (status == -2 || status == -3) { + fprintf(pgpout,LANG("\n\007Could not read key from file '%s'.\n"), keyfile); fclose(gpkf); /* close key file */ return -1; } if (is_key_ctb(ctb)) { if (find_keyID(keyID) != -1) - fprintf(pgpout, "warning: duplicate key in keyring '%s'\n", keyfile); + fprintf(pgpout, "Warning: duplicate key in keyring '%s'\n", keyfile); if (!hashleft) { hashptr = allocbuf(HASH_ALLOC * sizeof(struct hashent)); hashleft = HASH_ALLOC;