📄 pgpreconstruct.c
字号:
dn = (char *)PGPNewData( con->memMgr,
strlen( kPGPReconCertIDAttr ) + sizeof( "=" ) + strlen( szKeyID ) +
sizeof( ", " ) + dnLength + 1,
kPGPMemoryMgrFlags_Clear );
if( IsNull( dn ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
sprintf( dn, "%s=%s, %s", kPGPReconCertIDAttr, szKeyID + 2, userDN );
event.data.keyServerData.state = kPGPKeyServerState_Uploading;
if( IsntNull( con->handler ) )
err = con->handler( con->context, &event, con->userValue ); CKERR;
err = sSendToServer( ldap, dn, con, con->blobData, con->blobDataSize ); CKERR;
event.data.keyServerData.state = kPGPKeyServerState_Closing;
if( IsntNull( con->handler ) )
err = con->handler( con->context, &event, con->userValue ); CKERR;
err = PGPldapUnbind( ldap ); CKERR;
done:
if( PGPtlsContextRefIsValid( tlsContext ) )
(void) PGPFreeTLSContext( tlsContext );
if( PGPtlsSessionRefIsValid( tlsSession ) )
(void) PGPFreeTLSSession( tlsSession );
if( IsntNull( userDN ) )
(void) PGPFreeData( userDN );
if( IsntNull( dn ) )
(void) PGPFreeData( dn );
if( IsntNull( lud ) )
(void) PGPFreeLDAPURLDesc( lud );
if( PGPldapContextRefIsValid( ldap ) )
(void) PGPFreeLDAPContext( ldap );
return err;
}
PGPError
PGPGetReconstructionPrompts(
PGPReconContextRef reconRef,
PGPReconPrompts outPromptInfo )
{
PGPError err = kPGPError_NoErr;
PGPReconContextPriv * con = (PGPReconContextPriv *)reconRef;
PGPUInt32 serverType = kPGPKeyServerClass_PGP;
char serverURL[256] = { 0 };
char serverDN[256] = { 0 };
char * dn = NULL;
char * userDN = NULL;
PGPldapContextRef ldap = kInvalidPGPldapContextRef;
PGPldapURLDesc * lud = NULL;
PGPBoolean bSecure = FALSE;
PGPtlsContextRef tlsContext = kInvalidPGPtlsContextRef;
PGPtlsSessionRef tlsSession = kInvalidPGPtlsSessionRef;
PGPKeyID keyid;
char szKeyID[kPGPMaxKeyIDStringSize] = { 0 };
char * attrs[] = { kPGPReconDataAttr, NULL };
PGPldapMessageRef message = kInvalidPGPldapMessageRef;
PGPberValue ** berValues = NULL;
char ** values = NULL;
PGPByte * blockWalk = NULL;
PGPSize numVars = 0;
#ifndef PGP_CMDLINE
PGPUInt32 numValue = 0;
#endif
PGPEvent event;
PGPKeyID targetKeyID;
/* CertServer: Search for Prompts based on KeyID
LDAPServer: Retrieve blob based on LDAP URL/username/pass */
#ifndef PGP_CMDLINE
err = PGPGetPrefStringBuffer( con->clientPrefs, kPGPPrefLDAPReconServer,
sizeof( serverURL ), serverURL ); CKERR;
if( !strlen( serverURL ) )
{
err = kPGPError_BadParams;
goto done;
}
#else /* PGP_CMDLINE */
strcpy(serverURL, con->szServerURL);
#endif /* PGP_CMDLINE */
err = PGPNewLDAPContext( con->context, &ldap ); CKERR;
#ifndef PGP_CMDLINE
err = PGPGetPrefNumber( con->clientPrefs, kPGPPrefLDAPReconServerType,
&numValue ); CKERR;
serverType = (PGPKeyServerClass) numValue;
#else /* PGP_CMDLINE */
serverType = (PGPKeyServerClass) con->serverType;
#endif /* PGP_CMDLINE */
if( serverType == 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 = 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 = PGPGetKeyID( con->targetKey, &keyid ); CKERR;
err = PGPGetKeyIDString( &keyid, kPGPKeyIDString_Full, szKeyID ); CKERR;
#ifndef PGP_CMDLINE
err = PGPGetPrefNumber( con->clientPrefs, kPGPPrefLDAPReconServerType,
&serverType ); CKERR;
#else /* PGP_CMDLINE */
serverType = (PGPKeyServerClass)con->serverType;
#endif /* PGP_CMDLINE */
if( serverType == kPGPKeyServerClass_PGP )
{
/* PGP Keyserver */
/* Query cn=PGPServerInfo for certserver location */
err = sGetCertserverLocation( ldap, serverDN ); CKERR;
dn = serverDN;
dn = (char *)PGPNewData( con->memMgr,
strlen( kPGPReconCertIDAttr ) + sizeof( "=" ) + strlen( szKeyID ) +
sizeof( ", " ) + strlen( serverDN ) + 1,
kPGPMemoryMgrFlags_Clear );
if( IsNull( dn ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
sprintf( dn, "%s=%s, %s", kPGPReconCertIDAttr, szKeyID + 2, serverDN );
/* Also get hashReps */
attrs[0] = kPGPReconPromptsAttr;
attrs[1] = kPGPReconHashRepsAttr;
attrs[2] = NULL;
}
else
{
/* Generic LDAP server */
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 = PGPldapSimpleBindSync( ldap, userDN, con->authPass ); CKERR;
dn = (char *)PGPNewData( con->memMgr,
strlen( kPGPReconCertIDAttr ) + sizeof( "=" ) + strlen( szKeyID ) +
sizeof( ", " ) + strlen( userDN ) + 1, kPGPMemoryMgrFlags_Clear );
if( IsNull( dn ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
sprintf( dn, "%s=%s, %s", kPGPReconCertIDAttr, szKeyID + 2, userDN );
attrs[0] = kPGPReconDataAttr;
attrs[1] = NULL;
}
/* dn now contains the DN we need to search for the key stuff */
err = PGPNewLDAPMessage( ldap, &message ); CKERR;
event.data.keyServerData.state = kPGPKeyServerState_Querying;
if( IsntNull( con->handler ) )
err = con->handler( con->context, &event, con->userValue ); CKERR;
err = PGPldapSearchSync( ldap, dn, kPGPldapScope_Base, kPGPObjectclassAny,
attrs, FALSE, message );
if( err == kPGPError_LDAPNoSuchObject )
err = kPGPError_ItemNotFound;
CKERR;
event.data.keyServerData.state = kPGPKeyServerState_ProcessingResults;
if( IsntNull( con->handler ) )
err = con->handler( con->context, &event, con->userValue ); CKERR;
/* Compare KeyID for match and copy retrieved prompts to outPromptInfo,
and save entire blob in con->blobData,blobDataSize if this is an LDAPServer */
if( serverType == kPGPKeyServerClass_PGP )
{
/* PGP Keyserver */
err = PGPldapGetValuesLen( ldap, message, kPGPReconPromptsAttr, &berValues );CKERR;
if( IsNull( berValues ) )
{
err = kPGPError_ItemNotFound;
goto done;
}
blockWalk = berValues[0]->value;
/* Also get hashReps */
err = PGPldapGetValues( ldap, message, kPGPReconHashRepsAttr, &values ); CKERR;
con->hashReps = atoi( values[0] );
}
else
{
/* Generic LDAP server */
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 );
blockWalk = con->blobData;
if( con->blobDataSize < 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 );
con->hashReps = PGPEndianToUInt16( kPGPBigEndian, blockWalk + sizeof( PGPReconPrompts ) );
}
pgpCopyMemory( blockWalk, outPromptInfo, sizeof( PGPReconPrompts ) );
event.data.keyServerData.state = kPGPKeyServerState_Closing;
if( IsntNull( con->handler ) )
err = con->handler( con->context, &event, con->userValue ); CKERR;
done:
if( PGPtlsContextRefIsValid( tlsContext ) )
(void) PGPFreeTLSContext( tlsContext );
if( PGPtlsSessionRefIsValid( tlsSession ) )
(void) PGPFreeTLSSession( tlsSession );
if( PGPldapContextRefIsValid( ldap ) )
(void) PGPFreeLDAPContext( ldap );
if( IsntNull( lud ) )
(void) PGPFreeLDAPURLDesc( lud );
if( PGPldapMessageRefIsValid( message ) )
(void) PGPFreeLDAPMessage( message );
if( IsntNull( values ) )
(void) PGPFreeLDAPValues( values );
if( IsntNull( berValues ) )
(void) PGPFreeLDAPValuesLen( berValues );
if( IsntNull( userDN ) )
(void) PGPFreeData( userDN );
if( IsntNull( dn ) )
(void) PGPFreeData( dn );
return err;
}
/*
* Armor 3 raw bytes into 4
* If armoring n < 3 bytes, make the trailers zero, and
* then overwrite the trailing 3-n bytes with '='
*/
static void
sArmorMorsel(PGPByte const raw[3], char armor[4])
{
armor[0] = armorTable[raw[0] >> 2 & 0x3f];
armor[1] = armorTable[(raw[0] << 4 & 0x30) + (raw[1] >> 4 & 0x0f)];
armor[2] = armorTable[(raw[1] << 2 & 0x3c) + (raw[2] >> 6 & 0x03)];
armor[3] = armorTable[raw[2] & 0x3f];
}
static int
sArmorLine (PGPByte const *in, unsigned inlen, char *out)
{
unsigned len;
int t;
char const *out0 = out;
/* Fill the output buffer from the input buffer */
for (len = 0; len < inlen; len += 3)
{
sArmorMorsel (in, out);
in += 3;
out += 4;
}
/* Now back up and erase any overrun */
t = (int)(inlen - len); /* Zero or negative */
while (t)
out[t++] = '=';
return (out - out0);
}
PGPError
PGPGetReconstructionData(
PGPReconContextRef reconRef,
PGPReconPasses inPassInfo,
PGPByte **outReconData,
PGPSize *outReconSize )
{
PGPError err = kPGPError_NoErr;
PGPReconContextPriv * con = (PGPReconContextPriv *)reconRef;
PGPldapContextRef ldap = kInvalidPGPldapContextRef;
PGPUInt32 numValue;
PGPKeyServerClass serverClass;
char serverURL[256];
char szCertserverDN[256];
char * dn = NULL;
PGPldapMessageRef message = kInvalidPGPldapMessageRef;
char szKeyID[kPGPMaxKeyIDStringSize];
char szArmoredPassKey[
( ( ( kPGPRecon_NumShares * kReconstructWrapKeySize / 3 ) + 1 ) * 4 ) + 1
];
char * attrs[2];
PGPberValue ** berValues = NULL;
PGPldapURLDesc * lud = NULL;
PGPBoolean bSecure = FALSE;
PGPtlsContextRef tlsContext = kInvalidPGPtlsContextRef;
PGPtlsSessionRef tlsSession = kInvalidPGPtlsSessionRef;
PGPKeyID keyid;
PGPSize len = 0;
PGPByte passKey[kPGPRecon_NumShares][kReconstructWrapKeySize];
PGPHashContextRef hashCon = kInvalidPGPHashContextRef;
PGPByte hashMagic[sizeof(PGPUInt32)];
PGPUInt32 shareIndex;
PGPUInt32 hashIndex;
PGPByte hashOut[20];
PGPValidatePtr( outReconData );
PGPValidatePtr( outReconSize );
/* We need to have already called PGPGetReconstructionPrompts and
* gotten the number of hashReps */
pgpAssert( con->hashReps != 0 );
/* 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -