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

📄 pgpreadann.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -