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

📄 pgpkeylib.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 3 页
字号:
								  (PGPByte *) passphrase, passphraseLength,
								  &outBuf, &outBufLength,
								  &certSet, &certSetLength );
			if( IsPGPError( err ) )
				goto error;
			
			/* Switch input to PKCS-8 data */
			if( mustFreeBuf )
				PGPFreeData( bufPtr );
			bufPtr = outBuf;
			bufLength = outBufLength;
			mustFreeBuf = TRUE;
		}

		/* Now have PKCS-8 data in bufPtr/bufLength */
		
		/* Create empty keyset */
		err = PGPNewKeySet( context, keys );
		if( IsPGPError( err ) )
			goto error;

		/* Process the returned cert set */
		if( IsntNull( certSet ) ) {
			err = pgpDecodeX509CertSet( certSet, certSetLength,
										context, &keys2 );
			if( IsPGPError( err ) )
				goto error;
			err = PGPAddKeys( keys2, *keys );
			if( IsPGPError( err ) )
				goto error;
			PGPFreeKeySet( keys2 );
			keys2 = NULL;
		}

		/* Decode PKCS-8 data */
		err = pgpDecodePCKS8( bufPtr, bufLength, context, &keys2 );
		if( IsPGPError( err ) )
			goto error;

		/* Combine keysets */
		err = PGPAddKeys( keys2, *keys );
		if( IsPGPError( err ) )
			goto error;

		/* Set passphrase on newly imported key */
		if( passphraseLength != 0 ) {
			RingSet const *ringset;
			RingIterator *ringiter;

			ringset = pgpKeyDBRingSet ((*keys)->keyDB);
			ringiter = ringIterCreate(ringset);
			if (ringiter) {
				/* Find key we just imported */
				while (ringIterNextObject (ringiter, 1) == 1) {
					key = ringIterCurrentObject (ringiter, 1);
					if (ringKeyIsSec( ringset, key ) )
						break;
					key = NULL;
				}
				ringIterDestroy (ringiter);
			}
			if( key ) {
				err = pgpDoChangePassphraseInternal( (*keys)->keyDB, ringset,
						key, NULL, NULL, 0, passphrase, passphraseLength,
						FALSE );
				if( IsPGPError( err ) )
					goto error;
				/* Ringset for keydb may be changed by above call */
				ringset = pgpKeyDBRingSet ((*keys)->keyDB);
			}
		}

		err = PGPCommitKeyRingChanges( *keys );
		if( IsPGPError( err ) )
			goto error;

		/* Done */
		goto error;
	}

	if( inputFormat >= kPGPInputFormat_PEMEncodedX509Cert &&
		inputFormat <= kPGPInputFormat_EntrustV1_PEMEncoded )
	{
		/* Need to remove PEM encoding */
		PGPByte *tmpBuf;
		PGPSize tmpBufLength;
		err = pgpRemovePEMEncoding( context, bufPtr, bufLength,
									&tmpBuf, &tmpBufLength );
		if( IsPGPError( err ) )
			goto error;
		/* Replace bufPtr, bufLength with tmp versions (which must be freed) */
		if( mustFreeBuf )
			PGPFreeData( bufPtr );
		mustFreeBuf = TRUE;
		bufPtr = tmpBuf;
		bufLength = tmpBufLength;
	}

	/* Now data is in bufPtr, of length bufLength */
	err = pgpDecodeX509Cert( bufPtr, bufLength,  context, keys );

error:
	if( mustFreeBuf )
		PGPFreeData( bufPtr );
	if( IsntNull( certSet ) )
		PGPFreeData( certSet );
	if( IsntNull( keys2 ) )
		PGPFreeKeySet( keys2 );

	return err;
}



static const PGPOptionType impkeyOptionSet[] = {
	kPGPOptionType_InputFileRef,
	kPGPOptionType_LocalEncoding,
	kPGPOptionType_InputBuffer,
	kPGPOptionType_EventHandler,
	kPGPOptionType_SendNullEvents,
	kPGPOptionType_InputFormat,
	kPGPOptionType_Passphrase,
	kPGPOptionType_X509Encoding
};

/* Frees optionList, unlike most other internal functions */
	PGPError
pgpImportKeySetInternal (PGPContextRef context, PGPKeySetRef *keys,
	PGPOptionListRef optionList)
{
	PGPError		err = kPGPError_NoErr;
	PGPKeySetRef	keyset;
	PGPInputFormat	inputFormat;
	PGPUInt32		fDo509;

	if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
						impkeyOptionSet, elemsof( impkeyOptionSet ) ) ) )
		return err;

	pgpAssertAddrValid( keys, PGPKeySetRef );
	*keys = NULL;
	
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_X509Encoding, FALSE,
						 "%d", &fDo509 ) ) )
		goto error;

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_InputFormat, FALSE,
						 "%d", &inputFormat ) ) )
		goto error;

	if( fDo509 || inputFormat >= kPGPInputFormat_X509DataInPKCS7 ) {
		err = sImportX509Certificate( context, keys, inputFormat, optionList );
		PGPFreeOptionList( optionList );
		goto error;
	}

	if( IsPGPError( err = PGPNewKeySet( context, &keyset ) ) )
		goto error;

	if( IsPGPError( err = PGPDecode( context, optionList,
									 PGPODiscardOutput(context, TRUE),
									 PGPOImportKeysTo(context, keyset),
									 PGPOLastOption(context) ) ) ) {
		PGPFreeKeySet( keyset );
		goto error;
	}
	*keys = keyset;
	
error:
	return err;
}


/*
 * Handle X509 based export formats.
 * Key is the top level key we are exporting; ringset controls which
 * sub objects if any we should look at
 */
static PGPError
sExportKeyX509 (
	PGPContextRef		context,
	PGPKeyRef		   key,
	RingSet const	   *ringset,
	PGPExportFormat		exportFormat,
	PGPOptionListRef	optionList
	)
{
	PGPEnv			   *env;
	PGPError			err = kPGPError_NoErr;
	PGPUInt32			fAppendOutput;
	PGPPipeline			*head = NULL, **tail = &head;
	PFLConstFileSpecRef	 outFileRef;
	PGPFile				*pfout;
	PGPByte				*outBufPtr;
	PGPByte			   **outBufPtrPtr;
	PGPSize				 outBufMaxLength;
	PGPSize				*outBufUsedLength;
	PGPPipeline			*outPipe;
	PGPByte				*buf = NULL;
	PGPSize				 bufLength = 0;
	PGPBoolean			 freeBuf = FALSE;
	PGPMemoryMgrRef		 mgr;
	void				*vFormatData;
	PGPAttributeValue	*formatData;
	PGPAttributeValue	*formatDataCopy = NULL;
	PGPAttributeValue	*newAV;
	PGPSize				 formatDataLength;
	PGPOptionListRef	 passphrase = NULL;
	PGPByte				*dpoint = NULL;
	PGPSize				 dpointlen = 0;
	static char			 s_pgpkeycr[] = "PGPKeyCreation=0x";
	static PGPByte		 s_pgpx509keycr [] = {
		0x30, 0x0e,		/* SEQUENCE */
			/* PGP Extension OID */
			/* (1 3 6 1 4 1 3401 8 1 1) */
			0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x9a, 0x49, 0x08,
					0x01, 0x01,
			0x04, 0x00	/* Octet string */
			/* Value as UTCTime value goes here */
	};
	char				 pgpkeycr[40];	/* big enough for either case */

	env = pgpContextGetEnvironment( context );
	mgr = PGPGetContextMemoryMgr( context );

	if (exportFormat == kPGPExportFormat_X509Cert) {
		/* Find the right X509 sig, somehow */
		RingObject *obj = NULL;
		RingObject *bestsig = NULL;
		RingIterator *ringiter;
		PGPInt32 level;

		ringiter = ringIterCreate (ringset);
		if( IsNull( ringiter ) ) {
			err = ringSetError( ringset )->error;
			goto error;
		}
		while ((level = ringIterNextObjectAnywhere(ringiter)) > 0) {
			obj = ringIterCurrentObject (ringiter, level);
			if (ringObjectType(obj) == RINGTYPE_SIG &&
				ringSigIsX509 (ringset, obj)) {
				RingObject *signer = ringSigMaker (ringset, obj, ringset);
				/* Use a self-sig if exists, else use first sig */
				if (signer == ringIterCurrentObject (ringiter, 1)) {
					bestsig = obj;
				} else if (bestsig == NULL) {
					bestsig = obj;
				}
			}
		}
		ringIterDestroy( ringiter );
		if (bestsig != NULL) {
			buf = ringSigX509Certificate( ringset, bestsig, &bufLength );
		}
	} else if (exportFormat >= kPGPExportFormat_X509GetCRL) {
		time_t curtime = PGPGetStdTimeFromPGPTime( PGPGetTime() );

		/* If InputBuffer is specified, it is CRL distribution point */
		if( IsPGPError( err = pgpFindOptionArgs( optionList,
							 kPGPOptionType_InputBuffer, FALSE,
							 "%p%l", &dpoint, &dpointlen ) ) )
			goto error;

		err = X509CreateCRLRequest ( context, key, dpoint, dpointlen,
				exportFormat, curtime, &buf, &bufLength );
		if( IsPGPError( err ) )
			goto error;

		freeBuf = TRUE;
	} else if (exportFormat >= kPGPExportFormat_X509GetCertInitial) {
		/* Structure for now will be a fixed empty sequence */
		static PGPByte emptysequence[] = {0x30, 0x00};
		buf = emptysequence;
		bufLength = sizeof(emptysequence);
		freeBuf = FALSE;
	} else if (exportFormat >= kPGPExportFormat_X509CertReq) {
		PGPOption passop;

		if( IsPGPError( err = pgpSearchOptionSingle( optionList,
									kPGPOptionType_Passphrase, &passop ) ) )
			goto error;
		if( IsntOp( passop ) ) {
			if( IsPGPError( err = pgpSearchOptionSingle( optionList,
										kPGPOptionType_Passkey, &passop ) ) )
				goto error;
		}

		if( IsOp( passop ) ) {
			PGPOption passopcopy;
			pgpCopyOption( context, &passop, &passopcopy );
			passphrase = pgpNewOneOptionList( context, &passopcopy );
		}

		if( IsPGPError( err = pgpFindOptionArgs( optionList,
							 kPGPOptionType_AttributeValue, FALSE,
							 "%p%l",
							 &vFormatData, &formatDataLength ) ) )
			goto error;
		formatData = vFormatData;
		formatDataLength /= sizeof(PGPAttributeValue);
		formatDataCopy = PGPNewData( mgr,
					(formatDataLength+1)*sizeof(PGPAttributeValue), 0 );
		if( IsNull( formatDataCopy ) ) {
			err = kPGPError_OutOfMemory;
			goto error;
		}
		pgpCopyMemory( formatData, formatDataCopy+1,
					   formatDataLength*sizeof(PGPAttributeValue) );
		newAV = formatDataCopy;

		/* Add "description" or extension field to hold keycreation data */
		if( exportFormat == kPGPExportFormat_VerisignV1_CertReq )
		{
			/* Use a new extension */
			PGPUInt32 kcr = ringKeyCreation (ringset, key->key);
			PGPByte *px = (PGPByte *)pgpkeycr + sizeof(s_pgpx509keycr);
			PGPSize tlen;
			char tbuf[PGPX509TIMELEN+1];

			tlen = pgpTimeToX509Time( kcr, tbuf );
			pgpCopyMemory( s_pgpx509keycr, pgpkeycr, sizeof(s_pgpx509keycr) );
			pgpkeycr[1] += tlen + 2;
			pgpkeycr[sizeof(s_pgpx509keycr)-1] += tlen + 2;
			/* Choose GeneralizedTime vs UTCTime tag */
			*px++ = (tlen == PGPX509TIMELEN) ? 24 : 23;
			*px++ =  tlen;
			pgpCopyMemory( tbuf, px, tlen );
			newAV->attribute = kPGPAVAttribute_CertificateExtension;
			newAV->size = sizeof(s_pgpx509keycr) + 2 + tlen;
			newAV->value.pointervalue = pgpkeycr;
			newAV->unused = 0;
		}
		else
		{
			/* Use description field in subject name */
			pgpCopyMemory( s_pgpkeycr, pgpkeycr, sizeof(s_pgpkeycr)-1 );
			sprintf ( pgpkeycr+sizeof(s_pgpkeycr)-1, "%08x",
					  ringKeyCreation (ringset, key->key) );
			newAV->attribute = kPGPAVAttribute_Description;
			newAV->size = sizeof(s_pgpkeycr)-1 + 8;
			newAV->value.pointervalue = pgpkeycr;
			newAV->unused = 0;
		}

		err = X509CreateCertificateRequest ( context, key, exportFormat,
				formatDataCopy, formatDataLength+1, passphrase,
				&buf, &bufLength );
		passphrase = NULL;
		PGPFreeData( formatDataCopy );
		formatDataCopy = NULL;
		if( IsPGPError( err ) )
			goto error;

		freeBuf = TRUE;

	} else {
		pgpAssert (0);
	}

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_AppendOutput, FALSE,
						 "%d", &fAppendOutput ) ) )
		goto error;

	err = pgpSetupOutputPipeline( context, optionList,
							env, FALSE, FALSE, FALSE,
							(PGPBoolean)fAppendOutput, TRUE,
							&tail, &outFileRef, &pfout,
							&outBufPtr, &outBufPtrPtr,
							&outBufMaxLength, &outBufUsedLength,
							&outPipe );
	
	if( IsPGPError( err ) )
		goto error;

	err = pgpPumpMem( head, buf, bufLength, NULL, NULL );
	if( IsPGPError( err ) )
		goto error;

	if( outPipe ) {
		if( IsntNull( outBufPtrPtr ) ) {
			/* Dynamically allocated buffer - tell user size & position */
			if( IsPGPError( err = pgpGetVariableMemOutput( outPipe,
							outBufMaxLength, outBufPtrPtr,
							outBufUsedLength ) ) )
				goto error;
		} else {
			/* Fixed size buffer - tell user actual size used */
			pgpAssert( IsntNull( outBufPtr ) );
			if( IsPGPError( err = pgpGetMemOutput( outPipe,
						outBufMaxLength, outBufUsedLength ) ) )
				goto error;
		}
	}

	head->teardown( head );
	head = NULL;

error:

	if( IsntNull( passphrase ) )
		pgpFreeOptionList( passphrase );
	if( IsntNull( formatDataCopy ) )
		PGPFreeData( formatDataCopy );
	if( freeBuf && IsntNull( buf ) )
		PGPFreeData( buf );
	if( IsntNull( head ) )
		head->teardown( head );

	return err;
}




/* 
 * Filter function for extraction.  Remove any secret objects.
 * If addarrs is true, also add any additional decryption key objects to
 * the set.  This will cause ADK's to be extracted with the keys
 * that use them.
 * XXX AUTOMATIC ADK EXTRACTION DOES NOT YET WORK.
 * There is no RingSet available in which
 * to look for ADK's.  The export functions typically are called with
 * just a memory RingSet.  We need to add versions which take an extra
 * PGPKeySet to flag that ADK's should be looked for there.
 */
static RingSet *
filterPubRingSet (RingSet const *rset,
	PGPBoolean exportmastersecrets, PGPBoolean exportsubsecrets,
	PGPBoolean addarks, PGPBoolean includeattributes)
{
	RingSet		   *rsetnew;	/* Set of recipients */
	RingSet		   *adkeyset;	/* Set of additional decryption keys */
	RingIterator   *riter;		/* Iterator over adding sets */
	int				level;
	PGPBoolean		exportsecrets = exportmastersecrets;
	PGPError		err	= kPGPError_NoErr;

	if (!rset)
		return NULL;
	adkeyset = NULL;
	rsetnew = ringSetCreate (ringSetPool (rset));
	if (!rsetnew)
		return NULL;
	riter = ringIterCreate (rset);
	if (!riter) {
		ringSetDestroy (rsetnew);
		return NULL;
	}
	/* 
	 * Copy objects in PGPKeySet to rsetnew except secret objects.
	 * At the same time, accumulate any additional decryption keys into
	 * adkeyset.
	 */
	while ((level = ringIterNextObjectAnywhere(riter)) > 0) {
		RingObject *obj = ringIterCurrentObject (riter, level);
		if (ringObjectType(obj) == RINGTYPE_KEY) {
			exportsecrets = ringKeyIsSubkey(rset, obj) ? exportsubsecrets :
														 exportmastersecrets;
		}
		/* Possibly skip secret objects */
		if (!exportsecrets && ringObjectType (obj) == RINGTYPE_SEC)
			continue;
		/* Skip signatures if exporting secret keys */
		if (exportsecrets && ringObjectType (obj) == RINGTYPE_SIG)
			continue;
		if (!includeattributes && ringObjectType (obj) == RINGTYPE_NAME
			&& ringNameIsAttribute (rset, obj))
			continue;
		if (!includeattributes && ringObjectType (obj) == RINGTYPE_SIG) {
			RingObject *parent = ringIterCurrentObject (riter, level-1);
			if (ringObjectType(parent) == RINGTYPE_NAME &&
				ringNameIsAttribute (rset, parent))
				continue;
		}
		ringSetAddObject (rsetnew, obj);
		/* For key objects, look for additional decryption keys */
		if (addarks && ringObjectType (obj) == RINGTYPE_KEY)
		{
			RingObject	   *rkey;		/* Decryption key */
			unsigned		nrkeys;		/* Number of decryption keys */
			
			if (ringKeyAdditionalRecipientRequestKey (obj, rset, 0, NULL,
										NULL, NULL, &nrkeys, &err) != NULL )
			{
				/* Add to special set for additional decryption keys */
				while (nrkeys-- > 0)
				{
					rkey = ringKeyAdditionalRecipientRequestKey (obj, rset, 0,
											NULL, NULL, NULL, &nrkeys, &err);
					pgpAssert (rkey);
					if (!adkeyset)
					{
						adkeyset = ringSetCreate (ringSetPool(rset));

⌨️ 快捷键说明

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