diff options
Diffstat (limited to 'lang/cpp/src')
-rw-r--r-- | lang/cpp/src/Makefile.in | 168 | ||||
-rw-r--r-- | lang/cpp/src/context.cpp | 43 | ||||
-rw-r--r-- | lang/cpp/src/context.h | 14 | ||||
-rw-r--r-- | lang/cpp/src/editinteractor.cpp | 19 | ||||
-rw-r--r-- | lang/cpp/src/global.h | 3 | ||||
-rw-r--r-- | lang/cpp/src/gpgsignkeyeditinteractor.cpp | 38 | ||||
-rw-r--r-- | lang/cpp/src/gpgsignkeyeditinteractor.h | 6 | ||||
-rw-r--r-- | lang/cpp/src/key.cpp | 83 | ||||
-rw-r--r-- | lang/cpp/src/key.h | 22 | ||||
-rw-r--r-- | lang/cpp/src/util.h | 3 | ||||
-rw-r--r-- | lang/cpp/src/verificationresult.cpp | 3 |
11 files changed, 342 insertions, 60 deletions
diff --git a/lang/cpp/src/Makefile.in b/lang/cpp/src/Makefile.in index 7ae2d5e..eb08ad9 100644 --- a/lang/cpp/src/Makefile.in +++ b/lang/cpp/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -202,7 +202,29 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/conf depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/callbacks.Plo \ + ./$(DEPDIR)/configuration.Plo ./$(DEPDIR)/context.Plo \ + ./$(DEPDIR)/context_vanilla.Plo ./$(DEPDIR)/data.Plo \ + ./$(DEPDIR)/decryptionresult.Plo \ + ./$(DEPDIR)/defaultassuantransaction.Plo \ + ./$(DEPDIR)/editinteractor.Plo \ + ./$(DEPDIR)/encryptionresult.Plo ./$(DEPDIR)/engineinfo.Plo \ + ./$(DEPDIR)/eventloopinteractor.Plo ./$(DEPDIR)/exception.Plo \ + ./$(DEPDIR)/gpgadduserideditinteractor.Plo \ + ./$(DEPDIR)/gpgagentgetinfoassuantransaction.Plo \ + ./$(DEPDIR)/gpggencardkeyinteractor.Plo \ + ./$(DEPDIR)/gpgsetexpirytimeeditinteractor.Plo \ + ./$(DEPDIR)/gpgsetownertrusteditinteractor.Plo \ + ./$(DEPDIR)/gpgsignkeyeditinteractor.Plo \ + ./$(DEPDIR)/importresult.Plo ./$(DEPDIR)/key.Plo \ + ./$(DEPDIR)/keygenerationresult.Plo \ + ./$(DEPDIR)/keylistresult.Plo \ + ./$(DEPDIR)/scdgetinfoassuantransaction.Plo \ + ./$(DEPDIR)/signingresult.Plo ./$(DEPDIR)/swdbresult.Plo \ + ./$(DEPDIR)/tofuinfo.Plo ./$(DEPDIR)/trustitem.Plo \ + ./$(DEPDIR)/verificationresult.Plo \ + ./$(DEPDIR)/vfsmountresult.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) @@ -463,6 +485,7 @@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -549,8 +572,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -614,35 +637,41 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/configuration.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context_vanilla.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decryptionresult.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defaultassuantransaction.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/editinteractor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encryptionresult.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/engineinfo.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventloopinteractor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgadduserideditinteractor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgagentgetinfoassuantransaction.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpggencardkeyinteractor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgsetexpirytimeeditinteractor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgsetownertrusteditinteractor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgsignkeyeditinteractor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/importresult.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/key.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keygenerationresult.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keylistresult.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scdgetinfoassuantransaction.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signingresult.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swdbresult.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tofuinfo.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trustitem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verificationresult.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vfsmountresult.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/configuration.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context_vanilla.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decryptionresult.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defaultassuantransaction.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/editinteractor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encryptionresult.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/engineinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventloopinteractor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception.Plo@am__quote@ # am--include-marker +@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)/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 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/importresult.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/key.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keygenerationresult.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keylistresult.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scdgetinfoassuantransaction.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signingresult.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swdbresult.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tofuinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trustitem.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verificationresult.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vfsmountresult.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -789,7 +818,10 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -863,7 +895,35 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/callbacks.Plo + -rm -f ./$(DEPDIR)/configuration.Plo + -rm -f ./$(DEPDIR)/context.Plo + -rm -f ./$(DEPDIR)/context_vanilla.Plo + -rm -f ./$(DEPDIR)/data.Plo + -rm -f ./$(DEPDIR)/decryptionresult.Plo + -rm -f ./$(DEPDIR)/defaultassuantransaction.Plo + -rm -f ./$(DEPDIR)/editinteractor.Plo + -rm -f ./$(DEPDIR)/encryptionresult.Plo + -rm -f ./$(DEPDIR)/engineinfo.Plo + -rm -f ./$(DEPDIR)/eventloopinteractor.Plo + -rm -f ./$(DEPDIR)/exception.Plo + -rm -f ./$(DEPDIR)/gpgadduserideditinteractor.Plo + -rm -f ./$(DEPDIR)/gpgagentgetinfoassuantransaction.Plo + -rm -f ./$(DEPDIR)/gpggencardkeyinteractor.Plo + -rm -f ./$(DEPDIR)/gpgsetexpirytimeeditinteractor.Plo + -rm -f ./$(DEPDIR)/gpgsetownertrusteditinteractor.Plo + -rm -f ./$(DEPDIR)/gpgsignkeyeditinteractor.Plo + -rm -f ./$(DEPDIR)/importresult.Plo + -rm -f ./$(DEPDIR)/key.Plo + -rm -f ./$(DEPDIR)/keygenerationresult.Plo + -rm -f ./$(DEPDIR)/keylistresult.Plo + -rm -f ./$(DEPDIR)/scdgetinfoassuantransaction.Plo + -rm -f ./$(DEPDIR)/signingresult.Plo + -rm -f ./$(DEPDIR)/swdbresult.Plo + -rm -f ./$(DEPDIR)/tofuinfo.Plo + -rm -f ./$(DEPDIR)/trustitem.Plo + -rm -f ./$(DEPDIR)/verificationresult.Plo + -rm -f ./$(DEPDIR)/vfsmountresult.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -911,7 +971,35 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/callbacks.Plo + -rm -f ./$(DEPDIR)/configuration.Plo + -rm -f ./$(DEPDIR)/context.Plo + -rm -f ./$(DEPDIR)/context_vanilla.Plo + -rm -f ./$(DEPDIR)/data.Plo + -rm -f ./$(DEPDIR)/decryptionresult.Plo + -rm -f ./$(DEPDIR)/defaultassuantransaction.Plo + -rm -f ./$(DEPDIR)/editinteractor.Plo + -rm -f ./$(DEPDIR)/encryptionresult.Plo + -rm -f ./$(DEPDIR)/engineinfo.Plo + -rm -f ./$(DEPDIR)/eventloopinteractor.Plo + -rm -f ./$(DEPDIR)/exception.Plo + -rm -f ./$(DEPDIR)/gpgadduserideditinteractor.Plo + -rm -f ./$(DEPDIR)/gpgagentgetinfoassuantransaction.Plo + -rm -f ./$(DEPDIR)/gpggencardkeyinteractor.Plo + -rm -f ./$(DEPDIR)/gpgsetexpirytimeeditinteractor.Plo + -rm -f ./$(DEPDIR)/gpgsetownertrusteditinteractor.Plo + -rm -f ./$(DEPDIR)/gpgsignkeyeditinteractor.Plo + -rm -f ./$(DEPDIR)/importresult.Plo + -rm -f ./$(DEPDIR)/key.Plo + -rm -f ./$(DEPDIR)/keygenerationresult.Plo + -rm -f ./$(DEPDIR)/keylistresult.Plo + -rm -f ./$(DEPDIR)/scdgetinfoassuantransaction.Plo + -rm -f ./$(DEPDIR)/signingresult.Plo + -rm -f ./$(DEPDIR)/swdbresult.Plo + -rm -f ./$(DEPDIR)/tofuinfo.Plo + -rm -f ./$(DEPDIR)/trustitem.Plo + -rm -f ./$(DEPDIR)/verificationresult.Plo + -rm -f ./$(DEPDIR)/vfsmountresult.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -934,9 +1022,9 @@ uninstall-am: uninstall-gpgmeppincludeHEADERS uninstall-libLTLIBRARIES \ .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-local install-dvi install-dvi-am \ diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index c0a1dc2..2560a33 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -563,44 +563,66 @@ KeyGenerationResult Context::keyGenerationResult() const } } -Error Context::exportPublicKeys(const char *pattern, Data &keyData) +Error Context::exportPublicKeys(const char *pattern, Data &keyData, unsigned int flags) { d->lastop = Private::Export; Data::Private *const dp = keyData.impl(); - return Error(d->lasterr = gpgme_op_export(d->ctx, pattern, 0, dp ? dp->data : nullptr)); + return Error(d->lasterr = gpgme_op_export(d->ctx, pattern, flags, dp ? dp->data : nullptr)); } -Error Context::exportPublicKeys(const char *patterns[], Data &keyData) +Error Context::exportPublicKeys(const char *patterns[], Data &keyData, unsigned int flags) { d->lastop = Private::Export; #ifndef HAVE_GPGME_EXT_KEYLIST_MODE_EXTERNAL_NONBROKEN if (!patterns || !patterns[0] || !patterns[1]) { // max. one pattern -> use the non-ext version - return exportPublicKeys(patterns ? patterns[0] : nullptr, keyData); + return exportPublicKeys(patterns ? patterns[0] : nullptr, keyData, flags); } #endif Data::Private *const dp = keyData.impl(); - return Error(d->lasterr = gpgme_op_export_ext(d->ctx, patterns, 0, dp ? dp->data : nullptr)); + return Error(d->lasterr = gpgme_op_export_ext(d->ctx, patterns, flags, dp ? dp->data : nullptr)); } -Error Context::startPublicKeyExport(const char *pattern, Data &keyData) +Error Context::startPublicKeyExport(const char *pattern, Data &keyData, unsigned int flags) { d->lastop = Private::Export; Data::Private *const dp = keyData.impl(); - return Error(d->lasterr = gpgme_op_export_start(d->ctx, pattern, 0, dp ? dp->data : nullptr)); + return Error(d->lasterr = gpgme_op_export_start(d->ctx, pattern, flags, dp ? dp->data : nullptr)); } -Error Context::startPublicKeyExport(const char *patterns[], Data &keyData) +Error Context::startPublicKeyExport(const char *patterns[], Data &keyData, unsigned int flags) { d->lastop = Private::Export; #ifndef HAVE_GPGME_EXT_KEYLIST_MODE_EXTERNAL_NONBROKEN if (!patterns || !patterns[0] || !patterns[1]) { // max. one pattern -> use the non-ext version - return startPublicKeyExport(patterns ? patterns[0] : nullptr, keyData); + return startPublicKeyExport(patterns ? patterns[0] : nullptr, keyData, flags); } #endif Data::Private *const dp = keyData.impl(); - return Error(d->lasterr = gpgme_op_export_ext_start(d->ctx, patterns, 0, dp ? dp->data : nullptr)); + return Error(d->lasterr = gpgme_op_export_ext_start(d->ctx, patterns, flags, dp ? dp->data : nullptr)); +} + + +/* Same as above but without flags */ +Error Context::exportPublicKeys(const char *pattern, Data &keyData) +{ + return exportPublicKeys(pattern, keyData, 0); +} + +Error Context::exportPublicKeys(const char *patterns[], Data &keyData) +{ + return exportPublicKeys(patterns, keyData, 0); +} + +Error Context::startPublicKeyExport(const char *pattern, Data &keyData) +{ + return startPublicKeyExport(pattern, keyData, 0); +} + +Error Context::startPublicKeyExport(const char *patterns[], Data &keyData) +{ + return startPublicKeyExport(patterns, keyData, 0); } ImportResult Context::importKeys(const Data &data) @@ -1615,6 +1637,7 @@ std::ostream &operator<<(std::ostream &os, KeyListMode mode) CHECK(Validate); CHECK(Ephemeral); CHECK(WithTofu); + CHECK(WithKeygrip); #undef CHECK return os << ')'; } diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h index b6b902a..70f1c42 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -182,11 +182,25 @@ public: // // Key Export // + enum ExportMode { + ExportDefault = 0, + ExportExtern = 2, + ExportMinimal = 4, + ExportSecret = 16, + ExportRaw = 32, + ExportPKCS12 = 64, + ExportNoUID = 128, + ExportSSH = 256, + }; GpgME::Error exportPublicKeys(const char *pattern, Data &keyData); + GpgME::Error exportPublicKeys(const char *pattern, Data &keyData, unsigned int flags); GpgME::Error exportPublicKeys(const char *pattern[], Data &keyData); + GpgME::Error exportPublicKeys(const char *pattern[], Data &keyData, unsigned int export_mode); GpgME::Error startPublicKeyExport(const char *pattern, Data &keyData); + GpgME::Error startPublicKeyExport(const char *pattern, Data &keyData, unsigned int flags); GpgME::Error startPublicKeyExport(const char *pattern[], Data &keyData); + GpgME::Error startPublicKeyExport(const char *pattern[], Data &keyData, unsigned int export_mode); // // Key Import diff --git a/lang/cpp/src/editinteractor.cpp b/lang/cpp/src/editinteractor.cpp index f7c994a..36d1be6 100644 --- a/lang/cpp/src/editinteractor.cpp +++ b/lang/cpp/src/editinteractor.cpp @@ -178,10 +178,25 @@ EditInteractor::Private::Private(EditInteractor *qq) error(), debug(nullptr) { - + const char *debug_env = getenv("GPGMEPP_INTERACTOR_DEBUG"); + if (!debug_env) { + return; + } + if (!strcmp(debug_env, "stdout")) { + debug = stdout; + } else if (!strcmp(debug_env, "stderr")) { + debug = stderr; + } else if (debug_env) { + debug = std::fopen(debug_env, "a+"); + } } -EditInteractor::Private::~Private() {} +EditInteractor::Private::~Private() +{ + if (debug) { + std::fclose(debug); + } +} EditInteractor::EditInteractor() : d(new Private(this)) diff --git a/lang/cpp/src/global.h b/lang/cpp/src/global.h index d5c2e13..7a88dc3 100644 --- a/lang/cpp/src/global.h +++ b/lang/cpp/src/global.h @@ -65,7 +65,8 @@ enum KeyListMode { SignatureNotations = 0x8, Validate = 0x10, Ephemeral = 0x20, - WithTofu = 0x40 + WithTofu = 0x40, + WithKeygrip = 0x80 }; enum SignatureMode { NormalSignatureMode, Detached, Clearsigned }; diff --git a/lang/cpp/src/gpgsignkeyeditinteractor.cpp b/lang/cpp/src/gpgsignkeyeditinteractor.cpp index 295802d..33ffbcf 100644 --- a/lang/cpp/src/gpgsignkeyeditinteractor.cpp +++ b/lang/cpp/src/gpgsignkeyeditinteractor.cpp @@ -64,6 +64,8 @@ public: std::vector<unsigned int> userIDs; std::vector<unsigned int>::const_iterator currentId, nextId; unsigned int checkLevel; + bool dupeOk; + Key key; const char *command() const { @@ -126,7 +128,8 @@ GpgSignKeyEditInteractor::Private::Private() userIDs(), currentId(), nextId(), - checkLevel(0) + checkLevel(0), + dupeOk(false) { } @@ -159,6 +162,8 @@ enum SignKeyState { SET_TRUST_REGEXP, CONFIRM, CONFIRM2, + DUPE_OK, + DUPE_OK2, QUIT, SAVE, ERROR = EditInteractor::ErrorState @@ -184,6 +189,7 @@ static GpgSignKeyEditInteractor_Private::TransitionMap makeTable() addEntry(COMMAND, GET_BOOL, "keyedit.sign_all.okay", UIDS_ANSWER_SIGN_ALL); addEntry(COMMAND, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(COMMAND, GET_BOOL, "sign_uid.local_promote_okay", CONFIRM2); + addEntry(COMMAND, GET_BOOL, "sign_uid.dupe_okay", DUPE_OK); addEntry(UIDS_ANSWER_SIGN_ALL, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(UIDS_ANSWER_SIGN_ALL, GET_LINE, "sign_uid.expire", SET_EXPIRE); addEntry(UIDS_ANSWER_SIGN_ALL, GET_LINE, "sign_uid.class", SET_CHECK_LEVEL); @@ -193,6 +199,8 @@ static GpgSignKeyEditInteractor_Private::TransitionMap makeTable() addEntry(SET_CHECK_LEVEL, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(SET_EXPIRE, GET_BOOL, "sign_uid.class", SET_CHECK_LEVEL); addEntry(CONFIRM, GET_BOOL, "sign_uid.local_promote_okay", CONFIRM); + addEntry(DUPE_OK, GET_BOOL, "sign_uid.okay", CONFIRM); + addEntry(DUPE_OK2, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(CONFIRM, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(CONFIRM2, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(CONFIRM, GET_LINE, "keyedit.prompt", COMMAND); @@ -205,6 +213,9 @@ static GpgSignKeyEditInteractor_Private::TransitionMap makeTable() addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "sign_uid.expire", SET_EXPIRE); addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "sign_uid.class", SET_CHECK_LEVEL); addEntry(UIDS_LIST_SEPARATELY_DONE, GET_BOOL, "sign_uid.okay", CONFIRM); + addEntry(UIDS_LIST_SEPARATELY_DONE, GET_BOOL, "sign_uid.dupe_okay", DUPE_OK); + addEntry(DUPE_OK, GET_BOOL, "sign_uid.dupe_okay", DUPE_OK2); + addEntry(DUPE_OK2, GET_BOOL, "sign_uid.dupe_okay", DUPE_OK); addEntry(CONFIRM, GET_LINE, "keyedit.prompt", QUIT); addEntry(ERROR, GET_LINE, "keyedit.prompt", QUIT); addEntry(QUIT, GET_BOOL, "keyedit.save.okay", SAVE); @@ -236,6 +247,9 @@ const char *GpgSignKeyEditInteractor::action(Error &err) const return nullptr; case SET_CHECK_LEVEL: return check_level_strings[d->checkLevel]; + case DUPE_OK: + case DUPE_OK2: + return answer(d->dupeOk); case CONFIRM2: case CONFIRM: return answer(true); @@ -246,7 +260,17 @@ const char *GpgSignKeyEditInteractor::action(Error &err) const default: if (st >= UIDS_LIST_SEPARATELY && st < UIDS_LIST_SEPARATELY_DONE) { std::stringstream ss; - ss << d->nextUserID(); + auto nextID = d->nextUserID(); + const char *hash; + assert (nextID); + if (!d->key.isNull() && (hash = d->key.userID(nextID - 1).uidhash())) { + /* Prefer uidhash if it is available as it might happen + * that uidattrs break the ordering of the uids in the + * edit-key interface */ + ss << "uid " << hash; + } else { + ss << nextID; + } d->scratch = ss.str(); return d->scratch.c_str(); } @@ -305,6 +329,10 @@ unsigned int GpgSignKeyEditInteractor::nextState(unsigned int status, const char err = GENERAL_ERROR; return ERROR; } +void GpgSignKeyEditInteractor::setKey(const Key &key) +{ + d->key = key; +} void GpgSignKeyEditInteractor::setCheckLevel(unsigned int checkLevel) { @@ -326,3 +354,9 @@ void GpgSignKeyEditInteractor::setSigningOptions(int options) assert(!d->started); d->options = options; } + +void GpgSignKeyEditInteractor::setDupeOk(bool value) +{ + assert(!d->started); + d->dupeOk = value; +} diff --git a/lang/cpp/src/gpgsignkeyeditinteractor.h b/lang/cpp/src/gpgsignkeyeditinteractor.h index 34b1f06..d459687 100644 --- a/lang/cpp/src/gpgsignkeyeditinteractor.h +++ b/lang/cpp/src/gpgsignkeyeditinteractor.h @@ -50,8 +50,14 @@ public: void setCheckLevel(unsigned int checkLevel); void setUserIDsToSign(const std::vector<unsigned int> &userIDsToSign); + void setKey(const Key &key); void setSigningOptions(int options); + /* Set this if it is ok to overwrite an existing signature. In that + * case the context has to have the flag "extended-edit" set to 1 through + * Context::setFlag before calling edit.*/ + void setDupeOk(bool value); + private: const char *action(Error &err) const override; unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const override; diff --git a/lang/cpp/src/key.cpp b/lang/cpp/src/key.cpp index 4638fd8..c422fcc 100644 --- a/lang/cpp/src/key.cpp +++ b/lang/cpp/src/key.cpp @@ -358,14 +358,14 @@ void Key::update() KeyListMode::Signatures | KeyListMode::SignatureNotations | KeyListMode::Validate | - KeyListMode::WithTofu); + KeyListMode::WithTofu | + KeyListMode::WithKeygrip); Error err; auto newKey = ctx->key(primaryFingerprint(), err, true); // Not secret so we get the information from the pubring. - if (newKey.isNull()) - { + if (newKey.isNull()) { newKey = ctx->key(primaryFingerprint(), err, false); - } + } delete ctx; if (err) { return; @@ -674,6 +674,11 @@ const char *UserID::comment() const return uid ? uid->comment : nullptr ; } +const char *UserID::uidhash() const +{ + return uid ? uid->uidhash : nullptr ; +} + UserID::Validity UserID::validity() const { if (!uid) { @@ -724,6 +729,76 @@ TofuInfo UserID::tofuInfo() const return TofuInfo(uid->tofu); } +static gpgme_key_sig_t find_last_valid_sig_for_keyid (gpgme_user_id_t uid, + const char *keyid) +{ + if (!keyid) { + return nullptr; + } + gpgme_key_sig_t ret = NULL; + for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next) { + if (s->keyid && !strcmp(keyid, s->keyid)) { + if (!s->expired && !s->revoked && !s->invalid && !s->status) { + if (!ret) { + ret = s; + } else if (ret && ret->timestamp <= s->timestamp) { + /* Equals because when the timestamps are the same we prefer + the last in the list */ + ret = s; + } + } + } + } + return ret; +} + +const char *UserID::remark(const Key &remarker, Error &err) const +{ + if (!uid || remarker.isNull()) { + err = Error::fromCode(GPG_ERR_GENERAL); + return nullptr; + } + + if (key->protocol != GPGME_PROTOCOL_OpenPGP) { + return nullptr; + } + + if (!(key->keylist_mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS) || + !(key->keylist_mode & GPGME_KEYLIST_MODE_SIGS)) { + err = Error::fromCode(GPG_ERR_NO_DATA); + return nullptr; + } + + gpgme_key_sig_t s = find_last_valid_sig_for_keyid(uid, remarker.keyID()); + + if (!s) { + return nullptr; + } + + for (gpgme_sig_notation_t n = s->notations; n ; n = n->next) { + if (n->name && !strcmp(n->name, "rem@gnupg.org")) { + return n->value; + } + } + return nullptr; +} + +std::vector<std::string> UserID::remarks(std::vector<Key> keys, Error &err) const +{ + std::vector<std::string> ret; + + for (const auto &key: keys) { + const char *rem = remark(key, err); + if (err) { + return ret; + } + if (rem) { + ret.push_back(rem); + } + } + return ret; +} + // // // class Signature diff --git a/lang/cpp/src/key.h b/lang/cpp/src/key.h index dd855ae..fc5e67e 100644 --- a/lang/cpp/src/key.h +++ b/lang/cpp/src/key.h @@ -363,6 +363,7 @@ public: const char *name() const; const char *email() const; const char *comment() const; + const char *uidhash() const; enum Validity { Unknown = 0, Undefined = 1, Never = 2, Marginal = 3, Full = 4, Ultimate = 5 @@ -413,6 +414,27 @@ public: * * @returns the last update time. */ time_t lastUpdate() const; + + /*! Get a remark made by the key provided. + * A remark is a signature notation on + * this user id made by the key with the + * name "rem@gnupg.org". Returns an error if the + * parent key of this user id was not listed with the + * keylist mode flags for signatures and signature notations. + * + * @param key The key for which comments should be searched. + * @param error Set to GPG_ERR_NO_DATA if the keylist did + * not include signature notations. + * + * @returns The value of the comment or NULL if none exists. + **/ + const char *remark(const Key &key, + Error &error) const; + + /*! Get multiple remarks made by potentially multiple keys. */ + std::vector <std::string> remarks(std::vector<GpgME::Key> remarkers, + Error &error) const; + private: shared_gpgme_key_t key; gpgme_user_id_t uid; diff --git a/lang/cpp/src/util.h b/lang/cpp/src/util.h index 4495cc0..1c0477f 100644 --- a/lang/cpp/src/util.h +++ b/lang/cpp/src/util.h @@ -81,6 +81,9 @@ static inline gpgme_keylist_mode_t add_to_gpgme_keylist_mode_t(unsigned int oldm if (newmodes & GpgME::WithTofu) { oldmode |= GPGME_KEYLIST_MODE_WITH_TOFU; } + if (newmodes & GpgME::WithKeygrip) { + oldmode |= GPGME_KEYLIST_MODE_WITH_KEYGRIP; + } #ifndef NDEBUG if (newmodes & ~(GpgME::Local | GpgME::Extern | GpgME::Signatures | GpgME::SignatureNotations | GpgME::Ephemeral | GpgME::Validate)) { //std::cerr << "GpgME::Context: keylist mode must be one of Local, " diff --git a/lang/cpp/src/verificationresult.cpp b/lang/cpp/src/verificationresult.cpp index 1e9f81f..bfe82e3 100644 --- a/lang/cpp/src/verificationresult.cpp +++ b/lang/cpp/src/verificationresult.cpp @@ -413,7 +413,8 @@ GpgME::Key GpgME::Signature::key(bool search, bool update) const KeyListMode::Signatures | KeyListMode::SignatureNotations | KeyListMode::Validate | - KeyListMode::WithTofu); + KeyListMode::WithTofu | + KeyListMode::WithKeygrip); Error e; ret = d->keys[idx] = ctx->key(fingerprint(), e, false); delete ctx; |