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

📄 pgpencode.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 4 页
字号:
								 kPGPOptionType_Passphrase, FALSE,
								 "%p%l", &passPhrase, &passLength ) ) )
				goto error;
			if( IsNull( passPhrase ) ) {
				hashedPhrase = TRUE;
				if( IsPGPError( err = pgpFindOptionArgs( op.subOptions,
								kPGPOptionType_Passkey, FALSE,
								"%p%l", &passPhrase, &passLength ) ) )
					goto error;
			}
			if( IsPGPError( err = pgpFindOptionArgs( op.subOptions,
								kPGPOptionType_CachePassphrase, FALSE,
								"%d%b", &cacheTimeOut, &cacheGlobal ) ) )
				goto error;
			if( !pgpSecPassphraseOK( signKey, passPhrase, passLength,
									 hashedPhrase, cacheTimeOut, cacheGlobal ))
			{
				err = kPGPError_BadPassphrase;
				goto error;
			}
		}

		/* See if text or binary mode */
		if( knownBinaryInput )
		{
			signMode = PGP_SIGTYPE_BINARY;
		}
		else
		{
			signMode =
				( PGPByte ) (pgpenvGetInt( env, PGPENV_TEXTMODE, NULL, NULL) ?
							PGP_SIGTYPE_TEXT : PGP_SIGTYPE_BINARY );
		}
		
		*sigspec = pgpSigSpecCreate( env, signKey, signMode );
		if( needsPassphrase )
			pgpSigSpecSetPassphrase( *sigspec, passPhrase, passLength,
									 hashedPhrase );
	}

	if( sepsig && IsNull( *sigspec ) ) {
		/* Error, detached sig requested without signing! */
		pgpDebugMsg( "Error: detached signature without signing key" );
		err = kPGPError_BadParams;
		goto error;
	}
	if( sepsig && fHaveEncryption ) {
		/* Error, can't do detached sig if encrypting */
		pgpDebugMsg( "Error: detached signature with encryption" );
		err = kPGPError_BadParams;
		goto error;
	}
	return kPGPError_NoErr;

error:
	if( IsntNull( *sigspec ) )
		pgpSigSpecDestroy (*sigspec);
	return err;
}



/************************** Main encode function ****************************/


/* All state information for pgpEncode is kept in a struct like this */
struct pgpEncodeJobState_
{
	PGPContextRef		 context;		/* Context pointer */
	PGPOptionListRef	 optionList;	/* List of all our options */
	PGPOptionListRef	 newOptionList;	/* Options changed by callback */
	PGPError			 err;			/* Error */
	PGPPipeline			*head, **tail;	/* Low level pipeline */
	PGPConvKey			*convkey;		/* Conventional encryption params */
	PGPSigSpec			*sigspec;		/* Message signing params */
	PGPKeySetRef		pubkeys;		/* Message encryption keys */
	PgpLiteralParams	 literal;		/* Filename, type info */
	PGPBoolean			 sepsig;		/* Create detached signature */
	PFLConstFileSpecRef	 inFileRef;		/* Input filename handle */
	PGPFileRead			*pfrin;			/* Input file reading structure */
	PGPByte				*inBufPtr;		/* Input buffer pointer */
	PGPSize				 inBufLength;	/* Size of input buffer */
	PFLConstFileSpecRef	 outFileRef;	/* Output filename handle */
	PGPFile				*pfout;			/* Output file writing structure */
	PGPByte				*outBufPtr;		/* Output buffer pointer */
	PGPByte			   **outBufPtrPtr;	/* Dynamically allocated buf ptr */
	PGPSize				 outBufMaxLength; /* Allocated size of outBufPtr */
	PGPSize				*outBufUsedLength; /* Amount output to outBufPtr */
	PGPPipeline			*outPipe;		/* Output-buffer pipeline module */
	PGPEnv				*env;			/* Environment for low-level fns */
	PGPRandomContext	*rng;			/* Random state */
	PGPOption			 op;			/* Selected option from list */
	PGPEventHandlerProcPtr func;		/* Pointer to user callback func */
	PGPUserValue		 userValue;		/* Arg to callback func */
	PGPBoolean			 fNullEvents;	/* True if user wants null events */
	PGPOutputFormat		 outputFormat;	/* Format of output data, PGP vs ... */
};
typedef struct pgpEncodeJobState_ pgpEncodeJobState;

