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

📄 pgpskep.c

📁 pgp soucecode pgp soucecode
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 1997 Network Associates Inc. and affiliated companies.
	All rights reserved.

	$Id: pgpSKEP.c,v 1.44 1999/03/10 02:58:43 heller Exp $
____________________________________________________________________________*/
#include "pgpSKEP.h"
#include "pgpSharePriv.h"
#include "pgpSockets.h"
#include "pgpTLS.h"
#include "pgpMem.h"
#include "pgpMemoryMgr.h"
#include "pgpEncode.h"
#include "pgpUtilities.h"
#include "pgpEndianConversion.h"
#include "pgpClientErrors.h"

#if PGP_WIN32
#include "pgpAsyncDNS.h"
#endif

typedef struct PGPskep		PGPskep;

#define kPGPskepMagic	0x156A3C91

struct PGPskep
{
	PGPUInt32				magic;
	PGPContextRef			context;
	PGPtlsContextRef		tlsContext;
	PGPSocketRef			socketOut;
	PGPSocketRef			socketIn;
	PGPskepEventHandler		eventHandler;
	PGPUserValue			userValue;
	PGPBoolean				cancel;
	PGPBoolean				freeTLSContext;
#if PGP_WIN32
	PGPAsyncHostEntryRef	asyncHostEntryRef;
#endif
};

#define PGPValidateSKEP(ref)	PGPValidateParam(ref != NULL)

#define kPGPskep_Port				14747
#define kPGPskep_ClosingMessage		0x155901C5
#define kPGPskepEndian				kPGPBigEndian

#define kPGPskepMajor	0x01	/* SKEP major version */
#define kPGPskepMinor	0x01	/* SKEP minor version */


static PGPError sSocketSend(PGPskepRef skep, PGPSocketRef socket, 
					void *data, PGPInt32 dataSize, PGPBoolean crossPlatform,
					PGPskepEventProgressData *progressData);

static PGPError sSocketReceive(PGPskepRef skep, PGPSocketRef socket, 
					void *data, PGPInt32 dataSize, PGPBoolean crossPlatform,
					PGPskepEventProgressData *progressData);

static PGPError sProcessResult(PGPskepRef skep, PGPInt32 result,
					PGPskepEventProgressData *progressData);

static PGPError sSocketCallback(PGPContextRef context, 
					struct PGPEvent *event, PGPUserValue userValue);


PGPError PGPNewSKEP(PGPContextRef context, 
				PGPtlsContextRef tlsContext,
				PGPskepRef *skep)
{
	PGPMemoryMgrRef memoryMgr = NULL;
	PGPError		err = kPGPError_NoErr;

	if (IsntNull(skep))
		*skep = NULL;

	PGPValidateParam(PGPContextRefIsValid(context));
	PGPValidatePtr(skep);

	memoryMgr = PGPGetContextMemoryMgr(context);
	
	pgpAssert(PGPMemoryMgrIsValid(memoryMgr));
	if (!PGPMemoryMgrIsValid(memoryMgr))
		return kPGPError_BadParams;

	*skep = (PGPskepRef) PGPNewData(memoryMgr, sizeof(PGPskep), 
							kPGPMemoryMgrFlags_Clear);

	pgpAssert(IsntNull(*skep));
	if (IsNull(*skep))
		return kPGPError_OutOfMemory;

	if (PGPtlsContextRefIsValid(tlsContext))
	{
		(*skep)->tlsContext = tlsContext;
		(*skep)->freeTLSContext = FALSE;
	}
	else
	{
		PGPNewTLSContext(context, &((*skep)->tlsContext));
		(*skep)->freeTLSContext = TRUE;
	}

	(*skep)->magic = kPGPskepMagic;
	(*skep)->context = context;
	(*skep)->socketOut = NULL;
	(*skep)->socketIn = NULL;
	(*skep)->eventHandler = NULL;
	(*skep)->userValue = NULL;
	(*skep)->cancel = FALSE;

	return err;
}


PGPError PGPskepSetEventHandler(PGPskepRef skep, PGPskepEventHandler handler,
				PGPUserValue userValue)
{
	PGPValidateSKEP(skep);
	PGPValidatePtr(handler);
	pgpAssertMsg(skep->magic == kPGPskepMagic, "Invalid SKEP object");

	skep->eventHandler = handler;
	skep->userValue = userValue;
	return kPGPError_NoErr;
}


