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

📄 pgpsigspec.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * pgpSigSpec.c -- Signature Specification
 *
 * Code to specify a PGP signature and signature attributes
 *
 * Written by:	Derek Atkins <warlord@MIT.EDU>
 *
 * $Id: pgpSigSpec.c,v 1.42.6.1 1999/06/04 00:28:54 heller Exp $
 */

#include "pgpConfig.h"

#include <stdio.h>
#include <time.h>
#include <string.h>

#include "pgpDebug.h"
#include "pgpHashPriv.h"
#include "pgpMem.h"
#include "pgpEnv.h"
#include "pgpErrors.h"
#include "pgpPktList.h"
#include "pgpPubKey.h"
#include "pgpRngPub.h"
#include "pgpTimeDate.h"
#include "pgpUsuals.h"
#include "pgpSigSpec.h"
#include "pgpContext.h"

struct PGPSigSpec {
	PGPContextRef	cdkContext;
	PGPSigSpec *next;
	PGPSecKey *seckey;
	PgpVersion version;
	PGPByte hashtype;
	PGPByte extra[5];			/* Sigtype, timestamp */

	PktList	*pkl;				/* Other subpackets */
	PktList	*pki;				/* Pointer into pkl for iteration */
	DEBUG_STRUCT_CONSTRUCTOR( PGPSigSpec )
};

PGPSigSpec *
pgpSigSpecCreate (PGPEnv const *env, PGPSecKey *sec,
		  PGPByte sigtype)
{
	PGPSigSpec *ss;
	PGPContextRef		cdkContext	= pgpenvGetContext( env );
	
	if (!env || !sec)
		return NULL;

	ss = (PGPSigSpec *)pgpContextMemAlloc( cdkContext,
		sizeof (*ss), kPGPMemoryMgrFlags_Clear);
	if (ss) {
		/*
		 * XXX: This hash algorithm selection must be kept in sync
		 *      with pgpHashAlgUsedForSignatures (in pgpKeyMan.c)
		 */
		int tzFix = pgpenvGetInt (env, PGPENV_TZFIX, NULL, NULL);
		PGPByte hash = pgpenvGetInt (env, PGPENV_HASH, NULL, NULL);
		PgpVersion version = pgpenvGetInt (env, PGPENV_VERSION, NULL,
						   NULL);
		/* Force SHA-1 hash with DSA */
		if (sec->pkAlg == kPGPPublicKeyAlgorithm_DSA) {
			hash = kPGPHashAlgorithm_SHA;
		}

		ss->cdkContext	= cdkContext;
#if 0
		ss->exportable = TRUE;
		ss->revocable = TRUE;
#endif
		if (pgpSigSpecSetSeckey (ss, sec) ||
			pgpSigSpecSetHashtype (ss, hash) ||
		    pgpSigSpecSetSigtype (ss, sigtype) ||
		    pgpSigSpecSetTimestamp (ss, pgpTimeStamp (tzFix)) ||
		    pgpSigSpecSetVersion (ss, version)) {
			pgpContextMemFree( cdkContext, ss);
			ss = NULL;
		}
	}
	return ss;
}

PGPSigSpec *
pgpSigSpecCopy (PGPSigSpec const *spec)
{
	PGPSigSpec *ss;
	PktList *pki, *sspk, **psspk;

	if (!spec)
		return NULL;

	ss = (PGPSigSpec *)pgpContextMemAlloc( spec->cdkContext,
		sizeof (*ss), 0);
	if (ss) {
		memcpy (ss, spec, sizeof (*ss));
		ss->next = NULL;
	}
	/* Copy over packetlist */
	ss->pkl = ss->pki = NULL;
	psspk = &ss->pkl;	/* Point at "next" of last entry in ss->pkl */
	for (pki = spec->pkl; pki; pki = pki->next) {
		sspk = pgpPktListNew( spec->cdkContext, pki->type, pki->buf,
							  pki->len );
		if( IsNull( sspk ) )
			return NULL;	/* out of memory */
		*psspk = sspk;
		psspk = &sspk->next;
		/* Copy iterator position in new list */
		if (pki == spec->pki)
			ss->pki = sspk;
	}
	return ss;
}

void
pgpSigSpecDestroy (PGPSigSpec *spec)
{
	PGPSigSpec *ss;

	for (ss = spec; ss; ss = spec)
	{
		PGPContextRef		cdkContext;
		
		cdkContext	= ss->cdkContext;
		spec = ss->next;
		pgpPktListFreeList( ss->pkl );
		pgpClearMemory( ss,  sizeof (*ss));
		pgpContextMemFree( cdkContext, ss);
	}
}

/* Lists...  Add a spec to a list; get the next spec from the list */
int
pgpSigSpecAdd (PGPSigSpec **list, PGPSigSpec *spec)
{
	if (!list)
		return kPGPError_BadParams;

	spec->next = *list;
	*list = spec;
	return 0;
}

PGPSigSpec *
pgpSigSpecNext (PGPSigSpec const *list)
{
	if (!list)
		return NULL;

	return list->next;
}

/*
 * Access functions and Modifier functions follow below
 */

/* Set and get the seckey */
int
pgpSigSpecSetSeckey (PGPSigSpec *spec, PGPSecKey *seckey)
{
	pgpAssert (spec);
	pgpAssert (seckey);

	spec->seckey = seckey;
	return 0;
}

PGPSecKey *
pgpSigSpecSeckey (PGPSigSpec const *spec)
{
	return spec->seckey;
}

/* Set and get the hash */
int
pgpSigSpecSetHashtype (PGPSigSpec *spec, PGPByte hashtype)
{
	pgpAssert (spec);

	if (!pgpHashByNumber( (PGPHashAlgorithm)hashtype))
		return kPGPError_BadHashNumber;

	spec->hashtype = hashtype;
	return 0;
}

PGPHashVTBL const *
pgpSigSpecHash (PGPSigSpec const *spec)
{
	return pgpHashByNumber( (PGPHashAlgorithm) spec->hashtype);
}

PGPByte
pgpSigSpecHashtype (PGPSigSpec const *spec)
{
	return spec->hashtype;
}

/* Set and get the version */
int
pgpSigSpecSetVersion (PGPSigSpec *spec, PgpVersion version)
{
	pgpAssert (spec);

	spec->version = version;
	return 0;
}

PgpVersion
pgpSigSpecVersion (PGPSigSpec const *spec)
{
	return spec->version;
}

/* Make sure we have a version new enough for subpackets */
static void
sSubPacketVersion(PGPSigSpec *spec)
{
	if (spec->version < PGPVERSION_4)
		spec->version = PGPVERSION_4;
}

/* Set the sigtype and timestamp; get the "extra" bytes which result */
int
pgpSigSpecSetSigtype (PGPSigSpec *spec, PGPByte sigtype)
{
	pgpAssert (spec);

	spec->extra[0] = sigtype;
	return 0;
}

int
pgpSigSpecSetTimestamp (PGPSigSpec *spec, PGPUInt32 timestamp)
{
	pgpAssert (spec);

	spec->extra[1] = (PGPByte)(timestamp>>24);
	spec->extra[2] = (PGPByte)(timestamp>>16);
	spec->extra[3] = (PGPByte)(timestamp>>8);
	spec->extra[4] = (PGPByte)timestamp;
	return 0;
}

/*
 * The timestamp is external for now because it is a part of the
 * SigParams structure from the environment.  Everything else is
 * a part of the PGPSigSpec structure 
 */
PGPByte const *
pgpSigSpecExtra (PGPSigSpec const *spec, size_t *extralen)
{
	if (extralen)
		*extralen = 5;

	return spec->extra;
}


/* Remaining functions use packetlist */

/* Find nth packet of specified type */
static PktList *
sSearchPkt( PGPSigSpec const *spec, int type, int nth )
{
	PktList *pki;

	for( pki = spec->pkl; pki; pki = pki->next ) {
		if( (pki->type & kPGPSigFlags_Type) == type )
			if (nth-- == 0)
				break;
	}
	return pki;
}

/* Free all packets of specified type */
static void
sFreePkts( PGPSigSpec *spec, int type )
{
	PktList **ppki, *pki;

	for( ppki = &spec->pkl; *ppki; ppki = &(*ppki)->next ) {
		while(*ppki && ((*ppki)->type & kPGPSigFlags_Type) == type ) {
			pki = *ppki;
			*ppki = pki->next;
			pgpPktListFreeOne( pki );
		}
		if( !*ppki )
			break;
	}
}

#if 0
/* Free nth packet of specified type */
static void
sFreePkt( PGPSigSpec *spec, int type, int nth )
{
	PktList **ppki, *pki;

	for( ppki = &spec->pkl; *ppki; ppki = &(*ppki)->next ) {
		if( ((*ppki)->type & kPGPSigFlags_Type) == type ) {
			if (nth-- == 0)
				break;
		}
	}
	if( *ppki ) {
		pki = *ppki;
		*ppki = pki->next;
		pgpPktListFreeOne( pki );
	}
}

#endif

#define sSigFlags(flags) \
	(((flags) & ~kPGPSigFlags_Type) | kPGPSigFlags_Present)


/* Get expiration */
PGPUInt32
pgpSigSpecSigExpiration (PGPSigSpec const *spec, PGPUInt32 *sigExpire)
{
	PktList *pkt;

	pkt = sSearchPkt( spec, SIGSUB_EXPIRATION, 0 );
	if( IsNull( pkt ) ) {
		*sigExpire = 0;
		return 0;
	}
	pgpAssert (pkt->len == sizeof (*sigExpire));
	*sigExpire = *(PGPUInt32 *)pkt->buf;
	return sSigFlags( pkt->type );
}

PGPError
pgpSigSpecSetSigExpiration (PGPSigSpec *spec, PGPUInt32 flags,
							PGPUInt32 sigExpire)
{
	PktList *pkt;

	sFreePkts( spec, SIGSUB_EXPIRATION );
	flags |= SIGSUB_EXPIRATION;
	pkt = pgpPktListNew( spec->cdkContext, flags, (PGPByte *)&sigExpire,
						 sizeof(sigExpire) );
	if( IsNull( pkt ) )
		return kPGPError_OutOfMemory;
	pkt->next = spec->pkl;
	spec->pkl = pkt;
	sSubPacketVersion(spec);
	return kPGPError_NoErr;
}


PGPUInt32

⌨️ 快捷键说明

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