static PGPError sPackageOutputX509( pgpEncodeJobState  *s );


/* Local callback function */

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

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

	static PGPError
encodePKEncryptCallBack (
	void				*arg,
	int					code
	)
{
	PGPError			  err = kPGPError_NoErr;
	pgpEncodeJobState	 *s = ( pgpEncodeJobState * ) arg;

	(void) code;

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




static const PGPOptionType encodeOptionSet[] = {
	kPGPOptionType_InputFileRef,
	kPGPOptionType_InputBuffer,
	kPGPOptionType_InputFileName,
	kPGPOptionType_OutputFileRef,
	kPGPOptionType_OutputBuffer,
	kPGPOptionType_OutputAllocatedBuffer,
	kPGPOptionType_AppendOutput,
	kPGPOptionType_DiscardOutput,
	kPGPOptionType_LocalEncoding,
	kPGPOptionType_RawPGPInput,
	kPGPOptionType_EncryptToKeyDBObj,
	kPGPOptionType_EncryptToKeySet,
	kPGPOptionType_SignWithKey,
	kPGPOptionType_ConventionalEncrypt,
	kPGPOptionType_Passphrase,
	kPGPOptionType_Passkey,
	kPGPOptionType_CachePassphrase,
	kPGPOptionType_DetachedSignature,
	kPGPOptionType_CipherAlgorithm,
	kPGPOptionType_HashAlgorithm,
	kPGPOptionType_FailBelowValidity,
	kPGPOptionType_WarnBelowValidity,
	kPGPOptionType_PGPMIMEEncoding,
	kPGPOptionType_OutputLineEndType,
	kPGPOptionType_EventHandler,
	kPGPOptionType_SendNullEvents,
	kPGPOptionType_AskUserForEntropy,
	kPGPOptionType_ArmorOutput,
	kPGPOptionType_DataIsASCII,
	kPGPOptionType_ClearSign,
	kPGPOptionType_ForYourEyesOnly,
	kPGPOptionType_CommentString,
	kPGPOptionType_Compression,
	kPGPOptionType_VersionString,
	kPGPOptionType_OmitMIMEVersion,
	kPGPOptionType_PreferredAlgorithms,
	kPGPOptionType_OutputFormat,
	/* really only for PGPExport, but that routine calls this */
	kPGPOptionType_ExportPrivateKeys,
	kPGPOptionType_ExportPrivateSubkeys,
	kPGPOptionType_ExportFormat,
	kPGPOptionType_ExportKeySet,
	kPGPOptionType_ExportKeyDBObj
};


/* Main entry point for this module */

	PGPError
pgpEncodeInternal(
	PGPContextRef		context,
	PGPOptionListRef	optionList
	)
{
	pgpEncodeJobState	 jobState,		/* State in a struct */
						*s=&jobState;	/* Use s-> to access all state  */
	PGPByte				*charMap;		/* Charmap for armor output */
	PGPLineEndType		 lineEnd;		/* Line endings for armor output */
	PGPBoolean			 fEncrypt;		/* Encryption */
	PGPBoolean			 fSign;			/* Signature */
	PGPUInt32			 fRawPGPInput;	/* Don't put on literal packet */
	PGPUInt32			 fAppendOutput;	/* Append to existing outfile */
	PGPOption			 op;			/* Selected option from list */
	PGPByte				*sessionKey = NULL;	/* session key for encryption */
	PGPSize				 sessionKeyLength;
	PGPFileDataType		 inFileDataType;	/* Input file data trype (ascii or binary) */
	PGPBoolean			 bLargeFile;
	
	/* Initialize pointers to NULL for easier error cleanup */
	pgpClearMemory( s, sizeof( *s ) );
	s->context = context;
	s->optionList = optionList;
	s->tail = &s->head;

	if (IsPGPError( s->err = pgpCheckOptionsInSet( optionList,
						encodeOptionSet, elemsof( encodeOptionSet ) ) ) )
		return s->err;

	/* Get copies of info from context */
	s->rng = pgpContextGetX9_17RandomContext ( s->context );

	/* Get a copy of the env to work with so our changes aren't permanent */
	if( IsPGPError( pgpenvCopy( pgpContextGetEnvironment( s->context ),
								&s->env ) ) )
		goto error;
	
	/* Set up PGPEnv structure for library internals */
	if( IsPGPError( s->err = pgpMakeEnvFromOptionList( s->optionList,
							s->env ) ) )
		goto error;

	/* Set up callback pointers and data */
	if( IsPGPError( s->err = pgpSetupCallback( s->optionList,
							 &s->func, &s->userValue, &s->fNullEvents ) ) )
		goto error;
	s->err = pgpEventInitial( s->context, &s->newOptionList,
							  s->func, s->userValue );
	pgpCleanupOptionList( &s->newOptionList );
	if( IsPGPError( s->err ) )
		goto error;

	/* Set up for conventional encryption if requested */
	if( IsPGPError( s->err = pgpSetupConventionalEncryption( s->context,
							  s->optionList, s->func, s->userValue,
							  &s->convkey ) ) )
		goto error;

	/* Set up for public key encryption if requested */
	if( IsPGPError( s->err = pgpSetupPublicKeyEncryption( s->context,
							  s->optionList,
							  s->env, &s->pubkeys ) ) )
		goto error;
	fEncrypt = (PGPBoolean) (IsntNull( s->pubkeys ) || IsntNull( s->convkey ));

	/* Determine if a detached signature has been requested */
	if( IsPGPError( s->err = pgpSearchOptionSingle( s->optionList,
							kPGPOptionType_DetachedSignature, &op ) ) )
		goto error;
		
	s->sepsig = IsOp( op );
	
	/* Check output format and handle X.509 related formats */
	if( IsPGPError( s->err = pgpFindOptionArgs( s->optionList,
						 kPGPOptionType_OutputFormat, FALSE,
						 "%d", &s->outputFormat ) ) )
		goto error;
	if( s->outputFormat >= kPGPOutputFormat_X509CertReqInPKCS7 ) {
		/* Handle output X.509 data */
		s->err = sPackageOutputX509 (s);
		goto error;
	}

	/* Set up input filenames and open file if any */
	if( IsPGPError( s->err = pgpSetupInput( s->context, s->optionList,
					&s->literal, s->rng, TRUE, s->sepsig,
					&s->inFileRef, &s->pfrin, &inFileDataType, &bLargeFile,
					&s->inBufPtr, &s->inBufLength ) ) )
		goto error;

	/* Set up for any signing operation requested */
	if( IsPGPError( s->err = pgpSetupSigning( s->context, s->optionList,
				  fEncrypt, s->env, s->func, s->userValue,
				  (PGPBoolean) (inFileDataType == kPGPFileDataType_Binary),
				  s->sepsig, &s->sigspec ) ) )
		goto error;

	/* Set up main processing pipeline (will set up output afterwards) */
	if( IsPGPError( s->err = pgpFindOptionArgs( s->optionList,
						 kPGPOptionType_RawPGPInput, FALSE,
						 "%d", &fRawPGPInput ) ) )
		goto error;

	/* Allocate space for session key if needed */
	if( fEncrypt ) {
		sessionKey = (PGPByte *)PGPNewSecureData(
					PGPPeekContextMemoryMgr( context ),
					PGP_CIPHER_MAXKEYSIZE+1, 0 );
		if (!sessionKey)
			goto error;
	}
	s->tail = pgpEncryptPipelineCreate( context, &s->head, s->env, NULL,
			s->rng, s->convkey, s->pubkeys, s->sigspec,
			(fRawPGPInput?NULL:&s->literal), s->sepsig, sessionKey,
			(PGPBoolean) (inFileDataType == kPGPFileDataType_Binary),
			bLargeFile, encodePKEncryptCallBack, s, &sessionKeyLength,
			&s->err );
	if( IsPGPError( s->err ) )
		goto error;
	
	if( IsntNull( sessionKey ) ) {
		s->err = pgpEventEncryption( s->context, &s->newOptionList,
									 s->func, s->userValue,
									 (PGPCipherAlgorithm)sessionKey[0],
									 sessionKey, sessionKeyLength );
		pgpCleanupOptionList( &s->newOptionList );
		PGPFreeData( sessionKey );		/* wipes it automatically */
		sessionKey = NULL;
	}

	/* Add a text conversion if needed for output */
	if( pgpenvGetInt( s->env, PGPENV_ARMOR, NULL, NULL ) ) {
		/* Ascii armoring output */
		/* Convert to local line endings if appropriate */
		charMap = (PGPByte *)pgpenvGetPointer( s->env, PGPENV_CHARMAPTOLATIN1,
											   NULL );
		lineEnd = pgpGetDefaultLineEndType ();
		if( IsPGPError( s->err = pgpSearchOptionSingle( optionList,
							  kPGPOptionType_OutputLineEndType, &s->op ) ) )
			goto error;
		if( IsOp( s->op ) ) {
			PGPUInt32 uintLineEnd;
			if( IsPGPError( s->err = pgpOptionUInt( &s->op, &uintLineEnd ) ) )
				goto error;
			lineEnd = (PGPLineEndType)uintLineEnd;
		}
		s->tail = pgpTextFiltCreate( s->context, s->tail, charMap,0,lineEnd );
	}

	/*
	 * Check for sufficient entropy.  Error if not enough, unless
	 * AskUserForEntropy option is specified, in which case we give an event.
	 */
	if( IsntNull( s->sigspec ) || fEncrypt ) {
		if( !PGPGlobalRandomPoolHasMinimumEntropy() ) {
			PGPUInt32 fEntropyEvent;
			if( IsPGPError( s->err = pgpFindOptionArgs( s->optionList,
								kPGPOptionType_AskUserForEntropy,
							   FALSE, "%d", &fEntropyEvent ) ) )
				goto error;
			if( !fEntropyEvent ) {
				s->err = kPGPError_OutOfEntropy;
				goto error;
			}
			while( !PGPGlobalRandomPoolHasMinimumEntropy() ) {
				PGPUInt32 entropy_needed;
				entropy_needed = PGPGlobalRandomPoolGetMinimumEntropy() -
								 PGPGlobalRandomPoolGetEntropy();
				s->err = pgpEventEntropy( s->context, &s->newOptionList,
									  s->func, s->userValue, entropy_needed );
				pgpCleanupOptionList( &s->newOptionList );
				if( IsPGPError( s->err ) )
					goto error;
			}
		}
	}

	/* Set up output pipeline */
	fSign = (PGPBoolean) IsntNull( s->sigspec );
	if( IsPGPError( s->err = pgpFindOptionArgs( s->optionList,
						 kPGPOptionType_AppendOutput, FALSE,
						 "%d", &fAppendOutput ) ) )
		goto error;
	if( IsPGPError( s->err = pgpSetupOutputPipeline( s->context, s->optionList,
							s->env, fEncrypt, fSign, s->sepsig,
							(PGPBoolean)fAppendOutput, FALSE,
							&s->tail, &s->outFileRef, &s->pfout,
							&s->outBufPtr, &s->outBufPtrPtr,

⌨️ 快捷键说明

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