gpgme.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "src/gpgme.h"
  2. #include <gpgme.h>
  3. #include <stdio.h>
  4. int rgpgfs_gpgme_get_encrypt_key(gpgme_ctx_t gpgme_ctx, const char *key_name,
  5. gpgme_key_t *key) {
  6. gpg_error_t err = gpgme_get_key(gpgme_ctx, key_name, key, 0);
  7. if (err != GPG_ERR_NO_ERROR) {
  8. fprintf(stderr, "Failed to load key %s: %s (%d)\n", key_name,
  9. gpg_strerror(err), err);
  10. return 1;
  11. }
  12. if (!(*key)->can_encrypt) {
  13. fprintf(stderr, "Selected key %s can not be used for encryption\n",
  14. (*key)->fpr);
  15. return 1;
  16. }
  17. return 0;
  18. }
  19. static int _rgpgfs_gpgme_write_data_to_file(FILE *file, gpgme_data_t data) {
  20. ssize_t count;
  21. char buf[BUFSIZ];
  22. while ((count = gpgme_data_read(data, buf, BUFSIZ)) > 0) {
  23. if (fwrite(buf, 1, count, file) != count) {
  24. fprintf(stderr, "%s: failed to write data to file", __func__);
  25. return 1;
  26. }
  27. }
  28. if (count != 0) {
  29. perror("_rgpgfs_gpgme_write_data_to_file: failed to load data into buffer");
  30. return 1;
  31. }
  32. return 0;
  33. }
  34. int rgpgfs_gpgme_data_to_file(const char *path, gpgme_data_t data) {
  35. if (gpgme_data_seek(data, 0, SEEK_SET) != 0) {
  36. perror("rgpgfs_gpgme_data_to_file: failed to seek");
  37. return 1;
  38. }
  39. FILE *file = fopen(path, "wb");
  40. if (file == NULL) {
  41. perror("rgpgfs_gpgme_data_to_file: failed to open file");
  42. return 1;
  43. }
  44. int res = _rgpgfs_gpgme_write_data_to_file(file, data);
  45. fclose(file);
  46. return res;
  47. }
  48. int rgpgfs_gpgme_encrypt_data_to_file(gpgme_ctx_t gpgme_ctx,
  49. gpgme_key_t recip_keys[],
  50. gpgme_data_t plain_data,
  51. const char *cipher_path) {
  52. gpgme_data_t cipher_data;
  53. if (gpgme_data_new(&cipher_data) != GPG_ERR_NO_ERROR) {
  54. fprintf(stderr, "rgpgfs_gpgme_encrypt_data_to_file: failed to prepare "
  55. "cipher data container\n");
  56. return 1;
  57. }
  58. int result = 0;
  59. // list of recipients may implicitly include the default recipient
  60. // (GPGME_ENCRYPT_NO_ENCRYPT_TO)
  61. gpgme_error_t enc_err =
  62. gpgme_op_encrypt(gpgme_ctx, recip_keys, 0, plain_data, cipher_data);
  63. if (enc_err == GPG_ERR_UNUSABLE_PUBKEY) {
  64. fprintf(stderr, "%s: some recipients are invalid\n", __func__);
  65. result = 1;
  66. } else if (enc_err != GPG_ERR_NO_ERROR) {
  67. fprintf(stderr, "%s: failed to encrypt: %s (%d)\n", __func__,
  68. gpg_strerror(enc_err), enc_err);
  69. result = 1;
  70. } else if (rgpgfs_gpgme_data_to_file(cipher_path, cipher_data)) {
  71. fprintf(stderr, "%s: failed to write cipher data to disk: %s\n", __func__,
  72. cipher_path);
  73. result = 1;
  74. }
  75. gpgme_data_release(cipher_data);
  76. return result;
  77. }
  78. int rgpgfs_gpgme_encrypt_file_to_file(gpgme_ctx_t gpgme_ctx,
  79. gpgme_key_t recip_keys[],
  80. const char *plain_path,
  81. const char *cipher_path) {
  82. gpgme_data_t plain_data;
  83. gpgme_error_t gpgme_read_err =
  84. gpgme_data_new_from_file(&plain_data, plain_path, 1);
  85. if (gpgme_read_err != GPG_ERR_NO_ERROR) {
  86. fprintf(stderr, "%s: failed to read file %s: %s (%d)\n", __func__,
  87. plain_path, gpg_strerror(gpgme_read_err), gpgme_read_err);
  88. return 1;
  89. }
  90. int result = rgpgfs_gpgme_encrypt_data_to_file(gpgme_ctx, recip_keys,
  91. plain_data, cipher_path);
  92. gpgme_data_release(plain_data);
  93. return result;
  94. }