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

📄 keysplit.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*	keysplit.c - Implements support for splitting/rejoining keys
	base off of code found in PGPKeys. */					 

#include <stdio.h>
#include <io.h>
#include <string.h>

#include "pgpBase.h"
#include "pgpKeys.h"
#include "pgpErrors.h"
#include "pgpContext.h"
#include "pgpEnv.h"
#include "pgpPubTypes.h"
#include "pgpFileSpec.h"

#include "pgpShare.h"
#include "pgpShareFile.h"

#include "globals.h"
#include "prototypes.h"
#include "language.h"
#include "fileio.h"

/* should probably move this to a header file later but...*/
typedef struct _SHAREHOLDERSTRUCT {
	PGPBoolean					bPublicKey;
	PGPKeyID					keyid;
	PGPPublicKeyAlgorithm		keyalg;
	char						szUserID[kPGPMaxUserIDSize];
	char						*pszPassphrase;
	PGPUInt16					uShares;
} SHAREHOLDERSTRUCT, *PSHAREHOLDERSTRUCT;

/* taken from KMShare.c */
#define MAX_SHARES						99
#define MAX_SHARES_LEN					2

PGPError sCreateFilePathFromUserName (char		*pszFolder,
									  char		*pszUserID,
									  PGPUInt16	uNumShares,
									  char		*pszModifier,
									  char		*pszPath, 
									  PGPInt16	iLen);


PGPError sSaveSharesToFile (PSHAREHOLDERSTRUCT	pshs, 
							PGPContextRef		context,
							PGPShareRef			sharesTotal,
							PGPKeySetRef		keyset,
							char				*pszFolder);

PGPError sChangeKeyPhrase (PGPContextRef	context,
						   PGPKeySetRef		keyset,
						   PGPKeyRef		key, 
						   char				*szOld, 
						   PGPByte*			pPasskeyOld,
						   PGPSize			sizePasskeyOld,
						   PGPByte*			pPasskey,
						   PGPSize			sizePasskey);

PGPError pgpParseShares(struct pgpmainBones *mainbPtr,
						SHAREHOLDERSTRUCT	**pshs, 
						char				**ppszUsers,
						PGPUInt16			myArgc,
						PGPUInt32			*dwThreshold,
						PGPUInt32			*dwTotalShares,
						PGPUInt32			*dwTotal);


PGPError SplitKey (struct pgpmainBones *mainbPtr, char *pszKeyToSplit, char **ppszUsers, PGPUInt16 myArgc) 
{
    PGPContextRef			context = mainbPtr->pgpContext;
	struct pgpargsBones		*argsbPtr = mainbPtr->argsbPtr;
    struct pgpfileBones		*filebPtr = mainbPtr->filebPtr;
    struct pgpenvBones		*envbPtr = mainbPtr->envbPtr;
	PGPKeySetRef			workingset = kPGPInvalidRef;
	PGPKeySetRef			keyset = kPGPInvalidRef;
	PGPKeyID				keyidToSplit;
	PGPPublicKeyAlgorithm	keyalgToSplit;
    PGPKeyListRef			keylist = kPGPInvalidRef;
    PGPKeyIterRef			keyiter = kPGPInvalidRef;
    PGPKeyRef				keyToSplit = kPGPInvalidRef;
	PGPError				err = kPGPError_NoErr;
	char					*pszPassphrase = NULL;
	PGPShareRef				shares = kPGPInvalidRef;
	PGPUInt32				dwThreshold = 0, dwTotalShares = 0;
	PGPBoolean				bNeedsFree = FALSE;

	PGPByte*				pPasskey = NULL; 
	PGPSize					sizePasskey	= 0;
	char					*pszPhraseKeyToSplit	= NULL;
	PGPByte*				pPasskeyToSplit	= NULL;	 
	PGPSize					sizePasskeyToSplit	= 0;
	PGPUInt32				numShares = 0;
	PGPUInt16				i = 0;
											   
	/* should probably modify this structure */
	SHAREHOLDERSTRUCT		*pshs = NULL;

	err = PGPOpenDefaultKeyRings(context, kPGPKeyRingOpenFlags_Mutable, &workingset);
	if(IsPGPError(err))
		return err;

	mainbPtr->workingRingSet = workingset;

	/* setup share structure */
	err = pgpParseShares(mainbPtr, &pshs, ppszUsers, myArgc, &dwThreshold, &dwTotalShares, &numShares);
	if(IsPGPError(err))
	{
		fprintf(filebPtr->pgpout,
			LANG("Error: parameter error!\n"));
		goto done;
	}

	err = pgpGetMatchingKeySet( mainbPtr, pszKeyToSplit, 0, &keyset);
	if(IsPGPError(err))
		goto done;

    err = PGPOrderKeySet( keyset, kPGPUserIDOrdering, &keylist );
    pgpAssertNoErr(err);
    err = PGPNewKeyIter( keylist, &keyiter );
    pgpAssertNoErr(err);
    err = PGPKeyIterRewind( keyiter );
    pgpAssertNoErr(err);

    err = PGPKeyIterNext( keyiter, &keyToSplit);
    /*if error, no keys found.*/
	if(IsntPGPError(err) && keyToSplit != kPGPInvalidRef)
	{
		PGPBoolean		bIsSecret = FALSE;

		/* check to see if key is secret key */
		err = PGPGetKeyBoolean(keyToSplit, kPGPKeyPropIsSecret, &bIsSecret);
		pgpAssertNoErr(err);

		if(!bIsSecret)
		{
			fprintf(filebPtr->pgpout,
				LANG("Error, cannot split public key!\n"));
			err = kPGPError_BadParams;
			goto done; 
		}

		/* check to see if key has already been split */
		err = PGPGetKeyBoolean(keyToSplit, kPGPKeyPropIsSecretShared, &bIsSecret);
		pgpAssertNoErr(err);

		if(bIsSecret)
		{
			fprintf(filebPtr->pgpout,
				LANG("Error, key has already been split!\n"));
			err = kPGPError_BadParams;
			goto done;
		}

		err = pgpGetValidPassphrase( mainbPtr, keyToSplit, &pszPassphrase, &bNeedsFree );
		if(IsPGPError(err))
		{
			err = kPGPError_UserAbort;
			goto done;
		}

		/* get keyid and alg of key to split */
		PGPGetKeyIDFromKey(keyToSplit, &keyidToSplit);
		PGPGetKeyNumber(keyToSplit, kPGPKeyPropAlgID, &keyalgToSplit);

		/* need to allow user to specify the number of shares required 
			to decrypt/sign with, default to total number of shares */
	
		// create the shares
		err = PGPCreateShares (context, keyToSplit, 
								dwThreshold, dwTotalShares, &shares);

		if(IsPGPError(err))
		{
			fprintf(filebPtr->pgpout,
				LANG("Error splitting key!\n"));
			goto done;
		}
		
		/* get the passkey from the shares */
		err = PGPGetPasskeyFromShares (shares, &pPasskey, &sizePasskey);
		if(IsPGPError(err))
		{
			fprintf(filebPtr->pgpout,
				LANG("Error splitting key!\n"));
			goto done;
		}


		for(i = 0; i < numShares; i++)
		{
			if(!pshs[i].bPublicKey)
			{
				err = pgpPassphraseDialogCmdline(mainbPtr, TRUE, 
							"Enter passphrase: ", &pshs[i].pszPassphrase);
			}
			err = sSaveSharesToFile (&pshs[i], context, shares,	workingset,
				argsbPtr->outputFileName ? argsbPtr->outputFileName : ".");

			if(IsPGPError(err))
			{
				fprintf(filebPtr->pgpout,
					LANG("Error splitting key!\n"));
				goto done;
			}
		}

		err = sChangeKeyPhrase (context, workingset, keyToSplit,
			pszPassphrase[0] == '\0' ? NULL : pszPassphrase,
			pPasskeyToSplit, sizePasskeyToSplit,
			pPasskey, sizePasskey);
	
		if(IsntPGPError(err) && PGPKeySetNeedsCommit(workingset))
		{
			PGPCommitKeyRingChanges(workingset);	
		}
	}
	else
	{
		fprintf(filebPtr->pgpout,
			LANG("Unable to find specified key to split!\n"));
		err = kPGPError_BadParams;
	}


done:
	if(pshs != NULL)
		free(pshs);
	if(shares != kPGPInvalidRef)
		PGPFreeShares(shares);
    if(keyiter != kPGPInvalidRef)
        PGPFreeKeyIter(keyiter);
    if(keylist != kPGPInvalidRef)
        PGPFreeKeyList(keylist);
	if(keyset != kPGPInvalidRef)
		PGPFreeKeySet(keyset);
	if(workingset != kPGPInvalidRef)
	{
		PGPFreeKeySet(workingset);
		mainbPtr->workingRingSet = kPGPInvalidRef;
	}

	return err;
}


/*	Code taken from PGPKeys
 *	_______________________________________________
 *
 *  split the key 
 */

static PGPError 
sSaveSharesToFile (
		PSHAREHOLDERSTRUCT	pshs, 
		PGPContextRef		context,
		PGPShareRef			sharesTotal,
		PGPKeySetRef		keyset,
		char				*pszFolder)
{
	PFLFileSpecRef		filespec		= NULL;
	PGPShareFileRef		sharefile		= NULL;
	PGPShareRef			sharesHolder	= NULL;
	PGPOptionListRef	encodeOptions	= NULL;
	PGPError			err				= kPGPError_NoErr;
	int					iModifier		= 0;

	char				szPath[MAX_PATH];
	char				szModifier[MAX_SHARES_LEN+1];
	char				sz1[32];
	char				sz2[kPGPMaxUserIDSize + 32];
	PGPKeyRef			key;

	// create file name and filespec
	err = sCreateFilePathFromUserName (pszFolder, pshs->szUserID, 
						pshs->uShares, "", szPath, sizeof(szPath));
	if (IsPGPError (err)) goto SaveFileCleanup;

	// check for pre-existence of file
	while (!_access (szPath, 0)) {
		iModifier++;
		if (iModifier > MAX_SHARES) {
			err = kPGPError_CantOpenFile;
			goto SaveFileCleanup;
		}
		sprintf (szModifier, " %i", iModifier);
		err = sCreateFilePathFromUserName (pszFolder, pshs->szUserID,
						pshs->uShares, szModifier, szPath, sizeof(szPath));
		if (IsPGPError (err)) goto SaveFileCleanup;
	}	

	err = PFLNewFileSpecFromFullPath (PGPGetContextMemoryMgr (context), 
		szPath, &filespec);
	if (IsPGPError (err)) goto SaveFileCleanup;
	
	err = PFLFileSpecCreate (filespec);
	if (IsPGPError (err)) goto SaveFileCleanup;

	err = PGPNewShareFile (filespec, &sharefile);
	if (IsPGPError (err)) goto SaveFileCleanup;

	err = PGPSetShareFileUserID (sharefile, pshs->szUserID);
	if (IsPGPError (err)) goto SaveFileCleanup;

	err = PGPSplitShares (sharesTotal, pshs->uShares, &sharesHolder);
	if (IsPGPError (err)) goto SaveFileCleanup;

	// if this shareholder has public key, use it
	if (pshs->bPublicKey) {
		err = PGPSetShareFileOwnerKeyID (sharefile, pshs->keyid);
		if (IsPGPError (err)) goto SaveFileCleanup;

		err = PGPGetKeyByKeyID (keyset, &(pshs->keyid), pshs->keyalg, &key);
		if(IsPGPError(err)) goto SaveFileCleanup;

		err = PGPBuildOptionList (context, &encodeOptions,
			PGPOEncryptToKey (context, key),
			PGPOLastOption (context));
		if (IsPGPError (err)) goto SaveFileCleanup;
	}

	// there is no public key for this shareholder
	else {
		err = PGPBuildOptionList (context, &encodeOptions,
			PGPOConventionalEncrypt (context,
				PGPOPassphrase (context, pshs->pszPassphrase),
				PGPOLastOption (context)),
			PGPOLastOption (context));
		if (IsPGPError (err)) goto SaveFileCleanup;
	}

	err = PGPCopySharesToFile (context, sharefile, 
									encodeOptions, sharesHolder);
	if (IsPGPError (err)) goto SaveFileCleanup;

	err = PGPSaveShareFile (sharefile);

SaveFileCleanup:

	if (encodeOptions != NULL)
		PGPFreeOptionList (encodeOptions);

	if (sharesHolder != NULL)
		PGPFreeShares (sharesHolder);

	if (sharefile != NULL)
		PGPFreeShareFile (sharefile);

	if (filespec != NULL)
		PFLFreeFileSpec (filespec);

	return err;
}


/* Code taken from PGPKeys
 *	___________________________________________________
 *
 * Change passphrase of key and all subkeys
 */

static PGPError 
sChangeKeyPhrase (
		PGPContextRef	context,
		PGPKeySetRef	keyset,
		PGPKeyRef		key, 
		char			*szOld, 
		PGPByte*		pPasskeyOld,
		PGPSize			sizePasskeyOld,
		PGPByte*		pPasskey,
		PGPSize			sizePasskey) 
{
	PGPUInt32		u;
	PGPKeyListRef	keylist;
	PGPKeyIterRef	keyiter;
	PGPSubKeyRef	subkey;
	PGPError		err;

	if (szOld) {
		err = PGPChangePassphrase (key, 
				PGPOPassphrase (context, szOld), 
				PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
				PGPOLastOption (context));
	}
	else if (sizePasskeyOld > 0) {
		err = PGPChangePassphrase (key, 
				PGPOPasskeyBuffer (context, pPasskeyOld, sizePasskeyOld), 
				PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
				PGPOLastOption (context));
	}
	else {
		err = PGPChangePassphrase (key, 
				PGPOPassphrase (context, ""), 
				PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
				PGPOLastOption (context));
	}
	if (IsPGPError (err)) return err;

	PGPGetKeyNumber (key, kPGPKeyPropAlgID, &u);
	switch (u) {
	case kPGPPublicKeyAlgorithm_RSA :
		break;

	case kPGPPublicKeyAlgorithm_DSA :
		PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist);
		PGPNewKeyIter (keylist, &keyiter);
		PGPKeyIterSeek (keyiter, key);
		PGPKeyIterNextSubKey (keyiter, &subkey);
		while (subkey) {
			if (szOld) {
				err = PGPChangeSubKeyPassphrase (subkey, 
						PGPOPassphrase (context, szOld),
						PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
						PGPOLastOption (context));
			}
			else if (sizePasskeyOld > 0) {
				err = PGPChangeSubKeyPassphrase (subkey, 
						PGPOPasskeyBuffer (context, 
											pPasskeyOld, sizePasskeyOld),
						PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
						PGPOLastOption (context));
			}
			else {
				err = PGPChangeSubKeyPassphrase (subkey, 
						PGPOPassphrase (context, ""),
						PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
						PGPOLastOption (context));
			}
			PGPKeyIterNextSubKey (keyiter, &subkey);
		}
		PGPFreeKeyIter (keyiter);
		PGPFreeKeyList (keylist);
		break;

	default :
		break;
	}

	return err;
}


static PGPError
sCreateFilePathFromUserName (
		char		*pszFolder,
		char		*pszUserID,
		PGPUInt16	uNumShares,
		char		*pszModifier,
		char		*pszPath, 
		PGPInt16	iLen) 
{
	char		sz[kPGPMaxUserIDSize];
	char		szDefName[16];
	char		szDefExt[8];
	char		szShares[16];
	PGPInt16	iMinRequiredLen;
	PGPInt16	i;

	/* prepare number of shares substring */
	if (uNumShares == 1) {
		sprintf(szShares, "1 Share");
	}
	else {
		sprintf(szShares, "%i Shares", uNumShares);
	}

	/* get default file name and extension */
	sprintf(szDefName, "User");
	strcat (szDefName, pszModifier);
	sprintf(szDefExt, "shf");

	/* check length of destination buffer */
	iMinRequiredLen = 
		strlen (pszFolder) + strlen (szDefExt) + strlen (szDefName) +1;
	if (iMinRequiredLen >= iLen) 
		return kPGPError_CantOpenFile;

	/* put folder into path */
	/* need to make sure to support path specifiers for all platforms */
	strcpy (pszPath, pszFolder);
	iLen -= strlen (pszPath);

⌨️ 快捷键说明

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