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

📄 pgparmor.c

📁 PGP—Pretty Good Privacy
💻 C
📖 第 1 页 / 共 3 页
字号:
		}
	}
	context->sizevalid = 1;
	if (bytes)
		return kPGPError_NoErr;	/* dont handle any more non-zero sizeAdvises */

	/* This is the end */
	context->sizevalid = 2;

	/* Clear out the clearsign buffer, if we have it. */
	if (context->clearsign && context->linebuf) {
		pgpFifoWrite (context->fd, context->header, context->input,
			      context->linebuf);
		context->linebuf = 0;
	}

	/*
	 * If clearsign input ended with '\r', will be hashed with '\r\n' but
	 * the output file will be missing the '\n'.  Add it here.
	 */
	if (context->clearsign && context->state==2) {
		pgpFifoWrite (context->fd, 
			 context->header,  (const unsigned char *) "\n", 
			      1);
		context->state = 0;
	}

	error = armorFlushFifo (myself);
	if (error)
		return error;
	
	if (!context->didheader && !context->clearsign)
		armorMakeHeader (context);
	error = DoFlush (myself);
	if (error)
		return error;

	if (!context->clearsign) {
		armorMakeFooter (context);

		/* Set clearsign so we don't emit another CRC */
		context->clearsign = 1;

		error = DoFlush (myself);
		if (error)
			return error;
	}

	if (context->tail)
		error = context->tail->sizeAdvise (context->tail, bytes);
	return error;
}

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

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

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

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

	pgpFifoDestroy (context->fd, context->fifo);
	pgpFifoDestroy (context->fd, context->header);
	if (context->messageid)
	{
		pgpContextMemFree( cdkContext, context->messageid);
	}
		
		
	pgpClearMemory ( context, sizeof (*context) );
	pgpContextMemFree( cdkContext, context);
	
	return( kPGPError_NoErr );
}

#define ATYPE_NORMAL	0
#define ATYPE_CLEARSIG	10
#define ATYPE_SEPSIG	20
#define ATYPE_SEPSIGMSG	21
#define ATYPE_MIMESIG	30
#define ATYPE_MIMEENC	40
#define ATYPE_MIMESEPSIG 50

static PGPPipeline **
armorDoCreate (
	PGPContextRef			cdkContext,
	PGPPipeline **			head,
	ArmorContext **			pcontext,
	PGPEnv const *			env,
	PgpVersion				version,
	PGPFifoDesc const *		fd,
	PGPRandomContext const *rc,
	unsigned long			armorlines,
	int						armortype,
	PGPByte const *			hashlist,
	unsigned				hashlen)
{
	PGPPipeline *mod;
	ArmorContext *context;
	PGPFifoContext *fifo;
	PGPFifoContext *header;

	if (!head)
		return NULL;

	pgpAssert (fd);

	context = (ArmorContext *)pgpContextMemAlloc( cdkContext,
		sizeof (*context), kPGPMemoryMgrFlags_Clear );
	if ( IsNull( context ) )
		return NULL;
	mod	= &context->pipe;
	if( IsntNull( pcontext ) )
		*pcontext = context;

	fifo = pgpFifoCreate ( cdkContext, fd);
	if (!fifo) {
		pgpContextMemFree( cdkContext, context);
		return NULL;
	}
	header = pgpFifoCreate (cdkContext, fd);
	if (!header) {
		pgpFifoDestroy (fd, fifo);
		pgpContextMemFree( cdkContext, context);
		return NULL;
	}
	mod->magic = ARMORMAGIC;
	mod->write = Write;
	mod->flush = Flush;
	mod->sizeAdvise = SizeAdvise;
	mod->annotate = Annotate;
	mod->teardown = Teardown;
	mod->name = "ASCII Armor Write Module";
	mod->priv = context;
	mod->cdkContext	= cdkContext;

	context->cdkContext = cdkContext; 
	context->outptr = context->output;
	context->armorlines = armorlines;
	context->crc = CRC_INIT;
	context->fd = fd;
	context->fifo = fifo;
	context->header = header;
	context->version = version;
	context->comment	= pgpenvGetCString (env, PGPENV_COMMENT, NULL );
	context->versionString = pgpenvGetCString( env,
											   PGPENV_VERSION_STRING, NULL );

	/* Will need to create a message id; now done deterministically later */
	if (rc) {
		context->needmessageid = TRUE;
	}

	if (armortype == ATYPE_CLEARSIG) {
#define CLRSIGN "-----BEGIN PGP SIGNED MESSAGE-----"
		int dohash=0;
		PGPHashVTBL const *hash;

		pgpFifoWrite (fd, header, (PGPByte const *)CLRSIGN,
			      strlen (CLRSIGN));
		context->clearsign = 1;
		context->armorlines = 0;

		/*
		 * Now deal with multiple hash types.  If we don't specify
		 * the hash type, or the only hash used is MD5, then ignore
		 * the Hash header.  Otherwise, we should print the out
		 */
		if (!hashlen || (hashlen == 1 && *hashlist == kPGPHashAlgorithm_MD5))
			goto clearsig_end;
		pgpFifoWrite (fd, header, (PGPByte const *)"\nHash: ", 7);
		while (hashlen--) {
			hash = pgpHashByNumber ( (PGPHashAlgorithm) (*hashlist++) );
			if (hash) {
				if (dohash)
					pgpFifoWrite (fd, header,
						      (PGPByte const *)", ", 2);
				pgpFifoWrite (fd, header,
					      (PGPByte const *)hash->name,
					      strlen (hash->name));
				dohash = 1;
			}
		}
clearsig_end:
		pgpFifoWrite (fd, header, (PGPByte const *)"\n\n", 2);
		context->didheader = TRUE;		/* No need for header here */
	} else if (armortype == ATYPE_MIMESIG) {
/*		pgpFifoWrite (fd, header, (PGPByte const *)MIMETOPHDR, */
/*			      strlen(MIMETOPHDR));*/
		context->clearsign = 1;
		context->armorlines = 0;
		context->pgpmime = PGPMIMESIG;
	} else if (armortype == ATYPE_SEPSIG) {
		context->blocktype = "SIGNATURE";
	} else if (armortype == ATYPE_SEPSIGMSG) {
		context->blocktype = "MESSAGE";
	} else if (armortype == ATYPE_MIMESEPSIG) {
		context->blocktype = "MESSAGE";
		context->pgpmime = PGPMIMESIG;
		context->armorlines = 0;
	} else if (armortype == ATYPE_MIMEENC) {
		context->pgpmime = PGPMIMEENC;
		context->armorlines = 0;
		context->pgpmimeversionline =
			pgpenvGetInt( env, PGPENV_PGPMIMEVERSIONLINE, NULL, NULL );
	}

	context->tail = *head;
	*head = mod;
	return &context->tail;
}

PGPPipeline **
pgpArmorWriteCreate (
	PGPContextRef cdkContext,
	PGPPipeline **head,
	PGPEnv const *env,
	PGPFifoDesc const *fd,
	PGPRandomContext const *rc,
	PgpVersion version,
	PGPByte armortype)
{
	int type = 0;
	unsigned long armorlines;
	PGPError	error;

	if (!head)
		return NULL;

	if (armortype == PGP_ARMOR_NORMAL) {
		if (pgpenvGetInt (env, PGPENV_PGPMIME, NULL, &error)) {
			type = ATYPE_MIMEENC;
			rc = NULL; /* prevents messageid appearing */
		} else {
			type = ATYPE_NORMAL;
		}
	} else if (armortype == PGP_ARMOR_SEPSIG) {
		type = ATYPE_SEPSIG;
	} else if (armortype == PGP_ARMOR_SEPSIGMSG) {
		type = ATYPE_SEPSIGMSG;
	} else {
		return NULL;
	}

	armorlines = pgpenvGetInt (env, PGPENV_ARMORLINES, NULL, NULL);


	return (armorDoCreate ( cdkContext,
		head, NULL, env, version, fd, rc, armorlines, type, NULL, 0));
}

