📄 pgpreconstruct.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: pgpReconstruct.c,v 1.37 2002/08/06 20:10:16 dallen Exp $
____________________________________________________________________________*/
#include <string.h>
#include "pflPrefTypes.h"
#include "pgpMem.h"
#include "pgpClientPrefs.h"
#include "pgpPFLPriv.h"
#include "pgpUtilities.h"
#include "pgpEndianConversion.h"
#include "pgpCBC.h"
#include "pgpLDAP.h"
#include "pgpReconstructPriv.h"
#include "pgpStrings.h"
#include "pgpKeys.h"
#define noPGPRECONSELFTEST
#define CKERR if( IsPGPError( err ) ) goto done
/* This is are table of 6-bit value -> character */
static char const armorTable[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
PGPError
PGPNewReconstruct(
PGPKeyDBObjRef inTargetKey,
PGPPrefRef inClientPrefRef,
char *inAuthUser,
char *inAuthPass,
PGPReconstructEventHandler inHandler,
PGPUserValue inUserValue,
PGPReconContextRef *outRef )
{
PGPError err = kPGPError_NoErr;
PGPReconContextPriv * pContext;
PGPContextRef context;
PGPMemoryMgrRef memMgr;
PGPBoolean splitKey;
*outRef = NULL;
PGPValidatePtr( inTargetKey );
(void)PGPGetKeyDBObjBooleanProperty( inTargetKey,
kPGPKeyProperty_IsSecretShared, &splitKey );
if( splitKey )
return kPGPError_SecretKeyNotFound;
context = PGPPeekKeyDBObjContext( inTargetKey );
memMgr = PGPPeekContextMemoryMgr( context );
pContext = (PGPReconContextPriv *) PGPNewSecureData( memMgr,
sizeof(PGPReconContextPriv),
kPGPMemoryMgrFlags_Clear );
if( IsntNull( pContext ) )
{
pContext->context = context;
pContext->memMgr = memMgr;
pContext->targetKey = inTargetKey;
pContext->clientPrefs = inClientPrefRef;
pContext->handler = inHandler;
pContext->userValue = inUserValue;
if( IsntNull( inAuthUser ) )
strcpy( pContext->authUser, inAuthUser );
if( IsntNull( inAuthPass ) )
strcpy( pContext->authPass, inAuthPass );
pContext->hashReps = 0;
pContext->blobData = NULL;
pContext->blobDataSize = 0;
*outRef = ( PGPReconContextRef ) pContext;
}
else
err = kPGPError_OutOfMemory;
return err;
}
PGPError
PGPFreeReconstruct(
PGPReconContextRef reconRef )
{
PGPError err = kPGPError_NoErr;
PGPReconContextPriv * con = (PGPReconContextPriv *)reconRef;
PGPValidatePtr( reconRef );
if( IsntNull( con->blobData ) )
(void)PGPFreeData( con->blobData );
err = PGPFreeData( reconRef );
return err;
}
static PGPError
sSendTLSEvent(
PGPContextRef context,
PGPEventHandlerProcPtr handler,
PGPUserValue userValue,
PGPKeyServerState state,
PGPtlsSessionRef tlsSession)
{
PGPEvent event;
if( IsNull( handler ) )
return kPGPError_NoErr;
pgpClearMemory( &event, sizeof( PGPEvent ) );
event.type = kPGPEvent_KeyServerTLSEvent;
event.data.keyServerTLSData.state = state;
event.data.keyServerTLSData.tlsSession = tlsSession;
return handler( context, &event, userValue );
}
static PGPError
sEstablishTLSSession(
PGPContextRef pgpContext,
PGPldapContextRef ldap,
PGPtlsContextRef * tlsContext,
PGPtlsSessionRef * tlsSession )
{
PGPSocketRef sock = kInvalidPGPSocketRef;
PGPError err = kPGPError_NoErr;
err = PGPldapGetOption( ldap, kPGPldapOpt_Desc, &sock ); CKERR;
err = PGPNewTLSContext( pgpContext, tlsContext ); CKERR;
err = PGPNewTLSSession( *tlsContext, tlsSession ); CKERR;
err = PGPSocketsEstablishTLSSession( sock, *tlsSession ); CKERR;
done:
return err;
}
static PGPError
sGetCertserverLocation(
PGPldapContextRef ldap,
char * dn )
{
PGPError err = kPGPError_NoErr;
char * attr[] = { kPGPBaseKeyspaceDN,
kPGPCertserverVersion,
NULL };
char ** values = NULL;
PGPldapMessageRef message = kInvalidPGPldapMessageRef;
err = PGPNewLDAPMessage( ldap, &message ); CKERR;
/*
* First check to see if the server can accept recon data. We check this
* by searching for a baseReconDN in the PGPServerInfo. If this exists,
* the server can accept recon data.
*/
err = PGPldapSearchSync( ldap,
kPGPServerInfoCN,
kPGPldapScope_Base,
kPGPObjectclassAny,
attr,
FALSE,
message ); CKERR;
err = PGPldapGetValues( ldap, message, kPGPBaseReconDN, &values );
if( err == kPGPError_LDAPNoSuchAttribute )
{
err = kPGPError_ServerOperationNotSupported;
goto done;
}
if( IsntNull( values ) )
{
(void) PGPFreeLDAPValues( values );
values = NULL;
}
/* Server supports it. Now find where to put it */
err = PGPldapGetValues( ldap, message, kPGPBaseKeyspaceDN, &values ); CKERR;
pgpCopyMemory( values[0], dn, strlen( values[0] ) + 1 );
done:
if( PGPldapMessageRefIsValid( message ) )
(void) PGPFreeLDAPMessage( message );
if( IsntNull( values ) )
(void) PGPFreeLDAPValues( values );
return err;
}
static PGPError
sCountLDAPVariables(
char * inDN,
PGPSize * num )
{
PGPError err = kPGPError_NoErr;
char * userid = NULL;
char * useridVars[] = kPGPUserIDVariables;
PGPUInt32 whichVar = 0;
PGPValidatePtr( inDN );
PGPValidatePtr( num );
*num = 0;
for( whichVar = 0; whichVar < sizeof( useridVars ) / sizeof( useridVars[0] ); whichVar++ )
{
for( userid = inDN;
userid <= inDN + strlen( inDN ) - strlen( useridVars[whichVar] );
userid++ )
{
if( pgpCompareStringsIgnoreCaseN( userid,
useridVars[whichVar],
strlen( useridVars[whichVar] ) ) == 0 )
{
(*num)++;
userid += strlen( useridVars[whichVar] );
}
}
}
return err;
}
static PGPError
sReplaceLDAPVariables(
char * inDN,
char * username,
char * outDN )
{
PGPError err = kPGPError_NoErr;
PGPSize len = 0;
PGPUInt32 i = 0;
PGPUInt32 j = 0;
PGPUInt32 k = 0;
char * useridVars[] = kPGPUserIDVariables;
PGPUInt32 whichVar = 0;
PGPBoolean found = FALSE;
PGPValidatePtr( inDN );
PGPValidatePtr( outDN );
if( IsNull( username ) )
username = "";
len = strlen( inDN );
while( i < len )
{
for( whichVar = 0; whichVar < sizeof( useridVars ) / sizeof( useridVars[0] ); whichVar++ )
{
if( i <= strlen( inDN ) - strlen( useridVars[whichVar] ) )
{
if( pgpCompareStringsIgnoreCaseN( inDN + i,
useridVars[whichVar],
strlen( useridVars[whichVar] ) ) == 0 )
{
for( k = 0; k < strlen( username ); k++ )
outDN[j++] = username[k];
i += strlen( useridVars[whichVar] );
found = TRUE;
break;
}
}
}
if( !found )
outDN[j++] = inDN[i++];
found = FALSE;
}
outDN[j] = '\0';
return err;
}
static PGPError
sSendToServer(
PGPldapContextRef ldap,
char * dn,
PGPReconContextPriv * con,
PGPByte * keyBlock,
PGPSize keyBlockLen )
{
PGPldapMod reconData;
PGPldapMod objectclassData;
PGPldapMod ownerData;
PGPldapMod keyData;
char * ownerAttr[2] = { 0 };
PGPldapMod * mod[4] = { NULL, NULL, NULL, NULL };
PGPberValue berData = { 0 };
PGPberValue * bvalue[2] = { &berData, NULL };
char * attr[2] = { kPGPReconElementObjectclass, NULL };
char certserverDN[256] = { 0 };
PGPUInt32 serverType = kPGPKeyServerClass_PGP;
char virtDN[256];
char * exportedKey = NULL;
PGPSize bufSize = 0;
char * keyAttr[2] = { NULL, NULL };
PGPError err = kPGPError_NoErr;
#ifndef PGP_CMDLINE
err = PGPGetPrefNumber( con->clientPrefs, kPGPPrefLDAPReconServerType,
&serverType ); CKERR;
#else /* PGP_CMDLINE */
serverType = (PGPKeyServerClass)con->serverType;
#endif /* PGP_CMDLINE */
if( serverType == kPGPKeyServerClass_PGP )
{
/* Query cn=PGPServerInfo for certserver location */
err = sGetCertserverLocation( ldap, certserverDN ); CKERR;
strcat( dn, certserverDN );
}
/*
* If using standard LDAP server, we try to modify it first,
* then if that fails, we add it. PGP certserver doesn't do
* modifies, so we just add it unconditionally.
*/
if( serverType == kPGPKeyServerClass_PGP )
{
/* PGP Keyserver */
sprintf( virtDN, "%s=%s, %s", kPGPReconCertIDAttr, kPGPCertIDVirtual, certserverDN );
err = PGPExport( con->context,
PGPOExportKeyDBObj( con->context, con->targetKey ),
PGPOAllocatedOutputBuffer( con->context,
(void **) &exportedKey,
MAX_PGPSize,
&bufSize ),
PGPOLastOption( con->context ) ); CKERR;
keyAttr[0] = exportedKey;
mod[0] = &keyData;
mod[0]->op = kPGPldapModOp_Add;
mod[0]->type = kPGPKeyAttr;
mod[0]->value = keyAttr;
mod[1] = &reconData;
mod[1]->op = (PGPldapModOp)( kPGPldapModOp_Replace | kPGPldapModOpMask_UseBERValues );
mod[1]->type = kPGPReconDataAttr;
bvalue[0]->value = keyBlock;
bvalue[0]->length = keyBlockLen;
bvalue[1] = NULL;
mod[1]->bvalue = bvalue;
mod[2] = NULL;
err = PGPldapAddSync( ldap, virtDN, mod ); CKERR;
}
else
{
/* Generic LDAP server */
mod[0] = &reconData;
mod[0]->op = (PGPldapModOp)( kPGPldapModOp_Replace | kPGPldapModOpMask_UseBERValues );
mod[0]->type = kPGPReconDataAttr;
bvalue[0]->value = keyBlock;
bvalue[0]->length = keyBlockLen;
bvalue[1] = NULL;
mod[0]->bvalue = bvalue;
mod[1] = &ownerData;
mod[1]->op = kPGPldapModOp_Replace;
mod[1]->type = kPGPOwnerAttr;
ownerAttr[0] = dn;
while( ( *ownerAttr[0] != ' ' ) && ( *ownerAttr[0] != '\0' ) )
ownerAttr[0]++;
while( ( *ownerAttr[0] == ' ' ) && ( *ownerAttr[0] != '\0' ) )
ownerAttr[0]++;
mod[1]->value = ownerAttr;
mod[2] = NULL;
err = PGPldapModifySync( ldap, dn, mod );
if( err == kPGPError_LDAPNoSuchObject )
{
/* Object didn't exist, we need to add it */
mod[0]->op = (PGPldapModOp)( kPGPldapModOp_Add | kPGPldapModOpMask_UseBERValues );
/* mod[0] is already set */
mod[1]->op = kPGPldapModOp_Add;
/* mod[1] is already set */
mod[2] = &objectclassData;
mod[2]->op = kPGPldapModOp_Add;
mod[2]->type = kPGPObjectclassAttr;
mod[2]->value = attr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -