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

📄 pgpkeyio.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 4 页
字号:
            kPGPOptionType_TokenKeyContainer, FALSE,
            "%p", &contOutDesc ) ) )
        goto error;

    /* Load onto the token by calling backend */
    {
        PGPKeyInfo *kinfo = pgpKeyToKeyInfo( key );
        PGPKeyDBObjRef userID;
		PGPByte *pUserID;
		PGPSize pUserID_len;
        const PGPKeyDBObjProperty prop = kPGPUserIDProperty_CommonName; 
            /* kPGPUserIDProperty_Name is too long and may not 
               be appropriate for other viewers. */

		PGPGetPrimaryUserID( key, &userID );
		pgpGetUserIDAllocatedStringBuffer( userID, prop,
											   &pUserID, &pUserID_len );

        err = pgpTokenImportX509_back( context, kinfo->keyID, 
                   pUserID,      pUserID_len, 
                   buf,          bufLength, 
                   password,     passwordLength );

        PGPFreeData( pUserID );


		if( (IsntPGPError(err) || err == kPGPError_SmartCardX509Exists) &&
			contOutDesc )  
        {
            err = pgpTokenGetKeyContainer_back( 
                context, kinfo->keyID, 
				password, passwordLength,
                (PGPByte **)contOutDesc->buffer, contOutDesc->actualBufferSize);
        }
    }


error:
    return err;
}


/*
 * 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 (PGPKeySet *keyset, PGPOptionListRef optionList)
{
	PGPContextRef		context;
	PGPKeyDBRef			kdb;
	PGPUInt32			fExportSecrets;
	PGPUInt32			fExportSubSecrets;
	PGPBoolean			fExportAttributes;
	PGPBoolean			fExportFormat;

    /* For export of key or X509 cert to the token */
    PGPBoolean			fOutputToken;

	PGPByte				*buf;
	PGPSize				bufSize;
	PGPSize				bufSizeRead;
	PGPFile				*pfile;
	PGPOptionListRef	optList;
	PGPExportFormat		exportFormat = kPGPExportFormat_Complete;
	PGPUInt32			wExportFormat;
	PGPBoolean			armorop;
	PGPUInt32			nkeys;
	PGPError			err = kPGPError_NoErr;

	pgpAssert( pgpKeySetIsValid( keyset ) );
	kdb = keyset->keyDB;
	context = PGPPeekKeyDBContext( kdb );

	buf = NULL;
	pfile = 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;

	/* Clear exportSecrets flags if doing a single non-secret key */
	if( (PGPCountKeys(keyset, &nkeys), nkeys == 1) &&
		!pgpKeyIsSec( pgpFirstKeyInKeySet( keyset ) ) )
	{
		fExportSecrets = FALSE;
		fExportSubSecrets = FALSE;
	}

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

	if (fExportFormat)
		exportFormat = (PGPExportFormat) wExportFormat;

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						kPGPOptionType_OutputToken, FALSE,
						 "%b", &fOutputToken ) ) )
		goto error;

    /* Put private key on the token */
    if( fOutputToken && exportFormat == kPGPExportFormat_Complete )  {
        err = pgpCopyKeyToToken( keyset, optionList );
        if( IsntPGPError(err) )
            err = sExportKeyContainer( keyset, FALSE, optionList );
        goto error;
    }

	/* Handle X509 export formats */
	if (exportFormat == kPGPExportFormat_X509Cert ||
		exportFormat >= kPGPExportFormat_X509CertReq) {
		PGPKeyDBObjRef key;
		if( IsNull( key = pgpFirstKeyInKeySet( keyset ) ) )
			goto error;
        if( fOutputToken )  {
            /* Export X509 certificate to the token */
            err = sExportKeyX509ToToken( keyset, optionList );

            /* Export key container, if specified */
            if( IsntPGPError(err) )
                err = sExportKeyContainer( keyset, FALSE, optionList );
        }
        else
		    err = sExportKeyX509 (key, keyset, exportFormat, optionList);
		goto error;
	}

    /* Handle optional key container */
    if( fOutputToken && IsntPGPError(err) && 
        exportFormat == kPGPExportFormat_TokenKeyContainer )  
    {
        /* Export key container, must be specified */
        err = sExportKeyContainer( keyset, TRUE, optionList );
        goto error;
    }

	fExportAttributes = (exportFormat > kPGPExportFormat_Basic);

	/* Output public or private portion */

	/* 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 = pgpExportToPGPFile( keyset, pfile,
								(PGPBoolean)fExportSecrets,
								(PGPBoolean)(fExportSubSecrets|fExportSecrets),
								fExportAttributes, TRUE /*includepubkey*/ ) ) )
		goto error;

	/* Read data we just wrote (hopefully smaller than 2 GB -wjb) */
	bufSize = (PGPSize)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 ) {

		/* 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 = pgpExportToPGPFile( keyset, pfile, FALSE, FALSE,
										fExportAttributes, TRUE /*includepubkey*/ ) ) )
			goto error;

		/* Read data we just wrote (hopefully smaller than 2 GB -wjb)*/
		bufSize = (PGPSize)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( 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_CachePassphrase,
	kPGPOptionType_AttributeValue,
	kPGPOptionType_InputBuffer
};



/* Frees optionList, unlike most other internal functions. */
PGPError
pgpExportKeySetInternal (PGPKeySet *keys, PGPOptionListRef optionList)
{
	PGPError			err = kPGPError_NoErr;

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

	err = sExportKeySetInternal (keys, optionList );

	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_ExportKeyDBObj,
	/* Used for cert requests */
	kPGPOptionType_Passphrase,
	kPGPOptionType_Passkey,
	kPGPOptionType_CachePassphrase,
	kPGPOptionType_AttributeValue,
	kPGPOptionType_InputBuffer,
    /* Used for Token operation */
    kPGPOptionType_OutputToken,
    kPGPOptionType_TokenKeyContainer,
    kPGPOptionType_TokenKeyContainerSuggested
};



/*
 * 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)
{
	PGPKeyDBObj		   *obj;
	PGPKeySet		   *keys = NULL;
	PGPBoolean			fExportKeyDBObjRef;
	PGPBoolean			fExportKeySetRef;
	PGPBoolean			fDeleteKeys = FALSE;
	void			   *wExportKeyDBObjRef;
	void			   *wExportKeySetRef;
	PGPInt32			successes = 0;
	PGPError			err = kPGPError_NoErr;

	(void) context;

	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_ExportKeyDBObj, FALSE,
						 "%b%d", &fExportKeyDBObjRef, &wExportKeyDBObjRef ) ) )
		goto error;
	if (fExportKeyDBObjRef)
		++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 keyset we will export */

	/* Handle the different cases */
	if (fExportKeySetRef) {
		keys = (PGPKeySet *) wExportKeySetRef;
	} else {
		obj = (PGPKeyDBObj *) wExportKeyDBObjRef;
		if( IsPGPError( err = PGPNewOneKeySet( obj, &keys ) ) )
			goto error;
		fDeleteKeys = TRUE;
	}

	if( IsPGPError( err = sExportKeySetInternal (keys, optionList ) ) )
		goto error;

	/* Fall through */
error:
	if( fDeleteKeys && IsntNull( keys ) )
		PGPFreeKeySet( keys );

	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 + -