⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpk.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 5 页
字号:
	int needwritesec=0;
	int newkeys = 0;
	int err = 0;

	mainOpenPubSec(env, &pub, &pubring, &sec, &secring, stderr);

	if (!argc) {
#if 0
		fprintf (stderr, "No input files -- reading from stdin\n");
		/* BUG. This won't work, requires fseek/ftell */
		keyfile = mainOpenKeyring (stdin, 0);
#else
		fprintf (stderr, "No key file specified for addition\n");
		goto cleanup;
#endif
	} else while (argc--) {
		struct RingSet *temp;
		FILE *fp;
		struct PgpFile *pfp;
		struct RingFile *ring;

		fprintf (stderr, "Opening ringfile \"%s\"...\n", argv[0]);
		fp = fopen (argv[0], "rb");
		pfp = pgpFileReadOpen (fp, NULL, NULL); /* chain errors */
		/* We will never close this ringfile */
		ring = ringFileOpen (ringpool, pfp, 0, &err); /* chain */
		temp = ringSetCopy(ringFileSet(ring)); /* chain */
		if (!temp) {
			fprintf (stderr, "Unable to open file \"%s\"\n",
				argv[0]);
		} else {
			fprintf (stderr,
"\nAdding keys:\n\n");
			ringTtyKeyView((void *)ui_arg, NULL, temp, argv[0], 0);
			newkeys++;
			if (keyfile) {
				struct RingSet *tring;
				tring = ringSetUnion(keyfile, temp);
				ringSetDestroy(keyfile);
				ringSetDestroy(temp);
				keyfile = tring;
			} else
				keyfile = temp;
		}
		fprintf (stderr, "\n");
		argv++;
	}

	if (!newkeys) {
		fprintf (stderr, "No keys to add\n");
		goto cleanup;
	}

	/* Add keys in keyfile to copy of pubring/secring as appropriate */
	newpub = ringSetCreate(ringpool);
	newsec = ringSetCreate(ringpool);
	if (!newpub || !newsec) {
		err = PGPERR_NOMEM;
		goto cleanup;
	}
	ringSetAddSet(newpub, pubring);
	ringSetAddSet(newsec, secring);
	ringSetDestroy(pubring);
	ringSetDestroy(secring);
	pubring = secring = NULL;

	ringSetFreeze(keyfile);
	iter = ringIterCreate(keyfile);
	if (!iter) {
		err = ringPoolError(ringpool)->error;
		goto cleanup;
	}
	while (ringIterNextObject(iter, 1) > 0) {
		union RingObject *obj = ringIterCurrentObject(iter, 1);
		pgpAssert(obj);
		pgpAssert (ringObjectType (obj) == RINGTYPE_KEY);
		/* Treat secret keys differently from public */
		if (ringKeyIsSec(keyfile, obj)) {
			struct RingSet *tring;
			struct RingSet *tring2;
			union RingObject *secobj;
			struct RingIterator *itersec;
			int level;

			/* Create tring holding just this key and children */
			tring = ringSetCreate(ringpool);
			tring2 = ringSetCreate(ringpool);
			if (!tring || !tring2) {
				err = ringPoolError(ringpool)->error;
				ringSetDestroy(tring);
				ringSetDestroy(tring2);
				goto cleanup;
			}
			ringSetAddHierarchy(tring, keyfile, obj);
			ringSetFreeze(tring);

			/* Make tring2 which holds tring minus signatures */
			ringSetAddSet(tring2, tring);
			itersec = ringIterCreate(tring);
			while ((level=ringIterNextObjectAnywhere(itersec))>0) {
				union RingObject *iterobj;
				iterobj = ringIterCurrentObject(itersec,level);
				if (ringObjectType(iterobj) == RINGTYPE_SIG)
					ringSetRemObject(tring2, iterobj);
			}

			/* Add set minus sigs to secret keyring */
			ringSetAddSet(newsec, tring2);

			/* Make another copy of tring, this one minus secret */
			ringSetAddSet(tring2, tring);
			ringIterRewind(itersec, 1);
			ringIterNextObject(itersec, 1);
			secobj = NULL;
			while (ringIterNextObject(itersec, 2) > 0) {
				secobj = ringIterCurrentObject(itersec, 2);
				if (ringObjectType(secobj) == RINGTYPE_SEC)
					break;
			}
			pgpAssert (secobj);
			ringIterDestroy(itersec);
			ringSetRemObject(tring2, secobj);
			ringObjectRelease(secobj);

			/* Add set without secret to pubring */
			ringSetAddSet(newpub, tring2);
			ringSetDestroy(tring2);
			ringSetDestroy(tring);

			needwritesec = 1;
		} else {
			/* Add to public keyring */
			ringSetAddHierarchy(newpub, keyfile, obj);
		}
	}
	ringIterDestroy(iter);
	ringSetDestroy(keyfile);
	keyfile = NULL;
	ringSetFreeze(newpub);
	ringSetFreeze(newsec);
	
	if (!pgpenvGetInt (env, PGPENV_FORCE, NULL, NULL)) {
	if (pgpenvGetInt (env, PGPENV_BATCHMODE, NULL, NULL)) {
	fprintf (stderr,
		"Use +force to add keys in batchmode\n\
Key addition cancelled.\n");
	goto cleanup;
	}
	if (needwritesec)
	fprintf (stderr,
"Do you want to add these keys to keyrings \"%s\" and\n"\
"\"%s\" (y/N)? ", pub, sec);
	else
	fprintf (stderr,
"Do you want to add these keys to keyring \"%s\" (y/N)? ", pub);
			if (!pgpTtyGetBool(0, stderr)) {
			fprintf (stderr, "Key addition cancelled.\n");
			err = 0;
			goto cleanup;
			}
		}

	/* Do maintenance pass on new rings. */
	reloadAllKeys (env, 0, 1); /* no untrusted keyrings */
	tmpring = ringSetUnion(allkeys, newpub);
	ringSetDestroy(allkeys);
	allkeys = ringSetUnion(tmpring, newsec);
	ringSetDestroy(tmpring);
	err = mainDoMaint ((void *) ui_arg, allkeys, 1, newpub);
	if (err < 0)
		goto cleanup;
	mainRingNewSet (pub, PGP_WRITETRUST_PUB, newpub);
	newpub = 0;	/* Don't destroy it */
	if (needwritesec) {
		mainRingNewSet (sec, PGP_WRITETRUST_SEC, newsec);
		newsec = 0;	/* Don't destroy it */
	}

	fprintf (stderr,
"Keys added successfully.\n");
	err = 0;
