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

📄 pgpdecode.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		}
	}
	/* Detect bad parsing situations */
	if (type == PGPANN_ESK_TOO_BIG
		|| type == PGPANN_SIGNATURE_TOO_BIG
		|| type == PGPANN_PACKET_SHORT
		|| type == PGPANN_PACKET_TRUNCATED
		|| type == PGPANN_SCOPE_TRUNCATED) {
		err = kPGPError_BadPacket;
		goto error;
	} else if (type == PGPANN_ARMOR_TOOLONG
		|| type == PGPANN_ARMOR_BADLINE
		|| type == PGPANN_ARMOR_NOCRC
		|| type == PGPANN_ARMOR_CRCCANT
		|| type == PGPANN_ARMOR_CRCBAD) {
		err = kPGPError_AsciiParseIncomplete;
		goto error;
	}
	/* Fall through */
error:
	return err;
}


/*
 * Display a message as appropriate.
 * Nothing is appropriate for us, as we have no UI.  Assert an error
 * if it happens.  (Perhaps better simply to ignore it.)
 */
	static PGPError
pgpDecodeShowMessage(
	void				*arg,
	PGPInt32			 type,
	PGPInt32			 msg,
	PGPUInt32			 numargs,
	...
	)
{
	PGPDecodeJob		*s;				/* Parameters for callbacks */

	s = (PGPDecodeJob *) arg;

	(void)type;
	(void)msg;
	(void)numargs;
	return kPGPError_NoErr;
}


/*
 * Decide whether to work on a section or to skip it.
 */
	static PGPError
pgpDecodeDoCommit(
	void				*arg,
	PGPInt32			 scope
	)
{
	PGPDecodeJob		*s;				/* Parameters for callbacks */
	PGPError			 err;			/* Error code */

	s = (PGPDecodeJob *) arg;

	if( s->analyzeState == kAnalyzeGotType ) {
		/* Tell user of results, let him say if we should continue */
		s->analyzeState = kAnalyzeSegmentEndWait;

		err = pgpEventBeginLex( s->context, &s->newOptionList,
								s->func, s->userValue, s->sectionNumber,
								s->sectOffset );
		pgpCleanupOptionList( &s->newOptionList );
		if( IsPGPError( err ) )
			return err;

		/* Give user analysis callback, let him tell us to skip section */
		err = pgpEventAnalyze( s->context, &s->newOptionList,
								s->func, s->userValue, s->analyzeType );
		pgpCleanupOptionList( &s->newOptionList );
		if( err == kPGPError_SkipSection ) {
			return PGPANN_PARSER_EATIT;
		}
		if( IsPGPError( err ) )
			return err;
	}
	/* Don't recurse into literal recursion packets unless set up for it */
	/* Must be in recurse and passthrough mode to do it, else don't recurse */
	if (scope == PGPANN_LITERAL_BEGIN && s->literalType == PGP_LITERAL_RECURSE
		&& (s->passThroughFifo == NULL || !s->recurse))
		return PGPANN_PARSER_PROCESS;
	return PGPANN_PARSER_RECURSE;
}

/* Set up the output pipeline as appropriate */

	static PGPError
pgpDecodeSetupNewOutput(
	void				 *arg,
	PGPPipeline			**output,
	PGPInt32			  type,
	char const			 *suggested_name
	)
{
	PGPDecodeJob		 *s;			/* Parameters for callbacks */
	PGPError			  err;			/* Error code */
	PGPUInt32			  outputCount;	/* How many output options we got */
	PGPFileOpenFlags	  fileFlags;	/* Flags for opening output file */
	PGPFileType			  fileType;		/* Type field for output file */
	PGPByte				 *charMap;		/* Charmap for output text filter */
	PGPUInt32			  passThroughNonPGP;
	PGPUInt32			 dummyLocalEncodeFlags;
	PGPLineEndType		 dummyLineEnd;
	PGPContextRef		cdkContext	= NULL;
	PGPMemoryMgrRef		memoryMgr	= NULL;
	PGPBoolean			fFYEO = FALSE;
	
	s = (PGPDecodeJob *) arg;
	err = kPGPError_NoErr;
	cdkContext	= s->context;
	memoryMgr	= PGPGetContextMemoryMgr( cdkContext );

	/*
	 * We need to adjust the pipeline at other stages, so we will save
	 * the output pointer.  For those to work, it must always be the
	 * same whenever we are called.  (The output pointer is the _address_
	 * of a pointer to the output portion of the pipeline, not the pointer
	 * to the pipeline itself.)
	 */
	if( IsNull( s->prevOutput ) )
		s->prevOutput = output;
	pgpAssert( s->prevOutput == output );

	/* If have a prevoutput pipeline saved, switch back to that first. */
	if( s->fPrevOutput ) {
		if( IsPGPError( err = pgpCloseOutput( s, output ) ) )
			goto error;
		sRestoreOutputState( s, output );
	}

	if( type == PGPANN_PGPKEY_BEGIN && !s->passThrough ) {
		/*
		 * Here we are adding a key.  We must copy the data somewhere,
		 * and then convert it to a key set and then add it.
		 * We handle keys in passthrough mode below.
		 */
		sSaveOutputState( s, output );
		if ( IsNull( s->outKey = pgpVariableMemModCreate( cdkContext,
					output, ~(PGPSize)0 ) ) ) {
			/* Guess at the cause */
			err = kPGPError_OutOfMemory;
		}
		/* Return with success or failure */
		goto error;
	}

	if( type == PGPANN_NONPGP_BEGIN ) {
		if( IsPGPError( pgpFindOptionArgs( s->optionList,
						kPGPOptionType_PassThroughIfUnrecognized, FALSE,
						"%d", &passThroughNonPGP ) ) )
			goto error;
		if( !passThroughNonPGP ) {
			/*
			 * Trash non-PGP data if not requesting passthrough.
			 * We will use the prevOutput mechanism to go back to what our
			 * output was before when we are through with it.
			 */
			sSaveOutputState( s, output );
			if ( IsNull( pgpDevNullCreate ( cdkContext, output ) ) ) {
				/* Guess at the cause */
				err = kPGPError_OutOfMemory;
			}
			/* Return with success or failure */
			goto error;
		}
	}

	/* If have fixed output, just leave it open */
	if( s->fixedOutput && IsntNull( *output ) ) {
		/* Leave things open */
		goto checkpassthrough;
	}

	/* Close previous output if any */
	if( IsPGPError( err = pgpCloseOutput( s, output ) ) )
		goto error;
		
	if( !s->fixedOutput ) {
		/* Get output for next part from user */
		pgpAssert( IsntNull( s->func ) );
		fFYEO = IsntNull( suggested_name ) &&
				0==strcmp( suggested_name, "_CONSOLE" );
		/* Turn empty names and magic ones into a null suggested_name */
		if( IsntNull( suggested_name ) &&
			( fFYEO || *suggested_name == '\0' ) )
			suggested_name = NULL;
		if( IsPGPError (err = pgpEventOutput( s->context, &s->newOptionList,
							  s->func, s->userValue,
							  type, suggested_name, fFYEO ) ) )
			goto error;
		/* Parse new output information if any */
		if( IsntNull( s->outFileRef ) ) {
			PFLFreeFileSpec( s->outFileRef );
			s->outFileRef = NULL;
		}
		err = pgpSetupOutput( s->newOptionList,
							s->env, &s->outFileRef,
							&s->outBufPtr, &s->outBufPtrPtr,
							&s->outBufMaxLength, &s->outBufUsedLength,
							&s->outDiscard, &dummyLocalEncodeFlags,
							&dummyLineEnd, &s->fAppendOutput );
		pgpCleanupOptionList( &s->newOptionList );
		if( IsPGPError( err ) )
			goto error;
		/* Make sure he gave us exactly one output option */
		outputCount = !!IsntNull( s->outFileRef ) +
					  !!IsntNull( s->outBufPtr ) +
					  !!IsntNull( s->outBufPtrPtr ) +
					  !!s->outDiscard;
		if( outputCount == 0 ) {
			pgpDebugMsg( "Error: no output options" );
			err = kPGPError_BadParams;
			goto error;
		} else if( outputCount > 1 ) {
			pgpDebugMsg( "Error: multiple output options" );
			err = kPGPError_BadParams;
			goto error;
		}
	}

	/* No support for other types than text or binary now */
	if( type == PGPANN_NONPGP_BEGIN ) {
		/* Treat non-PGP data similarly to text input data */
		type = PGP_LITERAL_TEXT;
	} else if( type != PGP_LITERAL_TEXT ) {
		type = PGP_LITERAL_BINARY;
	}

	if( type==PGP_LITERAL_TEXT ) {
		/* Convert to local line endings if appropriate */
		charMap = (PGPByte *)pgpenvGetPointer( s->env, PGPENV_CHARMAPTOLATIN1,
											   NULL );
		output = pgpTextFiltCreate( s->context,
			output, charMap, 0, s->lineEnd );
	}

	/* Now open output modules as needed */
	if( IsntNull( s->outFileRef ) ) {
		/* Open output file */
		pgpAssert((s->localEncodeFlags & ~(kPGPFileOpenMaybeLocalEncode
									  | kPGPFileOpenNoMacBinCRCOkay)) == 0);

		/* Create output file pipeline */
		fileFlags = s->fAppendOutput ? kPGPFileOpenStdAppendFlags :
									   kPGPFileOpenStdWriteFlags ;
		fileFlags |=  s->localEncodeFlags;
	#if PGP_MACINTOSH
		/* always force decoding of MacBinary */
		fileFlags	|= kPGPFileOpenForceLocalEncode;
	#endif
		fileType =  type == PGP_LITERAL_TEXT ?
								kPGPFileTypeDecryptedText :
								kPGPFileTypeDecryptedBin;
		s->pfout = pgpFileRefOpen( cdkContext,
						(PFLConstFileSpecRef)s->outFileRef,
						fileFlags, fileType, &err );
		if( IsNull( s->pfout ) )
			goto error;
		
		/* Set up output pipeline */
		if( IsNull( pgpFileWriteCreate( cdkContext,
				output, s->pfout, 0 ) ) ) {
			/* Guess at the cause */
			err = kPGPError_OutOfMemory;
			pgpFileClose( s->pfout );
			goto error;
		}
	} else if( IsntNull( s->outBufPtr ) ) {
		/* Open fixed-size memory buffer */
		if ( IsNull( s->outPipe = pgpMemModCreate( cdkContext, output,
						(char *)s->outBufPtr, s->outBufMaxLength ) ) ) {
			/* Guess at the cause */
			err = kPGPError_OutOfMemory;
			goto error;
		}
		if( s->fAppendOutput ) {
			/* Skip past existing buffer contents */
			if( IsPGPError( err = (s->outPipe)->annotate( s->outPipe, NULL,
					 PGPANN_MEM_PREPEND,
					 (unsigned char *)s->outBufPtr, *s->outBufUsedLength ) ) )
				goto error;
		}
	} else if( IsntNull( s->outBufPtrPtr ) ) {
		/* Open variable-size memory buffer */
		/* Use secure mode if a FYEO buffer */
		s->outPipe = fFYEO	? pgpSecureVariableMemModCreate( cdkContext,
												output, s->outBufMaxLength )
							: pgpVariableMemModCreate( cdkContext,
												output, s->outBufMaxLength );
		
		if ( IsNull( s->outPipe ) ) {
			/* Guess at the cause */
			err = kPGPError_OutOfMemory;
			goto error;
		}
		if( s->fAppendOutput && *s->outBufUsedLength != 0 ) {
			/* Prepend existing buffer contents */
			if( IsPGPError( err = (s->outPipe)->annotate( s->outPipe, NULL,
					 PGPANN_MEM_PREPEND, (unsigned char *)*s->outBufPtrPtr,
					 *s->outBufUsedLength ) ) )
				goto error;
			/* Free buffer now that we have captured it */
			PGPFreeData( *s->outBufPtrPtr );
			*s->outBufPtrPtr = NULL;
		}
	} else if( s->outDiscard ) {
		/* Pass to the bit bucket */
		if ( IsNull( pgpDevNullCreate ( cdkContext, output ) ) ) {
			/* Guess at the cause */
			err = kPGPError_OutOfMemory;
			goto error;
		}
	} else {
		/* Checked for this case above */
		pgpAssert( 0 );
	}

checkpassthrough:
	/* Passthrough mode means we want to use data from annotations for
	 * output rather than the data coming down the pipe.  Save the output
	 * we've set up, and then convert output pipe to /dev/null for clearsign
	 * or to a memmod buffer for keys.
	 */
	if( s->passThrough ) {
		/*
		 * Handle passthrough for clearsign and keys.
		 * May have changed output temporarily for textfilt setup, so restore
		 * from prevOutput
		 */
		output = s->prevOutput;
		sSaveOutputState( s, output );
		sDrainPassThroughFifo( s );
		if( s->analyzeType == kPGPAnalyze_Key ) {
			if ( IsNull( s->outKey = pgpVariableMemModCreate( s->context,
						output, ~(PGPSize)0 ) ) ) {
				/* Guess at the cause */
				err = kPGPError_OutOfMemory;
			}
		} else {
			if ( IsNull( pgpDevNullCreate ( cdkContext, output ) ) ) {
				/* Guess at the cause */
				err = kPGPError_OutOfMemory;
			}
		}
	}

	return kPGPError_NoErr;
error:
	return err;
}


