📄 pgpkeyman.c
字号:
pgpenvDestroy (pgpEnvCopy);
if (error)
goto cleanup;
}
/* Generate the keyring objects. Use keyspec defaults except for
expiration (validity) period */
keyspec = pgpKeySpecCreate (pgpEnv);
if (!keyspec) {
error = kPGPError_OutOfMemory;
goto cleanup;
}
if( creationDate != 0 )
{
pgpKeySpecSetCreation(keyspec, creationDate +
(60 * 60 * pgpenvGetInt(pgpEnv, PGPENV_TZFIX, NULL, NULL)));
}
pgpKeySpecSetValidity (keyspec, expirationDays);
pgpKeySpecSetVersion( keyspec, v3 ? PGPVERSION_3 : PGPVERSION_4 );
pgpKeySpecSetPkAlg( keyspec, pkalg );
if( prefkeyservLength > 0 )
pgpKeySpecSetPrefKeyserv( keyspec, prefkeyserv, prefkeyservLength );
if( fkeyflags )
pgpKeySpecSetKeyflags( keyspec, keyflags );
if( fkeyservprefs )
pgpKeySpecSetKeyservPrefs( keyspec, keyservprefs );
if (genMaster) {
/* Generating master signing key */
if (prefalgLength > 0) {
/* Convert preferred algorithm to byte array */
PGPByte *prefalgByte;
prefalgLength /= sizeof(PGPCipherAlgorithm);
prefalgByte = (PGPByte *)pgpContextMemAlloc( context,
prefalgLength, 0);
if( IsNull( prefalgByte ) ) {
error = kPGPError_OutOfMemory;
goto cleanup;
}
for (i=0; i<prefalgLength; ++i) {
prefalgByte[i] = (PGPByte)prefalg[i];
}
pgpKeySpecSetPrefAlgs( keyspec, prefalgByte, prefalgLength );
pgpContextMemFree( context, prefalgByte );
}
if( pgpFrontEndKeyDB( keyDB ) )
{
PGPUInt32 *newobjs;
PGPSize newobjslen;
PGPUInt32 *adklist;
PGPSize adklistsize;
PGPUInt32 *raklist;
PGPSize raklistsize;
PGPUInt32 newkeyid;
PGPByte *keyspecBuf;
PGPSize keyspecSize;
PGPByte *seckeyBuf;
PGPSize seckeySize;
if( IsPGPError(error = pgpKeySetFlatten( adkset,
&adklist, &adklistsize)))
goto cleanup;
if( IsPGPError(error = pgpKeySetFlatten( rakset,
&raklist, &raklistsize)))
{
PGPFreeData( adklist );
goto cleanup;
}
if( IsPGPError( error = pgpKeySpecFlatten( keyspec, &keyspecBuf,
&keyspecSize ) ) )
{
PGPFreeData( raklist );
PGPFreeData( adklist );
goto cleanup;
}
seckeySize = pgpSecKeyBufferLength( seckey );
if( IsNull( seckeyBuf = pgpContextMemAlloc( context,
seckeySize, 0 ) ) )
{
error = kPGPError_OutOfMemory;
PGPFreeData( keyspecBuf );
PGPFreeData( adklist );
PGPFreeData( adklist );
goto cleanup;
}
pgpSecKeyToBuffer( seckey, seckeyBuf );
error = pgpCreateKeypair_back( context, keyDB->id,
seckeyBuf, seckeySize, keyspecBuf, keyspecSize,
name, name_len,
adklist, adklistsize, adkclass,
raklist, raklistsize, rakclass,
passphrase, passphraseLength,
passphraseIsKey, cacheTimeOut, cacheGlobal,
&newobjs, &newobjslen, &newkeyid);
if( IsntPGPError( error ) )
{
error = pgpAddFromKeyArray( keyDB, NULL, newobjs, 1, TRUE );
PGPFreeData( newobjs );
}
if( IsntPGPError( error ) )
{
error = PGPFindNode( keyDB->idToObj, newkeyid,
(PGPUserValue *)&newobj );
}
} else {
newobj = pgpCreateKeypair (pgpEnv, keyDB, seckey, keyspec,
name, name_len,
adkset, adkclass, rakset, rakclass,
(PGPByte *) passphrase, passphraseLength,
passphraseIsKey, &error);
}
}
else {
/* Generating encryption subkey. Get the master seckey and
unlock it */
masterseckey = pgpSecSecKey (masterkey, PGP_PKUSE_SIGN);
if (!masterseckey) {
error = pgpKeyDBError(PGPPeekKeyDBObjKeyDB(masterkey));
goto cleanup;
}
if (pgpSecKeyIslocked (masterseckey)) {
if (IsNull( masterpass )) {
error = kPGPError_BadPassphrase;
goto cleanup;
}
error = (PGPError)pgpSecKeyUnlock (masterseckey,
masterpass, masterpassLength, FALSE);
if (error != 1) {
if (error == 0)
error = kPGPError_BadPassphrase;
goto cleanup;
}
}
if( pgpFrontEndKeyDB( keyDB ) )
{
PGPUInt32 *newobjs;
PGPSize newobjslen;
PGPUInt32 newkeyid;
PGPByte *keyspecBuf;
PGPSize keyspecSize;
PGPByte *seckeyBuf;
PGPSize seckeySize;
if( IsPGPError( error = pgpKeySpecFlatten( keyspec, &keyspecBuf,
&keyspecSize ) ) )
{
goto cleanup;
}
seckeySize = pgpSecKeyBufferLength( seckey );
if( IsNull( seckeyBuf = pgpContextMemAlloc( context,
seckeySize, 0 ) ) )
{
PGPFreeData( keyspecBuf );
error = kPGPError_OutOfMemory;
goto cleanup;
}
pgpSecKeyToBuffer( seckey, seckeyBuf );
error = pgpCreateSubkeypair_back( context,pgpKeyDBObjID(masterkey),
seckeyBuf, seckeySize,
keyspecBuf, keyspecSize,
passphrase, passphraseLength,
passphraseIsKey, cacheTimeOut, cacheGlobal,
&newobjs, &newobjslen, &newkeyid);
if( IsntPGPError( error ) )
{
error = pgpAddFromKeyArray( keyDB, masterkey,
newobjs, 1, TRUE );
PGPFreeData( newobjs );
}
if( IsntPGPError( error ) )
{
error = PGPFindNode( keyDB->idToObj, newkeyid,
(PGPUserValue *)&newobj );
}
} else {
newobj = pgpCreateSubkeypair (masterkey, pgpEnv, seckey,
keyspec, (PGPByte *) passphrase,
passphraseLength, passphraseIsKey,
&error);
}
}
if( IsntPGPError(error) && IsntNull( tok ) && (genMaster==v3) )
{
/* Token gets locked when we destroy seckey used for signing */
pgpSecKeyUnlock(seckey, passphrase, passphraseLength, passphraseIsKey);
error = pgpTokenCopyPubKeyToToken( context,
(genMaster?newobj:masterkey), tokenID, tok );
if( IsPGPError( error ) )
{
/* Delete just-generated key from token if we couldn't finish */
PGPKeyID keyID;
PGPBoolean hasOtherSubkey = FALSE;
if( !genMaster )
hasOtherSubkey = IsntNull( pgpKeySubkey(masterkey, NULL) );
if( ! hasOtherSubkey ) {
pgpKeyID8 ((genMaster?newobj:masterkey), NULL, &keyID);
pgpDeleteKeyOnToken( context, &keyID, tokenID );
}
if( !genMaster )
{
pgpKeyID8 (newobj, NULL, &keyID);
pgpDeleteKeyOnToken( context, &keyID, tokenID );
/* Finally, put PGP public object on the token --
it is still a usable key */
if( hasOtherSubkey && error==kPGPError_SmartCardOutOfMemory ) {
PGPError err2;
pgpKeyDBRemoveObject( PGPPeekKeyDBObjKeyDB(masterkey), newobj );
err2 = pgpTokenCopyPubKeyToToken(
context,masterkey,tokenID, tok );
/* We should have enough space on the token for this */
}
}
}
}
pgpRandomStir (pgpRng); /* this helps us count randomness in pool */
if (error)
goto cleanup;
*newkey = newobj;
pgpKeyDBChanged( keyDB, TRUE );
cleanup:
if (seckey)
pgpSecKeyDestroy (seckey);
if (masterseckey)
pgpSecKeyDestroy (masterseckey);
if (keyspec)
pgpKeySpecDestroy (keyspec);
return error;
}
static const PGPOptionType keygenOptionSet[] = {
kPGPOptionType_KeyDBRef,
kPGPOptionType_KeyGenParams,
kPGPOptionType_KeyGenName,
kPGPOptionType_Passphrase,
kPGPOptionType_Passkey,
kPGPOptionType_CachePassphrase,
kPGPOptionType_Expiration,
kPGPOptionType_CreationDate,
kPGPOptionType_EventHandler,
kPGPOptionType_PreferredAlgorithms,
kPGPOptionType_PreferredKeyServer,
kPGPOptionType_KeyServerPreferences,
kPGPOptionType_KeyFlags,
kPGPOptionType_AdditionalRecipientRequestKeySet,
kPGPOptionType_RevocationKeySet,
kPGPOptionType_KeyGenFast,
kPGPOptionType_KeyGenUseExistingEntropy,
kPGPOptionType_KeyGenOnToken
};
PGPError
pgpGenerateKeyInternal(
PGPKeyDBObjRef *key,
PGPOptionListRef optionList
)
{
PGPContextRef context;
PGPKeyDBRef keydb;
PGPUInt32 pkalg;
PGPUInt32 bits;
PGPUInt32 expiration;
PGPTime creationDate;
PGPByte *name;
PGPUInt32 nameLength;
PGPByte *passphrase;
PGPUInt32 passphraseLength;
PGPBoolean passphraseIsKey = FALSE;
PGPUInt32 cacheTimeOut = 0;
PGPBoolean cacheGlobal;
PGPKeySetRef adkset;
PGPUInt32 adkclass;
PGPKeySetRef rakset = NULL;
PGPUInt32 rakclass = 0;
PGPEventHandlerProcPtr progress;
PGPUserValue userValue;
PGPKeyDBObjRef newkey;
PGPCipherAlgorithm *prefalg;
PGPSize prefalgLength;
PGPByte *prefkeyserv;
PGPSize prefkeyservLength;
PGPEnv *pgpEnv;
PGPBoolean fastgenop;
PGPUInt32 fastgen;
PGPBoolean keyflagsop;
PGPUInt32 keyflags;
PGPBoolean keyservprefsop;
PGPUInt32 keyservprefs;
PGPUInt32 noentropy = FALSE;
PGPBoolean useToken;
PGPUInt32 tokenID;
PGPError err;
if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
keygenOptionSet, elemsof( keygenOptionSet ) ) ) )
return err;
if( IsNull( key ) )
return kPGPError_BadParams;
/* First pick up mandatory options */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyDBRef, TRUE,
"%p", &keydb ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenParams, TRUE,
"%d%d", &pkalg, &bits ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenName, TRUE,
"%p%l", &name, &nameLength ) ) )
goto error;
context = PGPPeekKeyDBContext( keydb );
pgpEnv = pgpContextGetEnvironment( context );
/* Now get optional parameters */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passphrase, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
goto error;
if (IsNull( passphrase )) {
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passkey, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
goto error;
if( IsntNull( passphrase ) )
passphraseIsKey = TRUE;
}
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_CachePassphrase, FALSE,
"%d%b", &cacheTimeOut, &cacheGlobal ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_CreationDate, FALSE,
"%T", &creationDate ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Expiration, FALSE,
"%d", &expiration ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_EventHandler, FALSE,
"%p%p", &progress, &userValue ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_PreferredAlgorithms, FALSE,
"%p%l", &prefalg, &prefalgLength ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_PreferredKeyServer, FALSE,
"%p%l", &prefkeyserv, &prefkeyservLength ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyFlags, FALSE,
"%b%d", &keyflagsop, &keyflags ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyServerPreferences, FALSE,
"%b%d", &keyservprefsop, &keyservprefs ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_AdditionalRecipientRequestKeySet,
FALSE, "%p%d", &adkset, &adkclass ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_RevocationKeySet, FALSE,
"%p%d", &rakset, &rakclass ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenOnToken, FALSE,
"%b%d", &useToken, &tokenID ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenFast, FALSE,
"%b%d", &fastgenop, &fastgen ) ) )
goto error;
if( !fastgenop ) {
fastgen = pgpenvGetInt (pgpEnv, PGPENV_FASTKEYGEN, NULL, NULL);
}
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenUseExistingEntropy, FALSE,
"%d", &noentropy ) ) )
goto error;
*key = NULL;
newkey = NULL; /* Necessary to flag masterkey vs subkey */
/* Generate in back end if we are using tokens, else front end OK */
if( pgpFrontEndKeyDB( keydb ) && useToken )
{
PGPUInt32 *newobjs;
PGPSize newobjslen;
PGPUInt32 *adklist;
PGPSize adklistsize;
PGPUInt32 *raklist;
PGPSize raklistsize;
PGPUInt32 newkeyid;
#if PGP_WIN32
PGPKeyDBRef olddb = NULL;
#endif /* PGP_WIN32 */
if( IsPGPError(err = pgpKeySetFlatten( adkset, &adklist,&adklistsize)))
goto error;
if( IsPGPError(err = pgpKeySetFlatten( rakset, &raklist,&raklistsize)))
{
PGPFreeData( adklist );
goto error;
}
#if PGP_WIN32
if( IsntNull( progress ) )
{
/* Create temp keydb for insertion, copy to keydb */
olddb = keydb;
PGPNewKeyDB( context, &keydb );
}
#endif /* PGP_WIN32 */
err = pgpDoGenerateKey_back (context, keydb->id, 0,
(PGPByte)pkalg, bits, creationDate,
(PGPUInt16)expiration, (char *) name, nameLength,
(char const *)passphrase, passphraseLength,
passphraseIsKey, NULL, 0, cacheTimeOut, cacheGlobal,
progress, userValue, (PGPBoolean)fastgen,
(PGPBoolean)!noentropy, useToken, tokenID,
adklist, adklistsize, (PGPByte)adkclass,
raklist, raklistsize, (PGPByte)rakclass,
prefalg, prefalgLength, prefkeyserv, prefkeyservLength,
keyflags, keyflagsop, keyservprefs, keyservprefsop,
&newobjs, &newobjslen, &newkeyid );
if( IsntPGPError( err ) )
{
err = pgpAddFromKeyArray( keydb, NULL, newobjs, 1, TRUE );
PGPFreeData( newobjs );
}
if( IsntPGPError( err ) )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -