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

📄 pgpx509keys.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 5 页
字号:
			CHKASNERR( err );

			/* prime p */
			bnbuf[0] = dssp->p.val;
			bnlen[0] = dssp->p.len;
			err = sDecodeX509Integer (bnbuf[0], bnlen[0], NULL, &bnlength[0]);
			if( IsPGPError( err ) )
				goto error;

			/* subprime q */
			bnbuf[1] = dssp->q.val;
			bnlen[1] = dssp->q.len;
			err = sDecodeX509Integer (bnbuf[1], bnlen[1], NULL, &bnlength[1]);
			if( IsPGPError( err ) )
				goto error;

			/* generator g */
			bnbuf[2] = dssp->g.val;
			bnlen[2] = dssp->g.len;
			err = sDecodeX509Integer (bnbuf[2], bnlen[2], NULL, &bnlength[2]);
			if( IsPGPError( err ) )
				goto error;

			/* public value y */
			bnbuf[3] = dssk->val;
			bnlen[3] = dssk->len;
			err = sDecodeX509Integer (bnbuf[3], bnlen[3], NULL, &bnlength[3]);
			if( IsPGPError( err ) )
				goto error;

			pubelems = 4;

		} else if (keyalgorithm == kPGPPublicKeyAlgorithm_ElGamal) {
			pgpasn_UnpackELGParms ( asnctx, &elgp,
									spki->algorithm.parameters->val,
									spki->algorithm.parameters->len, &err );
			CHKASNERR( err );
			pgpasn_UnpackELGPublicKey ( asnctx, &elgk,
										spki->subjectPublicKey.val,
										spki->subjectPublicKey.len, &err );
			CHKASNERR( err );

			/* prime p */
			bnbuf[0] = elgp->p.val;
			bnlen[0] = elgp->p.len;
			err = sDecodeX509Integer (bnbuf[0], bnlen[0], NULL, &bnlength[0]);
			if( IsPGPError( err ) )
				goto error;

			/* generator g */
			bnbuf[1] = elgp->g.val;
			bnlen[1] = elgp->g.len;
			err = sDecodeX509Integer (bnbuf[1], bnlen[1], NULL, &bnlength[1]);
			if( IsPGPError( err ) )
				goto error;

			/* public value y */
			bnbuf[2] = elgk->val;
			bnlen[2] = elgk->len;
			err = sDecodeX509Integer (bnbuf[2], bnlen[2], NULL, &bnlength[2]);
			if( IsPGPError( err ) )
				goto error;

			pubelems = 3;

		} else /* RSA */ {
			pgpasn_UnpackRSAKey ( asnctx, &rsak, spki->subjectPublicKey.val,
								  spki->subjectPublicKey.len, &err );
			CHKASNERR( err );

			/* modulus n */
			bnbuf[0] = rsak->modulus.val;
			bnlen[0] = rsak->modulus.len;
			err = sDecodeX509Integer (bnbuf[0], bnlen[0], NULL, &bnlength[0]);
			if( IsPGPError( err ) )
				goto error;

			/* exponent e */
			bnbuf[1] = rsak->exponent.val;
			bnlen[1] = rsak->exponent.len;
			err = sDecodeX509Integer (bnbuf[1], bnlen[1], NULL, &bnlength[1]);
			if( IsPGPError( err ) )
				goto error;
			pubelems = 2;
		}
	}

	keybuflength = 0;
	publength = 0;
	for (i=0; i<elemsof(bnlength); ++i) {
		if( bnlength[i] == 0 )
			break;
		if (i < pubelems)
			publength += bnlength[i];
		keybuflength += bnlength[i];
	}

	/*
	 * To better estimate keybuflength, we need to construct the numeric
	 * data portion and then see if it matches an incoming key.  Only then
	 * can we know what kind of key packet we are dealing with.
	 */

	pubbuf = PGPNewData (mgr, publength, 0);
	CHKNONNULL(pubbuf, err);
	o = 0;
	for (i=0; i<pubelems; ++i) {
		if( bnlength[i] == 0 )
			break;
		err = sDecodeX509Integer (bnbuf[i], bnlen[i],
								  pubbuf+o, &bnlength[i]);
		if( IsPGPError( err ) )
			goto error;
		o += bnlength[i];
	}
	pgpAssert (o == publength);

	/* Get hash of numeric data */
	pgpFingerprint20HashBuf (context, pubbuf, publength, hash20);

	/* See if this matches an existing key */
	matchkey = NULL;
	if( IsntNull( refdb ) )
	{
		matchkey = pgpKeyDBFindKey20n (refdb, hash20);
	} else {
		refdb = pgpContextGetFirstKeyDB(context);
		while( IsntNull( refdb )  &&  IsNull( matchkey ) )
		{
			matchkey = pgpKeyDBFindKey20n (refdb, hash20);
			refdb = pgpKeyDBNextKeyDB( refdb );
		}
	}
	if( IsNull( matchkey ) ) {
		/* Fall back on defaults */
		if (keyalgorithm == kPGPPublicKeyAlgorithm_RSA)
			keyversion = PGPVERSION_3;
		else
			keyversion = PGPVERSION_4;
	} else {
		PGPSize hlen;
		matchkeybuf = pgpFetchObject (matchkey, &matchkeybuflength);
		if( IsNull( matchkeybuf ) ) {
			err = pgpKeyDBError(PGPPeekKeyDBObjKeyDB(matchkey));
			goto error;
		}
		hlen = pgpPktBufferHeaderLen( matchkeybuf );
		matchkeybuf += hlen;
		matchkeybuflength -= hlen;
		keyversion = matchkeybuf[0];
	}

	keybuflength += 6;	/* bytes preceding bignums */
	if( keyversion <= PGPVERSION_3)
			keybuflength += 2;	/* room for expiration date */

	if( IsntNull( pinfo ) ) {
		/*
		 * Can only import private if we have a matching key,
		 * because we can't synthesize a userid for it
		 */
		if( IsNull( matchkey ) ) {
			err = kPGPError_PublicKeyNotFound;
			goto error;
		}
		keybuflength += 3;		/* Private adds 1 enc byte + 2 csum */
	}

	if( IsNull( keyBuf ) ) {
		*keyLength = keybuflength;
	} else {
		pgpAssert (*keyLength == keybuflength);
		/* public key packet */
		o = 0;
		keyBuf[o++] = keyversion;
		/* 1-4 are timestamp */
		if (IsntNull( matchkey ) ) {
			pgpCopyMemory (matchkeybuf+1, keyBuf+o, 4);
		} else {
			PGPUInt32 creation = sDecodeKeyCreation( asnctx, cert );
			if( creation != 0 ) {
				keyBuf[o+0] = (creation >> 24) & 0xff;
				keyBuf[o+1] = (creation >> 16) & 0xff;
				keyBuf[o+2] = (creation >>  8) & 0xff;
				keyBuf[o+3] = (creation >>  0) & 0xff;
			} else {
				/* Use certificate creation date if all else fails */
				err = sDecodeNotBefore4( asnctx, cert, keyBuf+o );
				if (IsPGPError( err ) ) {
					pgpClearMemory (keyBuf+o, 4);
					err = kPGPError_NoErr;
				}
			}
		}
		o += 4;
		/* Next two are expiration if V3 packets */
		if (keyversion <= PGPVERSION_3) {
			if (IsntNull( matchkey ) ) {
				pgpCopyMemory (matchkeybuf+5, keyBuf+o, 2);
			} else {
				pgpClearMemory (keyBuf+o, 2);
			}
			o += 2;
		}
		keyBuf[o++] = keyalgorithm;
		pgpCopyMemory (pubbuf, keyBuf+o, publength);
		o += publength;
		PGPFreeData( pubbuf );
		pubbuf = NULL;

		if( IsntNull( pinfo ) ) {
			/* Save secret key fields */
			keyBuf[o++] = '\0';		/* Unencrypted secret data */
			checksum = 0;
			for (i=pubelems; i<elemsof(bnlength); ++i) {
				if( bnlength[i] == 0 )
					break;
				err = sDecodeX509Integer (bnbuf[i], bnlen[i],
										  keyBuf+o, &bnlength[i]);
				if( IsPGPError( err ) )
					goto error;
				for (j=0; j<bnlength[i]; ++j)
					checksum += keyBuf[o+j];
				o += bnlength[i];
			}
			keyBuf[o++] = (checksum >> 8) & 0xff;
			keyBuf[o++] = (checksum >> 0) & 0xff;
		}

		pgpAssert (o == keybuflength);
	}