cleanup:
	if (pubring)
		ringSetDestroy(pubring);
	if (secring)
		ringSetDestroy(secring);
	if (newpub)
		ringSetDestroy(newpub);
	if (newsec)
		ringSetDestroy(newsec);
	if (keyfile)
		ringSetDestroy(keyfile);
	return err;
}

static int
doKeyExtract (struct PgpEnv *env, struct Flags *flags, int argc, char *argv[],
	struct PgpTtyUI *ui_arg)
{
	struct RingSet *pubring = NULL;
	struct RingSet *keyfile = NULL;
	char const *pub;
	byte doarmor = flags->doarmor;
	int err;

	(void) ui_arg;

	/* Check the command-line args for armor */
	if (!doarmor && flags->argc && strchr (flags->args, 'a'))
		doarmor++;

	mainOpenPubSec(env, &pub, &pubring, NULL, NULL, stderr);
	if (!pubring) {
		fprintf (stderr, "No keys in pubring\n");
		return 0;
	}

	err = selectKeyArgs (env, argc, argv, pub, pubring, &keyfile, 0);
	if (err < 0)
		return err;
	if (err == 0) {
		fprintf (stderr, "No keys were selected for extraction.\n");
		return 0;
	}
	ringSetFreeze (keyfile);

	ringSetDestroy(pubring);

	if (flags->outfile &&
	pgpTtyCheckOverwrite ((void *) ui_arg, flags->outfile))
	return PGPERR_NO_FILE;
	if (doarmor) {
		FILE *fp = flags->outfile ? fopen(flags->outfile, "w") :
									stdout;
		if (!fp)
			return PGPERR_NO_FILE;
		err = mainWriteArmoredSet (fp, 0, keyfile, env);
	} else if (flags->outfile) {
		FILE *fp = fopen(flags->outfile, "wb");
		if (!fp)
			return PGPERR_NO_FILE;
		err = mainWriteSet (fp, 0, keyfile);
	} else {
		err = mainWriteSet (stdout, 0, keyfile);
	}
	ringSetDestroy(keyfile);
	return err;
}

