📄 pgpkeyio.c
字号:
mgr = PGPPeekContextMemoryMgr( context );
/* Exactly one of targetkey or pkcs10Buffer must be null */
(void)pgpSetupInputToBuffer( context, optionList, &pkcs10Buffer,
&pkcs10BufferSize, &mustFreeBuf );
if( IsNull( targetkey) == IsNull( pkcs10Buffer ) )
return kPGPError_BadParams;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_CreationDate, FALSE,
"%T", &creationTime ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Expiration, FALSE,
"%d", &expirationDays ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passphrase, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
goto error;
if (IsNull( passphrase )) {
hashedPhrase = TRUE;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passkey, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
goto error;
}
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_AttributeValue, TRUE,
"%p%l",
&vFormatData, &formatDataLength ) ) )
goto error;
formatData = vFormatData;
formatDataCopy = PGPNewData( mgr,
formatDataLength+sizeof(PGPAttributeValue), 0 );
if( IsNull( formatDataCopy ) ) {
err = kPGPError_OutOfMemory;
goto error;
}
if( IsNull( targetkey ) )
{
if( formatDataLength > 0 )
pgpCopyMemory( formatData, formatDataCopy, formatDataLength );
} else {
if( formatDataLength > 0 )
pgpCopyMemory( formatData, formatDataCopy+1, formatDataLength );
formatDataLength += sizeof(PGPAttributeValue);
/* Add extension field to hold keycreation data */
sAddPGPX509Extension( formatDataCopy, pgpkeycr, targetkey, TRUE );
}
if( IsntNull( pkcs10Buffer ) )
{
/* See if we need to remove PEM encoding */
/* This is a hack based on usual buffer patterns */
if( pkcs10Buffer[0] != 0x30 || (pkcs10Buffer[1] & 0x80) != 0x80 )
{
PGPByte *tmpBuf;
PGPSize tmpBufLength;
err = pgpRemovePEMEncoding( context,pkcs10Buffer,pkcs10BufferSize,
&tmpBuf, &tmpBufLength );
if( IsntPGPError( err ) && tmpBufLength > 50 )
{
/* Replace buffer with decoded version and set flag */
if( mustFreeBuf )
PGPFreeData( pkcs10Buffer );
mustFreeBuf = TRUE;
pkcs10Buffer = tmpBuf;
pkcs10BufferSize = tmpBufLength;
}
}
}
err = pgpX509CreateCert_internal( context, signer, targetkey,
pkcs10Buffer, pkcs10BufferSize,
creationTime, expirationDays, formatDataCopy,
formatDataLength, (PGPByte *)passphrase,
passphraseLength, hashedPhrase, sig );
if( IsPGPError( err ) )
goto error;
error:
if( IsntNull( formatDataCopy ) )
PGPFreeData( formatDataCopy );
if( mustFreeBuf )
PGPFreeData( pkcs10Buffer );
return err;
}
static const PGPOptionType cx509crlOptionSet[] = {
kPGPOptionType_Passphrase,
kPGPOptionType_Passkey,
kPGPOptionType_CachePassphrase,
kPGPOptionType_Expiration,
kPGPOptionType_CreationDate
};
/*
* Create X.509 CRL. Gets added to the signer key in its keydb.
*/
PGPError
pgpCreateX509CRLInternal(
PGPKeyDBObjRef signer,
PGPKeySetRef targetkeys,
PGPOptionListRef optionList
)
{
PGPContextRef context;
char * passphrase;
PGPSize passphraseLength;
PGPBoolean hashedPhrase = FALSE;
PGPTime creationTime;
PGPUInt32 expirationDays;
PGPError err;
if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
cx509crlOptionSet, elemsof( cx509crlOptionSet ) ) ) )
return err;
context = PGPPeekKeyDBObjContext( signer );
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_CreationDate, FALSE,
"%T", &creationTime ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Expiration, FALSE,
"%d", &expirationDays ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passphrase, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
goto error;
if (IsNull( passphrase )) {
hashedPhrase = TRUE;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passkey, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
goto error;
}
err = pgpX509CreateCRL_internal( context, signer, targetkeys,
creationTime, expirationDays,
(PGPByte *)passphrase, passphraseLength,
hashedPhrase );
if( IsPGPError( err ) )
goto error;
error:
return err;
}
/*
* Export function. Not clear how to split this between front end and
* back end. Either need to get data from back end to front end and do
* it all on front end, or we need to be able to export objects one at
* a time in back end, appending to a buffer we are accumulating. No,
* the first way is better.
*/
PGPError
pgpExportToPGPFile( PGPKeySet *set, PGPFile *file,
PGPBoolean exportmastersecrets, PGPBoolean exportsubsecrets,
PGPBoolean includeattributes, PGPBoolean includepubkey )
{
PGPKeyDBObj * key;
PGPKeyDBObj * child;
PGPKeyDBObj * gchild;
PGPByte const * data;
PGPSize datalen;
PGPKeyDB * kdb = set->keyDB;
PGPError err = kPGPError_NoErr;
for (key = kdb->firstKeyInDB; IsntNull(key); key = key->next) {
if( !pgpKeyDBObjIsReal( key ) )
continue;
if( !pgpKeySetIsMember( key, set ) )
continue;
if( includepubkey ) { /*if the storage is precious, we may need to exclude it*/
data = pgpFetchObject( key, &datalen );
if (!exportmastersecrets && pgpKeyIsSec (key)) {
data = pgpKeyDBObjToPubData( key, &datalen );
if( pgpFileWrite( data, datalen, file ) != datalen ) {
err = kPGPError_WriteFailed;
goto error;
}
PGPFreeData( (PGPByte *)data );
} else {
if( pgpFileWrite( data, datalen, file ) != datalen ) {
err = kPGPError_WriteFailed;
goto error;
}
}
}
for (child = key->down; IsntNull(child); child = child->next) {
if( !pgpKeyDBObjIsReal( child ) )
continue;
if( !pgpKeySetIsMember( child, set ) )
continue;
if (!includeattributes && pgpObjectType (child) == RINGTYPE_USERID
&& pgpUserIDIsAttribute (child) )
continue;
if( !includeattributes && OBJISCRL(child) )
continue;
if( OBJISSIG(child) )
{ PGPSigInfo *sinfo = pgpSigToSigInfo( child );
if( !SIGISEXPORTABLE(sinfo) )
continue;
if( pgpSigIsSuperceded(child) )
continue;
if( exportmastersecrets )
continue; /* No sigs in private key files */
}
data = pgpFetchObject( child, &datalen );
if (!exportsubsecrets && OBJISKEY(child) && pgpKeyIsSec (child)) {
data = pgpKeyDBObjToPubData( child, &datalen );
if( pgpFileWrite( data, datalen, file ) != datalen ) {
err = kPGPError_WriteFailed;
goto error;
}
PGPFreeData( (PGPByte *)data );
} else {
if( pgpFileWrite( data, datalen, file ) != datalen ) {
err = kPGPError_WriteFailed;
goto error;
}
}
for (gchild = child->down; IsntNull(gchild);
gchild = gchild->next) {
if( !pgpKeyDBObjIsReal( gchild ) )
continue;
if( !pgpKeySetIsMember( gchild, set ) )
continue;
if( !includeattributes && OBJISCRL(gchild) )
continue;
if( OBJISSIG(gchild) )
{ PGPSigInfo *sinfo = pgpSigToSigInfo( gchild );
if( !SIGISEXPORTABLE(sinfo) )
continue;
if( pgpSigIsSuperceded(gchild) )
continue;
if( OBJISKEY(child)?exportsubsecrets:exportmastersecrets )
continue; /* No sigs in private key files */
}
data = pgpFetchObject( gchild, &datalen );
if( pgpFileWrite( data, datalen, file ) != datalen ) {
err = kPGPError_WriteFailed;
goto error;
}
}
}
}
error:
return err;
}
#if PGP_MACINTOSH
#pragma global_optimizer on
#endif
static PGPError
sExportKeyContainer( PGPKeySetRef keyset, PGPBoolean mandatory, PGPOptionListRef optionList )
{
PGPError err = kPGPError_NoErr;
PGPContextRef context;
PGPByte *contName = NULL;
PGPSize contSize=0;
void *password=NULL;
PGPSize passwordLength=0;
void *PIN=NULL;
PGPSize PINlength=0;
PGPBoolean hashedPassword, hashedPIN;
PGPKeyDBObjRef key;
pgpAssert( pgpKeySetIsValid( keyset ) );
context = PGPPeekKeyDBContext( keyset->keyDB );
if( IsNull( key = pgpFirstKeyInKeySet( keyset ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_TokenKeyContainerSuggested, mandatory,
"%p%l", &contName, &contSize ) ) )
goto error;
pgpSearchPassphraseOptions( optionList, &password, &passwordLength,
&hashedPassword, &PIN, &PINlength, &hashedPIN);
if( password == NULL || hashedPIN )
{
err = kPGPError_BadParams;
goto error;
}
if( IsntPGPError(err) && contSize )
{
PGPKeyInfo *kinfo = pgpKeyToKeyInfo( key );
err = pgpTokenPutKeyContainer_back(
context, kinfo->keyID,
(IsNull(PIN)?password:PIN),(IsNull(PIN)?passwordLength:PINlength),
contName, contSize
);
}
error:
return err;
}
/* Exports certificate from the given keyset to the appropriate token */
static PGPError
sExportKeyX509ToToken ( PGPKeySetRef keyset, PGPOptionListRef optionList )
{
PGPError err = kPGPError_NoErr;
PGPKeyDBObj *obj = NULL;
PGPKeyDBObj *bestsig = NULL;
PGPKeyIter *iter;
PGPByte *password=NULL;
PGPSize passwordLength=0;
PGPKeyDBObjRef key;
PGPContextRef context;
PGPByte *buf = NULL;
PGPSize bufLength = 0;
PGPOAllocatedOutputBufferDesc *contOutDesc = NULL;
pgpAssert( pgpKeySetIsValid( keyset ) );
key = pgpFirstKeyInKeySet( keyset );
if( IsNull( key ) ) {
err = kPGPError_BadParams;
goto error;
}
#if 0
/* Key maybe in the temporary DB, so attributes will not be copied */
pgpAssert( pgpKeyIsSec(key) );
if( ! pgpKeyIsOnToken( key ) )
return kPGPError_SecretKeyNotFound;
#endif
context = PGPPeekKeyDBContext( keyset->keyDB );
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passphrase, FALSE,
"%p%l", &password, &passwordLength ) ) )
goto error;
/* We are working with token-based key here. */
#ifdef PGP_DEBUG
{
PGPBoolean fOutputToken=FALSE;
PGPUInt32 tokNumber=0;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_OutputToken, FALSE,
"%b%d", &fOutputToken, &tokNumber ) ) )
pgpAssert( fOutputToken && tokNumber == -1 );
/* Output to the token corresponding to KeyID */
}
#endif
/* Find the right X509 sig, somehow */
if( IsPGPError( err = PGPNewKeyIterFromKeySet( keyset, &iter ) ) )
goto error;
while( IsntPGPError( pgpKeyIterNextObject( iter, &obj ) ) ) {
if (pgpObjectType(obj) == RINGTYPE_SIG &&
pgpSigIsX509 (obj)) {
PGPKeyDBObj *signer = pgpSigMaker (obj);
/* Use a self-sig if exists, else use first sig */
if (signer == obj->up) {
bestsig = obj;
} else if (bestsig == NULL) {
bestsig = obj;
}
}
}
PGPFreeKeyIter( iter );
iter = NULL;
if (bestsig != NULL) {
buf = pgpSigX509Certificate( bestsig, &bufLength );
}
/* Return output buffer with X509 cert, if was requested */
{
PGPOAllocatedOutputBufferDesc *desc;
err = pgpFindOptionArgs( optionList,
kPGPOptionType_OutputAllocatedBuffer, FALSE, "%p", &desc );
if( IsntNull( desc ) )
{
void *outBuffer =
(void*)PGPNewData(
PGPPeekContextMemoryMgr(context),
bufLength, kPGPMemoryMgrFlags_None);
if( outBuffer == NULL ) {
err = kPGPError_OutOfMemory;
goto error;
}
pgpCopyMemory(buf, outBuffer, bufLength);
*desc->buffer = outBuffer;
*desc->actualBufferSize = bufLength;
}
}
/* Return existing key container, if was requested */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -