2013-04-09 54 views
1

我正面临一个问题,它给我带来一点麻烦,可以用gpgme跟踪。 我已经复制了一个简单的测试程序(从我发现的另一个简单的例子开始),我粘贴下面。这适用于基于32位debian的系统,但在64位系统上失败。 特别地,在64位的情况下,我可以成功地读取和解密(未在所示的例子中),但我在加密得到一个相当神秘的错误:gpgme无法在64位debian上加密

$ ./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 有效size这是我如何编译:

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; 
} 

非常感谢任何帮助,您可以给我! 我还没有发现任何有用的东西,但还没有帮助我调试此。

回答

0

在提供的示例中,pDest的值从未实际设置。

为了得到gpgme_data_t对象dest的值,请使用gpgme_data_release_and_get_mem

例如:

version=1.4.2 
Protocol name: OpenPGP 
file=/usr/bin/gpg, home=(null) 
Result: 
-----BEGIN PGP MESSAGE----- 
Version: GnuPG v1 

hQIMA33UcjHVsYaXARAAh1txbI4bSsterGLf2d1AhrjQaugDfqaqSX32itxPKv1K 
<SNIP> 
EHlJTb0rVRvnTGjp5yLMy/hlw4hEtTh7HA== 
=LRyw 
-----END PGP MESSAGE----- 

#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 *p; 
    size_t read_bytes; 
    gpgme_ctx_t ceofcontext; 
    gpgme_error_t err; 

    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;  
    } 

    p = gpgme_data_release_and_get_mem(dest, &read_bytes); 

    p[read_bytes] = 0; 

    //retrieve result 
    printf("Result: \n%s\n", p); 

    //release key and buffers 
    gpgme_key_release(key[0]); 
    gpgme_data_release(source); 

    /* free context */ 
    gpgme_release(ceofcontext); 

    return 0; 
} 

在编译时gcc -Wall -m64 -D_FILE_OFFSET_BITS=64 -g test2.c -lgpgme -lgpg-error -o test2

结果

相关问题