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

📄 pgpdecode.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*____________________________________________________________________________
	pgpDecode.c
	High level decode functionality
	
	Copyright (C) 1997 Network Associates Inc. and affiliated companies.
	All rights reserved.

	$Id: pgpDecode.c,v 1.119 1999/05/07 23:47:44 hal Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"	/* or pgpConfig.h in the CDK */

#include <string.h>

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

/* Private headers */
#include "pgpSDKBuildFlags.h"
#include "pgpDebug.h"
#include "pgpEncodePriv.h"
#include "pgpAnnotate.h"
#include "pgpArmor.h"
#include "pgpBufMod.h"
#include "pgpSymmetricCipherPriv.h"
#include "pgpConvKey.h"
#include "pgpDecPipe.h"
#include "pgpDevNull.h"
#include "pgpEnv.h"
#include "pgpESK.h"
#include "pgpEventPriv.h"
#include "pgpFIFO.h"
#include "pgpFile.h"
#include "pgpFileMod.h"
#include "pgpFileRef.h"
#include "pgpFileSpec.h"
#include "pgpFileType.h"
#include "pgpHash.h"
#include "pgpKeyDB.h"
#include "pgpKeyIDPriv.h"
#include "pgpKDBInt.h"
#include "pgpMem.h"
#include "pgpMemMod.h"
#include "pgpOptionList.h"
#include "pgpPipeline.h"
#include "pgpPubKey.h"
#include "pgpRandomPoolPriv.h"
#include "pgpRngPub.h"
#include "pgpSig.h"
#include "pgpTextFilt.h"
#include "pgpTrstPkt.h"
#include "pgpUI.h"
#include "pgpVMemMod.h"
#include "pgpX509Priv.h"

#define elemsof(x) ((unsigned)(sizeof(x)/sizeof(*x)))

/************************** Types and Constants ***************************/


/* All state information for pgpDecode is kept in a struct like this */
struct PGPDecodeJob_
{
	PGPContextRef		 context;		/* Context pointer */
	PGPOptionListRef	 optionList;	/* List of all our options */
	PGPOptionListRef	 newOptionList;	/* New options from user callback */
	PGPUICb              ui;			/* Callback functions */
	PGPError			 err;			/* Error */
	PGPEnv				*env;			/* Environment for low-level fns */
	PGPRandomContext	*rng;			/* Random state */
	PGPOption			 op;			/* Selected option from list */
	PGPBoolean			 fUsedDetachedSigOp;  /* Have used detachedsig op */
	PGPPipeline			*head, **tail;	/* Low level pipeline */
	PGPPipeline			*outPipe;		/* Dynamic memory output module */
	PGPFile				*pfout;			/* Output file handle */
	PGPPipeline			*outKey;		/* Key data output module */
	PGPPipeline			*prevStarOutput;/* Deferred tail of output pipeline */
	PGPPipeline		   **prevOutput;	/* Address of pointer to pipe tail */
	PGPPipeline			*prevOutPipe;	/* Dynamic memory mod for prevoutput */
	PGPFile				*prevPFout;		/* Output file handle for prevoutput */
	PGPBoolean			 fPrevOutput;	/* Have set prevOutput */
	PFLConstFileSpecRef	 inFileRef;		/* Input filename handle */
	PGPFileRead			*pfrin;			/* Input file reading structure */
	PGPByte				*inBufPtr;		/* Input buffer pointer */
	PGPSize				 inBufLength;	/* Size of input buffer */
	PFLFileSpecRef		 outFileRef;	/* Output filename handle */
	PGPByte				*outBufPtr;		/* Output buffer pointer */
	PGPByte			   **outBufPtrPtr;	/* Dynamically allocated buf ptr */
	PGPSize				 outBufMaxLength; /* Allocated size of outBufPtr */
	PGPSize				*outBufUsedLength; /* Amount output to outBufPtr */
	PGPBoolean			 outDiscard;	/* True if want to discard output */
	PGPBoolean			 fixedOutput;	/* Use same output throughout */
	PGPBoolean			 fAppendOutput;	/* Append output to buffer or file */
	PGPEventHandlerProcPtr func;		/* Pointer to user callback func */
	PGPUserValue		 userValue;		/* Arg to callback func */
	PGPBoolean			 fNullEvents;	/* True if user wants null events */
	PGPUInt32			 localEncodeFlags; /* Macbinary etc. for output */
	PGPLineEndType		 lineEnd;		/* Line endings for text output */
	PGPKeySetRef		 keySet;		/* Keyset to check sigs, decrypt */
	PGPByte				*passPhrase;	/* Pass phrase from user */
	PGPSize				 passLength;	/* Length of passPhrase */
	PGPBoolean			 hashedPhrase;	/* True if given passkey */
	PGPBoolean			 passPhraseIsSessionKey; /* in passphrase buffer */
	PGPUInt32			sectionNumber;	/* Number of section we are on */
	PGPAnalyzeType		analyzeType;	/* Type of section we found */
	PGPInt32			analyzeState;	/* kAnalyze status */
	PGPInt32			scopeLevel;	/* Nesting scope */
	PGPInt32			scopeSegment;	/* scopeLevel at start of segment */
	PGPSize				sectOffset;		/* Offset in input to start of sect */
	PGPBoolean			passThrough;	/* True if outputing without change */
	PGPFifoContext		*passThroughFifo; /* Accumulate some passthrough data*/
	PGPByte				literalType;	/* type of literal packet */
	PGPBoolean			recurse;		/* Recursing on decode */
	PGPInputFormat		inputFormat;	/* Format of input data, PGP vs ... */
};
typedef struct PGPDecodeJob_ PGPDecodeJob;

/* analyzeState values */
enum {
	kAnalyzeWaiting = 1,
	kAnalyzeGotType,
	kAnalyzeSegmentEndWait
};


static PGPError sDecodeInputX509( PGPDecodeJob  *s );



/*********** Functions to set up data structures for pipeline *************/


/* Parse output specifications */

/*
 * Note that any outFileRef returned will be a fresh copy, which the
 * caller is responsible for freeing after use.
 */
	static PGPError
pgpSetupOutput(
	PGPOptionListRef	  optionList,
	PGPEnv				 *env,
	PFLFileSpecRef		 *outFileRef,	/* Output params */
	PGPByte				**outBufPtr,
	PGPByte			   ***outBufPtrPtr,
	PGPSize				 *outBufLength,
	PGPSize				**outBufUsed,
	PGPBoolean			 *outDiscard,
	PGPUInt32			 *localEncodeFlags,
	PGPLineEndType		 *lineEnd,
	PGPBoolean			 *pAppendOutput
	)
{
	PGPOption			 op;			/* Selected option from list */
	PGPError			 err;			/* Error return code */
	PGPUInt32			 localEncode;	/* Enum for macbinary, etc. */
	PFLConstFileSpecRef	 lOutFileRef;	/* Local copy of outfileref */
	PGPFileSpecRef	 	 lOutFileRefPGP;/* Another local copy of outfileref */
	PGPUInt32			 fDiscard;		/* Discard output option flag */
	PGPUInt32			 fAppendOutput;	/* Append to output flag */

	(void) env;

	/* Init return data to default states */
	pgpa( pgpaAddrValid( outFileRef, PFLConstFileSpecRef ) );
	pgpa( pgpaAddrValid( outBufPtr, PGPByte * ) );
	pgpa( pgpaAddrValid( outBufLength, PGPSize ) );
	pgpa( pgpaAddrValid( outBufUsed, PGPSize * ) );
	pgpa( pgpaAddrValid( outDiscard, PGPBoolean ) );
	pgpa( pgpaAddrValid( localEncodeFlags, PGPUInt32 ) );
	pgpa( pgpaAddrValid( lineEnd, PGPLineEndType ) );
	*outFileRef = NULL;
	*outBufPtr = NULL;
	*outBufLength = 0;
	*outBufUsed = NULL;
	*outDiscard = FALSE;
	*localEncodeFlags = 0;
	*lineEnd = pgpGetDefaultLineEndType ();
	*pAppendOutput = FALSE;

	/* Test for append flag */
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_AppendOutput, FALSE,
						 "%d", &fAppendOutput ) ) )
		goto error;
	*pAppendOutput = (PGPBoolean)fAppendOutput;

	/* See if there is an output file specified */
	if( IsPGPError( err = pgpSearchOptionSingle( optionList,
							 kPGPOptionType_OutputFileRef, &op ) ) )
		goto error;

	if( IsOp( op ) ) {
		/* Have an output file specified */
		if( IsPGPError( err = pgpOptionPtr( &op, (void **)&lOutFileRefPGP ) ) )
			goto error;
		lOutFileRef = (PFLConstFileSpecRef) lOutFileRefPGP;
		if( IsPGPError( err = PFLCopyFileSpec( lOutFileRef, outFileRef ) ) )
			goto error;
	}

	/* See if there is an output buffer specified */
	if( IsPGPError( err = pgpSearchOptionSingle( optionList,
							 kPGPOptionType_OutputBuffer, &op ) ) )
		goto error;

	if( IsOp( op ) ) {
		/* Have an output buffer specified */
		if( IsntNull( *outFileRef ) ) {
			pgpDebugMsg( "Error: multiple output options" );
			err = kPGPError_BadParams;
			goto error;
		}
	
		if( IsPGPError( err = pgpOptionPtrLengthPtr( &op, (void **)outBufPtr,
								outBufLength, (void **)outBufUsed ) ) )
			goto error;

	}

	/* Check for variable-sized output buffer specification */
	if( IsPGPError( err = pgpSearchOptionSingle( optionList,
							 kPGPOptionType_OutputAllocatedBuffer, &op ) ) )
		goto error;

	if( IsOp( op ) ) {
		/* Have an output buffer specified */
		if( IsntNull( *outFileRef ) || IsntNull( *outBufPtr ) ) {
			pgpDebugMsg( "Error: multiple output options" );
			err = kPGPError_BadParams;
			goto error;
		}
	
		if( IsPGPError( err = pgpOptionPtrLengthPtr( &op,
				(void **)outBufPtrPtr, outBufLength, (void **)outBufUsed ) ) )
			goto error;
	}

	/* Check for request to discard output (send to devnull module) */
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_DiscardOutput, FALSE,
						 "%d", &fDiscard ) ) )
		goto error;
	if( fDiscard ) {
		/* User wants to go to /dev/null */
		if( IsntNull( *outFileRef ) || IsntNull( *outBufPtr ) ||
			IsntNull( *outBufPtrPtr ) ) {
			pgpDebugMsg( "Error: multiple output options" );
			err = kPGPError_BadParams;
			goto error;
		}
		*outDiscard = TRUE;
	}

	/* Read output local encoding and line endings */
	if( IsPGPError( err = pgpSearchOptionSingle( optionList,
						  kPGPOptionType_LocalEncoding, &op ) ) )
			goto error;
	if( IsOp( op ) ) {
		if( IsPGPError( err = pgpOptionUInt( &op, &localEncode ) ) )
			goto error;
		*localEncodeFlags = pgpLocalEncodingToFlags( localEncode );
	}
	if( IsPGPError( err = pgpSearchOptionSingle( optionList,
						  kPGPOptionType_OutputLineEndType, &op ) ) )
		goto error;
	if( IsOp( op ) ) {
		PGPUInt32 uintLineEnd;
		if( IsPGPError( err = pgpOptionUInt( &op, &uintLineEnd ) ) )
			goto error;
		*lineEnd = (PGPLineEndType) uintLineEnd;
	}

	return kPGPError_NoErr;