PGPPipeline **
pgpArmorWriteCreateClearsig (
	PGPPipeline **texthead,
	PGPPipeline **signhead,
	PGPEnv const *env,
	PGPFifoDesc const *fd,
	PgpVersion version, PGPByte *hashlist,
	unsigned hashlen)
{
	PGPPipeline *txthead = NULL, *sighead = NULL;
	PGPPipeline **joinhead, **sigtail, **tail;
	ArmorContext *context;
	PGPContextRef	cdkContext	= pgpenvGetContext( env );

	if (!texthead || !signhead)
		return NULL;

	joinhead = armorDoCreate ( cdkContext,
			&txthead, NULL, env, version, fd, NULL, 0,
				  ATYPE_CLEARSIG, hashlist, hashlen);
	if (!joinhead)
		return NULL;

	tail = pgpJoinCreate (cdkContext, joinhead, fd);
	if (!tail) {
		txthead->teardown (txthead);
		return NULL;
	}

	sigtail = armorDoCreate ( cdkContext,
			&sighead, NULL, env, version, fd, NULL, 0, ATYPE_SEPSIG, NULL, 0);
	if (!sigtail) {
		txthead->teardown (txthead);
		return NULL;
	}

	/* Add the charset used when generating the clearsigned message */
	context = (ArmorContext *)sighead->priv;
	pgpAssert (context);
	context->charset	= pgpenvGetCString (env, PGPENV_CHARSET, NULL);
	/* noconv is default, don't put it in */
	if( strcmp( context->charset, "noconv" ) == 0) {
		context->charset = NULL;
	}

	*sigtail = pgpJoinAppend (*joinhead);
	if (!*sigtail) {
		txthead->teardown (txthead);
		sighead->teardown (sighead);
		return NULL;
	}
		
	pgpJoinBuffer (*sigtail, (PGPByte *)"\n", 1);

	*texthead = txthead;
	*signhead = sighead;
	return tail;
}

