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

📄 pgpencsubr.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 3 页
字号:

	pgpAssert( IsntNull( pOutBuf ) );
	pgpAssert( IsntNull( pOutBufLength ) );
	*pOutBuf = NULL;
	*pOutBufLength = 0;

	mgr = PGPPeekContextMemoryMgr( context );
	outBuf = PGPNewData( mgr, 0, 0 );
	if( IsNull( outBuf ) ) {
		err = kPGPError_OutOfMemory;
		goto error;
	}

	pgpParseAscInit ();

	/* Skip leading spaces on each line */
	while (inBufLength && isspace(inBuf[0]))
		--inBufLength,++inBuf;

	if (inBufLength >= sizeof(sBegin)-1 &&
		pgpMemoryEqual (sBegin, inBuf, sizeof(sBegin)-1))
	{
		/* Must skip to end of line */
		while (inBufLength && (inBuf[0] != '\n') && (inBuf[0] != '\r'))
			--inBufLength,++inBuf;
	}
		
	for ( ; ; )
	{
		while (inBufLength && isspace(inBuf[0]))
			--inBufLength,++inBuf;
		if( inBufLength == 0 )
			break;
		if( inBufLength >= sizeof(sEnd)-1 &&
			pgpMemoryEqual (sEnd, inBuf, sizeof(sEnd)-1) )
			break;
		inlen = 0;
		while( inlen < inBufLength && !isspace(inBuf[inlen]) )
			++inlen;
		if( inlen % 4 != 0 )
		{
			err = kPGPError_BadParams;
			goto error;
		}
		err = PGPReallocData( mgr, &outBuf, outBufLength + inlen*3/4, 0 );
		if( IsPGPError( err ) )
			goto error;
		outlen = pgpDearmorLine (inBuf, (PGPByte *)outBuf+outBufLength, inlen);
		if( outlen < 0 )
		{
			err = (PGPError) outlen;
			goto error;
		}
		pgpAssert( (PGPUInt32)outlen <= inlen*3/4 );
		outBufLength += outlen;
		inBuf += inlen;
		inBufLength -= inlen;
	}
	*pOutBuf = (PGPByte *) outBuf;
	*pOutBufLength = outBufLength;

 error:
	if( IsPGPError( err ) && IsntNull( outBuf ) )
		PGPFreeData( outBuf );

	return err;
}



/* Set up output file pipeline */

	PGPError
