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

📄 pgpskep.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 3 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: pgpSKEP.c,v 1.9 2002/08/06 20:10:16 dallen 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"
#include "pgpPFLPriv.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	0x02	/* SKEP major version */
#define kPGPskepMinor	0x00	/* SKEP minor version */

#define kPGPskepAcceptTimeout	2
#define kPGPskepReceiveTimeout	1


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 PGPSocketRef sSocketAccept(PGPskepRef skep, PGPSocketRef sock,
					PGPSocketAddress *sockAddr, PGPInt32 *addrLength);

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 = PGPPeekContextMemoryMgr(context);
	
	*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, PGPKeyDBObjRef 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;
	PGPKeyDBObjRef				remoteKey = NULL;
	PGPKeyID					keyID;
	PGPShareID					shareID;
	PGPUInt32					inetAddress;
	PGPUInt32					threshold;
	PGPUInt32					numShares;
	PGPUInt32					totalShares;
	PGPUInt32					closing;
	PGPSize						shareDataSize;
	PGPSize						dataSize;
	PGPByte *					shareData = NULL;
	PGPByte						version;
	PGPBoolean					weConfirmed;
	PGPBoolean					theyConfirmed;
	char *						newPassphrase = NULL;
	PGPByte *					newPasskey = NULL;
	PGPSize						newPasskeySize = 0;
	PGPError					err = kPGPError_NoErr;
	PGPSocketsThreadStorageRef	previousStorage;
#if PGP_WIN32
	char						h_name[256];
#endif

	PGPValidateSKEP(skep);
	PGPValidateParam(PGPKeyDBObjRefIsValid(authKey));
	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);
	}
	
	while (IsntPGPError(err))
	{
		PGPBoolean goodPassphrase;

		if (IsNull(newPasskey))
			goodPassphrase = PGPPassphraseIsValid(authKey,
								passphrase ?
									PGPOPassphrase(skep->context, passphrase):
									PGPONullOption(skep->context),
								PGPOLastOption(skep->context));
		else
			goodPassphrase = PGPPassphraseIsValid(authKey,
								PGPOPasskeyBuffer(skep->context, newPasskey, 
									newPasskeySize),
								PGPOLastOption(skep->context));
		
		if (!goodPassphrase)
		{
			if (IsntNull(skep->eventHandler))
			{
				if (IsntNull(newPassphrase))
					PGPFreeData(newPassphrase);

				if (IsntNull(newPasskey))
					PGPFreeData(newPasskey);

				skepEvent.type = kPGPskepEvent_PassphraseEvent;
				skepEvent.data.ppd.passphrase = NULL;
				skepEvent.data.ppd.passkey = NULL;
				
				err = skep->eventHandler(skep, &skepEvent, skep->userValue);
				if (IsPGPError(err))
					break;

				newPassphrase = skepEvent.data.ppd.passphrase;
				newPasskey = skepEvent.data.ppd.passkey;
				newPasskeySize = skepEvent.data.ppd.passkeySize;
				if (IsNull(newPassphrase) && IsNull(newPasskey))
					err = kPGPError_BadPassphrase;
				else
					passphrase = newPassphrase;
			}
			else
				err = kPGPError_BadPassphrase;
		}
		else
			break;
	}
	
	if (IsntPGPError(err))
	{
		if (IsNull(newPasskey))
			err = PGPtlsSetLocalPrivateKey(tlsSession, authKey, NULL,
					passphrase ?
						PGPOPassphrase( skep->context, passphrase ) :
						PGPONullOption( skep->context),
					PGPOLastOption( skep->context ) );
		else
			err = PGPtlsSetLocalPrivateKey(tlsSession, authKey, NULL,
					PGPOPasskeyBuffer( skep->context, newPasskey,
						newPasskeySize ),
					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(dataSize) + sizeof(dataSize) +
									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;

⌨️ 快捷键说明

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