📄 pgpencsubr.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: pgpEncSubr.c,v 1.21 2002/08/06 20:10:59 dallen Exp $
____________________________________________________________________________*/
/*
* pgpEncSubr.c -- Helper subroutines for encode/decode API
*/
#include "pgpConfig.h" /* or pgpConfig.h in the CDK */
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
/* Public headers */
#include "pgpPubTypes.h"
#include "pgpArmor.h"
#include "pgpContext.h"
#include "pgpEncode.h"
#include "pgpErrors.h"
#include "pgpFIFO.h"
#include "pgpFileRef.h"
#include "pgpKeys.h"
#include "pgpMem.h"
/* Private headers */
#include "pgpDebug.h"
#include "pgpAnnotate.h"
#include "pgpDevNull.h"
#include "pgpEncodePriv.h"
#include "pgpEnv.h"
#include "pgpEventPriv.h"
#include "pgpMemMod.h"
#include "pgpPipeline.h"
#include "pgpPrsAsc.h"
#include "pgpRandomContext.h"
#include "pgpKeyPriv.h"
#include "pgpVMemMod.h"
#include "pgpUtilities.h"
/******************* Misc functions for encode/decode ********************/
/*
* Convert the user flags used to specify local encoding into a flag value
* from pgpFileRef.h
*/
PGPFileOpenFlags
pgpLocalEncodingToFlags( PGPUInt32 localEncode )
{
PGPFileOpenFlags flags = (PGPFileOpenFlags)0;
/* Wrapper function ensured that only one of these was given */
if( localEncode & kPGPLocalEncoding_Auto )
flags = kPGPFileOpenMaybeLocalEncode;
else if( localEncode & kPGPLocalEncoding_Force )
flags = kPGPFileOpenForceLocalEncode;
/* Add optional modifier flags */
if( localEncode & kPGPLocalEncoding_NoMacBinCRCOkay )
flags |= kPGPFileOpenNoMacBinCRCOkay;
return flags;
}
/******************* Helper functions for encode/decode ********************/
/*
* Pump data from the memory buffer at inBufPtr, of size InBufLength,
* into head. Do the terminating sizeAdvise but don't do the teardown.
*/
PGPError
pgpPumpMem(
PGPPipeline *head,
PGPByte *inBufPtr,
PGPSize inBufLength,
PGPProgressCallBack callBack,
void *callBackArg
)
{
PGPSize totalSize;
PGPError err = kPGPError_NoErr;
PGPSize written;
totalSize = inBufLength;
err = head->sizeAdvise( head, inBufLength );
if( IsPGPError( err ) )
return err;
err = head->annotate (head, NULL, PGPANN_FILE_BEGIN, NULL, 0);
if( IsPGPError( err ) )
return err;
err = head->sizeAdvise( head, inBufLength );
while( inBufLength>0 && IsntPGPError( err ) ) {
written = head->write( head, inBufPtr,
pgpMin(inBufLength, 4096), &err );
inBufPtr += written;
inBufLength -= written;
if( IsPGPError( err ) )
break;
if( IsntNull( callBack ) )
err = callBack( callBackArg, totalSize - inBufLength, totalSize );
}
if( IsntPGPError( err ) )
err = head->sizeAdvise( head, 0 );
if( IsntPGPError( err ) )
err = head->annotate (head, NULL, PGPANN_FILE_END, NULL, 0);
if( IsntPGPError( err ) )
err = head->sizeAdvise( head, 0 );
return err;
}
/* Send a warning event to the user if he is set up for events */
PGPError
pgpWarnUser(
PGPContextRef context, /* Input parameters */
PGPOptionListRef optionList,
PGPError errCode,
void *warnArg
)
{
PGPError err;
PGPEventHandlerProcPtr handler;
PGPUserValue arg;
PGPOptionListRef dummyOptionList = NULL;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_EventHandler, FALSE,
"%p%p", &handler, &arg ) ) )
goto error;
if( IsntNull( handler ) ) {
if( IsPGPError( err = pgpEventWarning( context, &dummyOptionList,
handler, arg, errCode, warnArg ) ) )
goto error;
pgpCleanupOptionList( &dummyOptionList );
}
return kPGPError_NoErr;
error:
return err;
}
/* Set fail-below validity values for failure and warning */
PGPError
pgpGetMinValidity(
PGPOptionListRef optionList,
PGPValidity *failValidity, /* Output parameters */
PGPValidity *warnValidity
)
{
PGPError err;
PGPOption op;
PGPUInt32 temp;
/* Init return pointers */
pgpa( pgpaAddrValid( failValidity, PGPValidity ) );
pgpa( pgpaAddrValid( warnValidity, PGPValidity ) );
/* XXX Need to fix these based on trust model and other aspects */
*failValidity = kPGPValidity_Unknown;
*warnValidity = kPGPValidity_Marginal;
if( IsPGPError( err = pgpSearchOptionSingle( optionList,
kPGPOptionType_FailBelowValidity, &op ) ) )
goto error;
if( IsOp( op ) ) {
if( IsPGPError( err = pgpOptionUInt( &op, &temp ) ) )
goto error;
*failValidity = (PGPValidity)temp;
}
if( IsPGPError( err = pgpSearchOptionSingle( optionList,
kPGPOptionType_WarnBelowValidity, &op ) ) )
goto error;
if( IsOp( op ) ) {
if( IsPGPError( err = pgpOptionUInt( &op, &temp ) ) )
goto error;
*warnValidity = (PGPValidity)temp;
}
return kPGPError_NoErr;
error:
return err;
}
/* Check a key for encryption or signature-verification validity. Return
an error if it is no good, no error to proceed */
PGPError
pgpCheckKeyValidity(
PGPContextRef context, /* Input parameters */
PGPOptionListRef optionList,
PGPKeyDBObj *key,
PGPValidity failValidity,
PGPValidity warnValidity,
PGPKeySet *warnKeys, /* Output parameters */
PGPValidity *pValidity
)
{
PGPValidity validity;
PGPError err;
PGPBoolean fRevoked,
fExpired,
fDisabled;
(void) context;
(void) optionList;
if( IsntNull( pValidity ) )
*pValidity = kPGPValidity_Unknown;
/* First calculate validity level */
if( IsPGPError( err = pgpGetKeyNumber( key, kPGPKeyProperty_Validity,
(PGPInt32 *)&validity ) ) )
goto error;
if( IsntNull( pValidity ) )
*pValidity = validity;
if( IsPGPError( err = pgpGetKeyBoolean( key, kPGPKeyProperty_IsRevoked,
&fRevoked ) ) )
goto error;
if( fRevoked ) {
err = kPGPError_KeyRevoked;
goto error;
}
if( IsPGPError( err = pgpGetKeyBoolean( key, kPGPKeyProperty_IsDisabled,
&fDisabled ) ) )
goto error;
if( fDisabled ) {
err = kPGPError_KeyDisabled;
goto error;
}
if( IsPGPError( err = pgpGetKeyBoolean( key, kPGPKeyProperty_IsExpired,
&fExpired ) ) )
goto error;
if( fExpired ) {
err = kPGPError_KeyExpired;
goto error;
}
if( validity < failValidity ) {
/* Return an error */
err = kPGPError_KeyInvalid;
goto error;
} else if( validity < warnValidity && IsntNull( warnKeys ) ) {
/* Send a warning */
if( IsPGPError( err = PGPAddKey( key, warnKeys ) ) )
goto error;
}
/* Everything is OK, proceed */
return kPGPError_NoErr;
error:
return err;
}
/*
* Set *outputBufferLen from pipeBuf.
* bufferSize is the allocated size of the buffer, and we return an error
* if we exceeded the allocated size. (We don't actually write beyond
* the end of the buffer, of course.)
*/
PGPError
pgpGetMemOutput(
PGPPipeline *pipeBuf,
PGPSize bufferSize,
PGPSize *outputBufferLen
)
{
pgpa( pgpaAddrValid( pipeBuf, PGPPipeline ) );
pipeBuf->annotate( pipeBuf, NULL,
PGPANN_MEM_BYTECOUNT, (PGPByte *)outputBufferLen,
sizeof( *outputBufferLen ) );
if( *outputBufferLen > bufferSize )
return kPGPError_OutputBufferTooSmall;
return kPGPError_NoErr;
}
/*
* Set *outputBufferPtr and *outputBufferLen from pipeBuf. maxSize
* was our limit on the allocated size of the buffer, and we return an
* error if we exceeded the max size. (We don't actually write more data
* than that into our dynamically allocated buffer, though.) The difference
* from the above is that in this case the buffer was dynamically allocated
* while in the previous routine it was a static buffer we were given.
*/
PGPError
pgpGetVariableMemOutput(
PGPPipeline *pipeBuf,
PGPSize maxSize,
PGPByte **outputBufferPtr,
PGPSize *outputBufferLen
)
{
PGPError err = kPGPError_NoErr;
pgpa( pgpaAddrValid( pipeBuf, PGPPipeline ) );
err = pipeBuf->annotate( pipeBuf, NULL,
PGPANN_MEM_BYTECOUNT, (PGPByte *)outputBufferLen,
sizeof( *outputBufferLen ) );
if ( IsntPGPError( err ) )
{
pipeBuf->annotate( pipeBuf, NULL,
PGPANN_MEM_MEMBUF, (PGPByte *)outputBufferPtr,
sizeof( *outputBufferPtr ) );
}
if ( IsntPGPError( err ) )
{
if( *outputBufferLen > maxSize )
err = kPGPError_OutputBufferTooSmall;
}
return err;
}
/*
* See if optionList specifies PGPMIME encoding, and if so, get MIME body
* offset and return it to caller.
*/
PGPError
pgpGetPGPMIMEBodyOffset(
PGPPipeline *pipeBuf,
PGPOptionListRef optionList)
{
PGPSize *mimeBodyOffPtr;
PGPSize mimeBodyOff;
char *mimeSeparator;
PGPUInt32 mimeHeaderLines;
PGPUInt32 mimeFlag;
PGPUInt32 lineEndFlag;
PGPLineEndType lineEnd;
PGPUInt32 uintLineEnd;
PGPError err = kPGPError_NoErr;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_PGPMIMEEncoding, FALSE,
"%d%p%p", &mimeFlag, &mimeBodyOffPtr,
&mimeSeparator) ) )
goto error;
if( mimeFlag ) {
if( IsntNull( mimeBodyOffPtr ) ) {
if( IsPGPError( err = pipeBuf->annotate( pipeBuf, NULL,
PGPANN_PGPMIME_HEADER_SIZE,
(unsigned char *)&mimeBodyOff, sizeof(mimeBodyOff) ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_OutputLineEndType, FALSE,
"%b%d", &lineEndFlag, &uintLineEnd ) ) )
goto error;
if( lineEndFlag )
lineEnd = (PGPLineEndType)uintLineEnd;
else
lineEnd = pgpGetDefaultLineEndType ();
if( lineEnd == kPGPLineEnd_CRLF ) {
if( IsPGPError( err = pipeBuf->annotate( pipeBuf, NULL,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -