diff options
author | JinWang An <jinwang.an@samsung.com> | 2021-12-01 16:54:38 +0900 |
---|---|---|
committer | JinWang An <jinwang.an@samsung.com> | 2021-12-01 16:54:38 +0900 |
commit | ca69957d6d6eeb4e69e77a70106785570050901b (patch) | |
tree | a3422b4ae6b55358960a4b9c3795adc9e41e0857 /src | |
parent | 098220f633aae872d150caa28de0f8b0f6074827 (diff) | |
download | gpgme-ca69957d6d6eeb4e69e77a70106785570050901b.tar.gz gpgme-ca69957d6d6eeb4e69e77a70106785570050901b.tar.bz2 gpgme-ca69957d6d6eeb4e69e77a70106785570050901b.zip |
Imported Upstream version 1.15.0upstream/1.15.0
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/Makefile.in | 61 | ||||
-rw-r--r-- | src/cJSON.c | 27 | ||||
-rw-r--r-- | src/context.h | 2 | ||||
-rw-r--r-- | src/engine-assuan.c | 27 | ||||
-rw-r--r-- | src/engine-backend.h | 6 | ||||
-rw-r--r-- | src/engine-g13.c | 2 | ||||
-rw-r--r-- | src/engine-gpg.c | 101 | ||||
-rw-r--r-- | src/engine-gpgconf.c | 2 | ||||
-rw-r--r-- | src/engine-gpgsm.c | 4 | ||||
-rw-r--r-- | src/engine-spawn.c | 2 | ||||
-rw-r--r-- | src/engine-uiserver.c | 2 | ||||
-rw-r--r-- | src/engine.c | 32 | ||||
-rw-r--r-- | src/engine.h | 10 | ||||
-rw-r--r-- | src/export.c | 16 | ||||
-rw-r--r-- | src/gpgme-json.c | 24 | ||||
-rw-r--r-- | src/gpgme.def | 6 | ||||
-rw-r--r-- | src/gpgme.h.in | 24 | ||||
-rw-r--r-- | src/libgpgme.vers | 6 | ||||
-rw-r--r-- | src/op-support.c | 4 | ||||
-rw-r--r-- | src/passphrase.c | 3 | ||||
-rw-r--r-- | src/revsig.c | 203 | ||||
-rw-r--r-- | src/setexpire.c | 193 | ||||
-rw-r--r-- | src/status-table.c | 1 | ||||
-rw-r--r-- | src/util.h | 9 | ||||
-rw-r--r-- | src/versioninfo.rc.in | 3 |
26 files changed, 674 insertions, 98 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 1bbb538..35add9c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -79,7 +79,9 @@ main_sources = \ encrypt.c encrypt-sign.c decrypt.c decrypt-verify.c verify.c \ sign.c passphrase.c progress.c \ key.c keylist.c keysign.c trust-item.c trustlist.c tofupolicy.c \ + revsig.c \ import.c export.c genkey.c delete.c edit.c getauditlog.c \ + setexpire.c \ opassuan.c passwd.c spawn.c assuan-support.c \ engine.h engine-backend.h engine.c engine-gpg.c status-table.c \ engine-gpgsm.c engine-assuan.c engine-gpgconf.c \ diff --git a/src/Makefile.in b/src/Makefile.in index f219399..8b323ed 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -177,14 +177,15 @@ am__libgpgme_glib_la_SOURCES_DIST = util.h conversion.c b64dec.c \ wait-user.c wait.h op-support.c encrypt.c encrypt-sign.c \ decrypt.c decrypt-verify.c verify.c sign.c passphrase.c \ progress.c key.c keylist.c keysign.c trust-item.c trustlist.c \ - tofupolicy.c import.c export.c genkey.c delete.c edit.c \ - getauditlog.c opassuan.c passwd.c spawn.c assuan-support.c \ - engine.h engine-backend.h engine.c engine-gpg.c status-table.c \ - engine-gpgsm.c engine-assuan.c engine-gpgconf.c \ - engine-uiserver.c engine-g13.c vfs-mount.c vfs-create.c \ - engine-spawn.c gpgconf.c queryswdb.c sema.h priv-io.h ath.h \ - posix-util.c posix-io.c w32-util.c sys-util.h dirinfo.c \ - debug.c debug.h gpgme.c version.c error.c ath.c w32-glib-io.c + tofupolicy.c revsig.c import.c export.c genkey.c delete.c \ + edit.c getauditlog.c setexpire.c opassuan.c passwd.c spawn.c \ + assuan-support.c engine.h engine-backend.h engine.c \ + engine-gpg.c status-table.c engine-gpgsm.c engine-assuan.c \ + engine-gpgconf.c engine-uiserver.c engine-g13.c vfs-mount.c \ + vfs-create.c engine-spawn.c gpgconf.c queryswdb.c sema.h \ + priv-io.h ath.h posix-util.c posix-io.c w32-util.c sys-util.h \ + dirinfo.c debug.c debug.h gpgme.c version.c error.c ath.c \ + w32-glib-io.c @HAVE_UISERVER_TRUE@am__objects_1 = engine-uiserver.lo @HAVE_DOSISH_SYSTEM_FALSE@am__objects_2 = posix-util.lo posix-io.lo @HAVE_DOSISH_SYSTEM_TRUE@am__objects_2 = w32-util.lo @@ -195,14 +196,14 @@ am__objects_3 = conversion.lo b64dec.lo get-env.lo parsetlv.lo \ wait-private.lo wait-user.lo op-support.lo encrypt.lo \ encrypt-sign.lo decrypt.lo decrypt-verify.lo verify.lo sign.lo \ passphrase.lo progress.lo key.lo keylist.lo keysign.lo \ - trust-item.lo trustlist.lo tofupolicy.lo import.lo export.lo \ - genkey.lo delete.lo edit.lo getauditlog.lo opassuan.lo \ - passwd.lo spawn.lo assuan-support.lo engine.lo engine-gpg.lo \ - status-table.lo engine-gpgsm.lo engine-assuan.lo \ - engine-gpgconf.lo $(am__objects_1) engine-g13.lo vfs-mount.lo \ - vfs-create.lo engine-spawn.lo gpgconf.lo queryswdb.lo \ - $(am__objects_2) dirinfo.lo debug.lo gpgme.lo version.lo \ - error.lo ath.lo + trust-item.lo trustlist.lo tofupolicy.lo revsig.lo import.lo \ + export.lo genkey.lo delete.lo edit.lo getauditlog.lo \ + setexpire.lo opassuan.lo passwd.lo spawn.lo assuan-support.lo \ + engine.lo engine-gpg.lo status-table.lo engine-gpgsm.lo \ + engine-assuan.lo engine-gpgconf.lo $(am__objects_1) \ + engine-g13.lo vfs-mount.lo vfs-create.lo engine-spawn.lo \ + gpgconf.lo queryswdb.lo $(am__objects_2) dirinfo.lo debug.lo \ + gpgme.lo version.lo error.lo ath.lo @BUILD_W32_GLIB_TRUE@am_libgpgme_glib_la_OBJECTS = $(am__objects_3) \ @BUILD_W32_GLIB_TRUE@ w32-glib-io.lo libgpgme_glib_la_OBJECTS = $(am_libgpgme_glib_la_OBJECTS) @@ -223,14 +224,15 @@ am__libgpgme_la_SOURCES_DIST = util.h conversion.c b64dec.c get-env.c \ wait.h op-support.c encrypt.c encrypt-sign.c decrypt.c \ decrypt-verify.c verify.c sign.c passphrase.c progress.c key.c \ keylist.c keysign.c trust-item.c trustlist.c tofupolicy.c \ - import.c export.c genkey.c delete.c edit.c getauditlog.c \ - opassuan.c passwd.c spawn.c assuan-support.c engine.h \ - engine-backend.h engine.c engine-gpg.c status-table.c \ - engine-gpgsm.c engine-assuan.c engine-gpgconf.c \ - engine-uiserver.c engine-g13.c vfs-mount.c vfs-create.c \ - engine-spawn.c gpgconf.c queryswdb.c sema.h priv-io.h ath.h \ - posix-util.c posix-io.c w32-util.c sys-util.h dirinfo.c \ - debug.c debug.h gpgme.c version.c error.c ath.c w32-io.c + revsig.c import.c export.c genkey.c delete.c edit.c \ + getauditlog.c setexpire.c opassuan.c passwd.c spawn.c \ + assuan-support.c engine.h engine-backend.h engine.c \ + engine-gpg.c status-table.c engine-gpgsm.c engine-assuan.c \ + engine-gpgconf.c engine-uiserver.c engine-g13.c vfs-mount.c \ + vfs-create.c engine-spawn.c gpgconf.c queryswdb.c sema.h \ + priv-io.h ath.h posix-util.c posix-io.c w32-util.c sys-util.h \ + dirinfo.c debug.c debug.h gpgme.c version.c error.c ath.c \ + w32-io.c @HAVE_DOSISH_SYSTEM_TRUE@am__objects_4 = w32-io.lo am_libgpgme_la_OBJECTS = $(am__objects_3) $(am__objects_4) libgpgme_la_OBJECTS = $(am_libgpgme_la_OBJECTS) @@ -290,7 +292,8 @@ am__depfiles_remade = $(DEPDIR)/setenv.Plo $(DEPDIR)/stpcpy.Plo \ ./$(DEPDIR)/parsetlv.Plo ./$(DEPDIR)/passphrase.Plo \ ./$(DEPDIR)/passwd.Plo ./$(DEPDIR)/posix-io.Plo \ ./$(DEPDIR)/posix-util.Plo ./$(DEPDIR)/progress.Plo \ - ./$(DEPDIR)/queryswdb.Plo ./$(DEPDIR)/sig-notation.Plo \ + ./$(DEPDIR)/queryswdb.Plo ./$(DEPDIR)/revsig.Plo \ + ./$(DEPDIR)/setexpire.Plo ./$(DEPDIR)/sig-notation.Plo \ ./$(DEPDIR)/sign.Plo ./$(DEPDIR)/signers.Plo \ ./$(DEPDIR)/spawn.Plo ./$(DEPDIR)/status-table.Plo \ ./$(DEPDIR)/tofupolicy.Plo ./$(DEPDIR)/trust-item.Plo \ @@ -595,7 +598,9 @@ main_sources = \ encrypt.c encrypt-sign.c decrypt.c decrypt-verify.c verify.c \ sign.c passphrase.c progress.c \ key.c keylist.c keysign.c trust-item.c trustlist.c tofupolicy.c \ + revsig.c \ import.c export.c genkey.c delete.c edit.c getauditlog.c \ + setexpire.c \ opassuan.c passwd.c spawn.c assuan-support.c \ engine.h engine-backend.h engine.c engine-gpg.c status-table.c \ engine-gpgsm.c engine-assuan.c engine-gpgconf.c \ @@ -943,6 +948,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posix-util.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/progress.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/queryswdb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revsig.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setexpire.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sig-notation.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sign.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signers.Plo@am__quote@ # am--include-marker @@ -1247,6 +1254,8 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/posix-util.Plo -rm -f ./$(DEPDIR)/progress.Plo -rm -f ./$(DEPDIR)/queryswdb.Plo + -rm -f ./$(DEPDIR)/revsig.Plo + -rm -f ./$(DEPDIR)/setexpire.Plo -rm -f ./$(DEPDIR)/sig-notation.Plo -rm -f ./$(DEPDIR)/sign.Plo -rm -f ./$(DEPDIR)/signers.Plo @@ -1370,6 +1379,8 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/posix-util.Plo -rm -f ./$(DEPDIR)/progress.Plo -rm -f ./$(DEPDIR)/queryswdb.Plo + -rm -f ./$(DEPDIR)/revsig.Plo + -rm -f ./$(DEPDIR)/setexpire.Plo -rm -f ./$(DEPDIR)/sig-notation.Plo -rm -f ./$(DEPDIR)/sign.Plo -rm -f ./$(DEPDIR)/signers.Plo diff --git a/src/cJSON.c b/src/cJSON.c index f233848..7769b0e 100644 --- a/src/cJSON.c +++ b/src/cJSON.c @@ -66,25 +66,14 @@ #define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) /* We use malloc function wrappers from gpgrt (aka libgpg-error). */ -#if GPGRT_VERSION_NUMBER >= 0x011c00 /* 1.28 */ -# include <gpgrt.h> -# define xtrycalloc(a,b) gpgrt_calloc ((a), (b)) -# define xtrystrdup(a) gpgrt_strdup ((a)) -# define xfree(a) gpgrt_free ((a)) -# if CALLOC_ONLY -# define xtrymalloc(a) gpgrt_calloc (1, (a)) -# else -# define xtrymalloc(a) gpgrt_malloc ((a)) -# endif -#else /* Without gpgrt (aka libgpg-error). */ -# define xtrycalloc(a,b) calloc ((a), (b)) -# define xtrystrdup(a) strdup ((a)) -# define xfree(a) free ((a)) -# if CALLOC_ONLY -# define xtrymalloc(a) calloc (1, (a)) -# else -# define xtrymalloc(a) malloc ((a)) -# endif +#include <gpgrt.h> +#define xtrycalloc(a,b) gpgrt_calloc ((a), (b)) +#define xtrystrdup(a) gpgrt_strdup ((a)) +#define xfree(a) gpgrt_free ((a)) +#if CALLOC_ONLY +# define xtrymalloc(a) gpgrt_calloc (1, (a)) +#else +# define xtrymalloc(a) gpgrt_malloc ((a)) #endif diff --git a/src/context.h b/src/context.h index 25dfc79..3ed3818 100644 --- a/src/context.h +++ b/src/context.h @@ -39,7 +39,7 @@ typedef enum OPDATA_IMPORT, OPDATA_GENKEY, OPDATA_KEYLIST, OPDATA_EDIT, OPDATA_VERIFY, OPDATA_TRUSTLIST, OPDATA_ASSUAN, OPDATA_VFS_MOUNT, OPDATA_PASSWD, OPDATA_EXPORT, OPDATA_KEYSIGN, OPDATA_TOFU_POLICY, - OPDATA_QUERY_SWDB + OPDATA_QUERY_SWDB, OPDATA_SETEXPIRE, OPDATA_REVSIG } ctx_op_data_id_t; diff --git a/src/engine-assuan.c b/src/engine-assuan.c index a40328f..ab9d05a 100644 --- a/src/engine-assuan.c +++ b/src/engine-assuan.c @@ -445,7 +445,10 @@ llass_set_locale (void *engine, int category, const char *value) static gpgme_error_t inquire_cb (engine_llass_t llass, const char *keyword, const char *args) { - gpg_error_t err; + gpg_error_t err, err2; + gpgme_data_t data = NULL; + char buf[1024]; + gpgme_ssize_t n; if (llass->opt.gpg_agent && !strcmp (keyword, "PINENTRY_LAUNCHED")) { @@ -454,17 +457,23 @@ inquire_cb (engine_llass_t llass, const char *keyword, const char *args) if (llass->user.inq_cb) { - gpgme_data_t data = NULL; - err = llass->user.inq_cb (llass->user.inq_cb_value, keyword, args, &data); if (!err && data) { - /* FIXME: Returning data is not yet implemented. However we - need to allow the caller to cleanup his data object. - Thus we run the callback in finish mode immediately. */ - err = llass->user.inq_cb (llass->user.inq_cb_value, - NULL, NULL, &data); + while ((n = gpgme_data_read (data, buf, sizeof buf)) > 0) + { + err = assuan_send_data (llass->assuan_ctx, buf, n); + if (err) + break; + } + /* Tell the caller that we are finished with the data + * object. The error code from assuan_send_data has + * priority over the one from the cleanup function. */ + err2 = llass->user.inq_cb (llass->user.inq_cb_value, + NULL, NULL, &data); + if (!err) + err = err2; } } else @@ -824,10 +833,12 @@ struct engine_ops _gpgme_engine_ops_assuan = NULL, /* keylist_ext */ NULL, /* keylist_data */ NULL, /* keysign */ + NULL, /* revsig */ NULL, /* tofu_policy */ NULL, /* sign */ NULL, /* verify */ NULL, /* getauditlog */ + NULL, /* setexpire */ llass_transact, /* opassuan_transact */ NULL, /* conf_load */ NULL, /* conf_save */ diff --git a/src/engine-backend.h b/src/engine-backend.h index c8bfad9..8f90b6c 100644 --- a/src/engine-backend.h +++ b/src/engine-backend.h @@ -108,6 +108,9 @@ struct engine_ops gpgme_key_t key, const char *userid, unsigned long expires, unsigned int flags, gpgme_ctx_t ctx); + gpgme_error_t (*revsig) (void *engine, + gpgme_key_t key, gpgme_key_t signing_key, + const char *userid, unsigned int flags); gpgme_error_t (*tofu_policy) (void *engine, gpgme_key_t key, gpgme_tofu_policy_t policy); @@ -120,6 +123,9 @@ struct engine_ops gpgme_ctx_t ctx); gpgme_error_t (*getauditlog) (void *engine, gpgme_data_t output, unsigned int flags); + gpgme_error_t (*setexpire) (void *engine, gpgme_key_t key, + unsigned long expires, const char *subfprs, + unsigned int reserved); gpgme_error_t (*opassuan_transact) (void *engine, const char *command, gpgme_assuan_data_cb_t data_cb, diff --git a/src/engine-g13.c b/src/engine-g13.c index 45f6c94..3c11149 100644 --- a/src/engine-g13.c +++ b/src/engine-g13.c @@ -804,10 +804,12 @@ struct engine_ops _gpgme_engine_ops_g13 = NULL, /* keylist_ext */ NULL, /* keylist_data */ NULL, /* keysign */ + NULL, /* revsig */ NULL, /* tofu_policy */ NULL, /* sign */ NULL, /* verify */ NULL, /* getauditlog */ + NULL, /* setexpire */ g13_transact, NULL, /* conf_load */ NULL, /* conf_save */ diff --git a/src/engine-gpg.c b/src/engine-gpg.c index af2533d..02a10ec 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -3211,6 +3211,52 @@ gpg_keysign (void *engine, gpgme_key_t key, const char *userid, static gpgme_error_t +gpg_revsig (void *engine, gpgme_key_t key, gpgme_key_t signing_key, + const char *userid, unsigned int flags) +{ + engine_gpg_t gpg = engine; + gpgme_error_t err; + const char *s; + + if (!key || !key->fpr) + return gpg_error (GPG_ERR_INV_ARG); + + if (!have_gpg_version (gpg, "2.2.24")) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + err = add_arg (gpg, "--quick-revoke-sig"); + + if (!err) + err = add_arg (gpg, "--"); + + if (!err) + err = add_arg (gpg, key->fpr); + + if (!err) + err = add_arg (gpg, signing_key->fpr); + + if (!err && userid) + { + if ((flags & GPGME_REVSIG_LFSEP)) + { + for (; !err && (s = strchr (userid, '\n')); userid = s + 1) + if ((s - userid)) + err = add_arg_len (gpg, "=", userid, s - userid); + if (!err && *userid) + err = add_arg_pfx (gpg, "=", userid); + } + else + err = add_arg_pfx (gpg, "=", userid); + } + + if (!err) + err = start (gpg); + + return err; +} + + +static gpgme_error_t gpg_tofu_policy (void *engine, gpgme_key_t key, gpgme_tofu_policy_t policy) { engine_gpg_t gpg = engine; @@ -3426,6 +3472,59 @@ gpg_getauditlog (void *engine, gpgme_data_t output, unsigned int flags) #undef MYBUFLEN } +static gpgme_error_t +gpg_setexpire (void *engine, gpgme_key_t key, unsigned long expires, + const char *subfprs, unsigned int reserved) +{ + engine_gpg_t gpg = engine; + gpgme_error_t err; + const char *s; + + if (reserved) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!key || !key->fpr) + return gpg_error (GPG_ERR_INV_ARG); + + if (!have_gpg_version (gpg, "2.1.22")) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + err = add_arg (gpg, "--quick-set-expire"); + + if (!err) + err = add_arg (gpg, "--"); + + if (!err) + err = add_arg (gpg, key->fpr); + + if (!err) + { + char tmpbuf[8+20]; + snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires); + err = add_arg (gpg, tmpbuf); + } + + if (!err && subfprs) + { + for (; !err && (s = strchr (subfprs, '\n')); subfprs = s + 1) + { + if ((s - subfprs)) + { + err = add_arg_len (gpg, NULL, subfprs, s - subfprs); + } + } + if (!err && *subfprs) + { + err = add_arg (gpg, subfprs); + } + } + + if (!err) + err = start (gpg); + + return err; +} + struct engine_ops _gpgme_engine_ops_gpg = @@ -3460,10 +3559,12 @@ struct engine_ops _gpgme_engine_ops_gpg = gpg_keylist_ext, gpg_keylist_data, gpg_keysign, + gpg_revsig, gpg_tofu_policy, /* tofu_policy */ gpg_sign, gpg_verify, gpg_getauditlog, + gpg_setexpire, NULL, /* opassuan_transact */ NULL, /* conf_load */ NULL, /* conf_save */ diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c index d4465e9..28f9115 100644 --- a/src/engine-gpgconf.c +++ b/src/engine-gpgconf.c @@ -1302,10 +1302,12 @@ struct engine_ops _gpgme_engine_ops_gpgconf = NULL, /* keylist_ext */ NULL, /* keylist_data */ NULL, /* keysign */ + NULL, /* revsig */ NULL, /* tofu_policy */ NULL, /* sign */ NULL, /* verify */ NULL, /* getauditlog */ + NULL, /* setexpire */ NULL, /* opassuan_transact */ gpgconf_conf_load, gpgconf_conf_save, diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index 671b385..d5f0d7a 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -573,9 +573,9 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir, _gpgme_io_close (gpgsm->output_cb.server_fd); if (gpgsm->message_cb.server_fd != -1) _gpgme_io_close (gpgsm->message_cb.server_fd); +#endif if (gpgsm->diag_cb.server_fd != -1) _gpgme_io_close (gpgsm->diag_cb.server_fd); -#endif if (err) gpgsm_release (gpgsm); @@ -2322,10 +2322,12 @@ struct engine_ops _gpgme_engine_ops_gpgsm = gpgsm_keylist_ext, NULL, /* keylist_data */ NULL, /* keysign */ + NULL, /* revsig */ NULL, /* tofu_policy */ gpgsm_sign, gpgsm_verify, gpgsm_getauditlog, + NULL, /* setexpire */ NULL, /* opassuan_transact */ NULL, /* conf_load */ NULL, /* conf_save */ diff --git a/src/engine-spawn.c b/src/engine-spawn.c index 0eeaeb1..368280f 100644 --- a/src/engine-spawn.c +++ b/src/engine-spawn.c @@ -464,10 +464,12 @@ struct engine_ops _gpgme_engine_ops_spawn = NULL, /* keylist_ext */ NULL, /* keylist_data */ NULL, /* keysign */ + NULL, /* revsig */ NULL, /* tofu_policy */ NULL, /* sign */ NULL, /* verify */ NULL, /* getauditlog */ + NULL, /* setexpire */ NULL, /* opassuan_transact */ NULL, /* conf_load */ NULL, /* conf_save */ diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c index c908ad7..9fce1de 100644 --- a/src/engine-uiserver.c +++ b/src/engine-uiserver.c @@ -1435,10 +1435,12 @@ struct engine_ops _gpgme_engine_ops_uiserver = NULL, /* keylist_ext */ NULL, /* keylist_data */ NULL, /* keysign */ + NULL, /* revsig */ NULL, /* tofu_policy */ uiserver_sign, uiserver_verify, NULL, /* getauditlog */ + NULL, /* setexpire */ NULL, /* opassuan_transact */ NULL, /* conf_load */ NULL, /* conf_save */ diff --git a/src/engine.c b/src/engine.c index ded2f4d..96b8d3a 100644 --- a/src/engine.c +++ b/src/engine.c @@ -258,11 +258,7 @@ gpgme_get_engine_info (gpgme_engine_info_t *info) if (!err && version && engine_minimal_version && !_gpgme_compare_versions (version, engine_minimal_version)) { -#if GPG_ERROR_VERSION_NUMBER < 0x011900 /* 1.25 */ - err = gpg_error (GPG_ERR_NO_ENGINE); -#else err = gpg_error (GPG_ERR_ENGINE_TOO_OLD); -#endif } /* Now set the dummy version for pseudo engines. */ @@ -825,6 +821,20 @@ _gpgme_engine_op_keysign (engine_t engine, gpgme_key_t key, const char *userid, gpgme_error_t +_gpgme_engine_op_revsig (engine_t engine, gpgme_key_t key, gpgme_key_t signing_key, + const char *userid, unsigned int flags) +{ + if (!engine) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!engine->ops->revsig) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + return (*engine->ops->revsig) (engine->engine, key, signing_key, userid, flags); +} + + +gpgme_error_t _gpgme_engine_op_tofu_policy (engine_t engine, gpgme_key_t key, gpgme_tofu_policy_t policy) { @@ -1128,3 +1138,17 @@ _gpgme_engine_op_spawn (engine_t engine, return (*engine->ops->opspawn) (engine->engine, file, argv, datain, dataout, dataerr, flags); } + +gpgme_error_t +_gpgme_engine_op_setexpire (engine_t engine, gpgme_key_t key, + unsigned long expires, const char *subfprs, + unsigned int reserved) +{ + if (!engine) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!engine->ops->setexpire) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + return (*engine->ops->setexpire) (engine->engine, key, expires, subfprs, reserved); +} diff --git a/src/engine.h b/src/engine.h index c512a25..d7ff542 100644 --- a/src/engine.h +++ b/src/engine.h @@ -131,6 +131,11 @@ gpgme_error_t _gpgme_engine_op_keysign (engine_t engine, unsigned long expires, unsigned int flags, gpgme_ctx_t ctx); +gpgme_error_t _gpgme_engine_op_revsig (engine_t engine, + gpgme_key_t key, + gpgme_key_t signing_key, + const char *userid, + unsigned int flags); gpgme_error_t _gpgme_engine_op_tofu_policy (engine_t engine, gpgme_key_t key, gpgme_tofu_policy_t policy); @@ -210,6 +215,11 @@ gpgme_error_t _gpgme_engine_op_spawn (engine_t engine, gpgme_data_t dataout, gpgme_data_t dataerr, unsigned int flags); +gpgme_error_t _gpgme_engine_op_setexpire (engine_t engine, + gpgme_key_t key, + unsigned long expires, + const char *subfprs, + unsigned int reserved); /* The available engine option flags. */ #define GPGME_ENGINE_FLAG_OFFLINE 1 diff --git a/src/export.c b/src/export.c index 7e394df..f827efa 100644 --- a/src/export.c +++ b/src/export.c @@ -163,6 +163,14 @@ export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern, if (err) return err; + if (ctx->passphrase_cb) + { + err = _gpgme_engine_set_command_handler + (ctx->engine, _gpgme_passphrase_command_handler, ctx); + if (err) + return err; + } + _gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx); return _gpgme_engine_op_export (ctx->engine, pattern, mode, keydata, @@ -258,6 +266,14 @@ export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[], if (err) return err; + if (ctx->passphrase_cb) + { + err = _gpgme_engine_set_command_handler + (ctx->engine, _gpgme_passphrase_command_handler, ctx); + if (err) + return err; + } + _gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx); return _gpgme_engine_op_export_ext (ctx->engine, pattern, mode, keydata, diff --git a/src/gpgme-json.c b/src/gpgme-json.c index bcaa1fc..d3b8035 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -41,10 +41,6 @@ #include "cJSON.h" -#if GPGRT_VERSION_NUMBER < 0x011c00 /* 1.28 */ -int main (void){fputs ("Build with Libgpg-error >= 1.28!\n", stderr);return 1;} -#else /* libgpg-error >= 1.28 */ - /* We don't allow a request with more than 64 MiB. */ #define MAX_REQUEST_SIZE (64 * 1024 * 1024) @@ -246,9 +242,6 @@ static gpg_error_t add_base64_to_object (cjson_t object, const char *name, const void *data, size_t datalen) { -#if GPGRT_VERSION_NUMBER < 0x011d00 /* 1.29 */ - return gpg_error (GPG_ERR_NOT_SUPPORTED); -#else gpg_err_code_t err; estream_t fp = NULL; gpgrt_b64state_t state = NULL; @@ -309,7 +302,6 @@ add_base64_to_object (cjson_t object, const char *name, gpgrt_b64enc_finish (state); es_fclose (fp); return err; -#endif } @@ -629,10 +621,6 @@ release_onetime_context (gpgme_ctx_t ctx) static gpg_error_t data_from_base64_string (gpgme_data_t *r_data, cjson_t json) { -#if GPGRT_VERSION_NUMBER < 0x011d00 /* 1.29 */ - *r_data = NULL; - return gpg_error (GPG_ERR_NOT_SUPPORTED); -#else gpg_error_t err; size_t len; char *buf = NULL; @@ -685,7 +673,6 @@ data_from_base64_string (gpgme_data_t *r_data, cjson_t json) xfree (buf); gpgrt_b64dec_finish (state); return err; -#endif } @@ -3553,10 +3540,8 @@ interactive_repl (void) int first; es_setvbuf (es_stdin, NULL, _IONBF, 0); -#if GPGRT_VERSION_NUMBER >= 0x011d00 /* 1.29 */ es_fprintf (es_stderr, "%s %s ready (enter \",help\" for help)\n", gpgrt_strusage (11), gpgrt_strusage (13)); -#endif do { es_fputs ("> ", es_stderr); @@ -3828,13 +3813,6 @@ my_strusage( int level ) int main (int argc, char *argv[]) { -#if GPGRT_VERSION_NUMBER < 0x011d00 /* 1.29 */ - - fprintf (stderr, "WARNING: Old libgpg-error - using limited mode\n"); - native_messaging_repl (); - -#else /* This is a modern libgp-error. */ - enum { CMD_DEFAULT = 0, CMD_INTERACTIVE = 'i', CMD_SINGLE = 's', @@ -3950,7 +3928,5 @@ main (int argc, char *argv[]) if (opt_debug) log_debug ("ready"); -#endif /* This is a modern libgp-error. */ return 0; } -#endif /* libgpg-error >= 1.28 */ diff --git a/src/gpgme.def b/src/gpgme.def index c690220..6644cae 100644 --- a/src/gpgme.def +++ b/src/gpgme.def @@ -274,5 +274,11 @@ EXPORTS gpgme_data_new_from_estream @204 + gpgme_op_setexpire @205 + gpgme_op_setexpire_start @206 + + gpgme_op_revsig @207 + gpgme_op_revsig_start @208 + ; END diff --git a/src/gpgme.h.in b/src/gpgme.h.in index b4f817b..1defa4d 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1868,6 +1868,13 @@ gpgme_error_t gpgme_op_set_uid_flag (gpgme_ctx_t ctx, gpgme_key_t key, const char *userid, const char *name, const char *value); +/* Change the expiry of a key. */ +gpgme_error_t gpgme_op_setexpire_start (gpgme_ctx_t ctx, + gpgme_key_t key, unsigned long expires, + const char *subfprs, unsigned int reserved); +gpgme_error_t gpgme_op_setexpire (gpgme_ctx_t ctx, + gpgme_key_t key, unsigned long expires, + const char *subfprs, unsigned int reserved); /* Retrieve a pointer to the result of a genkey, createkey, or * createsubkey operation. */ @@ -1912,6 +1919,20 @@ gpgme_error_t gpgme_op_keysign (gpgme_ctx_t ctx, unsigned int flags); +/* Flags for the signature revoking functions. */ +#define GPGME_REVSIG_LFSEP (1 << 8) /* Indicate LF separated user ids. */ + +/* Revoke the signatures made with SIGNING_KEY on the USERID(s) of KEY. */ +gpgme_error_t gpgme_op_revsig_start (gpgme_ctx_t ctx, + gpgme_key_t key, + gpgme_key_t signing_key, + const char *userid, + unsigned int flags); +gpgme_error_t gpgme_op_revsig (gpgme_ctx_t ctx, + gpgme_key_t key, + gpgme_key_t signing_key, + const char *userid, + unsigned int flags); /* @@ -2555,7 +2576,8 @@ typedef enum GPGME_STATUS_TOFU_STATS_LONG = 97, GPGME_STATUS_NOTATION_FLAGS = 98, GPGME_STATUS_DECRYPTION_COMPLIANCE_MODE = 99, - GPGME_STATUS_VERIFICATION_COMPLIANCE_MODE = 100 + GPGME_STATUS_VERIFICATION_COMPLIANCE_MODE = 100, + GPGME_STATUS_CANCELED_BY_USER = 101 } gpgme_status_code_t; diff --git a/src/libgpgme.vers b/src/libgpgme.vers index 79cbeef..8e86e4e 100644 --- a/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -273,6 +273,12 @@ GPGME_1.0 { gpgme_err_code_from_syserror; gpgme_err_set_errno; + gpgme_op_setexpire; + gpgme_op_setexpire_start; + + gpgme_op_revsig; + gpgme_op_revsig_start; + local: *; diff --git a/src/op-support.c b/src/op-support.c index 6affb5e..88a133b 100644 --- a/src/op-support.c +++ b/src/op-support.c @@ -34,10 +34,6 @@ #include "util.h" #include "debug.h" -#if GPG_ERROR_VERSION_NUMBER < 0x011700 /* 1.23 */ -# define GPG_ERR_SUBKEYS_EXP_OR_REV 217 -#endif - gpgme_error_t diff --git a/src/passphrase.c b/src/passphrase.c index 2a7daea..140cd03 100644 --- a/src/passphrase.c +++ b/src/passphrase.c @@ -111,6 +111,9 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code, opd->no_passphrase = 1; break; + case GPGME_STATUS_CANCELED_BY_USER: + return gpg_error (GPG_ERR_CANCELED); + case GPGME_STATUS_EOF: if (opd->no_passphrase || opd->bad_passphrase) return gpg_error (GPG_ERR_BAD_PASSPHRASE); diff --git a/src/revsig.c b/src/revsig.c new file mode 100644 index 0000000..8c61f73 --- /dev/null +++ b/src/revsig.c @@ -0,0 +1,203 @@ +/* revsig.c - Revoke signature helpers. + * Copyright (C) 2020 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * GPGME is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <https://gnu.org/licenses/>. + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdlib.h> + +#include "gpgme.h" +#include "debug.h" +#include "context.h" +#include "ops.h" + + +typedef struct +{ + /* The error code from a FAILURE status line or 0. */ + gpg_error_t failure_code; + + /* The error code from certain ERROR status lines or 0. */ + gpg_error_t error_code; + +} *op_data_t; + + +/* Parse an error status line. Return the error location and the + error code. The function may modify ARGS. */ +static char * +parse_error (char *args, gpg_error_t *r_err) +{ + char *where = strchr (args, ' '); + char *which; + + if (where) + { + *where = '\0'; + which = where + 1; + + where = strchr (which, ' '); + if (where) + *where = '\0'; + + where = args; + } + else + { + *r_err = trace_gpg_error (GPG_ERR_INV_ENGINE); + return NULL; + } + + *r_err = atoi (which); + + return where; +} + + +static gpgme_error_t +revsig_status_handler (void *priv, gpgme_status_code_t code, char *args) +{ + gpgme_ctx_t ctx = (gpgme_ctx_t) priv; + gpgme_error_t err; + void *hook; + op_data_t opd; + char *loc; + + /* Pipe the status code through the progress status handler. */ + err = _gpgme_progress_status_handler (ctx, code, args); + if (err) + return err; + + err = _gpgme_op_data_lookup (ctx, OPDATA_REVSIG, &hook, -1, NULL); + opd = hook; + if (err) + return err; + + switch (code) + { + case GPGME_STATUS_ERROR: + loc = parse_error (args, &err); + if (!loc) + return err; + if (!opd->error_code) + opd->error_code = err; + break; + + case GPGME_STATUS_FAILURE: + opd->failure_code = _gpgme_parse_failure (args); + break; + + case GPGME_STATUS_EOF: + if (opd->error_code) + return opd->error_code; + else if (opd->failure_code) + return opd->failure_code; + break; + + case GPGME_STATUS_INQUIRE_MAXLEN: + if (ctx->status_cb && !ctx->full_status) + { + err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args); + if (err) + return err; + } + break; + + default: + break; + } + return 0; +} + + +/* Revoke the signature(s) on USERID of KEY made with SIGNING_KEY. + * If USERID is NULL, revoke signatures on all user ids. To put several + * user ids into USERID, separate them by LF and set the flag + * GPGME_REVSIG_LFSEP. */ +static gpgme_error_t +revsig_start (gpgme_ctx_t ctx, int synchronous, + gpgme_key_t key, gpgme_key_t signing_key, + const char *userid, unsigned int flags) +{ + gpgme_error_t err; + void *hook; + op_data_t opd; + + if (!ctx) + return gpg_error (GPG_ERR_INV_ARG); + + if (ctx->protocol != GPGME_PROTOCOL_OPENPGP) + return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL); + + if (!key) + return gpg_error (GPG_ERR_INV_ARG); + + err = _gpgme_op_reset (ctx, synchronous); + if (err) + return err; + + err = _gpgme_op_data_lookup (ctx, OPDATA_REVSIG, &hook, sizeof (*opd), + NULL); + opd = hook; + if (err) + return err; + + _gpgme_engine_set_status_handler (ctx->engine, revsig_status_handler, ctx); + + if (ctx->passphrase_cb) + { + err = _gpgme_engine_set_command_handler + (ctx->engine, _gpgme_passphrase_command_handler, ctx); + if (err) + return err; + } + + return _gpgme_engine_op_revsig (ctx->engine, key, signing_key, userid, flags); +} + + +gpgme_error_t +gpgme_op_revsig_start (gpgme_ctx_t ctx, gpgme_key_t key, gpgme_key_t signing_key, + const char *userid, unsigned int flags) +{ + gpgme_error_t err; + + TRACE_BEG (DEBUG_CTX, "gpgme_op_revsig_start", ctx, + "key=%p, uid='%s' flags=0x%x", key, userid, flags); + + err = revsig_start (ctx, 0, key, signing_key, userid, flags); + return TRACE_ERR (err); +} + + +gpgme_error_t +gpgme_op_revsig (gpgme_ctx_t ctx, gpgme_key_t key, gpgme_key_t signing_key, + const char *userid, unsigned int flags) +{ + gpgme_error_t err; + + TRACE_BEG (DEBUG_CTX, "gpgme_op_revsig", ctx, + "key=%p, uid='%s' flags=0x%x", key, userid, flags); + + err = revsig_start (ctx, 1, key, signing_key, userid, flags); + if (!err) + err = _gpgme_wait_one (ctx); + return TRACE_ERR (err); +} diff --git a/src/setexpire.c b/src/setexpire.c new file mode 100644 index 0000000..5161499 --- /dev/null +++ b/src/setexpire.c @@ -0,0 +1,193 @@ +/* setexpire.c - Set expire helpers. + * Copyright (C) 2020 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * GPGME is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <https://gnu.org/licenses/>. + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdlib.h> + +#include "gpgme.h" +#include "debug.h" +#include "context.h" +#include "ops.h" + + +typedef struct +{ + /* The error code from a FAILURE status line or 0. */ + gpg_error_t failure_code; + + /* The error code from an ERROR status line or 0. */ + gpg_error_t error_code; + +} *op_data_t; + + +/* Parse an error status line. Return the error location and the + error code. The function may modify ARGS. */ +static char * +parse_error (char *args, gpg_error_t *r_err) +{ + char *where = strchr (args, ' '); + char *which; + + if (where) + { + *where = '\0'; + which = where + 1; + + where = strchr (which, ' '); + if (where) + *where = '\0'; + + where = args; + } + else + { + *r_err = trace_gpg_error (GPG_ERR_INV_ENGINE); + return NULL; + } + + *r_err = atoi (which); + + return where; +} + + +static gpgme_error_t +setexpire_status_handler (void *priv, gpgme_status_code_t code, char *args) +{ + gpgme_ctx_t ctx = (gpgme_ctx_t) priv; + gpgme_error_t err; + void *hook; + op_data_t opd; + char *loc; + + err = _gpgme_op_data_lookup (ctx, OPDATA_SETEXPIRE, &hook, -1, NULL); + opd = hook; + if (err) + return err; + + switch (code) + { + case GPGME_STATUS_ERROR: + loc = parse_error (args, &err); + if (!loc) + return err; + if (!opd->error_code) + opd->error_code = err; + break; + + case GPGME_STATUS_FAILURE: + opd->failure_code = _gpgme_parse_failure (args); + break; + + case GPGME_STATUS_EOF: + if (opd->error_code) + err = opd->error_code; + else if (opd->failure_code) + err = opd->failure_code; + break; + + default: + break; + } + + return err; +} + + +/* Set the expiration time of a key or its subkeys. See + --quick-set-expire in the gnupg documentation. */ +static gpg_error_t +setexpire (gpgme_ctx_t ctx, int synchronous, + gpgme_key_t key, + unsigned long expires, + const char *subfprs, + unsigned int reserved) +{ + gpgme_error_t err; + void *hook; + op_data_t opd; + + TRACE_BEG (DEBUG_CTX, "gpgme_op_setexpire", ctx, + "%d key=%p expiry: %lu subkeys: '%s' reserved=0x%x", + synchronous, key, expires, subfprs, reserved); + + if (!ctx) + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); + + if (ctx->protocol != GPGME_PROTOCOL_OPENPGP) + return TRACE_ERR (gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL)); + + if (!key) + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); + + err = _gpgme_op_reset (ctx, synchronous); + if (err) + return err; + + err = _gpgme_op_data_lookup (ctx, OPDATA_SETEXPIRE, &hook, sizeof (*opd), + NULL); + opd = hook; + if (err) + return err; + + _gpgme_engine_set_status_handler (ctx->engine, setexpire_status_handler, + ctx); + + if (ctx->passphrase_cb) + { + err = _gpgme_engine_set_command_handler + (ctx->engine, _gpgme_passphrase_command_handler, ctx); + if (err) + return err; + } + + err = _gpgme_engine_op_setexpire (ctx->engine, key, expires, subfprs, reserved); + + if (synchronous && !err) + err = _gpgme_wait_one (ctx); + return TRACE_ERR (err); +} + + +/* See setexpire. */ +gpgme_error_t +gpgme_op_setexpire_start (gpgme_ctx_t ctx, + gpgme_key_t key, + unsigned long expires, + const char *subfprs, + unsigned int reserved) +{ + return setexpire (ctx, 0, key, expires, subfprs, reserved); +} + + +/* See setexpire. This is the synchronous variant. */ +gpgme_error_t +gpgme_op_setexpire (gpgme_ctx_t ctx, + gpgme_key_t key, + unsigned long expires, + const char *subfprs, + unsigned int reserved) +{ + return setexpire (ctx, 1, key, expires, subfprs, reserved); +} diff --git a/src/status-table.c b/src/status-table.c index eeafb89..6ec73ab 100644 --- a/src/status-table.c +++ b/src/status-table.c @@ -51,6 +51,7 @@ static struct status_table_s status_table[] = { "BEGIN_ENCRYPTION", GPGME_STATUS_BEGIN_ENCRYPTION }, { "BEGIN_SIGNING", GPGME_STATUS_BEGIN_SIGNING }, { "BEGIN_STREAM", GPGME_STATUS_BEGIN_STREAM }, + { "CANCELED_BY_USER", GPGME_STATUS_CANCELED_BY_USER }, { "CARDCTRL", GPGME_STATUS_CARDCTRL }, { "DECRYPTION_FAILED", GPGME_STATUS_DECRYPTION_FAILED }, { "DECRYPTION_INFO", GPGME_STATUS_DECRYPTION_INFO }, @@ -41,15 +41,6 @@ #define DIM(v) (sizeof(v)/sizeof((v)[0])) -#if GPG_ERROR_VERSION_NUMBER < 0x011900 /* 1.25 */ -# define GPG_ERR_ENGINE_TOO_OLD 300 -# define GPG_ERR_TOO_OLD 308 -#endif - -#ifndef GPGRT_ATTR_SENTINEL -# define GPGRT_ATTR_SENTINEL(a) /* */ -#endif - /*-- {posix,w32}-util.c --*/ diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in index 88b662e..598d5c2 100644 --- a/src/versioninfo.rc.in +++ b/src/versioninfo.rc.in @@ -39,7 +39,7 @@ BEGIN VALUE "FileDescription", "GPGME - GnuPG Made Easy\0" VALUE "FileVersion", "@LIBGPGME_LT_CURRENT@.@LIBGPGME_LT_AGE@.@LIBGPGME_LT_REVISION@.@BUILD_REVISION@\0" VALUE "InternalName", "gpgme\0" - VALUE "LegalCopyright", "Copyright © 2001-2018 g10 Code GmbH\0" + VALUE "LegalCopyright", "Copyright © 2001-2020 g10 Code GmbH\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "gpgme.dll\0" VALUE "PrivateBuild", "\0" @@ -49,4 +49,3 @@ BEGIN END END END - |