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

📄 pgpreconstruct.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 4 页
字号:

			mod[3] = NULL;

			err = PGPldapAddSync( ldap, dn, mod );
		}
	}
	CKERR;

done:

	if( IsntNull( exportedKey ) )
	{
		(void) PGPFreeData( exportedKey );
		exportedKey = NULL;
	}

	return err;
}


	PGPError
PGPSetReconstructionEventHandler(
	PGPReconContextRef			reconRef,
	PGPReconstructEventHandler	inHandler,
	PGPUserValue				inUserValue )
{
	PGPError					err = kPGPError_NoErr;
	PGPReconContextPriv *		con = (PGPReconContextPriv *)reconRef;
	
	PGPValidatePtr( reconRef );
	
	con->handler = inHandler;
	con->userValue = inUserValue;
	
	return err;
}


	PGPError
PGPMakeReconstruction(
	PGPReconContextRef			reconRef,
	PGPReconPrompts 			inPromptInfo,
	PGPReconPasses				inPassInfo,
	char						*inPassphrase )
{
	PGPError					err = kPGPError_NoErr;
	PGPReconContextPriv *		con = (PGPReconContextPriv *)reconRef;
	PGPKeyDBRef					unlockDB = kInvalidPGPKeyDBRef;
	PGPKeyDBObjRef				udbTarget = kInvalidPGPKeyDBObjRef;
	PGPKeySetRef				udbSet = kInvalidPGPKeySetRef; /* do not free */
	PGPKeyListRef				udbList = kInvalidPGPKeyListRef;
	PGPKeyIterRef				udbIter = kInvalidPGPKeyIterRef;
	PGPKeyDBObjRef				udbObj = kInvalidPGPKeyDBObjRef;
	PGPHashContextRef			hashCon = kInvalidPGPHashContextRef;
	PGPSymmetricCipherContextRef symmCon = kInvalidPGPSymmetricCipherContextRef;
	PGPCBCContextRef			cbcCon = kInvalidPGPCBCContextRef;
	PGPUInt32					shareIndex;
	PGPUInt16					hashReps;
	PGPByte						*rawExport = NULL;
	PGPByte						*blockKey = NULL;
	PGPByte						*blockShares = NULL;
	PGPByte						*innerBlock = NULL;
	PGPByte						*outerBlock = NULL;
	PGPByte						*blockWalk = NULL;	/* do not free */
	PGPByte						*shareWalk = NULL;	/* do not free */
	PGPSize						rawExportSize = 0,
								innerBlockLen = 0,
								innerKeyBlockLen = 0,
								innerBlockPadLen = 0,
								outerBlockLen = 0;
	PGPByte						zeroIV[kReconCipherBlockSize];
	PGPUInt16					hashIndex;
	PGPByte						hashMagic[sizeof(PGPUInt32)];
	PGPByte						hashOut[20];
	PGPByte						tempShare[kReconShareSize];
	PGPBoolean					secretKey;
	
	pgpClearMemory( zeroIV, kReconCipherBlockSize );
	(void)PGPGetKeyDBObjBooleanProperty( con->targetKey,
			kPGPKeyProperty_IsSecret, &secretKey );
	if( !secretKey )
		return kPGPError_SecretKeyNotFound;
	
	/*	First Wrap */
	err = PGPNewKeyDB( con->context, &unlockDB );						CKERR;
	err = PGPCopyKeyDBObj( con->targetKey, unlockDB, &udbTarget );		CKERR;
	err = PGPChangePassphrase( udbTarget, 
			PGPOPassphrase( con->context, inPassphrase ),
			PGPOPassphrase( con->context, "" ),
			PGPOLastOption( con->context ) );							CKERR;
	udbSet = PGPPeekKeyDBRootKeySet( unlockDB );
	err = PGPOrderKeySet( udbSet, kPGPKeyOrdering_Any, FALSE, &udbList );CKERR;
	err = PGPNewKeyIter( udbList, &udbIter );							CKERR;
	PGPKeyIterSeek( udbIter, udbTarget );
	while( IsntPGPError( err ) && IsntPGPError(
		PGPKeyIterNextKeyDBObj( udbIter, kPGPKeyDBObjType_SubKey, &udbObj ) ) &&
		PGPKeyDBObjRefIsValid( udbObj ) )
	{
		err = PGPChangePassphrase( udbObj, 
				PGPOPassphrase( con->context, inPassphrase ),
				PGPOPassphrase( con->context, "" ),
				PGPOLastOption( con->context ) );						CKERR;
	}
	err = PGPExport( con->context,
			PGPOExportKeyDBObj( con->context, udbTarget ),
			PGPOAllocatedOutputBuffer( con->context, (void **) &rawExport,
					MAX_PGPUInt32, &rawExportSize ),
			PGPOExportPrivateKeys( con->context, TRUE ),
			PGPOExportFormat( con->context, kPGPExportFormat_Complete ),
			PGPOArmorOutput( con->context, FALSE ),
			PGPOLastOption( con->context ) );							CKERR;
	innerBlockLen = rawExportSize + sizeof(PGPUInt32);
	while( innerBlockLen % kReconCipherBlockSize )
		innerBlockLen++;
	innerKeyBlockLen = innerBlockLen;
	innerBlockLen += sizeof(PGPKeyID) + sizeof(PGPUInt16) +
						( kReconShareSize * kPGPRecon_NumShares );
	innerBlock = (PGPByte *)PGPNewSecureData( con->memMgr,
						innerBlockLen, kPGPMemoryMgrFlags_Clear);		CKERR;
	blockKey = (PGPByte *)PGPNewSecureData( con->memMgr,
						kReconstructWrapKeySize,
						kPGPMemoryMgrFlags_Clear);						CKERR;
	blockShares = (PGPByte *)PGPNewSecureData( con->memMgr,
						kReconNaturalShareSize * kPGPRecon_NumShares,
						kPGPMemoryMgrFlags_Clear);						CKERR;
	err = PGPGetKeyID( con->targetKey, (PGPKeyID *)innerBlock );		CKERR;
	err = PGPContextGetRandomBytes( con->context, blockKey,
						kReconstructWrapKeySize );						CKERR;
	err = PGPSecretShareData( con->context, blockKey, kReconstructWrapKeySize,
			kPGPRecon_Threshold, kPGPRecon_NumShares, blockShares );	CKERR;
	do
	{
		err = PGPContextGetRandomBytes( con->context, &hashReps,
							sizeof(PGPUInt16) );						CKERR;
	} while ( !hashReps || ( hashReps > kReconMaxHashReps ) );
	blockWalk = innerBlock + sizeof(PGPKeyID);
	*blockWalk++ = ( hashReps >> 8 ) & 0xFF;
	*blockWalk++ = hashReps & 0xFF;
	shareWalk = blockShares;
	err = PGPNewHashContext( con->context,
			kPGPHashAlgorithm_SHA, &hashCon );							CKERR;
	err = PGPNewSymmetricCipherContext( con->context,
			kPGPCipherAlgorithm_CAST5, &symmCon );						CKERR;
	err = PGPNewCBCContext( symmCon, &cbcCon );							CKERR;
	PGPUInt32ToEndian( kReconInnerMagic, kPGPBigEndian, hashMagic );
	for( shareIndex = 0; shareIndex < kPGPRecon_NumShares; shareIndex++ )
	{
		for( hashIndex = 0; hashIndex < hashReps; hashIndex++ )
		{
			(void) PGPContinueHash( hashCon, inPassInfo[shareIndex],
					strlen( inPassInfo[shareIndex] ) );
			(void) PGPContinueHash( hashCon, hashMagic, sizeof(hashMagic) );
		}
		err = PGPFinalizeHash( hashCon, hashOut );							CKERR;
		err = PGPResetHash( hashCon );										CKERR;
		pgpClearMemory( tempShare, sizeof(tempShare) );
		pgpCopyMemory( shareWalk, tempShare, kReconNaturalShareSize );
		shareWalk += kReconNaturalShareSize;
		err = PGPInitCBC( cbcCon, hashOut, zeroIV );						CKERR;
		err = PGPCBCEncrypt( cbcCon, tempShare, kReconShareSize, blockWalk );CKERR;
		blockWalk += kReconShareSize;
		pgpClearMemory( hashOut, sizeof(hashOut) );
	}
	PGPUInt32ToEndian( rawExportSize, kPGPBigEndian, blockWalk );
	pgpCopyMemory( rawExport, blockWalk + sizeof(PGPUInt32), rawExportSize );
	err = PGPInitCBC( cbcCon, blockKey, zeroIV );							CKERR;
	err = PGPCBCEncrypt( cbcCon, blockWalk, innerKeyBlockLen, blockWalk );	CKERR;
	/* innerBlock First Wrap complete */
	
	/*	Second Wrap */
	innerBlockPadLen = innerBlockLen;
	while( innerBlockPadLen % kReconCipherBlockSize )
		innerBlockPadLen++;
	outerBlockLen = sizeof(PGPKeyID) + sizeof(PGPReconPrompts) + sizeof(PGPUInt16) +
		sizeof(PGPUInt32) + kReconShareSize * kPGPRecon_NumShares + innerBlockPadLen;
	outerBlock = (PGPByte *)PGPNewSecureData( con->memMgr,
						outerBlockLen, kPGPMemoryMgrFlags_Clear);		CKERR;
	err = PGPGetKeyID( con->targetKey, (PGPKeyID *)outerBlock );		CKERR;
	blockWalk = outerBlock + sizeof(PGPKeyID);
	pgpCopyMemory( inPromptInfo, blockWalk, sizeof(PGPReconPrompts) );
	blockWalk += sizeof(PGPReconPrompts);
	*blockWalk++ = ( hashReps >> 8 ) & 0xFF;
	*blockWalk++ = hashReps & 0xFF;
	PGPUInt32ToEndian( innerBlockPadLen, kPGPBigEndian, blockWalk );
	blockWalk += sizeof(PGPUInt32);
	err = PGPContextGetRandomBytes( con->context, blockKey,
						kReconstructWrapKeySize );						CKERR;
	err = PGPSecretShareData( con->context, blockKey, kReconstructWrapKeySize,
			kPGPRecon_Threshold, kPGPRecon_NumShares, blockShares );	CKERR;
	PGPUInt32ToEndian( kReconOuterMagic, kPGPBigEndian, hashMagic );
	shareWalk = blockShares;
	for( shareIndex = 0; shareIndex < kPGPRecon_NumShares; shareIndex++ )
	{
		for( hashIndex = 0; hashIndex < hashReps; hashIndex++ )
		{
			(void) PGPContinueHash( hashCon, inPassInfo[shareIndex],
					strlen( inPassInfo[shareIndex] ) );
			(void) PGPContinueHash( hashCon, hashMagic, sizeof(hashMagic) );
		}
		err = PGPFinalizeHash( hashCon, hashOut );							CKERR;
		err = PGPResetHash( hashCon );										CKERR;
		pgpClearMemory( tempShare, sizeof(tempShare) );
		pgpCopyMemory( shareWalk, tempShare, kReconNaturalShareSize );
		shareWalk += kReconNaturalShareSize;
		err = PGPInitCBC( cbcCon, hashOut, zeroIV );						CKERR;
		err = PGPCBCEncrypt( cbcCon, tempShare, kReconShareSize, blockWalk );CKERR;
		blockWalk += kReconShareSize;
		pgpClearMemory( hashOut, sizeof(hashOut) );
	}
	pgpCopyMemory( innerBlock, blockWalk, innerBlockLen );
	err = PGPInitCBC( cbcCon, blockKey, zeroIV );							CKERR;
	err = PGPCBCEncrypt( cbcCon, blockWalk, innerBlockPadLen, blockWalk );	CKERR;

	con->blobData = outerBlock;
	con->blobDataSize = outerBlockLen;

#ifdef PGPRECONSELFTEST
	PGPKeyDBRef	testKeyDB = kInvalidPGPKeyDBRef;
	
	err = PGPReconstruct( reconRef, inPromptInfo, inPassInfo, &testKeyDB );
	if( PGPKeyDBRefIsValid( testKeyDB ) )
		(void)PGPFreeKeyDB( testKeyDB );
#endif
	

done:
	if( PGPCBCContextRefIsValid( cbcCon ) )
		(void) PGPFreeCBCContext( cbcCon );
	if( PGPHashContextRefIsValid( hashCon ) )
		(void) PGPFreeHashContext( hashCon );
	if( IsntNull( blockShares ) )
		(void) PGPFreeData( blockShares );
	if( IsntNull( blockKey ) )
		(void) PGPFreeData( blockKey );
	if( IsntNull( innerBlock ) )
		(void) PGPFreeData( innerBlock );
	if( IsntNull( rawExport ) )
	{
		pgpClearMemory( rawExport, rawExportSize );
		(void) PGPFreeData( rawExport );
	}
	if( PGPKeyIterRefIsValid( udbIter ) )
		(void) PGPFreeKeyIter( udbIter );
	if( PGPKeyListRefIsValid( udbList ) )
		(void) PGPFreeKeyList( udbList );
	if( PGPKeyDBRefIsValid( unlockDB ) )
		(void) PGPFreeKeyDB( unlockDB );

	return err;
}

	PGPError
PGPGetReconstruction(
	PGPReconContextRef			reconRef,
	PGPByte 					**reconData,
	PGPSize 					*reconDataSize )
{
	PGPError					err = kPGPError_NoErr;
	PGPReconContextPriv *		con = (PGPReconContextPriv *)reconRef;

	PGPValidatePtr( reconRef );
	PGPValidatePtr( reconData );
	PGPValidatePtr( reconDataSize );

	pgpAssert( con->blobDataSize > 0 );
	PGPValidatePtr( con->blobData );
	
	*reconData = (PGPByte *)PGPNewSecureData( con->memMgr,
		con->blobDataSize,
		kPGPMemoryMgrFlags_Clear );
	if( IsNull( *reconData ) )
	{
		err = kPGPError_OutOfMemory;
		goto done;
	}

	pgpCopyMemory( con->blobData, reconData, con->blobDataSize );
	*reconDataSize = con->blobDataSize;

done:
	return err;
}

	PGPError
PGPSendReconstruction(
	PGPReconContextRef			reconRef )
{
	PGPError					err = kPGPError_NoErr;
	PGPReconContextPriv *		con = (PGPReconContextPriv *)reconRef;
	PGPUInt32					numValue;
	char						serverURL[256];
	PGPKeyServerClass			serverClass;
	PGPKeyID					keyid;
	PGPEvent					event;
	char						szKeyID[kPGPMaxKeyIDStringSize] = { 0 };
	char *						dn = NULL;
	char *						userDN = NULL;
	PGPSize						dnLength = 0;
	PGPSize						numVars = 0;
	PGPldapContextRef			ldap = kInvalidPGPldapContextRef;
	PGPldapURLDesc				*lud = NULL;
	PGPBoolean					bSecure = FALSE;
	PGPtlsContextRef			tlsContext = kInvalidPGPtlsContextRef;
	PGPtlsSessionRef			tlsSession = kInvalidPGPtlsSessionRef;

	/*	Check Server Info */
#ifndef PGP_CMDLINE
	err = PGPGetPrefStringBuffer( con->clientPrefs, kPGPPrefLDAPReconServer,
				sizeof(serverURL), serverURL );	CKERR;
	err = PGPGetPrefNumber( con->clientPrefs, kPGPPrefLDAPReconServerType,
				&numValue );	CKERR;
#else /* PGP_CMDLINE */
	numValue = con->serverType;
	strcpy(serverURL, con->szServerURL);
#endif /* PGP_CMDLINE */
	serverClass = (PGPKeyServerClass) numValue;
	if( !strlen( serverURL ) )
	{
		err = kPGPError_BadParams;
		goto done;
	}

	/*	Send Wrapper to Server */
	err = PGPNewLDAPContext( con->context, &ldap );						CKERR;

	/*
	 * PGPldapURLParse needs the server URL to be an actual URL, meaning
	 * that it has at the minimum "ldap://x.x.x.x/".  We add the trailing
	 * '/' to make the URL fit this form.
	 */
	if( serverClass == kPGPKeyServerClass_PGP )
		strcat( serverURL, "/" );
	
	err = PGPldapURLParse( ldap, serverURL, &lud );						CKERR;

	if( strstr( serverURL, "ldaps://" ) != NULL )
		bSecure = TRUE;

	if( lud->port == 0 )
		lud->port = bSecure ? kPGPldap_DefaultSecurePort : kPGPldap_DefaultPort;
	
	pgpClearMemory( &event, sizeof(PGPEvent) );
	event.type = kPGPEvent_KeyServerEvent;
	event.data.keyServerData.state = kPGPKeyServerState_Opening;
	if( IsntNull( con->handler ) )
		err = con->handler( con->context, &event, con->userValue );		CKERR;

	err = sCountLDAPVariables( lud->dn, &numVars );						CKERR;

	userDN = (char *) PGPNewData( con->memMgr, 
			strlen( lud->dn ) + 
			( IsntNull( con->authUser ) ? strlen( con->authUser ) : 0 ) * numVars + 
			1,
			kPGPMemoryMgrFlags_Clear );
	if( IsNull( userDN ) )
	{
		err = kPGPError_OutOfMemory;
		goto done;
	}
	err = sReplaceLDAPVariables( lud->dn, con->authUser, userDN );CKERR;
	
	err = PGPldapOpen( ldap, lud->host, lud->port );					CKERR;

	if( bSecure )
	{
		err = sEstablishTLSSession( con->context,
			ldap, 
			&tlsContext, 
			&tlsSession );
		if( IsPGPError( err ) )
		{
			(void) sSendTLSEvent( con->context, con->handler, con->userValue,
				kPGPKeyServerState_TLSUnableToSecureConnection, tlsSession );
			goto done;
		}
		else
		{
			err = sSendTLSEvent( con->context, con->handler, con->userValue,
				kPGPKeyServerState_TLSConnectionSecured, tlsSession ); CKERR;
		}
	}

	err = PGPldapSimpleBindSync( ldap, userDN, con->authPass );			CKERR;

	err = PGPGetKeyID( con->targetKey, &keyid );						CKERR;
	err = PGPGetKeyIDString( &keyid, kPGPKeyIDString_Full, szKeyID );	CKERR;

	/*
	 * If using PGP certserver, we need to allocate enough extra
	 * room for the DN we get later from querying cn=PGPServerInfo.
	 */
	if( serverClass == kPGPKeyServerClass_PGP )
		dnLength = sizeof( serverURL );
	else
		dnLength = strlen( userDN );

⌨️ 快捷键说明

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