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

📄 pgpkeyadd.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 5 页
字号:
	PGPBoolean			revocable;
	PGPByte				trustLevel;
	PGPByte				trustValue;
	PGPBoolean			hasRegExp;
	PGPBoolean			hasDPoint = FALSE;
	PGPBoolean			isX509;
	PGPBoolean			primaryUID;
	PGPKeyID			keyID;
	PGPError			err;

	(void)pkttype;
	pgpAssert( IsntNull( parent ) );

	/* Look for matching sig structure */
	sig = pgpFindMatchingChild( parent, buf, len );

	if( IsntNull( sig ) ) {
		/* Got a match */
		if( sig->objflags & kPGPKeyDBObjFlags_Deleted )
		{
			/* Bring back to life at end of list */
			sig->objflags &= ~kPGPKeyDBObjFlags_Deleted;
			pgpUnlinkChild( sig, parent );
			pgpLinkChild( sig, parent );
			/* See if sig is on sigsby list, put it there if not */
			sinfo = pgpSigToSigInfo( sig );
			key = sinfo->by;
			kinfo = pgpKeyToKeyInfo( key );
			for( tsig = kinfo->sigsby; IsntNull(tsig); tsig=sinfo->nextby )
			{
				if ( tsig == sig )
					return sig;		/* Done */
				sinfo = pgpSigToSigInfo( tsig );
			}
			/* Not found, put it on list */
			sinfo = pgpSigToSigInfo( sig );
			sinfo->nextby = kinfo->sigsby;
			kinfo->sigsby = sig;
		}
		return sig;
	} else {
		err = pgpSigParse(buf, len, FALSE, &pkalg, keyidbytes, &tstamp,
						  &sigvalidity, &type, &hashalg, &extralen, &version,
						  &exportable, &revocable, &trustLevel, &trustValue,
						  &hasRegExp, &isX509, &primaryUID);
		if( IsPGPError( err ) )
			return NULL;

		/* X.509 sigs use hash of issuer name as keyid; also get hash of
		 * subject name for later. */
		if( isX509 )
		{
			sX509KeyIDBytes( kdb, buf, len, &hasDPoint,
							 keyidbytes, x509subjectkeyidbytes);
		}
		if( isX509 )			/* Use high values for pkalg on X509's */
			pkalg = 0x80;
		vpkalg = pkalg;			/* Viacrypt correction */
		if ((vpkalg | 1) == 3)
			vpkalg = 1;
		pgpNewKeyIDFromRawData(keyidbytes, vpkalg, sizeof(keyidbytes), &keyID);
		(void)pgpGetKeyByKeyID( kdb, &keyID, TRUE, TRUE, &key);
		if( IsNull( key ) ) {
			/* Must create dummy key */
			key = sNewKey( kdb );
			if( IsNull( key ) )
			{
				err = kPGPError_OutOfMemory;
				goto error;
			}
			kinfo = pgpKeyToKeyInfo( key );
			pgpCopyMemory( keyidbytes, kinfo->keyID, sizeof(keyidbytes));
			kinfo->pkalg = pkalg;
			key->objflags |= kPGPKeyDBObjFlags_Dummy;
			if( isX509 )
				key->objflags |= kPGPKeyDBObjFlags_X509;
			pgpLinkKey( key, kdb );
			pgpLinkKeyToTree( key, kdb );
		} else if( pgpKeyDBObjIsDeleted( key ) ) {
			key->objflags &= ~kPGPKeyDBObjFlags_Deleted;
			key->objflags |= kPGPKeyDBObjFlags_Dummy;
		}

		sig = sNewSig( kdb );
		if ( sig == NULL ) {
			err = kPGPError_OutOfMemory;
			goto error;
		}
		pgpLinkChild( sig, parent );

		sinfo = pgpSigToSigInfo( sig );
		sinfo->by = key;
		kinfo = pgpKeyToKeyInfo( key );
		sinfo->nextby = kinfo->sigsby;
		kinfo->sigsby = sig;
		if (extralen != 5)
			sinfo->flags |= SIGF_NONFIVE;
		sinfo->tstamp = tstamp;
		sinfo->sigvalidity = sigvalidity;
		sinfo->type = type;
		sinfo->version = version;
		sinfo->hashalg = hashalg;
		sinfo->trust = 0;
		sinfo->trustLevel = trustLevel;
		sinfo->trustValue = trustValue;
		if (exportable)
			SIGSETEXPORTABLE(sinfo);
		else
			SIGSETNONEXPORTABLE(sinfo);
		if (revocable)
			SIGSETREVOCABLE(sinfo);
		else
			SIGSETNONREVOCABLE(sinfo);
		if (hasRegExp)
			SIGSETUSESREGEXP(sinfo);
		else
			SIGCLEARUSESREGEXP(sinfo);
		if (isX509)
			SIGSETX509(sinfo);
		else
			SIGCLEARX509(sinfo);
		if (hasDPoint)
			SIGSETDISTPOINT(sinfo);
		else
			SIGCLEARDISTPOINT(sinfo);
		if (primaryUID)
			SIGSETPRIMARYUID(sinfo);
		else
			SIGCLEARPRIMARYUID(sinfo);
	}
	if( isX509 )
		sFixupX509ParentKey( kdb, sig, x509subjectkeyidbytes );
	sinfo = pgpSigToSigInfo( sig );

	if( IS_OLD_PKTBYTE(buf[0])
		&& PKTBYTE_LLEN(buf[0]) == 0
		&& pkalg == kPGPPublicKeyAlgorithm_RSA )
	{
		/* PGP 2.6.2 requires RSA sigs to have two byte lengths */
		PGPByte pktbyte;
		PGPByte *pktbuf;
		PGPContextRef context;

		pktbyte = PKTBYTE_BUILD( PKTBYTE_SIG, 1 );
		/* Len will be 1 bigger */
		len += 1;

		/* Allocate space */
		context = PGPPeekKeyDBContext( kdb );
		pktbuf = pgpContextMemAlloc( context, len, 0 );
		if( IsNull(pktbuf) )
			return NULL;

		/* Fill buffer.  len-3 is length of payload. */
		pgpPktHeaderPut( pktbuf, pktbyte, len-3 );
		pgpCopyMemory( buf+2, pktbuf+3, len-3 );

		/* Store data buffer */
		sinfo->data = pgpNewObjData( kdb, pktbuf, len );
		PGPFreeData( pktbuf );
		
	} else
		sinfo->data = pgpNewObjData( kdb, buf, len );

	return sig;
 error:
	*error = err;
	return NULL;
}


PGPKeyDBObj *
pgpAddCRL( PGPInt32 pkttype, PGPByte const *buf, PGPSize len,
	PGPKeyDB *kdb, PGPKeyDBObj *parent, PGPError *outerr )
{
	PGPKeyDBObj *		crl;
	PGPCRLInfo *		cinfo;
	PGPContextRef		context;
	PGPUInt32			tstamp, tstampnext;
	PGPByte				version;
	PGPByte				type;
	PGPByte const *		dpoint;
	PGPSize				dpointlen;
	PGPError			err;

	(void)pkttype;
	pgpAssert( IsntNull( parent ) );
	if( !OBJISTOPKEY( parent ) )
		return NULL;

	/* Find any matching CRL structure */
	crl = pgpFindMatchingChild( parent, buf, len );

	if( IsntNull( crl ) ) {
		/* Got a match */
		crl->objflags &= ~kPGPKeyDBObjFlags_Deleted;
		return crl;
	} else {
		crl = sNewCRL( kdb );
		if ( crl == NULL ) {
			err = kPGPError_OutOfMemory;
			goto error;
		}
		pgpLinkChild( crl, parent );
	}
	cinfo = pgpCRLToCRLInfo( crl );
	context = PGPPeekKeyDBContext( kdb );
	(void)pgpCRLParse( context, buf, len, &version, &type, &tstamp,
					   &tstampnext, &dpoint, &dpointlen );
	cinfo->version = version;
	cinfo->tstamp = tstamp;
	cinfo->tstampnext = tstampnext;
	if (type == PGPCRLTYPE_X509 || type == PGPCRLTYPE_X509DPOINT)
		CRLSETX509(cinfo);
	else
		CRLCLEARX509(cinfo);
	if (type == PGPCRLTYPE_X509DPOINT) {
		CRLSETDPOINT(cinfo);
	} else {
		CRLCLEARDPOINT(cinfo);
	}
	cinfo->data = pgpNewObjData( kdb, buf, len );
	return crl;
 error:
	*outerr = err;
	return NULL;
}