pgpSetupOutputPipeline(
	PGPContextRef	 	  context,		/* Input params */
	PGPOptionListRef	  optionList,
	PGPEnv				 *env,
	PGPBoolean			  fEncrypt,
	PGPBoolean			  fSign,
	PGPBoolean			  fDetachedSig,
	PGPBoolean			  fAppendOutput,
	PGPBoolean			  fExported509Keys,
	PGPPipeline		   ***tail,			/* Input/output param */
	PFLConstFileSpecRef	 *outFileRef,	/* Output params */
	PGPFile				 **pfout,
	PGPByte				**outBufPtr,
	PGPByte			   ***outBufPtrPtr,
	PGPSize				 *outBufLength,
	PGPSize				**outBufUsed,
	PGPPipeline			**outPipe
	)
{
	PGPOption			 op;			/* Selected option from list */
	PGPError			 err;			/* Error return code */
	PGPFileType			 filetype;		/* Type of output file we open */
	PGPUInt32			 fDiscard;		/* Discard output option flag */
	PGPBoolean			 fArmor;		/* Ascii armor */
	PGPMemoryMgrRef		memoryMgr	= NULL;

	/* Init return data to default states */
	pgpa( pgpaAddrValid( outFileRef, PFLConstFileSpecRef ) );
	pgpa( pgpaAddrValid( pfout, PGPFile * ) );
	pgpa( pgpaAddrValid( outBufPtr, PGPByte * ) );
	pgpa( pgpaAddrValid( outBufPtrPtr, PGPByte ** ) );
	pgpa( pgpaAddrValid( outBufLength, PGPSize ) );
	pgpa( pgpaAddrValid( outBufUsed, PGPSize * ) );
	pgpa( pgpaAddrValid( outPipe, PGPPipeline * ) );
	*outFileRef = NULL;
	*pfout = NULL;
	*outBufPtr = NULL;
	*outBufPtrPtr = NULL;
	*outBufLength = 0;
	*outBufUsed = NULL;
	*outPipe = NULL;
	
	memoryMgr	= PGPPeekContextMemoryMgr( context );

	/* 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 */
		PGPFileOpenFlags flags;

		if( IsPGPError( err = pgpOptionPtr( &op, (void **)outFileRef ) ) )
			goto error;

		/* See whether we are outputing an encrypted vs ascii armored file */
		fArmor = pgpenvGetInt( env, PGPENV_ARMOR, NULL, NULL );
		if( fArmor) {
			filetype = kPGPFileTypeArmorFile;
		} else if( fEncrypt ) {
			filetype = kPGPFileTypeEncryptedData;
		} else if( fSign ) {
			if( fDetachedSig ) {
				filetype = kPGPFileTypeDetachedSig;
			} else {
				filetype = kPGPFileTypeSignedData;
			}
		} else if( fExported509Keys ) {
			filetype = kPGPFileTypeExported509Keys;
		} else {
			pgpDebugMsg( "pgpSetupOutputPipeline(): Unknown file type" );
			filetype = kPGPFileTypeNone;
		}

		/* Open output file */
		flags = fAppendOutput ? kPGPFileOpenStdAppendFlags :
								kPGPFileOpenStdWriteFlags ;
		*pfout = pgpFileRefOpen( context, *outFileRef, flags, filetype, &err );
		if( IsNull( *pfout ) ) {
			goto error;
		}
		
		/* Set up output pipeline.  This reads and writes *tail. */
		if( IsNull( pgpFileWriteCreate( context,
					*tail, *pfout, 1 ) ) ) {
			err = kPGPError_OutOfMemory;
			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;

		*outPipe = pgpMemModCreate( context, *tail, (char *) *outBufPtr,
									*outBufLength);
		if ( IsNull( *outPipe ) ) {
			err = kPGPError_OutOfMemory; /* What else could it be? */
			goto error;
		}
		if( fAppendOutput ) {
			/* Skip past existing buffer contents */
			if( IsPGPError( err = (*outPipe)->annotate( *outPipe, NULL,
					 PGPANN_MEM_PREPEND,
					 (unsigned char *)*outBufPtr, **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;

		*outPipe = pgpVariableMemModCreate( context,
						*tail, *outBufLength );
		if ( IsNull( *outPipe ) ) {
			err = kPGPError_OutOfMemory; /* What else could it be? */
			goto error;
		}
		if( fAppendOutput && **outBufUsed != 0 ) {
			/* Prepend existing buffer contents */
			if( IsPGPError( err = (*outPipe)->annotate( *outPipe, NULL,
					 PGPANN_MEM_PREPEND,
					 (unsigned char *)**outBufPtrPtr, **outBufUsed ) ) )
				goto error;
			/* Free buffer now that we have captured it */
			PGPFreeData( **outBufPtrPtr );
			**outBufPtrPtr = NULL;
		}
	}

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_DiscardOutput, FALSE,
						 "%d", &fDiscard ) ) )
		goto error;
	/* Make Discard be the default if no output options specified */
	if( fDiscard || ( IsNull( *outFileRef ) && IsNull( *outBufPtr )
			   						 && IsNull( *outBufPtrPtr ) ) ) {
		/* User wants to go to /dev/null */
		if( IsntNull( *outFileRef ) || IsntNull( *outBufPtr ) ||
			IsntNull( *outBufPtrPtr ) ) {
			pgpDebugMsg( "Error: multiple output options" );
			err = kPGPError_BadParams;
			goto error;
		}
		if ( IsNull( pgpDevNullCreate( context, *tail ) ) ) {
			err = kPGPError_OutOfMemory; /* What else could it be? */
			goto error;
		}
	}

	return kPGPError_NoErr;

error:

	*outFileRef = NULL;
	if( IsntNull( *pfout ) ) {
		pgpFileClose( *pfout );
		*pfout = NULL;
	}
	*outBufPtr = NULL;
	*outBufPtrPtr = NULL;
	*outBufLength = 0;
	*outPipe = NULL;
	return err; 
}



/* Output data from a buffer into the requested optionlist endpoint */

	PGPError
pgpOutputBufferByOptionList( PGPContextRef context, PGPByte const *buf,
	PGPSize bufLength, PGPOptionListRef optionList, PGPInt32 annotate )
{
	PGPPipeline			*head = NULL, **tail = &head;
	PGPUInt32			fAppendOutput;
	PGPUInt32			fArmorOutput;
	PGPEnv			   *env;
	PFLConstFileSpecRef	 outFileRef;
	PGPFile				*pfout;
	PGPByte				*outBufPtr;
	PGPByte			   **outBufPtrPtr;
	PGPSize				 outBufMaxLength;
	PGPSize				*outBufUsedLength;
	PGPPipeline			*outPipe;
	PGPError			err;

	env = pgpContextGetEnvironment( context );

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_ArmorOutput, FALSE,
						 "%d", &fArmorOutput ) ) )
		goto error;
	if( fArmorOutput && annotate != 0 )
	{
		PGPByte				*charMap;
		PGPLineEndType		 lineEnd;
		PGPOption			 op;

		tail = pgpArmorWriteCreate ( context, tail, env, &pgpByteFifoDesc,
									 NULL, PGPVERSION_3, PGP_ARMOR_NORMAL );
		head->annotate (head, NULL, annotate, 0, 0);

		/* Convert to local line endings if appropriate */
		charMap = (PGPByte *)pgpenvGetPointer( env, PGPENV_CHARMAPTOLATIN1,
											   NULL );
		lineEnd = pgpGetDefaultLineEndType ();
		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;
		}
		tail = pgpTextFiltCreate( context, tail, charMap, 0, lineEnd );
	}

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_AppendOutput, FALSE,
						 "%d", &fAppendOutput ) ) )
		goto error;
	err = pgpSetupOutputPipeline( context, optionList,
							env, FALSE, FALSE, FALSE,
							(PGPBoolean)fAppendOutput, TRUE,
							&tail, &outFileRef, &pfout,
							&outBufPtr, &outBufPtrPtr,
							&outBufMaxLength, &outBufUsedLength,
							&outPipe );
	
	if( IsPGPError( err ) )
		goto error;

	err = pgpPumpMem( head, (PGPByte *)buf, bufLength, NULL, NULL );
	if( IsPGPError( err ) )
		goto error;

	if( outPipe ) {
		if( IsntNull( outBufPtrPtr ) ) {
			/* Dynamically allocated buffer - tell user size & position */
			if( IsPGPError( err = pgpGetVariableMemOutput( outPipe,
							outBufMaxLength, outBufPtrPtr,
							outBufUsedLength ) ) )
				goto error;
		} else {
			/* Fixed size buffer - tell user actual size used */
			pgpAssert( IsntNull( outBufPtr ) );
			if( IsPGPError( err = pgpGetMemOutput( outPipe,
						outBufMaxLength, outBufUsedLength ) ) )
				goto error;
		}
	}

	head->teardown( head );
	head = NULL;

error:

	if( IsntNull( head ) )
		head->teardown( head );

	return err;
}





/*__Editor_settings____

	Local Variables:
	tab-width: 4
	End:
	vi: ts=4 sw=4
	vim: si
_____________________*/

⌨️ 快捷键说明

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