PGPError PGPskepSendShares(PGPskepRef skep, PGPKeyRef authKey,
				const char *passphrase, PGPShareRef shares,
				const char *destSocketAddress)
{
	PGPSocketRef				socket = NULL;
	PGPtlsSessionRef			tlsSession = NULL;
	PGPEventHandlerProcPtr		oldCallback = NULL;
	PGPUserValue				oldUserValue;
	PGPSocketAddressInternet	sockAddr;
	PGPHostEntry *				hostEntry = NULL;
	PGPskepEvent				skepEvent;
	PGPskepEventProgressData	progressData = {0,0};
	PGPInt32					result;
	PGPKeyRef					remoteKey = NULL;
	PGPKeyID					keyID;
	PGPShareID					shareID;
	PGPUInt32					inetAddress;
	PGPUInt32					threshold;
	PGPUInt32					numShares;
	PGPUInt32					totalShares;
	PGPUInt32					closing;
	PGPSize						shareDataSize;
	PGPByte *					shareData = NULL;
	PGPByte						version;
	PGPBoolean					weConfirmed;
	PGPBoolean					theyConfirmed;
	PGPError					err = kPGPError_NoErr;
	PGPSocketsThreadStorageRef	previousStorage;
#if PGP_WIN32
	char						h_name[256];
#endif

	PGPValidateSKEP(skep);
	PGPValidateParam(PGPKeyRefIsValid(authKey));
	PGPValidatePtr(passphrase);
	PGPValidateParam(PGPShareRefIsValid(shares));
	PGPValidatePtr(destSocketAddress);
	pgpAssertMsg(skep->magic == kPGPskepMagic, "Invalid SKEP object");

	skep->cancel = FALSE;

	PGPSocketsInit();
	PGPSocketsCreateThreadStorage(&previousStorage);
	if (IsntNull(skep->eventHandler))
	{
		PGPGetSocketsIdleEventHandler(&oldCallback, &oldUserValue);
		PGPSetSocketsIdleEventHandler(sSocketCallback, skep);
	}

	inetAddress = PGPDottedToInternetAddress(destSocketAddress);
	if (inetAddress != kPGPSockets_Error)
	{
#if PGP_WIN32
		err = PGPStartAsyncGetHostByAddress(inetAddress,
					&skep->asyncHostEntryRef);
		if (IsntPGPError(err)) {
			PGPWaitForGetHostByAddress(skep->asyncHostEntryRef,
					h_name, 256);
			skep->asyncHostEntryRef = kPGPInvalidAsyncHostEntryRef;
		}
#else
		hostEntry = PGPGetHostByAddress((char *) &inetAddress, 
						sizeof(PGPInternetAddress), 
						kPGPProtocolFamilyInternet);
#endif
	}
	else
	{
#if PGP_WIN32
		err = PGPStartAsyncGetHostByName(destSocketAddress,
					&skep->asyncHostEntryRef);
		if (IsntPGPError(err)) {
			PGPWaitForGetHostByName(skep->asyncHostEntryRef,
					&inetAddress);
			skep->asyncHostEntryRef = kPGPInvalidAsyncHostEntryRef;
			strcpy(h_name, destSocketAddress);
		}
#else
		hostEntry = PGPGetHostByName(destSocketAddress);
#endif
	}
		
	if (IsntPGPError(err) && IsNull(hostEntry))
		if (inetAddress == kPGPSockets_Error)
			err = PGPGetLastSocketsError();

	if (IsntPGPError(err))
	{
		socket = PGPOpenSocket(kPGPAddressFamilyInternet, 
					kPGPSocketTypeStream, kPGPTCPProtocol);
		
		if (IsNull(socket))
		{
			err = PGPGetLastSocketsError();
			pgpAssertNoErr(err);
		}
	}

	if (IsntPGPError(err))
	{
		skep->socketOut = socket;
		sockAddr.sin_family = kPGPAddressFamilyInternet;
		sockAddr.sin_port = PGPHostToNetShort(kPGPskep_Port);

		/* If we were able to get the host entry, use the IP address list */
		/* from that. If not, use the IP address passed in by the caller  */

		if (IsntNull(hostEntry))
			sockAddr.sin_addr = *((PGPInternetAddress*) 
									*hostEntry->h_addr_list);
		else
			sockAddr.sin_addr = *((PGPInternetAddress*) &inetAddress);

		result = PGPConnect(socket, (PGPSocketAddress *) &sockAddr, 
					sizeof(sockAddr));

		if (result == kPGPSockets_Error)
			err = PGPGetLastSocketsError();
		else
		{
			skepEvent.type = kPGPskepEvent_ConnectEvent;
			if (skep->eventHandler != NULL)
				err = skep->eventHandler(skep, &skepEvent, 
						skep->userValue);
		}
	}

	if (IsntPGPError(err))
	{
		err = PGPNewTLSSession(skep->tlsContext, &tlsSession);
		pgpAssertNoErr(err);
	}

	if (IsntPGPError(err))
	{
		err = PGPtlsSetProtocolOptions(tlsSession, kPGPtlsFlags_ClientSide);
		pgpAssertNoErr(err);
	}

	if (IsntPGPError(err))
	{
		err = PGPtlsSetLocalPrivateKey(tlsSession, authKey,
					kInvalidPGPSigRef, kInvalidPGPKeySetRef,
					PGPOPassphrase( skep->context, passphrase ),
					PGPOLastOption( skep->context ) );
		pgpAssertNoErr(err);
	}

	if (IsntPGPError(err))
	{
		err = PGPSocketsEstablishTLSSession(socket, tlsSession);
		if (IsPGPError(err))
			err = PGPGetLastSocketsError();

		if (skep->cancel == TRUE)
			err = kPGPError_UserAbort;

		pgpAssertNoErr(err);
	}

	if (IsntPGPError(err))
	{
		err = PGPtlsGetRemoteAuthenticatedKey(tlsSession, &remoteKey, NULL);

		if (skep->cancel == TRUE)
			err = kPGPError_UserAbort;

		pgpAssertNoErr(err);
	}

	if (IsntPGPError(err))
	{
		/* If we don't have the host name, set it to the IP address */

		if (IsntNull(hostEntry))
#if PGP_WIN32
			skepEvent.data.ad.remoteHostname = h_name;
#else
			skepEvent.data.ad.remoteHostname = hostEntry->h_name;
#endif
		else
			skepEvent.data.ad.remoteHostname = 
				PGPInternetAddressToDottedString(sockAddr.sin_addr);

		skepEvent.type = kPGPskepEvent_AuthenticateEvent;
		skepEvent.data.ad.remoteKey = remoteKey;
		skepEvent.data.ad.remoteIPAddress = 
			PGPInternetAddressToDottedString(sockAddr.sin_addr);
		PGPtlsGetNegotiatedCipherSuite( tlsSession,
			&skepEvent.data.ad.tlsCipher );
		
		if( ( skepEvent.data.ad.tlsCipher == kPGPtls_TLS_PGP_DHE_DSS_WITH_NULL_SHA ) ||
			( skepEvent.data.ad.tlsCipher == kPGPtls_TLS_DHE_DSS_WITH_NULL_SHA ) )
			err = kPGPError_TLSNoCommonCipher;
		else
		{
			if (skep->eventHandler != NULL)
				err = skep->eventHandler(skep, &skepEvent, 
						skep->userValue);

			if (IsntPGPError(err))
				weConfirmed = TRUE;
			else
				weConfirmed = FALSE;

			err = kPGPError_NoErr;
		}
	}

	if (IsntPGPError(err))
	{
		pgpGetShareData(shares, &shareData, &shareDataSize);

		progressData.bytesTotal = sizeof(shareDataSize) + shareDataSize + 
									sizeof(PGPKeyID) + sizeof(PGPShareID) +
									sizeof(threshold) + sizeof(numShares) + 
									sizeof(totalShares) + 4;

		version = kPGPskepMajor;
		err = sSocketSend(skep, socket, &version, 1, FALSE, &progressData);
	}
	else
		remoteKey = NULL;

	if (IsntPGPError(err))
	{
		version = kPGPskepMinor;
		err = sSocketSend(skep, socket, &version, 1, FALSE, &progressData);
	}

	if (IsntPGPError(err))
	{
		err = sSocketSend(skep, socket, &weConfirmed, 1, FALSE, 
				&progressData);
	}

	if (IsntPGPError(err))
	{
		err = sSocketReceive(skep, socket, &theyConfirmed, 1, FALSE, 
				&progressData);

		if (!theyConfirmed)
			err = kPGPClientError_RejectedSKEPAuthentication;

		if (!weConfirmed)
			err = kPGPError_UserAbort;
	}

	if (IsntPGPError(err))
		err = sSocketSend(skep, socket, &shareDataSize, 
				sizeof(shareDataSize), TRUE, &progressData);

	if (IsntPGPError(err))
	{
		PGPGetKeyIDFromShares(shares, &keyID);
		err = sSocketSend(skep, socket, &keyID, sizeof(PGPKeyID), 
				FALSE, &progressData);
	}

	if (IsntPGPError(err))
	{
		PGPGetShareID(shares, &shareID);
		err = sSocketSend(skep, socket, &shareID, sizeof(PGPShareID), 
				FALSE, &progressData);
	}

	if (IsntPGPError(err))
	{
		threshold = PGPGetShareThreshold(shares);
		err = sSocketSend(skep, socket, &threshold, sizeof(threshold), 
				TRUE, &progressData);
	}

	if (IsntPGPError(err))
	{
		numShares = PGPGetNumberOfShares(shares);
		err = sSocketSend(skep, socket, &numShares, sizeof(numShares), 
				TRUE, &progressData);
	}

	if (IsntPGPError(err))
	{
		totalShares = PGPGetTotalNumberOfShares(shares);
		err = sSocketSend(skep, socket, &totalShares, sizeof(totalShares), 
				TRUE, &progressData);
	}

	if (IsntPGPError(err))
	{
		err = sSocketSend(skep, socket, shareData, 
				shareDataSize, FALSE, &progressData);
	}

	if (IsntPGPError(err))
	{
		skepEvent.type = kPGPskepEvent_CloseEvent;
		if (skep->eventHandler != NULL)
			err = skep->eventHandler(skep, &skepEvent, 
					skep->userValue);
	}

	if (IsntPGPError(err))
	{
		progressData.bytesTotal = 0;
		err = sSocketReceive(skep, socket, &closing, sizeof(closing), TRUE,
				&progressData);
	}

	if (IsntPGPError(err))
	{
		if (closing != kPGPskep_ClosingMessage)
		{
			err = kPGPError_CorruptData;
			pgpAssertNoErr(err);
		}
	}

	if (IsntNull(shareData))
		PGPFreeData(shareData);

	if (IsntNull(tlsSession))
	{
		if (IsntNull(remoteKey))
			PGPtlsClose(tlsSession, FALSE);
		else
			PGPtlsClose(tlsSession, TRUE);
		PGPFreeTLSSession(tlsSession);
	}

	if (IsntNull(socket))
	{
		PGPCloseSocket(socket);
		skep->socketOut = NULL;
	}

	if (IsntNull(skep->eventHandler))
		PGPSetSocketsIdleEventHandler(oldCallback, oldUserValue);

	PGPSocketsDisposeThreadStorage(previousStorage);
	PGPSocketsCleanup();

	if (skep->cancel == TRUE)
		err = kPGPError_UserAbort;

	return err;
}