PGPKeyDBObj *
pgpAddUnknown( PGPInt32 pkttype, PGPByte const *buf, PGPSize len,
	PGPKeyDB *kdb, PGPKeyDBObj *parent, PGPError *outerr )
{
	PGPKeyDBObj *		unk;
	PGPUnkInfo *		ninfo;
	PGPError			err;

	(void)pkttype;
	pgpAssert( IsntNull( parent ) );
	if( !OBJISTOPKEY( parent ) )
		return NULL;

	/* Find any matching Unknown structure */
	unk = pgpFindMatchingChild( parent, buf, len );

	if( IsntNull( unk ) ) {
		/* Got a match */
		unk->objflags &= ~kPGPKeyDBObjFlags_Deleted;
		return unk;
	} else {
		unk = sNewUnknown( kdb );
		if ( unk == NULL ) {
			err = kPGPError_OutOfMemory;
			goto error;
		}
		pgpLinkChild( unk, parent );
	}
	ninfo = pgpUnkToUnkInfo( unk );
	ninfo->data = pgpNewObjData( kdb, buf, len );
	return unk;
 error:
	*outerr = err;
	return NULL;
}




PGPKeyDBObj *
pgpAddObject( PGPByte const *buf, PGPSize len,
	PGPKeyDB *kdb, PGPKeyDBObj *parent, PGPBoolean trusted, PGPError *err )
{
	PGPByte pkttype;

	if( len == 0 )
		return NULL;

	pkttype = PKTBYTE_TYPE(*buf);
	switch (pkttype) {
	case PKTBYTE_PUBKEY:
	case PKTBYTE_PUBSUBKEY:
	case PKTBYTE_SECKEY:
	case PKTBYTE_SECSUBKEY:
		return pgpAddKey( pkttype, buf, len, kdb, parent, trusted, err );
	case PKTBYTE_ATTRIBUTE:
	case PKTBYTE_USERID:
		return pgpAddUserID( pkttype, buf, len, kdb, parent, err );
	case PKTBYTE_SIG:
		return pgpAddSig( pkttype, buf, len, kdb, parent, err );
	case PKTBYTE_CRL:
		return pgpAddCRL( pkttype, buf, len, kdb, parent, err );
	default:
		return pgpAddUnknown( pkttype, buf, len, kdb, parent, err );
	}
}


static PGPError
pgpTrustPacket( PGPByte const *buf, PGPSize len, PGPKeyDB *kdb,
				PGPKeyDBObj *lastobj, PGPEnv *env )
{
	PGPKeyInfo *kinfo;
	PGPUserIDInfo *uinfo;
	PGPSigInfo *sinfo;
	PGPCRLInfo *cinfo;
	PGPUnkInfo *ninfo;
	PGPByte trust;
	PGPByte validity;
	PGPByte confidence;
	PGPContextRef context;
	PGPSize hlen;
	PGPEnv *pgpEnv;

	if( len == 0 )
		return kPGPError_NoErr;

	context = PGPPeekKeyDBContext( kdb );
	pgpEnv = pgpContextGetEnvironment( context );

	hlen = pgpPktBufferHeaderLen( buf );
	buf += hlen;
	len -= hlen;

	if( len == 0 )
		return kPGPError_NoErr;

	trust = buf[0];

	if( OBJISUSERID( lastobj ) ) {
		/*
		 * Name trust packets can be up to 3 bytes
		 * long:
		 * Byte 1: old-style trust packet
		 * Byte 2: validity of name
		 * Byte 3: confidence in name as introducer
		 */
		/* Default trust and validity bytes */
		switch (trust & kPGPUserIDTrust_Mask) {
		  case kPGPUserIDTrust_Complete:
			validity = pgpenvCompleteTrust( env );
			break;
		  case kPGPUserIDTrust_Marginal:
			validity = pgpenvMarginalTrust( env );
			break;
		  default:
			validity = 0;
			break;
		}
		pgpAssert(OBJISKEY(lastobj->up));

		kinfo = pgpKeyToKeyInfo( lastobj->up );
		confidence = pgpTrustOldToExtern(pgpEnv, kinfo->trust);

		if (len > 1) {
			/* Fetch validity */
			validity = buf[1];
			if (len > 2) {
				/* Fetch confidence */
				confidence = buf[2];
			}
		}
		uinfo = pgpUserIDToUserIDInfo( lastobj );
		uinfo->oldvalidity = trust;
		uinfo->validity = validity;
		uinfo->confidence = confidence;
		uinfo->valid = pgpTrustToIntern (validity);
	} else {	/* Not a name */
		/* Set the appropriate flags */
		switch (pgpObjectType(lastobj)) {
		default:
			pgpAssert(0);
		case RINGTYPE_KEY:
		case RINGTYPE_SUBKEY:
			kinfo = pgpKeyToKeyInfo( lastobj );
			kinfo->trust = trust;
			break;
		case RINGTYPE_SIG:
			sinfo = pgpSigToSigInfo( lastobj );
			sinfo->trust = trust;
			break;
		case RINGTYPE_CRL:
			cinfo = pgpCRLToCRLInfo( lastobj );
			cinfo->trust = trust;
			break;
		case RINGTYPE_UNK:
			ninfo = pgpUnkToUnkInfo( lastobj );
			ninfo->trust = trust;
			break;
		}
	}


	/* Handle key validity info from trusted self-signatures */
	if( OBJISSIG(lastobj) ) {
		PGPKeyDBObj *keyobj;
		PGPKeyDBObj *topkeyobj;
		PGPByte const *sdata;
		PGPSize sdatalen;
		PGPByte const *pk;

		sinfo = pgpSigToSigInfo( lastobj );
		if( (sinfo->trust & PGP_SIGTRUSTF_CHECKED) &&
			!(sinfo->trust & PGP_SIGTRUSTF_REVOKEDBYCRL) ) {
			keyobj = lastobj->up;
			while( !OBJISKEY( keyobj ) )
				keyobj = keyobj->up;
			topkeyobj = keyobj;
			while( !OBJISTOPKEY( topkeyobj ) )
				topkeyobj = topkeyobj->up;
			if( sinfo->by == topkeyobj ) {
				sdata = pgpFetchObject( lastobj, &sdatalen );
				pk = pgpSigFindSubpacket ( sdata,
					SIGSUB_KEY_EXPIRATION,
					0, NULL, NULL, NULL, NULL, NULL);
				if( IsntNull(pk) ) {
					PGPUInt32 keyexp;
					keyexp = (PGPUInt32)((unsigned)pk[0]<<8|pk[1]) << 16 |
									((unsigned)pk[2]<<8|pk[3]);
					kinfo = pgpKeyToKeyInfo( keyobj );
					kinfo->validityperiod = keyexp / (24 * 3600);
				}
			}
		}
	}
	return kPGPError_NoErr;
}


/*
 * When copying an obj from one db to another, copy its trust info.  We will
 * keep the max of the old and new trust.
 */
	void
pgpCopyObjectTrust( PGPKeyDBObj *oldobj, PGPKeyDBObj *newobj )
{
	PGPKeyInfo *okinfo, *nkinfo;
	PGPUserIDInfo *ouinfo, *nuinfo;
	PGPSigInfo *osinfo, *nsinfo;
	PGPCRLInfo *ocinfo, *ncinfo;
	PGPUnkInfo *oninfo, *nninfo;

	if( OBJISUSERID( oldobj ) ) {
		pgpAssert( OBJISUSERID( newobj ) );
		ouinfo = pgpUserIDToUserIDInfo( oldobj );
		nuinfo = pgpUserIDToUserIDInfo( newobj );
		nuinfo->oldvalidity =
			((ouinfo->oldvalidity|nuinfo->oldvalidity) &
			 (PGP_USERIDTRUSTF_WARNONLY|PGP_USERIDTRUSTF_PRIMARY)) |
			pgpMax(ouinfo->oldvalidity&3, nuinfo->oldvalidity&3);
		nuinfo->validity = (nuinfo->validity == PGP_NEWTRUST_UNDEFINED)
			? ouinfo->validity
			: ( (ouinfo->validity == PGP_NEWTRUST_UNDEFINED)
				? nuinfo->validity
				: pgpMax(ouinfo->validity, nuinfo->validity) );
		nuinfo->confidence = (nuinfo->confidence == PGP_NEWTRUST_UNDEFINED)
			? ouinfo->confidence
			: ( (ouinfo->confidence == PGP_NEWTRUST_UNDEFINED)
				? nuinfo->confidence
				: pgpMax(ouinfo->confidence, nuinfo->confidence) );
		nuinfo->valid = pgpMax(ouinfo->valid, nuinfo->valid);
	} else {	/* Not a name */
		/* Set the appropriate flags */
		switch (pgpObjectType(oldobj)) {

⌨️ 快捷键说明

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