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

📄 pgpreconstruct.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 4 页
字号:
	if( !strlen( serverURL ) )
	{
		err = kPGPError_BadParams;
		goto done;
	}

	if( serverClass == kPGPKeyServerClass_PGP )
	{
		/*
		 * We have the hashed passphrases in inPassInfo[...] and the
		 * number of hash repetitions in con->hashReps.
		 */

		err = PGPNewLDAPContext( con->context, &ldap );						CKERR;
		if( IsNull( ldap ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}

		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;

		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 = PGPNewHashContext( con->context,
			kPGPHashAlgorithm_SHA, &hashCon );									CKERR;

		/* Hash all 5 outer keys */
		PGPUInt32ToEndian( kReconOuterMagic, kPGPBigEndian, hashMagic );
		for( shareIndex = 0; shareIndex < kPGPRecon_NumShares; shareIndex++ )
		{
			for( hashIndex = 0; hashIndex < con->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;
			pgpCopyMemory( hashOut, passKey[shareIndex], kReconstructWrapKeySize );
			pgpClearMemory( hashOut, sizeof(hashOut) );
		}

		len = sArmorLine( (PGPByte *) passKey, 
			kPGPRecon_NumShares * kReconstructWrapKeySize,
			(char *) szArmoredPassKey );
		szArmoredPassKey[len] = '\0';

		err = sGetCertserverLocation( ldap, szCertserverDN );				CKERR;

		err = PGPNewLDAPMessage( ldap, &message );							CKERR;
		if( IsNull( message ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}

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

		dn = (char *)PGPNewData( con->memMgr, 
				strlen( kPGPReconCertIDAttr ) + sizeof( "=" ) + strlen( szKeyID ) +
				sizeof( ", " ) +  strlen( szCertserverDN ) + 1, 
				kPGPMemoryMgrFlags_Clear );
		if( IsNull( dn ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		
		sprintf( dn, "%s=%s, %s", kPGPReconCertIDAttr, szKeyID + 2, szCertserverDN );

		err = PGPldapBindSync( ldap, dn, szArmoredPassKey, kPGPldapAuth_Simple );CKERR;

		attrs[0] = kPGPReconDataAttr;
		attrs[1] = NULL;

		err = PGPldapSearchSync( ldap, 
			dn, 
			kPGPldapScope_Base,
			kPGPObjectclassAny,
			attrs,
			FALSE,
			message );
		if( err == kPGPError_LDAPNoSuchObject )
			err = kPGPError_ItemNotFound;
		CKERR;

		err = PGPldapGetValuesLen( ldap, message, kPGPReconDataAttr, &berValues );CKERR;

		if( IsNull( berValues ) )
		{
			err = kPGPError_ItemNotFound;
			goto done;
		}

		con->blobDataSize = berValues[0]->length;
		con->blobData = (PGPByte *)PGPNewSecureData( con->memMgr, con->blobDataSize,
			kPGPMemoryMgrFlags_Clear );
		if( IsNull( con->blobData ) )
		{
			con->blobDataSize = 0;
			err = kPGPError_OutOfMemory;
			goto done;
		}
		pgpCopyMemory( berValues[0]->value, con->blobData, con->blobDataSize );
	}
	
	*outReconData = (PGPByte *)PGPNewSecureData( con->memMgr,
		con->blobDataSize, kPGPMemoryMgrFlags_Clear );
	if( IsNull( *outReconData ) )
	{
		err = kPGPError_OutOfMemory;
		goto done;
	}

	pgpCopyMemory( con->blobData, *outReconData, con->blobDataSize );
	*outReconSize = con->blobDataSize;

done:
	if( PGPtlsContextRefIsValid( tlsContext ) )
		(void) PGPFreeTLSContext( tlsContext );
	if( PGPtlsSessionRefIsValid( tlsSession ) )
		(void) PGPFreeTLSSession( tlsSession );
	if( IsntNull( dn ) )
		(void) PGPFreeData( dn );
	if( IsntNull( lud ) )
		(void) PGPFreeLDAPURLDesc( lud );
	if( IsntNull( berValues ) )
		(void) PGPFreeLDAPValuesLen( berValues );
	if( PGPldapMessageRefIsValid( message ) )
		(void) PGPFreeLDAPMessage( message );
	if( PGPldapContextRefIsValid( ldap ) )
		(void) PGPFreeLDAPContext( ldap );
	if( PGPHashContextRefIsValid( hashCon ) )
		(void) PGPFreeHashContext( hashCon );

	return err;
}


	PGPError
PGPReconstruct(
	PGPReconContextRef			reconRef,
	PGPReconPasses				inPassInfo,
	PGPByte						*inReconData,
	PGPSize						inReconDataSize,
	PGPKeyDBRef					*outReconstructedKey )
{
	PGPError					err = kPGPError_NoErr;
	PGPReconContextPriv *		con = (PGPReconContextPriv *)reconRef;
	PGPByte						zeroIV[kReconCipherBlockSize];
	PGPByte						*blockWalk;
	PGPKeyID					targetKeyID;
	PGPUInt16					hashReps;
	PGPUInt32					innerBlockPadLen,
								innerBlockLen;
	PGPByte						*innerBlock = NULL;
	PGPUInt16					matrixIndex[kPGPRecon_Threshold];
	PGPUInt16					matrixIndex2[kPGPRecon_Threshold];
	PGPUInt32					hashIndex,
								shareIndex;
	PGPByte						passKey[kPGPRecon_NumShares][kReconstructWrapKeySize];
	PGPByte						shares[kPGPRecon_Threshold][kReconNaturalShareSize];
	PGPSymmetricCipherContextRef symmCon = kInvalidPGPSymmetricCipherContextRef;
	PGPCBCContextRef			cbcCon = kInvalidPGPCBCContextRef;
	PGPHashContextRef			hashCon = kInvalidPGPHashContextRef;
	PGPByte						hashMagic[sizeof(PGPUInt32)];
	PGPByte						hashOut[20];
	PGPByte						shareOut[kReconShareSize];
	PGPByte						blockKey[kReconstructWrapKeySize];
	
	*outReconstructedKey = kInvalidPGPKeyDBRef;
	pgpClearMemory( zeroIV, kReconCipherBlockSize );

	err = PGPNewHashContext( con->context,
			kPGPHashAlgorithm_SHA, &hashCon );									CKERR;

	blockWalk = inReconData;
	if( inReconDataSize < kReconMinBlobSize )
	{
		err = kPGPError_KeyInvalid;
		goto done;
	}
	err = PGPGetKeyID( con->targetKey, &targetKeyID );							CKERR;
	if( PGPCompareKeyIDs( (PGPKeyID *)blockWalk, &targetKeyID ) )
	{
		err = kPGPError_KeyInvalid;
		goto done;
	}
	blockWalk += sizeof(PGPKeyID) + sizeof(PGPReconPrompts);
	hashReps = PGPEndianToUInt16( kPGPBigEndian, blockWalk );

	/* Hash all 5 outer keys */
	PGPUInt32ToEndian( kReconOuterMagic, 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;
		pgpCopyMemory( hashOut, passKey[shareIndex], kReconstructWrapKeySize );
		pgpClearMemory( hashOut, sizeof(hashOut) );
	}
	
	/*	Unwrap outer layer */
	blockWalk = inReconData;
	blockWalk += sizeof(PGPKeyID) + sizeof(PGPReconPrompts);
	blockWalk += sizeof(PGPUInt16);
	innerBlockPadLen = PGPEndianToUInt32( kPGPBigEndian, blockWalk );
	blockWalk += sizeof(PGPUInt32);
	
	err = PGPNewSymmetricCipherContext( con->context,
			kPGPCipherAlgorithm_CAST5, &symmCon );							CKERR;
	err = PGPNewCBCContext( symmCon, &cbcCon );								CKERR;
	innerBlock = (PGPByte *)PGPNewSecureData( con->memMgr,
						innerBlockPadLen, kPGPMemoryMgrFlags_Clear);		CKERR;
	
	/* Try all possible combinations of 3 keys against innerBlock		*/
	/* Use only 3 so that some wrong answers don't penalize				*/
	/* Going 6 levels deep, redented for readability...					*/
		for( matrixIndex[0] = 0; matrixIndex[0] < kPGPRecon_NumShares; matrixIndex[0]++ )
	{	for( matrixIndex[1] = 0; matrixIndex[1] < kPGPRecon_NumShares; matrixIndex[1]++ )
	{	for( matrixIndex[2] = 0; matrixIndex[2] < kPGPRecon_NumShares; matrixIndex[2]++ )
	{
		if( ( matrixIndex[0] == matrixIndex[1] ) || ( matrixIndex[1] == matrixIndex[2] ) ||
			( matrixIndex[2] == matrixIndex[0] ) )
			continue;
		for( matrixIndex2[0] = 0; matrixIndex2[0] < kPGPRecon_NumShares; matrixIndex2[0]++ )
	{	for( matrixIndex2[1] = 0; matrixIndex2[1] < kPGPRecon_NumShares; matrixIndex2[1]++ )
	{	for( matrixIndex2[2] = 0; matrixIndex2[2] < kPGPRecon_NumShares; matrixIndex2[2]++ )
	{
		if( ( matrixIndex2[0] == matrixIndex2[1] ) || ( matrixIndex2[1] == matrixIndex2[2] ) ||
			( matrixIndex2[2] == matrixIndex2[0] ) )
			continue;
		for( shareIndex = 0; shareIndex < kPGPRecon_Threshold; shareIndex++ )
		{
			err = PGPInitCBC( cbcCon, passKey[matrixIndex[shareIndex]], zeroIV );	CKERR;
			err = PGPCBCDecrypt( cbcCon, blockWalk +
					kReconShareSize * matrixIndex2[shareIndex],
					kReconShareSize, shareOut );									CKERR;
			pgpCopyMemory( shareOut, shares[shareIndex], kReconNaturalShareSize );
		}
		if( ( shares[0][0] != kPGPShare_Version1 ) ||
			( shares[1][0] != kPGPShare_Version1 ) ||
			( shares[2][0] != kPGPShare_Version1 ) )
			continue;
		err = PGPSecretReconstructData( con->context, shares, 
				kReconstructWrapKeySize, kPGPRecon_Threshold, blockKey );
		if( IsPGPError( err ) )
		{
			err = kPGPError_NoErr;
			continue;
		}
		err = PGPInitCBC( cbcCon, blockKey, zeroIV );								CKERR;
		err = PGPCBCDecrypt( cbcCon, blockWalk + kReconShareSize * kPGPRecon_NumShares,
				innerBlockPadLen, innerBlock );										CKERR;
		if( !PGPCompareKeyIDs( (PGPKeyID *)innerBlock, &targetKeyID ) )
		{
			/* Outer layer has been removed */
			goto foundCombo;
		}
	}}}}}}
	err = kPGPError_BadPassphrase;
	goto done;
foundCombo:
	/*	Unwrap inner layer */
	blockWalk = innerBlock + sizeof(PGPKeyID);
	if( hashReps != PGPEndianToUInt16( kPGPBigEndian, blockWalk ) )
	{
		err = kPGPError_BadPassphrase;
		goto done;
	}
	blockWalk += sizeof(PGPUInt16);
	/* Hash all 5 inner keys */
	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;
		pgpCopyMemory( hashOut, passKey[shareIndex], kReconstructWrapKeySize );
		pgpClearMemory( hashOut, sizeof(hashOut) );
	}
	/* Decrypt the shares */
	for( shareIndex = 0; shareIndex < kPGPRecon_Threshold; shareIndex++ )
	{
		err = PGPInitCBC( cbcCon, passKey[matrixIndex[shareIndex]], zeroIV );	CKERR;
		err = PGPCBCDecrypt( cbcCon, blockWalk +
				kReconShareSize * matrixIndex2[shareIndex],
				kReconShareSize, shareOut );									CKERR;
		pgpCopyMemory( shareOut, shares[shareIndex], kReconNaturalShareSize );
	}
	err = PGPSecretReconstructData( con->context, shares, 
			kReconstructWrapKeySize, kPGPRecon_Threshold, blockKey );
	if( IsPGPError( err ) )
	{
		err = kPGPError_BadPassphrase;
		goto done;
	}
	blockWalk += kReconShareSize * kPGPRecon_NumShares;
	innerBlockPadLen -= sizeof(PGPKeyID) + sizeof(PGPUInt16) +
						kReconShareSize * kPGPRecon_NumShares;
	while( innerBlockPadLen % kReconCipherBlockSize )
		innerBlockPadLen--;
	err = PGPInitCBC( cbcCon, blockKey, zeroIV );								CKERR;
	err = PGPCBCDecrypt( cbcCon, blockWalk, innerBlockPadLen, blockWalk );		CKERR;
	innerBlockLen = PGPEndianToUInt32( kPGPBigEndian, blockWalk );
	blockWalk += sizeof(PGPUInt32);
	if( innerBlockLen > innerBlockPadLen )
	{
		err = kPGPError_CorruptData;
		goto done;
	}
	/*	Import private key */
	err = PGPImport( con->context, outReconstructedKey,
			PGPOInputBuffer( con->context, blockWalk, innerBlockLen ),
			PGPOLastOption( con->context ) );									CKERR;
	
done:
	pgpClearMemory( blockKey, sizeof(blockKey) );
	pgpClearMemory( passKey, sizeof(passKey) );
	pgpClearMemory( shares, sizeof(shares) );
	if( IsntNull( innerBlock ) )
		(void) PGPFreeData( innerBlock );
	if( PGPCBCContextRefIsValid( cbcCon ) )
		(void) PGPFreeCBCContext( cbcCon );
	if( PGPHashContextRefIsValid( hashCon ) )
		(void) PGPFreeHashContext( hashCon );
	return err;
}

#ifdef PGP_CMDLINE
	PGPError
PGPSetReconstructionServerURL(
	PGPReconContextRef			reconRef,
	char						*pszServerURL,
	PGPUInt32					dwServerType )
{
	PGPError					err = kPGPError_NoErr;
	PGPReconContextPriv *		con = (PGPReconContextPriv *)reconRef;
	
	PGPValidatePtr( reconRef );
	
	strcpy(con->szServerURL, pszServerURL);
	con->serverType  = dwServerType;
	
	return err;
}
#endif /* PGP_CMDLINE */

/*__Editor_settings____

	Local Variables:
	tab-width: 4
	End:
	vi: ts=4 sw=4
	vim: si
_____________________*/

⌨️ 快捷键说明

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