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

📄 pgpkeylib.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 3 页
字号:
						if (!adkeyset)
						{
							ringIterDestroy (riter);
							ringSetDestroy (rsetnew);
							return NULL;
						}
					}
					ringSetAddObjectChildren (adkeyset, rset, rkey);
				}
			}
		}
	}
	ringIterDestroy (riter);

	/* Last, merge adkeyset into rsetnew, also stripping secrets */
	if (adkeyset) {
		ringSetFreeze (adkeyset);
		riter = ringIterCreate (adkeyset);
		if (!riter) {
			ringSetDestroy (adkeyset);
			ringSetDestroy (rsetnew);
			return NULL;
		}
		/* Loop over rsetnew iterator, adding non-secret objects */
		/* We will always strip ADK secrets, he can export those explicitly */
		while ((level = ringIterNextObjectAnywhere(riter)) > 0) {
			RingObject *obj = ringIterCurrentObject (riter, level);
			if (ringObjectType (obj) == RINGTYPE_SEC)
				continue;
			ringSetAddObject (rsetnew, obj);
		}
		ringIterDestroy (riter);
		ringSetDestroy (adkeyset);
	}

	/* Return new set in frozen form */
	ringSetFreeze (rsetnew);
	return rsetnew;
}



#if PGP_MACINTOSH
#pragma global_optimizer on
#endif


/*
 * Frees optionList, unlike most other internal functions.  rset
 * defines the exact set to be exported; key is the first key in the
 * set.
 */
static PGPError
sExportKeySetInternal (PGPContextRef context, PGPKeyRef key,
	RingSet const *rset, PGPOptionListRef optionList)
{
	PGPUInt32			fExportSecrets;
	PGPUInt32			fExportSubSecrets;
	PGPBoolean			fExportAttributes;
	PGPBoolean			fExportFormat;
	PGPByte				*buf;
	PGPSize				bufSize;
	PGPSize				bufSizeRead;
	PGPFile				*pfile;
	RingSet const		*rsetpub;
	PGPOptionListRef	optList;
	PGPExportFormat		exportFormat = kPGPExportFormat_Complete;
	PGPUInt32			wExportFormat;
	PGPBoolean			armorop;
	PGPError			err = kPGPError_NoErr;

	pgpAssert( pgpContextIsValid( context ) );

	buf = NULL;
	pfile = NULL;
	rsetpub = NULL;
	optList = NULL;

	/* Read optional options */
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_ExportPrivateKeys, FALSE,
						 "%d", &fExportSecrets ) ) )
		goto error;

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

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_ExportFormat, FALSE,
						 "%b%d", &fExportFormat, &wExportFormat ) ) )
		goto error;

	if (fExportFormat)
		exportFormat = (PGPExportFormat) wExportFormat;

	/* Handle X509 export formats */
	if (exportFormat == kPGPExportFormat_X509Cert ||
		exportFormat >= kPGPExportFormat_X509CertReq) {
		err = sExportKeyX509 (context, key, rset,
							  exportFormat, optionList);
		goto error;
	}

	fExportAttributes = (exportFormat > kPGPExportFormat_Basic);

	/* Output public or private portion */
	rsetpub = filterPubRingSet (rset, (PGPBoolean)fExportSecrets,
								(PGPBoolean)(fExportSubSecrets|fExportSecrets),
								FALSE, fExportAttributes);
	if (!rsetpub) {
		err = kPGPError_OutOfMemory;
		goto error;
	}

	/* Create memory buffer to write to */
	pfile = pgpFileMemOpen( context, NULL, 0 );
	if( IsNull( pfile ) ) {
		err = kPGPError_OutOfMemory;
		goto error;
	}

	/* Output data to memory buffer */
	if( IsPGPError( err = ringSetWrite (rsetpub, pfile, NULL, PGPVERSION_3,
										0) ) )
		goto error;
	ringSetDestroy( (RingSet *)rsetpub );
	rsetpub = NULL;

	/* Read data we just wrote */
	bufSize = pgpFileTell (pfile );
	buf = (PGPByte *)pgpContextMemAlloc( context, bufSize, 0 );
	if( IsNull( buf ) ) {
		err = kPGPError_OutOfMemory;
		goto error;
	}
	(void)pgpFileSeek( pfile, 0, SEEK_SET );
	bufSizeRead = pgpFileRead( buf, bufSize, pfile );
	pgpAssert( bufSizeRead == bufSize );
	pgpFileClose( pfile );
	pfile = NULL;

	/* Do ascii armoring */
	/* If user specified an ascii armor option, use his, else use TRUE */
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						kPGPOptionType_ArmorOutput, FALSE,
						"%b", &armorop ) ) )
		goto error;

	/* This next call frees optionList */
	if( IsPGPError( err = PGPBuildOptionList( context, &optList, optionList, 
									 (armorop ?
									  PGPONullOption(context) :
									  PGPOArmorOutput(context, TRUE)),
									 PGPORawPGPInput(context, TRUE),
									 PGPOCompression(context, FALSE),
									 PGPOLastOption(context) ) ) )
		goto error;
	optionList = NULL;

	if( IsPGPError( err = PGPEncode( context, optList,
									 PGPOInputBuffer(context, buf, bufSize),
									 PGPOLastOption(context) ) ) )
		goto error;

	pgpContextMemFree( context, buf );
	buf = NULL;

	/*
	 * If exporting private keys, append public keys to the buffer.
	 * We can't export them both together, as we end up with an output
	 * which has private keys followed by names and sigs.  This can not
	 * be safely imported, because of the "version bug".  The private key
	 * may have the incorrect version.  So we instead output the public
	 * part with names and sigs, after the private part with private keys
	 * and names.
	 */
	if( fExportSecrets || fExportSubSecrets ) {

		/* Get ringset for public portion */
		rsetpub = filterPubRingSet (rset, FALSE, FALSE, FALSE,
									fExportAttributes);
		if (!rsetpub) {
			err = kPGPError_OutOfMemory;
			goto error;
		}

		/* Create memory buffer to write to */
		pfile = pgpFileMemOpen( context, NULL, 0 );
		if( IsNull( pfile ) ) {
			err = kPGPError_OutOfMemory;
			goto error;
		}

		/* Output data to memory buffer */
		if( IsPGPError( err = ringSetWrite (rsetpub, pfile, NULL,
											PGPVERSION_3, 0) ) )
			goto error;
		ringSetDestroy( (RingSet *)rsetpub );
		rsetpub = NULL;

		/* Read data we just wrote */
		bufSize = pgpFileTell (pfile );
		buf = (PGPByte *)pgpContextMemAlloc( context, bufSize, 0 );
		if( IsNull( buf ) ) {
			err = kPGPError_OutOfMemory;
			goto error;
		}
		(void)pgpFileSeek( pfile, 0, SEEK_SET );
		bufSizeRead = pgpFileRead( buf, bufSize, pfile );
		pgpAssert( bufSizeRead == bufSize );
		pgpFileClose( pfile );
		pfile = NULL;

		/* Do ascii armoring, append to existing output */
		PGPAppendOptionList( optList,
							 PGPOAppendOutput(context, TRUE),
							 PGPOLastOption(context) );
		if( IsPGPError( err = PGPEncode( context, optList,
									PGPOInputBuffer(context, buf, bufSize),
									PGPOLastOption(context) ) ) )
			goto error;

		pgpContextMemFree( context, buf );
		buf = NULL;
	}

	err = kPGPError_NoErr;

	/* Fall through */
error:
	if( IsntNull( optList ) )
		PGPFreeOptionList( optList );
	if( IsntNull( optionList ) )
		PGPFreeOptionList( optionList );
	if( IsntNull( pfile ) )
		pgpFileClose( pfile );
	if( IsntNull( rsetpub ) )
		ringSetDestroy ( (RingSet *)rsetpub);
	if( IsntNull( buf ) )
		pgpContextMemFree( context, buf );
	return err;
}

#if PGP_MACINTOSH
#pragma global_optimizer reset
#endif


static const PGPOptionType expkeyOptionSet[] = {
	kPGPOptionType_ExportPrivateKeys,
	kPGPOptionType_ExportPrivateSubkeys,
	kPGPOptionType_ExportFormat,
	kPGPOptionType_OutputFileRef,
	kPGPOptionType_OutputBuffer,
	kPGPOptionType_OutputAllocatedBuffer,
	kPGPOptionType_DiscardOutput,
	kPGPOptionType_ArmorOutput,
	kPGPOptionType_CommentString,
	kPGPOptionType_VersionString,
	kPGPOptionType_EventHandler,
	kPGPOptionType_SendNullEvents,
	kPGPOptionType_OutputLineEndType,
	kPGPOptionType_OutputFormat,
	/* Used for cert requests */
	kPGPOptionType_Passphrase,
	kPGPOptionType_Passkey,
	kPGPOptionType_AttributeValue,
	kPGPOptionType_InputBuffer
};



/* Frees optionList, unlike most other internal functions. */
PGPError
pgpExportKeySetInternal (PGPKeySet *keys, PGPOptionListRef optionList)
{
	RingSet const		*rset = NULL;
	PGPContextRef		context;
	PGPKeyRef			key;
	PGPKeyListRef		klist;
	PGPKeyIterRef		kiter;
	PGPError			err = kPGPError_NoErr;

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

	context = PGPGetKeySetContext( keys );

	/* Get ringset corresponding to keyset */
	if( IsPGPError( err = pgpKeySetRingSet( keys, TRUE, &rset ) ) )
		goto error;

	/* Extract first key from keyset */
	if( IsPGPError( err = PGPOrderKeySet( keys, kPGPAnyOrdering, &klist ) ) )
		goto error;
	if( IsPGPError( err = PGPNewKeyIter( klist, &kiter ) ) ) {
		PGPFreeKeyList( klist );
		goto error;
	}
	err = PGPKeyIterNext( kiter, &key );
	PGPFreeKeyIter( kiter );
	PGPFreeKeyList( klist );
	if( IsPGPError( err ) )
		goto error;


	if( IsPGPError( err = sExportKeySetInternal (context, key, rset,
												 optionList ) ) )
		goto error;

	/* Fall through */
error:
	if( IsntNull( rset ) )
		ringSetDestroy ( (RingSet *)rset);

	return err;

}


static const PGPOptionType expOptionSet[] = {
	kPGPOptionType_ExportPrivateKeys,
	kPGPOptionType_ExportPrivateSubkeys,
	kPGPOptionType_ExportFormat,
	kPGPOptionType_OutputFileRef,
	kPGPOptionType_OutputBuffer,
	kPGPOptionType_OutputAllocatedBuffer,
	kPGPOptionType_DiscardOutput,
	kPGPOptionType_ArmorOutput,
	kPGPOptionType_CommentString,
	kPGPOptionType_VersionString,
	kPGPOptionType_EventHandler,
	kPGPOptionType_SendNullEvents,
	kPGPOptionType_OutputLineEndType,
	kPGPOptionType_OutputFormat,
	kPGPOptionType_ExportKeySet,
	kPGPOptionType_ExportKey,
	kPGPOptionType_ExportUserID,
	kPGPOptionType_ExportSig,
	/* Used for cert requests */
	kPGPOptionType_Passphrase,
	kPGPOptionType_Passkey,
	kPGPOptionType_AttributeValue,
	kPGPOptionType_InputBuffer
};



/*
 * Frees optionList, unlike most other internal functions.  This is
 * like exportkeyset, but it allows a single userid or sig to be
 * specified.  We only export that object, plus its parent object(s)
 * and all its children.  This is especially convenient when exporting
 * a particular X.509 certificate.
 */
PGPError
pgpExportInternal (PGPContextRef context, PGPOptionListRef optionList)
{
	PGPKeyRef			key;
	PGPUserIDRef		userid;
	PGPSigRef			sig;
	RingPool	   	   *pool;
	RingSet			   *rset = NULL;
	PGPKeySet		   *keys;
	RingSet const	   *dbrset;
	PGPBoolean			fExportKeyRef, fExportUserIDRef, fExportSigRef;
	PGPBoolean			fExportKeySetRef;
	void			   *wExportKeyRef, *wExportUserIDRef, *wExportSigRef;
	void			   *wExportKeySetRef;
	PGPInt32			successes = 0;
	PGPError			err = kPGPError_NoErr;

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


	/* See if we have a target key/name/sig to export */

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_ExportKeySet, FALSE,
						 "%b%d", &fExportKeySetRef, &wExportKeySetRef ) ) )
		goto error;
	if (fExportKeySetRef)
		++successes;
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_ExportKey, FALSE,
						 "%b%d", &fExportKeyRef, &wExportKeyRef ) ) )
		goto error;
	if (fExportKeyRef)
		++successes;
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_ExportUserID, FALSE,
						 "%b%d", &fExportUserIDRef, &wExportUserIDRef ) ) )
		goto error;
	if (fExportUserIDRef)
		++successes;
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_ExportSig, FALSE,
						 "%b%d", &fExportSigRef, &wExportSigRef ) ) )
		goto error;
	if (fExportSigRef)
		++successes;
	
	if (successes > 1) {
		pgpDebugMsg( "too many key object selection options for PGPExport" );
		err = kPGPError_BadParams;
		goto error;
	} else if (successes == 0) {
		pgpDebugMsg( "no key object selection options for PGPExport" );
		err = kPGPError_BadParams;
		goto error;
	}

	/* Create ringset we will export */
	pool = pgpContextGetRingPool( context );
	pgpAssert( IsntNull( pool ) );

	/* Handle the different cases */
	if (fExportKeySetRef) {
		PGPKeyListRef		klist;
		PGPKeyIterRef		kiter;
		keys = (PGPKeySet *) wExportKeySetRef;
		/* Extract first key from keyset */
		if( IsPGPError( err = PGPOrderKeySet( keys, kPGPAnyOrdering,
											  &klist ) ) )
			goto error;
		if( IsPGPError( err = PGPNewKeyIter( klist, &kiter ) ) ) {
			PGPFreeKeyList( klist );
			goto error;
		}
		err = PGPKeyIterNext( kiter, &key );
		PGPFreeKeyIter( kiter );
		PGPFreeKeyList( klist );
		if( IsPGPError( err ) )
			goto error;
		if( IsPGPError( err = pgpKeySetRingSet( keys, TRUE,
												(RingSet const **)&rset ) ) )
			goto error;
	} else {
		RingObject *obj = NULL;
		rset = ringSetCreate (pool);
		if( IsNull( rset ) ) {
			err = ringPoolError(pool)->error;
			goto error;
		}
		if (fExportKeyRef) {
			key = (PGPKey *) wExportKeyRef;
			obj = key->key;
		} else if (fExportUserIDRef) {
			userid = (PGPUserID *) wExportUserIDRef;
			key = userid->key;
			obj = userid->userID;
		} else if (fExportSigRef) {
			sig = (PGPSig *) wExportSigRef;
			if (sig->type == keycert) {
				key = sig->up.key;
			} else {
				key = sig->up.userID->key;
			}
			obj = sig->cert;
		} else {
			pgpAssert(0);
		}
		pgpAssert( IsntNull( obj ) );
		dbrset = pgpKeyDBRingSet (key->keyDB);
		ringSetAddObjectChildren( rset, dbrset, obj );
		ringSetFreeze( rset );
	}

	if( IsPGPError( err = sExportKeySetInternal (context, key, rset,
												 optionList ) ) )
		goto error;

	/* Fall through */
error:
	if( IsntNull( rset ) )
		ringSetDestroy ( (RingSet *)rset);

	return err;
}


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

⌨️ 快捷键说明

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