1

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。また、実際にサイズが8であることも確認しましたoff_t。これがコンパイル方法です。

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

あなたが私に与えることができるどんな助けにも感謝します! これをデバッグするのに役立つものはまだ見つかりません..

4

1 に答える 1

0

提供されているサンプルでは、​​ の値がpDest実際に設定されることはありません。

gpgme_data_tオブジェクトの値を取得するにはdest、 を使用しますgpgme_data_release_and_get_mem

例:

#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

結果:

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-----
于 2015-04-26T01:44:18.763 に答える