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

📄 pgprngpars.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 3 页
字号:
				sublen = 1 << (sublen & 0x1f);
				partlen = sublen;
				bp = buf + partlen;
				while (!final) {
					partlen = (unsigned)*bp++;
					if (partlen < 0xe0) {
						final = TRUE;
						if (partlen >= 0xc0)
							partlen = ((partlen&0x3f) << 8)
												+ (unsigned)*bp++ + 192;
					} else {
						partlen = 1 << (partlen & 0x1f);
					}
					sublen += partlen;
					bp += partlen;
				}
				offset = bp - buf;
			}
			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)((unsigned)buf[0]<<8|buf[1]) << 16 |
									   ((unsigned)buf[2]<<8|buf[3]);
				pgpSigSpecSetTimestamp (spec, dat);
				break;
			case SIGSUB_EXPIRATION:
				if (sublen != 4)
					return kPGPError_ExtraDateOnSignature;
				dat = (PGPUInt32)((unsigned)buf[0]<<8|buf[1]) << 16 |
									   ((unsigned)buf[2]<<8|buf[3]);
				pgpSigSpecSetSigExpiration (spec, SFLAGS(critical, hashed),
											dat);
				break;
			case SIGSUB_KEY_EXPIRATION:
				if (sublen != 4)
					return kPGPError_ExtraDateOnSignature;
				dat = (PGPUInt32)((unsigned)buf[0]<<8|buf[1]) << 16 |
									   ((unsigned)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_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 *
ringAttrSubpacket(PGPByte *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 */

	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 & 0xe0) == 0xc0) {
			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;
		} 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;
		}
		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
ringAttrCountSubpackets(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 */

	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 & 0xe0) == 0xc0) {
			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;
		} 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;
		}
		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
 */
size_t
ringKeyParsePublicPrefix(PGPByte const *buf, size_t len)
{
	size_t size;
	unsigned vsize;

	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;
	return size;
}

int
ringKeyParseFingerprint16(PGPContextRef context, PGPByte const *kbuf,
						  size_t klen, PGPByte *fingerprint)
{
	PGPHashVTBL const *h;
	PGPHashContext *hc;
	PGPByte const *buf;
	unsigned len;
    PGPMemoryMgrRef	memoryMgr	= PGPGetContextMemoryMgr( context );

	h = pgpHashByNumber (kPGPHashAlgorithm_MD5);
	if (!h)
		return kPGPError_BadHashNumber;
	hc = pgpHashCreate( memoryMgr, h);
	if (!hc)
		return kPGPError_OutOfMemory;

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

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

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

	return h->hashsize;	/* Success */
error:
	PGPFreeHashContext(hc);
	pgpClearMemory( fingerprint,  16);
	return ringKeyParse(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 */
size_t
ringKeyBufferLength(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 */
int
ringKeyToBuffer(PGPByte *buf, PGPKeySpec const *ks, PGPByte pkalg)
{
	PGPUInt32 tstamp;
	PGPUInt16 validity;
	unsigned 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;
}

/* Return the size of a prefix buffer for a secret key */
size_t
ringSecBufferLength(PGPKeySpec const *ks, PGPByte pkalg)
{
	return ringKeyBufferLength(ks, pkalg);
}

/* Create the prefix buffer for a secret key */
int
ringSecToBuffer(PGPByte *buf, PGPKeySpec const *ks, PGPByte pkalg)
{
	return ringKeyToBuffer(buf, ks, pkalg);
}


/* Parse a CRL packet */
PGPError
ringCRLParse( RingPool *pool, PGPByte const *buf, PGPSize len,
	PGPByte *version, PGPByte *type, PGPUInt32 *tstamp, PGPUInt32 *tstampnext,
	PGPByte const **dpoint, PGPSize *dpointlen )
{
	PGPASN_CertificateRevocationList *crl509;
	PGPSize dpoff;
	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;

	/* 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(pool->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( pool->context, crl509 );
	}

	return kPGPError_NoErr;

short_err:
	return kPGPError_CRLPacketTruncated;
}

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

	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 *
ringCRLFindCRL( PGPByte const *buf, PGPSize buflen, PGPSize *len )
{
	PGPSize dplen = 0;

	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;
}

⌨️ 快捷键说明

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