static int
keygenProgress (void *arg, int c)
{
	(void)arg;		/* make the compiler happy */
	putc (c, stderr);
	fflush (stderr);
	return 0;
}

/* Optional Arguments: name keybits */
static int
doKeyGenerate (struct PgpEnv *env, int argc, char *argv[], void *ui_arg)
{
	struct RingSet *pubring = NULL, *secring = NULL;
	struct RingSet *newpub = NULL, *newsec = NULL;
	struct PgpKeySpec *keyspec = NULL;
	struct PgpSecKey *seckey = NULL, *subseckey = NULL;
	struct PgpPkAlg const *pkalg, *subkalg;
	char const *pub = NULL, *sec = NULL; /* make the compiler happy */
	char *name = NULL, namebuf[256];
	size_t namelen = 0;
	unsigned keybits = 0;
	int keytype;
	unsigned entropy;
	int error = 0;
	unsigned len;
	char buf[20];

	fprintf (stderr,
		"Choose the type of your public key:\n"
		"  1) DSS/Diffie-Hellman - New for PGP 5!  "
									"Separate signing and encryption keys\n"
		"  2) RSA                - Compatible with old versions of PGP\n"
		"  3) RSA pair           - Separate signing and encryption using RSA\n"
		"Choose 1, 2, or 3: ");
	len = pgpTtyGetString (buf, sizeof(buf), stderr);
	if (!len) {
		fprintf (stderr, "No key type was chosen\n");
		error = -1;
		goto cleanup;
	}
	keytype = atoi(buf);
	switch (keytype) {
	case 1:
		pkalg = pgpPkalgByNumber(PGP_PKALG_DSA);
		subkalg = pgpPkalgByNumber(PGP_PKALG_ELGAMAL);
		break;
	case 2:
		pkalg = pgpPkalgByNumber(PGP_PKALG_RSA);
		subkalg = 0;
		break;
	case 3:
		pkalg = pgpPkalgByNumber(PGP_PKALG_RSA);
		subkalg = pgpPkalgByNumber(PGP_PKALG_RSA);
		break;
	default:
		/* Allow unforeseen key types */
		pkalg = pgpPkalgByNumber(keytype);
		subkalg = 0;
		break;
	}
	if (!pkalg) {
		fprintf (stderr, "No legal key type was chosen\n");
		error = -1;
		goto cleanup;
	}

	/* Need to get userid, keysizes, etc. */
	if (argc) {
		name = argv[0];
		namelen = strlen (name);
		argv++;
		argc--;
	}
	if (argc) {
		keybits = atoi (argv[0]);
		argv++;
		argc--;
	}

	if (!keybits) {
		fputs (
"\nPick your public/private keypair key size:\n\
\n***** TEMPORARY LABELS, TO BE DETERMINED LATER!! *****\n\n\
    1)   768 bits- Commercial grade, probably not currently breakable\n\
    2)  1024 bits- High commercial grade, secure for many years\n\
    3)  2048 bits- \"Military\" grade, secure for the forseeable future\n\
    4)  3072 bits- Archival grade, slow, highest security\n\
Choose 1, 2, 3, or 4, or enter desired number of bits: ", stderr);
		fflush (stderr);
		len = pgpTtyGetString (buf, sizeof(buf), stderr);
		if (!len) {
			fprintf (stderr, "Keygen error\n");
			error = -1;
			goto cleanup;
		}
		keybits = atoi (buf);
		switch (keybits) {
			case 1: keybits = 768; break;
			case 2: keybits = 1024; break;
			case 3: keybits = 2048; break;
			case 4: keybits = 3072; break;
			default:
				if (keybits < 512) {
					fprintf (stderr,
"Minimum key size is 512 bits\n");
					error = -1;
					goto cleanup;
				}
				if (keybits > 4096) {
					fprintf (stderr,
"Maximum key size is 4096 bits\n");
					error = -1;
					goto cleanup;
				}
				break;
		}
	}

	if (!name) {
		name = namebuf;
		fputs (
"\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\
<angle brackets>, 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: ", stderr);
		fflush (stderr);
		namelen = pgpTtyGetString (namebuf, sizeof (namebuf), stderr);
	}

	if (!namelen) {
		fprintf (stderr, "Keygen error\n");
		error = -1;
		goto cleanup;
	}

	/* Open the existing keyrings */
	mainOpenPubSec(env, &pub, &pubring, &sec, &secring, stderr);

	/* Copy pubring and secring */
	newpub = ringSetCreate (ringpool);
	ringSetAddSet (newpub, pubring);
	ringSetDestroy(pubring);
	newsec = ringSetCreate (ringpool);
	ringSetAddSet (newsec, secring);
	ringSetDestroy(secring);

	if (!newpub || !newsec) {
		error = PGPERR_NOMEM;
		goto cleanup;
	}

	/* Generate Randomness */
	if (!rng)
		rng = pgpRandomCreate();

	/* Need to ask for randomness */
	entropy = pgpSecKeyEntropy (pkalg, keybits, FALSE);
	if (subkalg)
		entropy += pgpSecKeyEntropy (subkalg, keybits, FALSE);
	pgpTtyRandAccum (ui_arg, entropy);
	
	/* Generate the SecKey */
	seckey = pgpSecKeyGenerate (pkalg, keybits, FALSE, rng, keygenProgress,
				NULL, &error);

	pgpRandomStir (rng);
	if (!seckey && !error)
		error = PGPERR_NOMEM;
	if (error)
		goto cleanup;

	/* Need to lock the SecKey */
	fprintf(stderr, "\n\
You need a pass phrase to protect your %s private key.\n\
Your pass phrase can be any sentence or phrase and may have many\n\
words, spaces, punctuation, or any other printable characters.\n",
		(subkalg ? "signature" : "RSA"));
	error = setPassword (env, seckey, ui_arg);
	if (error)
		goto cleanup;

	/* Generate the keyring objects */

	keyspec = pgpKeySpecCreate (env);
	if (!keyspec) {
		error = PGPERR_NOMEM;
		goto cleanup;
	}

	error = ringCreateKeypair (env, seckey, keyspec, name, namelen, rng,
				newpub, newsec);
	if (error)
		goto cleanup;

	/* Make subkey if requested */
	if (subkalg) {
		/* Generate the subseckey */
		subseckey = pgpSecKeyGenerate (subkalg, keybits, FALSE, rng,
					keygenProgress, NULL, &error);
		pgpRandomStir (rng);
		if (!subseckey && !error)
			error = PGPERR_NOMEM;
		if (error)
			goto cleanup;

		/* Need to lock the encryption SubSecKey */
		fprintf(stderr, "\n\
You also need a pass phrase to protect your encryption private key.\n\
Your pass phrase can be any sentence or phrase and may have many\n\
words, spaces, punctuation, or any other printable characters.\n");
		error = setPassword (env, subseckey, ui_arg);
		if (error)
			goto cleanup;

		error = ringCreateSubkeypair (env, seckey, subseckey, keyspec,
					rng, newpub, newsec);
		if (error)
			goto cleanup;
	}

	/* Freeze the sets */
	ringSetFreeze (newpub);
	ringSetFreeze (newsec);

	/* Write out newpub and newsec */
	mainRingNewSet (sec, PGP_WRITETRUST_SEC, newsec);
	mainRingNewSet (pub, PGP_WRITETRUST_PUB, newpub);
	newsec = newpub = 0;	/* Don't destroy these */

	cleanup:
	if (newpub)
		ringSetDestroy (newpub);
	if (newsec)
		ringSetDestroy (newsec);
	if (seckey)
		pgpSecKeyDestroy (seckey);
	if (subseckey)
		pgpSecKeyDestroy (subseckey);
	if (keyspec)
		pgpKeySpecDestroy (keyspec);
	putc ('\n', stderr);
	if (!error)
		fprintf (stderr,
"Keypair created successfully.\n\

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -