📄 keygen.c
字号:
done:
if(myiter)
PGPFreeKeyIter( myiter );
if(mylist)
PGPFreeKeyList( mylist );
if(myset)
PGPFreeKeySet( myset );
if( !cansign ) {
*mykey = NULL;
return kPGPError_SecretKeyNotFound;
}
return kPGPError_NoErr;
}
PGPError pgpGetKeyRemainingValidityDays( PGPKeyRef key, PGPInt32 *days )
{
PGPError err;
PGPTime now,expyTime;
now = PGPGetTime();
err = PGPGetKeyTime( key, kPGPKeyPropExpiration, &expyTime );
pgpAssertNoErr(err);
if( ( expyTime - now ) < 0 )
return kPGPError_KeyExpired;
*days = ( expyTime - now ) / 86400;
if( *days > kMaxKeyExpirationDays )
*days = kPGPExpirationTime_Never;
return kPGPError_NoErr;
}
PGPError askUserIDString( struct pgpfileBones *filebPtr, char *useridstr )
{
struct pgpenvBones *envbPtr=filebPtr->envbPtr;
PGPEnv *env = envbPtr->m_env;
PGPInt32 pri;
const char *myname = pgpenvGetCString( env, PGPENV_MYNAME, &pri );
int i;
if ( myname != NULL && *myname != '\0' && pri > PGPENV_PRI_CONFIG ) {
strcpy(useridstr, myname);
return kPGPError_NoErr;
}
for(i=0; i<3; i++) {
fprintf( filebPtr->pgpout,
LANG(
"\nYou need a user ID for your public key. The desired form for this\n"
"user ID is your name, followed by your E-mail address enclosed in\n"
"<angle brackets>, if you have an E-mail address.\n"
"For example: John Q. Smith <jqsmith@nai.com>\n") );
fprintf( filebPtr->pgpout,
LANG("Enter a user ID for your public key: ") );
fflush( filebPtr->pgpout );
pgpTtyGetString(useridstr, kPGPMaxUserIDSize-1 , filebPtr->pgpout);
if( strlen(useridstr) > 0 )
return kPGPError_NoErr;
fprintf( filebPtr->pgpout, LANG("\nInvalid response.\n"));
}
return kPGPError_UserAbort;
}
/*
Do a key pair generation, and write them out to the keyring files.
sigbitsstr is a decimal string, the desired bitcount for the DSA component.
encbitsstr is a decimal string, the desired bitcount for the ElGamal
component.
If the 2.6.2 compatibility bit is FALSE, activate advanced features to
ask for master and/or subkey generation.
*/
int dokeygen(struct pgpmainBones *mainbPtr,char *sigbitsstr, char
*encbitsstr )
{
PGPContextRef context = mainbPtr->pgpContext;
char useridstr[kPGPMaxUserIDSize];
PGPSize sigbits,encbits;
struct pgpfileBones *filebPtr=mainbPtr->filebPtr;
struct pgpenvBones *envbPtr=mainbPtr->envbPtr;
PGPEnv *env = envbPtr->m_env;
PGPError err;
char *passphrase;
PGPInt32 pri;
PGPBoolean signOnly = FALSE, encOnly = FALSE;
PGPBoolean batchmode = pgpenvGetInt( env, PGPENV_BATCHMODE, &pri, &err );
PGPBoolean compatible = envbPtr->compatible;
PGPPublicKeyAlgorithm sigalg,encalg;
PGPSize sigvalidfor,encvalidfor;
char *sigalgstr, *encalgstr;
PGPUInt32 signeed = 0, encneed = 0;
PGPKeySetRef keyringset = NULL;
PGPKeyRef masterkey = NULL;
PGPSubKeyRef subkey = NULL;
PGPBoolean needsfree = FALSE;
PGPBoolean haveRSAAlgorithm;
PGPBoolean canGenerateKeys;
char copyright[255];
/* pgp -kg [sigbits [encbits]] */
/* Assumption: the following dialog makes sense for the case:
generate signing key only. */
sigalg = kPGPPublicKeyAlgorithm_DSA;
encalg = kPGPPublicKeyAlgorithm_ElGamal;
if(compatible) {
sigalgstr = "DSS/DH";
encalgstr = "DSS/DH";
} else {
sigalgstr = "DSS";
encalgstr = "DH";
}
err = PGPOpenDefaultKeyRings( context,
kPGPKeyRingOpenFlags_Create|kPGPKeyRingOpenFlags_Mutable,
&keyringset );
if( IsPGPError(err) ) {
fprintf( filebPtr->pgpout, LANG("Can't open key rings\n"));
return -1;
}
GetRSAStatus( &haveRSAAlgorithm, &canGenerateKeys, copyright );
if( haveRSAAlgorithm && canGenerateKeys && !compatible ) {
char scratch[8];
PGPBoolean ok=FALSE;
while(!ok) {
fputs(
LANG("Choose the public-key algorithm to use with your new key\n"
"1) DSS/DH (a.k.a. DSA/ElGamal) (default)\n"
"2) RSA\nChoose 1 or 2: "), filebPtr->pgpout);
pgpTtyGetString(scratch, 5, filebPtr->pgpout);
if(strlen(scratch)!=1)
scratch[1]='\0';
switch( scratch[0] ) {
case '\0':
case '1':
ok=TRUE;
break;
case '2':
#ifdef TRY_RSA_MASTER_SUBKEY
sigalg = kPGPPublicKeyAlgorithm_RSASignOnly;
encalg = kPGPPublicKeyAlgorithm_RSAEncryptOnly;
sigalgstr = LANG("RSA Sign");
encalgstr = LANG("RSA Encrypt");
#else
sigalg = kPGPPublicKeyAlgorithm_RSA;
encalg = kPGPPublicKeyAlgorithm_RSA;
sigalgstr = "RSA";
encalgstr = "RSA";
#endif
ok=TRUE;
break;
default:
fprintf( filebPtr->pgpout, LANG("Invalid response\n"));
}
}
}
if( !compatible ) {
if(encalg != kPGPPublicKeyAlgorithm_RSA
&& encalg != kPGPPublicKeyAlgorithm_RSASignOnly
&& encalg != kPGPPublicKeyAlgorithm_RSAEncryptOnly)
{
err = askWhetherSubKey( filebPtr, &encOnly );
if( IsPGPError(err) )
goto ex;
}
if( encOnly ) {
PGPInt32 algnum;
mainbPtr->workingRingSet = keyringset;
/*mainbPtr->workingGroupSet = NULL;*/
err = askForMasterKey( mainbPtr, &masterkey);
if( IsPGPError(err) )
goto ex;
PGPGetKeyNumber( masterkey, kPGPKeyPropAlgID, &algnum );
sigalg = algnum;
switch( sigalg ) {
case kPGPPublicKeyAlgorithm_DSA:
break;
case kPGPPublicKeyAlgorithm_RSASignOnly:
if( haveRSAAlgorithm && canGenerateKeys ) {
encalg = kPGPPublicKeyAlgorithm_RSAEncryptOnly;
encalgstr = LANG("RSA Encrypt-only");
break;
}
case kPGPPublicKeyAlgorithm_RSA:
if( haveRSAAlgorithm ) {
fprintf( filebPtr->pgpout,
LANG("error: That key doesn't require a subkey\n"));
err = kPGPError_ItemAlreadyExists;
/* hmm... don't need a subkey.*/
goto ex;
}
default:
fprintf( filebPtr->pgpout,
LANG("error: Unknown public key algorithm\n"));
err = kPGPError_BadParams;
goto ex;
}
err = pgpGetKeyRemainingValidityDays( masterkey, &sigvalidfor );
pgpAssertNoErr(err);
err = pgpGetValidPassphrase( mainbPtr, masterkey, &passphrase,
&needsfree );
if( IsPGPError(err) )
goto ex;
signeed = 0;
/* must have: default encbits, sigalg, encalg, signeed,
sigvalidfor, passphrase*/
goto encr;
}
}
if (sigbitsstr && *sigbitsstr) {
sigbits = atoi( sigbitsstr );
if( sigbits < 768 )
goto ex;
} else {
if(compatible) {
err = askKeySize( filebPtr, encalg, encalgstr, &encbits );
if( err == kPGPError_UserAbort )
goto ex;
if( encbits > 1024 )
sigbits = 1024;
else
sigbits = encbits;
fprintf( filebPtr->pgpout, LANG("Generating a %d-bit %s key.\n"),
encbits, encalgstr);
} else {
err = askMasterKeySize( filebPtr, sigalg, sigalgstr, &sigbits );
if( err == kPGPError_UserAbort )
goto ex;
encbits = sigbits;
fprintf( filebPtr->pgpout, LANG("Generating a %d-bit %s key.\n"),
sigbits, sigalgstr);
}
}
/* ( !encOnly )*/
{
err = askUserIDString( filebPtr, useridstr );
if( err == kPGPError_UserAbort )
goto ex;
sigvalidfor=0;
if(!compatible) {
err = askKeyValidityPeriod( filebPtr, LANG("signing"), 0,
kMaxKeyExpirationDays, &sigvalidfor );
if( IsPGPError(err) )
goto ex;
}
fprintf( filebPtr->pgpout,
LANG("\nYou need a pass phrase to protect your %s secret key.\n"
"Your pass phrase can be any sentence or phrase and may have many\n"
"words, spaces, punctuation, or any other printable characters.\n"),
sigalgstr);
err = pgpPassphraseDialogCmdline( mainbPtr, TRUE, NULL, &passphrase);
needsfree = TRUE;
if( IsPGPError( err ) ) {
pgpShowError( filebPtr, err, __FILE__,__LINE__ );
goto ex;
}
if( sigalg == kPGPPublicKeyAlgorithm_DSA )
sigbits = (encbits > kMaxDSS_Bits ? kMaxDSS_Bits : encbits);
else
sigbits = encbits;
if( !compatible && encalg != kPGPPublicKeyAlgorithm_RSA
&& encalg != kPGPPublicKeyAlgorithm_RSAEncryptOnly
&& encalg != kPGPPublicKeyAlgorithm_RSASignOnly)
{
fprintf( filebPtr->pgpout,
LANG("\nPGP will generate a signing key. Do you also require an \n"
"encryption key? (Y/n) "));
fflush( filebPtr->pgpout );
signOnly = !getyesno(filebPtr, 'y', batchmode);
}
signeed = PGPGetKeyEntropyNeeded( context,
PGPOKeyGenParams( context, sigalg, sigbits ),
PGPOLastOption( context ));
}
encr:
/* must have: default encbits, sigalg, encalg, signeed, sigvalidfor,
passphrase*/
if( !compatible ) {
if(signOnly)
encneed = 0;
else if(encalg != kPGPPublicKeyAlgorithm_RSA
&& encalg != kPGPPublicKeyAlgorithm_RSAEncryptOnly
&& encalg != kPGPPublicKeyAlgorithm_RSASignOnly)
{
err = askKeySize( filebPtr, encalg, encalgstr, &encbits );
if( err == kPGPError_UserAbort )
goto ex;
err = askKeyValidityPeriod( filebPtr, LANG("encryption"),
sigvalidfor, (sigvalidfor == 0 ?
kMaxKeyExpirationDays : sigvalidfor),
&encvalidfor );
if(encvalidfor == 0)
encvalidfor = kPGPExpirationTime_Never;
}
}
encneed = PGPGetKeyEntropyNeeded( context,
PGPOKeyGenParams( context, encalg, encbits ),
PGPOLastOption( context ));
fprintf( filebPtr->pgpout,
LANG("\n\nNote that key generation is a lengthy process.\n") );
#if PGP_UNIX || PGP_WIN32
err = pgpAcquireEntropy( filebPtr, signeed+encneed );
#else
err = PGPCollectRandomDataDialog( context, signeed+encneed,
PGPOLastOption( context ) );
#endif
if( IsPGPError( err ) ) {
if(!compatible)
pgpShowError( filebPtr, err ,__FILE__,__LINE__);
goto ex;
}
if( !encOnly ) {
/* generate the master key*/
if(sigvalidfor == 0)
sigvalidfor = kPGPExpirationTime_Never;
err = PGPGenerateKey ( context, &masterkey,
PGPOKeySetRef( context, keyringset ),
PGPOKeyGenParams( context, sigalg, sigbits ),
PGPOKeyGenName( context, useridstr, strlen(useridstr) ),
PGPOExpiration( context, sigvalidfor ),
PGPOPassphrase( context, passphrase ),
PGPOEventHandler( context, genhandler, (PGPUserValue)
mainbPtr ),
PGPOLastOption( context ));
if( IsPGPError( err ) ) {
if(!compatible)
pgpShowError( filebPtr, err ,__FILE__,__LINE__);
goto ex;
}
/* set this key's trust to axiomatic*/
err = PGPSetKeyAxiomatic( masterkey, PGPOLastOption( context));
pgpAssertNoErr(err);
if(!compatible) {
/* make this the default signing key (unless MYNAME overrides)*/
fprintf( filebPtr->pgpout,
LANG("\nMake this the default signing key? (Y/n) "));
fflush(filebPtr->pgpout);
if(getyesno(filebPtr, 'y', batchmode))
err = PGPSetDefaultPrivateKey(masterkey);
} else
err = PGPSetDefaultPrivateKey(masterkey);
pgpAssertNoErr(err);
err = PGPsdkSavePrefs( context );
pgpAssertNoErr(err);
}
#ifndef TRY_RSA_MASTER_SUBKEY
if( sigalg == kPGPPublicKeyAlgorithm_RSA )
goto commit;
#endif
if( !signOnly ) {
/* generate the sub key*/
if(encvalidfor == 0)
encvalidfor = kPGPExpirationTime_Never;
err = PGPGenerateSubKey ( context, &subkey,
PGPOKeyGenMasterKey( context, masterkey ),
PGPOKeyGenParams( context, encalg, encbits ),
PGPOExpiration( context, encvalidfor ),
PGPOPassphrase( context, passphrase ),
PGPOEventHandler( context, genhandler, (PGPUserValue)
mainbPtr ),
PGPOLastOption( context ));
if( IsPGPError(err) ) {
if(!compatible)
pgpShowError( filebPtr, err,0,0); /*__FILE__,__LINE__);*/
goto ex;
}
}
commit:
err = PGPCommitKeyRingChanges( keyringset );
if( IsntPGPError(err))
fprintf( filebPtr->pgpout, LANG("\nKey generation completed.\n"));
ex:
if( keyringset ) {
PGPFreeKeySet( keyringset );
mainbPtr->workingRingSet = NULL;
}
if( passphrase && needsfree ) {
PGPFreeData(passphrase);
pgpRemoveFromPointerList( mainbPtr->leaks, passphrase );
}
return err;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -