Search code examples
cencryptiongnupggpgme

C GPGMe ignore user keyring


I recently finished a program that downloads public keys into memory, then creates an encrypted message with all of them. However, I have been having some difficulty creating a list of only the keys I download. When they are first downloaded, they are stored in gpgme_data_t. I was unable to find a function that converted this directly to a gpgme_key_t. Because of this, I just imported them into a new context. However, when I went to export the keys again in order to build a list for gpgme_op_encrypt, I end up with other keys from my local keyring. I tried setting disable-gpgconf, but that didn’t change anything. I also tried setting GNUPGHOME to a tmp directory, but that caused a segmentation fault when I called encrypt. Is there a way not to import the user’s keyring or to convert a gpgme_data_t or char* to a gpgme_key_t?


Solution

  • Is there a way not to import the user's keyring

    To prevent loading the users keyring, you will need set the GnuPG homedir of the context to someplace else.

    Below is an example without any error checking

    #include <gpgme.h>
    #include <locale.h>
    
    int main() {
        gpgme_ctx_t ctx;  // the context
        gpgme_error_t err; // errors
        gpgme_key_t key; // the key
        gpgme_keylist_result_t result; // the keylist results
    
        setlocale (LC_ALL, ""); // set the locale
        gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); // set gpgme locale
        gpgme_check_version(NULL); // initialize gpgme
    
        gpgme_new (&ctx); // initialize the context
    
        gpgme_ctx_set_engine_info (ctx, GPGME_PROTOCOL_OpenPGP, NULL, "/tmp/xyz"); // set the context GNUPGHOME to "/tmp/xyz"
    
        gpgme_op_keylist_start (ctx, NULL, 0); // start the keylist
    
        while (!(err = gpgme_op_keylist_next (ctx, &key))) { // loop through the keys in the keyring
            fprintf(stdout, "Key ID: %s\n", key->subkeys->keyid); // print out the keyid
            gpgme_key_unref (key); // release the key reference
        }
    
        gpgme_release(ctx); // release the context, all done
    
        return 0;
    }