PGPPipeline **
pgpArmorWriteCreatePgpMimesig (
	PGPPipeline **texttail,
	PGPPipeline **signtail,
	PGPEnv const *env,
	PGPFifoDesc const *fd,
	PGPRandomContext const *rc,
	PgpVersion version, PGPByte *hashlist,
	unsigned hashlen)
{
	ArmorContext *context, *sigcontext;
	PGPPipeline *txthead = NULL, *sighead = NULL;
	PGPPipeline **joinhead, **sigtail, **tail;
	PGPPipeline **splithead, **splittail;
	PGPContextRef	cdkContext	= pgpenvGetContext( env );
	PGPByte		sepbits[(NSEPCHARS+7)/8];
	PGPSize		bodyoff = 0;
	PGPUInt32	headerlines = 0;
	PGPUInt32	i;

	if (!texttail || !signtail || !rc)
		return NULL;

	splithead = armorDoCreate ( cdkContext,
		&txthead, &context, env, version, fd, NULL, 0,
		 ATYPE_MIMESIG, hashlist, hashlen);
	if (!splithead)
		return NULL;

	/* Create split to take output from clearmime armor module */
	joinhead = pgpSplitCreate(cdkContext, splithead);

	/* Set second split output to go to signing pipeline */
	splittail = pgpSplitAdd (*splithead);
	*splittail = *texttail;

	tail = pgpJoinCreate ( cdkContext, joinhead, fd);
	if (!tail) {
		txthead->teardown (txthead);
		return NULL;
	}

	sigtail = armorDoCreate ( cdkContext, &sighead, &sigcontext, env, version,
				fd, NULL, 0, ATYPE_MIMESEPSIG, NULL, 0);
	if (!sigtail) {
		txthead->teardown (txthead);
		return NULL;
	}

	*sigtail = pgpJoinAppend (*joinhead);
	if (!*sigtail) {
		txthead->teardown (txthead);
		sighead->teardown (sighead);
		return NULL;
	}

	/* Create a random message separator */
	pgpRandomGetBytes (rc, sepbits, (NSEPCHARS+7)/8);
	for (i=0; i<NSEPCHARS; ++i) {
		context->mimesigsep[i] = ((sepbits[i/8]>>(i&7))&1) ? '-' : '=';
	}
	context->mimesigsep[NSEPCHARS] = '\0';
	pgpCopyMemory(context->mimesigsep, sigcontext->mimesigsep, NSEPCHARS+1);

	bodyoff = 0;
	headerlines = 0;
	context->pgpmimeversionline = pgpenvGetInt( env,
									PGPENV_PGPMIMEVERSIONLINE, NULL, NULL );
	if( context->pgpmimeversionline ) {
		pgpJoinBuffer (*joinhead, (PGPByte *)MIMESIGHDR1a,
					   strlen(MIMESIGHDR1a));
		bodyoff += strlen(MIMESIGHDR1a);
		headerlines += MIMESIGHDRLINESa;
	}
	pgpJoinBuffer (*joinhead, (PGPByte *)MIMESIGHDR1b, strlen(MIMESIGHDR1b));
	pgpJoinBuffer (*joinhead, (PGPByte *)context->mimesigsep, NSEPCHARS);
	pgpJoinBuffer (*joinhead, (PGPByte *)MIMESIGHDR2, strlen(MIMESIGHDR2));
	bodyoff += strlen(MIMESIGHDR1b) + NSEPCHARS + strlen(MIMESIGHDR2);
	headerlines += MIMESIGHDRLINESb;
	if (!hashlen) {
		pgpJoinBuffer (*joinhead, (PGPByte *)MIMEMIC, strlen(MIMEMIC));
		pgpJoinBuffer (*joinhead, (PGPByte *)MIMEDFLTMIC,
				strlen(MIMEDFLTMIC));
		bodyoff += strlen(MIMEMIC) + strlen(MIMEDFLTMIC);
	} else {
		while (hashlen--) {
			PGPHashVTBL const *hash = NULL;
			unsigned j, len;
			char hashname[30]; /* lower case name */

			hash = pgpHashByNumber ( (PGPHashAlgorithm) (*hashlist++) );
			pgpAssert(hash);
			len = strlen(hash->name);
			pgpAssert (len < sizeof(hashname));
			pgpJoinBuffer (*joinhead, (PGPByte *)MIMEMIC,
				       strlen(MIMEMIC));
			for (j=0; j<len; ++j)
				hashname[j] = tolower(hash->name[j]);
			pgpJoinBuffer (*joinhead, (PGPByte *)hashname,
				       len);
			bodyoff += strlen(MIMEMIC) + len;
			if( hashlen ) {
				pgpJoinBuffer (*joinhead, (PGPByte *)";", 1);
				bodyoff += 1;
			}
		}
	}
	pgpJoinBuffer (*joinhead, (PGPByte *)"\n\n", 2);
	bodyoff += 2;
	headerlines += 2;
	context->mimebodyoff = bodyoff;
	context->mimeheaderlines = headerlines;
	pgpJoinBuffer (*joinhead, (PGPByte *)"--", 2);
	pgpJoinBuffer (*joinhead, (PGPByte *)context->mimesigsep, NSEPCHARS);
	pgpJoinBuffer (*joinhead, (PGPByte *)"\n", 1);

	pgpJoinBuffer (*sigtail, (PGPByte *)"\n--", 3);
	pgpJoinBuffer (*sigtail, (PGPByte *)context->mimesigsep, NSEPCHARS);
	pgpJoinBuffer (*sigtail, (PGPByte *)"\n", 1);
	pgpJoinBuffer (*sigtail, (PGPByte *)MIMEMIDBOUND, strlen(MIMEMIDBOUND));

	*texttail = txthead;
	*signtail = sighead;
	return tail;
}

⌨️ 快捷键说明

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