⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keygen.c

📁 PGP—Pretty Good Privacy
💻 C
📖 第 1 页 / 共 2 页
字号:
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 + -