/* Local callback function */

	static PGPError
decodeLocalCallBack (
	void				*arg,
	PGPFileOffset		soFar,
	PGPFileOffset		total
	)
{
	PGPError			  err = kPGPError_NoErr;
	PGPDecodeJob		 *s = ( PGPDecodeJob * ) arg;

	if( IsntNull( s->func )  &&  s->fNullEvents ) {
		err = pgpEventNull( s->context, &s->newOptionList, s->func,
							s->userValue, soFar, total );
		pgpCleanupOptionList( &s->newOptionList );
	}
	return err;
}


/*
 * Look for input file when we find a detached signature.
 */
	static PGPError
pgpDecodeFindAltInput(
	void				*arg,
	PGPPipeline			*head
	)
{
	PGPDecodeJob		*s;				/* Parameters for callbacks */
	PFLConstFileSpecRef		 detFileRef;	/* Input fileref */
	PGPFileRead			*pfrdet;		/* Input PGPFile pointer */
	PGPByte				*detBufPtr;		/* Input buffer pointer */
	PGPSize				 detBufLength;	/* Input buffer length */
	PGPOption			 op;			/* Selected option from list */
	PGPOptionListRef	 setupOp;		/* Optlist for setting up input */
	PGPError			 err;			/* Error codes */
	PGPFileDataType		 inFileDataType;	/* Unused */
	PGPOptionListRef	 freshOpList;	/* Fresh options from the user */
	
	(void) head;

	s = (PGPDecodeJob *) arg;
	freshOpList = kInvalidPGPOptionListRef;

	/* See if there was a detached-signature option specified */
	if( IsPGPError( err = pgpSearchOptionSingle( s->optionList,
							 kPGPOptionType_DetachedSignature, &op ) ) )
		goto error;
	if( !s->fUsedDetachedSigOp && IsOp( op )  && IsntNull( op.subOptions ) ) {
		/* Only use the detachedsig op once, after that we will ask user */
		s->fUsedDetachedSigOp = TRUE;
		setupOp = op.subOptions;
	} else {
		/* Ask user for detached signature input */

		if( IsNull( s->func ) ) {
			err = kPGPError_DetachedSignatureFound;
			goto error;
		}

		if( IsPGPError (err = pgpEventDetachedSignature( s->context,
								&s->newOptionList, s->func, s->userValue ) ) )
			goto error;
		if( IsPGPError( err = pgpSearchOptionSingle( s->newOptionList,
								kPGPOptionType_DetachedSignature, &op ) ) )
			goto error;

⌨️ 快捷键说明

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