📄 pgpkeyio.c
字号:
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 + -