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

📄 pgpkeyman.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:

/* Return the amount of entropy needed to create a key of the specified
   type and size.  The application must call pgpRandpoolEntropy() itself
   until it has accumulated this much. */

PGPUInt32
pgpKeyEntropyNeededInternal(
	PGPContextRef	context,
	PGPOptionListRef	optionList
	)
{
	PGPEnv				*pgpEnv;
	PGPUInt32			fastgen;
	PGPBoolean			fastgenop;
	PGPUInt32			noentropy = FALSE;
	PGPUInt32			pkalg;
	PGPUInt32			bits;
	PGPError			err = kPGPError_NoErr;

	if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
						keyentOptionSet, elemsof( keyentOptionSet ) ) ) )
		return err;

	/* If generating with existing entropy, we don't need any amount */
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						kPGPOptionType_KeyGenUseExistingEntropy, FALSE,
						"%d", &noentropy ) ) )
		goto error;
	if (noentropy)
		return 0;
	
	pgpEnv = pgpContextGetEnvironment( context );
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						kPGPOptionType_KeyGenParams, TRUE,
						"%d%d", &pkalg, &bits ) ) )
		goto error;
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						kPGPOptionType_KeyGenFast, FALSE,
						"%b%d", &fastgenop, &fastgen ) ) )
		goto error;
	if( !fastgenop ) {
		fastgen = pgpenvGetInt (pgpEnv, PGPENV_FASTKEYGEN, NULL, NULL);
	}

	return pgpSecKeyEntropy (pgpPkalgByNumber ((PGPByte)pkalg), bits,
							(PGPBoolean)fastgen);

	/* Should not have an error unless bad parameters */
error:
	pgpAssert(0);
	return ~(PGPUInt32)0;
}


/* Internal function for passphraseIsValid */
	static PGPError
sPassphraseIsValid(
	PGPKeyRef		key,
	const char *	passphrase,
	PGPSize			passphraseLength,
	PGPBoolean		hashedPhrase,
	PGPBoolean *	isValid)
{
	RingObject *	keyobj;
	PGPKeyDBRef		keys;
	RingSet const *	ringset;
	PGPContextRef	context;
	PGPEnv *		pgpEnv;
	PGPSecKey *		seckey;
	
	PGPError		err = kPGPError_NoErr;

	PGPValidateKey( key );
	PGPValidateParam( passphrase );
	PGPValidateParam( isValid );

	/* Default return value */
	*isValid = FALSE;

	/* Dig stuff out of key structure */
	keyobj =	key->key;
	keys =		key->keyDB;
	ringset =	pgpKeyDBRingSet (keys);
	context =	keys->context;
	pgpEnv =	pgpContextGetEnvironment( context );

	seckey = ringSecSecKey (ringset, keyobj, 0);

	/* If not a secret key, just return */
	if( !seckey )
		return err;

	/* Returns 1 on success, 0 on failure, else error */
	err = (PGPError)pgpSecKeyUnlock (seckey, pgpEnv, passphrase, 
									passphraseLength, hashedPhrase);
	pgpSecKeyDestroy( seckey );
	if (err == (PGPError)1) {
		*isValid = TRUE;
		err = kPGPError_NoErr;
	}
	return err;
}

	

static const PGPOptionType passphraseisvalidOptionSet[] = {
	kPGPOptionType_Passphrase,
	kPGPOptionType_Passkey
};

	PGPBoolean
pgpPassphraseIsValidInternal(
	PGPKeyRef			key,
	PGPOptionListRef	optionList
	)
{
	PGPContextRef		context;
	char *				passphrase;
	PGPSize				passphraseLength;
	PGPBoolean			hashedPhrase = FALSE;
	PGPBoolean			rslt;
	PGPError			err = kPGPError_NoErr;

	pgpa(pgpaPGPKeyValid(key));
	if ( ! pgpKeyIsValid( key ) )
		return( FALSE );
	
	context = key->keyDB->context;

	if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
								passphraseisvalidOptionSet,
								elemsof( passphraseisvalidOptionSet ) ) ) )
		return FALSE;

	/* Pick up mandatory options */
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_Passphrase, FALSE,
						 "%p%l", &passphrase, &passphraseLength ) ) )
		return FALSE;
	if (IsNull( passphrase )) {
		hashedPhrase = TRUE;
		if( IsPGPError( err = pgpFindOptionArgs( optionList,
							kPGPOptionType_Passkey, TRUE,
							"%p%l", &passphrase, &passphraseLength ) ) )
			return FALSE;
	}

	if( IsPGPError( sPassphraseIsValid( key, passphrase, passphraseLength,
										hashedPhrase, &rslt ) ) )
		return FALSE;

	return rslt;
}

	


/*____________________________________________________________________________
	Key Generation
____________________________________________________________________________*/


/*
 * Callback impedence matching, convert from internal state to callback
 * state.
 */
typedef struct PGPKeyGenProgressState {
	PGPContextRef			context;
	PGPEventHandlerProcPtr	progress;
	PGPUserValue			userValue;
} PGPKeyGenProgressState;
	
static int								/* Return < 0 to abort run */
genProgress(
	void *arg,
	int c
	)
{
	PGPKeyGenProgressState	*s = (PGPKeyGenProgressState *)arg;
	PGPError				err = kPGPError_NoErr;
	PGPOptionListRef		newOptionList = NULL;

	if (IsntNull (s->progress)) {
		err = pgpEventKeyGen (s->context, &newOptionList,
							 s->progress, s->userValue, (PGPUInt32)c);
		if (IsntNull (newOptionList))
			pgpFreeOptionList (newOptionList);
	}
	return err;
}



/*  Common code for generating master keys and subkeys. *masterkey
    is NULL when generating a master key, and is used to return
	the master PGPKey object.  If *masterkey contains a value,
	a subkey is to be generated associated with the PGPKey object. */

	static PGPError
pgpDoGenerateKey (
	PGPKeyDB *		keyDB,
	PGPKey **		masterkey,
	PGPSubKey **	newsubkey,
	PGPByte			pkalg,
	unsigned		bits,
	PGPTime			creationDate,
	PGPUInt16		expirationDays,
	char const *	name,
	int				name_len, 
	char const *	passphrase,
	PGPSize			passphraseLength,
	PGPBoolean		passphraseIsKey,
	char const *	masterpass, 
	PGPSize			masterpassLength,
	PGPEventHandlerProcPtr progress,
	PGPUserValue	userValue,
	PGPBoolean		fastgen,
	PGPBoolean		checkentropy,
	RingSet const *	adkset,
	PGPByte			adkclass,
	RingSet const *	rakset,
	PGPByte			rakclass,
	PGPCipherAlgorithm const * prefalg,
	PGPSize			prefalgLength)
{
	RingSet const			*allset;
	RingSet 				*addset = NULL;
	union RingObject    	*newobj = NULL;
	PGPError	          	error = kPGPError_NoErr;
	PGPSecKey				*seckey = NULL, *masterseckey = NULL;
	PGPKeySpec				*keyspec = NULL;
	long             		entropy_needed, entropy_available;
	PGPBoolean              genMaster = (*masterkey == NULL);
	PGPEnv					*pgpEnv;
	PGPRandomContext		*pgpRng;
	PGPKeyGenProgressState	progressState;
	PGPContextRef			context	= pgpGetKeyDBContext( keyDB );
	PGPByte					*prefalgByte;
	PGPUInt32				i;
	const PGPPkAlg *		algInfo;
	
	if ( !pgpKeyDBIsMutable( keyDB ) )
		return kPGPError_ItemIsReadOnly;

	algInfo = pgpPkalgByNumber( pkalg );
	if( IsntNull( algInfo ) )
	{
		if( ( pgpKeyUse( algInfo ) & PGP_PKUSE_SIGN ) == 0 &&
			genMaster )
		{
			pgpDebugMsg( "Invalid master key algorithm" );
			error = kPGPError_BadParams;
		}
		else if( ( pgpKeyUse( algInfo ) & PGP_PKUSE_ENCRYPT ) == 0 &&
				! genMaster )
		{
			pgpDebugMsg( "Invalid subkey algorithm" );
			error = kPGPError_BadParams;
		}
	}
	else
	{
		pgpDebugMsg( "Invaid public key algorithm" );
		error = kPGPError_BadParams;
	}
	
	if( IsPGPError( error ) )
		goto cleanup;
		
	pgpEnv = pgpContextGetEnvironment( keyDB->context );
	if( checkentropy )
	{
		/* Check we have sufficient random bits to generate the keypair */
		entropy_needed = pgpSecKeyEntropy (algInfo, bits, fastgen);
		entropy_available = PGPGlobalRandomPoolGetEntropy ( );
		if (entropy_needed > entropy_available)
		{
			error = kPGPError_OutOfEntropy;
			goto cleanup;
		}
	}
	
	/* Generate the secret key */
	progressState.progress = progress;
	progressState.userValue = userValue;
	progressState.context = keyDB->context;
	pgpRng = pgpContextGetX9_17RandomContext( keyDB->context );
	seckey = pgpSecKeyGenerate( context, algInfo, bits, fastgen, pgpRng, 
				genProgress, &progressState, &error);
	if (error)
		goto cleanup;
	pgpRandomStir (pgpRng);

	/* Need to lock the SecKey with the passphrase.  */
	if (passphrase && passphraseLength > 0) {
		PGPStringToKeyType s2ktype;
		if (passphraseIsKey) {
			s2ktype = kPGPStringToKey_LiteralShared;
		} else if (seckey->pkAlg <= kPGPPublicKeyAlgorithm_RSA + 2) {
			s2ktype = kPGPStringToKey_Simple;
		} else {
			s2ktype = kPGPStringToKey_IteratedSalted;
		}
		error = (PGPError)pgpSecKeyChangeLock (seckey, pgpEnv, pgpRng, 
									passphrase, passphraseLength,
									s2ktype);
		if (error)
			goto cleanup;
	}

	/*  Generate the keyring objects.  Use keyspec defaults except for 
		expiration (validity) period */
	keyspec = pgpKeySpecCreate (pgpEnv);
	if (!keyspec) {
		error = kPGPError_OutOfMemory;
		goto cleanup;
	}
	
	if( creationDate != 0 )
	{
		pgpKeySpecSetCreation(keyspec, creationDate +
				(60 * 60 * pgpenvGetInt(pgpEnv, PGPENV_TZFIX,  NULL, NULL)));
	}
	
	pgpKeySpecSetValidity (keyspec, expirationDays);

	allset = pgpKeyDBRingSet (keyDB);

	if (genMaster) {
	   /* Generating master signing key */  
	   addset = ringSetCreate (ringSetPool (allset));
		if (!addset) {
		   error = kPGPError_OutOfMemory;
			goto cleanup;
		}
		prefalgByte = NULL;
		if (prefalgLength > 0) {
			/* Convert preferred algorithm to byte array */
			prefalgLength /= sizeof(PGPCipherAlgorithm);
			prefalgByte = (PGPByte *)pgpContextMemAlloc( context,
														prefalgLength, 0);
			if( IsNull( prefalgByte ) ) {
				error = kPGPError_OutOfMemory;
				goto cleanup;
			}
			for (i=0; i<prefalgLength; ++i) {
				prefalgByte[i] = (PGPByte)prefalg[i];
			}
		}
	   newobj = ringCreateKeypair (pgpEnv, seckey, keyspec, name,
									name_len, pgpRng, addset, addset,
									rakset, rakclass,
									prefalgByte, prefalgLength,
								    adkset, adkclass,
									&error);
		if( IsntNull( prefalgByte ) ) {
			pgpContextMemFree( context, prefalgByte );
		}
	}
	else {
	   /* Generating encryption subkey.  Get the master seckey and 
		  unlock it */
	   error = pgpCopyKey (allset, (*masterkey)->key, &addset);
		if (error)
		   goto cleanup;
	   masterseckey = ringSecSecKey (allset, (*masterkey)->key, 
									 PGP_PKUSE_SIGN);
		if (!masterseckey) {
		   error = ringSetError(allset)->error;
			goto cleanup;
		}
		if (pgpSecKeyIslocked (masterseckey)) {
		   if (IsNull( masterpass )) {
			   error = kPGPError_BadPassphrase;
			   goto cleanup;
			}
			error = (PGPError)pgpSecKeyUnlock (masterseckey, pgpEnv,
										masterpass, masterpassLength, FALSE);
			if (error != 1) {
			   if (error == 0) 
				   error = kPGPError_BadPassphrase;
				goto cleanup;
			}
		}
	   newobj = ringCreateSubkeypair (pgpEnv, masterseckey, seckey,
									keyspec, pgpRng, addset, addset, &error);
	}
	pgpRandomStir (pgpRng);		/* this helps us count randomness in pool */
	if (error)
		goto cleanup;

	/*  Add objects to main KeyDB.  Before doing so, locate
	   the master key object and return it. */
	ringSetFreeze (addset);
	error = pgpAddObjects (keyDB, addset);
	if (genMaster && !error) {
	   *masterkey = pgpGetKeyByRingObject (keyDB, newobj);
	} else if (!genMaster && !error && IsntNull( newsubkey ) ) {
		PGPSubKey *subk = (PGPSubKey *) (*masterkey)->subKeys.next;
		while( subk != (PGPSubKey *) &(*masterkey)->subKeys ) {
			if( subk->subKey == newobj )
				break;
			subk = subk->next;
		}
		pgpAssert( subk->subKey == newobj );
		*newsubkey = subk;
	}

cleanup:
	if (addset)
		ringSetDestroy (addset);
	if (seckey)
		pgpSecKeyDestroy (seckey);
	if (masterseckey)
	   pgpSecKeyDestroy (masterseckey);
	if (keyspec)
		pgpKeySpecDestroy (keyspec);
	return error;
}


static const PGPOptionType keygenOptionSet[] = {
	kPGPOptionType_KeySetRef,
	kPGPOptionType_KeyGenParams,
	kPGPOptionType_KeyGenName,
	kPGPOptionType_Passphrase,
	kPGPOptionType_Passkey,
	kPGPOptionType_Expiration,
	kPGPOptionType_CreationDate,
	kPGPOptionType_EventHandler,
	kPGPOptionType_PreferredAlgorithms,
	kPGPOptionType_AdditionalRecipientRequestKeySet,
	kPGPOptionType_RevocationKeySet,
	kPGPOptionType_KeyGenFast,
	kPGPOptionType_KeyGenUseExistingEntropy
};

PGPError
pgpGenerateKeyInternal(
	PGPContextRef		context,
	PGPKeyRef			*key,
	PGPOptionListRef	optionList
	)
{
	PGPKeySetRef		keyset;
	PGPUInt32			pkalg;
	PGPUInt32			bits;
	PGPUInt32			expiration;
	PGPTime				creationDate;
	PGPByte				*name;
	PGPUInt32			nameLength;
	PGPByte				*passphrase;
	PGPUInt32			passphraseLength;
	PGPBoolean			passphraseIsKey = FALSE;
	PGPKeySetRef		adkset;
	PGPUInt32			adkclass;
	PGPKeySetRef		rakset = NULL;
	PGPUInt32			rakclass = 0;
	PGPEventHandlerProcPtr progress;
	PGPUserValue		userValue;
	RingSet const		*adkringset = NULL;
	RingSet const		*rakringset = NULL;
	PGPKeyRef			newkey;
	PGPCipherAlgorithm	*prefalg;
	PGPSize				prefalgLength;
	PGPEnv				*pgpEnv;
	PGPBoolean			fastgenop;
	PGPUInt32			fastgen;
	PGPUInt32			noentropy = FALSE;
	PGPError			err;

	if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
						keygenOptionSet, elemsof( keygenOptionSet ) ) ) )
		return err;

	if( IsNull( key ) )
		return kPGPError_BadParams;

	pgpEnv = pgpContextGetEnvironment( context );

	/* First pick up mandatory options */
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						kPGPOptionType_KeySetRef, TRUE,
						"%p", &keyset ) ) )
		goto error;

⌨️ 快捷键说明

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