📄 pgpreconstruct.c
字号:
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 + -