📄 pgpreadann.c
字号:
/*
* pgpReadAnn.c -- Annotation Reader
*
* Written by: Colin Plumb and Derek Atkins <warlord@MIT.EDU>
*
* $Id: pgpReadAnn.c,v 1.27 1998/07/08 20:04:45 hal Exp $
*/
#include "pgpConfig.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "pgpDebug.h"
#include "pgpReadAnn.h"
#include "pgpVrfySig.h"
#include "pgpAnnotate.h"
#include "pgpESK.h"
#include "pgpHashPriv.h"
#include "pgpMem.h"
#include "pgpErrors.h"
#include "pgpMsg.h"
#include "pgpUI.h"
#include "pgpPipeline.h"
#include "pgpSig.h"
#include "pgpTextFilt.h"
#include "pgpUsuals.h"
#include "pgpContext.h"
#define READANNOTATIONMAGIC 0xf00b0b
/* should never have more than this many nested scopes! */
#define MAX_RECURSE 50
typedef struct ReadAnnContext {
PGPPipeline pipe;
int stack[MAX_RECURSE];
int sp;
int file_sp;
int type;
char *name;
PGPPipeline *tail;
PGPUICb const *ui;
PGPEnv const *env;
void *ui_arg;
PGPESK *esklist;
PGPSig *siglist[MAX_RECURSE];
PGPByte sepsig[MAX_RECURSE];
/* For the sigverify callback-callback to check the signature */
PGPSig const *cursig;
/* flag -- do we need a new output? */
PGPByte newoutput;
DEBUG_STRUCT_CONSTRUCTOR( ReadAnnContext )
} ReadAnnContext;
typedef struct TryCB {
PGPPipeline *myself, *origin;
int reply;
} TryCB;
static size_t
Write (PGPPipeline *myself, PGPByte const *buf, size_t size, PGPError *error)
{
ReadAnnContext *context;
pgpAssert (myself);
pgpAssert (myself->magic == READANNOTATIONMAGIC);
context = (ReadAnnContext *)myself->priv;
pgpAssert (context);
pgpAssert (error);
if (context->newoutput) {
*error = (PGPError)context->ui->newOutput (context->ui_arg,
&context->tail,
context->type,
context->name);
if (*error)
return kPGPError_NoErr;
/* Remember scope to close output */
context->file_sp = context->sp;
context->newoutput = 0;
}
pgpAssert (context->tail);
return context->tail->write (context->tail, buf, size, error);
}
static PGPError
sighash(PGPPipeline *myself, PGPPipeline *origin, int reply)
{
ReadAnnContext *context;
PGPByte *buf;
PGPError err;
unsigned len;
PGPContextRef cdkContext;
pgpAssertAddrValid( myself, PGPPipeline );
cdkContext = myself->cdkContext;
pgpAssert (myself);
pgpAssert (myself->magic == READANNOTATIONMAGIC);
context = (ReadAnnContext *)myself->priv;
pgpAssert (context);
/* Build list of hashes we need */
len = pgpSigDistinctHashCount(context->siglist[context->sp-1]);
buf = (PGPByte *)pgpContextMemAlloc( cdkContext,
len, kPGPMemoryMgrFlags_Clear);
if (!buf)
return kPGPError_OutOfMemory;
pgpSigDistinctHashes(context->siglist[context->sp-1], buf);
/* Tell the parser to do the hashes */
err = origin->annotate (origin, myself, reply, buf, len);
pgpContextMemFree( cdkContext, buf);
return err;
}
/* Try out all the hashes */
/* (Note that this is called with context->sp already decremented) */
static int
sigtry (PGPPipeline *myself, PGPPipeline *origin)
{
ReadAnnContext *context;
PGPByte *buf;
PGPByte const *extra;
unsigned extralen;
PGPSig const *sig;
PGPError error;
pgpAssert (myself);
pgpAssert (myself->magic == READANNOTATIONMAGIC);
context = (ReadAnnContext *)myself->priv;
pgpAssert (context);
for (sig = context->siglist[context->sp]; sig;
sig = pgpSigNext (sig)) {
extra = pgpSigExtra(sig, &extralen);
buf = (PGPByte *)pgpContextMemAlloc(myself->cdkContext, extralen+2, 0);
if( IsNull( buf ) )
return kPGPError_OutOfMemory;
buf[0] = pgpSigVersion(sig);
buf[1] = pgpSigHash(sig)->algorithm;
memcpy(buf+2, extra, extralen);
context->cursig = sig;
/* This ends up invoking sigverify, below */
error = origin->annotate (origin, myself,
PGPANN_HASH_REQUEST,
buf, extralen+2);
if (error) {
context->ui->message (context->ui_arg, error,
PGPMSG_SIG_ERROR, 0);
}
pgpClearMemory( buf, extralen+2 );
pgpContextMemFree( myself->cdkContext, buf );
}
context->cursig = 0;
pgpSigFreeList (context->siglist[context->sp]);
context->siglist[context->sp] = 0;
return 0;
}
/* Get the callback from the callback... */
/* (Note that this is called with context->sp already decremented) */
static int
sigverify(PGPPipeline *myself, PGPByte const *string, size_t size)
{
ReadAnnContext *context;
PGPHashVTBL const *hash;
(void)size; /* Avoid warning */
pgpAssert (myself);
pgpAssert (myself->magic == READANNOTATIONMAGIC);
context = (ReadAnnContext *)myself->priv;
pgpAssert (context);
pgpAssert (context->cursig);
hash = pgpSigHash (context->cursig);
pgpAssert (hash);
pgpAssert (size == hash->hashsize);
return context->ui->sigVerify (context->ui_arg, context->cursig,
string);
}
static int
sepsighash (ReadAnnContext *context)
{
int err;
err = pgpSepsigVerify (context->siglist[context->sp-1], context->env,
context->ui, context->ui_arg);
pgpSigFreeList (context->siglist[context->sp-1]);
context->siglist[context->sp-1] = 0;
return err;
}
/*
* Try a single key to see if it works.
*/
static int
eskTryKey (void *arg, PGPByte const *key, PGPSize keylen)
{
TryCB const *cb = (TryCB *)arg;
pgpAssert (cb);
pgpAssert (cb->myself);
pgpAssert (cb->myself->magic == READANNOTATIONMAGIC);
pgpAssert (cb->origin);
return cb->origin->annotate (cb->origin, cb->myself, cb->reply,
key, keylen);
}
/*
* Decrypt an PGPESK from an esklist -- this calls the UI function to
* decrypt an esklist. Uses the eskTryKey function to try the keys,
* and pre-allocates a buffer which is the largest possible PGPESK from
* all the PgpESKs in the list. Returns 0 or an error.
*/
static int
eskdecrypt (PGPPipeline *myself, PGPPipeline *origin, int reply)
{
TryCB cb;
ReadAnnContext *context;
PGPESK const *esk;
PGPByte *buf = 0;
int i, buflen = 0;
PGPSize keylen = 0;
PGPContextRef cdkContext;
pgpAssertAddrValid( myself, PGPPipeline );
cdkContext = myself->cdkContext;
pgpAssert (myself);
pgpAssert (myself->magic == READANNOTATIONMAGIC);
context = (ReadAnnContext *)myself->priv;
pgpAssert (context);
cb.myself = myself;
cb.origin = origin;
cb.reply = reply;
/* Figure out the size of the largest PGPESK */
for (esk = context->esklist; esk; esk = pgpEskNext(esk)) {
i = pgpEskMaxKeySize (esk);
if (buflen < i)
buflen = i;
}
if (buflen) {
buf = (PGPByte *)pgpContextMemAlloc( cdkContext,
buflen, kPGPMemoryMgrFlags_Clear);
if (!buf)
return kPGPError_OutOfMemory;
} else
return kPGPError_BadParams;
keylen = (size_t)buflen;
i = context->ui->eskDecrypt (context->ui_arg, context->esklist, buf,
&keylen, eskTryKey, &cb);
pgpClearMemory( buf, buflen);
pgpContextMemFree( cdkContext, buf);
pgpEskFreeList (context->esklist);
context->esklist = 0;
if (i) {
/* Cannot decrypt... Either eatit or passthrough */
if (i != PGPANN_PARSER_EATIT && i != PGPANN_PARSER_PASSTHROUGH)
return i;
cb.reply = i; /* What to do? */
i = eskTryKey (&cb, NULL, 0);
}
return i;
}
static PGPError
Annotate (PGPPipeline *myself, PGPPipeline *origin, int type,
PGPByte const *string, size_t size)
{
ReadAnnContext *context;
PGPError error = kPGPError_NoErr;
int i;
PgpUICbArg msgarg1;
PGPContextRef cdkContext;
pgpAssertAddrValid( myself, PGPPipeline );
cdkContext = myself->cdkContext;
pgpAssert (myself);
pgpAssert (myself->magic == READANNOTATIONMAGIC);
context = (ReadAnnContext *)myself->priv;
pgpAssert (context);
if (PGP_IS_SCOPE_MARKER (type)) {
if (PGP_IS_BEGIN_SCOPE (type)) {
context->stack[context->sp++] = type;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -