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

📄 pgpencsubr.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	pgpEncSubr.c
	Helper subroutines for encode/decode API
	
	Copyright (C) 1997 Network Associates Inc. and affiliated companies.
	All rights reserved.

	$Id: pgpEncSubr.c,v 1.59 1999/04/23 00:36:44 hal Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"	/* or pgpConfig.h in the CDK */

#include <stdarg.h>
#include <string.h>
#include <ctype.h>

/* Public headers */
#include "pgpPubTypes.h"
#include "pgpContext.h"
#include "pgpEncode.h"
#include "pgpErrors.h"
#include "pgpFileRef.h"
#include "pgpKeys.h"
#include "pgpMem.h"

/* Private headers */
#include "pgpDebug.h"
#include "pgpAnnotate.h"
#include "pgpDevNull.h"
#include "pgpEncodePriv.h"
#include "pgpEnv.h"
#include "pgpEventPriv.h"
#include "pgpMemMod.h"
#include "pgpPipeline.h"
#include "pgpPrsAsc.h"
#include "pgpRandomContext.h"
#include "pgpRngPub.h"
#include "pgpVMemMod.h"
#include "pgpUtilities.h"


/******************* Misc functions for encode/decode ********************/

/*
 * Convert the user flags used to specify local encoding into a flag value
 * from pgpFileRef.h
 */
	PGPFileOpenFlags
pgpLocalEncodingToFlags( PGPUInt32 localEncode )
{
	PGPFileOpenFlags	flags = (PGPFileOpenFlags)0;

	/* Wrapper function ensured that only one of these was given */
	if( localEncode & kPGPLocalEncoding_Auto )
		flags = kPGPFileOpenMaybeLocalEncode;
	else if( localEncode & kPGPLocalEncoding_Force )
		flags = kPGPFileOpenForceLocalEncode;

	/* Add optional modifier flags */
	if( localEncode & kPGPLocalEncoding_NoMacBinCRCOkay )
		flags |= kPGPFileOpenNoMacBinCRCOkay;

	return flags;
}



/******************* Helper functions for encode/decode ********************/



/*
 * Pump data from the memory buffer at inBufPtr, of size InBufLength,
 * into head.  Do the terminating sizeAdvise but don't do the teardown.
 */

	PGPError
pgpPumpMem(
	PGPPipeline			*head,
	PGPByte				*inBufPtr,
	PGPSize				 inBufLength,
	PGPProgressCallBack	 callBack,
	void				 *callBackArg
	)
{
	PGPSize				totalSize;
	PGPError			err = kPGPError_NoErr;
	PGPSize				written;

	totalSize = inBufLength;

	err = head->sizeAdvise( head, inBufLength );
	if( IsPGPError( err ) )
		return err;
	err = head->annotate (head, NULL, PGPANN_FILE_BEGIN, NULL, 0);
	if( IsPGPError( err ) )
		return err;
	err = head->sizeAdvise( head, inBufLength );

	while( inBufLength>0 && IsntPGPError( err ) ) {
		written = head->write( head, inBufPtr,
							   pgpMin(inBufLength, 4096), &err );
		inBufPtr += written;
		inBufLength -= written;
		if( IsPGPError( err ) )
			break;
		if( IsntNull( callBack ) )
			err = callBack( callBackArg, totalSize - inBufLength, totalSize );
	}
	if( IsntPGPError( err ) )
		err = head->sizeAdvise( head, 0 );
	if( IsntPGPError( err ) )
		err = head->annotate (head, NULL, PGPANN_FILE_END, NULL, 0);
	if( IsntPGPError( err ) )
		err = head->sizeAdvise( head, 0 );
	return err;
}


/* Send a warning event to the user if he is set up for events */

	PGPError
pgpWarnUser(
	PGPContextRef	 	 context,		/* Input parameters */
	PGPOptionListRef	 optionList,
	PGPError			 errCode,
	void				*warnArg
	)
{
	PGPError			 err;
	PGPEventHandlerProcPtr handler;
	PGPUserValue		 arg;
	PGPOptionListRef	dummyOptionList = NULL;

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_EventHandler, FALSE,
						 "%p%p", &handler, &arg ) ) )
		goto error;

	if( IsntNull( handler ) ) {
		if( IsPGPError( err = pgpEventWarning( context, &dummyOptionList,
								  handler, arg, errCode, warnArg ) ) )
			goto error;
		pgpCleanupOptionList( &dummyOptionList );
	}
	return kPGPError_NoErr;

error:
	return err;
}


/* Set fail-below validity values for failure and warning */

	PGPError
pgpGetMinValidity(
	PGPOptionListRef	 optionList,
	PGPValidity			*failValidity,	/* Output parameters */
	PGPValidity			*warnValidity
	)
{
	PGPError			 err;
	PGPOption			 op;
	PGPUInt32			temp;

	/* Init return pointers */
	pgpa( pgpaAddrValid( failValidity, PGPValidity ) );
	pgpa( pgpaAddrValid( warnValidity, PGPValidity ) );
	/* XXX Need to fix these based on trust model and other aspects */
	*failValidity = kPGPValidity_Unknown;
	*warnValidity = kPGPValidity_Marginal;

	if( IsPGPError( err = pgpSearchOptionSingle( optionList,
						  kPGPOptionType_FailBelowValidity, &op ) ) )
		goto error;
	if( IsOp( op ) ) {
		
		if( IsPGPError( err = pgpOptionUInt( &op, &temp ) ) )
			goto error;
		*failValidity	= (PGPValidity)temp;
	}
	if( IsPGPError( err = pgpSearchOptionSingle( optionList,
						  kPGPOptionType_WarnBelowValidity, &op ) ) )
		goto error;
	if( IsOp( op ) ) {
		if( IsPGPError( err = pgpOptionUInt( &op, &temp ) ) )
			goto error;
		*warnValidity	= (PGPValidity)temp;
	}
	return kPGPError_NoErr;

error:
	return err;
}

	


/* Check a key for encryption or signature-verification validity.  Return
   an error if it is no good, no error to proceed */

	PGPError
pgpCheckKeyValidity(
	PGPContextRef	 	 context,		/* Input parameters */
	PGPOptionListRef	 optionList,
	PGPKey				*key,
	RingSet const		*ringSet,
	PGPValidity			 failValidity,
	PGPValidity			 warnValidity,
	PGPKeySet			*warnKeySet,	/* Output parameters */
	PGPValidity			*pValidity
	)
{
	PGPValidity			 validity;
	PgpTrustModel		 pgptrustmodel;
	PGPError			 err;
	PGPBoolean			 fRevoked,
						 fExpired,
						 fDisabled;

	(void) context;
	(void) optionList;

	if( IsntNull( pValidity ) )
		*pValidity = kPGPValidity_Unknown;

	pgptrustmodel = pgpTrustModel (ringSetPool (ringSet));

	/* First calculate validity level */
	if (pgptrustmodel == PGPTRUST0) {
		if( IsPGPError( err = PGPGetKeyNumber( key, kPGPKeyPropValidity,
											   (PGPInt32 *)&validity ) ) )
			goto error;
	} else {
		/* Not yet supported */
		if( IsPGPError( err = PGPGetKeyNumber( key, kPGPKeyPropValidity,
											   (PGPInt32 *)&validity ) ) )
			goto error;
	}

	if( IsntNull( pValidity ) )
		*pValidity = validity;

	if( IsPGPError( err = PGPGetKeyBoolean( key, kPGPKeyPropIsRevoked,
											&fRevoked ) ) )
		goto error;
	if( fRevoked ) {
		err = kPGPError_KeyRevoked;
		goto error;
	}

	if( IsPGPError( err = PGPGetKeyBoolean( key, kPGPKeyPropIsDisabled,
											&fDisabled ) ) )
		goto error;
	if( fDisabled ) {
		err = kPGPError_KeyDisabled;
		goto error;
	}

	if( IsPGPError( err = PGPGetKeyBoolean( key, kPGPKeyPropIsExpired,
											&fExpired ) ) )
		goto error;
	if( fExpired ) {
		err = kPGPError_KeyExpired;
		goto error;
	}

	if( validity < failValidity ) {
		/* Return an error */
		err = kPGPError_KeyInvalid;
		goto error;
	} else if( validity < warnValidity && IsntNull( warnKeySet ) ) {
		/* Send a warning */
		PGPKeySet *tmpKeySet;
		if( IsPGPError( err = PGPNewSingletonKeySet( key,
													 &tmpKeySet ) ) )
			goto error;
		if( IsNull( tmpKeySet ) ) {
			err = kPGPError_OutOfMemory;
			goto error;
		}
		if( IsPGPError( err = PGPAddKeys( tmpKeySet, warnKeySet ) ) )
			goto error;
		if( IsPGPError( err = PGPFreeKeySet( tmpKeySet ) ) )
			goto error;
	}

	/* Everything is OK, proceed */
	return kPGPError_NoErr;

error:
	return err;
}

/*
 * Set *outputBufferLen from pipeBuf.
 * bufferSize is the allocated size of the buffer, and we return an error
 * if we exceeded the allocated size.  (We don't actually write beyond
 * the end of the buffer, of course.)
 */

	PGPError
pgpGetMemOutput(
	PGPPipeline			*pipeBuf,
	PGPSize				 bufferSize,
	PGPSize				*outputBufferLen
	)
{
	pgpa( pgpaAddrValid( pipeBuf, PGPPipeline ) );

	pipeBuf->annotate( pipeBuf, NULL,
					   PGPANN_MEM_BYTECOUNT, (PGPByte *)outputBufferLen,
					   sizeof( *outputBufferLen ) );
	if( *outputBufferLen > bufferSize )
		return kPGPError_OutputBufferTooSmall;
	return kPGPError_NoErr;
}


/*
 * Set *outputBufferPtr and *outputBufferLen from pipeBuf.  maxSize
 * was our limit on the allocated size of the buffer, and we return an
 * error if we exceeded the max size.  (We don't actually write more data
 * than that into our dynamically allocated buffer, though.)  The difference
 * from the above is that in this case the buffer was dynamically allocated
 * while in the previous routine it was a static buffer we were given.
 */

	PGPError
pgpGetVariableMemOutput(
	PGPPipeline			*pipeBuf,
	PGPSize				 maxSize,
	PGPByte			   **outputBufferPtr,
	PGPSize				*outputBufferLen
	)
{
	PGPError	err	= kPGPError_NoErr;
	
	pgpa( pgpaAddrValid( pipeBuf, PGPPipeline ) );

	err	= pipeBuf->annotate( pipeBuf, NULL,
				 PGPANN_MEM_BYTECOUNT, (PGPByte *)outputBufferLen,
				 sizeof( *outputBufferLen ) );
	if ( IsntPGPError( err ) )
	{
		pipeBuf->annotate( pipeBuf, NULL,
			PGPANN_MEM_MEMBUF, (PGPByte *)outputBufferPtr,
			sizeof( *outputBufferPtr ) );
	}
	
	if ( IsntPGPError( err ) )
	{
		if( *outputBufferLen > maxSize )
			err	= kPGPError_OutputBufferTooSmall;
	}
		
	return err;
}


/*
 * See if optionList specifies PGPMIME encoding, and if so, get MIME body
 * offset and return it to caller.
 */
	PGPError
pgpGetPGPMIMEBodyOffset(
	PGPPipeline			*pipeBuf,
	PGPOptionListRef	 optionList)
{
	PGPSize				*mimeBodyOffPtr;
	PGPSize				 mimeBodyOff;
	char				*mimeSeparator;
	PGPUInt32	 		 mimeHeaderLines;
	PGPUInt32			 mimeFlag;
	PGPUInt32			 lineEndFlag;
	PGPLineEndType		 lineEnd;
	PGPUInt32			 uintLineEnd;
	PGPError			 err = kPGPError_NoErr;

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
							 kPGPOptionType_PGPMIMEEncoding, FALSE,
							 "%d%p%p", &mimeFlag, &mimeBodyOffPtr,
									   &mimeSeparator) ) )
		goto error;
	if( mimeFlag ) {
		if( IsntNull( mimeBodyOffPtr ) ) {
			if( IsPGPError( err = pipeBuf->annotate( pipeBuf, NULL,
					 PGPANN_PGPMIME_HEADER_SIZE,
					 (unsigned char *)&mimeBodyOff, sizeof(mimeBodyOff) ) ) )
			   goto error;
			if( IsPGPError( err = pgpFindOptionArgs( optionList,
								  kPGPOptionType_OutputLineEndType, FALSE,
								  "%b%d", &lineEndFlag, &uintLineEnd ) ) )
				goto error;
			if( lineEndFlag )
				lineEnd = (PGPLineEndType)uintLineEnd;
			else
				lineEnd = pgpGetDefaultLineEndType ();
			if( lineEnd == kPGPLineEnd_CRLF ) {
				if( IsPGPError( err = pipeBuf->annotate( pipeBuf, NULL,
									PGPANN_PGPMIME_HEADER_LINES,
									(unsigned char *)&mimeHeaderLines,
									sizeof(mimeHeaderLines) ) ) )
					goto error;
				mimeBodyOff += mimeHeaderLines;
			}
			*mimeBodyOffPtr = mimeBodyOff;
		}
		if( IsntNull( mimeSeparator ) ) {
			if( IsPGPError( err = pipeBuf->annotate( pipeBuf, NULL,
					 PGPANN_PGPMIME_SEPARATOR,
					 (unsigned char *)mimeSeparator,
					 kPGPMimeSeparatorSize ) ) )
				goto error;
		}
	}
error:
	return err;
}




/* Line ending control */

	PGPLineEndType
pgpGetDefaultLineEndType ()
{
#if defined(PGP_MSDOS) || defined(PGP_WIN32)
	return kPGPLineEnd_CRLF;
#elif PGP_MACINTOSH
	return kPGPLineEnd_CR;
#else
	return kPGPLineEnd_LF;
#endif
}




/* Parse an optionlist structure and extract callback info */

	PGPError
pgpSetupCallback(
	PGPOptionListRef	  optionList,
	PGPEventHandlerProcPtr *func,		/* Output params */
	PGPUserValue		 *userValue,
	PGPBoolean			 *fNullEvents
	)
{
	PGPError			  err;
	PGPBoolean			  lNullEvents;

	/* Init return data to default states */
	pgpa( pgpaAddrValid( func, PGPEventHandlerProcPtr ) );
	pgpa( pgpaAddrValid( userValue, PGPUserValue ) );
	pgpa( pgpaAddrValid( fNullEvents, PGPBoolean ) );
	*func = NULL;
	*userValue = (PGPUserValue)0;
	*fNullEvents = FALSE;

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_EventHandler, FALSE,
						 "%p%p", func, userValue ) ) )
		goto error;

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_SendNullEvents, FALSE,
						 "%b", &lNullEvents ) ) )
		goto error;
	if( lNullEvents ) {
		/* Wants notification of null events */
		if( IsNull (*func) ) {
			pgpDebugMsg(
				   "Error: Null events requested without event handler" );
			err = kPGPError_BadParams;
			goto error;
		}
		*fNullEvents = TRUE;
	}
	return kPGPError_NoErr;

error:
	*func = NULL;
	*userValue = (PGPUserValue)0;
	*fNullEvents = FALSE;

	return err;
}

		

/* Open input specification if there is one.  Optionally set up filename
 * literal structure, and seed RNG.
 */

	PGPError
pgpSetupInput(
	PGPContextRef	 	  context,		/* Input params */
	PGPOptionListRef	  optionList,
	PgpLiteralParams	 *literal,
	PGPRandomContext	 *rng,
	PGPBoolean			  inputMode,
	PGPBoolean			  detachedSignature,
	PFLConstFileSpecRef	 *inFileRef,	/* Output params */
	PGPFileRead         **pfrin,
	PGPFileDataType		 *inFileDataType,
	PGPByte				**inBufPtr,
	PGPSize				 *inBufLength
	)
{
	PGPOption			 op;			/* Selected option from list */
	PGPError			 err;			/* Error return code */
	static char			 fyeomagic[] = "_CONSOLE"; /* Display-only mode */
	PGPUInt32			 localEncode;	/* Special input encoding (macbin) */
	PGPFileOpenFlags	 localEncodeFlags;	/* Flag form of localEncode */
	PGPByte const		*peekBuf;		/* For RNG seeding from file */
	PGPSize				 peekLength;	/* Length of peekBuf */

	/* Init return data to default states */
	pgpa( pgpaAddrValid( inFileRef, PFLConstFileSpecRef ) );
	pgpa( pgpaAddrValid( pfrin, PGPFileRead * ) );
	pgpa( pgpaAddrValid( inFileDataType, PGPFileDataType ) );
	pgpa( pgpaAddrValid( inBufPtr, PGPByte * ) );
	pgpa( pgpaAddrValid( inBufLength, PGPSize ) );

⌨️ 快捷键说明

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