📄 pgpsigspec.c
字号:
/*
* 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 + -