error:

	*outFileRef = NULL;
	*outBufPtr = NULL;
	*outBufPtrPtr = NULL;
	*outBufLength = 0;
	*outDiscard = FALSE;
	*localEncodeFlags = 0;
	*lineEnd = pgpGetDefaultLineEndType();
	return err; 
}


/* Get keyring set from user if specified */

	static PGPError
pgpSetupKeySet(
	PGPOptionListRef	  optionList,
	PGPKeySetRef		 *keySet		/* Output params */
	)
{
	PGPOption			 op;			/* Selected option from list */
	PGPError			 err;			/* Error return code */

	/* Init return data to default states */
	pgpa( pgpaAddrValid( keySet, PGPKeySetRef ) );
	*keySet = NULL;

	/* See if there is a keyset specified */
	if( IsPGPError( err = pgpSearchOptionSingle( optionList,
							 kPGPOptionType_KeySetRef, &op ) ) )
		goto error;

	if( IsOp( op ) ) {
		if( IsPGPError( err = pgpOptionPtr( &op, (void **)keySet ) ) )
			goto error;
	}

	return kPGPError_NoErr;

error:
	*keySet = NULL;
	return err;
}
	
/*
 * Get passphrase from user.  We make a copy of the passphrase because if
 * it is specified from a callback, when we free the optionlist it will
 * go away.
 */

	static PGPError
