📄 pgpencode.c
字号:
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),
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 ) || 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;
}
}
}
/* Set up output pipeline */
fEncrypt = (PGPBoolean) (IsntNull( s->pubkeys ) || IsntNull( s->convkey ));
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;
/* 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 ) ) {
PGPSecKey *skey = pgpSigSpecSeckey(s->sigspec);
if( IsntNull( skey ) )
pgpSecKeyDestroy(skey);
pgpSigSpecDestroy( s->sigspec );
s->sigspec = NULL;
}
while( IsntNull( s->pubkeys ) ) {
PGPPubKey *pk1 = pgpPubKeyNext( s->pubkeys );
pgpPubKeyDestroy( s->pubkeys );
s->pubkeys = pk1;
}
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 ****************************/
static PGPError
sPackageOutputX509( pgpEncodeJobState *s )
{
PGPOption passop;
PGPOptionListRef passphrase = NULL;
PGPCipherAlgorithm encalg;
PGPByte *outBuf = NULL;
PGPSize outBufLength;
PGPBoolean fEncrypt;
PGPBoolean fSign;
PGPBoolean fMustFreeBuf;
PGPUInt32 fAppendOutput;
/* 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, &s->signkeyref ) ) )
goto error;
if( IsntNull( s->convkey ) ||
( IsntNull( s->pubkeys ) &&
IsntNull( pgpPubKeyNext( s->pubkeys ) ) ) ||
( IsntNull( s->sigspec) &&
IsntNull( pgpSigSpecNext (s->sigspec) ) ) ||
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 */
s->err = X509PackageCertificateRequest (s->context,
s->inBufPtr, s->inBufLength,
s->enckeyref, encalg,
s->signkeyref, passphrase,
s->outputFormat,
&outBuf, &outBufLength );
passphrase = NULL;
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 + -