PGPError PGPskepReceiveShares(PGPskepRef skep, PGPKeyRef authKey,
				const char *passphrase)
{
	PGPShareRef					shares;
	PGPSocketRef				socket = NULL;
	PGPSocketRef				socketIn;
	PGPtlsSessionRef			tlsSession;
	PGPEventHandlerProcPtr		oldCallback = NULL;
	PGPUserValue				oldUserValue;
	PGPSocketAddressInternet	sockAddr;
	PGPskepEvent				skepEvent;
	PGPskepEventProgressData	progressData;
	PGPInt32					result;
	PGPKeyRef					remoteKey;
	PGPKeyID					keyID;
	PGPShareID					shareID;
	PGPUInt32					threshold;
	PGPUInt32					numShares;
	PGPUInt32					totalShares;
	PGPUInt32					closing = kPGPskep_ClosingMessage;
	PGPUInt32					shareDataSize;
	PGPByte *					shareData;
	PGPByte						version;
	PGPBoolean					weConfirmed;
	PGPBoolean					theyConfirmed;
	PGPHostEntry *				hostEntry;
	PGPError					err = kPGPError_NoErr;
	PGPSocketsThreadStorageRef	previousStorage;
#if PGP_WIN32
	char						h_name[256];
#endif

	PGPValidateSKEP(skep);
	PGPValidateParam(PGPKeyRefIsValid(authKey));
	PGPValidatePtr(passphrase);
	pgpAssertMsg(skep->magic == kPGPskepMagic, "Invalid SKEP object");

	skep->cancel = FALSE;

	PGPSocketsInit();
	PGPSocketsCreateThreadStorage(&previousStorage);

	if (IsntNull(skep->eventHandler))
	{
		PGPGetSocketsIdleEventHandler(&oldCallback, &oldUserValue);
		PGPSetSocketsIdleEventHandler(sSocketCallback, skep);
	}

	socket = PGPOpenSocket(kPGPAddressFamilyInternet, 
				kPGPSocketTypeStream, kPGPTCPProtocol);

	if (IsNull(socket))
	{
		err = PGPGetLastSocketsError();
		pgpAssertNoErr(err);
	}

⌨️ 快捷键说明

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