pgpSetupDecodePassphrase(
	PGPContextRef	 	  context,		/* Input params */
	PGPOptionListRef	  optionList,
	PGPByte				**passPhrase,	/* Output params */
	PGPSize				 *passLength,
	PGPBoolean			 *hashedPhrase,
	PGPBoolean			 *sessionKey
	)
{
	void				*vPassPhrase;	/* Pointer to option pphrase */
	PGPByte				*lPassPhrase;	/* Local allocated passphrase */
	PGPSize				 lPassLength;	/* Local copy of pphrase length */
	PGPError			 err;			/* Error return code */

	/* Init return data to default states */
	pgpa( pgpaAddrValid( passPhrase, PGPByte * ) );
	pgpa( pgpaAddrValid( passLength, PGPSize ) );
	pgpa( pgpaAddrValid( passLength, PGPBoolean ) );
	*passPhrase = NULL;
	*passLength = (PGPSize)0;
	*hashedPhrase = FALSE;
	*sessionKey = FALSE;

	/* See if there is a pass phrase specified */
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_Passphrase, FALSE,
						 "%p%l", &vPassPhrase, &lPassLength ) ) )
		goto error;
	if( IsNull( vPassPhrase ) ) {
		if( IsPGPError( err = pgpFindOptionArgs( optionList,
							 kPGPOptionType_Passkey, FALSE,
							 "%p%l", &vPassPhrase, &lPassLength ) ) )
			goto error;
		if( IsntNull( vPassPhrase ) )
			*hashedPhrase = TRUE;
	}
	if( IsNull( vPassPhrase ) ) {
		if( IsPGPError( err = pgpFindOptionArgs( optionList,
							 kPGPOptionType_SessionKey, FALSE,
							 "%p%l", &vPassPhrase, &lPassLength ) ) )
			goto error;
		if( IsntNull( vPassPhrase ) )
			*sessionKey = TRUE;
	}
	if( IsntNull( vPassPhrase ) ) {
		lPassPhrase = (PGPByte *)
			PGPNewSecureData(PGPGetContextMemoryMgr(context), lPassLength, 0);
		if( IsNull( lPassPhrase ) ) {
			err = kPGPError_OutOfMemory;
			goto error;
		}
		pgpCopyMemory( vPassPhrase, lPassPhrase, lPassLength );
		*passPhrase = lPassPhrase;
		*passLength = lPassLength;
	}
	return kPGPError_NoErr;

error:
	*passPhrase = NULL;
	*passLength = (PGPSize)0;
	return err;
}


/*
 * Handle options requesting that we pass clearsigned data and/or keys
 * through to the output, unchanged.  We still do the signature checking
 * on signed text, and we still do the key callbacks.  This just affects
 * what goes into the output.
 */

	static PGPError
pgpSetupPassThrough(
	PGPContextRef	 	  context,		/* Input params */
	PGPOptionListRef	  optionList,
	PGPPipeline			 *pipeHead,
	PGPFifoContext		**fifo,			/* Output params */
	PGPBoolean			*recurse
	)
{
	PGPUInt32			 fPassClear;		/* True if passthroughcleartext */
	PGPUInt32			 fPassKeys;			/* True if passthroughkeys */
	PGPUInt32			 fRecurse;			/* True if recursivelydecode */
	PGPByte				 boolFlag = TRUE;	/* Flag for turning on modes */
	PGPError			 err;				/* Error return code */

	/* Init return data to default states */
	pgpa( pgpaAddrValid( fifo, PGPByte * ) );
	pgpa( pgpaAddrValid( recurse, PGPBoolean ) );
	*fifo = NULL;
	*recurse = FALSE;

	/* Read our passthroughoptions */
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_PassThroughClearSigned, FALSE,
						 "%d", &fPassClear ) ) )
		goto error;

⌨️ 快捷键说明

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