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

📄 pgprngpars.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 3 页
字号:
				offset = bp - buf;
#endif
			}
			if (len < 1)
				return kPGPError_ExtraDateOnSignature;
			type = buf[0];
			critical = type & SIGSUBF_CRITICAL;
			type &= ~SIGSUBF_CRITICAL;
			buf += 1;
			len -= 1;
			sublen -= 1;
			offset -= 1;
			if (len < sublen)
				return kPGPError_ExtraDateOnSignature;
			/* Illegal to have critical packets in unhashed region */
			if (critical && !hashed)
				return kPGPError_ExtraDateOnSignature;
			switch (type) {
			case SIGSUB_CREATION:
				if (sublen != 4)
					return kPGPError_ExtraDateOnSignature;
				dat = (PGPUInt32)((PGPUInt32)buf[0]<<8|buf[1]) << 16 |
									   ((PGPUInt32)buf[2]<<8|buf[3]);
				pgpSigSpecSetTimestamp (spec, dat);
				break;
			case SIGSUB_EXPIRATION:
				if (sublen != 4)
					return kPGPError_ExtraDateOnSignature;
				dat = (PGPUInt32)((PGPUInt32)buf[0]<<8|buf[1]) << 16 |
									   ((PGPUInt32)buf[2]<<8|buf[3]);
				pgpSigSpecSetSigExpiration (spec, SFLAGS(critical, hashed),
											dat);
				break;
			case SIGSUB_KEY_EXPIRATION:
				if (sublen != 4)
					return kPGPError_ExtraDateOnSignature;
				dat = (PGPUInt32)((PGPUInt32)buf[0]<<8|buf[1]) << 16 |
									   ((PGPUInt32)buf[2]<<8|buf[3]);
				pgpSigSpecSetKeyExpiration (spec, SFLAGS(critical, hashed),
											dat);
				break;
			case SIGSUB_KEYID:
				/* This was processed beforehand to set up the sigspec */
				if (sublen != 8)
					return kPGPError_ExtraDateOnSignature;
				break;
			case SIGSUB_EXPORTABLE:
				/* Allow exportability attribute not to be hashed */
				if (sublen != 1)
					return kPGPError_ExtraDateOnSignature;
				pgpSigSpecSetExportable (spec, SFLAGS(critical, hashed),
											(PGPBoolean)(buf[0]!=0));
				break;
			case SIGSUB_REVOCABLE:
				if (sublen != 1)
					return kPGPError_ExtraDateOnSignature;
				pgpSigSpecSetRevocable (spec, SFLAGS(critical, hashed),
											(PGPBoolean)(buf[0]!=0));
				break;
			case SIGSUB_PRIMARY_USERID:
				pgpSigSpecSetPrimaryUserID (spec,
											SFLAGS(critical, hashed),
											(PGPBoolean)(buf[0]!=0));
				break;
			case SIGSUB_TRUST:
				/* Packet format not fully decided, use 1st two bytes */
				if (sublen != 2)
					return kPGPError_ExtraDateOnSignature;
				pgpSigSpecSetTrustLevel (spec, SFLAGS(critical, hashed),
										 (PGPBoolean)(buf[0]!=0),
										 (PGPBoolean)(buf[1]!=0));
				break;
			case SIGSUB_REGEXP:
				pgpSigSpecSetRegExp (spec, SFLAGS(critical, hashed),
									 (char *)buf);
				break;
			case SIGSUB_PREFERRED_ENCRYPTION_ALGS:
				pgpSigSpecSetPrefAlgs (spec, SFLAGS(critical, hashed),
									 buf, sublen);
				break;
			case SIGSUB_PREFERRED_KEYSERVER:
				pgpSigSpecSetPrefKeyServ (spec, SFLAGS(critical, hashed),
									 buf, sublen);
				break;
			case SIGSUB_KEYFLAGS:
				pgpSigSpecSetKeyFlags (spec, SFLAGS(critical, hashed),
									 buf, sublen);
				break;
			case SIGSUB_KEYSERVER_PREFERENCES:
				pgpSigSpecSetKeyServPrefs (spec, SFLAGS(critical, hashed),
									 buf, sublen);
				break;
			case SIGSUB_KEY_ADDITIONAL_RECIPIENT_REQUEST:
				pgpSigSpecSetAdditionalRecipientRequest (spec,
							SFLAGS(critical, hashed), buf, sublen);
				break;
			case SIGSUB_KEY_REVOCATION_KEY:
				pgpSigSpecSetRevocationKey (spec,
							SFLAGS(critical, hashed), buf, sublen);
				break;
			default:
				pgpSigSpecSetPacket (spec, SFLAGS(critical, hashed),
									 buf-1, sublen+1);
				break;
			}
			buf += offset;
			len -= offset;
		}
		hashed = !hashed;
	} while (!hashed);			/* Two iterations */
	return kPGPError_NoErr;
}




/*
 * Return data for nth subpacket in an attribute object.
 * Data is in buf.
 * Format is as for signature subpacket portion:
 * A chain of subpackets, with the following format:
 * Offset,Length  Meaning
 *	0	x(1-2)	Subpacket length (=y)
 *	x	1	Subpacket type (with critical flag)
 *	x+1	y-1	Subpacket data
 *
 * This may alter the contents of buf, so should only be called once on
 * any given buffer.
 *
 * nth should be set to 0 to find first subpacket, 1 for second, etc.
 * Returns type of subpacket and its size.
 */
	PGPByte const *
pgpAttrSubpacket(PGPByte const *buf, PGPSize len, PGPUInt32 nth,
	PGPUInt32 *subpacktype, PGPSize *plen)
{
	PGPSize		sublen;				/* Length of subpacket */
	PGPSize		offset;				/* Offset to next subpacket */
	PGPUInt32	type;				/* Type of subpacket */
	PGPUInt32	npackets = 0;		/* Number of matches so far */
	PGPSize		hlen;

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

	while (len) {
		if (len < 2)
			return NULL;
		/* Subpacket length may be one or two bytes, or variable-length */
		sublen = (PGPSize)buf[0];
		if (sublen < 0xc0) {
			/* sublen is the length */
			offset = sublen;
			len -= 1;
			buf += 1;
		} else if (sublen < 0xff) {
			sublen &= 0x3f;
			sublen = (sublen << 8) + (PGPSize)buf[1] + 192;
			offset = sublen;
			len -= 2;
			buf += 2;
		} else if (sublen == 0xff) {
			sublen = (((((buf[1]<<8)|buf[2])<<8)|buf[3])<<8)|buf[4];
			offset = sublen;
			len -= 5;
			buf += 5;
#if 0
		} else {
			/* Variable length subpacket; concatenate data */
			PGPSize partlen;
			PGPByte *bp;
			PGPBoolean final = FALSE;
			len -= 1;
			buf += 1;
			sublen = 1 << (sublen & 0x1f);
			partlen = sublen;
			bp = buf + partlen;
			while (!final) {
				partlen = (PGPSize)*bp++;
				if (partlen < 0xe0) {
					final = TRUE;
					if (partlen >= 0xc0)
						partlen = ((partlen&0x3f) << 8) + (PGPSize)*bp++ + 192;
				} else {
					partlen = 1 << (partlen & 0x1f);
				}
				pgpCopyMemory (bp, buf+sublen, partlen);
				sublen += partlen;
				bp += partlen;
			}
			offset = bp - buf;
#endif
		}
		if (len < 1)
			return NULL;
		type = buf[0];
		buf += 1;
		len -= 1;
		sublen -= 1;
		offset -= 1;

		if (npackets++ == nth) {
			if (plen)
				*plen = sublen;
			if (subpacktype)
				*subpacktype = type;
			return buf;
		}
	}

	/* Get here if fewer than n+1 subpackets */
	return NULL;
}

/* Return the number of subpackets in the buffer */
	PGPUInt32
pgpAttrCountSubpackets(PGPByte const *buf, PGPSize len)
{
	PGPSize		sublen;				/* Length of subpacket */
	PGPSize		offset;				/* Offset to next subpacket */
	PGPUInt32	type;				/* Type of subpacket */
	PGPUInt32	npackets = 0;		/* Number of matches so far */
	PGPSize		hlen;

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

	while (len) {
		if (len < 2)
			return 0;
		/* Subpacket length may be 1/2/4 bytes, or variable-length */
		sublen = (PGPSize)buf[0];
		if (sublen < 0xc0) {
			/* sublen is the length */
			offset = sublen;
			len -= 1;
			buf += 1;
		} else if (sublen < 0xff) {
			sublen &= 0x3f;
			sublen = (sublen << 8) + (PGPSize)buf[1] + 192;
			offset = sublen;
			len -= 2;
			buf += 2;
		} else if (sublen == 0xff) {
			sublen = (((((buf[1]<<8)|buf[2])<<8)|buf[3])<<8)|buf[4];
			offset = sublen;
			len -= 5;
			buf += 5;
#if 0
		} else {
			/* Variable length subpacket */
			PGPSize partlen;
			PGPByte const *bp;
			PGPBoolean final = FALSE;
			len -= 1;
			buf += 1;
			sublen = 1 << (sublen & 0x1f);
			partlen = sublen;
			bp = buf + partlen;
			while (!final) {
				partlen = (PGPSize)*bp++;
				if (partlen < 0xe0) {
					final = TRUE;
					if (partlen >= 0xc0)
						partlen = ((partlen&0x3f) << 8) + (PGPSize)*bp++ + 192;
				} else {
					partlen = 1 << (partlen & 0x1f);
				}
				sublen += partlen;
				bp += partlen;
			}
			offset = bp - buf;
#endif
		}
		if (len < 1)
			return 0;
		type = buf[0];
		buf += 1;
		len -= 1;
		sublen -= 1;
		offset -= 1;

		++npackets;
	}

	return npackets;
}


/*
 * Return the length of the prefix of a secret key which is a public key,
 * or 0 if it can't be determined.  A key's prefix is:
 * 0 1 - Version
 * 1 4 - Creation time
 * 5 2 - Vaidity period (days)
 * 7 1 - Algorithm
 * 8 ? - Algorithm-specific parameters
 */
	PGPSize
pgpKeyParsePublicPrefix(PGPByte const *buf, PGPSize len)
{
	PGPSize size;
	PGPSize vsize;
	PGPSize hlen;

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

	if (buf[0] == PGPVERSION_4) {
		vsize = 0;
	} else {
		vsize = 2;
	}

	/* Check version bytes */
	if (!KNOWN_PGP_VERSION(buf[0]) || len < 6+vsize)
		return 0;
	size = pgpPubKeyPrefixSize(buf[5+vsize], buf+6+vsize, len-6-vsize);
	if (size)
		size += 6+vsize+hlen;
	return size;
}

	PGPError
pgpKeyParseFingerprint16(PGPContextRef context, PGPByte const *kbuf,
						  PGPSize klen, PGPByte *fingerprint)
{
	PGPHashVTBL const *h;
	PGPHashContext *hc;
	PGPByte const *buf;
	PGPSize len;
	MemPool *pool = NULL;
	MemPool	cut;
    PGPMemoryMgrRef	mgr;

	h = pgpHashByNumber (kPGPHashAlgorithm_MD5);
	if (!h)
		return kPGPError_BadHashNumber;

	pool = pgpPeekContextMemPool( context );
	cut = *pool;
	mgr = pgpMemPoolMemoryMgr( pool );
	hc = pgpHashCreate( mgr, h);
	if (!hc) {
		memPoolCutBack( pool, &cut );
		return kPGPError_OutOfMemory;
	}

	buf = sKeyParseModulus(kbuf, klen, &len);
	if (!buf)
	goto error;
	PGPContinueHash(hc, buf, len);

	buf = sKeyParseExponent(kbuf, klen, &len);
	if (!buf)
	goto error;
	PGPContinueHash(hc, buf, len);

	buf = (PGPByte *) pgpHashFinal(hc);
	memcpy(fingerprint, buf, h->hashsize);
	PGPFreeHashContext(hc);
	memPoolCutBack( pool, &cut );

	return h->hashsize;	/* Success */
error:
	PGPFreeHashContext(hc);
	memPoolCutBack( pool, &cut );
	pgpClearMemory( fingerprint,  16);
	return pgpKeyParse(context, kbuf, klen, NULL, NULL, NULL, NULL, NULL,
						NULL, NULL, 0);
	/*                              Pkalg KeyID KeybitTstampValid */
}


/* Return the size which will be used to create the key prefix buffer */
	PGPSize
pgpKeyBufferLength(PGPKeySpec const *ks, PGPByte pkalg)
{
	(void)pkalg;
	if (pgpKeySpecVersion(ks)==PGPVERSION_4)
		return 6;	/* version(1)+timestamp(4)+pkalg(1) */
	else
		return 8;	/* version(1)+timestamp(4)+validity(2)+pkalg(1) */
}

/* Create the key prefix buffer */
	PGPError
pgpKeyToBuffer(PGPByte *buf, PGPKeySpec const *ks, PGPByte pkalg)
{
	PGPUInt32 tstamp;
	PGPUInt16 validity;
	PGPSize vsize;


	buf[0] = pgpKeySpecVersion(ks);
	if (buf[0] == PGPVERSION_4) {
		vsize = 0;
	} else {
		vsize = 2;
	}
	tstamp = pgpKeySpecCreation(ks);
	buf[1] = (PGPByte)(tstamp>>24);
	buf[2] = (PGPByte)(tstamp>>16);
	buf[3] = (PGPByte)(tstamp>> 8);
	buf[4] = (PGPByte)(tstamp    );
	if (vsize) {
		validity = pgpKeySpecValidity(ks);
		buf[5] = (PGPByte)(validity>>8);
		buf[6] = (PGPByte)(validity   );
	}
	buf[5+vsize] = pkalg;
	return 0;
}



/* Parse a CRL packet */
	PGPError
pgpCRLParse( PGPContextRef context, PGPByte const *buf, PGPSize len,
	PGPByte *version, PGPByte *type, PGPUInt32 *tstamp, PGPUInt32 *tstampnext,
	PGPByte const **dpoint, PGPSize *dpointlen )
{
	PGPASN_CertificateRevocationList *crl509;
	PGPSize dpoff;
	PGPSize hlen;
	PGPError err = kPGPError_NoErr;

	/* Defaults in case of error */
	if (version)
		*version = 0;
	if (type)
		*type = 0;
	if (tstamp)
		*tstamp = 0;
	if (tstampnext)
		*tstampnext = 0;
	if (dpoint)
		*dpoint = NULL;
	if (dpointlen)
		*dpointlen = 0;

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

	/* First two bytes are version, type */
	if (len < 2)
		goto short_err;
	if (version)
		*version = buf[0];
	if (type)
		*type = buf[1];

	if (buf[0] == PGPVERSION_4) {
		dpoff = 0;
		if (buf[1] == PGPCRLTYPE_X509DPOINT) {
			dpoff = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
			if (dpoint)
				*dpoint = buf+6;
			if (dpointlen)
				*dpointlen = dpoff;
			dpoff += 4;
		}
		err = pgpX509BufferToCRL(context, (PGPByte *)buf+2+dpoff,
								 len-2-dpoff, &crl509);
		if( IsPGPError( err ) )
			return err;

		if (tstamp)
			(void)pgpX509DecodeTime (&crl509->tbsCertList.thisUpdate, tstamp);
		if (tstampnext && IsntNull(crl509->tbsCertList.nextUpdate))
			(void)pgpX509DecodeTime (crl509->tbsCertList.nextUpdate,
									 tstampnext);

		pgpX509FreeCRL( context, crl509 );
	}

	return kPGPError_NoErr;

short_err:
	return kPGPError_CRLPacketTruncated;
}

/* Find the DistributionPoint information in the packet */
	PGPByte const *
pgpCRLFindDPoint( PGPByte const *buf, PGPSize buflen, PGPSize *len )
{
	PGPSize dplen;
	PGPSize hlen;

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

	if (len)
		*len = 0;
	if (buf[0] != PGPVERSION_4  ||  buf[1] != PGPCRLTYPE_X509DPOINT)
		return NULL;
	if (buflen < 6)
		return NULL;
	dplen = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
	if (dplen + 6 > buflen)
		return NULL;
	if (len)
		*len = dplen;
	return buf + 6;
}


/* Find the CRL information in the packet */
	PGPByte const *
pgpCRLFindCRL( PGPByte const *buf, PGPSize buflen, PGPSize *len )
{
	PGPSize dplen = 0;
	PGPSize hlen;

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

	if (buf[0] != PGPVERSION_4  ||  (buf[1] != PGPCRLTYPE_X509
									 && buf[1] != PGPCRLTYPE_X509DPOINT))
		return NULL;
	if (buf[1] == PGPCRLTYPE_X509DPOINT)
		dplen = ((buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5]) + 4;
	if (len)
		*len = buflen - 2 - dplen;
	return buf + 2 + dplen;
}


/*
 * Local Variables:
 * tab-width: 4
 * End:
 * vi: ts=4 sw=4
 * vim: si
 */

⌨️ 快捷键说明

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