📄 pgpkeyman.c
字号:
"%p%l", &passphrase, &passphraseLength ) ) )
goto error;
}
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_CachePassphrase, FALSE,
"%d%b", &cacheTimeOut, &cacheGlobal ) ) )
goto error;
if( pgpFrontEndKey( key ) )
{
PGPUInt32 *newobjs;
PGPSize newobjslen;
PGPKeyDB *keydb = PGPPeekKeyDBObjKeyDB( key );
err = pgpRevokeKey_back( PGPPeekKeyDBContext(keydb),
pgpKeyDBObjID(key), passphrase,
passphraseLength, hashedPhrase, cacheTimeOut,
cacheGlobal, &newobjs, &newobjslen);
if( IsPGPError( err ) )
return err;
pgpKeyDBObjRefresh( key, FALSE );
err = pgpAddFromKeyArray( keydb, NULL, newobjs, 1, FALSE );
PGPFreeData( newobjs );
} else {
err = pgpRevokeKey_internal( key, passphrase, passphraseLength,
hashedPhrase, cacheTimeOut, cacheGlobal );
}
/* Calculate trust changes as a result */
if( err == kPGPError_NoErr )
(void)PGPCalculateTrust( PGPPeekKeyDBObjKeyDB(key)->rootSet, NULL );
error:
return err;
}
static const PGPOptionType keyentOptionSet[] = {
kPGPOptionType_KeyGenParams,
kPGPOptionType_KeyGenFast,
kPGPOptionType_KeyFlags,
kPGPOptionType_KeyGenUseExistingEntropy,
kPGPOptionType_KeyGenOnToken
};
/* Return the amount of entropy needed to create a key of the specified
type and size. The application must call pgpRandpoolEntropy() itself
until it has accumulated this much. */
PGPUInt32
pgpKeyEntropyNeededInternal(
PGPContextRef context,
PGPOptionListRef optionList
)
{
PGPEnv *pgpEnv;
PGPUInt32 fastgen;
PGPBoolean fastgenop;
PGPUInt32 noentropy = FALSE;
PGPUInt32 pkalg;
PGPUInt32 bits;
PGPBoolean keyflagsop;
PGPUInt32 keyflags;
PGPBoolean v3;
PGPBoolean useToken;
PGPUInt32 tokenID;
void * tok = NULL;
PGPError err = kPGPError_NoErr;
if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
keyentOptionSet, elemsof( keyentOptionSet ) ) ) )
return err;
/* If generating with existing entropy, we don't need any amount */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenUseExistingEntropy, FALSE,
"%d", &noentropy ) ) )
goto error;
if (noentropy)
return 0;
pgpEnv = pgpContextGetEnvironment( context );
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenParams, TRUE,
"%d%d", &pkalg, &bits ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenOnToken, FALSE,
"%b%d", &useToken, &tokenID ) ) )
goto error;
if( useToken )
tok = pgpTokenGetIndexed( tokenID );
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_KeyFlags, FALSE,
"%b%d", &keyflagsop, &keyflags ) ) )
goto error;
v3 = (pkalg == kPGPPublicKeyAlgorithm_RSA) && !keyflagsop;
return pgpSecKeyEntropy (pgpPkalgByNumber ((PGPByte)pkalg), bits,
(PGPBoolean)fastgen, v3, tok);
/* Should not have an error unless bad parameters */
error:
pgpAssert(0);
return ~(PGPUInt32)0;
}
/* Internal function for passphraseIsValid */
PGPError
pgpPassphraseIsValid_internal(
PGPKeyDBObjRef key,
const char * passphrase,
PGPSize passphraseLength,
PGPBoolean hashedPhrase,
PGPUInt32 cacheTimeOut,
PGPBoolean cacheGlobal,
PGPBoolean * isValid)
{
PGPSecKey * seckey;
PGPKeyDBObjRef child;
PGPError err = kPGPError_NoErr;
PGPValidateKey( key );
if( IsntNull( passphrase ) )
PGPValidateParam( passphrase );
PGPValidateParam( isValid );
/* Default return value */
*isValid = FALSE;
seckey = pgpSecSecKey (key, 0);
/* If not a secret key, just return */
if( !seckey )
return err;
err = pgpSecKeyUnlockWithCache( seckey, (PGPByte const *)passphrase,
passphraseLength, hashedPhrase,
cacheTimeOut, cacheGlobal );
pgpSecKeyDestroy( seckey );
*isValid = IsntPGPError( err );
/* If requesting caching, also try it with all child keys */
if( cacheTimeOut > 0 && OBJISTOPKEY( key ) && *isValid )
{
for( child = key->down; IsntNull( child ); child = child->next )
{
if( !OBJISSUBKEY( child ) )
continue;
seckey = pgpSecSecKey (child, 0);
if( !seckey )
continue;
pgpSecKeyUnlockWithCache( seckey, (PGPByte const *)passphrase,
passphraseLength, hashedPhrase,
cacheTimeOut, cacheGlobal );
pgpSecKeyDestroy( seckey );
}
}
return kPGPError_NoErr;
}
static const PGPOptionType passphraseisvalidOptionSet[] = {
kPGPOptionType_Passphrase,
kPGPOptionType_Passkey,
kPGPOptionType_CachePassphrase
};
PGPBoolean
pgpPassphraseIsValidInternal(
PGPKeyDBObjRef key,
PGPOptionListRef optionList
)
{
char * passphrase = NULL;
PGPSize passphraseLength;
PGPBoolean hashedPhrase = FALSE;
PGPUInt32 cacheTimeOut = 0;
PGPBoolean cacheGlobal;
PGPBoolean rslt;
PGPError err = kPGPError_NoErr;
pgpa(pgpaPGPKeyValid(key));
if ( ! pgpKeyIsValid( key ) )
return( FALSE );
if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
passphraseisvalidOptionSet,
elemsof( passphraseisvalidOptionSet ) ) ) )
return FALSE;
/* Pick up optional options */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passphrase, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
return FALSE;
if (IsNull( passphrase )) {
hashedPhrase = TRUE;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passkey, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
return FALSE;
}
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_CachePassphrase, FALSE,
"%d%b", &cacheTimeOut, &cacheGlobal ) ) )
return FALSE;
if( pgpFrontEndKey( key ) )
{
if( IsPGPError( pgpPassphraseIsValid_back( PGPPeekKeyDBObjContext(key),
pgpKeyDBObjID(key),
passphrase,passphraseLength,
hashedPhrase, cacheTimeOut,
cacheGlobal, &rslt ) ) )
return FALSE;
} else {
if( IsPGPError( pgpPassphraseIsValid_internal( key, passphrase,
passphraseLength,
hashedPhrase,
cacheTimeOut,
cacheGlobal, &rslt ) ) )
return FALSE;
}
return rslt;
}
/*____________________________________________________________________________
Key Generation
____________________________________________________________________________*/
/*
* Callback impedence matching, convert from internal state to callback
* state.
*/
typedef struct PGPKeyGenProgressState {
PGPContextRef context;
PGPEventHandlerProcPtr progress;
PGPUserValue userValue;
} PGPKeyGenProgressState;
static int /* Return < 0 to abort run */
genProgress(
void *arg,
int c
)
{
PGPKeyGenProgressState *s = (PGPKeyGenProgressState *)arg;
PGPError err = kPGPError_NoErr;
PGPOptionListRef newOptionList = NULL;
if (IsntNull (s->progress)) {
err = pgpEventKeyGen (s->context, &newOptionList,
s->progress, s->userValue, (PGPUInt32)c);
if (IsntNull (newOptionList))
pgpFreeOptionList (newOptionList);
}
return err;
}
/* Common code for generating master keys and subkeys. *masterkey
is NULL when generating a master key, and is used to return
the master PGPKeyDBObj. If *masterkey contains a value,
a subkey is to be generated associated with the PGPKeyDBObj.
Depending on the circumstances, this may be called either on the
front end or the back end. Presently, smartcard keys are done on
the back end and other keys on the front end.
*/
PGPError
pgpDoGenerateKey_internal (
PGPKeyDB * keyDB,
PGPKeyDBObj * masterkey,
PGPByte pkalg,
unsigned bits,
PGPTime creationDate,
PGPUInt16 expirationDays,
char const * name,
int name_len,
char const * passphrase,
PGPSize passphraseLength,
PGPBoolean passphraseIsKey,
char const * masterpass,
PGPSize masterpassLength,
PGPUInt32 cacheTimeOut,
PGPBoolean cacheGlobal,
PGPEventHandlerProcPtr progress,
PGPUserValue userValue,
PGPBoolean fastgen,
PGPBoolean checkentropy,
PGPBoolean useToken,
PGPUInt32 tokenID,
PGPKeySet const *adkset,
PGPByte adkclass,
PGPKeySet const *rakset,
PGPByte rakclass,
PGPCipherAlgorithm const * prefalg,
PGPSize prefalgLength,
PGPByte const * prefkeyserv,
PGPSize prefkeyservLength,
PGPUInt32 keyflags,
PGPBoolean fkeyflags,
PGPUInt32 keyservprefs,
PGPBoolean fkeyservprefs,
PGPKeyDBObj ** newkey)
{
PGPKeyDBObj *newobj = NULL;
PGPError error = kPGPError_NoErr;
PGPSecKey *seckey = NULL, *masterseckey = NULL;
PGPKeySpec *keyspec = NULL;
long entropy_needed, entropy_available;
PGPBoolean genMaster = (masterkey == NULL);
PGPEnv *pgpEnv;
PGPEnv *pgpEnvCopy;
PGPRandomContext *pgpRng;
PGPKeyGenProgressState progressState;
PGPContextRef context = PGPPeekKeyDBContext( keyDB );
PGPUInt32 i;
const PGPPkAlg * algInfo;
void *tok = NULL;
int v3;
if( useToken )
tok = pgpTokenGetIndexed( tokenID );
v3 = (pkalg == kPGPPublicKeyAlgorithm_RSA) && !fkeyflags;
algInfo = pgpPkalgByNumber( pkalg );
if( IsntNull( algInfo ) )
{
if( ( pgpKeyAlgUse( algInfo ) & PGP_PKUSE_SIGN ) == 0 &&
genMaster )
{
pgpDebugMsg( "Invalid master key algorithm" );
error = kPGPError_BadParams;
}
else if( ( pgpKeyAlgUse( algInfo ) & PGP_PKUSE_ENCRYPT ) == 0 &&
! genMaster )
{
pgpDebugMsg( "Invalid subkey algorithm" );
error = kPGPError_BadParams;
}
}
else
{
pgpDebugMsg( "Invaid public key algorithm" );
error = kPGPError_BadParams;
}
if( IsPGPError( error ) )
goto cleanup;
/* Grab system state from RNG for highest quality seeding */
{ PGPRandomContext rc;
pgpInitGlobalRandomPoolContext( &rc );
pgpRandomCollectOsData( &rc, FALSE );
}
pgpEnv = pgpContextGetEnvironment( keyDB->context );
if( checkentropy )
{
/* Check we have sufficient random bits to generate the keypair */
entropy_needed = pgpSecKeyEntropy (algInfo, bits, fastgen, v3, tok);
entropy_available = 8*PGPContextReserveRandomBytes ( context, 0 );
if (entropy_needed > entropy_available)
{
error = kPGPError_OutOfEntropy;
goto cleanup;
}
}
/* Generate the secret key */
progressState.progress = progress;
progressState.userValue = userValue;
progressState.context = keyDB->context;
pgpRng = pgpContextGetX9_17RandomContext( keyDB->context );
seckey = pgpSecKeyGenerate( context, algInfo, bits, fastgen, v3, pgpRng,
genProgress, &progressState, tok, (PGPByte *) passphrase,
passphraseLength, genMaster, &error);
if (error) {
if( masterkey && IsntNull( tok ) ) {
PGPKeyDBObjRef subkey = pgpKeySubkey(masterkey, NULL);
/* If we have no other subkey, remove master key from the token */
if( IsNull( subkey ) ) {
PGPKeyID keyID;
pgpKeyID8 (masterkey, NULL, &keyID);
pgpDeleteKeyOnToken( context, &keyID, tokenID );
}
}
goto cleanup;
}
pgpRandomStir (pgpRng);
/* Need to lock the SecKey with the passphrase. */
if (!useToken && IsntNull(passphrase) && passphraseLength > 0) {
PGPStringToKeyType s2ktype;
if (passphraseIsKey) {
s2ktype = kPGPStringToKey_LiteralShared;
} else if (seckey->pkAlg <= kPGPPublicKeyAlgorithm_RSA) {
s2ktype = kPGPStringToKey_Simple;
} else {
s2ktype = kPGPStringToKey_IteratedSalted;
}
/* Lock using key's preferred algorithm if known */
if( IsPGPError( error = pgpenvCopy( pgpEnv, &pgpEnvCopy ) ) )
goto cleanup;
if( !genMaster )
{
/* For subkey, look at master key's preferred algs */
PGPByte const *prefAlgs;
PGPSize prefAlgsLength;
PGPBoolean hashed;
prefAlgs = pgpKeyFindSubpacket ( masterkey,
SIGSUB_PREFERRED_ENCRYPTION_ALGS, 0,
&prefAlgsLength, NULL, &hashed, NULL, NULL, &error);
for( i = 0; hashed && (i < prefAlgsLength); ++i )
{
PGPCipherAlgorithm lockAlg = (PGPCipherAlgorithm)prefAlgs[i];
if( IsntNull( pgpCipherGetVTBL ( lockAlg ) ) )
{
pgpenvSetInt (pgpEnvCopy, PGPENV_CIPHER, lockAlg,
PGPENV_PRI_FORCE);
break;
}
}
} else {
/* For master key, use prefalg parameter */
for( i = 0; i < prefalgLength/sizeof(PGPCipherAlgorithm); ++i )
{
PGPCipherAlgorithm lockAlg = (PGPCipherAlgorithm)prefalg[i];
if( IsntNull( pgpCipherGetVTBL ( lockAlg ) ) )
{
pgpenvSetInt (pgpEnvCopy, PGPENV_CIPHER, lockAlg,
PGPENV_PRI_FORCE);
break;
}
}
}
error = (PGPError)pgpSecKeyChangeLock (seckey, pgpEnvCopy, pgpRng,
NULL, 0, FALSE,
passphrase, passphraseLength,
s2ktype);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -