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

📄 shamirtest.c

📁 PGP.Corporation.PGP.SDK.v3.7.2.rar 此前从本站下载的那个缺少几个lib文件
💻 C
字号:
 /*____________________________________________________________________________
ShamirTest.c

Copyright (C) 2003,2004 PGP Corporation
All rights reserved.

FIPS 140-2 Operational Test/ Secret sharing test

$Id: ShamirTest.c 48493 2006-10-12 21:19:56Z vinnie $
____________________________________________________________________________*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#if PGP_WIN32
 #include <io.h>
 #include <direct.h>
#endif


#include "pgpErrors.h"
#include "pgpKeys.h"
#include "pgpShare.h"
#include "pgpShareFile.h"
#include "pgpMemoryMgr.h" 
#include "pgpUtilities.h"

#include "optest.h"

#define kPGPShareHeaderSize		4
#define kNumShares				6
#define kShareThreshold			4

   
 static PGPError TestShares(PGPContextRef context)
{
	PGPError			err 		= kPGPError_NoErr;
	PGPKeyDBRef			keyDB	 	= kInvalidPGPKeyDBRef;
   	PGPKeyDBObjRef		theKey		= kInvalidPGPKeyDBObjRef;
	PGPShareRef			share		= kInvalidPGPShareRef;
	PGPFileSpecRef		shareDirSpec = kInvalidPGPFileSpecRef;
  	PGPSize				passKeySize		= 0;
	PGPByte*			passKey			= NULL;
	
  	PGPKeyID			theKeyID;
	char				buffer[256];
	char				keyIDstr[kPGPMaxKeyIDStringSize];
 	PGPSize				bufSize;
	PGPInt32			version = 0;
	int					i;
	PGPBoolean			done = FALSE;
	PGPByte				fp[64];
	PGPSize				fplen;
   
	OPTESTPrintF("\tHigh Level Key Share Test\n");

	/* Read in the test key and get a ref to it */
	err = importKeys(context,gTestKeysPath, kPGPInputFormat_PGP, &keyDB); CKERR;
	
 	 /* TE03.14.02  - Key Management */
	 /* Find test Key */
	 OPTESTPrintF("\t Find Key %s", kAlicesKeyIDString );
 	 err =  PGPNewKeyIDFromString( kAlicesKeyIDString,  kPGPPublicKeyAlgorithm_Invalid,  &theKeyID); CKERR;
	 err =  PGPFindKeyByKeyID( keyDB, &theKeyID, &theKey); CKERR;

	 /* get the primary key ID (signing key) name */
 	 PGPGetKeyID( theKey, &theKeyID );
	 PGPGetKeyIDString( &theKeyID, kPGPKeyIDString_Abbreviated, keyIDstr);
	 PGPGetKeyDBObjDataProperty(theKey,kPGPKeyProperty_Fingerprint, &fp,sizeof(fp), &fplen);
	  
 	 err = PGPGetPrimaryUserIDName(theKey,  buffer, sizeof(buffer), &bufSize);
	 OPTESTPrintF("\"%s\" \n",buffer);
 
	OPTESTPrintF("\t Deconstructing Key into %d shares\n",kNumShares);
	err = PGPCreateShares(context, theKey, kShareThreshold, kNumShares,  &share); CKERR;
 	OPTESTPrintF("\t Split into %d shares, %d needed to recombine.\n", PGPGetTotalNumberOfShares( share), PGPGetShareThreshold( share));
 
	OPTESTPrintF("\t Getting passkey for shares\n");
	err = PGPGetPasskeyFromShares (share, &passKey, &passKeySize); 
	if(gVerbose_flag)
	{
		dumpHex(passKey,  passKeySize, 0);
 	}
	OPTESTPrintF("\t Changing Alice's passphrases to new passkey\n");
	err = PGPChangePassphrase( theKey,  
				PGPOPassphrase( context, kAlicesPassPhrase ),
				PGPOPasskeyBuffer( context, passKey, passKeySize ),
				PGPOLastOption( context ) );	 CKERR;

	/* we must also change all subkey paasphrases. */
 	err = PGPGetKeyDBObjNumericProperty( theKey, kPGPKeyProperty_Version, &version );	CKERR;
	if( version == kPGPKeyVersion_V4 )
	{
		PGPKeyIterRef		keyIter;
		PGPKeyDBObjRef		subKey;
		
		err = PGPNewKeyIterFromKeyDB( keyDB, &keyIter );	CKERR;
		PGPKeyIterSeek( keyIter, theKey );
		while( IsntPGPError ( err ) &&
			IsntPGPError( PGPKeyIterNextKeyDBObj( keyIter, kPGPKeyDBObjType_SubKey, &subKey ) ) )
		{
			err = PGPChangePassphrase( subKey,  
				PGPOPassphrase( context, kAlicesPassPhrase ),
				PGPOPasskeyBuffer( context, passKey, passKeySize ),
				PGPOLastOption( context ) );
		}
		PGPFreeKeyIter( keyIter );
	}
	
 	PGPFreeData( passKey );
	passKey= NULL;
	
	OPTESTPrintF("\t Trying old passphrase...");
	if( !PGPPassphraseIsValid(theKey,
						  PGPOPassphrase( context, kAlicesPassPhrase ),
						  PGPOLastOption( context )))
	{
		OPTESTPrintF("no longer valid.\n");
	}
	else FAIL("passphrase did not change");
	
 	OPTESTPrintF("\t Create share %d files, (1 share each)\n", kNumShares);
	for(i = 0; i < kNumShares; i++)
	{
		PGPFileSpecRef		shareSpec		= kInvalidPGPFileSpecRef;
		PGPShareFileRef		shareFile		= kInvalidPGPShareFileRef;
		PGPShareRef			sharesHolder	= kInvalidPGPShareRef;	
		PGPOptionListRef	optionList		= kInvalidPGPOptionListRef;
	
 		sprintf(buffer, "%s/share%d", gOutputDirectory, i);
		if(makeFile(buffer) ) FAIL("makefile Failed \n");
		
		err = PGPNewFileSpecFromFullPath(context, buffer, &shareSpec) ; CKERR;
		if(gVerbose_flag) OPTESTPrintF("\t   %s\n", buffer);
		
		err = PGPBuildOptionList (context, &optionList,
			PGPOConventionalEncrypt (context,
				PGPOPassphrase (context, kAlicesPassPhrase),
				PGPOLastOption (context)),
			PGPOLastOption (context)); CKERR;
		
  		err = PGPNewShareFile ((PFLFileSpecRef)shareSpec, &shareFile); CKERR;
		
  		err = PGPSetShareFileUserID (shareFile, (PGPUTF8*)"Optest User"); CKERR;
		err = PGPSetShareFileOwnerKeyID(shareFile, theKeyID); CKERR;
		err = PGPSetShareFileOwnerFingerprint(shareFile, fplen, fp);CKERR;
		err = PGPSplitShares (share, 1, &sharesHolder); CKERR;
		err = PGPCopySharesToFile (context, shareFile, optionList, sharesHolder); CKERR;
		err = PGPSaveShareFile (shareFile); CKERR;
		
		if (PGPOptionListRefIsValid (optionList))
				PGPFreeOptionList (optionList);
				
		if (PGPShareRefIsValid (sharesHolder))
			PGPFreeShares (sharesHolder);
			
		if (PGPShareFileRefIsValid (shareFile))
			PGPFreeShareFile (shareFile);
			
		if (PGPFileSpecRefIsValid (shareSpec))
				PGPFreeFileSpec (shareSpec);
 	}

	/* free up shares */
	PGPFreeShares( share );
	share = kInvalidPGPShareRef;
	 

	OPTESTPrintF("\t Joining shares \n");
	for(done = FALSE, i = 0; i < kNumShares && !done; i++)
	{
		PGPFileSpecRef		shareSpec		= kInvalidPGPFileSpecRef;
		PGPShareFileRef		shareFile		= kInvalidPGPShareFileRef;
		PGPShareRef			newShares		= kInvalidPGPShareRef;	
		PGPShareRef			tempShares			= kInvalidPGPShareRef;
		PGPOptionListRef	optionList		= kInvalidPGPOptionListRef;
		PGPKeyID			thisKeyID;
	
 		sprintf(buffer, "%s/share%d", gOutputDirectory, i);
 	
	 	err = PGPNewFileSpecFromFullPath(context, buffer, &shareSpec) ; CKERR;
		if(gVerbose_flag)OPTESTPrintF("\t    %s - ", buffer);
		
		err = PGPOpenShareFile((PFLFileSpecRef)shareSpec, &shareFile); CKERR;
 	
	 	err = PGPGetShareFileUserID(shareFile, sizeof(buffer), (PGPUTF8*)buffer, &bufSize); CKERR;
		buffer[bufSize] = '\0';
		if(gVerbose_flag) OPTESTPrintF("%s - %d share\n", buffer, PGPGetNumSharesInFile(shareFile));
	
		err = PGPGetShareFileSharedKeyID(shareFile, &thisKeyID);  CKERR;
		err = PGPGetShareFileOwnerFingerprint(shareFile, sizeof(fp), (PGPUTF8*)fp, &fplen); CKERR;
 		
		err = PGPBuildOptionList (context, &optionList,
 				PGPOPassphrase (context, kAlicesPassPhrase),
				PGPOLastOption (context)); CKERR;
	

		err = PGPCopySharesFromFile (context, shareFile, optionList, &newShares);  CKERR;
		if (err == kPGPError_BadPassphrase)
		{
			/* Ignore bad passphrase errors, just move on to the next share */
			err = kPGPError_NoErr;
		}
 	
		if (PGPShareRefIsValid (newShares))
		{
			 PGPShareID shareID;
				 
			err = PGPGetKeyIDFromShares(newShares, &thisKeyID); CKERR;
  			err = PGPGetShareID(newShares, &shareID); CKERR;
			
			if( PGPCompareKeyIDs(&theKeyID, &thisKeyID)  == 0)
			{
				if (PGPShareRefIsValid (share))
				{
					err = PGPCombineShares (share, newShares, &tempShares);
					if (err == kPGPError_SplitIdenticalShares)
					{
						err = kPGPError_NoErr;
					}
					else if (IsPGPError (err))
					{
						CKERR;
					}
					else
					{
						err = PGPFreeShares (share); CKERR;
						share = tempShares;
						tempShares = kInvalidPGPShareRef;

					}
					err = PGPFreeShares (newShares); CKERR;
					newShares = kInvalidPGPShareRef;
					
					if( PGPGetNumberOfShares( share) >= PGPGetShareThreshold( share))
					{
						OPTESTPrintF("\t Collected %d shares, only needed %d.\n", 
								PGPGetNumberOfShares( share),PGPGetShareThreshold( share));
						done = TRUE;
					}
				}
				else
				{
					share = newShares;
					newShares = kInvalidPGPShareRef;

				}
			}
		}
		
 
		
 		if (PGPOptionListRefIsValid (optionList))
				PGPFreeOptionList (optionList);
				
		if (PGPShareRefIsValid (newShares))
			PGPFreeShares (newShares);
			
		if (PGPShareFileRefIsValid (shareFile))
			PGPFreeShareFile (shareFile);
			
		if (PGPFileSpecRefIsValid (shareSpec))
				PGPFreeFileSpec (shareSpec);
 	}

	OPTESTPrintF("\t Getting passkey for shares\n");
 	err = PGPGetPasskeyFromShares (share, &passKey, &passKeySize); 
	 	if(gVerbose_flag)
	{
 		dumpHex(passKey,  passKeySize, 0);
	}
	
	OPTESTPrintF("\t Checking Alice's passphrases with combined passkey\n");
 	err =  PGPPassphraseIsValid( theKey,  
 				PGPOPasskeyBuffer( context, passKey, passKeySize ),
 				PGPOLastOption( context ) )?kPGPError_NoErr:kPGPError_BadPassphrase; CKERR;
 
   done:
	if (PGPFileSpecRefIsValid (shareDirSpec))
				PGPFreeFileSpec (shareDirSpec);
				
 	if( IsntNull( passKey ) )
		PGPFreeData( passKey );
	
	if( PGPShareRefIsValid( share ) )
		PGPFreeShares( share );
  	
	if( PGPKeyDBRefIsValid( keyDB ) )
		PGPFreeKeyDB( keyDB );
 
    return err;

}



/*
 Run Secret sharing test
 */

static PGPError TestShamir(PGPContextRef context)
{
	PGPError	err 			= kPGPError_NoErr;
 	PGPUInt32 	shareSize;
	PGPUInt32	totalSharesSize;
	PGPByte * 	shareBuf 		= NULL;
	PGPUInt32 	i;
	
	PGPByte testData[] = {
		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
		0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
		0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
	};

	PGPByte decodeBuf[sizeof (testData)];
 	
	OPTESTPrintF("\tLow Level Shamir Key splitting Test\n");

 	if(gVerbose_flag)
	{	
		OPTESTPrintF("\t  Original Data:\n");
		dumpHex(testData , sizeof (testData),0);
		OPTESTPrintF("\n");
	}
	
	shareSize = kPGPShareHeaderSize + sizeof (testData);
	totalSharesSize = shareSize * kNumShares;

	shareBuf = (PGPByte *)PGPNewSecureData( PGPGetDefaultMemoryMgr(),
										  totalSharesSize,
										  kPGPMemoryMgrFlags_Clear);

/* TE03.14.02  - Split a binary passphrase */
	OPTESTPrintF("\t Deconstructing data into %d shares\n",kNumShares);
	err = PGPSecretShareData(context,testData, sizeof (testData), kShareThreshold, kNumShares,  shareBuf);
	CKERR;

	if(gVerbose_flag)
	{
		 for( i = 0; i < kNumShares; i++)
		{
			OPTESTPrintF("\t  Share %d:\n", i);
			dumpHex(shareBuf+(shareSize *i)  , shareSize,0);
		}
		OPTESTPrintF("\n");
 	}
	
	OPTESTPrintF("\t Check shares for data leakage against known original message...");
 	for( i = 0; i < kNumShares; i++)
	{
		/*  check shares for data leakage against known original message */
		err = pgpMemoryEqual(shareBuf+(shareSize *i) + kPGPShareHeaderSize,
					   testData,  sizeof (testData))
		? kPGPError_SelfTestFailed : kPGPError_NoErr; 
		CKERR;
 	}
	OPTESTPrintF("OK\n");

	/* Reconstruct data */
	OPTESTPrintF("\t Attempt to Reconstructing data with not enough shares (%d)\n",kShareThreshold -1 );
	err = PGPSecretReconstructData(context, shareBuf, sizeof(testData), kShareThreshold -1, decodeBuf); 
 	if(IsPGPError(err))
	{
		char str[256];

		PGPGetErrorString( err, 256, str);
		OPTESTPrintF("\t     Failed %d - %s\n",err,str);
 	}
	else
		RETERR(kPGPError_SelfTestFailed);
 	
 	/* Reconstruct data */
	OPTESTPrintF("\t Reconstructing data with just %d shares...",kShareThreshold);
	err = PGPSecretReconstructData(context, shareBuf, sizeof(testData), kShareThreshold, decodeBuf); CKERR;
	OPTESTPrintF("OK\n");

	/*  check result against known original message */
	OPTESTPrintF("\t Check result against known original message...");
	err = pgpMemoryEqual(decodeBuf, testData,  sizeof (testData))
		? kPGPError_NoErr : kPGPError_SelfTestFailed; CKERR;
	OPTESTPrintF("OK\n");
 

done:
		if( shareBuf != NULL)
			PGPFreeData(shareBuf);
  
    return err;
}


PGPError TestSecretSharing(PGPContextRef context)
{
	PGPError	err 			= kPGPError_NoErr;

 	err = TestShamir(context); CKERR;
	OPTESTPrintF("\t --------------------\n\n");
	err = TestShares(context); CKERR;
	
done:
  
    return err;

}

⌨️ 快捷键说明

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