我遇到了一个问题,这给我用 gpgme 追踪带来了一些麻烦。我用一个简单的测试程序(从我找到的另一个简单示例开始)复制了它,我将其粘贴在下面。这适用于 32 位基于 debian 的系统,但在 64 位系统上失败。特别是在 64 位情况下,我可以成功读取和解密(示例中未显示),但在加密中出现了一个相当神秘的错误:
$ ./test2 C37DBF71 Ciao!
version=1.2.0
Protocol name: OpenPGP
file=/usr/bin/gpg, home=(null)
Error in encrypting data. Error 1: General error (Unspecified source)
libgpgme 的版本也如上所示。
这是 的输出uname
,只是为了向您展示我在 64 位系统上运行:
$ uname -a
Linux spagan-laptop 3.2.0-39-generic #62-Ubuntu SMP Thu Feb 28 00:28:53 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
是的,我做的第一件事就是广泛尝试确保我正在定义_FILE_OFFSET_BITS=64
;我还检查了off_t
它的有效大小为 8。这就是我编译它的方式:
gcc -m64 -D_FILE_OFFSET_BITS=64 -g test2.c -lgpgme -L/usr/lib/x86_64-linux-gnu -lgpg-error -o test2
最后是测试程序:
#include <gpgme.h> /* gpgme */
#include <stdio.h> /* printf */
#include <unistd.h> /* write */
#include <errno.h> /* errno */
#include <locale.h> /* locale support */
#include <string.h> /* string support */
#include <stdlib.h> /* memory management */
#define SIZE 1024
int main(int argc, char **argv)
{
if (argc < 2) {
printf("ERROR. Usage: %s key message\n", argv[0]);
return -1;
}
char *m_key = argv[1];
char *pSource = argv[2];
char *pDest = malloc(65536);
char *p;
char buf[SIZE];
size_t read_bytes;
int tmp;
gpgme_ctx_t ceofcontext;
gpgme_error_t err;
gpgme_data_t data;
gpgme_engine_info_t enginfo;
/* The function `gpgme_check_version' must be called before any other
* function in the library, because it initializes the thread support
* subsystem in GPGME. (from the info page) */
setlocale (LC_ALL, "");
p = (char *) gpgme_check_version(NULL);
printf("version=%s\n",p);
/* set locale, because tests do also */
gpgme_set_locale(NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
/* check for OpenPGP support */
err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
if(err != GPG_ERR_NO_ERROR) return 1;
p = (char *) gpgme_get_protocol_name(GPGME_PROTOCOL_OpenPGP);
printf("Protocol name: %s\n",p);
/* get engine information */
err = gpgme_get_engine_info(&enginfo);
if(err != GPG_ERR_NO_ERROR) return 2;
printf("file=%s, home=%s\n",enginfo->file_name,enginfo->home_dir);
/* create our own context */
err = gpgme_new(&ceofcontext);
if(err != GPG_ERR_NO_ERROR) return 3;
/* set protocol to use in our context */
err = gpgme_set_protocol(ceofcontext,GPGME_PROTOCOL_OpenPGP);
if(err != GPG_ERR_NO_ERROR) return 4;
/* set engine info in our context; I changed it for ceof like this:
err = gpgme_ctx_set_engine_info (ceofcontext, GPGME_PROTOCOL_OpenPGP,
"/usr/bin/gpg","/home/user/nico/.ceof/gpg/");
but I'll use standard values for this example: */
err = gpgme_ctx_set_engine_info (ceofcontext, GPGME_PROTOCOL_OpenPGP,
enginfo->file_name,enginfo->home_dir);
if(err != GPG_ERR_NO_ERROR) return 5;
/* do ascii armor data, so output is readable in console */
gpgme_set_armor(ceofcontext, 1);
gpgme_data_t source;
gpgme_data_t dest;
//get key to encrypt, get the first key
gpgme_key_t key[2];
err = gpgme_op_keylist_start(ceofcontext, m_key, 0);
err = gpgme_op_keylist_next (ceofcontext, key);
if (err) {
printf("Key not found in current key-ring: %s\n", m_key);
return 1;
}
key[1] = 0; //set to NULL the second entry
//point to source buffer
err = gpgme_data_new_from_mem(&source, pSource, strlen(pSource), 0);
if (err != GPG_ERR_NO_ERROR) {
printf("Error in reading data to encrypt. Error %d: %s (%s)\n",
gpgme_err_code(err), gpgme_strerror(err), gpgme_strsource(err));
return 2;
}
//create dest buffer
err = gpgme_data_new(&dest);
if (err != GPG_ERR_NO_ERROR) {
printf("Error in creating output data buffer to encrypt. Error %d: %s (%s)\n",
gpgme_err_code(err), gpgme_strerror(err), gpgme_strsource(err));
return 3;
}
//encrypt text
gpgme_encrypt_flags_t flags;
flags = GPGME_ENCRYPT_NO_ENCRYPT_TO; //only specified recipient, no defaults please
err = gpgme_op_encrypt(ceofcontext, key, flags, source, dest);
if (err != GPG_ERR_NO_ERROR) {
printf("Error in encrypting data. Error %d: %s (%s)\n",
gpgme_err_code(err), gpgme_strerror(err), gpgme_strsource(err));
return 4;
}
//retrieve result
printf("Result: \n%s\n", pDest);
//release key and buffers
gpgme_key_release(key[0]);
gpgme_data_release(dest);
gpgme_data_release(source);
free(pDest);
/* free context */
gpgme_release(ceofcontext);
return 0;
}
非常感谢您能给我的任何帮助!我还没有发现任何有用的东西来帮助我调试这个..