Key generation with GPGME and GnuPG hangs at gpgme_op_genkey

Sandra Schreiner sasc0041 at stud.hs-kl.de
Wed Jan 27 16:58:30 CET 2016


>> Yes, that was the problem. I installed haveged and it worked. But it seems
>> that the key generation in my C++ application will not work, if a custom passphrase
>> callback is set. The key generation code is unchanged, but with the callback I get an
>> GPG_ERR_GENERAL error. The init and callback code is as follows:

>I cleaned your code up a bit and it works fine.

I can't get that work. I copy pasted you code in my project and executed your main, 
but I still get a 'general error'. In the meanwhile I upgraded my system from jesse to
debian 'testing'. I'm now using GnuPG 2.0.28 and GPGME 1.6 but the problem stays the
same. I build the application with QT Creator 3.6 without any specific flags for GnuPG.
Is there anything left I could check or try to figure out where the problem is?

Moreover I experience a very strange behaviour if i use my callback and a existing key for encryption.
I want to encrypt a string only for a specific lists of recipients, but I get a 
password request for a uid that wasn't even included in the recipients list. It is always the same key
with the uid 'dummy dummy...' (it was the first key ever created). The request is a window opened
by GnuPG Agent, which seems to ingore my custom password callback. The window will sometimes
just reopen periodically.  I thought GnuPG might include this dummy key by default so I tried to use 
the GPGME_ENCRYPT_NO_ENCRYPT_TO flag... but the result stays the same. I feel like I should
resign. The code for encryption is:

encrypt(const std::string &plaintext, std::set<std::string> uids,
                                 std::string &ciphertext) const{   
    bool result = false;
    //create a null terminated recipients array including current user
    int recipientsCount = uids.size() + 1;
    gpgme_key_t* recipients = new gpgme_key_t[recipientsCount];
    int i = 0;
    for(auto const &curUid: uids){
        //this will return the first gpgme key with exactly the given uid
        if(getGPGMEKey(curUid.c_str(), recipients[i], false)){
            i++;
        }
    }
    recipients[i] = NULL; // null terminate the array
    gpgme_data_t plain;
    gpgme_data_t cipher;
    if(!convertStringToData(plaintext, plain) || gpgme_data_new(&cipher)){
        //todo error code: data allocation error
    }
    else{
        //at this point GnuPG Agents asks for 'dummy dummy' password
        if(gpgme_op_encrypt_sign(mContext, recipients, (gpgme_encrypt_flags_t)(GPGME_ENCRYPT_NO_ENCRYPT_TO), plain, cipher)
                || gpgme_op_encrypt_result(mContext)->invalid_recipients) {
            //todo error code: encryption error
        }else{
            //now fetch the encrypted data
            if(convertDataToString(cipher, ciphertext)){
                result = true;
            }
        }
    }
    //release references and buffer
    //...
    return result;
}



More information about the Gnupg-users mailing list