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

📄 pgpencode.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 4 页
字号:
							&s->outBufMaxLength, &s->outBufUsedLength,
							&s->outPipe ) ) )
		goto error;

	/* Now pump the data through the pipes */
	if( s->inFileRef ) {
		/* File input */
		if( IsntNull( s->func ) && s->fNullEvents ) {
			pgpFileReadSetCallBack( s->pfrin, encodeLocalCallBack, s );
		}
		s->err = pgpFileReadPump( s->pfrin, s->head );
		pgpFileReadDestroy( s->pfrin );
		s->pfrin = NULL;
		if( IsPGPError( s->err ) )
			goto error;
		s->err = s->head->sizeAdvise( s->head, 0 );
		if( IsPGPError( s->err ) )
			goto error;
	} else {
		/* Buffer input */
		if( IsntNull( s->func ) && s->fNullEvents ) {
			s->err = pgpPumpMem( s->head, s->inBufPtr, s->inBufLength,
								 encodeLocalCallBack, s );
		} else {
			s->err = pgpPumpMem( s->head, s->inBufPtr, s->inBufLength,
								 NULL, NULL );
		}
		if( IsPGPError( s->err ) )
			goto error;
	}

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

	/* Get PGPMIME header offset if appropriate */
	if( IsPGPError( s->err = pgpGetPGPMIMEBodyOffset( s->head, 
					s->optionList ) ) )
		goto error;

	/* Now we can tear down the pipeline */
	s->head->teardown( s->head );
	s->head = NULL;

	/* Done, clean up and return */
	s->err = kPGPError_NoErr;

error:

	if( IsntNull( sessionKey ) ) {
		PGPFreeData( sessionKey );
		sessionKey = NULL;
	}
	if( IsntNull( s->env ) ) {
		pgpenvDestroy( s->env );
		s->env = NULL;
	}
	if( IsntNull( s->head ) ) {
		s->head->teardown( s->head );
		s->head = NULL;
	}
	if( IsntNull( s->sigspec ) ) {
		pgpSigSpecDestroy( s->sigspec );
		s->sigspec = NULL;
	}
	if( IsntNull( s->pubkeys ) ) {
		PGPFreeKeySet( s->pubkeys );
		s->pubkeys = NULL;
	}
	if( IsntNull( s->convkey ) ) {
		pgpClearMemory( (s->convkey)->pass, (s->convkey)->passlen );
		pgpContextMemFree( context, (char *)(s->convkey)->pass );
		pgpContextMemFree( context, s->convkey );
		s->convkey = NULL;
	}
	if( IsntNull( s->literal.filename ) ) {
		pgpContextMemFree( context, (char *)s->literal.filename );
		s->literal.filename = NULL;
	}
	if( IsntNull( s->pfrin ) ) {
		pgpFileReadDestroy( s->pfrin );
		s->pfrin = NULL;
	}
	if ( s->err != kPGPError_NoErr && IsntNull( s->outFileRef ) ) {
		PFLFileSpecDelete( s->outFileRef );
		s->outFileRef = NULL;
	}

	/* Notify user via callback of error if requested */
	if( IsPGPError( s->err ) && IsntNull( s->func ) ) {
		(void)pgpEventError( s->context, &s->newOptionList, s->func,
							 s->userValue, s->err, NULL );
		pgpCleanupOptionList( &s->newOptionList );
	}
		
	(void)pgpEventFinal( s->context, &s->newOptionList, s->func,
						 s->userValue );
	pgpCleanupOptionList( &s->newOptionList );

	return s->err;
}


/************************** X509 encode function ****************************/


/*
 * Compute transaction ID for request, from key.
 * We want successive requests for certs from the same CA to use different
 * trans IDs, so we will base the trans ID on the key material, along
 * with the creation time of the most recent X.509 cert on the key.
 * If there is no X.509 cert we just use the MD5 hash of the key material.
 * This way when we renew a cert, the existing cert will be the most
 * recent one, and so we will use a different trans ID for the renewal
 * request.
 */
static PGPByte *
sTransactionIDFromKey( PGPKeyDBObjRef key, PGPSize *idLength )
{
	PGPTime				latesttime = (PGPTime)0;
	PGPTime				sigtime;
	PGPKeyIterRef		iter;
	PGPKeyDBObjRef		obj;
	PGPUInt32			objtype;
	PGPBoolean			isX509;
	void			   *vbuf;
	PGPByte			   *buf;
	PGPUInt32			i;

	PGPNewKeyIterFromKeyDB( PGPPeekKeyDBObjKeyDB( key ), &iter );
	PGPKeyIterSeek( iter, key );
	while( PGPKeyIterNextKeyDBObj( iter, kPGPKeyDBObjType_Any, &obj ),
		   (void)(IsntNull(obj) && PGPGetKeyDBObjNumericProperty( obj,
										  kPGPKeyDBObjProperty_ObjectType,
										  (PGPInt32*)&objtype )),
		   (IsntNull(obj) && objtype != kPGPKeyDBObjType_Key) )
	{
		if( objtype == kPGPKeyDBObjType_Signature )
		{
			PGPGetKeyDBObjBooleanProperty( obj, kPGPSigProperty_IsX509,
										   &isX509 );
			if( isX509 )
			{
				PGPGetKeyDBObjTimeProperty( obj, kPGPSigProperty_Creation,
											&sigtime );
				if( latesttime == 0 || sigtime > latesttime )
					latesttime = sigtime;
			}
		}
	}
	PGPFreeKeyIter( iter );

	PGPGetKeyDBObjAllocatedDataProperty( key, kPGPKeyProperty_X509MD5Hash,
										 &vbuf, idLength );
	buf = vbuf;
	/* XOR latesttime into the MD5 hash to get a unique hash */
	for( i=0; i<sizeof(latesttime); ++i )
	{
		buf[i] ^= (latesttime>>(i*8)) & 0xff;
	}

	return buf;
}



