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

📄 pgpmakesig.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: pgpMakeSig.c,v 1.12 2002/08/06 20:11:04 dallen Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"
#include <string.h>

#include "pgpDebug.h"
#include "pgpMakeSig.h"
#include "pgpContext.h"
#include "pgpHashPriv.h"
#include "pgpErrors.h"
#include "pgpKeyPriv.h"
#include "pgpMem.h"
#include "pgpPktByte.h"
#include "pgpSigSpec.h"
#include "pgpUsuals.h"


#define CRIT(flags)  (((flags)&kPGPSigFlags_Critical) ? SIGSUBF_CRITICAL : 0)


/* Forward declaration */
static int
pgpMakeSigSubs (PGPSigSpec const *spec,
	 PGPHashContext const *hc, PGPByte **buf);

/* True if will need to be done as a V4 sig */
static int
pgpV4Sig (PGPSigSpec const *spec)
{
	return pgpSigSpecVersion( spec ) >= PGPVERSION_4;
}

/* The maximum size of the signature packet not counting the sig itself */
static int
pgpMakeSigExtraSize(PGPSigSpec const *spec)
{
	PGPSize extralen;
	char *regExp;

	if (pgpV4Sig (spec)) {
		PGPByte *dummyptr;
		PGPUInt32 dummyuint;
		PGPBoolean dummybool;
		PGPByte dummybyte;
		PGPSize dummylen;
		int i;

		if (pgpSigSpecPrefAlgs(spec, &dummyptr, &extralen)
					& kPGPSigFlags_Present) {
			extralen += 2;
		}
		extralen += 2 + 8;		/* Keyid subpacket */
		extralen += 2 + 4;		/* Sig creation subpacket */
		if (pgpSigSpecSigExpiration(spec, &dummyuint) & kPGPSigFlags_Present)
			extralen += 2 + 4;
		if (pgpSigSpecExportable(spec, &dummybool) & kPGPSigFlags_Present)
			extralen += 2 + 1;
		if (pgpSigSpecRevocable(spec, &dummybool) & kPGPSigFlags_Present)
			extralen += 2 + 1;
		if (pgpSigSpecPrimaryUserID(spec, &dummybool) & kPGPSigFlags_Present)
			extralen += 2 + 1;
		if (pgpSigSpecTrustLevel(spec, &dummybyte, &dummybyte)
											& kPGPSigFlags_Present)
			extralen += 2 + 2;
		if (pgpSigSpecRegExp(spec, &regExp) & kPGPSigFlags_Present )
			extralen += 2 + strlen(regExp) + 1;
		if (pgpSigSpecKeyExpiration(spec, &dummyuint) & kPGPSigFlags_Present)
			extralen += 2 + 4;
		for (i=0;
			 pgpSigSpecAdditionalRecipientRequest (spec, &dummyptr,
												   &dummylen, i) &
				 kPGPSigFlags_Present;
					++i)
			extralen += 2 + dummylen;
		for (i=0;
			 pgpSigSpecRevocationKey (spec, &dummyptr, &dummylen, i) &
				 kPGPSigFlags_Present;
					++i)
			extralen += 2 + dummylen;
		for (i=0;
			 pgpSigSpecPacket (spec, &dummyptr, &dummylen, i) &
				 kPGPSigFlags_Present;
					++i)
			extralen += 5 + dummylen;
		if (pgpSigSpecPrefKeyServ (spec, &dummyptr, &dummylen)
					& kPGPSigFlags_Present) {
			extralen += 2 + dummylen;
		}
		if (pgpSigSpecKeyServPrefs (spec, &dummyptr, &dummylen)
					& kPGPSigFlags_Present) {
			extralen += 2 + dummylen;
		}
		if (pgpSigSpecKeyFlags (spec, &dummyptr, &dummylen)
					& kPGPSigFlags_Present) {
			extralen += 2 + dummylen;
		}
		/* packlen includes the type byte */
		/* 4 bytes before subpackets, 2*2 length fields, 2 bytes of hash */
		return 10 + extralen;
	} else {
		/* Old format */
		(void)pgpSigSpecExtra(spec, &extralen);
		return 14 + extralen;
	}
}
	
/*
 * Given a buffer of at least "pgpMakeSigMaxSize" bytes, make a signature
 * into it and return the size of the signature, or 0.
 *
 * Format of signature packets:
 *
 *      Offset  Length  Meaning
 *       0      1       Version byte (= 2 or 3).
 *       1      1       Length of following material included in MD5 (x, = 5)
 *       2      1       Signature type
 *       3      4       32-bit timestamp of signature
 * -------- MD5 additional material stops here, at offset 7 ----------
 *       2+x    8       KeyID
 *      10+x    1       PK algorithm type (1 = RSA)
 *      11+x    1       MD algorithm type (1 = MD5)
 *      12+x    2       First 2 bytes of message digest (16-bit checksum)
 *      14+x    2+?     MPI of PK-encrypted integer
 */
PGPInt32
pgpMakeSig (PGPSigSpec const *spec, PGPHashContext const *hc, PGPByte **buf)
{
	PGPContextRef context;
	PGPKeyDBObjRef seckey;
	PGPHashContext *temp_hc;
	PGPHashVTBL const *h;
	PGPSize extralen;
	PGPByte const *extra;
	PGPByte const *hash;
	PGPByte *sigbuf;
	PGPByte *pktbuf;
	void *vbuf;
	PGPSize pktbuflen;
	int i;
	PGPSize sigsize;
	PGPInt32 pkalg;
	PGPKeyID keyid;
	PGPByte const *keyidbytes;
	PGPSize dummy;
	PGPByte const *passphrase;
	PGPSize passphraseLength;
	PGPBoolean hashedPhrase;
	
	/* Use subpacket sig formats if requesting preferred algs */
	if (pgpV4Sig (spec)) {
		return pgpMakeSigSubs (spec, hc, buf);
	}

	/* Get buffer to fill with our data */
	context = pgpSigSpecContext(spec);
	pktbuflen = pgpMakeSigExtraSize( spec );
	pktbuf = pgpContextMemAlloc( context, pktbuflen, 0 );
	if( IsNull( pktbuf ) )
		return kPGPError_OutOfMemory;

	/* Get some basic facts about signing key */
	seckey = pgpSigSpecSeckey(spec);
	pgpGetKeyNumber( seckey, kPGPKeyProperty_AlgorithmID, &pkalg );
	pgpGetKeyPropertyBuffer( seckey, kPGPKeyProperty_KeyID, sizeof(keyid),
							 &keyid, &dummy );
	keyidbytes = pgpGetKeyIDBytes( &keyid );

	temp_hc = pgpHashCopy (hc);
	if (!temp_hc)
		return kPGPError_OutOfMemory;

	extra = pgpSigSpecExtra(spec, &extralen);
	pgpAssert(extralen < 256);
	PGPContinueHash (temp_hc, extra, extralen);

	hash = (PGPByte *) pgpHashFinal(temp_hc);
	/* Copy the first 2 bytes over while they're available */
	pgpCopyMemory (hash, pktbuf+12+extralen, 2);
	passphrase = pgpSigSpecPassphrase( spec, &passphraseLength, &hashedPhrase);
	h = pgpHashGetVTBL( hc );
	i = pgpKeySign( seckey, passphrase, passphraseLength, hashedPhrase,
					0, FALSE, h->algorithm, hash, h->hashsize,
					kPGPPublicKeyMessageFormat_PGP, &sigbuf, &sigsize );
	PGPFreeHashContext(temp_hc);
	if (i < 0) {
		pktbuf[12+extralen] = 0;
		pktbuf[13+extralen] = 0;
		pgpContextMemFree( context, pktbuf );
		return i;
	}
	/* Resize pktbuf and put sigbuf into it */
	vbuf = pktbuf;
	if( IsPGPError( pgpContextMemRealloc( context, &vbuf, pktbuflen+sigsize,
										  0 ) ) )
	{
		pgpContextMemFree( context, pktbuf );
		pgpContextMemFree( context, sigbuf );
		return kPGPError_OutOfMemory;
	}
	pktbuf = vbuf;
	pgpCopyMemory( sigbuf, pktbuf+14+extralen, sigsize );
	pgpContextMemFree( context, sigbuf );
	
	/* Okay, build the signature packet - lots of magic numbers. */
	pktbuf[0] = (PGPByte)PGPVERSION_3;		/* Force version 3 as format */
	pktbuf[1] = extralen;
	pgpCopyMemory(extra, pktbuf+2, extralen);
	pgpCopyMemory(keyidbytes, pktbuf+2+extralen, 8);
	
	pktbuf[10+extralen] = (PGPByte) pkalg;
	pktbuf[11+extralen] = pgpHashGetVTBL( hc )->algorithm;
	/* First 2 bytes of hash are already copied in */

	*buf = pktbuf;
	return (int)sigsize+14+(int)extralen;
}



/*
 * Subpacket Sig layout:
 *
 * Offset,Length  Meaning
 *	0		1	Version byte (=4)
 *	1		1	Signature type (included in hash) (nested flag)
 *	2		1	PK algorithm (1 = RSA) (included in hash)
 *	3		1	Hash algorithm (1 = MD5) (included in hash)
 *	4		2	Length of extra material included in hash (=y)
 *	6		y	Subpackets (hashed)
 *  6+y		2	Length of extra material not included in hash (=z)
 *  8+y		z	Subpackets (unhashed)
 *=====
 *remainder not present on sig headers
 *=====
 *	8+y+z	2	First 2 bytes of message digest (16-bit checksum)
 *	10+y+z	2+w	MPI of PK-signed integer
 *	12+y+z+w
 *
 * Remember, if adding new subpackets here, that they must go in increasing
 * order of type value within each hashed/unhashed block.
 */
static PGPInt32
pgpMakeSigSubs( PGPSigSpec const *spec, PGPHashContext const *hc,
	PGPByte **buf )
{
	PGPContextRef context;
	PGPKeyDBObjRef seckey;
	PGPHashContext *temp_hc;
	PGPHashVTBL const *h;
	PGPSize extralen;
	unsigned l, l_init;
	PGPUInt32 flags;
	PGPSize pktdatalen;
	PGPSize adkeylen;
	PGPByte const *extra;
	PGPByte const *hash;
	PGPByte *pktdata;
	PGPByte *adkey;
	PGPByte *pktbuf;
	void *vbuf;
	PGPSize pktbuflen;
	PGPByte *sigbuf;
	PGPByte trustLevel, trustValue;
	PGPBoolean bool1;
	PGPUInt32 dat;
	PGPByte *pack;
	PGPSize packlen;
	char *regExp;
	int i;
	PGPSize sigsize;
	PGPByte postscript[6];
	PGPBoolean hashedpart;
	PGPInt32 pkalg;
	PGPKeyID keyid;
	PGPByte const *keyidbytes;
	PGPSize dummy;
	PGPByte const *passphrase;
	PGPSize passphraseLength;
	PGPBoolean hashedPhrase;
	
	/* Get buffer to fill with our data */
	context = pgpSigSpecContext(spec);
	pktbuflen = pgpMakeSigExtraSize( spec );
	pktbuf = pgpContextMemAlloc( context, pktbuflen, 0 );
	if( IsNull( pktbuf ) )
		return kPGPError_OutOfMemory;

	/* Get some basic facts about signing key */
	seckey = pgpSigSpecSeckey(spec);
	pgpGetKeyNumber( seckey, kPGPKeyProperty_AlgorithmID, &pkalg );
	pgpGetKeyPropertyBuffer( seckey, kPGPKeyProperty_KeyID, sizeof(keyid),
							 &keyid, &dummy );
	keyidbytes = pgpGetKeyIDBytes( &keyid );

	temp_hc = pgpHashCopy (hc);
	if (!temp_hc)
		return kPGPError_OutOfMemory;

	extra = pgpSigSpecExtra(spec, &extralen);
	pgpAssert(extralen == 5);
	
	/* Okay, build the signature packet - lots of magic numbers. */
	pktbuf[0] = (PGPByte)PGPVERSION_4;
	pktbuf[1] = extra[0];			/* Signature type */
	pktbuf[2] = (PGPByte) pkalg;
	pktbuf[3] = pgpHashGetVTBL( hc )->algorithm;

	/* Fill in extralen after we figure out how much we need */
	l = 4;
	hashedpart = TRUE;

	/* Loop twice, hashedpart then !hashedpart */
	do {
		/* Remember where length will go, skip past it for now */
		l_init = l;
		l += 2;

		/* Signature creation, always present in hashed portion */
		if (hashedpart) {
			pktbuf[l+1] = SIGSUB_CREATION;
			pktbuf[l] = 4 + 1;				/* length */

⌨️ 快捷键说明

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