summaryrefslogtreecommitdiff
path: root/lang
diff options
context:
space:
mode:
authorTizenOpenSource <tizenopensrc@samsung.com>2023-02-01 18:22:00 +0900
committerTizenOpenSource <tizenopensrc@samsung.com>2023-02-01 18:22:00 +0900
commit73f75b48c0470a46b31340f5cc9e5219d6ee0faa (patch)
treede57a4f03945b3365d4a85eac0ea2eb4c68ab801 /lang
parent9dc2bb3fe7e57cb5a597efe3a7bf78bda815f374 (diff)
downloadgpgme-73f75b48c0470a46b31340f5cc9e5219d6ee0faa.tar.gz
gpgme-73f75b48c0470a46b31340f5cc9e5219d6ee0faa.tar.bz2
gpgme-73f75b48c0470a46b31340f5cc9e5219d6ee0faa.zip
Imported Upstream version 1.18.0upstream/1.18.0
Diffstat (limited to 'lang')
-rw-r--r--lang/Makefile.in2
-rw-r--r--lang/cl/Makefile.in2
-rw-r--r--lang/cl/gpgme.asd2
-rw-r--r--lang/cpp/Makefile.in2
-rw-r--r--lang/cpp/src/GpgmeppConfig-w32.cmake.in.in4
-rw-r--r--lang/cpp/src/GpgmeppConfig.cmake.in.in4
-rw-r--r--lang/cpp/src/Makefile.am5
-rw-r--r--lang/cpp/src/Makefile.in14
-rw-r--r--lang/cpp/src/context.cpp38
-rw-r--r--lang/cpp/src/context.h14
-rw-r--r--lang/cpp/src/context_p.h1
-rw-r--r--lang/cpp/src/editinteractor.cpp19
-rw-r--r--lang/cpp/src/editinteractor.h3
-rw-r--r--lang/cpp/src/global.h15
-rw-r--r--lang/cpp/src/gpgrevokekeyeditinteractor.cpp216
-rw-r--r--lang/cpp/src/gpgrevokekeyeditinteractor.h62
-rw-r--r--lang/cpp/src/importresult.cpp125
-rw-r--r--lang/cpp/src/importresult.h10
-rw-r--r--lang/cpp/src/key.cpp12
-rw-r--r--lang/cpp/src/result.h8
-rw-r--r--lang/cpp/src/util.h35
-rw-r--r--lang/cpp/tests/Makefile.in2
-rw-r--r--lang/cpp/tests/run-getkey.cpp14
-rw-r--r--lang/cpp/tests/run-keylist.cpp18
-rw-r--r--lang/js/BrowserTestExtension/Makefile.in2
-rw-r--r--lang/js/DemoExtension/Makefile.in2
-rw-r--r--lang/js/Makefile.in2
-rw-r--r--lang/js/src/Makefile.in2
-rw-r--r--lang/python/Makefile.in2
-rw-r--r--lang/python/doc/Makefile.in2
-rw-r--r--lang/python/examples/Makefile.in2
-rw-r--r--lang/python/src/Makefile.in2
-rw-r--r--lang/python/src/core.py28
-rw-r--r--lang/python/tests/Makefile.in2
-rwxr-xr-xlang/python/tests/t-idiomatic.py3
-rw-r--r--lang/qt/Makefile.in2
-rw-r--r--lang/qt/doc/Makefile.in2
-rw-r--r--lang/qt/src/Makefile.am23
-rw-r--r--lang/qt/src/Makefile.in62
-rw-r--r--lang/qt/src/RevokeKeyJob1
-rw-r--r--lang/qt/src/SetPrimaryUserIDJob1
-rw-r--r--lang/qt/src/decryptjob.h2
-rw-r--r--lang/qt/src/decryptverifyjob.h2
-rw-r--r--lang/qt/src/downloadjob.h2
-rw-r--r--lang/qt/src/encryptjob.cpp61
-rw-r--r--lang/qt/src/encryptjob.h7
-rw-r--r--lang/qt/src/exportjob.h3
-rw-r--r--lang/qt/src/gpgcardjob.h18
-rw-r--r--lang/qt/src/job.cpp6
-rw-r--r--lang/qt/src/keyformailboxjob.h10
-rw-r--r--lang/qt/src/keylistjob.h6
-rw-r--r--lang/qt/src/protocol.h16
-rw-r--r--lang/qt/src/protocol_p.h35
-rw-r--r--lang/qt/src/qgpgmedecryptverifyjob.cpp8
-rw-r--r--lang/qt/src/qgpgmeencryptjob.cpp25
-rw-r--r--lang/qt/src/qgpgmekeyformailboxjob.cpp2
-rw-r--r--lang/qt/src/qgpgmerefreshsmimekeysjob.cpp (renamed from lang/qt/src/qgpgmerefreshkeysjob.cpp)61
-rw-r--r--lang/qt/src/qgpgmerefreshsmimekeysjob.h (renamed from lang/qt/src/qgpgmerefreshkeysjob.h)17
-rw-r--r--lang/qt/src/qgpgmerevokekeyjob.cpp128
-rw-r--r--lang/qt/src/qgpgmerevokekeyjob.h70
-rw-r--r--lang/qt/src/qgpgmesetprimaryuseridjob.cpp75
-rw-r--r--lang/qt/src/qgpgmesetprimaryuseridjob.h64
-rw-r--r--lang/qt/src/qgpgmesignencryptjob.cpp23
-rw-r--r--lang/qt/src/qgpgmesignkeyjob.cpp6
-rw-r--r--lang/qt/src/refreshkeysjob.h23
-rw-r--r--lang/qt/src/revokekeyjob.h86
-rw-r--r--lang/qt/src/setprimaryuseridjob.h69
-rw-r--r--lang/qt/src/signencryptjob.cpp61
-rw-r--r--lang/qt/src/signencryptjob.h7
-rw-r--r--lang/qt/src/signjob.h2
-rw-r--r--lang/qt/src/signkeyjob.h2
-rw-r--r--lang/qt/src/util.cpp18
-rw-r--r--lang/qt/src/util.h16
-rw-r--r--lang/qt/src/verifydetachedjob.h5
-rw-r--r--lang/qt/src/verifyopaquejob.h2
-rw-r--r--lang/qt/src/wkspublishjob.h7
-rw-r--r--lang/qt/tests/Makefile.am13
-rw-r--r--lang/qt/tests/Makefile.in87
-rw-r--r--lang/qt/tests/run-refreshkeysjob.cpp155
-rw-r--r--lang/qt/tests/t-revokekey.cpp338
-rw-r--r--lang/qt/tests/t-setprimaryuserid.cpp165
-rw-r--r--lang/qt/tests/t-various.cpp12
-rw-r--r--lang/qt/tests/t-verify.cpp2
83 files changed, 2273 insertions, 211 deletions
diff --git a/lang/Makefile.in b/lang/Makefile.in
index c080aa4..0be4fc8 100644
--- a/lang/Makefile.in
+++ b/lang/Makefile.in
@@ -109,6 +109,7 @@ host_triplet = @host@
subdir = lang
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -257,6 +258,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/cl/Makefile.in b/lang/cl/Makefile.in
index d9639d4..9891ca7 100644
--- a/lang/cl/Makefile.in
+++ b/lang/cl/Makefile.in
@@ -110,6 +110,7 @@ host_triplet = @host@
subdir = lang/cl
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -229,6 +230,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/cl/gpgme.asd b/lang/cl/gpgme.asd
index facdc8e..72564c4 100644
--- a/lang/cl/gpgme.asd
+++ b/lang/cl/gpgme.asd
@@ -27,7 +27,7 @@
(defsystem gpgme
:description "GnuPG Made Easy."
:author "g10 Code GmbH"
- :version "1.17.1"
+ :version "1.18.0"
:licence "GPL"
:defsystem-depends-on ("cffi-grovel")
:depends-on ("cffi" "gpg-error" "trivial-garbage")
diff --git a/lang/cpp/Makefile.in b/lang/cpp/Makefile.in
index 14315ac..7c835ea 100644
--- a/lang/cpp/Makefile.in
+++ b/lang/cpp/Makefile.in
@@ -110,6 +110,7 @@ host_triplet = @host@
subdir = lang/cpp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -259,6 +260,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/cpp/src/GpgmeppConfig-w32.cmake.in.in b/lang/cpp/src/GpgmeppConfig-w32.cmake.in.in
index 1282676..51ada3b 100644
--- a/lang/cpp/src/GpgmeppConfig-w32.cmake.in.in
+++ b/lang/cpp/src/GpgmeppConfig-w32.cmake.in.in
@@ -97,7 +97,3 @@ unset(_IMPORT_CHECK_TARGETS)
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
-
-get_filename_component(QGpgme_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
-# Pull in QGpgme for compatibility with KF5 variant.
-find_package(QGpgme CONFIG)
diff --git a/lang/cpp/src/GpgmeppConfig.cmake.in.in b/lang/cpp/src/GpgmeppConfig.cmake.in.in
index 73f5eaa..8777623 100644
--- a/lang/cpp/src/GpgmeppConfig.cmake.in.in
+++ b/lang/cpp/src/GpgmeppConfig.cmake.in.in
@@ -93,7 +93,3 @@ unset(_IMPORT_CHECK_TARGETS)
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
-
-get_filename_component(QGpgme_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
-# Pull in QGpgme for compatibility with KF5 variant.
-find_package(QGpgme CONFIG)
diff --git a/lang/cpp/src/Makefile.am b/lang/cpp/src/Makefile.am
index ba8a7fb..fbec70b 100644
--- a/lang/cpp/src/Makefile.am
+++ b/lang/cpp/src/Makefile.am
@@ -34,6 +34,7 @@ main_sources = \
gpgsetownertrusteditinteractor.cpp gpgsignkeyeditinteractor.cpp \
gpgadduserideditinteractor.cpp gpggencardkeyinteractor.cpp \
gpgaddexistingsubkeyeditinteractor.cpp \
+ gpgrevokekeyeditinteractor.cpp \
defaultassuantransaction.cpp \
scdgetinfoassuantransaction.cpp gpgagentgetinfoassuantransaction.cpp \
statusconsumerassuantransaction.cpp \
@@ -49,6 +50,7 @@ gpgmepp_headers = \
gpgsetownertrusteditinteractor.h gpgsignkeyeditinteractor.h \
gpggencardkeyinteractor.h \
gpgaddexistingsubkeyeditinteractor.h \
+ gpgrevokekeyeditinteractor.h \
importresult.h keygenerationresult.h key.h keylistresult.h \
notation.h result.h scdgetinfoassuantransaction.h signingresult.h \
statusconsumerassuantransaction.h \
@@ -71,7 +73,8 @@ nodist_gpgmeppinclude_HEADERS = gpgmepp_version.h
libgpgmepp_la_SOURCES = $(main_sources) $(gpgmepp_headers) context_vanilla.cpp \
$(interface_headers) $(private_gpgmepp_headers)
-AM_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_CFLAGS@ @LIBASSUAN_CFLAGS@ \
+AM_CPPFLAGS = -I$(top_builddir)/src \
+ @GPGME_CPP_CFLAGS@ @GPG_ERROR_CFLAGS@ @LIBASSUAN_CFLAGS@ \
-DBUILDING_GPGMEPP -Wsuggest-override \
-Wzero-as-null-pointer-constant
diff --git a/lang/cpp/src/Makefile.in b/lang/cpp/src/Makefile.in
index f5e859a..0518307 100644
--- a/lang/cpp/src/Makefile.in
+++ b/lang/cpp/src/Makefile.in
@@ -113,6 +113,7 @@ host_triplet = @host@
subdir = lang/cpp/src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -174,7 +175,8 @@ am__objects_1 = exception.lo context.lo key.lo trustitem.lo data.lo \
gpgsetownertrusteditinteractor.lo gpgsignkeyeditinteractor.lo \
gpgadduserideditinteractor.lo gpggencardkeyinteractor.lo \
gpgaddexistingsubkeyeditinteractor.lo \
- defaultassuantransaction.lo scdgetinfoassuantransaction.lo \
+ gpgrevokekeyeditinteractor.lo defaultassuantransaction.lo \
+ scdgetinfoassuantransaction.lo \
gpgagentgetinfoassuantransaction.lo \
statusconsumerassuantransaction.lo vfsmountresult.lo \
configuration.lo tofuinfo.lo swdbresult.lo util.lo
@@ -217,6 +219,7 @@ am__depfiles_remade = ./$(DEPDIR)/callbacks.Plo \
./$(DEPDIR)/gpgadduserideditinteractor.Plo \
./$(DEPDIR)/gpgagentgetinfoassuantransaction.Plo \
./$(DEPDIR)/gpggencardkeyinteractor.Plo \
+ ./$(DEPDIR)/gpgrevokekeyeditinteractor.Plo \
./$(DEPDIR)/gpgsetexpirytimeeditinteractor.Plo \
./$(DEPDIR)/gpgsetownertrusteditinteractor.Plo \
./$(DEPDIR)/gpgsignkeyeditinteractor.Plo \
@@ -350,6 +353,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
@@ -513,6 +517,7 @@ main_sources = \
gpgsetownertrusteditinteractor.cpp gpgsignkeyeditinteractor.cpp \
gpgadduserideditinteractor.cpp gpggencardkeyinteractor.cpp \
gpgaddexistingsubkeyeditinteractor.cpp \
+ gpgrevokekeyeditinteractor.cpp \
defaultassuantransaction.cpp \
scdgetinfoassuantransaction.cpp gpgagentgetinfoassuantransaction.cpp \
statusconsumerassuantransaction.cpp \
@@ -528,6 +533,7 @@ gpgmepp_headers = \
gpgsetownertrusteditinteractor.h gpgsignkeyeditinteractor.h \
gpggencardkeyinteractor.h \
gpgaddexistingsubkeyeditinteractor.h \
+ gpgrevokekeyeditinteractor.h \
importresult.h keygenerationresult.h key.h keylistresult.h \
notation.h result.h scdgetinfoassuantransaction.h signingresult.h \
statusconsumerassuantransaction.h \
@@ -549,7 +555,8 @@ nodist_gpgmeppinclude_HEADERS = gpgmepp_version.h
libgpgmepp_la_SOURCES = $(main_sources) $(gpgmepp_headers) context_vanilla.cpp \
$(interface_headers) $(private_gpgmepp_headers)
-AM_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_CFLAGS@ @LIBASSUAN_CFLAGS@ \
+AM_CPPFLAGS = -I$(top_builddir)/src \
+ @GPGME_CPP_CFLAGS@ @GPG_ERROR_CFLAGS@ @LIBASSUAN_CFLAGS@ \
-DBUILDING_GPGMEPP -Wsuggest-override \
-Wzero-as-null-pointer-constant
@@ -664,6 +671,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgadduserideditinteractor.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgagentgetinfoassuantransaction.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpggencardkeyinteractor.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgrevokekeyeditinteractor.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgsetexpirytimeeditinteractor.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgsetownertrusteditinteractor.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgsignkeyeditinteractor.Plo@am__quote@ # am--include-marker
@@ -925,6 +933,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/gpgadduserideditinteractor.Plo
-rm -f ./$(DEPDIR)/gpgagentgetinfoassuantransaction.Plo
-rm -f ./$(DEPDIR)/gpggencardkeyinteractor.Plo
+ -rm -f ./$(DEPDIR)/gpgrevokekeyeditinteractor.Plo
-rm -f ./$(DEPDIR)/gpgsetexpirytimeeditinteractor.Plo
-rm -f ./$(DEPDIR)/gpgsetownertrusteditinteractor.Plo
-rm -f ./$(DEPDIR)/gpgsignkeyeditinteractor.Plo
@@ -1004,6 +1013,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/gpgadduserideditinteractor.Plo
-rm -f ./$(DEPDIR)/gpgagentgetinfoassuantransaction.Plo
-rm -f ./$(DEPDIR)/gpggencardkeyinteractor.Plo
+ -rm -f ./$(DEPDIR)/gpgrevokekeyeditinteractor.Plo
-rm -f ./$(DEPDIR)/gpgsetexpirytimeeditinteractor.Plo
-rm -f ./$(DEPDIR)/gpgsetownertrusteditinteractor.Plo
-rm -f ./$(DEPDIR)/gpgsignkeyeditinteractor.Plo
diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp
index 5072681..dba958c 100644
--- a/lang/cpp/src/context.cpp
+++ b/lang/cpp/src/context.cpp
@@ -195,6 +195,19 @@ std::ostream &operator<<(std::ostream &os, const Error &err)
return os << "GpgME::Error(" << err.encodedError() << " (" << err.asString() << "))";
}
+Context::KeyListModeSaver::KeyListModeSaver(Context *ctx)
+ : mCtx{ctx}
+ , mKeyListMode{ctx ? ctx->keyListMode() : 0}
+{
+}
+
+Context::KeyListModeSaver::~KeyListModeSaver()
+{
+ if (mCtx) {
+ mCtx->setKeyListMode(mKeyListMode);
+ }
+}
+
Context::Context(gpgme_ctx_t ctx) : d(new Private(ctx))
{
}
@@ -522,19 +535,25 @@ const char *Context::getSender ()
Error Context::startKeyListing(const char *pattern, bool secretOnly)
{
- d->lastop = Private::KeyList;
+ d->lastop = (((keyListMode() & GpgME::Locate) == GpgME::Locate)
+ ? Private::KeyListWithImport
+ : Private::KeyList);
return Error(d->lasterr = gpgme_op_keylist_start(d->ctx, pattern, int(secretOnly)));
}
Error Context::startKeyListing(const char *patterns[], bool secretOnly)
{
- d->lastop = Private::KeyList;
+ d->lastop = (((keyListMode() & GpgME::Locate) == GpgME::Locate)
+ ? Private::KeyListWithImport
+ : Private::KeyList);
return Error(d->lasterr = gpgme_op_keylist_ext_start(d->ctx, patterns, int(secretOnly), 0));
}
Key Context::nextKey(GpgME::Error &e)
{
- d->lastop = Private::KeyList;
+ d->lastop = (((keyListMode() & GpgME::Locate) == GpgME::Locate)
+ ? Private::KeyListWithImport
+ : Private::KeyList);
gpgme_key_t key = nullptr;
e = Error(d->lasterr = gpgme_op_keylist_next(d->ctx, &key));
return Key(key, false);
@@ -1154,6 +1173,7 @@ Error Context::startCombinedDecryptionAndVerification(const Data &cipherText, Da
return startCombinedDecryptionAndVerification(cipherText, plainText, DecryptNone);
}
+namespace {
unsigned int to_auditlog_flags(unsigned int flags)
{
unsigned int result = 0;
@@ -1168,6 +1188,7 @@ unsigned int to_auditlog_flags(unsigned int flags)
}
return result;
}
+}
Error Context::startGetAuditLog(Data &output, unsigned int flags)
{
@@ -1620,6 +1641,16 @@ Error Context::startRevUid(const Key &k, const char *userid)
k.impl(), userid, 0));
}
+Error Context::setPrimaryUid(const Key &k, const char *userid)
+{
+ return Error(d->lasterr = gpgme_op_set_uid_flag(d->ctx, k.impl(), userid, "primary", nullptr));
+}
+
+Error Context::startSetPrimaryUid(const Key &k, const char *userid)
+{
+ return Error(d->lasterr = gpgme_op_set_uid_flag_start(d->ctx, k.impl(), userid, "primary", nullptr));
+}
+
Error Context::createSubkey(const Key &k, const char *algo,
unsigned long reserved,
unsigned long expires,
@@ -1847,6 +1878,7 @@ std::ostream &operator<<(std::ostream &os, KeyListMode mode)
CHECK(WithTofu);
CHECK(WithKeygrip);
CHECK(WithSecret);
+ CHECK(ForceExtern);
#undef CHECK
return os << ')';
}
diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h
index 9c2b2a5..7bd1b03 100644
--- a/lang/cpp/src/context.h
+++ b/lang/cpp/src/context.h
@@ -64,6 +64,17 @@ class GPGMEPP_EXPORT Context
public:
//using GpgME::Protocol;
+ /// RAII-style class for saving/restoring the key list mode.
+ class GPGMEPP_EXPORT KeyListModeSaver
+ {
+ public:
+ explicit KeyListModeSaver(Context *ctx);
+ ~KeyListModeSaver();
+ private:
+ Context *mCtx;
+ unsigned int mKeyListMode;
+ };
+
//
// Creation and destruction:
//
@@ -284,6 +295,9 @@ public:
Error revUid(const Key &key, const char *userid);
Error startRevUid(const Key &key, const char *userid);
+ Error setPrimaryUid(const Key &key, const char *userid);
+ Error startSetPrimaryUid(const Key &key, const char *userid);
+
Error createSubkey(const Key &key, const char *algo,
unsigned long reserved = 0,
unsigned long expires = 0,
diff --git a/lang/cpp/src/context_p.h b/lang/cpp/src/context_p.h
index 491e7f7..8782609 100644
--- a/lang/cpp/src/context_p.h
+++ b/lang/cpp/src/context_p.h
@@ -53,6 +53,7 @@ public:
KeyGen = 0x080,
KeyList = 0x100,
+ KeyListWithImport = KeyList | Import, // gpgme_keylist_result_t and gpgme_import_result_t
TrustList = 0x200, // no gpgme_trustlist_result_t, but nevertheless...
Edit = 0x400, // no gpgme_edit_result_t, but nevertheless...
diff --git a/lang/cpp/src/editinteractor.cpp b/lang/cpp/src/editinteractor.cpp
index e411ada..08cb1bc 100644
--- a/lang/cpp/src/editinteractor.cpp
+++ b/lang/cpp/src/editinteractor.cpp
@@ -29,6 +29,7 @@
#include "editinteractor.h"
#include "callbacks.h"
#include "error.h"
+#include "util.h"
#include <gpgme.h>
@@ -100,7 +101,7 @@ public:
std::fprintf(ei->debug, "EditInteractor: %u -> nextState( %s, %s ) -> %u\n",
oldState, status_to_string(status), args ? args : "<null>", ei->state);
}
- if (err) {
+ if (err || err.isCanceled()) {
ei->state = oldState;
goto error;
}
@@ -153,7 +154,7 @@ public:
}
error:
- if (err) {
+ if (err || err.isCanceled()) {
ei->error = err;
ei->state = EditInteractor::ErrorState;
}
@@ -256,6 +257,20 @@ void EditInteractor::setDebugChannel(std::FILE *debug)
d->debug = debug;
}
+GpgME::Error EditInteractor::parseStatusError(const char *args)
+{
+ Error err;
+
+ const auto fields = split(args, ' ');
+ if (fields.size() >= 2) {
+ err = Error{static_cast<unsigned int>(std::stoul(fields[1]))};
+ } else {
+ err = Error::fromCode(GPG_ERR_GENERAL);
+ }
+
+ return err;
+}
+
static const char *const status_strings[] = {
"EOF",
/* mkstatus processing starts here */
diff --git a/lang/cpp/src/editinteractor.h b/lang/cpp/src/editinteractor.h
index 247bf8c..2505b02 100644
--- a/lang/cpp/src/editinteractor.h
+++ b/lang/cpp/src/editinteractor.h
@@ -60,6 +60,9 @@ public:
void setDebugChannel(std::FILE *file);
+protected:
+ Error parseStatusError(const char *args);
+
private:
class Private;
Private *const d;
diff --git a/lang/cpp/src/global.h b/lang/cpp/src/global.h
index a25b46c..1336142 100644
--- a/lang/cpp/src/global.h
+++ b/lang/cpp/src/global.h
@@ -60,18 +60,29 @@ enum Engine { GpgEngine, GpgSMEngine, GpgConfEngine, UnknownEngine, AssuanEngine
enum KeyListMode {
Local = 0x1,
Extern = 0x2,
- Locate = 0x3,
+ Locate = Local|Extern,
Signatures = 0x4,
SignatureNotations = 0x8,
Validate = 0x10,
Ephemeral = 0x20,
WithTofu = 0x40,
WithKeygrip = 0x80,
- WithSecret = 0x100
+ WithSecret = 0x100,
+ ForceExtern = 0x200,
+ LocateExternal = Locate|ForceExtern,
+
+ KeyListModeMask = 0x3ff
};
enum SignatureMode { NormalSignatureMode, Detached, Clearsigned };
+enum class RevocationReason {
+ Unspecified = 0,
+ Compromised = 1,
+ Superseded = 2,
+ NoLongerUsed = 3
+};
+
GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, Protocol proto);
GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, Engine eng);
GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, KeyListMode mode);
diff --git a/lang/cpp/src/gpgrevokekeyeditinteractor.cpp b/lang/cpp/src/gpgrevokekeyeditinteractor.cpp
new file mode 100644
index 0000000..86b3c3c
--- /dev/null
+++ b/lang/cpp/src/gpgrevokekeyeditinteractor.cpp
@@ -0,0 +1,216 @@
+/*
+ gpgrevokekeyeditinteractor.cpp - Edit Interactor to revoke own OpenPGP keys
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ This file is part of GPGME++.
+
+ GPGME++ is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with GPGME++; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "gpgrevokekeyeditinteractor.h"
+
+#include "error.h"
+
+#include <gpgme.h>
+
+#include <sstream>
+#include <vector>
+
+// avoid conflict (msvc)
+#ifdef ERROR
+# undef ERROR
+#endif
+
+using namespace GpgME;
+
+class GpgRevokeKeyEditInteractor::Private
+{
+ enum {
+ START = EditInteractor::StartState,
+ COMMAND,
+ CONFIRM_REVOKING_ENTIRE_KEY,
+ REASON_CODE,
+ REASON_TEXT,
+ // all these free slots belong to REASON_TEXT, too; we increase state()
+ // by one for each line of text, so that action() is called
+ REASON_TEXT_DONE = REASON_TEXT + 1000,
+ CONFIRM_REASON,
+ QUIT,
+ CONFIRM_SAVE,
+
+ ERROR = EditInteractor::ErrorState
+ };
+
+ GpgRevokeKeyEditInteractor *const q = nullptr;
+
+public:
+ Private(GpgRevokeKeyEditInteractor *q)
+ : q{q}
+ , reasonCode{"0"}
+ {
+ }
+
+ const char *action(Error &err) const;
+ unsigned int nextState(unsigned int statusCode, const char *args, Error &err);
+
+ std::string reasonCode;
+ std::vector<std::string> reasonLines;
+ int nextLine = -1;
+};
+
+const char *GpgRevokeKeyEditInteractor::Private::action(Error &err) const
+{
+ switch (const auto state = q->state()) {
+ case COMMAND:
+ return "revkey";
+ case CONFIRM_REVOKING_ENTIRE_KEY:
+ return "Y";
+ case REASON_CODE:
+ return reasonCode.c_str();
+ case REASON_TEXT_DONE:
+ return "";
+ case CONFIRM_REASON:
+ return "Y";
+ case QUIT:
+ return "quit";
+ case CONFIRM_SAVE:
+ return "Y";
+ case START:
+ return nullptr;
+ default:
+ if (state >= REASON_TEXT && state < REASON_TEXT_DONE) {
+ return reasonLines[nextLine].c_str();
+ }
+ // fall through
+ case ERROR:
+ err = Error::fromCode(GPG_ERR_GENERAL);
+ return nullptr;
+ }
+}
+
+unsigned int GpgRevokeKeyEditInteractor::Private::nextState(unsigned int status, const char *args, Error &err)
+{
+ using std::strcmp;
+
+ static const Error GENERAL_ERROR = Error::fromCode(GPG_ERR_GENERAL);
+
+ if (q->needsNoResponse(status)) {
+ return q->state();
+ }
+
+ if (status == GPGME_STATUS_ERROR) {
+ err = q->parseStatusError(args);
+ return ERROR;
+ }
+ switch (const auto state = q->state()) {
+ case START:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keyedit.prompt") == 0) {
+ return COMMAND;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case COMMAND:
+ if (status == GPGME_STATUS_GET_BOOL &&
+ strcmp(args, "keyedit.revoke.subkey.okay") == 0) {
+ return CONFIRM_REVOKING_ENTIRE_KEY;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case CONFIRM_REVOKING_ENTIRE_KEY:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "ask_revocation_reason.code") == 0) {
+ return REASON_CODE;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case REASON_CODE:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "ask_revocation_reason.text") == 0) {
+ nextLine++;
+ return nextLine < reasonLines.size() ? REASON_TEXT : REASON_TEXT_DONE;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ default:
+ if (state >= REASON_TEXT && state < REASON_TEXT_DONE) {
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "ask_revocation_reason.text") == 0) {
+ nextLine++;
+ return nextLine < reasonLines.size() ? state + 1 : REASON_TEXT_DONE;
+ }
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case REASON_TEXT_DONE:
+ if (status == GPGME_STATUS_GET_BOOL &&
+ strcmp(args, "ask_revocation_reason.okay") == 0) {
+ return CONFIRM_REASON;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case CONFIRM_REASON:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keyedit.prompt") == 0) {
+ return QUIT;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case QUIT:
+ if (status == GPGME_STATUS_GET_BOOL &&
+ strcmp(args, "keyedit.save.okay") == 0) {
+ return CONFIRM_SAVE;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case ERROR:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keyedit.prompt") == 0) {
+ return QUIT;
+ }
+ err = q->lastError();
+ return ERROR;
+ }
+}
+
+GpgRevokeKeyEditInteractor::GpgRevokeKeyEditInteractor()
+ : EditInteractor{}
+ , d{new Private{this}}
+{
+}
+
+GpgRevokeKeyEditInteractor::~GpgRevokeKeyEditInteractor() = default;
+
+void GpgRevokeKeyEditInteractor::setReason(RevocationReason reason, const std::vector<std::string> &description)
+{
+ d->reasonCode = std::to_string(static_cast<int>(reason));
+ d->reasonLines = description;
+}
+
+const char *GpgRevokeKeyEditInteractor::action(Error &err) const
+{
+ return d->action(err);
+}
+
+unsigned int GpgRevokeKeyEditInteractor::nextState(unsigned int status, const char *args, Error &err) const
+{
+ return d->nextState(status, args, err);
+}
diff --git a/lang/cpp/src/gpgrevokekeyeditinteractor.h b/lang/cpp/src/gpgrevokekeyeditinteractor.h
new file mode 100644
index 0000000..c33a71b
--- /dev/null
+++ b/lang/cpp/src/gpgrevokekeyeditinteractor.h
@@ -0,0 +1,62 @@
+/*
+ gpgrevokekeyeditinteractor.h - Edit Interactor to revoke own OpenPGP keys
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ This file is part of GPGME++.
+
+ GPGME++ is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with GPGME++; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __GPGMEPP_GPGREVOKEKEYEDITINTERACTOR_H__
+#define __GPGMEPP_GPGREVOKEKEYEDITINTERACTOR_H__
+
+#include "editinteractor.h"
+#include "global.h"
+
+#include <memory>
+#include <vector>
+
+namespace GpgME
+{
+
+/** Edit interactor to revoke the key a key edit operation is working on.
+ * Supports revocation of own keys only. */
+class GPGMEPP_EXPORT GpgRevokeKeyEditInteractor : public EditInteractor
+{
+public:
+ GpgRevokeKeyEditInteractor();
+ ~GpgRevokeKeyEditInteractor() override;
+
+ /** Sets the reason for the revocation. The reason defaults to \c Unspecified.
+ * \a description can be used for adding a comment for the revocation. The
+ * individual elements of \a description must be non-empty strings and they
+ * must not contain any endline characters.
+ */
+ void setReason(RevocationReason reason, const std::vector<std::string> &description = {});
+
+private:
+ const char *action(Error &err) const override;
+ unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const override;
+
+private:
+ class GPGMEPP_NO_EXPORT Private;
+ const std::unique_ptr<Private> d;
+};
+
+} // namespace GpgME
+
+#endif // __GPGMEPP_GPGREVOKEKEYEDITINTERACTOR_H__
diff --git a/lang/cpp/src/importresult.cpp b/lang/cpp/src/importresult.cpp
index 803c34d..0625872 100644
--- a/lang/cpp/src/importresult.cpp
+++ b/lang/cpp/src/importresult.cpp
@@ -94,6 +94,131 @@ void GpgME::ImportResult::init(gpgme_ctx_t ctx)
make_standard_stuff(ImportResult)
+void GpgME::ImportResult::mergeWith(const ImportResult &other)
+{
+ if (other.isNull()) {
+ return;
+ }
+ if (isNull()) { // just assign
+ operator=(other);
+ return;
+ }
+
+ // Add the numbers of considered keys; the number will be corrected when
+ // merging the imports to account for duplicates
+ d->res.considered += other.d->res.considered;
+ // Add the numbers of keys without user ID; may count duplicates
+ d->res.no_user_id += other.d->res.no_user_id;
+ // Add the numbers of imported keys
+ d->res.imported += other.d->res.imported;
+ // Add the numbers of imported RSA keys
+ d->res.imported_rsa += other.d->res.imported_rsa;
+ // Add the numbers of unchanged keys; the number will be corrected when
+ // merging the imports to account for keys changed by this import
+ d->res.unchanged += other.d->res.unchanged;
+ // Add the numbers of new user IDs
+ d->res.new_user_ids += other.d->res.new_user_ids;
+ // Add the numbers of new subkeys
+ d->res.new_sub_keys += other.d->res.new_sub_keys;
+ // Add the numbers of new signatures
+ d->res.new_signatures += other.d->res.new_signatures;
+ // Add the numbers of new revocations
+ d->res.new_revocations += other.d->res.new_revocations;
+
+ // Add the numbers of considered secret keys; the number will be corrected when
+ // merging the imports to account for duplicates
+ d->res.secret_read += other.d->res.secret_read;
+ // Add the numbers of imported secret keys
+ d->res.secret_imported += other.d->res.secret_imported;
+ // Add the numbers of unchanged secret keys; the number will be corrected when
+ // merging the imports to account for keys changed by this import
+ d->res.secret_unchanged += other.d->res.secret_unchanged;
+
+ // Add the numbers of new keys that were skipped; may count duplicates
+ d->res.skipped_new_keys += other.d->res.skipped_new_keys;
+ // Add the numbers of keys that were not imported; may count duplicates
+ d->res.not_imported += other.d->res.not_imported;
+ // Add the numbers of v3 keys that were skipped; may count duplicates
+ d->res.skipped_v3_keys += other.d->res.skipped_v3_keys;
+
+ // Look at the list of keys for which an import was attempted during the
+ // other import to correct some of the consolidated numbers
+ for (auto it = std::begin(other.d->imports), end = std::end(other.d->imports); it != end; ++it) {
+ const char *fpr = (*it)->fpr;
+ if (!fpr || !*fpr) {
+ // we cannot derive any useful information about an import if the
+ // fingerprint is null or empty
+ continue;
+ }
+ // was this key also considered during the first import
+ const auto consideredInFirstImports =
+ std::any_of(std::begin(d->imports), std::end(d->imports), [fpr](const auto i) {
+ return i->fpr && !strcmp(i->fpr, fpr);
+ });
+ // did we see this key already in the list of keys of the other import
+ const auto consideredInPreviousOtherImports =
+ std::any_of(std::begin(other.d->imports), it, [fpr](const auto i) {
+ return i->fpr && !strcmp(i->fpr, fpr);
+ });
+ // was anything added to this key during the other import
+ const auto changedInOtherImports =
+ std::any_of(std::begin(other.d->imports), std::end(other.d->imports), [fpr](const auto i) {
+ return i->fpr && !strcmp(i->fpr, fpr) && (i->status != 0);
+ });
+ if (consideredInFirstImports && !consideredInPreviousOtherImports) {
+ // key was also considered during first import, but not before in the list of other imports
+ d->res.considered -= 1;
+ if (!changedInOtherImports) {
+ // key was (most likely) counted as unchanged in the second import;
+ // this needs to be corrected (regardless of whether it was changed in the first import)
+ d->res.unchanged -= 1;
+ }
+ }
+
+ // now do the same for the secret key counts
+ const auto secretKeyConsideredInFirstImports =
+ std::any_of(std::begin(d->imports), std::end(d->imports), [fpr](const auto i) {
+ return i->fpr && !strcmp(i->fpr, fpr) && (i->status & GPGME_IMPORT_SECRET);
+ });
+ const auto secretKeyConsideredInPreviousOtherImports =
+ std::any_of(std::begin(other.d->imports), it, [fpr](const auto i) {
+ return i->fpr && !strcmp(i->fpr, fpr) && (i->status & GPGME_IMPORT_SECRET);
+ });
+ const auto secretKeyChangedInOtherImports =
+ std::any_of(std::begin(other.d->imports), std::end(other.d->imports), [fpr](const auto i) {
+ return i->fpr && !strcmp(i->fpr, fpr) && (i->status & GPGME_IMPORT_SECRET) && (i->status != GPGME_IMPORT_SECRET);
+ });
+ if (secretKeyConsideredInFirstImports && !secretKeyConsideredInPreviousOtherImports) {
+ // key was also considered during first import, but not before in the list of other imports
+ d->res.secret_read -= 1;
+ if (!secretKeyChangedInOtherImports) {
+ // key was (most likely) counted as unchanged in the second import;
+ // this needs to be corrected (regardless of whether it was changed in the first import)
+ d->res.secret_unchanged -= 1;
+ }
+ }
+ }
+
+ // Now append the list of keys for which an import was attempted during the
+ // other import
+ d->imports.reserve(d->imports.size() + other.d->imports.size());
+ std::transform(std::begin(other.d->imports), std::end(other.d->imports),
+ std::back_inserter(d->imports),
+ [](const auto import) {
+ gpgme_import_status_t copy = new _gpgme_import_status{*import};
+ if (import->fpr) {
+ copy->fpr = strdup(import->fpr);
+ }
+ copy->next = nullptr; // should already be null, but better safe than sorry
+ return copy;
+ });
+
+ // Finally, merge the error if there was none yet
+ if (!bool(error())) {
+ Result::operator=(other);
+ }
+}
+
int GpgME::ImportResult::numConsidered() const
{
return d ? d->res.considered : 0 ;
diff --git a/lang/cpp/src/importresult.h b/lang/cpp/src/importresult.h
index bcd956c..5936698 100644
--- a/lang/cpp/src/importresult.h
+++ b/lang/cpp/src/importresult.h
@@ -60,6 +60,16 @@ public:
swap(this->d, other.d);
}
+ /**
+ * Merges the result @p other into this result (and all of its copies).
+ *
+ * @note The merge algorithm assumes that @p other is the result of an
+ * import that was performed after the import of this result.
+ * @note Some numbers cannot be consolidated reliably, e.g. the number of
+ * keys without user ID.
+ */
+ void mergeWith(const ImportResult &other);
+
bool isNull() const;
int numConsidered() const;
diff --git a/lang/cpp/src/key.cpp b/lang/cpp/src/key.cpp
index b893a7c..293c9e5 100644
--- a/lang/cpp/src/key.cpp
+++ b/lang/cpp/src/key.cpp
@@ -1250,16 +1250,22 @@ std::ostream &operator<<(std::ostream &os, const Subkey &subkey)
os << "GpgME::Subkey(";
if (!subkey.isNull()) {
os << "\n fingerprint: " << protect(subkey.fingerprint())
+ << "\n keyGrip: " << protect(subkey.keyGrip())
<< "\n creationTime: " << subkey.creationTime()
<< "\n expirationTime:" << subkey.expirationTime()
<< "\n isRevoked: " << subkey.isRevoked()
<< "\n isExpired: " << subkey.isExpired()
- << "\n isInvalid: " << subkey.isRevoked()
- << "\n isDisabled: " << subkey.isInvalid()
+ << "\n isInvalid: " << subkey.isInvalid()
+ << "\n isDisabled: " << subkey.isDisabled()
<< "\n canSign: " << subkey.canSign()
<< "\n canEncrypt: " << subkey.canEncrypt()
<< "\n canCertify: " << subkey.canCertify()
- << "\n canAuth: " << subkey.canAuthenticate();
+ << "\n canAuth: " << subkey.canAuthenticate()
+ << "\n isSecret: " << subkey.isSecret()
+ << "\n isQualified: " << subkey.isQualified()
+ << "\n isDeVs: " << subkey.isDeVs()
+ << "\n isCardKey: " << subkey.isCardKey()
+ << "\n cardSerialNumber:" << protect(subkey.cardSerialNumber());
}
return os << ')';
}
diff --git a/lang/cpp/src/result.h b/lang/cpp/src/result.h
index 5ed52a8..a587afb 100644
--- a/lang/cpp/src/result.h
+++ b/lang/cpp/src/result.h
@@ -50,6 +50,14 @@ public:
{
return mError;
}
+ /**
+ * Replaces the error set during construction with \p error.
+ * Use with care, e.g. to set a more suitable error.
+ */
+ void setError(const Error &error)
+ {
+ mError = error;
+ }
protected:
Error mError;
diff --git a/lang/cpp/src/util.h b/lang/cpp/src/util.h
index b6f9ca5..cb6df0d 100644
--- a/lang/cpp/src/util.h
+++ b/lang/cpp/src/util.h
@@ -89,19 +89,15 @@ static inline gpgme_keylist_mode_t add_to_gpgme_keylist_mode_t(unsigned int oldm
if (newmodes & GpgME::WithSecret) {
oldmode |= GPGME_KEYLIST_MODE_WITH_SECRET;
}
+ if (newmodes & GpgME::ForceExtern) {
+ oldmode |= GPGME_KEYLIST_MODE_FORCE_EXTERN;
+ }
#ifndef NDEBUG
- if (newmodes & ~(GpgME::Local |
- GpgME::Extern |
- GpgME::Signatures |
- GpgME::SignatureNotations |
- GpgME::Validate |
- GpgME::Ephemeral |
- GpgME::WithTofu |
- GpgME::WithKeygrip |
- GpgME::WithSecret)) {
+ if (newmodes & ~(GpgME::KeyListModeMask)) {
//std::cerr << "GpgME::Context: keylist mode must be one of Local, "
//"Extern, Signatures, SignatureNotations, Validate, Ephemeral, WithTofu, "
- //"WithKeygrip, WithSecret, or a combination thereof!" << std::endl;
+ //"WithKeygrip, WithSecret, ForceExtern, or a combination thereof!"
+ //<< std::endl;
}
#endif
return static_cast<gpgme_keylist_mode_t>(oldmode);
@@ -137,6 +133,9 @@ static inline unsigned int convert_from_gpgme_keylist_mode_t(unsigned int mode)
if (mode & GPGME_KEYLIST_MODE_VALIDATE) {
result |= GpgME::Validate;
}
+ if (mode & GPGME_KEYLIST_MODE_FORCE_EXTERN) {
+ result |= GpgME::ForceExtern;
+ }
#ifndef NDEBUG
if (mode & ~(GPGME_KEYLIST_MODE_LOCAL |
GPGME_KEYLIST_MODE_EXTERN |
@@ -146,7 +145,8 @@ static inline unsigned int convert_from_gpgme_keylist_mode_t(unsigned int mode)
GPGME_KEYLIST_MODE_WITH_TOFU |
GPGME_KEYLIST_MODE_WITH_KEYGRIP |
GPGME_KEYLIST_MODE_EPHEMERAL |
- GPGME_KEYLIST_MODE_VALIDATE)) {
+ GPGME_KEYLIST_MODE_VALIDATE |
+ GPGME_KEYLIST_MODE_FORCE_EXTERN)) {
//std::cerr << "GpgME: WARNING: gpgme_get_keylist_mode() returned an unknown flag!" << std::endl;
}
#endif // NDEBUG
@@ -177,6 +177,19 @@ static inline gpgme_sig_notation_flags_t add_to_gpgme_sig_notation_flags_t(unsi
return static_cast<gpgme_sig_notation_flags_t>(result);
}
+static inline std::vector<std::string> split(const std::string &text, char delimiter)
+{
+ std::vector<std::string> result;
+ if (!text.empty()) {
+ std::istringstream stream{text};
+ std::string line;
+ while (std::getline(stream, line, delimiter)) {
+ result.push_back(line);
+ }
+ }
+ return result;
+}
+
/**
* Adapter for passing a vector of strings as NULL-terminated array of
* const char* to the C-interface of gpgme.
diff --git a/lang/cpp/tests/Makefile.in b/lang/cpp/tests/Makefile.in
index 280ffec..46dd9f0 100644
--- a/lang/cpp/tests/Makefile.in
+++ b/lang/cpp/tests/Makefile.in
@@ -111,6 +111,7 @@ noinst_PROGRAMS = run-getkey$(EXEEXT) run-keylist$(EXEEXT) \
subdir = lang/cpp/tests
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -274,6 +275,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/cpp/tests/run-getkey.cpp b/lang/cpp/tests/run-getkey.cpp
index 35b15eb..c47da0b 100644
--- a/lang/cpp/tests/run-getkey.cpp
+++ b/lang/cpp/tests/run-getkey.cpp
@@ -60,6 +60,8 @@ show_usage (int ex)
" --ephemeral use GPGME_KEYLIST_MODE_EPHEMERAL\n"
" --validate use GPGME_KEYLIST_MODE_VALIDATE\n"
" --locate use GPGME_KEYLIST_MODE_LOCATE\n"
+ " --force-extern use GPGME_KEYLIST_MODE_FORCE_EXTERN\n"
+ " --locate-external use GPGME_KEYLIST_MODE_LOCATE_EXTERNAL\n"
, stderr);
exit (ex);
}
@@ -116,6 +118,12 @@ main (int argc, char **argv)
} else if (!strcmp (*argv, "--locate")) {
argc--; argv++;
mode |= KeyListMode::Locate;
+ } else if (!strcmp (*argv, "--force-extern")) {
+ argc--; argv++;
+ mode |= KeyListMode::ForceExtern;
+ } else if (!strcmp (*argv, "--locate-external")) {
+ argc--; argv++;
+ mode |= KeyListMode::LocateExternal;
} else if (!strncmp (*argv, "--", 2)) {
show_usage (1);
}
@@ -132,6 +140,12 @@ main (int argc, char **argv)
return -1;
}
ctx->setKeyListMode (mode);
+ if (ctx->keyListMode() != mode) {
+ // unfortunately, Context::setKeyListMode() does not return the error
+ // returned by gpgme
+ std::cerr << "Failed to set keylist mode. You may have used an invalid combination of options.";
+ return -1;
+ }
Error err;
const GpgME::Key key = ctx->key (*argv, err, only_secret);
std::stringstream ss;
diff --git a/lang/cpp/tests/run-keylist.cpp b/lang/cpp/tests/run-keylist.cpp
index 5457739..9e7d763 100644
--- a/lang/cpp/tests/run-keylist.cpp
+++ b/lang/cpp/tests/run-keylist.cpp
@@ -61,6 +61,8 @@ show_usage (int ex)
" --ephemeral use GPGME_KEYLIST_MODE_EPHEMERAL\n"
" --validate use GPGME_KEYLIST_MODE_VALIDATE\n"
" --locate use GPGME_KEYLIST_MODE_LOCATE\n"
+ " --force-extern use GPGME_KEYLIST_MODE_FORCE_EXTERN\n"
+ " --locate-external use GPGME_KEYLIST_MODE_LOCATE_EXTERNAL\n"
, stderr);
exit (ex);
}
@@ -117,7 +119,17 @@ main (int argc, char **argv)
} else if (!strcmp (*argv, "--locate")) {
argc--; argv++;
mode |= KeyListMode::Locate;
+ } else if (!strcmp (*argv, "--with-secret")) {
+ argc--; argv++;
+ mode |= KeyListMode::WithSecret;
+ } else if (!strcmp (*argv, "--force-extern")) {
+ argc--; argv++;
+ mode |= KeyListMode::ForceExtern;
+ } else if (!strcmp (*argv, "--locate-external")) {
+ argc--; argv++;
+ mode |= KeyListMode::LocateExternal;
} else if (!strncmp (*argv, "--", 2)) {
+ std::cerr << "Error: Unknown option: " << *argv << std::endl;
show_usage (1);
}
}
@@ -133,6 +145,12 @@ main (int argc, char **argv)
return -1;
}
ctx->setKeyListMode (mode);
+ if (ctx->keyListMode() != mode) {
+ // unfortunately, Context::setKeyListMode() does not return the error
+ // returned by gpgme
+ std::cerr << "Failed to set keylist mode. You may have used an invalid combination of options.\n";
+ return -1;
+ }
Error err = ctx->startKeyListing (*argv, only_secret);
if (err) {
std::cout << "Error: " << err.asString() << "\n";
diff --git a/lang/js/BrowserTestExtension/Makefile.in b/lang/js/BrowserTestExtension/Makefile.in
index 68fa1ac..5f6fae4 100644
--- a/lang/js/BrowserTestExtension/Makefile.in
+++ b/lang/js/BrowserTestExtension/Makefile.in
@@ -110,6 +110,7 @@ host_triplet = @host@
subdir = lang/js/BrowserTestExtension
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -199,6 +200,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/js/DemoExtension/Makefile.in b/lang/js/DemoExtension/Makefile.in
index ce14e1f..70d5b1c 100644
--- a/lang/js/DemoExtension/Makefile.in
+++ b/lang/js/DemoExtension/Makefile.in
@@ -110,6 +110,7 @@ host_triplet = @host@
subdir = lang/js/DemoExtension
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -199,6 +200,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/js/Makefile.in b/lang/js/Makefile.in
index 8810732..a0904d9 100644
--- a/lang/js/Makefile.in
+++ b/lang/js/Makefile.in
@@ -109,6 +109,7 @@ host_triplet = @host@
subdir = lang/js
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -258,6 +259,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/js/src/Makefile.in b/lang/js/src/Makefile.in
index 05f1d7a..b11046d 100644
--- a/lang/js/src/Makefile.in
+++ b/lang/js/src/Makefile.in
@@ -110,6 +110,7 @@ host_triplet = @host@
subdir = lang/js/src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -199,6 +200,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/python/Makefile.in b/lang/python/Makefile.in
index c0fc091..b3e6b56 100644
--- a/lang/python/Makefile.in
+++ b/lang/python/Makefile.in
@@ -109,6 +109,7 @@ host_triplet = @host@
subdir = lang/python
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -259,6 +260,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/python/doc/Makefile.in b/lang/python/doc/Makefile.in
index a53283b..2d9e826 100644
--- a/lang/python/doc/Makefile.in
+++ b/lang/python/doc/Makefile.in
@@ -109,6 +109,7 @@ host_triplet = @host@
subdir = lang/python/doc
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -198,6 +199,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/python/examples/Makefile.in b/lang/python/examples/Makefile.in
index 06ea925..87c0c20 100644
--- a/lang/python/examples/Makefile.in
+++ b/lang/python/examples/Makefile.in
@@ -109,6 +109,7 @@ host_triplet = @host@
subdir = lang/python/examples
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -198,6 +199,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/python/src/Makefile.in b/lang/python/src/Makefile.in
index f250242..c711628 100644
--- a/lang/python/src/Makefile.in
+++ b/lang/python/src/Makefile.in
@@ -109,6 +109,7 @@ host_triplet = @host@
subdir = lang/python/src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -198,6 +199,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/python/src/core.py b/lang/python/src/core.py
index 9618adc..c7b312b 100644
--- a/lang/python/src/core.py
+++ b/lang/python/src/core.py
@@ -106,9 +106,13 @@ class GpgmeWrapper(object):
set_func = getattr(gpgme, "{}set_{}".format(self._cprefix, key))
def get(slf):
+ if not slf.wrapped:
+ return False
return bool(get_func(slf.wrapped))
def set_(slf, value):
+ if not slf.wrapped:
+ return
set_func(slf.wrapped, bool(value))
p = property(get, set_, doc="{} flag".format(key))
@@ -135,6 +139,8 @@ class GpgmeWrapper(object):
if self._errorcheck(name):
def _funcwrap(slf, *args):
+ if not slf.wrapped:
+ return None
result = func(slf.wrapped, *args)
if slf._callback_excinfo:
gpgme.gpg_raise_callback_exception(slf)
@@ -142,6 +148,8 @@ class GpgmeWrapper(object):
else:
def _funcwrap(slf, *args):
+ if not slf.wrapped:
+ return None
result = func(slf.wrapped, *args)
if slf._callback_excinfo:
gpgme.gpg_raise_callback_exception(slf)
@@ -332,8 +340,7 @@ class Context(GpgmeWrapper):
finally:
if passphrase is not None:
self.pinentry_mode = old_pinentry_mode
- if old_passphrase_cb:
- self.set_passphrase_cb(*old_passphrase_cb[1:])
+ gpgme.gpg_set_passphrase_cb(self, old_passphrase_cb)
result = self.op_encrypt_result()
assert not result.invalid_recipients
@@ -426,8 +433,7 @@ class Context(GpgmeWrapper):
finally:
if passphrase is not None:
self.pinentry_mode = old_pinentry_mode
- if old_passphrase_cb:
- self.set_passphrase_cb(*old_passphrase_cb[1:])
+ gpgme.gpg_set_passphrase_cb(self, old_passphrase_cb)
result = self.op_decrypt_result()
@@ -851,8 +857,7 @@ class Context(GpgmeWrapper):
finally:
if util.is_a_string(passphrase):
self.pinentry_mode = old_pinentry_mode
- if old_passphrase_cb:
- self.set_passphrase_cb(*old_passphrase_cb[1:])
+ gpgme.gpg_set_passphrase_cb(self, old_passphrase_cb)
return self.op_genkey_result()
@@ -934,8 +939,7 @@ class Context(GpgmeWrapper):
finally:
if util.is_a_string(passphrase):
self.pinentry_mode = old_pinentry_mode
- if old_passphrase_cb:
- self.set_passphrase_cb(*old_passphrase_cb[1:])
+ gpgme.gpg_set_passphrase_cb(self, old_passphrase_cb)
return self.op_genkey_result()
@@ -1102,6 +1106,8 @@ class Context(GpgmeWrapper):
@property
def signers(self):
"""Keys used for signing"""
+ if not self.wrapped:
+ return None
return [self.signers_enum(i) for i in range(self.signers_count())]
@signers.setter
@@ -1137,6 +1143,8 @@ class Context(GpgmeWrapper):
@property
def home_dir(self):
"""Engine's home directory"""
+ if not self.wrapped:
+ return None
return self.engine_info.home_dir
@home_dir.setter
@@ -1182,7 +1190,7 @@ class Context(GpgmeWrapper):
return self
def __exit__(self, type, value, tb):
- self.__del__()
+ return False
def op_keylist_all(self, *args, **kwargs):
self.op_keylist_start(*args, **kwargs)
@@ -1520,7 +1528,7 @@ class Data(GpgmeWrapper):
return self
def __exit__(self, type, value, tb):
- self.__del__()
+ return False
def _free_datacbs(self):
self._data_cbs = None
diff --git a/lang/python/tests/Makefile.in b/lang/python/tests/Makefile.in
index 9e60086..cbc6980 100644
--- a/lang/python/tests/Makefile.in
+++ b/lang/python/tests/Makefile.in
@@ -108,6 +108,7 @@ host_triplet = @host@
subdir = lang/python/tests
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -197,6 +198,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/python/tests/t-idiomatic.py b/lang/python/tests/t-idiomatic.py
index bc05e6c..faa4190 100755
--- a/lang/python/tests/t-idiomatic.py
+++ b/lang/python/tests/t-idiomatic.py
@@ -35,6 +35,9 @@ with gpg.Context() as c, gpg.Data() as d:
d.write(b"Halloechen")
leak_c = c
leak_d = d
+
+leak_c.__del__()
+leak_d.__del__()
assert leak_c.wrapped is None
assert leak_d.wrapped is None
diff --git a/lang/qt/Makefile.in b/lang/qt/Makefile.in
index d186d88..b8d894b 100644
--- a/lang/qt/Makefile.in
+++ b/lang/qt/Makefile.in
@@ -110,6 +110,7 @@ host_triplet = @host@
subdir = lang/qt
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -259,6 +260,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/qt/doc/Makefile.in b/lang/qt/doc/Makefile.in
index eadc021..56ffde0 100644
--- a/lang/qt/doc/Makefile.in
+++ b/lang/qt/doc/Makefile.in
@@ -109,6 +109,7 @@ host_triplet = @host@
subdir = lang/qt/doc
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -198,6 +199,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am
index d47da89..3923e5b 100644
--- a/lang/qt/src/Makefile.am
+++ b/lang/qt/src/Makefile.am
@@ -21,7 +21,7 @@
lib_LTLIBRARIES = libqgpgme.la
EXTRA_DIST = QGpgmeConfig.cmake.in.in QGpgmeConfigVersion.cmake.in \
qgpgme_debug.h qgpgme_version.h.in \
- QGpgmeConfig.cmake.in.in
+ QGpgmeConfig-w32.cmake.in.in
qgpgme_sources = \
dataprovider.cpp \
@@ -35,14 +35,17 @@ qgpgme_sources = \
qgpgmeimportjob.cpp qgpgmekeygenerationjob.cpp qgpgmekeylistjob.cpp \
qgpgmelistallkeysjob.cpp qgpgmenewcryptoconfig.cpp \
qgpgmereceivekeysjob.cpp \
- qgpgmerefreshkeysjob.cpp \
+ qgpgmerefreshsmimekeysjob.cpp \
+ qgpgmerevokekeyjob.cpp \
+ qgpgmesetprimaryuseridjob.cpp \
qgpgmesignencryptjob.cpp \
qgpgmesignjob.cpp qgpgmesignkeyjob.cpp qgpgmeverifydetachedjob.cpp \
qgpgmeverifyopaquejob.cpp qgpgmewkdlookupjob.cpp threadedjobmixin.cpp \
qgpgmekeyformailboxjob.cpp qgpgme_debug.cpp \
qgpgmetofupolicyjob.cpp qgpgmequickjob.cpp \
defaultkeygenerationjob.cpp qgpgmewkspublishjob.cpp \
- qgpgmegpgcardjob.cpp changeexpiryjob.cpp importjob.cpp \
+ qgpgmegpgcardjob.cpp changeexpiryjob.cpp encryptjob.cpp importjob.cpp \
+ signencryptjob.cpp \
dn.cpp cryptoconfig.cpp wkdlookupresult.cpp \
util.cpp
@@ -70,6 +73,8 @@ qgpgme_headers= \
qgpgmenewcryptoconfig.h \
quickjob.h \
receivekeysjob.h \
+ revokekeyjob.h \
+ setprimaryuseridjob.h \
specialjob.h \
signjob.h \
signkeyjob.h \
@@ -114,6 +119,8 @@ camelcase_headers= \
QGpgMENewCryptoConfig \
QuickJob \
ReceiveKeysJob \
+ RevokeKeyJob \
+ SetPrimaryUserIDJob \
SpecialJob \
SignJob \
SignKeyJob \
@@ -158,7 +165,9 @@ private_qgpgme_headers = \
qgpgmekeylistjob.h \
qgpgmelistallkeysjob.h \
qgpgmereceivekeysjob.h \
- qgpgmerefreshkeysjob.h \
+ qgpgmerefreshsmimekeysjob.h \
+ qgpgmerevokekeyjob.h \
+ qgpgmesetprimaryuseridjob.h \
qgpgmesignencryptjob.h \
qgpgmesignjob.h \
qgpgmesignkeyjob.h \
@@ -211,7 +220,9 @@ qgpgme_moc_sources = \
qgpgmekeylistjob.moc \
qgpgmelistallkeysjob.moc \
qgpgmereceivekeysjob.moc \
- qgpgmerefreshkeysjob.moc \
+ qgpgmerefreshsmimekeysjob.moc \
+ qgpgmerevokekeyjob.moc \
+ qgpgmesetprimaryuseridjob.moc \
qgpgmesignencryptjob.moc \
qgpgmesignjob.moc \
qgpgmesignkeyjob.moc \
@@ -223,6 +234,8 @@ qgpgme_moc_sources = \
qgpgmetofupolicyjob.moc \
receivekeysjob.moc \
refreshkeysjob.moc \
+ revokekeyjob.moc \
+ setprimaryuseridjob.moc \
signencryptjob.moc \
signjob.moc \
signkeyjob.moc \
diff --git a/lang/qt/src/Makefile.in b/lang/qt/src/Makefile.in
index 2f09648..52ab451 100644
--- a/lang/qt/src/Makefile.in
+++ b/lang/qt/src/Makefile.in
@@ -92,6 +92,7 @@ host_triplet = @host@
subdir = lang/qt/src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -155,15 +156,17 @@ am__objects_1 = dataprovider.lo debug.lo job.lo multideletejob.lo \
qgpgmeimportjob.lo qgpgmekeygenerationjob.lo \
qgpgmekeylistjob.lo qgpgmelistallkeysjob.lo \
qgpgmenewcryptoconfig.lo qgpgmereceivekeysjob.lo \
- qgpgmerefreshkeysjob.lo qgpgmesignencryptjob.lo \
+ qgpgmerefreshsmimekeysjob.lo qgpgmerevokekeyjob.lo \
+ qgpgmesetprimaryuseridjob.lo qgpgmesignencryptjob.lo \
qgpgmesignjob.lo qgpgmesignkeyjob.lo \
qgpgmeverifydetachedjob.lo qgpgmeverifyopaquejob.lo \
qgpgmewkdlookupjob.lo threadedjobmixin.lo \
qgpgmekeyformailboxjob.lo qgpgme_debug.lo \
qgpgmetofupolicyjob.lo qgpgmequickjob.lo \
defaultkeygenerationjob.lo qgpgmewkspublishjob.lo \
- qgpgmegpgcardjob.lo changeexpiryjob.lo importjob.lo dn.lo \
- cryptoconfig.lo wkdlookupresult.lo util.lo
+ qgpgmegpgcardjob.lo changeexpiryjob.lo encryptjob.lo \
+ importjob.lo signencryptjob.lo dn.lo cryptoconfig.lo \
+ wkdlookupresult.lo util.lo
am__objects_2 =
am_libqgpgme_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_2)
@@ -195,9 +198,9 @@ am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/changeexpiryjob.Plo \
./$(DEPDIR)/cryptoconfig.Plo ./$(DEPDIR)/dataprovider.Plo \
./$(DEPDIR)/debug.Plo ./$(DEPDIR)/defaultkeygenerationjob.Plo \
- ./$(DEPDIR)/dn.Plo ./$(DEPDIR)/importjob.Plo \
- ./$(DEPDIR)/job.Plo ./$(DEPDIR)/multideletejob.Plo \
- ./$(DEPDIR)/qgpgme_debug.Plo \
+ ./$(DEPDIR)/dn.Plo ./$(DEPDIR)/encryptjob.Plo \
+ ./$(DEPDIR)/importjob.Plo ./$(DEPDIR)/job.Plo \
+ ./$(DEPDIR)/multideletejob.Plo ./$(DEPDIR)/qgpgme_debug.Plo \
./$(DEPDIR)/qgpgmeaddexistingsubkeyjob.Plo \
./$(DEPDIR)/qgpgmeadduseridjob.Plo \
./$(DEPDIR)/qgpgmebackend.Plo \
@@ -220,7 +223,9 @@ am__depfiles_remade = ./$(DEPDIR)/changeexpiryjob.Plo \
./$(DEPDIR)/qgpgmenewcryptoconfig.Plo \
./$(DEPDIR)/qgpgmequickjob.Plo \
./$(DEPDIR)/qgpgmereceivekeysjob.Plo \
- ./$(DEPDIR)/qgpgmerefreshkeysjob.Plo \
+ ./$(DEPDIR)/qgpgmerefreshsmimekeysjob.Plo \
+ ./$(DEPDIR)/qgpgmerevokekeyjob.Plo \
+ ./$(DEPDIR)/qgpgmesetprimaryuseridjob.Plo \
./$(DEPDIR)/qgpgmesignencryptjob.Plo \
./$(DEPDIR)/qgpgmesignjob.Plo ./$(DEPDIR)/qgpgmesignkeyjob.Plo \
./$(DEPDIR)/qgpgmetofupolicyjob.Plo \
@@ -228,6 +233,7 @@ am__depfiles_remade = ./$(DEPDIR)/changeexpiryjob.Plo \
./$(DEPDIR)/qgpgmeverifyopaquejob.Plo \
./$(DEPDIR)/qgpgmewkdlookupjob.Plo \
./$(DEPDIR)/qgpgmewkspublishjob.Plo \
+ ./$(DEPDIR)/signencryptjob.Plo \
./$(DEPDIR)/threadedjobmixin.Plo ./$(DEPDIR)/util.Plo \
./$(DEPDIR)/wkdlookupresult.Plo
am__mv = mv -f
@@ -351,6 +357,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
@@ -524,7 +531,7 @@ top_srcdir = @top_srcdir@
lib_LTLIBRARIES = libqgpgme.la
EXTRA_DIST = QGpgmeConfig.cmake.in.in QGpgmeConfigVersion.cmake.in \
qgpgme_debug.h qgpgme_version.h.in \
- QGpgmeConfig.cmake.in.in
+ QGpgmeConfig-w32.cmake.in.in
qgpgme_sources = \
dataprovider.cpp \
@@ -538,14 +545,17 @@ qgpgme_sources = \
qgpgmeimportjob.cpp qgpgmekeygenerationjob.cpp qgpgmekeylistjob.cpp \
qgpgmelistallkeysjob.cpp qgpgmenewcryptoconfig.cpp \
qgpgmereceivekeysjob.cpp \
- qgpgmerefreshkeysjob.cpp \
+ qgpgmerefreshsmimekeysjob.cpp \
+ qgpgmerevokekeyjob.cpp \
+ qgpgmesetprimaryuseridjob.cpp \
qgpgmesignencryptjob.cpp \
qgpgmesignjob.cpp qgpgmesignkeyjob.cpp qgpgmeverifydetachedjob.cpp \
qgpgmeverifyopaquejob.cpp qgpgmewkdlookupjob.cpp threadedjobmixin.cpp \
qgpgmekeyformailboxjob.cpp qgpgme_debug.cpp \
qgpgmetofupolicyjob.cpp qgpgmequickjob.cpp \
defaultkeygenerationjob.cpp qgpgmewkspublishjob.cpp \
- qgpgmegpgcardjob.cpp changeexpiryjob.cpp importjob.cpp \
+ qgpgmegpgcardjob.cpp changeexpiryjob.cpp encryptjob.cpp importjob.cpp \
+ signencryptjob.cpp \
dn.cpp cryptoconfig.cpp wkdlookupresult.cpp \
util.cpp
@@ -574,6 +584,8 @@ qgpgme_headers = \
qgpgmenewcryptoconfig.h \
quickjob.h \
receivekeysjob.h \
+ revokekeyjob.h \
+ setprimaryuseridjob.h \
specialjob.h \
signjob.h \
signkeyjob.h \
@@ -618,6 +630,8 @@ camelcase_headers = \
QGpgMENewCryptoConfig \
QuickJob \
ReceiveKeysJob \
+ RevokeKeyJob \
+ SetPrimaryUserIDJob \
SpecialJob \
SignJob \
SignKeyJob \
@@ -662,7 +676,9 @@ private_qgpgme_headers = \
qgpgmekeylistjob.h \
qgpgmelistallkeysjob.h \
qgpgmereceivekeysjob.h \
- qgpgmerefreshkeysjob.h \
+ qgpgmerefreshsmimekeysjob.h \
+ qgpgmerevokekeyjob.h \
+ qgpgmesetprimaryuseridjob.h \
qgpgmesignencryptjob.h \
qgpgmesignjob.h \
qgpgmesignkeyjob.h \
@@ -715,7 +731,9 @@ qgpgme_moc_sources = \
qgpgmekeylistjob.moc \
qgpgmelistallkeysjob.moc \
qgpgmereceivekeysjob.moc \
- qgpgmerefreshkeysjob.moc \
+ qgpgmerefreshsmimekeysjob.moc \
+ qgpgmerevokekeyjob.moc \
+ qgpgmesetprimaryuseridjob.moc \
qgpgmesignencryptjob.moc \
qgpgmesignjob.moc \
qgpgmesignkeyjob.moc \
@@ -727,6 +745,8 @@ qgpgme_moc_sources = \
qgpgmetofupolicyjob.moc \
receivekeysjob.moc \
refreshkeysjob.moc \
+ revokekeyjob.moc \
+ setprimaryuseridjob.moc \
signencryptjob.moc \
signjob.moc \
signkeyjob.moc \
@@ -861,6 +881,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defaultkeygenerationjob.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dn.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encryptjob.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/importjob.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/job.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multideletejob.Plo@am__quote@ # am--include-marker
@@ -887,7 +908,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmenewcryptoconfig.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmequickjob.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmereceivekeysjob.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmerefreshkeysjob.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmerefreshsmimekeysjob.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmerevokekeyjob.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmesetprimaryuseridjob.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmesignencryptjob.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmesignjob.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmesignkeyjob.Plo@am__quote@ # am--include-marker
@@ -896,6 +919,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmeverifyopaquejob.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmewkdlookupjob.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgpgmewkspublishjob.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signencryptjob.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threadedjobmixin.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wkdlookupresult.Plo@am__quote@ # am--include-marker
@@ -1135,6 +1159,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/debug.Plo
-rm -f ./$(DEPDIR)/defaultkeygenerationjob.Plo
-rm -f ./$(DEPDIR)/dn.Plo
+ -rm -f ./$(DEPDIR)/encryptjob.Plo
-rm -f ./$(DEPDIR)/importjob.Plo
-rm -f ./$(DEPDIR)/job.Plo
-rm -f ./$(DEPDIR)/multideletejob.Plo
@@ -1161,7 +1186,9 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/qgpgmenewcryptoconfig.Plo
-rm -f ./$(DEPDIR)/qgpgmequickjob.Plo
-rm -f ./$(DEPDIR)/qgpgmereceivekeysjob.Plo
- -rm -f ./$(DEPDIR)/qgpgmerefreshkeysjob.Plo
+ -rm -f ./$(DEPDIR)/qgpgmerefreshsmimekeysjob.Plo
+ -rm -f ./$(DEPDIR)/qgpgmerevokekeyjob.Plo
+ -rm -f ./$(DEPDIR)/qgpgmesetprimaryuseridjob.Plo
-rm -f ./$(DEPDIR)/qgpgmesignencryptjob.Plo
-rm -f ./$(DEPDIR)/qgpgmesignjob.Plo
-rm -f ./$(DEPDIR)/qgpgmesignkeyjob.Plo
@@ -1170,6 +1197,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/qgpgmeverifyopaquejob.Plo
-rm -f ./$(DEPDIR)/qgpgmewkdlookupjob.Plo
-rm -f ./$(DEPDIR)/qgpgmewkspublishjob.Plo
+ -rm -f ./$(DEPDIR)/signencryptjob.Plo
-rm -f ./$(DEPDIR)/threadedjobmixin.Plo
-rm -f ./$(DEPDIR)/util.Plo
-rm -f ./$(DEPDIR)/wkdlookupresult.Plo
@@ -1226,6 +1254,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/debug.Plo
-rm -f ./$(DEPDIR)/defaultkeygenerationjob.Plo
-rm -f ./$(DEPDIR)/dn.Plo
+ -rm -f ./$(DEPDIR)/encryptjob.Plo
-rm -f ./$(DEPDIR)/importjob.Plo
-rm -f ./$(DEPDIR)/job.Plo
-rm -f ./$(DEPDIR)/multideletejob.Plo
@@ -1252,7 +1281,9 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/qgpgmenewcryptoconfig.Plo
-rm -f ./$(DEPDIR)/qgpgmequickjob.Plo
-rm -f ./$(DEPDIR)/qgpgmereceivekeysjob.Plo
- -rm -f ./$(DEPDIR)/qgpgmerefreshkeysjob.Plo
+ -rm -f ./$(DEPDIR)/qgpgmerefreshsmimekeysjob.Plo
+ -rm -f ./$(DEPDIR)/qgpgmerevokekeyjob.Plo
+ -rm -f ./$(DEPDIR)/qgpgmesetprimaryuseridjob.Plo
-rm -f ./$(DEPDIR)/qgpgmesignencryptjob.Plo
-rm -f ./$(DEPDIR)/qgpgmesignjob.Plo
-rm -f ./$(DEPDIR)/qgpgmesignkeyjob.Plo
@@ -1261,6 +1292,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/qgpgmeverifyopaquejob.Plo
-rm -f ./$(DEPDIR)/qgpgmewkdlookupjob.Plo
-rm -f ./$(DEPDIR)/qgpgmewkspublishjob.Plo
+ -rm -f ./$(DEPDIR)/signencryptjob.Plo
-rm -f ./$(DEPDIR)/threadedjobmixin.Plo
-rm -f ./$(DEPDIR)/util.Plo
-rm -f ./$(DEPDIR)/wkdlookupresult.Plo
diff --git a/lang/qt/src/RevokeKeyJob b/lang/qt/src/RevokeKeyJob
new file mode 100644
index 0000000..5d0f973
--- /dev/null
+++ b/lang/qt/src/RevokeKeyJob
@@ -0,0 +1 @@
+#include "qgpgme/revokekeyjob.h"
diff --git a/lang/qt/src/SetPrimaryUserIDJob b/lang/qt/src/SetPrimaryUserIDJob
new file mode 100644
index 0000000..f61a24c
--- /dev/null
+++ b/lang/qt/src/SetPrimaryUserIDJob
@@ -0,0 +1 @@
+#include "qgpgme/setprimaryuseridjob.h"
diff --git a/lang/qt/src/decryptjob.h b/lang/qt/src/decryptjob.h
index 7753e18..5195407 100644
--- a/lang/qt/src/decryptjob.h
+++ b/lang/qt/src/decryptjob.h
@@ -84,8 +84,6 @@ public:
If \a plainText is non-null, the plaintext is written
there. Otherwise, it will be delivered in the second argument
of result().
-
- \throws GpgME::Exception if starting fails
*/
virtual void start(const std::shared_ptr<QIODevice> &cipherText, const std::shared_ptr<QIODevice> &plainText = std::shared_ptr<QIODevice>()) = 0;
diff --git a/lang/qt/src/decryptverifyjob.h b/lang/qt/src/decryptverifyjob.h
index e5c4346..8444e4d 100644
--- a/lang/qt/src/decryptverifyjob.h
+++ b/lang/qt/src/decryptverifyjob.h
@@ -85,8 +85,6 @@ public:
If \a plainText is non-null, the plaintext is written
there. Otherwise, it will be delivered in the third argument
of result().
-
- \throws GpgME::Exception if starting fails
*/
virtual void start(const std::shared_ptr<QIODevice> &cipherText, const std::shared_ptr<QIODevice> &plainText = std::shared_ptr<QIODevice>()) = 0;
diff --git a/lang/qt/src/downloadjob.h b/lang/qt/src/downloadjob.h
index 7c8bb72..b916c41 100644
--- a/lang/qt/src/downloadjob.h
+++ b/lang/qt/src/downloadjob.h
@@ -38,6 +38,7 @@
#include "job.h"
#include <QtCore/QByteArray>
+#include <QtCore/QStringList>
#include <memory>
@@ -46,7 +47,6 @@ namespace GpgME
class Error;
}
-class QStringList;
class QIODevice;
class QByteArray;
diff --git a/lang/qt/src/encryptjob.cpp b/lang/qt/src/encryptjob.cpp
new file mode 100644
index 0000000..7533bd9
--- /dev/null
+++ b/lang/qt/src/encryptjob.cpp
@@ -0,0 +1,61 @@
+/*
+ encryptjob.cpp
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "encryptjob.h"
+#include "job_p.h"
+
+using namespace QGpgME;
+
+namespace
+{
+struct EncryptJobPrivate : public JobPrivate
+{
+ QString m_fileName;
+};
+}
+
+void EncryptJob::setFileName(const QString &fileName)
+{
+ auto d = jobPrivate<EncryptJobPrivate>(this);
+ d->m_fileName = fileName;
+}
+
+QString EncryptJob::fileName() const
+{
+ auto d = jobPrivate<EncryptJobPrivate>(this);
+ return d->m_fileName;
+}
diff --git a/lang/qt/src/encryptjob.h b/lang/qt/src/encryptjob.h
index 937ee8d..8135053 100644
--- a/lang/qt/src/encryptjob.h
+++ b/lang/qt/src/encryptjob.h
@@ -5,6 +5,8 @@
Copyright (c) 2004, 2007 Klarälvdalens Datakonsult AB
Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik
Software engineering by Intevation GmbH
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
QGpgME is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -80,6 +82,9 @@ protected:
public:
~EncryptJob();
+ void setFileName(const QString &fileName);
+ QString fileName() const;
+
/**
Starts the encryption operation. \a recipients is the a list of
keys to encrypt \a plainText to. Empty (null) keys are
@@ -99,8 +104,6 @@ public:
If \a cipherText is non-null, the ciphertext is written
there. Otherwise, it will be delivered in the second argument of
result().
-
- \throws GpgME::Exception if starting fails
*/
virtual void start(const std::vector<GpgME::Key> &recipients,
const std::shared_ptr<QIODevice> &plainText,
diff --git a/lang/qt/src/exportjob.h b/lang/qt/src/exportjob.h
index 7f79ea0..4fdb468 100644
--- a/lang/qt/src/exportjob.h
+++ b/lang/qt/src/exportjob.h
@@ -39,14 +39,13 @@
#include "job.h"
#include <QtCore/QByteArray>
+#include <QtCore/QStringList>
namespace GpgME
{
class Error;
}
-class QStringList;
-
namespace QGpgME
{
diff --git a/lang/qt/src/gpgcardjob.h b/lang/qt/src/gpgcardjob.h
index 63f5cf7..3f1b239 100644
--- a/lang/qt/src/gpgcardjob.h
+++ b/lang/qt/src/gpgcardjob.h
@@ -44,24 +44,6 @@ class Error;
namespace QGpgME
{
-/**
- @short Get the best key to use for a Mailbox
-
- To use the keyformailboxjob, first obtain an instance from the
- CryptoBackend and either exec it or start and
- conncet the result() signals to a suitable slot.
- The job will be automatically deleted in which
- case the KeylistJob instance will have schedules it's own
- destruction with a call to QObject::deleteLater().
-
- The best key is defined as the key with a UID that has an
- E-Mail that matches the mailbox provided. If multiple
- keys are found the one with the highest validity is returned.
-
- After result() is emitted, the
- KeyListJob will schedule it's own destruction by calling
- QObject::deleteLater().
-*/
class QGPGME_EXPORT GpgCardJob: public Job
{
Q_OBJECT
diff --git a/lang/qt/src/job.cpp b/lang/qt/src/job.cpp
index a9edc8e..98f408b 100644
--- a/lang/qt/src/job.cpp
+++ b/lang/qt/src/job.cpp
@@ -72,6 +72,8 @@
#include "quickjob.h"
#include "gpgcardjob.h"
#include "receivekeysjob.h"
+#include "revokekeyjob.h"
+#include "setprimaryuseridjob.h"
#include <QCoreApplication>
#include <QDebug>
@@ -172,6 +174,8 @@ make_job_subclass(WKSPublishJob)
make_job_subclass(TofuPolicyJob)
make_job_subclass(QuickJob)
make_job_subclass(GpgCardJob)
+make_job_subclass(RevokeKeyJob)
+make_job_subclass(SetPrimaryUserIDJob)
#undef make_job_subclass
@@ -208,3 +212,5 @@ make_job_subclass(GpgCardJob)
#include "quickjob.moc"
#include "gpgcardjob.moc"
#include "receivekeysjob.moc"
+#include "revokekeyjob.moc"
+#include "setprimaryuseridjob.moc"
diff --git a/lang/qt/src/keyformailboxjob.h b/lang/qt/src/keyformailboxjob.h
index 42d1729..5e08907 100644
--- a/lang/qt/src/keyformailboxjob.h
+++ b/lang/qt/src/keyformailboxjob.h
@@ -57,18 +57,14 @@ namespace QGpgME
To use the keyformailboxjob, first obtain an instance from the
CryptoBackend and either exec it or start and
- conncet the result() signals to a suitable slot.
- The job will be automatically deleted in which
- case the KeylistJob instance will have schedules it's own
- destruction with a call to QObject::deleteLater().
+ connect the result() signal to a suitable slot.
The best key is defined as the key with a UID that has an
E-Mail that matches the mailbox provided. If multiple
keys are found the one with the highest validity is returned.
- After result() is emitted, the
- KeyListJob will schedule it's own destruction by calling
- QObject::deleteLater().
+ After result() is emitted, the job will schedule it's own
+ destruction by calling QObject::deleteLater().
*/
class QGPGME_EXPORT KeyForMailboxJob: public Job
{
diff --git a/lang/qt/src/keylistjob.h b/lang/qt/src/keylistjob.h
index 88eac87..ace9fbe 100644
--- a/lang/qt/src/keylistjob.h
+++ b/lang/qt/src/keylistjob.h
@@ -44,6 +44,8 @@
# include <gpgme++/key.h>
#endif
+#include <QtCore/QStringList>
+
#include <vector>
namespace GpgME
@@ -52,8 +54,6 @@ class Error;
class KeyListResult;
}
-class QStringList;
-
namespace QGpgME
{
@@ -64,7 +64,7 @@ namespace QGpgME
CryptoBackend implementation, connect the nextKey(), progress()
and result() signals to suitable slots and then start the key
listing with a call to start(). This call might fail, in which
- case the KeylistJob instance will have schedules it's own
+ case the KeylistJob instance will have scheduled it's own
destruction with a call to QObject::deleteLater().
During keylisting, you will receive new key objects through the
diff --git a/lang/qt/src/protocol.h b/lang/qt/src/protocol.h
index 62b2cb2..019633a 100644
--- a/lang/qt/src/protocol.h
+++ b/lang/qt/src/protocol.h
@@ -71,6 +71,8 @@ class TofuPolicyJob;
class QuickJob;
class GpgCardJob;
class ReceiveKeysJob;
+class RevokeKeyJob;
+class SetPrimaryUserIDJob;
/** The main entry point for QGpgME Comes in OpenPGP and SMIME(CMS) flavors.
*
@@ -134,6 +136,12 @@ public:
virtual DeleteJob *deleteJob() const = 0;
virtual SignEncryptJob *signEncryptJob(bool armor = false, bool textMode = false) const = 0;
virtual DecryptVerifyJob *decryptVerifyJob(bool textmode = false) const = 0;
+
+ /**
+ * For S/MIME keys this job performs a full validation check of the keys
+ * with updated CRLs.
+ * For OpenPGP keys, use receiveKeysJob.
+ */
virtual RefreshKeysJob *refreshKeysJob() const = 0;
virtual ChangeExpiryJob *changeExpiryJob() const = 0;
virtual SignKeyJob *signKeyJob() const = 0;
@@ -173,6 +181,14 @@ public:
virtual ExportJob *secretSubkeyExportJob(bool armor = false) const = 0;
virtual AddExistingSubkeyJob *addExistingSubkeyJob() const = 0;
virtual ReceiveKeysJob *receiveKeysJob() const = 0;
+
+ virtual RevokeKeyJob *revokeKeyJob() const = 0;
+
+ /**
+ * Returns a job for flagging a user ID as the primary user ID of an
+ * OpenPGP key.
+ */
+ virtual SetPrimaryUserIDJob *setPrimaryUserIDJob() const = 0;
};
/** Obtain a reference to the OpenPGP Protocol.
diff --git a/lang/qt/src/protocol_p.h b/lang/qt/src/protocol_p.h
index 4211e00..685ac4d 100644
--- a/lang/qt/src/protocol_p.h
+++ b/lang/qt/src/protocol_p.h
@@ -42,7 +42,7 @@
#include "qgpgmelistallkeysjob.h"
#include "qgpgmedecryptjob.h"
#include "qgpgmedecryptverifyjob.h"
-#include "qgpgmerefreshkeysjob.h"
+#include "qgpgmerefreshsmimekeysjob.h"
#include "qgpgmedeletejob.h"
#include "qgpgmedownloadjob.h"
#include "qgpgmesignencryptjob.h"
@@ -65,6 +65,8 @@
#include "qgpgmetofupolicyjob.h"
#include "qgpgmequickjob.h"
#include "qgpgmereceivekeysjob.h"
+#include "qgpgmerevokekeyjob.h"
+#include "qgpgmesetprimaryuseridjob.h"
namespace
{
@@ -282,12 +284,11 @@ public:
QGpgME::RefreshKeysJob *refreshKeysJob() const Q_DECL_OVERRIDE
{
- if (mProtocol != GpgME::CMS) { // fixme: add support for gpg, too
+ if (mProtocol != GpgME::CMS) {
return nullptr;
}
- // this operation is not supported by gpgme, so we have to call gpgsm ourselves:
- return new QGpgME::QGpgMERefreshKeysJob();
+ return new QGpgME::QGpgMERefreshSMIMEKeysJob;
}
QGpgME::DownloadJob *downloadJob(bool armor) const Q_DECL_OVERRIDE
@@ -421,7 +422,7 @@ public:
if (!context) {
return nullptr;
}
- context->setKeyListMode(GpgME::Extern | GpgME::Local | GpgME::Signatures | GpgME::Validate);
+ context->setKeyListMode(GpgME::Locate | GpgME::Signatures | GpgME::Validate);
return new QGpgME::QGpgMEKeyListJob(context);
}
@@ -481,6 +482,30 @@ public:
}
return new QGpgME::QGpgMEQuickJob(context);
}
+
+ QGpgME::RevokeKeyJob *revokeKeyJob() const Q_DECL_OVERRIDE
+ {
+ if (mProtocol != GpgME::OpenPGP) {
+ return nullptr;
+ }
+ GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
+ if (!context) {
+ return nullptr;
+ }
+ return new QGpgME::QGpgMERevokeKeyJob(context);
+ }
+
+ QGpgME::SetPrimaryUserIDJob *setPrimaryUserIDJob() const override
+ {
+ if (mProtocol != GpgME::OpenPGP) {
+ return nullptr;
+ }
+ GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
+ if (!context) {
+ return nullptr;
+ }
+ return new QGpgME::QGpgMESetPrimaryUserIDJob{context};
+ }
};
}
diff --git a/lang/qt/src/qgpgmedecryptverifyjob.cpp b/lang/qt/src/qgpgmedecryptverifyjob.cpp
index 5f9a8ab..e2b3724 100644
--- a/lang/qt/src/qgpgmedecryptverifyjob.cpp
+++ b/lang/qt/src/qgpgmedecryptverifyjob.cpp
@@ -67,8 +67,7 @@ static QGpgMEDecryptVerifyJob::result_type decrypt_verify(Context *ctx, QThread
const std::weak_ptr<QIODevice> &cipherText_,
const std::weak_ptr<QIODevice> &plainText_)
{
-
- qCDebug(QGPGME_LOG);
+ qCDebug(QGPGME_LOG) << __func__;
const std::shared_ptr<QIODevice> cipherText = cipherText_.lock();
const std::shared_ptr<QIODevice> plainText = plainText_.lock();
@@ -86,7 +85,7 @@ static QGpgMEDecryptVerifyJob::result_type decrypt_verify(Context *ctx, QThread
const std::pair<DecryptionResult, VerificationResult> res = ctx->decryptAndVerify(indata, outdata);
Error ae;
const QString log = _detail::audit_log_as_html(ctx, ae);
- qCDebug(QGPGME_LOG) << "End no plainText. Error: " << ae;
+ qCDebug(QGPGME_LOG) << __func__ << "- End no plainText. Error:" << ae.asString();
return std::make_tuple(res.first, res.second, out.data(), log, ae);
} else {
QGpgME::QIODeviceDataProvider out(plainText);
@@ -95,10 +94,9 @@ static QGpgMEDecryptVerifyJob::result_type decrypt_verify(Context *ctx, QThread
const std::pair<DecryptionResult, VerificationResult> res = ctx->decryptAndVerify(indata, outdata);
Error ae;
const QString log = _detail::audit_log_as_html(ctx, ae);
- qCDebug(QGPGME_LOG) << "End plainText. Error: " << ae;
+ qCDebug(QGPGME_LOG) << __func__ << "- End plainText. Error:" << ae.asString();
return std::make_tuple(res.first, res.second, QByteArray(), log, ae);
}
-
}
static QGpgMEDecryptVerifyJob::result_type decrypt_verify_qba(Context *ctx, const QByteArray &cipherText)
diff --git a/lang/qt/src/qgpgmeencryptjob.cpp b/lang/qt/src/qgpgmeencryptjob.cpp
index 8fb3dd3..cd54496 100644
--- a/lang/qt/src/qgpgmeencryptjob.cpp
+++ b/lang/qt/src/qgpgmeencryptjob.cpp
@@ -5,6 +5,8 @@
Copyright (c) 2004,2007,2008 Klarälvdalens Datakonsult AB
Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik
Software engineering by Intevation GmbH
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
QGpgME is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -45,7 +47,7 @@
#include "data.h"
#include <QBuffer>
-
+#include <QFileInfo>
#include <cassert>
@@ -71,7 +73,8 @@ static QGpgMEEncryptJob::result_type encrypt(Context *ctx, QThread *thread,
const std::weak_ptr<QIODevice> &plainText_,
const std::weak_ptr<QIODevice> &cipherText_,
const Context::EncryptionFlags eflags,
- bool outputIsBsse64Encoded)
+ bool outputIsBsse64Encoded,
+ const QString &fileName)
{
const std::shared_ptr<QIODevice> plainText = plainText_.lock();
@@ -81,7 +84,12 @@ static QGpgMEEncryptJob::result_type encrypt(Context *ctx, QThread *thread,
const _detail::ToThreadMover ptMover(plainText, thread);
QGpgME::QIODeviceDataProvider in(plainText);
- const Data indata(&in);
+ Data indata(&in);
+
+ const auto pureFileName = QFileInfo{fileName}.fileName().toStdString();
+ if (!pureFileName.empty()) {
+ indata.setFileName(pureFileName.c_str());
+ }
if (!cipherText) {
QGpgME::QByteArrayDataProvider out;
@@ -111,20 +119,20 @@ static QGpgMEEncryptJob::result_type encrypt(Context *ctx, QThread *thread,
}
-static QGpgMEEncryptJob::result_type encrypt_qba(Context *ctx, const std::vector<Key> &recipients, const QByteArray &plainText, const Context::EncryptionFlags eflags, bool outputIsBsse64Encoded)
+static QGpgMEEncryptJob::result_type encrypt_qba(Context *ctx, const std::vector<Key> &recipients, const QByteArray &plainText, const Context::EncryptionFlags eflags, bool outputIsBsse64Encoded, const QString &fileName)
{
const std::shared_ptr<QBuffer> buffer(new QBuffer);
buffer->setData(plainText);
if (!buffer->open(QIODevice::ReadOnly)) {
assert(!"This should never happen: QBuffer::open() failed");
}
- return encrypt(ctx, nullptr, recipients, buffer, std::shared_ptr<QIODevice>(), eflags, outputIsBsse64Encoded);
+ return encrypt(ctx, nullptr, recipients, buffer, std::shared_ptr<QIODevice>(), eflags, outputIsBsse64Encoded, fileName);
}
Error QGpgMEEncryptJob::start(const std::vector<Key> &recipients, const QByteArray &plainText, bool alwaysTrust)
{
run(std::bind(&encrypt_qba, std::placeholders::_1, recipients, plainText,
- alwaysTrust ? Context::AlwaysTrust : Context::None, mOutputIsBase64Encoded));
+ alwaysTrust ? Context::AlwaysTrust : Context::None, mOutputIsBase64Encoded, fileName()));
return Error();
}
@@ -136,14 +144,15 @@ void QGpgMEEncryptJob::start(const std::vector<Key> &recipients, const std::shar
recipients,
std::placeholders::_3, std::placeholders::_4,
eflags,
- mOutputIsBase64Encoded),
+ mOutputIsBase64Encoded,
+ fileName()),
plainText, cipherText);
}
EncryptionResult QGpgMEEncryptJob::exec(const std::vector<Key> &recipients, const QByteArray &plainText,
const Context::EncryptionFlags eflags, QByteArray &cipherText)
{
- const result_type r = encrypt_qba(context(), recipients, plainText, eflags, mOutputIsBase64Encoded);
+ const result_type r = encrypt_qba(context(), recipients, plainText, eflags, mOutputIsBase64Encoded, fileName());
cipherText = std::get<1>(r);
resultHook(r);
return mResult;
diff --git a/lang/qt/src/qgpgmekeyformailboxjob.cpp b/lang/qt/src/qgpgmekeyformailboxjob.cpp
index 534e9a3..b6ab3db 100644
--- a/lang/qt/src/qgpgmekeyformailboxjob.cpp
+++ b/lang/qt/src/qgpgmekeyformailboxjob.cpp
@@ -71,7 +71,7 @@ static bool subkeyIsOk(const Subkey s)
static QGpgMEKeyForMailboxJob::result_type do_work(Context *ctx, const QString &mailbox, bool canEncrypt)
{
/* Do a Keylisting. */
- ctx->setKeyListMode(GpgME::Extern | GpgME::Local | GpgME::Signatures | GpgME::Validate);
+ ctx->setKeyListMode(GpgME::Locate | GpgME::Signatures | GpgME::Validate);
std::vector<Key> keys;
QGpgMEKeyListJob *keylist = new QGpgMEKeyListJob(ctx);
diff --git a/lang/qt/src/qgpgmerefreshkeysjob.cpp b/lang/qt/src/qgpgmerefreshsmimekeysjob.cpp
index 5f78f2a..3187a0c 100644
--- a/lang/qt/src/qgpgmerefreshkeysjob.cpp
+++ b/lang/qt/src/qgpgmerefreshsmimekeysjob.cpp
@@ -1,5 +1,5 @@
/*
- qgpgmerefreshkeysjob.cpp
+ qgpgmerefreshsmimekeysjob.cpp
This file is part of qgpgme, the Qt API binding for gpgme
Copyright (c) 2004 Klarävdalens Datakonsult AB
@@ -38,21 +38,27 @@
#include "config.h"
#endif
-#include "qgpgmerefreshkeysjob.h"
+#include "qgpgmerefreshsmimekeysjob.h"
+#include "util.h"
#include <QDebug>
#include "qgpgme_debug.h"
#include "context.h"
+#include <key.h>
#include <QByteArray>
+#include <QMetaObject>
+#include <QProcess>
#include <QStringList>
#include <gpg-error.h>
#include <assert.h>
-QGpgME::QGpgMERefreshKeysJob::QGpgMERefreshKeysJob()
+using namespace QGpgME;
+
+QGpgMERefreshSMIMEKeysJob::QGpgMERefreshSMIMEKeysJob()
: RefreshKeysJob(nullptr),
mProcess(nullptr),
mError(0)
@@ -60,12 +66,12 @@ QGpgME::QGpgMERefreshKeysJob::QGpgMERefreshKeysJob()
}
-QGpgME::QGpgMERefreshKeysJob::~QGpgMERefreshKeysJob()
+QGpgMERefreshSMIMEKeysJob::~QGpgMERefreshSMIMEKeysJob()
{
}
-GpgME::Error QGpgME::QGpgMERefreshKeysJob::start(const QStringList &patterns)
+GpgME::Error QGpgMERefreshSMIMEKeysJob::start(const QStringList &patterns)
{
assert(mPatternsToDo.empty());
@@ -79,11 +85,31 @@ GpgME::Error QGpgME::QGpgMERefreshKeysJob::start(const QStringList &patterns)
return startAProcess();
}
+GpgME::Error QGpgMERefreshSMIMEKeysJob::start(const std::vector<GpgME::Key> &keys)
+{
+ if (keys.empty()) {
+ QMetaObject::invokeMethod(this, [this]() {
+ Q_EMIT slotProcessExited(0, QProcess::NormalExit);
+ }, Qt::QueuedConnection);
+ return {};
+ }
+
+ const bool gotWrongKeys = std::any_of(std::begin(keys), std::end(keys), [](const auto &k) {
+ return k.protocol() != GpgME::CMS;
+ });
+ if (gotWrongKeys) {
+ qCDebug(QGPGME_LOG) << "Error: At least one of the keys is not an S/MIME key";
+ return GpgME::Error::fromCode(GPG_ERR_INV_VALUE);
+ }
+
+ return start(toFingerprints(keys));
+}
+
#if MAX_CMD_LENGTH < 65 + 128
#error MAX_CMD_LENGTH is too low
#endif
-GpgME::Error QGpgME::QGpgMERefreshKeysJob::startAProcess()
+GpgME::Error QGpgMERefreshSMIMEKeysJob::startAProcess()
{
if (mPatternsToDo.empty()) {
return GpgME::Error();
@@ -122,10 +148,12 @@ GpgME::Error QGpgME::QGpgMERefreshKeysJob::startAProcess()
connect(mProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
SLOT(slotProcessExited(int,QProcess::ExitStatus)));
- connect(mProcess, SIGNAL(readyReadStandardOutput()),
- SLOT(slotStdout()));
- connect(mProcess, &QProcess::readyReadStandardError,
- this, &QGpgMERefreshKeysJob::slotStderr);
+ connect(mProcess, &QProcess::readyReadStandardOutput, this, [this]() {
+ qCDebug(QGPGME_LOG) << "stdout:" << mProcess->readAllStandardOutput();
+ });
+ connect(mProcess, &QProcess::readyReadStandardError, this, [this]() {
+ qCDebug(QGPGME_LOG) << "stderr:" << mProcess->readAllStandardError();
+ });
mProcess->start();
if (!mProcess->waitForStarted()) {
@@ -137,7 +165,7 @@ GpgME::Error QGpgME::QGpgMERefreshKeysJob::startAProcess()
}
}
-void QGpgME::QGpgMERefreshKeysJob::slotCancel()
+void QGpgMERefreshSMIMEKeysJob::slotCancel()
{
if (mProcess) {
mProcess->kill();
@@ -146,7 +174,7 @@ void QGpgME::QGpgMERefreshKeysJob::slotCancel()
mError = GpgME::Error::fromCode(GPG_ERR_CANCELED, GPG_ERR_SOURCE_GPGSM);
}
-void QGpgME::QGpgMERefreshKeysJob::slotStatus(QProcess *proc, const QString &type, const QStringList &args)
+void QGpgMERefreshSMIMEKeysJob::slotStatus(QProcess *proc, const QString &type, const QStringList &args)
{
if (proc != mProcess) {
return;
@@ -204,12 +232,7 @@ void QGpgME::QGpgMERefreshKeysJob::slotStatus(QProcess *proc, const QString &typ
}
}
-void QGpgME::QGpgMERefreshKeysJob::slotStderr()
-{
- // implement? or not?
-}
-
-void QGpgME::QGpgMERefreshKeysJob::slotProcessExited(int exitCode, QProcess::ExitStatus exitStatus)
+void QGpgMERefreshSMIMEKeysJob::slotProcessExited(int exitCode, QProcess::ExitStatus exitStatus)
{
if (!mError && !mPatternsToDo.empty()) {
if (const GpgME::Error err = startAProcess()) {
@@ -227,4 +250,4 @@ void QGpgME::QGpgMERefreshKeysJob::slotProcessExited(int exitCode, QProcess::Exi
Q_EMIT result(mError);
deleteLater();
}
-#include "qgpgmerefreshkeysjob.moc"
+#include "qgpgmerefreshsmimekeysjob.moc"
diff --git a/lang/qt/src/qgpgmerefreshkeysjob.h b/lang/qt/src/qgpgmerefreshsmimekeysjob.h
index 4dfd942..b5b70e9 100644
--- a/lang/qt/src/qgpgmerefreshkeysjob.h
+++ b/lang/qt/src/qgpgmerefreshsmimekeysjob.h
@@ -1,5 +1,5 @@
/*
- qgpgmerefreshkeysjob.h
+ qgpgmerefreshsmimekeysjob.h
This file is part of qgpgme, the Qt API binding for gpgme
Copyright (c) 2004 Klarälvdalens Datakonsult AB
@@ -32,8 +32,8 @@
your version.
*/
-#ifndef __QGPGME_QGPGMEREFRESHKEYSJOB_H__
-#define __QGPGME_QGPGMEREFRESHKEYSJOB_H__
+#ifndef __QGPGME_QGPGMEREFRESHSMIMEKEYSJOB_H__
+#define __QGPGME_QGPGMEREFRESHSMIMEKEYSJOB_H__
#include "refreshkeysjob.h"
#ifdef BUILDING_QGPGME
@@ -48,22 +48,23 @@
namespace QGpgME
{
-class QGpgMERefreshKeysJob : public RefreshKeysJob
+class QGpgMERefreshSMIMEKeysJob : public RefreshKeysJob
{
Q_OBJECT
public:
- QGpgMERefreshKeysJob();
- ~QGpgMERefreshKeysJob();
+ QGpgMERefreshSMIMEKeysJob();
+ ~QGpgMERefreshSMIMEKeysJob();
/* from RefreshKeysJob */
GpgME::Error start(const QStringList &patterns) Q_DECL_OVERRIDE;
+ GpgME::Error start(const std::vector<GpgME::Key> &keys) override;
+
private Q_SLOTS:
/* from Job */
void slotCancel() Q_DECL_OVERRIDE;
void slotStatus(QProcess *, const QString &, const QStringList &);
- void slotStderr();
void slotProcessExited(int exitCode, QProcess::ExitStatus exitStatus);
private:
@@ -77,4 +78,4 @@ private:
}
-#endif // __QGPGME_QGPGMEREFRESHKEYSJOB_H__
+#endif // __QGPGME_QGPGMEREFRESHSMIMEKEYSJOB_H__
diff --git a/lang/qt/src/qgpgmerevokekeyjob.cpp b/lang/qt/src/qgpgmerevokekeyjob.cpp
new file mode 100644
index 0000000..8a2c224
--- /dev/null
+++ b/lang/qt/src/qgpgmerevokekeyjob.cpp
@@ -0,0 +1,128 @@
+/*
+ qgpgmerevokekeyjob.cpp
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "qgpgmerevokekeyjob.h"
+
+#include "dataprovider.h"
+
+#include <context.h>
+#include <data.h>
+#include <gpgrevokekeyeditinteractor.h>
+#include <key.h>
+
+#include <gpg-error.h>
+
+#include "qgpgme_debug.h"
+
+using namespace QGpgME;
+using namespace GpgME;
+
+QGpgMERevokeKeyJob::QGpgMERevokeKeyJob(Context *context)
+ : mixin_type{context}
+{
+ lateInitialization();
+}
+
+QGpgMERevokeKeyJob::~QGpgMERevokeKeyJob() = default;
+
+
+static Error check_arguments(const Key &key,
+ RevocationReason reason,
+ const std::vector<std::string> &description)
+{
+ if (key.isNull()) {
+ qWarning(QGPGME_LOG) << "Error: Key is null key";
+ return Error::fromCode(GPG_ERR_INV_ARG);
+ }
+ if (reason < RevocationReason::Unspecified || reason > RevocationReason::NoLongerUsed) {
+ qWarning(QGPGME_LOG) << "Error: Invalid revocation reason" << static_cast<int>(reason);
+ return Error::fromCode(GPG_ERR_INV_VALUE);
+ }
+ if (std::any_of(std::begin(description), std::end(description),
+ [](const std::string &line) {
+ return line.empty() || line.find('\n') != std::string::npos;
+ })) {
+ qWarning(QGPGME_LOG) << "Error: Revocation description contains empty lines or lines with endline characters";
+ return Error::fromCode(GPG_ERR_INV_VALUE);
+ }
+ return {};
+}
+
+static QGpgMERevokeKeyJob::result_type revoke_key(Context *ctx, const Key &key,
+ RevocationReason reason,
+ const std::vector<std::string> &description)
+{
+ std::unique_ptr<GpgRevokeKeyEditInteractor> interactor{new GpgRevokeKeyEditInteractor};
+ interactor->setReason(reason, description);
+
+ QGpgME::QByteArrayDataProvider dp;
+ Data outData(&dp);
+ assert(!outData.isNull());
+
+ ctx->setFlag("extended-edit", "1");
+
+ const Error err = ctx->edit(key, std::unique_ptr<EditInteractor>(interactor.release()), outData);
+ Error ae;
+ const QString log = _detail::audit_log_as_html(ctx, ae);
+ return std::make_tuple(err, log, ae);
+}
+
+Error QGpgMERevokeKeyJob::start(const GpgME::Key &key,
+ GpgME::RevocationReason reason,
+ const std::vector<std::string> &description)
+{
+ Error err = check_arguments(key, reason, description);
+ if (!err) {
+ run(std::bind(&revoke_key, std::placeholders::_1, key, reason, description));
+ }
+ return err;
+}
+
+Error QGpgMERevokeKeyJob::exec(const GpgME::Key &key,
+ GpgME::RevocationReason reason,
+ const std::vector<std::string> &description)
+{
+ Error err = check_arguments(key, reason, description);
+ if (!err) {
+ const result_type r = revoke_key(context(), key, reason, description);
+ resultHook(r);
+ err = std::get<0>(r);
+ }
+ return err;
+}
+
+#include "qgpgmerevokekeyjob.moc"
diff --git a/lang/qt/src/qgpgmerevokekeyjob.h b/lang/qt/src/qgpgmerevokekeyjob.h
new file mode 100644
index 0000000..0eba5cb
--- /dev/null
+++ b/lang/qt/src/qgpgmerevokekeyjob.h
@@ -0,0 +1,70 @@
+/*
+ qgpgmerevokekeyjob.h
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __QGPGME_QGPGMEREVOKEKEYJOB_H__
+#define __QGPGME_QGPGMEREVOKEKEYJOB_H__
+
+#include "threadedjobmixin.h"
+#include "revokekeyjob.h"
+
+namespace QGpgME
+{
+
+class QGpgMERevokeKeyJob
+#ifdef Q_MOC_RUN
+ : public RevokeKeyJob
+#else
+ : public _detail::ThreadedJobMixin<RevokeKeyJob>
+#endif
+{
+ Q_OBJECT
+#ifdef Q_MOC_RUN
+public Q_SLOTS:
+ void slotFinished();
+#endif
+public:
+ explicit QGpgMERevokeKeyJob(GpgME::Context *context);
+ ~QGpgMERevokeKeyJob() override;
+
+ GpgME::Error start(const GpgME::Key &key,
+ GpgME::RevocationReason reason = GpgME::RevocationReason::Unspecified,
+ const std::vector<std::string> &description = {}) override;
+
+ GpgME::Error exec(const GpgME::Key &key,
+ GpgME::RevocationReason reason = GpgME::RevocationReason::Unspecified,
+ const std::vector<std::string> &description = {}) override;
+};
+
+}
+
+#endif // __QGPGME_QGPGMEREVOKEKEYJOB_H__
diff --git a/lang/qt/src/qgpgmesetprimaryuseridjob.cpp b/lang/qt/src/qgpgmesetprimaryuseridjob.cpp
new file mode 100644
index 0000000..32da1fc
--- /dev/null
+++ b/lang/qt/src/qgpgmesetprimaryuseridjob.cpp
@@ -0,0 +1,75 @@
+/*
+ qgpgmesetprimaryuseridjob.cpp
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "qgpgmesetprimaryuseridjob.h"
+
+#include "util.h"
+
+#include <engineinfo.h>
+
+using namespace QGpgME;
+using namespace GpgME;
+
+static bool quickSetPrimayUidSupportsUidHash()
+{
+ return GpgME::engineInfo(GpgME::GpgEngine).engineVersion() >= "2.3.8";
+}
+
+static QGpgMESetPrimaryUserIDJob::result_type set_primary_userid(Context *ctx, const GpgME::UserID &userId)
+{
+ auto err = ctx->setPrimaryUid(userId.parent(), quickSetPrimayUidSupportsUidHash() ? userId.uidhash() : userId.id());
+ return std::make_tuple(err, QString(), Error());
+}
+
+QGpgMESetPrimaryUserIDJob::QGpgMESetPrimaryUserIDJob(Context *context)
+ : mixin_type{context}
+{
+ lateInitialization();
+}
+
+QGpgMESetPrimaryUserIDJob::~QGpgMESetPrimaryUserIDJob() = default;
+
+GpgME::Error QGpgMESetPrimaryUserIDJob::start(const GpgME::UserID &userId)
+{
+ if (userId.isNull()) {
+ return Error{make_error(GPG_ERR_INV_ARG)};
+ }
+ run([userId](Context *ctx) { return set_primary_userid(ctx, userId); });
+ return {};
+}
+
+#include "qgpgmesetprimaryuseridjob.moc"
diff --git a/lang/qt/src/qgpgmesetprimaryuseridjob.h b/lang/qt/src/qgpgmesetprimaryuseridjob.h
new file mode 100644
index 0000000..4ee967a
--- /dev/null
+++ b/lang/qt/src/qgpgmesetprimaryuseridjob.h
@@ -0,0 +1,64 @@
+/*
+ qgpgmesetprimaryuseridjob.h
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __QGPGME_QGPGMESETPRIMARYUSERIDJOB_H__
+#define __QGPGME_QGPGMESETPRIMARYUSERIDJOB_H__
+
+#include "setprimaryuseridjob.h"
+#include "threadedjobmixin.h"
+
+namespace QGpgME
+{
+
+class QGpgMESetPrimaryUserIDJob
+#ifdef Q_MOC_RUN
+ : public SetPrimaryUserIDJob
+#else
+ : public _detail::ThreadedJobMixin<SetPrimaryUserIDJob>
+#endif
+{
+ Q_OBJECT
+#ifdef Q_MOC_RUN
+public Q_SLOTS:
+ void slotFinished();
+#endif
+public:
+ explicit QGpgMESetPrimaryUserIDJob(GpgME::Context *context);
+ ~QGpgMESetPrimaryUserIDJob() override;
+
+ GpgME::Error start(const GpgME::UserID &userId) override;
+};
+
+}
+
+#endif // __QGPGME_QGPGMESETPRIMARYUSERIDJOB_H__
diff --git a/lang/qt/src/qgpgmesignencryptjob.cpp b/lang/qt/src/qgpgmesignencryptjob.cpp
index 284c110..5466c54 100644
--- a/lang/qt/src/qgpgmesignencryptjob.cpp
+++ b/lang/qt/src/qgpgmesignencryptjob.cpp
@@ -5,6 +5,8 @@
Copyright (c) 2004, 2007 Klarälvdalens Datakonsult AB
Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik
Software engineering by Intevation GmbH
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
QGpgME is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -46,7 +48,7 @@
#include "exception.h"
#include <QBuffer>
-
+#include <QFileInfo>
#include <cassert>
@@ -69,7 +71,7 @@ void QGpgMESignEncryptJob::setOutputIsBase64Encoded(bool on)
static QGpgMESignEncryptJob::result_type sign_encrypt(Context *ctx, QThread *thread, const std::vector<Key> &signers,
const std::vector<Key> &recipients, const std::weak_ptr<QIODevice> &plainText_,
- const std::weak_ptr<QIODevice> &cipherText_, const Context::EncryptionFlags eflags, bool outputIsBsse64Encoded)
+ const std::weak_ptr<QIODevice> &cipherText_, const Context::EncryptionFlags eflags, bool outputIsBsse64Encoded, const QString &fileName)
{
const std::shared_ptr<QIODevice> &plainText = plainText_.lock();
const std::shared_ptr<QIODevice> &cipherText = cipherText_.lock();
@@ -78,7 +80,12 @@ static QGpgMESignEncryptJob::result_type sign_encrypt(Context *ctx, QThread *thr
const _detail::ToThreadMover ptMover(plainText, thread);
QGpgME::QIODeviceDataProvider in(plainText);
- const Data indata(&in);
+ Data indata(&in);
+
+ const auto pureFileName = QFileInfo{fileName}.fileName().toStdString();
+ if (!pureFileName.empty()) {
+ indata.setFileName(pureFileName.c_str());
+ }
ctx->clearSigningKeys();
Q_FOREACH (const Key &signer, signers)
@@ -116,26 +123,26 @@ static QGpgMESignEncryptJob::result_type sign_encrypt(Context *ctx, QThread *thr
}
static QGpgMESignEncryptJob::result_type sign_encrypt_qba(Context *ctx, const std::vector<Key> &signers,
- const std::vector<Key> &recipients, const QByteArray &plainText, const Context::EncryptionFlags eflags, bool outputIsBsse64Encoded)
+ const std::vector<Key> &recipients, const QByteArray &plainText, const Context::EncryptionFlags eflags, bool outputIsBsse64Encoded, const QString &fileName)
{
const std::shared_ptr<QBuffer> buffer(new QBuffer);
buffer->setData(plainText);
if (!buffer->open(QIODevice::ReadOnly)) {
assert(!"This should never happen: QBuffer::open() failed");
}
- return sign_encrypt(ctx, nullptr, signers, recipients, buffer, std::shared_ptr<QIODevice>(), eflags, outputIsBsse64Encoded);
+ return sign_encrypt(ctx, nullptr, signers, recipients, buffer, std::shared_ptr<QIODevice>(), eflags, outputIsBsse64Encoded, fileName);
}
Error QGpgMESignEncryptJob::start(const std::vector<Key> &signers, const std::vector<Key> &recipients, const QByteArray &plainText, bool alwaysTrust)
{
- run(std::bind(&sign_encrypt_qba, std::placeholders::_1, signers, recipients, plainText, alwaysTrust ? Context::AlwaysTrust : Context::None, mOutputIsBase64Encoded));
+ run(std::bind(&sign_encrypt_qba, std::placeholders::_1, signers, recipients, plainText, alwaysTrust ? Context::AlwaysTrust : Context::None, mOutputIsBase64Encoded, fileName()));
return Error();
}
void QGpgMESignEncryptJob::start(const std::vector<Key> &signers, const std::vector<Key> &recipients,
const std::shared_ptr<QIODevice> &plainText, const std::shared_ptr<QIODevice> &cipherText, const Context::EncryptionFlags eflags)
{
- run(std::bind(&sign_encrypt, std::placeholders::_1, std::placeholders::_2, signers, recipients, std::placeholders::_3, std::placeholders::_4, eflags, mOutputIsBase64Encoded), plainText, cipherText);
+ run(std::bind(&sign_encrypt, std::placeholders::_1, std::placeholders::_2, signers, recipients, std::placeholders::_3, std::placeholders::_4, eflags, mOutputIsBase64Encoded, fileName()), plainText, cipherText);
}
void QGpgMESignEncryptJob::start(const std::vector<Key> &signers, const std::vector<Key> &recipients, const std::shared_ptr<QIODevice> &plainText, const std::shared_ptr<QIODevice> &cipherText, bool alwaysTrust)
@@ -145,7 +152,7 @@ void QGpgMESignEncryptJob::start(const std::vector<Key> &signers, const std::vec
std::pair<SigningResult, EncryptionResult> QGpgMESignEncryptJob::exec(const std::vector<Key> &signers, const std::vector<Key> &recipients, const QByteArray &plainText, const Context::EncryptionFlags eflags, QByteArray &cipherText)
{
- const result_type r = sign_encrypt_qba(context(), signers, recipients, plainText, eflags, mOutputIsBase64Encoded);
+ const result_type r = sign_encrypt_qba(context(), signers, recipients, plainText, eflags, mOutputIsBase64Encoded, fileName());
cipherText = std::get<2>(r);
resultHook(r);
return mResult;
diff --git a/lang/qt/src/qgpgmesignkeyjob.cpp b/lang/qt/src/qgpgmesignkeyjob.cpp
index 5036a9b..506d64a 100644
--- a/lang/qt/src/qgpgmesignkeyjob.cpp
+++ b/lang/qt/src/qgpgmesignkeyjob.cpp
@@ -127,11 +127,11 @@ static QGpgMESignKeyJob::result_type sign_key(Context *ctx, const Key &key, cons
if (expirationDate.isValid()) {
// on 2106-02-07, the Unix time will reach 0xFFFFFFFF; since gpg uses uint32 internally
- // for the expiration date clip it at 2106-02-06
- static const QDate maxAllowedDate{2106, 2, 6};
+ // for the expiration date clip it at 2106-02-05 to avoid problems with negative time zones
+ static const QDate maxAllowedDate{2106, 2, 5};
const auto clippedExpirationDate = expirationDate <= maxAllowedDate ? expirationDate : maxAllowedDate;
if (clippedExpirationDate != expirationDate) {
- qCWarning(QGPGME_LOG) << "Expiration of certification has been changed to" << clippedExpirationDate;
+ qCDebug(QGPGME_LOG) << "Expiration of certification has been changed to" << clippedExpirationDate;
}
// use the "days from now" format to specify the expiration date of the certification;
// this format is the most appropriate regardless of the local timezone
diff --git a/lang/qt/src/refreshkeysjob.h b/lang/qt/src/refreshkeysjob.h
index c4ba74a..67774c2 100644
--- a/lang/qt/src/refreshkeysjob.h
+++ b/lang/qt/src/refreshkeysjob.h
@@ -38,6 +38,8 @@
#include "job.h"
#include "qgpgme_export.h"
+#include <QtCore/QStringList>
+
#include <vector>
namespace GpgME
@@ -46,8 +48,6 @@ class Error;
class Key;
}
-class QStringList;
-
namespace QGpgME
{
@@ -61,7 +61,7 @@ namespace QGpgME
RefreshKeysJob instance will have scheduled its own destruction
with a call to QObject::deleteLater().
- After result() is emitted, the KeyListJob will schedule it's own
+ After result() is emitted, the job will schedule it's own
destruction by calling QObject::deleteLater().
*/
class QGPGME_EXPORT RefreshKeysJob : public Job
@@ -73,21 +73,22 @@ public:
~RefreshKeysJob();
/**
- Starts the keylist operation. \a pattern is a list of patterns
+ Starts the refresh operation. \a pattern is a list of patterns
used to restrict the list of keys returned. Empty patterns are
ignored. If \a pattern is empty or contains only empty strings,
- all keys are returned (however, the backend is free to truncate
- the result and should do so; when this happens, it will be
- reported by the reult object).
+ all keys are refreshed.
- If \a secretOnly is true, only keys for which the secret key is
- also available are returned. Use this if you need to select a
- key for signing.
+ Only implemented for S/MIME.
*/
virtual GpgME::Error start(const QStringList &patterns) = 0;
+ /**
+ Starts a refresh of the \a keys.
+ */
+ virtual GpgME::Error start(const std::vector<GpgME::Key> &keys) = 0;
+
Q_SIGNALS:
- void result(const GpgME::Error &error);
+ void result(const GpgME::Error &result);
};
}
diff --git a/lang/qt/src/revokekeyjob.h b/lang/qt/src/revokekeyjob.h
new file mode 100644
index 0000000..69aef06
--- /dev/null
+++ b/lang/qt/src/revokekeyjob.h
@@ -0,0 +1,86 @@
+/*
+ revokekeyjob.h
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __QGPGME_REVOKEKEYJOB_H__
+#define __QGPGME_REVOKEKEYJOB_H__
+
+#include "job.h"
+#include "qgpgme_export.h"
+
+class QString;
+
+namespace GpgME
+{
+class Error;
+class Key;
+}
+
+namespace QGpgME
+{
+
+class QGPGME_EXPORT RevokeKeyJob : public Job
+{
+ Q_OBJECT
+protected:
+ explicit RevokeKeyJob(QObject *parent);
+
+public:
+ ~RevokeKeyJob();
+
+ /**
+ Starts the operation. \a key is the key to revoke with reason \a reason and
+ optional description \a description. The individual elements of \a description
+ must be non-empty strings and they must not contain any endline characters.
+
+ The job deletes itself after it has completed the operation.
+ */
+ virtual GpgME::Error start(const GpgME::Key &key,
+ GpgME::RevocationReason reason = GpgME::RevocationReason::Unspecified,
+ const std::vector<std::string> &description = {}) = 0;
+
+ /**
+ Runs the operation. \a key is the key to revoke with reason \a reason and
+ optional description \a description. The individual elements of \a description
+ must be non-empty strings and they must not contain any endline characters.
+ */
+ virtual GpgME::Error exec(const GpgME::Key &key,
+ GpgME::RevocationReason reason = GpgME::RevocationReason::Unspecified,
+ const std::vector<std::string> &description = {}) = 0;
+
+Q_SIGNALS:
+ void result(const GpgME::Error &result, const QString &auditLogAsHtml = {}, const GpgME::Error &auditLogError = {});
+};
+
+}
+
+#endif // __QGPGME_REVOKEKEYJOB_H__
diff --git a/lang/qt/src/setprimaryuseridjob.h b/lang/qt/src/setprimaryuseridjob.h
new file mode 100644
index 0000000..fa76199
--- /dev/null
+++ b/lang/qt/src/setprimaryuseridjob.h
@@ -0,0 +1,69 @@
+/*
+ setprimaryuseridjob.h
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __QGPGME_SETPRIMARYUSERIDJOB_H__
+#define __QGPGME_SETPRIMARYUSERIDJOB_H__
+
+#include "job.h"
+
+#include "qgpgme_export.h"
+
+namespace GpgME
+{
+class Error;
+class UserID;
+}
+
+namespace QGpgME
+{
+
+class QGPGME_EXPORT SetPrimaryUserIDJob : public Job
+{
+ Q_OBJECT
+public:
+ explicit SetPrimaryUserIDJob(QObject *parent);
+ ~SetPrimaryUserIDJob() override;
+
+ /**
+ * Starts setting user ID \a userId as the primary user ID.
+ */
+ virtual GpgME::Error start(const GpgME::UserID &userId) = 0;
+
+Q_SIGNALS:
+ void result(const GpgME::Error &error,
+ const QString &auditLogAsHtml = QString(), const GpgME::Error &auditLogError = GpgME::Error());
+};
+
+}
+
+#endif // __QGPGME_SETPRIMARYUSERIDJOB_H__
diff --git a/lang/qt/src/signencryptjob.cpp b/lang/qt/src/signencryptjob.cpp
new file mode 100644
index 0000000..aa02fca
--- /dev/null
+++ b/lang/qt/src/signencryptjob.cpp
@@ -0,0 +1,61 @@
+/*
+ signencryptjob.cpp
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "signencryptjob.h"
+#include "job_p.h"
+
+using namespace QGpgME;
+
+namespace
+{
+struct SignEncryptJobPrivate : public JobPrivate
+{
+ QString m_fileName;
+};
+}
+
+void SignEncryptJob::setFileName(const QString &fileName)
+{
+ auto d = jobPrivate<SignEncryptJobPrivate>(this);
+ d->m_fileName = fileName;
+}
+
+QString SignEncryptJob::fileName() const
+{
+ auto d = jobPrivate<SignEncryptJobPrivate>(this);
+ return d->m_fileName;
+}
diff --git a/lang/qt/src/signencryptjob.h b/lang/qt/src/signencryptjob.h
index 61ab5c6..ebb866d 100644
--- a/lang/qt/src/signencryptjob.h
+++ b/lang/qt/src/signencryptjob.h
@@ -5,6 +5,8 @@
Copyright (c) 2004, 2007 Klarälvdalens Datakonsult AB
Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik
Software engineering by Intevation GmbH
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
QGpgME is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -85,6 +87,9 @@ protected:
public:
~SignEncryptJob();
+ void setFileName(const QString &fileName);
+ QString fileName() const;
+
/**
Starts the combined signing and encrypting operation. \a signers
is the list of keys to sign \a plainText with. \a recipients is
@@ -106,8 +111,6 @@ public:
If \a cipherText is non-null, the ciphertext is written
there. Otherwise, it will be delivered in the third argument of
result().
-
- \throws GpgME::Exception if starting fails
*/
virtual void start(const std::vector<GpgME::Key> &signers,
const std::vector<GpgME::Key> &recipients,
diff --git a/lang/qt/src/signjob.h b/lang/qt/src/signjob.h
index 57d2d17..c05231c 100644
--- a/lang/qt/src/signjob.h
+++ b/lang/qt/src/signjob.h
@@ -95,8 +95,6 @@ public:
If \a signature is non-null the signature is written
there. Otherwise, it will be delivered in the second argument of
result().
-
- \throws GpgME::Exception if starting fails
*/
virtual void start(const std::vector<GpgME::Key> &signers,
const std::shared_ptr<QIODevice> &plainText,
diff --git a/lang/qt/src/signkeyjob.h b/lang/qt/src/signkeyjob.h
index f4b3ed8..d0e90c2 100644
--- a/lang/qt/src/signkeyjob.h
+++ b/lang/qt/src/signkeyjob.h
@@ -149,7 +149,7 @@ public:
* Sets the expiration date of the key signature to @a expiration. By default,
* key signatures do not expire.
*
- * Note: Expiration dates after 2106-02-06 will be set to 2106-02-06.
+ * Note: Expiration dates after 2106-02-05 will be set to 2106-02-05.
*
* Not pure virtual for ABI compatibility.
**/
diff --git a/lang/qt/src/util.cpp b/lang/qt/src/util.cpp
index 3d10e2f..66c7eed 100644
--- a/lang/qt/src/util.cpp
+++ b/lang/qt/src/util.cpp
@@ -31,9 +31,17 @@
your version.
*/
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include "util.h"
#include <QStringList>
+
+#include <key.h>
+
+#include <algorithm>
#include <functional>
std::vector<std::string> toStrings(const QStringList &l)
@@ -45,3 +53,13 @@ std::vector<std::string> toStrings(const QStringList &l)
std::mem_fn(&QString::toStdString));
return v;
}
+
+QStringList toFingerprints(const std::vector<GpgME::Key> &keys)
+{
+ QStringList fprs;
+ fprs.reserve(keys.size());
+ std::transform(std::begin(keys), std::end(keys), std::back_inserter(fprs), [](const auto &k) {
+ return QString::fromLatin1(k.primaryFingerprint());
+ });
+ return fprs;
+}
diff --git a/lang/qt/src/util.h b/lang/qt/src/util.h
index 94c9733..6aba62e 100644
--- a/lang/qt/src/util.h
+++ b/lang/qt/src/util.h
@@ -36,11 +36,17 @@
#include <gpgme.h>
+#include <sstream>
#include <string>
#include <vector>
class QStringList;
+namespace GpgME
+{
+class Key;
+}
+
static inline gpgme_error_t make_error(gpgme_err_code_t code)
{
return gpgme_err_make((gpgme_err_source_t)22, code);
@@ -48,4 +54,14 @@ static inline gpgme_error_t make_error(gpgme_err_code_t code)
std::vector<std::string> toStrings(const QStringList &l);
+QStringList toFingerprints(const std::vector<GpgME::Key> &keys);
+
+template<class Result>
+std::string toLogString(const Result &result)
+{
+ std::stringstream stream;
+ stream << result;
+ return stream.str();
+}
+
#endif // __QGPGME_UTIL_H__
diff --git a/lang/qt/src/verifydetachedjob.h b/lang/qt/src/verifydetachedjob.h
index 2293f3a..12fdfbb 100644
--- a/lang/qt/src/verifydetachedjob.h
+++ b/lang/qt/src/verifydetachedjob.h
@@ -81,11 +81,6 @@ public:
virtual GpgME::Error start(const QByteArray &signature,
const QByteArray &signedData) = 0;
- /*!
- \overload
-
- \throws GpgME::Exception if starting fails.
- */
virtual void start(const std::shared_ptr<QIODevice> &signature, const std::shared_ptr<QIODevice> &signedData) = 0;
virtual GpgME::VerificationResult exec(const QByteArray &signature,
diff --git a/lang/qt/src/verifyopaquejob.h b/lang/qt/src/verifyopaquejob.h
index bfa34e9..c9b2247 100644
--- a/lang/qt/src/verifyopaquejob.h
+++ b/lang/qt/src/verifyopaquejob.h
@@ -85,8 +85,6 @@ public:
If \a plainText is non-null, the plaintext is written
there. Otherwise, it will be delivered in the second argument
of result().
-
- \throws GpgME::Exception if starting fails
*/
virtual void start(const std::shared_ptr<QIODevice> &signedData, const std::shared_ptr<QIODevice> &plainText = std::shared_ptr<QIODevice>()) = 0;
diff --git a/lang/qt/src/wkspublishjob.h b/lang/qt/src/wkspublishjob.h
index ff3f21e..2b4daf5 100644
--- a/lang/qt/src/wkspublishjob.h
+++ b/lang/qt/src/wkspublishjob.h
@@ -52,11 +52,9 @@ namespace QGpgME {
* The workflow is to call startCreate, check for errors and then
* send the RFC822 mail returned in returnedData.
*
- * When the response is received start a startRecieve with the
+ * When the response is received call startReceive with the
* RFC822 mail received as parameter response. Check for errors
- * and then send again send the result from returnedData back to
- * the server.
- *
+ * and then send the result from returnedData back to the server.
*/
class QGPGME_EXPORT WKSPublishJob: public Job
{
@@ -66,7 +64,6 @@ protected:
public:
~WKSPublishJob();
-
/** Start a check if WKS Publishing is supported. As this involves
* an HTTP Query it might take a while. Returns GPG_ERR_NOT_SUPPORED
* result if GnuPG is too old or the required tools are not installed.
diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am
index 6c082b0..5724a2d 100644
--- a/lang/qt/tests/Makefile.am
+++ b/lang/qt/tests/Makefile.am
@@ -30,7 +30,7 @@ the_tests = \
t-addexistingsubkey \
t-keylist t-keylocate t-ownertrust t-tofuinfo \
t-encrypt t-verify t-various t-config t-remarks t-trustsignatures \
- t-changeexpiryjob t-wkdlookup t-import
+ t-changeexpiryjob t-wkdlookup t-import t-revokekey t-setprimaryuserid
TESTS = initial.test $(the_tests) final.test
@@ -39,7 +39,8 @@ moc_files = \
t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc \
t-encrypt.moc t-support.hmoc t-wkspublish.moc t-verify.moc \
t-various.moc t-config.moc t-remarks.moc t-trustsignatures.moc \
- t-changeexpiryjob.moc t-wkdlookup.moc t-import.moc
+ t-changeexpiryjob.moc t-wkdlookup.moc t-import.moc t-revokekey.moc \
+ t-setprimaryuserid.moc
AM_LDFLAGS = -no-install
@@ -70,10 +71,13 @@ t_trustsignatures_SOURCES = t-trustsignatures.cpp $(support_src)
t_changeexpiryjob_SOURCES = t-changeexpiryjob.cpp $(support_src)
t_wkdlookup_SOURCES = t-wkdlookup.cpp $(support_src)
t_import_SOURCES = t-import.cpp $(support_src)
+t_revokekey_SOURCES = t-revokekey.cpp $(support_src)
+t_setprimaryuserid_SOURCES = t-setprimaryuserid.cpp $(support_src)
run_exportjob_SOURCES = run-exportjob.cpp
run_importjob_SOURCES = run-importjob.cpp
run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp
run_receivekeysjob_SOURCES = run-receivekeysjob.cpp
+run_refreshkeysjob_SOURCES = run-refreshkeysjob.cpp
nodist_t_keylist_SOURCES = $(moc_files)
@@ -83,8 +87,9 @@ noinst_PROGRAMS = \
t-addexistingsubkey \
t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt \
run-keyformailboxjob t-wkspublish t-verify t-various t-config t-remarks \
- t-trustsignatures t-changeexpiryjob t-wkdlookup t-import run-importjob \
- run-exportjob run-receivekeysjob
+ t-trustsignatures t-changeexpiryjob t-wkdlookup t-import t-revokekey \
+ t-setprimaryuserid \
+ run-importjob run-exportjob run-receivekeysjob run-refreshkeysjob
CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \
gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \
diff --git a/lang/qt/tests/Makefile.in b/lang/qt/tests/Makefile.in
index 89fad15..1c4b87a 100644
--- a/lang/qt/tests/Makefile.in
+++ b/lang/qt/tests/Makefile.in
@@ -114,11 +114,14 @@ noinst_PROGRAMS = t-addexistingsubkey$(EXEEXT) t-keylist$(EXEEXT) \
t-wkspublish$(EXEEXT) t-verify$(EXEEXT) t-various$(EXEEXT) \
t-config$(EXEEXT) t-remarks$(EXEEXT) \
t-trustsignatures$(EXEEXT) t-changeexpiryjob$(EXEEXT) \
- t-wkdlookup$(EXEEXT) t-import$(EXEEXT) run-importjob$(EXEEXT) \
- run-exportjob$(EXEEXT) run-receivekeysjob$(EXEEXT)
+ t-wkdlookup$(EXEEXT) t-import$(EXEEXT) t-revokekey$(EXEEXT) \
+ t-setprimaryuserid$(EXEEXT) run-importjob$(EXEEXT) \
+ run-exportjob$(EXEEXT) run-receivekeysjob$(EXEEXT) \
+ run-refreshkeysjob$(EXEEXT)
subdir = lang/qt/tests
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/glib-2.0.m4 $(top_srcdir)/m4/glibc21.m4 \
@@ -161,6 +164,11 @@ run_receivekeysjob_OBJECTS = $(am_run_receivekeysjob_OBJECTS)
run_receivekeysjob_LDADD = $(LDADD)
run_receivekeysjob_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \
../src/libqgpgme.la ../../../src/libgpgme.la
+am_run_refreshkeysjob_OBJECTS = run-refreshkeysjob.$(OBJEXT)
+run_refreshkeysjob_OBJECTS = $(am_run_refreshkeysjob_OBJECTS)
+run_refreshkeysjob_LDADD = $(LDADD)
+run_refreshkeysjob_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \
+ ../src/libqgpgme.la ../../../src/libgpgme.la
am__objects_1 = t-support.$(OBJEXT)
am_t_addexistingsubkey_OBJECTS = t-addexistingsubkey.$(OBJEXT) \
$(am__objects_1)
@@ -212,6 +220,17 @@ t_remarks_OBJECTS = $(am_t_remarks_OBJECTS)
t_remarks_LDADD = $(LDADD)
t_remarks_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \
../src/libqgpgme.la ../../../src/libgpgme.la
+am_t_revokekey_OBJECTS = t-revokekey.$(OBJEXT) $(am__objects_1)
+t_revokekey_OBJECTS = $(am_t_revokekey_OBJECTS)
+t_revokekey_LDADD = $(LDADD)
+t_revokekey_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \
+ ../src/libqgpgme.la ../../../src/libgpgme.la
+am_t_setprimaryuserid_OBJECTS = t-setprimaryuserid.$(OBJEXT) \
+ $(am__objects_1)
+t_setprimaryuserid_OBJECTS = $(am_t_setprimaryuserid_OBJECTS)
+t_setprimaryuserid_LDADD = $(LDADD)
+t_setprimaryuserid_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \
+ ../src/libqgpgme.la ../../../src/libgpgme.la
am_t_tofuinfo_OBJECTS = t-tofuinfo.$(OBJEXT) $(am__objects_1)
t_tofuinfo_OBJECTS = $(am_t_tofuinfo_OBJECTS)
t_tofuinfo_LDADD = $(LDADD)
@@ -262,11 +281,13 @@ am__depfiles_remade = ./$(DEPDIR)/run-exportjob.Po \
./$(DEPDIR)/run-importjob.Po \
./$(DEPDIR)/run-keyformailboxjob.Po \
./$(DEPDIR)/run-receivekeysjob.Po \
+ ./$(DEPDIR)/run-refreshkeysjob.Po \
./$(DEPDIR)/t-addexistingsubkey.Po \
./$(DEPDIR)/t-changeexpiryjob.Po ./$(DEPDIR)/t-config.Po \
./$(DEPDIR)/t-encrypt.Po ./$(DEPDIR)/t-import.Po \
./$(DEPDIR)/t-keylist.Po ./$(DEPDIR)/t-keylocate.Po \
./$(DEPDIR)/t-ownertrust.Po ./$(DEPDIR)/t-remarks.Po \
+ ./$(DEPDIR)/t-revokekey.Po ./$(DEPDIR)/t-setprimaryuserid.Po \
./$(DEPDIR)/t-support.Po ./$(DEPDIR)/t-tofuinfo.Po \
./$(DEPDIR)/t-trustsignatures.Po ./$(DEPDIR)/t-various.Po \
./$(DEPDIR)/t-verify.Po ./$(DEPDIR)/t-wkdlookup.Po \
@@ -310,23 +331,26 @@ am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(run_exportjob_SOURCES) $(run_importjob_SOURCES) \
$(run_keyformailboxjob_SOURCES) $(run_receivekeysjob_SOURCES) \
- $(t_addexistingsubkey_SOURCES) $(t_changeexpiryjob_SOURCES) \
- $(t_config_SOURCES) $(t_encrypt_SOURCES) $(t_import_SOURCES) \
- $(t_keylist_SOURCES) $(nodist_t_keylist_SOURCES) \
- $(t_keylocate_SOURCES) $(t_ownertrust_SOURCES) \
- $(t_remarks_SOURCES) $(t_tofuinfo_SOURCES) \
- $(t_trustsignatures_SOURCES) $(t_various_SOURCES) \
- $(t_verify_SOURCES) $(t_wkdlookup_SOURCES) \
- $(t_wkspublish_SOURCES)
-DIST_SOURCES = $(run_exportjob_SOURCES) $(run_importjob_SOURCES) \
- $(run_keyformailboxjob_SOURCES) $(run_receivekeysjob_SOURCES) \
- $(t_addexistingsubkey_SOURCES) $(t_changeexpiryjob_SOURCES) \
- $(t_config_SOURCES) $(t_encrypt_SOURCES) $(t_import_SOURCES) \
- $(t_keylist_SOURCES) $(t_keylocate_SOURCES) \
+ $(run_refreshkeysjob_SOURCES) $(t_addexistingsubkey_SOURCES) \
+ $(t_changeexpiryjob_SOURCES) $(t_config_SOURCES) \
+ $(t_encrypt_SOURCES) $(t_import_SOURCES) $(t_keylist_SOURCES) \
+ $(nodist_t_keylist_SOURCES) $(t_keylocate_SOURCES) \
$(t_ownertrust_SOURCES) $(t_remarks_SOURCES) \
+ $(t_revokekey_SOURCES) $(t_setprimaryuserid_SOURCES) \
$(t_tofuinfo_SOURCES) $(t_trustsignatures_SOURCES) \
$(t_various_SOURCES) $(t_verify_SOURCES) \
$(t_wkdlookup_SOURCES) $(t_wkspublish_SOURCES)
+DIST_SOURCES = $(run_exportjob_SOURCES) $(run_importjob_SOURCES) \
+ $(run_keyformailboxjob_SOURCES) $(run_receivekeysjob_SOURCES) \
+ $(run_refreshkeysjob_SOURCES) $(t_addexistingsubkey_SOURCES) \
+ $(t_changeexpiryjob_SOURCES) $(t_config_SOURCES) \
+ $(t_encrypt_SOURCES) $(t_import_SOURCES) $(t_keylist_SOURCES) \
+ $(t_keylocate_SOURCES) $(t_ownertrust_SOURCES) \
+ $(t_remarks_SOURCES) $(t_revokekey_SOURCES) \
+ $(t_setprimaryuserid_SOURCES) $(t_tofuinfo_SOURCES) \
+ $(t_trustsignatures_SOURCES) $(t_various_SOURCES) \
+ $(t_verify_SOURCES) $(t_wkdlookup_SOURCES) \
+ $(t_wkspublish_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -378,7 +402,8 @@ am__EXEEXT_1 = t-addexistingsubkey$(EXEEXT) t-keylist$(EXEEXT) \
t-encrypt$(EXEEXT) t-verify$(EXEEXT) t-various$(EXEEXT) \
t-config$(EXEEXT) t-remarks$(EXEEXT) \
t-trustsignatures$(EXEEXT) t-changeexpiryjob$(EXEEXT) \
- t-wkdlookup$(EXEEXT) t-import$(EXEEXT)
+ t-wkdlookup$(EXEEXT) t-import$(EXEEXT) t-revokekey$(EXEEXT) \
+ t-setprimaryuserid$(EXEEXT)
am__DIST_COMMON = $(srcdir)/Makefile.in \
$(top_srcdir)/build-aux/depcomp \
$(top_srcdir)/build-aux/mkinstalldirs
@@ -432,6 +457,7 @@ GPGME_CONFIG_AVAIL_LANG = @GPGME_CONFIG_AVAIL_LANG@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
+GPGME_CPP_CFLAGS = @GPGME_CPP_CFLAGS@
GPGME_QTTEST_CFLAGS = @GPGME_QTTEST_CFLAGS@
GPGME_QTTEST_LIBS = @GPGME_QTTEST_LIBS@
GPGME_QT_CFLAGS = @GPGME_QT_CFLAGS@
@@ -589,14 +615,15 @@ the_tests = \
t-addexistingsubkey \
t-keylist t-keylocate t-ownertrust t-tofuinfo \
t-encrypt t-verify t-various t-config t-remarks t-trustsignatures \
- t-changeexpiryjob t-wkdlookup t-import
+ t-changeexpiryjob t-wkdlookup t-import t-revokekey t-setprimaryuserid
moc_files = \
t-addexistingsubkey.moc \
t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc \
t-encrypt.moc t-support.hmoc t-wkspublish.moc t-verify.moc \
t-various.moc t-config.moc t-remarks.moc t-trustsignatures.moc \
- t-changeexpiryjob.moc t-wkdlookup.moc t-import.moc
+ t-changeexpiryjob.moc t-wkdlookup.moc t-import.moc t-revokekey.moc \
+ t-setprimaryuserid.moc
AM_LDFLAGS = -no-install
LDADD = ../../cpp/src/libgpgmepp.la ../src/libqgpgme.la \
@@ -625,10 +652,13 @@ t_trustsignatures_SOURCES = t-trustsignatures.cpp $(support_src)
t_changeexpiryjob_SOURCES = t-changeexpiryjob.cpp $(support_src)
t_wkdlookup_SOURCES = t-wkdlookup.cpp $(support_src)
t_import_SOURCES = t-import.cpp $(support_src)
+t_revokekey_SOURCES = t-revokekey.cpp $(support_src)
+t_setprimaryuserid_SOURCES = t-setprimaryuserid.cpp $(support_src)
run_exportjob_SOURCES = run-exportjob.cpp
run_importjob_SOURCES = run-importjob.cpp
run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp
run_receivekeysjob_SOURCES = run-receivekeysjob.cpp
+run_refreshkeysjob_SOURCES = run-refreshkeysjob.cpp
nodist_t_keylist_SOURCES = $(moc_files)
BUILT_SOURCES = $(moc_files) pubring-stamp
CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \
@@ -696,6 +726,10 @@ run-receivekeysjob$(EXEEXT): $(run_receivekeysjob_OBJECTS) $(run_receivekeysjob_
@rm -f run-receivekeysjob$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(run_receivekeysjob_OBJECTS) $(run_receivekeysjob_LDADD) $(LIBS)
+run-refreshkeysjob$(EXEEXT): $(run_refreshkeysjob_OBJECTS) $(run_refreshkeysjob_DEPENDENCIES) $(EXTRA_run_refreshkeysjob_DEPENDENCIES)
+ @rm -f run-refreshkeysjob$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(run_refreshkeysjob_OBJECTS) $(run_refreshkeysjob_LDADD) $(LIBS)
+
t-addexistingsubkey$(EXEEXT): $(t_addexistingsubkey_OBJECTS) $(t_addexistingsubkey_DEPENDENCIES) $(EXTRA_t_addexistingsubkey_DEPENDENCIES)
@rm -f t-addexistingsubkey$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(t_addexistingsubkey_OBJECTS) $(t_addexistingsubkey_LDADD) $(LIBS)
@@ -732,6 +766,14 @@ t-remarks$(EXEEXT): $(t_remarks_OBJECTS) $(t_remarks_DEPENDENCIES) $(EXTRA_t_rem
@rm -f t-remarks$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(t_remarks_OBJECTS) $(t_remarks_LDADD) $(LIBS)
+t-revokekey$(EXEEXT): $(t_revokekey_OBJECTS) $(t_revokekey_DEPENDENCIES) $(EXTRA_t_revokekey_DEPENDENCIES)
+ @rm -f t-revokekey$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(t_revokekey_OBJECTS) $(t_revokekey_LDADD) $(LIBS)
+
+t-setprimaryuserid$(EXEEXT): $(t_setprimaryuserid_OBJECTS) $(t_setprimaryuserid_DEPENDENCIES) $(EXTRA_t_setprimaryuserid_DEPENDENCIES)
+ @rm -f t-setprimaryuserid$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(t_setprimaryuserid_OBJECTS) $(t_setprimaryuserid_LDADD) $(LIBS)
+
t-tofuinfo$(EXEEXT): $(t_tofuinfo_OBJECTS) $(t_tofuinfo_DEPENDENCIES) $(EXTRA_t_tofuinfo_DEPENDENCIES)
@rm -f t-tofuinfo$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(t_tofuinfo_OBJECTS) $(t_tofuinfo_LDADD) $(LIBS)
@@ -766,6 +808,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-importjob.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-keyformailboxjob.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-receivekeysjob.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-refreshkeysjob.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-addexistingsubkey.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-changeexpiryjob.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-config.Po@am__quote@ # am--include-marker
@@ -775,6 +818,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-keylocate.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-ownertrust.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-remarks.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-revokekey.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-setprimaryuserid.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-support.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-tofuinfo.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-trustsignatures.Po@am__quote@ # am--include-marker
@@ -1044,6 +1089,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/run-importjob.Po
-rm -f ./$(DEPDIR)/run-keyformailboxjob.Po
-rm -f ./$(DEPDIR)/run-receivekeysjob.Po
+ -rm -f ./$(DEPDIR)/run-refreshkeysjob.Po
-rm -f ./$(DEPDIR)/t-addexistingsubkey.Po
-rm -f ./$(DEPDIR)/t-changeexpiryjob.Po
-rm -f ./$(DEPDIR)/t-config.Po
@@ -1053,6 +1099,8 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/t-keylocate.Po
-rm -f ./$(DEPDIR)/t-ownertrust.Po
-rm -f ./$(DEPDIR)/t-remarks.Po
+ -rm -f ./$(DEPDIR)/t-revokekey.Po
+ -rm -f ./$(DEPDIR)/t-setprimaryuserid.Po
-rm -f ./$(DEPDIR)/t-support.Po
-rm -f ./$(DEPDIR)/t-tofuinfo.Po
-rm -f ./$(DEPDIR)/t-trustsignatures.Po
@@ -1109,6 +1157,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/run-importjob.Po
-rm -f ./$(DEPDIR)/run-keyformailboxjob.Po
-rm -f ./$(DEPDIR)/run-receivekeysjob.Po
+ -rm -f ./$(DEPDIR)/run-refreshkeysjob.Po
-rm -f ./$(DEPDIR)/t-addexistingsubkey.Po
-rm -f ./$(DEPDIR)/t-changeexpiryjob.Po
-rm -f ./$(DEPDIR)/t-config.Po
@@ -1118,6 +1167,8 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/t-keylocate.Po
-rm -f ./$(DEPDIR)/t-ownertrust.Po
-rm -f ./$(DEPDIR)/t-remarks.Po
+ -rm -f ./$(DEPDIR)/t-revokekey.Po
+ -rm -f ./$(DEPDIR)/t-setprimaryuserid.Po
-rm -f ./$(DEPDIR)/t-support.Po
-rm -f ./$(DEPDIR)/t-tofuinfo.Po
-rm -f ./$(DEPDIR)/t-trustsignatures.Po
diff --git a/lang/qt/tests/run-refreshkeysjob.cpp b/lang/qt/tests/run-refreshkeysjob.cpp
new file mode 100644
index 0000000..940c0c7
--- /dev/null
+++ b/lang/qt/tests/run-refreshkeysjob.cpp
@@ -0,0 +1,155 @@
+/*
+ run-refreshkeysjob.cpp
+
+ This file is part of QGpgME's test suite.
+ Copyright (c) 2022 by g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ QGpgME 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <protocol.h>
+#include <refreshkeysjob.h>
+#include <receivekeysjob.h>
+
+#include <QCoreApplication>
+#include <QDebug>
+
+#include <context.h>
+#include <importresult.h>
+
+#include <iostream>
+
+using namespace GpgME;
+
+std::ostream &operator<<(std::ostream &os, const QString &s)
+{
+ return os << s.toLocal8Bit().constData();
+}
+
+const char *displayName(Protocol protocol)
+{
+ switch (protocol) {
+ case GpgME::OpenPGP:
+ return "OpenPGP";
+ case GpgME::CMS:
+ return "S/MIME";
+ default:
+ return "Unknown protocol";
+ }
+}
+
+struct KeyAndError {
+ Key key;
+ Error error;
+};
+
+KeyAndError getKey(const QString &keyId, Protocol protocol)
+{
+ KeyAndError result;
+
+ auto ctx = Context::create(protocol);
+ if (!ctx) {
+ result.error = Error::fromCode(GPG_ERR_GENERAL);
+ return result;
+ }
+
+ result.key = ctx->key(keyId.toLatin1().constData(), result.error);
+ if (result.error.code() == GPG_ERR_EOF) {
+ result.error = Error{};
+ }
+ return result;
+}
+
+int main(int argc, char **argv)
+{
+ GpgME::initializeLibrary();
+
+ if (argc != 2) {
+ std::cerr << "Usage: " << argv[0] << " KEYID" << std::endl;
+ return 1;
+ }
+
+ QCoreApplication app{argc, argv};
+ const auto keyId = qApp->arguments().last();
+
+ auto openPGPKey = getKey(keyId, GpgME::OpenPGP);
+ auto smimeKey = getKey(keyId, GpgME::CMS);
+ if ((!openPGPKey.key.isNull() && !smimeKey.key.isNull())
+ || (openPGPKey.error.code() == GPG_ERR_AMBIGUOUS_NAME)
+ || (smimeKey.error.code() == GPG_ERR_AMBIGUOUS_NAME)) {
+ std::cerr << "Error: Multiple keys matching '" << keyId << "' found" << std::endl;
+ return 1;
+ } else if (openPGPKey.key.isNull() && smimeKey.key.isNull()) {
+ std::cerr << "Error: No key matching '" << keyId << "' found" << std::endl;
+ return 1;
+ }
+ if (openPGPKey.error) {
+ std::cerr << "Warning: Error while getting OpenPGP key: " << openPGPKey.error.asString() << std::endl;
+ }
+ if (smimeKey.error) {
+ std::cerr << "Warning: Error while getting S/MIME key: " << openPGPKey.error.asString() << std::endl;
+ }
+ auto key = openPGPKey.key.isNull() ? smimeKey.key : openPGPKey.key;
+ std::cout << "Refreshing " << displayName(key.protocol()) << " key " << key.userID(0).id() << std::endl;
+
+ if (key.protocol() == GpgME::OpenPGP) {
+ auto job = QGpgME::openpgp()->receiveKeysJob();
+ if (!job) {
+ std::cerr << "Error: Could not create job to refresh OpenPGP key" << std::endl;
+ return 1;
+ }
+ QObject::connect(job, &QGpgME::ReceiveKeysJob::result, &app, [](const GpgME::ImportResult &result, const QString &, const GpgME::Error &) {
+ std::cout << "Result: " << result << std::endl;
+ qApp->quit();
+ });
+ const auto err = job->start({QString::fromLatin1(key.primaryFingerprint())});
+ if (err) {
+ std::cerr << "Error: " << err.asString() << std::endl;
+ return 1;
+ }
+ } else {
+ auto job = QGpgME::smime()->refreshKeysJob();
+ if (!job) {
+ std::cerr << "Error: Could not create job to refresh S/MIME key" << std::endl;
+ return 1;
+ }
+ QObject::connect(job, &QGpgME::RefreshKeysJob::result, &app, [](const GpgME::Error &err) {
+ std::cout << "Result: " << err.asString() << std::endl;
+ qApp->quit();
+ });
+ const auto err = job->start({key});
+ if (err) {
+ std::cerr << "Error: " << err.asString() << std::endl;
+ return 1;
+ }
+ }
+
+ return app.exec();
+}
diff --git a/lang/qt/tests/t-revokekey.cpp b/lang/qt/tests/t-revokekey.cpp
new file mode 100644
index 0000000..83d5e71
--- /dev/null
+++ b/lang/qt/tests/t-revokekey.cpp
@@ -0,0 +1,338 @@
+/* t-revokekey.cpp
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "t-support.h"
+
+#include <protocol.h>
+#include <revokekeyjob.h>
+
+#include <QDebug>
+#include <QProcess>
+#include <QRegularExpression>
+#include <QSignalSpy>
+#include <QTest>
+
+#include <context.h>
+#include <data.h>
+
+#include <algorithm>
+
+using namespace QGpgME;
+using namespace GpgME;
+
+/* Test keys
+ sec ed25519 2022-03-29 [SC]
+ 604122B94C86BE846EAFE637FC2BCFB1B19A1CF4
+ uid [ultimate] revoke-me@example.net
+ ssb cv25519 2022-03-29 [E]
+ * generated with
+export GNUPGHOME=$(mktemp -d)
+gpg -K
+gpg --batch --pinentry-mode loopback --passphrase abc --quick-gen-key revoke-me@example.net default default never
+gpg -K
+gpg --export-secret-keys --armor --batch --pinentry-mode loopback --passphrase abc --comment revoke-me@example.net revoke-me@example.net | sed 's/\(.*\)/ "\1\\n"/'
+#rm -rf ${GNUPGHOME}
+unset GNUPGHOME
+*/
+static const char *testKeyData =
+ "-----BEGIN PGP PRIVATE KEY BLOCK-----\n"
+ "Comment: revoke-me@example.net\n"
+ "\n"
+ "lIYEYkLSGhYJKwYBBAHaRw8BAQdAWKBjYOZIW33CjwlHKKGIgqXDOGhmbPCStkj1\n"
+ "+2/cVFL+BwMCXJpRHkD8EcT8DMWdVo84Lx4w7RNDCQx5xnm6rO5kvtmh+PjgM3qt\n"
+ "CQVGy8H7Dq35yzi0Hihm5zvHxVGYdAu96ShAI2ZqqVL7is0CdAmAibQVcmV2b2tl\n"
+ "LW1lQGV4YW1wbGUubmV0iJQEExYKADwWIQRgQSK5TIa+hG6v5jf8K8+xsZoc9AUC\n"
+ "YkLSGgIbAwULCQgHAgMiAgEGFQoJCAsCBBYCAwECHgcCF4AACgkQ/CvPsbGaHPSH\n"
+ "LAD/RNFgm1Bp6ltDXLS6oS0S5Bgjjg3CBpbdxWTvLjPpaagBAIU2pTLrsGNDKIZq\n"
+ "EAY7hY50tdcvOfT4OSAySJACJzMFnIsEYkLSGhIKKwYBBAGXVQEFAQEHQIOTbPEz\n"
+ "hUtL72BHfetUWESlEbh2IF/NEUWASUtQJDghAwEIB/4HAwJGE5naBnwwcfyPC+Nq\n"
+ "DwY5FO28hQVAzgNu9KAncmPtpST1J8sEPAtJGhtq/9fki9eSvBMbAa64VVpFHKHK\n"
+ "ravZxr2uCrK6J/u4rTvnR8HgiHgEGBYKACAWIQRgQSK5TIa+hG6v5jf8K8+xsZoc\n"
+ "9AUCYkLSGgIbDAAKCRD8K8+xsZoc9ANAAP9rX/xanm7YvcGFIxPclmy4h33lLaG8\n"
+ "dE5RA6zeSg7DqQD8Dae82iKaqKfTpe2+2vIEyxBVy8+WttoElUoXiwr0AQg=\n"
+ "=/5re\n"
+ "-----END PGP PRIVATE KEY BLOCK-----\n";
+
+class RevokeKeyJobTest : public QGpgMETest
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void initTestCase()
+ {
+ QGpgMETest::initTestCase();
+
+ // set up the test fixture for this test
+ qputenv("GNUPGHOME", mGnupgHomeTestFixture.path().toUtf8());
+ QVERIFY(importSecretKeys(testKeyData, 1));
+ }
+
+ void init()
+ {
+ // set up a copy of the test fixture for each test function
+ mGnupgHomeTestCopy.reset(new QTemporaryDir{});
+ QVERIFY(copyKeyrings(mGnupgHomeTestFixture.path(), mGnupgHomeTestCopy->path()));
+ qputenv("GNUPGHOME", mGnupgHomeTestCopy->path().toUtf8());
+ }
+
+ void testAsync()
+ {
+ // Get the key that shall be revoked
+ auto key = getTestKey("revoke-me@example.net");
+ QVERIFY(!key.isNull());
+ QVERIFY(!key.isRevoked());
+
+ auto job = std::unique_ptr<RevokeKeyJob>{openpgp()->revokeKeyJob()};
+ hookUpPassphraseProvider(job.get());
+
+ Error result;
+ connect(job.get(), &RevokeKeyJob::result,
+ job.get(), [this, &result](const Error &result_) {
+ result = result_;
+ Q_EMIT asyncDone();
+ });
+ QVERIFY(!job->start(key, RevocationReason::NoLongerUsed,
+ {"This key is not used anymore."}));
+ job.release(); // after the job has been started it's on its own
+
+ QSignalSpy spy (this, SIGNAL(asyncDone()));
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
+
+ QVERIFY(result.code() == GPG_ERR_NO_ERROR);
+ key.update();
+ QVERIFY(key.isRevoked());
+ verifyReason(key, RevocationReason::NoLongerUsed,
+ {"This key is not used anymore."});
+ }
+
+ void testSync_noReasonDescription()
+ {
+ // Get the key that shall be revoked
+ auto key = getTestKey("revoke-me@example.net");
+ QVERIFY(!key.isNull());
+ QVERIFY(!key.isRevoked());
+
+ auto job = std::unique_ptr<RevokeKeyJob>{openpgp()->revokeKeyJob()};
+ hookUpPassphraseProvider(job.get());
+
+ const auto result = job->exec(key);
+
+ QVERIFY(result.code() == GPG_ERR_NO_ERROR);
+ key.update();
+ QVERIFY(key.isRevoked());
+ verifyReason(key, RevocationReason::Unspecified, {});
+ }
+
+ void testSync_oneLineReasonDescription()
+ {
+ // Get the key that shall be revoked
+ auto key = getTestKey("revoke-me@example.net");
+ QVERIFY(!key.isNull());
+ QVERIFY(!key.isRevoked());
+
+ auto job = std::unique_ptr<RevokeKeyJob>{openpgp()->revokeKeyJob()};
+ hookUpPassphraseProvider(job.get());
+
+ const auto result = job->exec(key, RevocationReason::Compromised,
+ {"The secret key was stolen."});
+
+ QVERIFY(result.code() == GPG_ERR_NO_ERROR);
+ key.update();
+ QVERIFY(key.isRevoked());
+ verifyReason(key, RevocationReason::Compromised,
+ {"The secret key was stolen."});
+ }
+
+ void testSync_twoLinesReasonDescription()
+ {
+ // Get the key that shall be revoked
+ auto key = getTestKey("revoke-me@example.net");
+ QVERIFY(!key.isNull());
+ QVERIFY(!key.isRevoked());
+
+ auto job = std::unique_ptr<RevokeKeyJob>{openpgp()->revokeKeyJob()};
+ hookUpPassphraseProvider(job.get());
+
+ const auto result = job->exec(key, RevocationReason::Superseded,
+ {"This key has been superseded by key",
+ "0000 1111 2222 3333 4444 5555 6666 7777 8888 9999."});
+
+ QVERIFY(result.code() == GPG_ERR_NO_ERROR);
+ key.update();
+ QVERIFY(key.isRevoked());
+ verifyReason(key, RevocationReason::Superseded,
+ {"This key has been superseded by key",
+ "0000 1111 2222 3333 4444 5555 6666 7777 8888 9999."});
+ }
+
+ void testErrorHandling_nullKey()
+ {
+ {
+ auto job = std::unique_ptr<RevokeKeyJob>{openpgp()->revokeKeyJob()};
+ QTest::ignoreMessage(QtWarningMsg, "Error: Key is null key");
+ const auto result = job->exec(Key{});
+ QVERIFY(result.code() == GPG_ERR_INV_ARG);
+ }
+ {
+ auto job = std::unique_ptr<RevokeKeyJob>{openpgp()->revokeKeyJob()};
+ QTest::ignoreMessage(QtWarningMsg, "Error: Key is null key");
+ const auto result = job->start(Key{});
+ QVERIFY(result.code() == GPG_ERR_INV_ARG);
+ }
+ }
+
+ void testErrorHandling_invalidReason()
+ {
+ // Get the key that shall be revoked
+ auto key = getTestKey("revoke-me@example.net");
+ QVERIFY(!key.isNull());
+ QVERIFY(!key.isRevoked());
+
+ {
+ auto job = std::unique_ptr<RevokeKeyJob>{openpgp()->revokeKeyJob()};
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression{"^Error: Invalid revocation reason"});
+ const auto result = job->exec(key, static_cast<RevocationReason>(-1));
+ QVERIFY(result.code() == GPG_ERR_INV_VALUE);
+ }
+ {
+ auto job = std::unique_ptr<RevokeKeyJob>{openpgp()->revokeKeyJob()};
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression{"^Error: Invalid revocation reason"});
+ const auto result = job->start(key, static_cast<RevocationReason>(4));
+ QVERIFY(result.code() == GPG_ERR_INV_VALUE);
+ }
+ }
+
+ void testErrorHandling_invalidDescription()
+ {
+ // Get the key that shall be revoked
+ auto key = getTestKey("revoke-me@example.net");
+ QVERIFY(!key.isNull());
+ QVERIFY(!key.isRevoked());
+
+ {
+ auto job = std::unique_ptr<RevokeKeyJob>{openpgp()->revokeKeyJob()};
+ QTest::ignoreMessage(QtWarningMsg, "Error: Revocation description contains empty lines or lines with endline characters");
+ const auto result = job->exec(key, RevocationReason::Unspecified,
+ {"line1", "", "line3"});
+ QVERIFY(result.code() == GPG_ERR_INV_VALUE);
+ }
+ {
+ auto job = std::unique_ptr<RevokeKeyJob>{openpgp()->revokeKeyJob()};
+ QTest::ignoreMessage(QtWarningMsg, "Error: Revocation description contains empty lines or lines with endline characters");
+ const auto result = job->start(key, RevocationReason::Unspecified,
+ {"line1\nline2"});
+ QVERIFY(result.code() == GPG_ERR_INV_VALUE);
+ }
+ }
+
+private:
+ Key getTestKey(const char *pattern)
+ {
+ auto ctx = Context::create(OpenPGP);
+ VERIFY_OR_OBJECT(ctx);
+
+ Error err;
+ auto key = ctx->key(pattern, err, /*secret=*/true);
+ VERIFY_OR_OBJECT(!err);
+ VERIFY_OR_OBJECT(!key.isNull());
+ return key;
+ }
+
+ bool verifyReason(const Key &key, RevocationReason reason, const QStringList &description)
+ {
+ static const auto startTimeout = std::chrono::milliseconds{1000};
+ static const auto finishTimeout = std::chrono::milliseconds{2000};
+ static const QStringList hexCodeForReason = {
+ QStringLiteral("00"), /* no particular reason */
+ QStringLiteral("02"), /* key has been compromised */
+ QStringLiteral("01"), /* key is superseded */
+ QStringLiteral("03") /* key is no longer used */
+ };
+
+ QProcess p;
+ p.setProgram(dirInfo("gpg-name"));
+ p.setArguments({QStringLiteral("-K"),
+ QStringLiteral("--with-colon"),
+ QStringLiteral("--with-sig-list"),
+ QLatin1String{key.primaryFingerprint()}
+ });
+
+ p.start();
+
+ if (!p.waitForStarted(startTimeout.count())) {
+ qWarning() << "Timeout while waiting for start of" << p.program() << p.arguments().join(u' ');
+ return false;
+ }
+ if (!p.waitForFinished(finishTimeout.count())) {
+ qWarning() << "Timeout while waiting for completion of" << p.program() << p.arguments().join(u' ');
+ return false;
+ }
+ if (p.exitStatus() != QProcess::NormalExit) {
+ qWarning() << p.program() << "terminated abnormally with exit status" << p.exitStatus();
+ return false;
+ }
+
+ const auto lines = QString::fromUtf8(p.readAllStandardOutput()).split(u'\n');
+ for (const auto &l : lines) {
+ const auto fields = l.split(u':');
+ if (fields[0] == QLatin1String{"rev"}) {
+ // or "rev" the signature class may be followed by a comma
+ // and a 2 digit hexnumber with the revocation reason
+ const auto sigClass = fields.value(10);
+ const auto revReason = sigClass.split(u',').value(1);
+ COMPARE_OR_FALSE(revReason, hexCodeForReason.value(static_cast<int>(reason)));
+
+ // decode the \n in the C-style quoted comment field
+ const auto comment = fields.value(20).replace(QStringLiteral("\\n"), QStringLiteral("\n"));
+ COMPARE_OR_FALSE(comment, description.join(u'\n'));
+ return true;
+ }
+ if (fields[0] == QLatin1String{"uid"}) {
+ qWarning() << "Found uid before rev in key listing:\n" << stdout;
+ return false;
+ }
+ }
+ return false;
+ }
+
+private:
+ QTemporaryDir mGnupgHomeTestFixture;
+ std::unique_ptr<QTemporaryDir> mGnupgHomeTestCopy;
+};
+
+QTEST_MAIN(RevokeKeyJobTest)
+
+#include "t-revokekey.moc"
diff --git a/lang/qt/tests/t-setprimaryuserid.cpp b/lang/qt/tests/t-setprimaryuserid.cpp
new file mode 100644
index 0000000..c1bd106
--- /dev/null
+++ b/lang/qt/tests/t-setprimaryuserid.cpp
@@ -0,0 +1,165 @@
+/* t-setprimaryuserid.cpp
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2022 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "t-support.h"
+
+#include <keylistjob.h>
+#include <protocol.h>
+
+#include <context.h>
+#include <engineinfo.h>
+#include <keylistresult.h>
+
+using namespace QGpgME;
+using namespace GpgME;
+
+class TestSetPrimaryUserID: public QGpgMETest
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void testSetPrimaryUserID()
+ {
+ Key key;
+ {
+ std::unique_ptr<KeyListJob> job{openpgp()->keyListJob()};
+ std::vector<GpgME::Key> keys;
+ GpgME::KeyListResult result = job->exec({QStringLiteral("alfa@example.net")}, true, keys);
+ QVERIFY(!result.error());
+ QVERIFY(keys.size() == 1);
+ key = keys.front();
+ }
+
+ QCOMPARE(key.numUserIDs(), 3u);
+ const std::string oldPrimaryUserId = key.userID(0).id();
+ const std::string newPrimaryUserId = key.userID(1).id();
+ const std::string newPrimaryUserIdHash = key.userID(1).uidhash();
+
+ {
+ std::unique_ptr<Context> ctx{Context::createForProtocol(key.protocol())};
+ QVERIFY(ctx);
+ hookUpPassphraseProvider(ctx.get());
+
+ if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() >= "2.3.8") {
+ QVERIFY(!ctx->setPrimaryUid(key, newPrimaryUserIdHash.c_str()));
+ } else {
+ QVERIFY(!ctx->setPrimaryUid(key, newPrimaryUserId.c_str()));
+ }
+ }
+ key.update();
+
+ QCOMPARE(key.userID(0).id(), newPrimaryUserId);
+
+ {
+ std::unique_ptr<Context> ctx{Context::createForProtocol(key.protocol())};
+ QVERIFY(ctx);
+ hookUpPassphraseProvider(ctx.get());
+
+ QVERIFY(!ctx->setPrimaryUid(key, oldPrimaryUserId.c_str()));
+ }
+ key.update();
+
+ QCOMPARE(key.userID(0).id(), oldPrimaryUserId);
+ }
+
+ void testErrorHandling_noSecretKey()
+ {
+ if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.3.8") {
+ QSKIP("gpg < 2.3.8 does not report status error");
+ }
+ Key key;
+ {
+ std::unique_ptr<KeyListJob> job{openpgp()->keyListJob()};
+ std::vector<GpgME::Key> keys;
+ GpgME::KeyListResult result = job->exec({QStringLiteral("bravo@example.net")}, false, keys);
+ QVERIFY(!result.error());
+ QVERIFY(keys.size() == 1);
+ key = keys.front();
+ }
+
+ QCOMPARE(key.numUserIDs(), 2u);
+ const std::string newPrimaryUserId = key.userID(1).id();
+
+ {
+ std::unique_ptr<Context> ctx{Context::createForProtocol(key.protocol())};
+ QVERIFY(ctx);
+ auto err = ctx->setPrimaryUid(key, newPrimaryUserId.c_str());
+ QCOMPARE(err.code(), static_cast<int>(GPG_ERR_NO_SECKEY));
+ }
+ }
+
+ void testErrorHandling_noUserID()
+ {
+ if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.3.8") {
+ QSKIP("gpg < 2.3.8 does not report status error");
+ }
+ Key key;
+ {
+ std::unique_ptr<KeyListJob> job{openpgp()->keyListJob()};
+ std::vector<GpgME::Key> keys;
+ GpgME::KeyListResult result = job->exec({QStringLiteral("alfa@example.net")}, true, keys);
+ QVERIFY(!result.error());
+ QVERIFY(keys.size() == 1);
+ key = keys.front();
+ }
+ {
+ std::unique_ptr<Context> ctx{Context::createForProtocol(key.protocol())};
+ QVERIFY(ctx);
+ auto err = ctx->setPrimaryUid(key, "bravo");
+ QCOMPARE(err.code(), static_cast<int>(GPG_ERR_NO_USER_ID));
+ }
+ }
+
+ void initTestCase()
+ {
+ QGpgMETest::initTestCase();
+ const QString gpgHome = qgetenv("GNUPGHOME");
+ QVERIFY(copyKeyrings(gpgHome, mDir.path()));
+ qputenv("GNUPGHOME", mDir.path().toUtf8());
+ QFile conf(mDir.path() + QStringLiteral("/gpg.conf"));
+ QVERIFY(conf.open(QIODevice::WriteOnly));
+ if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() >= "2.2.18") {
+ conf.write("allow-weak-key-signatures\n");
+ }
+ conf.close();
+ }
+
+private:
+ QTemporaryDir mDir;
+};
+
+QTEST_MAIN(TestSetPrimaryUserID)
+
+#include "t-setprimaryuserid.moc"
diff --git a/lang/qt/tests/t-various.cpp b/lang/qt/tests/t-various.cpp
index b630350..336ad34 100644
--- a/lang/qt/tests/t-various.cpp
+++ b/lang/qt/tests/t-various.cpp
@@ -328,8 +328,6 @@ private Q_SLOTS:
}
});
- QTest::ignoreMessage(QtWarningMsg, "Expiration of certification has been changed to QDate(\"2106-02-06\")");
-
job->start(target);
QSignalSpy spy{this, &TestVarious::asyncDone};
QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
@@ -339,7 +337,15 @@ private Q_SLOTS:
const auto keySignature = target.userID(0).signature(target.userID(0).numSignatures() - 1);
QVERIFY(!keySignature.neverExpires());
const auto expirationDate = QDateTime::fromSecsSinceEpoch(uint_least32_t(keySignature.expirationTime())).date();
- QCOMPARE(expirationDate, QDate(2106, 2, 6)); // expiration date is capped at 2106-02-06
+ // expiration date is capped at 2106-02-05; we also allow 2106-02-04 as expiration date because for locations that use DST
+ // the expiration date may be 2106-02-04-23:xx:xx (in local non-DST time) if the current time is 00:xx::xx (in local DST time)
+ const auto expectedExpirationRange = std::make_pair(QDate{2106, 2, 4}, QDate{2106, 2, 5});
+ QVERIFY2(expirationDate >= expectedExpirationRange.first,
+ ("\n Actual : " + expirationDate.toString(Qt::ISODate).toLatin1() +
+ "\n Expected: " + expectedExpirationRange.first.toString(Qt::ISODate).toLatin1()).constData());
+ QVERIFY2(expirationDate <= expectedExpirationRange.second,
+ ("\n Actual : " + expirationDate.toString(Qt::ISODate).toLatin1() +
+ "\n Expected: " + expectedExpirationRange.second.toString(Qt::ISODate).toLatin1()).constData());
}
void testVersion()
diff --git a/lang/qt/tests/t-verify.cpp b/lang/qt/tests/t-verify.cpp
index e6b0c8a..0dbecf7 100644
--- a/lang/qt/tests/t-verify.cpp
+++ b/lang/qt/tests/t-verify.cpp
@@ -81,7 +81,7 @@ private Q_SLOTS:
QVERIFY(!key.isNull());
bool found = false;
- for (const auto subkey: key.subkeys()) {
+ for (const auto &subkey: key.subkeys()) {
if (!strcmp (subkey.fingerprint(), sig.fingerprint())) {
found = true;
}