--- pgp/src/keymgmt.c 2018/04/24 16:43:52 1.1.1.7 +++ pgp/src/keymgmt.c 2018/04/24 16:44:50 1.1.1.8 @@ -674,7 +674,8 @@ int getpublickey(int flags, char *keyfil pktlen = (int) (ftell(f) - fpos); keystatus = status; if (!keyID && !(flags & GPK_DISABLED) && - is_ctb_type(ctb, CTB_CERT_SECKEY_TYPE) && + (is_ctb_type(ctb, CTB_CERT_SECKEY_TYPE) || + is_ctb_type(ctb, CTB_CERT_PUBKEY_TYPE)) && read_trust(f, &keyctrl) == 0 && (keyctrl & KC_DISABLED)) skip = TRUE; @@ -1667,21 +1668,21 @@ int dokeycheck(char *mcguffin, char *rin if (failed && fixedf) { copyfilepos(f, fixedf, -1L, fixpos); + fclose(f); if (write_error(fixedf)) { fclose(fixedf); - fclose(f); return -1; } fclose(fixedf); if (!batchmode) fprintf(pgpout, LANG("Remove bad signatures (Y/n)? ")); if (batchmode || getyesno('y')) { - fclose(f); savetempbak(tempring, ringfile); failed = 0; } + } else { + fclose(f); } - fclose(f); /* close key file */ return 0; /* normal return */ @@ -2333,15 +2334,26 @@ Defaulting to public keyring.")); extract_keyID(keyID, n); - /* Now read private key, too - * Default name is the same as your secret keyring, then try - * "secring.pgp" if that fails. +#if 0 + /* + * Old code: looks in the same directory as the given keyring, but + * with the secret keyring filename. */ strcpy(secring, ringfile); strcpy(file_tail(secring), file_tail(globalSecringName)); if (!file_exists(secring) && strcmp(file_tail(secring), "secring.pgp")) { strcpy(file_tail(secring), "secring.pgp"); } +#else + /* + * What it should do: use the secret keyring, always. + * Now that the path can be set, this is The Right Thing. + * It used to be impossible to put the secret and public keyring in + * different directories, so forcing the same directory name was The + * Right Thing. It is no longer. + */ + strcpy(secring, globalSecringName); +#endif if (!file_exists(secring)) { fprintf(pgpout, LANG("\nCan't open secret key ring file '%s'\n"), secring); @@ -2589,8 +2601,9 @@ Do you want to enable this key again (y/ * Do an RSA key pair generation, and write them out to the keyring files. * numstr is a decimal string, the desired bitcount for the modulus n. * numstr2 is a decimal string, the desired bitcount for the exponent e. + * username is the desired name for the key. */ -int dokeygen(char *numstr, char *numstr2) +int dokeygen(char *numstr, char *numstr2, char *username) { unit n[MAX_UNIT_PRECISION], e[MAX_UNIT_PRECISION]; unit d[MAX_UNIT_PRECISION], p[MAX_UNIT_PRECISION]; @@ -2634,8 +2647,33 @@ Choose 1, 2, or 3, or enter desired numb /* minimum RSA keysize: */ if (keybits < 384) keybits = 384; - if (keybits > 1024) - keybits = 1024; + + /* + * We want to allow some time after release (like, say, 3 months) for + * this new version to be widely used before people start flinging 2Kbit + * keys around, which earlier versions of PGP will break on. + * Accepting 2048-bit keys was supposed to be a quiet change in 2.6.1, + * so the next release could generate them, but a) the change was + * messed up, so PGP 2.6.1 didn't, and b) it was announced, causing + * great noise and commotion. PGP has always added code to *accept* + * new features before (usually, one version before) *generating* + * the new features. Remember, it's a communications package, so + * there are at least two people involved, and *both* must be able + * to deal with the new feature. + * + * Please have patience before exercising your paranoia, or AT LEAST + * before uploading it to key servers and inflicting it on an unprepared + * world! The date is about 3 months after the release. + * + * @@@ TODO: stop doing this test in 1995. + */ + if (get_timestamp(NULL) < 0x2efcb600) { /* Telling would spoil the fun */ + if (keybits > 1024) + keybits = 1024; + } else { + if (keybits > 2048) + keybits = 2048; + } #else if (keybits > MAX_BIT_PRECISION) keybits = MAX_BIT_PRECISION; @@ -2648,18 +2686,27 @@ Choose 1, 2, or 3, or enter desired numb fprintf(pgpout, LANG("Generating an RSA key with a %d-bit modulus.\n"), keybits); - fputs( + if (username == NULL || *username == '\0') { + /* We need to ask for a username */ + fputs( LANG("\nYou need a user ID for your public key. The desired form for this\n\ user ID is your name, followed by your E-mail address enclosed in\n\ , if you have an E-mail address.\n\ For example: John Q. Smith <12345.6789@compuserve.com>\n\ Enter a user ID for your public key: \n"), pgpout); #ifdef VMS - putch('\n'); /* That last newline was just a return, do a real one */ + putch('\n'); /* That last newline was just a return, do a real one */ #endif - getstring((char *) userid, 255, TRUE); /* echo keyboard input */ - if (userid[0] == '\0') /* user entered null response */ - return -1; /* error return */ + getstring((char *) userid, 255, TRUE); /* echo keyboard input */ + if (userid[0] == '\0') /* user entered null response */ + return -1; /* error return */ + + } else { + /* Copy in passed-in username */ + memcpy(userid, username, 255); + fprintf(pgpout, + LANG("Generating RSA key-pair with UserID \"%s\".\n"), userid); + } CONVERT_TO_CANONICAL_CHARSET((char *) userid); CToPascal((char *) userid); /* convert to length-prefixed string */ @@ -2675,7 +2722,7 @@ words, spaces, punctuation, or any other /* As rsa_keygen does a major accumulation of random bits, if we need * any others for a seed file, let's get them at the same time. */ - cryptrandflag = (cryptRandOpen() < 0); + cryptrandflag = (cryptRandOpen((struct IdeaCfbContext *)0) < 0); if (cryptrandflag) trueRandAccumLater(192); @@ -2745,7 +2792,8 @@ words, spaces, punctuation, or any other */ if (cryptrandflag) { trueRandConsume(192); - cryptRandCreate(); + cryptRandInit((struct IdeaCfbContext *)0); + /* It will get saved by exitPGP */ } return 0; /* normal return */ } /* dokeygen */