2013-04-09 57 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

結果

相關問題