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

📄 pgpaddhdr.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 2 页
字号:
			*(context->bufptr) = 0xE0 + BLOCK_SIZE;

			continue;
		}

	} while (size);

	return size0 - size;
}

/* This is only used in V3 mode */
static size_t
Write(PGPPipeline *myself, PGPByte const *buf, size_t size, PGPError *error)
{
	AddHdrContext *context;

	pgpAssert(myself);
	pgpAssert(myself->magic == ADDHEADERMAGIC);
	pgpAssert(error);

	context = (AddHdrContext *)myself->priv;
	pgpAssert(context);
	pgpAssert(context->tail);
	pgpAssert(context->fifo);

	if (!context->dowrite) {
		/* Buffer into the fifo until we get a sizeadvise */

		return pgpFifoWrite (context->fifod, context->fifo, buf, size);
	}

	/*
	 * Ok, we've been given our size.  Flush the fifo and then be
	 * a write-through
	 */
	*error = DoFlush(context);
	if (*error)
		return 0;
	if (context->sizeknown && size > context->bytes) {
		pgpAssert(0);
		*error = kPGPError_SizeAdviseFailure;
		return 0;
	}

	size = context->tail->write(context->tail, buf, size, error);
	context->bytes -= size;
	return size;
}

static PGPError
Annotate(PGPPipeline *myself, PGPPipeline *origin, int type,
	  PGPByte const *string, size_t size)
{
	AddHdrContext *context;
	PGPError	error;

	pgpAssert(myself);
	pgpAssert(myself->magic == ADDHEADERMAGIC);

	context = (AddHdrContext *)myself->priv;
	pgpAssert(context);
	pgpAssert(context->tail);

	error = context->tail->annotate(context->tail, origin, type,
					string, size);
	if (!error)
		PGP_SCOPE_DEPTH_UPDATE(context->scope_depth, type);
	pgpAssert(context->scope_depth != -1);
	return error;
}

/* This is only used in V4 mode */
static PGPError
BufferSizeAdvise(PGPPipeline *myself, PGPFileOffset size)
{
	AddHdrContext *context;
	PGPError	error;
	int i;

	pgpAssert(myself);
	pgpAssert(myself->magic == ADDHEADERMAGIC);

	context = (AddHdrContext *)myself->priv;
	pgpAssert(context);
	pgpAssert(context->tail);
	pgpAssert(context->buffer);

	/* Do not pass non-zero sizeAdvise -- I can't do that! */
	if (size || context->scope_depth)
		return( kPGPError_NoErr );

	/* Okay, we're at end of input. */
	if (context->buflen) {
		/* We have a bug when file length is zero; we get here without having
		 * flushed the header.  We can't easily distinguish between a zero
		 * length file and the EOF sizeadvise, but we don't need to.
		 */
		error = FlushHeader(context);
		if (error)
			return error;
		if (context->dowrite) {
			/* Ready to output a partial body length full buffer */
			/* However the last block must not use partial body length */
			/* Take out pbl header byte and output it normally */
			/* This assumes that the buffer size is less than 8383 bytes,
			 * so this fix will not work with BIGBLOCKS.  We will need
			 * a different fix for that.
			 */
			context->bufptr++;
			context->buflen--;
			context->dowrite = 0;
#ifndef BIGBLOCKS
		}
		if (context->midflush) {
			error = ForceFlush(context);
		} else {
			i = context->buflen;
			if (PKTLEN_ONE_BYTE(i)) {
				context->bufptr--;
				context->buflen++;
				context->bufptr[0] = PKTLEN_1BYTE(i);
			} else {
				context->bufptr -= 2;
				context->buflen += 2;
				context->bufptr[0] = PKTLEN_BYTE0(i);
				context->bufptr[1] = PKTLEN_BYTE1(i);
			}
			context->midflush = context->buflen;
#else /* BIGBLOCKS */
		} else {
			context->lastblock = 1;
#endif /* BIGBLOCKS */
			error = ForceFlush(context);
		}
		if (error)
			return error;
	}
	
	return context->tail->sizeAdvise(context->tail, 0);
}

/* This is only used in V3 mode */
static PGPError
SizeAdvise(PGPPipeline *myself, PGPFileOffset len)
{
	AddHdrContext *context;
	PGPFileOffset size;
	PGPError	error;
	int i;

	pgpAssert(myself);
	pgpAssert(myself->magic == ADDHEADERMAGIC);

	context = (AddHdrContext *)myself->priv;
	pgpAssert(context);
	pgpAssert(context->tail);
	pgpAssert(context->fifo);

	if (context->scope_depth)
		return( kPGPError_NoErr );	/* Can't pass it through */

	/*
	 * The actual size myself module will output is the byte size
	 * passed in (size), plus the size of the buffered header,
	 * plus the size of the data in the fifo.  However the packet
	 * size does not include the header size, so add in the header
	 * size after we compute the header.
	 */

	/*
	 * Set the header packet up properly, if we haven't already
	 * done so.  We know how long the length-of-length should be,
	 * so fill that many bytes of the header in MSB-first order.
	 */
	if (!context->dowrite) {
		size = len + pgpFifoSize (context->fifod, context->fifo);
	
		i = PKTBYTE_LLEN(context->header[0]);
		if (size >= 0x10000 && i <= 2)
			i = 2;
		else if (size >= 0x100 && i <= 1)
			i = 1;
		context->header[0] = (context->header[0] & ~3) | i;

		i = LLEN_TO_BYTES(i);
		context->hdrlen = i+1;
		while (i--) {
			context->header[i+1] = (PGPByte)(size & 0xff);
			size >>= 8;
		}
	}

	if (!context->sizeknown) {
		context->bytes = len;
		context->sizeknown = 1;
	} else if (context->bytes != len) {
		return kPGPError_SizeAdviseFailure;
	}

	/*
	 * Now add in the header size, sizeAdvise the next module, and
	 * if everything is ok, set the state to dowrite and flush.
	 */	   
	size = len + pgpFifoSize (context->fifod, context->fifo)
		+ context->hdrlen;
	error = context->tail->sizeAdvise(context->tail, size);
	if (error)
		return error;

	context->dowrite = 1;

	error = DoFlush(context);
	/*
	 * Just in case we got a sizeAdvise(0) without anything else.
	 * calling sizeAdvise(0) twice is ok!
	 */
	if (!error && !len)
		error = context->tail->sizeAdvise(context->tail, 0);

	return error;
}

static PGPError
Teardown(PGPPipeline *myself)
{
	AddHdrContext *context;
	PGPContextRef	cdkContext;
	
	pgpAssertAddrValid( myself, PGPPipeline );
	cdkContext	= myself->cdkContext;

	pgpAssert(myself);
	pgpAssert(myself->magic == ADDHEADERMAGIC);

	context = (AddHdrContext *)myself->priv;
	pgpAssert(context);

	if (context->tail)
		context->tail->teardown(context->tail);

	if (context->fifo)
		pgpFifoDestroy (context->fifod, context->fifo);

	if (context->buffer) {
		pgpClearMemory(context->buffer, BUFFER_SIZE+2);
		pgpContextMemFree( cdkContext, context->buffer);
	}
	
	pgpClearMemory(context, sizeof(*context));
	pgpContextMemFree( cdkContext, context);
	
	return kPGPError_NoErr;
}

PGPPipeline **
pgpAddHeaderCreate(
	PGPContextRef		cdkContext,
	PGPPipeline **		head,
	PgpVersion			vers,
	PGPFifoDesc const *	fd,
	PGPByte				pkttype,
	PGPByte llen,
	PGPByte *hdr,
	size_t headerlen)
{
	PGPPipeline *mod;
	PGPFifoContext *fifop = NULL;
	AddHdrContext *context;
	PGPByte *buf = NULL;
	PGPByte pktbite;

	if (!head)
		return NULL;

	pgpAssert(fd);

	/* XXX If we have versions > 2.6, ignore llen */
	if (vers > PGPVERSION_3)
		pktbite = PKTBYTE_BUILD_NEW(pkttype);
	else
		pktbite = PKTBYTE_BUILD(pkttype, llen);

	context = (AddHdrContext *)pgpContextMemAlloc( cdkContext,
		sizeof(*context), kPGPMemoryMgrFlags_Clear );
	if (!context)
		return NULL;
	mod = &context->pipe;

	if (vers > PGPVERSION_3) {
		buf = (PGPByte *)pgpContextMemAlloc( cdkContext,
			BUFFER_SIZE + 2, kPGPMemoryMgrFlags_Clear);
		if (!buf) {
			pgpContextMemFree( cdkContext, context);
			return NULL;
		}
		memcpy(buf+2, hdr, headerlen);

	} else {
		fifop = pgpFifoCreate ( cdkContext, fd);
		if (!fifop) {
			pgpContextMemFree( cdkContext, context);
			return NULL;
		}

		if (pgpFifoWrite (fd, fifop, hdr, headerlen) != headerlen) {
			pgpContextMemFree( cdkContext, context);
			pgpFifoDestroy (fd, fifop);
			return NULL;
		}
	}

	mod->magic = ADDHEADERMAGIC;
	mod->flush = Flush;
	mod->write = Write;
	mod->sizeAdvise = SizeAdvise;
	mod->annotate = Annotate;
	mod->teardown = Teardown;
	mod->name = "Add Header Module";
	mod->priv = context;
	mod->cdkContext	= cdkContext;

	if (buf) {
		mod->write = BufferWrite;
		mod->sizeAdvise = BufferSizeAdvise;
	}

	context->fifod = fd;
	context->fifo = fifop;
	context->ptr = context->header;
	context->header[0] = pktbite;
	context->hdrlen = 1;
	context->version = vers;
	context->buffer = buf;
	context->bufptr = buf + 2;
	context->bufwrite = context->bufptr + headerlen;

	if (vers > PGPVERSION_3)
		context->buflen = headerlen;
	else if (llen == 3)
		context->dowrite = 1;
	
	context->tail = *head;
	*head = mod;
	return &context->tail;
}

⌨️ 快捷键说明

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