error:

	if( IsntNull( pubbuf ) )
		PGPFreeData( pubbuf );
	if( IsntNull( dssp ) )
		pgpasn_FreeDssParms( asnctx, dssp );
	if( IsntNull( dssk ) )
		pgpasn_FreeDSAPublicKey( asnctx, dssk );
	if( IsntNull( elgp ) )
		pgpasn_FreeELGParms( asnctx, elgp );
	if( IsntNull( elgk ) )
		pgpasn_FreeELGPublicKey( asnctx, elgk );
	if( IsntNull( rsak ) )
		pgpasn_FreeRSAKey( asnctx, rsak );
	if( IsntNull( rsapriv ) )
		pgpasn_FreeRSAPrivateKey( asnctx, rsapriv );

	return err;
}


/*
 * Given an X509 cert, return a PGPKeyDBRef containing a single PGP key
 * with the same key material as the original cert.  The userid on the
 * key is one of the 509 subject distinguished name fields, the common name
 * if it exists, else one of the other fields.
 */
static PGPError
sDecode509(PGPContextRef context, PGPASN_CONTEXT *asnctx,
		   PGPASN_Certificate *cert, PGPKeyDBRef refdb, PGPKeyDBRef *keydb)
{
	PGPMemoryMgrRef mgr;
	PGPByte *pgpkeybuf = NULL;
	PGPSize keylen;
	PGPSize namelen;
	PGPSize siglen;
	PGPSize pgpkeylen;
	PGPUInt32 o;
	PGPKeyDBRef kdb;
	PGPError err = kPGPError_NoErr;

	*keydb = NULL;
	mgr = PGPPeekContextMemoryMgr( context );

	/* Decode signature packet */
	err = sDecodeSig (context, asnctx, cert, SIGSUBSUB_X509_VERSION_LO,
					  NULL, &siglen);
	if (IsPGPError(err))
		goto error;

	/* Decode subject name */
	err = sDecodeName (asnctx, cert, FALSE, NULL, &namelen);
	if (IsPGPError(err))
		goto error;
	
	/* Decode key packet */
	err = sDecodeKey (context, refdb, asnctx, cert, NULL, NULL, &keylen);
	if (IsPGPError(err))
		goto error;

	/* Now create the PGP key */

	pgpkeylen = 3 + keylen + 2 + (namelen>255) + namelen
				  + ((siglen>0)?(3+siglen):0);
	pgpkeybuf = (PGPByte *) PGPNewData( mgr, pgpkeylen, 0 );
	CHKNONNULL (pgpkeybuf, err);

	/* public key packet */
	o = 0;
	pgpkeybuf[o++] = PKTBYTE_BUILD(PKTBYTE_PUBKEY, 1),
	pgpkeybuf[o++] = (keylen >> 8) & 0xff;
	pgpkeybuf[o++] = (keylen >> 0) & 0xff;
	err = sDecodeKey (context, refdb, asnctx, cert, NULL, pgpkeybuf + o,
					  &keylen);
	if (IsPGPError(err))
		goto error;
	o += keylen;

	/* userid packet */
	if( namelen > 255 )
	{
		pgpAssert( namelen < 0x10000 );
		pgpkeybuf[o++] = PKTBYTE_BUILD(PKTBYTE_USERID, 1);
		pgpkeybuf[o++] = (namelen >> 8) & 0xff;
		pgpkeybuf[o++] = (namelen >> 0) & 0xff;
	} else {
		pgpkeybuf[o++] = PKTBYTE_BUILD(PKTBYTE_USERID, 0);
		pgpkeybuf[o++] = (PGPByte)namelen;
	}
	err = sDecodeName (asnctx, cert, FALSE, pgpkeybuf + o, &namelen);
	if (IsPGPError(err))
		goto error;
	o += namelen;

	/* sig packet */
	pgpkeybuf[o++] = PKTBYTE_BUILD(PKTBYTE_SIG, 1);
	pgpkeybuf[o++] = (siglen >> 8) & 0xff;
	pgpkeybuf[o++] = (siglen >> 0) & 0xff;
	err = sDecodeSig (context, asnctx, cert, SIGSUBSUB_X509_VERSION_LO,
					  pgpkeybuf + o, &siglen);
	if (IsPGPError(err))
		goto error;
	o += siglen;

	pgpAssert (o == pgpkeylen);

	err = pgpImportKeyBinary( context, pgpkeybuf, pgpkeylen, &kdb );
	if( IsPGPError( err ) )
		goto error;

	*keydb = kdb;
	/* Fall through */
error:

	if( IsntNull(pgpkeybuf) )
		PGPFreeData( pgpkeybuf );
	return err;
}


/* Entry point to import a 509 cert from the specified location */
	PGPError
pgpDecodeX509Cert( PGPByte *buf, PGPSize len, PGPContextRef context,
				   PGPKeyDBRef refdb, PGPKeyDBRef *keydb )
{
	PGPASN_Certificate *cert;
	PGPMemoryMgrRef	mgr;
	PGPASN_CONTEXT	asnctx_static, *asnctx = &asnctx_static;
	PGPASN_MemoryMgr asnmem;
	PGPError		err = kPGPError_NoErr;
	
	mgr = PGPPeekContextMemoryMgr( context );
	sSetupASNCONTEXT (mgr, asnctx, &asnmem);

	pgpasn_UnpackCertificate( asnctx, &cert, buf, len, &err );
	CHKASNERR( err )

	err = sDecode509( context, asnctx, cert, refdb, keydb);

	pgpasn_FreeCertificate( asnctx, cert );

error:

	return err;
}

/* Entry point to import a SET OF X509 certs */
	PGPError
pgpDecodeX509CertSet(PGPByte *buf, PGPSize len, PGPContextRef context,
					 PGPKeyDBRef refdb, PGPKeyDBRef *keydb)
{
	PGPASN_Certificates *certs = NULL;
	PGPASN_Certificate *cert;
	PGPMemoryMgrRef	mgr;
	PGPASN_CONTEXT	asnctx_static, *asnctx = &asnctx_static;
	PGPASN_MemoryMgr asnmem;
	PGPKeyDBRef	newkdb = NULL;
	PGPKeyDBRef	tmpkdb = NULL;
	PGPInt32		i;
	PGPError		err = kPGPError_NoErr;

	mgr = PGPPeekContextMemoryMgr( context );
	sSetupASNCONTEXT (mgr, asnctx, &asnmem);
	pgpAssert( IsntNull( keydb ) );
	*keydb = NULL;

	if( IsPGPError( err = PGPNewKeyDB( context, &newkdb ) ) )
		goto error;

	pgpasn_UnpackCertificates( asnctx, &certs, buf, len, &err );
	CHKASNERR( err );

	for (i=0; i<certs->n; ++i) {
		cert = certs->elt[i];
		err = sDecode509( context, asnctx, cert, refdb, &tmpkdb );
		CHKASNERR( err );
		PGPCopyKeys( pgpKeyDBPeekRootSet(tmpkdb), newkdb, NULL );
		PGPFreeKeyDB( tmpkdb );
		tmpkdb = NULL;
	}

error:
	if( IsntNull( certs ) )
		pgpasn_FreeCertificates( asnctx, certs );
	if( IsntNull( tmpkdb ) )
		PGPFreeKeyDB( tmpkdb );

	if( IsntPGPError( err ) )
		*keydb = newkdb;
	else if( IsntNull( newkdb ) )
		PGPFreeKeyDB( newkdb );

	return err;
}


/* Entry point to import a SET OF X509 CRLs.  Creates a new keydb. */
	PGPError
pgpDecodeX509CRLSet( PGPByte *buf, PGPSize len, PGPContextRef context,
					 PGPKeyDBRef refdb, PGPKeyDBRef *keydb )
{
	PGPASN_CertificateRevocationLists *crls = NULL;
	PGPASN_CertificateRevocationList *crl;
	PGPASN_Extension *ext;
	PGPASN_DistributionPointName *dpname;
	PGPASN_GeneralNames *gnames;
	PGPASN_IssuingDistributionPoint *dpt = NULL;
	PGPMemoryMgrRef	mgr;
	PGPASN_CONTEXT	asnctx_static, *asnctx = &asnctx_static;
	PGPASN_MemoryMgr asnmem;
	PGPPubKey *pubkey = NULL;
	PGPByte *pgpcrlbuf = NULL;
	PGPByte *pgpcrlbufptr;
	PGPSize pgpcrllen;
	PGPSize pgpcrlbuflen;
	PGPSize pgpcrlheaderlen;
	PGPByte *crlbuf = NULL;
	PGPSize crllen;
	PGPKeyDBRef	newkdb = NULL;
	PGPKeyDBObj *crlkey = NULL;
	PGPByte *namebuf = NULL;
	PGPSize namebuflen;
	PGPByte *dpoint = NULL;		/* Dynamically allocated */
	PGPByte const *keybuf, *keynamebuf;
	PGPSize keybuflen, keynamebuflen;
	PGPByte pkttype;
	PGPSize dpointlen;
	PGPInt32		j;
	PGPError		err = kPGPError_NoErr;

	pgpAssert( IsntNull( keydb ) );
	*keydb = NULL;

	mgr = PGPPeekContextMemoryMgr( context );
	sSetupASNCONTEXT (mgr, asnctx, &asnmem);

	pgpasn_UnpackCertificateRevocationLists( asnctx, &crls, buf, len, &err );
	CHKASNERR( err );

	/* Only use first CRL because we must create a new keydb 

⌨️ 快捷键说明

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