static PGPError
sPackageOutputX509( pgpEncodeJobState  *s )
{
	PGPOption			passop;
	PGPOptionListRef	passphrase = NULL;
	PGPCipherAlgorithm	encalg;
	PGPKeyDBObjRef		enckey;
	PGPKeyDBObjRef		signkey;
	PGPByte				*outBuf = NULL;
	PGPSize				 outBufLength;
	PGPByte				*transactionID = NULL;
	PGPSize				 transactionIDLen;
	PGPBoolean			 fEncrypt;
	PGPBoolean			 fSign;
	PGPBoolean			 fMustFreeBuf;
	PGPUInt32			 fAppendOutput;
	PGPUInt32			 keycnt;

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

	/* Check for various things we can't do: conventional encryption,
	 * encryption to more than one recipient; signing by more than one
	 * signature key; detached sigs.
	 */
	if( IsntNull( s->convkey ) )
		return kPGPError_BadParams;
	if ( IsntNull( s->pubkeys ) &&
		 	IsntPGPError(PGPCountKeys(s->pubkeys,&keycnt)) &&  keycnt > 1 )
		return kPGPError_BadParams;
	if ( IsntNull( s->sigspec) &&
		  IsntNull( pgpSigSpecNext (s->sigspec) ) )
		return kPGPError_BadParams;
	if( s->sepsig )
		return kPGPError_BadParams;

	encalg = (PGPCipherAlgorithm) pgpenvGetInt (s->env, PGPENV_CIPHER,
												NULL, NULL);

	/* Get passphrase from suboptions of signwithkey */
	passphrase = NULL;
	if( s->sigspec ) {
		PGPOption signop;

		if( IsPGPError( s->err = pgpSearchOptionSingle( s->optionList,
									kPGPOptionType_SignWithKey, &signop ) ) )
			goto error;
		if( IsPGPError( s->err = pgpSearchOptionSingle( signop.subOptions,
									kPGPOptionType_Passphrase, &passop ) ) )
			goto error;
		if( IsntOp( passop ) ) {
			if( IsPGPError( s->err = pgpSearchOptionSingle( signop.subOptions,
										kPGPOptionType_Passkey, &passop ) ) )
				goto error;
		}

		if( IsOp( passop ) ) {
			PGPOption passopcopy;
			pgpCopyOption( s->context, &passop, &passopcopy );
			passphrase = pgpNewOneOptionList( s->context, &passopcopy );
		}
	}

	/*
	 * Check for sufficient entropy.  Error if not enough, unless
	 * AskUserForEntropy option is specified, in which case we give an event.
	 */
	if( IsntNull( s->sigspec ) || IsntNull( s->pubkeys ) ) {
		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;
			}
		}
	}


	/* Get input into a memory buffer */
	s->err = pgpSetupInputToBuffer( s->context, s->optionList, &s->inBufPtr,
								 &s->inBufLength, &fMustFreeBuf );
	if( IsPGPError( s->err ) )
		goto error;

	/* Do the operation */
	enckey = IsntNull(s->pubkeys) ? pgpFirstKeyInKeySet( s->pubkeys ) : NULL;
	signkey = IsntNull(s->sigspec) ? pgpSigSpecSeckey( s->sigspec ) : NULL;
	if( IsntNull( enckey ) )
		pgpAssert( pgpKeyIsValid( enckey ) );

	if( IsntNull( signkey ) )
	{
		/* Get transaction ID from signing key */
		transactionID = sTransactionIDFromKey( signkey, &transactionIDLen );
	}

    s->err = X509PackageCertificateRequest (s->context,
											s->inBufPtr, s->inBufLength,
											transactionID, transactionIDLen,
											enckey, encalg,
											signkey, passphrase,
											s->outputFormat,
											&outBuf, &outBufLength );

	passphrase = NULL;
	if( IsntNull( transactionID ) )
		PGPFreeData( transactionID );
	if( fMustFreeBuf ) {
		PGPFreeData( s->inBufPtr );
		s->inBufPtr = NULL;
		s->inBufLength = 0;
	}

	if( IsPGPError( s->err ) )
		goto error;

	/* Push result out to user */

	fEncrypt = (PGPBoolean) IsntNull( s->pubkeys );
	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,
							&s->outBufMaxLength, &s->outBufUsedLength,
							&s->outPipe ) ) )
		goto error;

	s->err = pgpPumpMem( s->head, outBuf, outBufLength, NULL, NULL );
	if( IsPGPError( s->err ) )
		goto error;

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

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


error:
	if( IsntNull( passphrase ) )
		pgpFreeOptionList( passphrase );
	if( IsntNull( s->head ) )
		s->head->teardown( s->head );
	if( IsntNull( outBuf ) )
		PGPFreeData( outBuf );

	return s->err;
}




/*__Editor_settings____

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

⌨️ 快捷键说明

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