[gitg/wip/adwait/signed_commit] Allow to sign commits




commit a304b015bf4958f64d1820f270aa29e66a377159
Author: Adwait Rawat <adwait rawat gmail com>
Date:   Mon Oct 10 22:18:01 2022 +0200

    Allow to sign commits

 data/org.gnome.gitg.gschema.xml.in      |    3 +
 gitg/commit/gitg-commit-dialog.vala     |   16 +
 gitg/commit/gitg-commit.vala            |    5 +
 gitg/meson.build                        |    1 -
 gitg/resources/ui/gitg-commit-dialog.ui |   19 +-
 libgitg/gitg-gpg-utils.vala             |   63 ++
 libgitg/gitg-stage.vala                 |   69 +-
 libgitg/meson.build                     |    2 +
 meson.build                             |    1 +
 vapi/gpg-error.vapi                     |  422 +++++++++++
 vapi/gpgme.deps                         |    1 +
 vapi/gpgme.vapi                         | 1225 +++++++++++++++++++++++++++++++
 12 files changed, 1816 insertions(+), 11 deletions(-)
---
diff --git a/data/org.gnome.gitg.gschema.xml.in b/data/org.gnome.gitg.gschema.xml.in
index b0d240a8..103bcd0f 100644
--- a/data/org.gnome.gitg.gschema.xml.in
+++ b/data/org.gnome.gitg.gschema.xml.in
@@ -371,5 +371,8 @@
     <key name="sign-off" type="b">
       <default>false</default>
     </key>
+    <key name="sign-commit" type="b">
+      <default>false</default>
+    </key>
   </schema>
 </schemalist>
diff --git a/gitg/commit/gitg-commit-dialog.vala b/gitg/commit/gitg-commit-dialog.vala
index 935bc83d..0b3f888a 100644
--- a/gitg/commit/gitg-commit-dialog.vala
+++ b/gitg/commit/gitg-commit-dialog.vala
@@ -57,6 +57,9 @@ class Dialog : Gtk.Dialog
        [GtkChild (name = "check_button_sign_off")]
        private unowned Gtk.CheckButton d_check_button_sign_off;
 
+       [GtkChild (name = "check_button_sign_commit")]
+       private Gtk.CheckButton d_check_button_sign_commit;
+
        [GtkChild (name = "image_avatar")]
        private unowned Gtk.Image d_image_avatar;
 
@@ -218,6 +221,8 @@ class Dialog : Gtk.Dialog
 
        public bool sign_off { get; set; }
 
+       public bool sign_commit { get; set; }
+
        public int max_number_commit_messages { get; set; }
 
        public int max_number_days_commit_messages { get; set; }
@@ -478,6 +483,11 @@ class Dialog : Gtk.Dialog
                                                      BindingFlags.BIDIRECTIONAL |
                                                      BindingFlags.SYNC_CREATE);
 
+               d_check_button_sign_commit.bind_property("active",
+                                                         this, "sign-commit",
+                                                         BindingFlags.BIDIRECTIONAL |
+                                                         BindingFlags.SYNC_CREATE);
+
                d_commit_settings = new Settings(Gitg.Config.APPLICATION_ID + ".state.commit");
 
                d_commit_settings.bind("sign-off",
@@ -486,6 +496,12 @@ class Dialog : Gtk.Dialog
                                     SettingsBindFlags.GET |
                                     SettingsBindFlags.SET);
 
+               d_commit_settings.bind("sign-commit",
+                                    this,
+                                    "sign-commit",
+                                    SettingsBindFlags.GET |
+                                    SettingsBindFlags.SET);
+
                d_message_settings = new Settings(Gitg.Config.APPLICATION_ID + ".preferences.commit.message");
 
                d_message_settings.bind("max-number-days-commit-messages",
diff --git a/gitg/commit/gitg-commit.vala b/gitg/commit/gitg-commit.vala
index cb561a09..e1fc374b 100644
--- a/gitg/commit/gitg-commit.vala
+++ b/gitg/commit/gitg-commit.vala
@@ -1099,6 +1099,11 @@ namespace GitgCommit
                                opts |= Gitg.StageCommitOptions.SIGN_OFF;
                        }
 
+                       if (dlg.sign_commit)
+                       {
+                               opts |= Gitg.StageCommitOptions.SIGN_COMMIT;
+                       }
+
                        if (skip_hooks)
                        {
                                opts |= Gitg.StageCommitOptions.SKIP_HOOKS;
diff --git a/gitg/meson.build b/gitg/meson.build
index 4b108a14..cc01887d 100644
--- a/gitg/meson.build
+++ b/gitg/meson.build
@@ -73,7 +73,6 @@ deps = [
   libpeas_dep,
   libdazzle_dep,
   json_glib_dependency,
-
   valac.find_library ('posix'),
 ]
 
diff --git a/gitg/resources/ui/gitg-commit-dialog.ui b/gitg/resources/ui/gitg-commit-dialog.ui
index a2014a60..443add8a 100644
--- a/gitg/resources/ui/gitg-commit-dialog.ui
+++ b/gitg/resources/ui/gitg-commit-dialog.ui
@@ -246,6 +246,23 @@
                 <property name="height">1</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkCheckButton" id="check_button_sign_commit">
+                <property name="label" translatable="yes">Add si_gnature</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
+                <property name="halign">start</property>
+                <property name="draw_indicator">True</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">7</property>
+                <property name="width">2</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
             <child>
               <object class="GtkBox">
                 <property name="visible">True</property>
@@ -280,7 +297,7 @@
               </object>
               <packing>
                 <property name="left_attach">2</property>
-                <property name="top_attach">6</property>
+                <property name="top_attach">7</property>
                 <property name="width">1</property>
                 <property name="height">1</property>
               </packing>
diff --git a/libgitg/gitg-gpg-utils.vala b/libgitg/gitg-gpg-utils.vala
new file mode 100644
index 00000000..82cf02a4
--- /dev/null
+++ b/libgitg/gitg-gpg-utils.vala
@@ -0,0 +1,63 @@
+
+/*
+ * This file is part of gitg
+ *
+ * Copyright (C) 2022 - Alberto Fanjul
+ *
+ * gitg 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.
+ *
+ * gitg 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 gitg. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using GPG;
+
+namespace Gitg
+{
+
+public class GPGUtils
+{
+       public static string sign_commit_object(string commit_content,
+                                               string signing_key) throws Error
+       {
+               check_version();
+               Data plain_data;
+               Data signed_data;
+               Data.create(out signed_data);
+               Data.create_from_memory(out plain_data, commit_content.data, false);
+               Context context;
+               Context.Context(out context);
+               context.set_armor(true);
+               Key key;
+               context.get_key(signing_key, out key, true);
+               if (key != null)
+                       context.signers_add(key);
+               context.op_sign(plain_data, signed_data, SigMode.DETACH);
+               return get_string_from_data(signed_data);
+       }
+
+       private static string get_string_from_data(Data data) {
+               data.seek(0);
+               uint8[] buf = new uint8[256];
+               ssize_t? len = null;
+               string res = "";
+               do {
+                       len = data.read(buf);
+                       if (len > 0) {
+                               string part = (string) buf;
+                               part = part.substring(0, (long) len);
+                               res += part;
+                       }
+               } while (len > 0);
+               return res;
+       }
+}
+}
diff --git a/libgitg/gitg-stage.vala b/libgitg/gitg-stage.vala
index 367fca2c..5aba26ac 100644
--- a/libgitg/gitg-stage.vala
+++ b/libgitg/gitg-stage.vala
@@ -26,7 +26,8 @@ public enum StageCommitOptions
        NONE       = 0,
        SIGN_OFF   = 1 << 0,
        AMEND      = 1 << 1,
-       SKIP_HOOKS = 1 << 2
+       SKIP_HOOKS = 1 << 2,
+       SIGN_COMMIT= 1 << 3
 }
 
 public errordomain StageError
@@ -34,7 +35,9 @@ public errordomain StageError
        PRE_COMMIT_HOOK_FAILED,
        COMMIT_MSG_HOOK_FAILED,
        NOTHING_TO_COMMIT,
-       INDEX_ENTRY_NOT_FOUND
+       INDEX_ENTRY_NOT_FOUND,
+       SIGN_CONFIG_NOT_FOUND,
+       SIGN_CONFIG_ERROR
 }
 
 public class PatchSet
@@ -92,6 +95,8 @@ public class PatchSet
 
 public class Stage : Object
 {
+       private const string CONFIG_USER_SIGNINGKEY = "user.signingkey";
+
        private weak Repository d_repository;
        private Mutex d_index_mutex;
        private Ggit.Tree? d_head_tree;
@@ -400,6 +405,7 @@ public class Stage : Object
                yield Async.thread(() => {
                        bool skip_hooks = (options & StageCommitOptions.SKIP_HOOKS) != 0;
                        bool amend = (options & StageCommitOptions.AMEND) != 0;
+                       bool sign_commit = (options & StageCommitOptions.SIGN_COMMIT) != 0;
 
                        // Write tree from index
                        var conf = d_repository.get_config().snapshot();
@@ -448,13 +454,58 @@ public class Stage : Object
                                        pars = parents;
                                }
 
-                               ret = d_repository.create_commit_from_ids(reference.get_name(),
-                                                                         author,
-                                                                         committer,
-                                                                         encoding,
-                                                                         emsg,
-                                                                         treeoid,
-                                                                         pars);
+                               if (sign_commit)
+                               {
+                                       string signing_key;
+                                       try {
+                                               signing_key = conf.get_string(CONFIG_USER_SIGNINGKEY);
+                                       } catch (Error e) {
+                                               throw new StageError.SIGN_CONFIG_NOT_FOUND(_("setup ā€œ%sā€ to 
do a signed commit"), CONFIG_USER_SIGNINGKEY);
+                                       }
+
+                                       Ggit.Commit[] parent_commits = new Ggit.Commit[pars.length];
+                                       for (int i = 0; i < pars.length; i++) {
+                                               Ggit.Commit commit = 
d_repository.lookup<Ggit.Commit>(pars[i]);
+                                               parent_commits[i] = commit;
+                                       }
+
+                                       var data = d_repository.create_commit_buffer(author,
+                                                                                    committer,
+                                                                                    encoding,
+                                                                                    emsg,
+                                                                                    
d_repository.lookup_tree(treeoid),
+                                                                                    parent_commits);
+
+                                       string signature;
+                                       try {
+                                               signature = Gitg.GPGUtils.sign_commit_object(data, 
signing_key);
+                                       } catch (Error e) {
+                                               throw new StageError.SIGN_CONFIG_ERROR(_("error signing the 
commit ā€œ%sā€"), e.message);
+                                       }
+
+                                       ret = d_repository.create_commit_with_signature(data, signature, 
null);
+
+                                       if (reference.get_reference_type() == Ggit.RefType.SYMBOLIC)
+                                       {
+                                               try
+                                               {
+                                                       var resolved = reference.resolve();
+                                                       resolved.set_target(ret, null);
+                                               } catch (Error e) {
+                                                       print("%s\n", e.message);
+                                               }
+                                       }
+                               }
+                               else
+                               {
+                                       ret = d_repository.create_commit_from_ids(reference.get_name(),
+                                                                                 author,
+                                                                                 committer,
+                                                                                 encoding,
+                                                                                 emsg,
+                                                                                 treeoid,
+                                                                                 pars);
+                               }
                        }
                        else
                        {
diff --git a/libgitg/meson.build b/libgitg/meson.build
index 9be08659..c572867f 100644
--- a/libgitg/meson.build
+++ b/libgitg/meson.build
@@ -14,6 +14,7 @@ common_deps = [
   gtk_dep,
   libgit2_glib_dep,
   libdazzle_dep,
+  gpgme_dependency,
 ]
 
 sources = files(
@@ -52,6 +53,7 @@ sources = files(
   'gitg-diff-view-options.vala',
   'gitg-diff-view.vala',
   'gitg-font-manager.vala',
+  'gitg-gpg-utils.vala',
   'gitg-hook.vala',
   'gitg-init.vala',
   'gitg-label-renderer.vala',
diff --git a/meson.build b/meson.build
index d2e507c4..5296f1c1 100644
--- a/meson.build
+++ b/meson.build
@@ -137,6 +137,7 @@ libsecret_dep = dependency('libsecret-1')
 libxml_dep = dependency('libxml-2.0', version: '>= 2.9.0')
 libdazzle_dep = dependency('libdazzle-1.0')
 json_glib_dependency = dependency('json-glib-1.0')
+gpgme_dependency = dependency('gpgme')
 
 config_dep = valac.find_library('config', dirs: vapi_dir)
 gitg_platform_support_dep = valac.find_library('gitg-platform-support', dirs: vapi_dir)
diff --git a/vapi/gpg-error.vapi b/vapi/gpg-error.vapi
new file mode 100644
index 00000000..42734a4a
--- /dev/null
+++ b/vapi/gpg-error.vapi
@@ -0,0 +1,422 @@
+/* gpg-error.vapi
+ *
+ * Copyright (C) 2009 Sebastian Reichel <sre ring0 de>
+ * Copyright (C) 2022 Itay Grudev <itay+git2022 grudev com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+[CCode (cheader_filename = "gpg-error.h")]
+namespace GPGError {
+       /**
+        * The error value type gpg_error_t
+        */
+       [SimpleType]
+       [CCode (cname = "gpg_error_t", has_type_id = false)]
+       public struct Error {
+               public GPGError.ErrorCode code {
+                       [CCode (cname = "gpg_err_code")]
+                       get;
+               }
+       }
+
+       /**
+        * The error code type gpg_err_code_t.
+        */
+       [CCode (cname = "gpg_err_code_t", cprefix = "GPG_ERR_", has_type_id = false)]
+       public enum ErrorCode {
+               NO_ERROR,
+               GENERAL,
+               UNKNOWN_PACKET,
+               UNKNOWN_VERSION,
+               PUBKEY_ALGO,
+               DIGEST_ALGO,
+               BAD_PUBKEY,
+               BAD_SECKEY,
+               BAD_SIGNATURE,
+               NO_PUBKEY,
+               CHECKSUM,
+               BAD_PASSPHRASE,
+               CIPHER_ALGO,
+               KEYRING_OPEN,
+               INV_PACKET,
+               INV_ARMOR,
+               NO_USER_ID,
+               NO_SECKEY,
+               WRONG_SECKEY,
+               BAD_KEY,
+               COMPR_ALGO,
+               NO_PRIME,
+               NO_ENCODING_METHOD,
+               NO_ENCRYPTION_SCHEME,
+               NO_SIGNATURE_SCHEME,
+               INV_ATTR,
+               NO_VALUE,
+               NOT_FOUND,
+               VALUE_NOT_FOUND,
+               SYNTAX,
+               BAD_MPI,
+               INV_PASSPHRASE,
+               SIG_CLASS,
+               RESOURCE_LIMIT,
+               INV_KEYRING,
+               TRUSTDB,
+               BAD_CERT,
+               INV_USER_ID,
+               UNEXPECTED,
+               TIME_CONFLICT,
+               KEYSERVER,
+               WRONG_PUBKEY_ALGO,
+               TRIBUTE_TO_D_A,
+               WEAK_KEY,
+               INV_KEYLEN,
+               INV_ARG,
+               BAD_URI,
+               INV_URI,
+               NETWORK,
+               UNKNOWN_HOST,
+               SELFTEST_FAILED,
+               NOT_ENCRYPTED,
+               NOT_PROCESSED,
+               UNUSABLE_PUBKEY,
+               UNUSABLE_SECKEY,
+               INV_VALUE,
+               BAD_CERT_CHAIN,
+               MISSING_CERT,
+               NO_DATA,
+               BUG,
+               NOT_SUPPORTED,
+               INV_OP,
+               TIMEOUT,
+               INTERNAL,
+               EOF_GCRYPT,
+               INV_OBJ,
+               TOO_SHORT,
+               TOO_LARGE,
+               NO_OBJ,
+               NOT_IMPLEMENTED,
+               CONFLICT,
+               INV_CIPHER_MODE,
+               INV_FLAG,
+               INV_HANDLE,
+               TRUNCATED,
+               INCOMPLETE_LINE,
+               INV_RESPONSE,
+               NO_AGENT,
+               AGENT,
+               INV_DATA,
+               ASSUAN_SERVER_FAULT,
+               ASSUAN,
+               INV_SESSION_KEY,
+               INV_SEXP,
+               UNSUPPORTED_ALGORITHM,
+               NO_PIN_ENTRY,
+               PIN_ENTRY,
+               BAD_PIN,
+               INV_NAME,
+               BAD_DATA,
+               INV_PARAMETER,
+               WRONG_CARD,
+               NO_DIRMNGR,
+               DIRMNGR,
+               CERT_REVOKED,
+               NO_CRL_KNOWN,
+               CRL_TOO_OLD,
+               LINE_TOO_LONG,
+               NOT_TRUSTED,
+               CANCELED,
+               BAD_CA_CERT,
+               CERT_EXPIRED,
+               CERT_TOO_YOUNG,
+               UNSUPPORTED_CERT,
+               UNKNOWN_SEXP,
+               UNSUPPORTED_PROTECTION,
+               CORRUPTED_PROTECTION,
+               AMBIGUOUS_NAME,
+               CARD,
+               CARD_RESET,
+               CARD_REMOVED,
+               INV_CARD,
+               CARD_NOT_PRESENT,
+               NO_PKCS15_APP,
+               NOT_CONFIRMED,
+               CONFIGURATION,
+               NO_POLICY_MATCH,
+               INV_INDEX,
+               INV_ID,
+               NO_SCDAEMON,
+               SCDAEMON,
+               UNSUPPORTED_PROTOCOL,
+               BAD_PIN_METHOD,
+               CARD_NOT_INITIALIZED,
+               UNSUPPORTED_OPERATION,
+               WRONG_KEY_USAGE,
+               NOTHING_FOUND,
+               WRONG_BLOB_TYPE,
+               MISSING_VALUE,
+               HARDWARE,
+               PIN_BLOCKED,
+               USE_CONDITIONS,
+               PIN_NOT_SYNCED,
+               INV_CRL,
+               BAD_BER,
+               INV_BER,
+               ELEMENT_NOT_FOUND,
+               IDENTIFIER_NOT_FOUND,
+               INV_TAG,
+               INV_LENGTH,
+               INV_KEYINFO,
+               UNEXPECTED_TAG,
+               NOT_DER_ENCODED,
+               NO_CMS_OBJ,
+               INV_CMS_OBJ,
+               UNKNOWN_CMS_OBJ,
+               UNSUPPORTED_CMS_OBJ,
+               UNSUPPORTED_ENCODING,
+               UNSUPPORTED_CMS_VERSION,
+               UNKNOWN_ALGORITHM,
+               INV_ENGINE,
+               PUBKEY_NOT_TRUSTED,
+               DECRYPT_FAILED,
+               KEY_EXPIRED,
+               SIG_EXPIRED,
+               ENCODING_PROBLEM,
+               INV_STATE,
+               DUP_VALUE,
+               MISSING_ACTION,
+               MODULE_NOT_FOUND,
+               INV_OID_STRING,
+               INV_TIME,
+               INV_CRL_OBJ,
+               UNSUPPORTED_CRL_VERSION,
+               INV_CERT_OBJ,
+               UNKNOWN_NAME,
+               LOCALE_PROBLEM,
+               NOT_LOCKED,
+               PROTOCOL_VIOLATION,
+               INV_MAC,
+               INV_REQUEST,
+               UNKNOWN_EXTN,
+               UNKNOWN_CRIT_EXTN,
+               LOCKED,
+               UNKNOWN_OPTION,
+               UNKNOWN_COMMAND,
+               UNFINISHED,
+               BUFFER_TOO_SHORT,
+               SEXP_INV_LEN_SPEC,
+               SEXP_STRING_TOO_LONG,
+               SEXP_UNMATCHED_PAREN,
+               SEXP_NOT_CANONICAL,
+               SEXP_BAD_CHARACTER,
+               SEXP_BAD_QUOTATION,
+               SEXP_ZERO_PREFIX,
+               SEXP_NESTED_DH,
+               SEXP_UNMATCHED_DH,
+               SEXP_UNEXPECTED_PUNC,
+               SEXP_BAD_HEX_CHAR,
+               SEXP_ODD_HEX_NUMBERS,
+               SEXP_BAD_OCT_CHAR,
+               ASS_GENERAL,
+               ASS_ACCEPT_FAILED,
+               ASS_CONNECT_FAILED,
+               ASS_INV_RESPONSE,
+               ASS_INV_VALUE,
+               ASS_INCOMPLETE_LINE,
+               ASS_LINE_TOO_LONG,
+               ASS_NESTED_COMMANDS,
+               ASS_NO_DATA_CB,
+               ASS_NO_INQUIRE_CB,
+               ASS_NOT_A_SERVER,
+               ASS_NOT_A_CLIENT,
+               ASS_SERVER_START,
+               ASS_READ_ERROR,
+               ASS_WRITE_ERROR,
+               ASS_TOO_MUCH_DATA,
+               ASS_UNEXPECTED_CMD,
+               ASS_UNKNOWN_CMD,
+               ASS_SYNTAX,
+               ASS_CANCELED,
+               ASS_NO_INPUT,
+               ASS_NO_OUTPUT,
+               ASS_PARAMETER,
+               ASS_UNKNOWN_INQUIRE,
+               USER_1,
+               USER_2,
+               USER_3,
+               USER_4,
+               USER_5,
+               USER_6,
+               USER_7,
+               USER_8,
+               USER_9,
+               USER_10,
+               USER_11,
+               USER_12,
+               USER_13,
+               USER_14,
+               USER_15,
+               USER_16,
+               MISSING_ERRNO,
+               UNKNOWN_ERRNO,
+               EOF,
+               E2BIG,
+               EACCES,
+               EADDRINUSE,
+               EADDRNOTAVAIL,
+               EADV,
+               EAFNOSUPPORT,
+               EAGAIN,
+               EALREADY,
+               EAUTH,
+               EBACKGROUND,
+               EBADE,
+               EBADF,
+               EBADFD,
+               EBADMSG,
+               EBADR,
+               EBADRPC,
+               EBADRQC,
+               EBADSLT,
+               EBFONT,
+               EBUSY,
+               ECANCELED,
+               ECHILD,
+               ECHRNG,
+               ECOMM,
+               ECONNABORTED,
+               ECONNREFUSED,
+               ECONNRESET,
+               ED,
+               EDEADLK,
+               EDEADLOCK,
+               EDESTADDRREQ,
+               EDIED,
+               EDOM,
+               EDOTDOT,
+               EDQUOT,
+               EEXIST,
+               EFAULT,
+               EFBIG,
+               EFTYPE,
+               EGRATUITOUS,
+               EGREGIOUS,
+               EHOSTDOWN,
+               EHOSTUNREACH,
+               EIDRM,
+               EIEIO,
+               EILSEQ,
+               EINPROGRESS,
+               EINTR,
+               EINVAL,
+               EIO,
+               EISCONN,
+               EISDIR,
+               EISNAM,
+               EL2HLT,
+               EL2NSYNC,
+               EL3HLT,
+               EL3RST,
+               ELIBACC,
+               ELIBBAD,
+               ELIBEXEC,
+               ELIBMAX,
+               ELIBSCN,
+               ELNRNG,
+               ELOOP,
+               EMEDIUMTYPE,
+               EMFILE,
+               EMLINK,
+               EMSGSIZE,
+               EMULTIHOP,
+               ENAMETOOLONG,
+               ENAVAIL,
+               ENEEDAUTH,
+               ENETDOWN,
+               ENETRESET,
+               ENETUNREACH,
+               ENFILE,
+               ENOANO,
+               ENOBUFS,
+               ENOCSI,
+               ENODATA,
+               ENODEV,
+               ENOENT,
+               ENOEXEC,
+               ENOLCK,
+               ENOLINK,
+               ENOMEDIUM,
+               ENOMEM,
+               ENOMSG,
+               ENONET,
+               ENOPKG,
+               ENOPROTOOPT,
+               ENOSPC,
+               ENOSR,
+               ENOSTR,
+               ENOSYS,
+               ENOTBLK,
+               ENOTCONN,
+               ENOTDIR,
+               ENOTEMPTY,
+               ENOTNAM,
+               ENOTSOCK,
+               ENOTSUP,
+               ENOTTY,
+               ENOTUNIQ,
+               ENXIO,
+               EOPNOTSUPP,
+               EOVERFLOW,
+               EPERM,
+               EPFNOSUPPORT,
+               EPIPE,
+               EPROCLIM,
+               EPROCUNAVAIL,
+               EPROGMISMATCH,
+               EPROGUNAVAIL,
+               EPROTO,
+               EPROTONOSUPPORT,
+               EPROTOTYPE,
+               ERANGE,
+               EREMCHG,
+               EREMOTE,
+               EREMOTEIO,
+               ERESTART,
+               EROFS,
+               ERPCMISMATCH,
+               ESHUTDOWN,
+               ESOCKTNOSUPPORT,
+               ESPIPE,
+               ESRCH,
+               ESRMNT,
+               ESTALE,
+               ESTRPIPE,
+               ETIME,
+               ETIMEDOUT,
+               ETOOMANYREFS,
+               ETXTBSY,
+               EUCLEAN,
+               EUNATCH,
+               EUSERS,
+               EWOULDBLOCK,
+               EXDEV,
+               EXFULL,
+               CODE_DIM
+       }
+}
diff --git a/vapi/gpgme.deps b/vapi/gpgme.deps
new file mode 100644
index 00000000..a0f4f82b
--- /dev/null
+++ b/vapi/gpgme.deps
@@ -0,0 +1 @@
+gpg-error
diff --git a/vapi/gpgme.vapi b/vapi/gpgme.vapi
new file mode 100644
index 00000000..bff0c745
--- /dev/null
+++ b/vapi/gpgme.vapi
@@ -0,0 +1,1225 @@
+/* libgpgme.vapi
+ *
+ * Copyright (C) 2009 Sebastian Reichel <sre ring0 de>
+ * Copyright (C) 2022 Itay Grudev <itay+git2022 grudev com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+/**
+ * GPGME is an API wrapper around GnuPG, which parses the output of GnuPG.
+ */
+[CCode (lower_case_cprefix = "gpgme_", cheader_filename = "gpgme.h")]
+namespace GPG {
+       /**
+        * EngineInfo as List
+        */
+       [CCode (cname = "struct _gpgme_engine_info")]
+       public struct EngineInfo {
+               /**
+                * Next entry in the list
+                */
+               EngineInfo* next;
+
+               /**
+                * The protocol ID
+                */
+               Protocol protocol;
+
+               /**
+                * filename of the engine binary
+                */
+               string file_name;
+
+               /**
+                * version string of the installed binary
+                */
+               string version;
+
+               /**
+                * minimum version required for gpgme
+                */
+               string req_version;
+
+               /**
+                * home directory to be used or null for default
+                */
+               string? home_dir;
+       }
+
+       /**
+        * A Key from the Keyring
+        */
+       [CCode (cname = "struct _gpgme_key", ref_function = "gpgme_key_ref", ref_function_void = true, 
unref_function = "gpgme_key_unref", free_function = "gpgme_key_release")]
+       public class Key {
+               public bool revoked;
+               public bool expired;
+               public bool disabled;
+               public bool invalid;
+               public bool can_encrypt;
+               public bool can_sign;
+               public bool can_certify;
+               public bool secret;
+               public bool can_authenticate;
+               public bool is_qualified;
+               public Protocol protocol;
+
+               /**
+                * If protocol is CMS, this string contains the issuer's serial
+                */
+               public string issuer_serial;
+
+               /**
+                * If protocol is CMS, this string contains the issuer's name
+                */
+               public string issuer_name;
+
+               /**
+                * If protocol is CMS, this string contains the chain ID.
+                */
+               public string chain_id;
+
+               /**
+                * If protocol is OpenPGP, this field contains the owner trust level
+                */
+               public Validity owner_trust;
+
+               /**
+                * The key's subkeys
+                */
+               [CCode(array_null_terminated = true)]
+               public SubKey[] subkeys;
+
+               /**
+                * The key's user ids
+                */
+               [CCode(array_null_terminated = true)]
+               public UserID[] uids;
+
+               public KeylistMode keylist_mode;
+       }
+
+       /**
+        * A signature notation
+        */
+       [CCode (cname = "struct _gpgme_sig_notation")]
+       public struct SigNotation {
+               /**
+                * The next SigNotation from the list
+                */
+               SigNotation* next;
+
+               /**
+                * If name is a null pointer value contains a policy url rather than a notation
+                */
+               string? name;
+
+               /**
+                * The value of the notation data
+                */
+               string value;
+
+               /**
+                * The length of the name of the notation data
+                */
+               int name_len;
+
+               /**
+                * The length of the value of the notation data
+                */
+               int value_len;
+
+               /**
+                * The accumulated flags
+                */
+               SigNotationFlags flags;
+
+               /**
+                * notation data is human readable
+                */
+               bool human_readable;
+
+               /**
+                * notation data is critical
+                */
+               bool critical;
+       }
+
+       /**
+        * A subkey from a Key
+        */
+       [CCode (cname = "struct _gpgme_subkey")]
+       public struct SubKey {
+               SubKey* next;
+               bool revoked;
+               bool expired;
+               bool disabled;
+               bool invalid;
+               bool can_encrypt;
+               bool can_sign;
+               bool can_certify;
+               bool secret;
+               bool can_authenticate;
+               bool is_qualified;
+               bool is_cardkey;
+               PublicKeyAlgorithm algo;
+               uint length;
+               string keyid;
+
+               /**
+                * Fingerprint of the key in hex form
+                */
+               string fpr;
+
+               /**
+                * The creation timestamp.
+                * -1 = invalid,
+                * 0 = not available
+                */
+               long timestamp;
+
+               /**
+                * The expiration timestamp.
+                * 0 = key does not expire
+                */
+               long expires;
+
+               /**
+                * The serial number of the smartcard holding this key or null
+                */
+               string? card_number;
+       }
+
+       /**
+        * A signature on a UserID
+        */
+       [CCode (cname = "struct _gpgme_key_sig")]
+       public struct KeySig {
+               /**
+                * The next signature from the list
+                */
+               KeySig* next;
+               bool revoked;
+               bool expired;
+               bool invalid;
+               bool exportable;
+               PublicKeyAlgorithm algo;
+               string keyid;
+
+               /**
+                * The creation timestamp.
+                * -1 = invalid,
+                * 0 = not available
+                */
+               long timestamp;
+
+               /**
+                * The expiration timestamp.
+                * 0 = key does not expire
+                */
+               long expires;
+
+               GPGError.Error status;
+
+               string uid;
+               string name;
+               string email;
+               string comment;
+
+               /**
+                * Crypto backend specific signature class
+                */
+               uint sig_class;
+
+               SigNotation notations;
+       }
+
+       /**
+        * A UserID from a Key
+        */
+       [CCode (cname = "struct _gpgme_user_id")]
+       public struct UserID {
+               /**
+                * The next UserID from the list
+                */
+               UserID* next;
+
+               bool revoked;
+               bool invalid;
+               Validity validity;
+               string uid;
+               string name;
+               string email;
+               string comment;
+
+               KeySig signatures;
+       }
+
+       /**
+        * verify result of OP
+        */
+       [CCode (cname = "struct _gpgme_op_verify_result")]
+       public struct VerifyResult {
+               Signature* signatures;
+
+               /**
+                * The original file name of the plaintext message, if available
+                */
+               string? file_name;
+       }
+
+       /**
+        * sign result of OP
+        */
+       [CCode (cname = "struct _gpgme_op_sign_result")]
+       public struct SignResult {
+               InvalidKey invalid_signers;
+               Signature* signatures;
+       }
+
+       /**
+        * encrypt result of OP
+        */
+       [CCode (cname = "struct _gpgme_op_encrypt_result")]
+       public struct EncryptResult {
+               /**
+                * The list of invalid repipients
+                */
+               InvalidKey invalid_signers;
+       }
+
+       /**
+        * decrypt result of OP
+        */
+       [CCode (cname = "struct _gpgme_op_decrypt_result")]
+       public struct DecryptResult {
+               string unsupported_algorithm;
+               bool wrong_key_usage;
+               Recipient recipients;
+               string file_name;
+       }
+
+       /**
+        * An receipient
+        */
+       [CCode (cname = "struct _gpgme_recipient")]
+       public struct Recipient {
+               Recipient *next;
+               string keyid;
+               PublicKeyAlgorithm pubkey_algo;
+               GPGError.Error status;
+       }
+
+       /**
+        * list of invalid keys
+        */
+       [CCode (cname = "struct _gpgme_invalid_key")]
+       public struct InvalidKey {
+               InvalidKey *next;
+               string fpr;
+               GPGError.Error reason;
+       }
+
+       /**
+        * A Signature
+        */
+       [CCode (cname = "struct _gpgme_signature")]
+       public struct Signature {
+               /**
+                * The next signature in the list
+                */
+               Signature *next;
+
+               /**
+                * A summary of the signature status
+                */
+               Sigsum summary;
+
+               /**
+                * Fingerprint or key ID of the signature
+                */
+               string fpr;
+
+               /**
+                * The Error status of the signature
+                */
+               GPGError.Error status;
+
+               /**
+                * Notation data and policy URLs
+                */
+               SigNotation notations;
+
+               /**
+                * Signature creation time
+                */
+               ulong timestamp;
+
+               /**
+                * Signature expiration time or 0
+                */
+               ulong exp_timestamp;
+
+               /**
+                * Key should not have been used for signing
+                */
+               bool wrong_key_usage;
+
+               /**
+                * PKA status
+                */
+               PKAStatus pka_trust;
+
+               /**
+                * Validity has been verified using the chain model
+                */
+               bool chain_model;
+
+               /**
+                * Validity
+                */
+               Validity validity;
+
+               /**
+                * Validity reason
+                */
+               GPGError.Error validity_reason;
+
+               /**
+                * public key algorithm used to create the signature
+                */
+               PublicKeyAlgorithm pubkey_algo;
+
+               /**
+                * The hash algorithm used to create the signature
+                */
+               HashAlgorithm hash_algo;
+
+               /**
+                * The mailbox from the PKA information or null
+                */
+               string? pka_address;
+       }
+
+       /**
+        * PKA Status
+        */
+       public enum PKAStatus {
+               NOT_AVAILABLE,
+               BAD,
+               OKAY,
+               RFU
+       }
+
+       /**
+        * Flags used for the summary field in a Signature
+        */
+       [CCode (cname = "gpgme_sigsum_t", cprefix = "GPGME_SIGSUM_")]
+       public enum Sigsum {
+               /**
+                * The signature is fully valid
+                */
+               VALID,
+
+               /**
+                * The signature is good
+                */
+               GREEN,
+
+               /**
+                * The signature is bad
+                */
+               RED,
+
+               /**
+                * One key has been revoked
+                */
+               KEY_REVOKED,
+
+               /**
+                * One key has expired
+                */
+               KEY_EXPIRED,
+
+               /**
+                * The signature has expired
+                */
+               SIG_EXPIRED,
+
+               /**
+                * Can't verfiy - missing key
+                */
+               KEY_MISSING,
+
+               /**
+                * CRL not available
+                */
+               CRL_MISSING,
+
+               /**
+                * Available CRL is too old
+                */
+               CRL_TOO_OLD,
+
+               /**
+                * A policy was not met
+                */
+               BAD_POLICY,
+
+               /**
+                * A system error occured
+                */
+               SYS_ERROR
+       }
+
+       /**
+        * Encoding modes of Data objects
+        */
+       [CCode (cname = "gpgme_data_encoding_t", cprefix = "GPGME_DATA_ENCODING_")]
+       public enum DataEncoding {
+               /**
+                * Not specified
+                */
+               NONE,
+               /**
+                * Binary encoded
+                */
+               BINARY,
+               /**
+                * Base64 encoded
+                */
+               BASE64,
+               /**
+                * Either PEM or OpenPGP Armor
+                */
+               ARMOR,
+               /**
+                * LF delimited URL list
+                */
+               URL,
+               /**
+                * LF percent escaped, delimited URL list
+                */
+               URLESC,
+               /**
+                * Nul determined URL list
+                */
+               URL0
+       }
+
+       /**
+        * Public Key Algorithms from libgcrypt
+        */
+       [CCode (cname = "gpgme_pubkey_algo_t", cprefix = "GPGME_PK_")]
+       public enum PublicKeyAlgorithm {
+               RSA,
+               RSA_E,
+               RSA_S,
+               ELG_E,
+               DSA,
+               ELG
+       }
+
+       /**
+        * Hash Algorithms from libgcrypt
+        */
+       [CCode (cname = "gpgme_hash_algo_t", cprefix = "GPGME_MD_")]
+       public enum HashAlgorithm {
+               NONE,
+               MD5,
+               SHA1,
+               RMD160,
+               MD2,
+               TIGER,
+               HAVAL,
+               SHA256,
+               SHA384,
+               SHA512,
+               MD4,
+               CRC32,
+               CRC32_RFC1510,
+               CRC24_RFC2440
+       }
+
+       /**
+        * Signature modes
+        */
+       [CCode (cname = "gpgme_sig_mode_t", cprefix = "GPGME_SIG_MODE_")]
+       public enum SigMode {
+               NORMAL,
+               DETACH,
+               CLEAR
+       }
+
+       /**
+        * Validities for a trust item or key
+        */
+       [CCode (cname = "gpgme_validity_t", cprefix = "GPGME_VALIDITY_")]
+       public enum Validity {
+               UNKNOWN,
+               UNDEFINED,
+               NEVER,
+               MARGINAL,
+               FULL,
+               ULTIMATE
+       }
+
+       /**
+        * Protocols
+        */
+       [CCode (cname = "gpgme_protocol_t", cprefix = "GPGME_PROTOCOL_")]
+       public enum Protocol {
+               /**
+                * Default Mode
+                */
+               OpenPGP,
+               /**
+                * Cryptographic Message Syntax
+                */
+               CMS,
+               /**
+                * Special code for gpgconf
+                */
+               GPGCONF,
+               /**
+                * Low-level access to an Assuan server
+                */
+               ASSUAN,
+               UNKNOWN
+       }
+
+       /**
+        * Keylist modes used by Context
+        */
+       [CCode (cname = "gpgme_keylist_mode_t", cprefix = "GPGME_KEYLIST_MODE_")]
+       public enum KeylistMode {
+               LOCAL,
+               EXTERN,
+               SIGS,
+               SIG_NOTATIONS,
+               EPHEMERAL,
+               VALIDATE
+       }
+
+       /**
+        * Export modes used by Context
+        */
+       [CCode (cname = "gpgme_export_mode_t", cprefix = "GPGME_EXPORT_MODE_")]
+       public enum ExportMode {
+               EXTERN
+       }
+
+       /**
+        * Audit log function flags
+        */
+       [CCode (cprefix = "GPGME_AUDITLOG_")]
+       public enum AuditLogFlag {
+               HTML,
+               WITH_HELP
+       }
+
+       /**
+        * Signature notation flags
+        */
+       [CCode (cname = "gpgme_sig_notation_flags_t", cprefix = "GPGME_SIG_NOTATION_")]
+       public enum SigNotationFlags {
+               HUMAN_READABLE,
+               CRITICAL
+       }
+
+       /**
+        * Encryption Flags
+        */
+       [CCode (cname = "gpgme_encrypt_flags_t", cprefix = "GPGME_ENCRYPT_")]
+       public enum EncryptFlags {
+               ALWAYS_TRUST,
+               NO_ENCRYPT_TO
+       }
+
+       /**
+        * Edit Operation Stati
+        */
+       [CCode (cname = "gpgme_status_code_t", cprefix = "GPGME_STATUS_")]
+       public enum StatusCode {
+               EOF,
+               ENTER,
+               LEAVE,
+               ABORT,
+               GOODSIG,
+               BADSIG,
+               ERRSIG,
+               BADARMOR,
+               RSA_OR_IDEA,
+               KEYEXPIRED,
+               KEYREVOKED,
+               TRUST_UNDEFINED,
+               TRUST_NEVER,
+               TRUST_MARGINAL,
+               TRUST_FULLY,
+               TRUST_ULTIMATE,
+               SHM_INFO,
+               SHM_GET,
+               SHM_GET_BOOL,
+               SHM_GET_HIDDEN,
+               NEED_PASSPHRASE,
+               VALIDSIG,
+               SIG_ID,
+               SIG_TO,
+               ENC_TO,
+               NODATA,
+               BAD_PASSPHRASE,
+               NO_PUBKEY,
+               NO_SECKEY,
+               NEED_PASSPHRASE_SYM,
+               DECRYPTION_FAILED,
+               DECRYPTION_OKAY,
+               MISSING_PASSPHRASE,
+               GOOD_PASSPHRASE,
+               GOODMDC,
+               BADMDC,
+               ERRMDC,
+               IMPORTED,
+               IMPORT_OK,
+               IMPORT_PROBLEM,
+               IMPORT_RES,
+               FILE_START,
+               FILE_DONE,
+               FILE_ERROR,
+               BEGIN_DECRYPTION,
+               END_DECRYPTION,
+               BEGIN_ENCRYPTION,
+               END_ENCRYPTION,
+               DELETE_PROBLEM,
+               GET_BOOL,
+               GET_LINE,
+               GET_HIDDEN,
+               GOT_IT,
+               PROGRESS,
+               SIG_CREATED,
+               SESSION_KEY,
+               NOTATION_NAME,
+               NOTATION_DATA,
+               POLICY_URL,
+               BEGIN_STREAM,
+               END_STREAM,
+               KEY_CREATED,
+               USERID_HINT,
+               UNEXPECTED,
+               INV_RECP,
+               NO_RECP,
+               ALREADY_SIGNED,
+               SIGEXPIRED,
+               EXPSIG,
+               EXPKEYSIG,
+               TRUNCATED,
+               ERROR,
+               NEWSIG,
+               REVKEYSIG,
+               SIG_SUBPACKET,
+               NEED_PASSPHRASE_PIN,
+               SC_OP_FAILURE,
+               SC_OP_SUCCESS,
+               CARDCTRL,
+               BACKUP_KEY_CREATED,
+               PKA_TRUST_BAD,
+               PKA_TRUST_GOOD,
+               PLAINTEXT
+       }
+
+       /**
+        * The Context object represents a GPG instance
+        */
+       [Compact]
+       [CCode (cname = "struct gpgme_context", free_function = "gpgme_release", cprefix = "gpgme_")]
+       public class Context {
+               /**
+                * Create a new context, returns Error Status Code
+                */
+               [CCode (cname = "gpgme_new")]
+               public static GPGError.Error Context(out Context ctx);
+
+               public GPGError.Error set_protocol(Protocol p);
+               public Protocol get_protocol();
+
+               public void set_armor(bool yes);
+               public bool get_armor();
+
+               public void set_textmode(bool yes);
+               public bool get_textmode();
+
+               public GPGError.Error set_keylist_mode(KeylistMode mode);
+               public KeylistMode get_keylist_mode();
+
+               /**
+                * Include up to nr_of_certs certificates in an S/MIME message,
+                * Use "-256" to use the backend's default.
+                */
+               public void set_include_certs(int nr_of_certs = -256);
+
+               /**
+                * Return the number of certs to include in an S/MIME message
+                */
+               public int get_include_certs();
+
+               /**
+                * Set callback function for requesting passphrase. hook_value will be
+                * passed as first argument.
+                */
+               public void set_passphrase_cb(passphrase_callback cb, void* hook_value = null);
+
+               /**
+                * Get callback function and hook_value
+                */
+               public void get_passphrase_cb(out passphrase_callback cb, out void* hook_value);
+
+               public GPGError.Error set_locale(int category, string val);
+
+               /**
+                * Get information about the configured engines. The returned data is valid
+                * until the next set_engine_info() call.
+                */
+               [CCode (cname = "gpgme_ctx_get_engine_info")]
+               public EngineInfo* get_engine_info();
+
+               /**
+                * Set information about the configured engines. The string parameters may not
+                * be free'd after this calls, because they are not copied.
+                */
+               [CCode (cname = "gpgme_ctx_set_engine_info")]
+               public GPGError.Error set_engine_info(Protocol proto, string file_name, string home_dir);
+
+               /**
+                * Delete all signers
+                */
+               public void signers_clear();
+
+               /**
+                * Add key to list of signers
+                */
+               public GPGError.Error signers_add(Key key);
+
+               /**
+                * Get the n-th signer's key
+                */
+               public Key* signers_enum(int n);
+
+               /**
+                * Clear all notation data
+                */
+               public void sig_notation_clear();
+
+               /**
+                * Add human readable notation data. If name is null,
+                * then value val should be a policy URL. The HUMAN_READABLE
+                * flag is forced to be true for notation data and false
+                * for policy URLs.
+                */
+               public GPGError.Error sig_notation_add(string name, string val, SigNotationFlags flags);
+
+               /**
+                * Get sig notations
+                */
+               public SigNotation* sig_notation_get();
+
+               /**
+                * Get key with the fingerprint FPR from the crypto backend.
+                * If SECRET is true, get the secret key.
+                */
+               public GPGError.Error get_key(string fpr, out Key key, bool secret);
+
+               /**
+                * process the pending operation and, if hang is true, wait for
+                * the pending operation to finish.
+                */
+               public Context* wait(out GPGError.Error status, bool hang);
+
+               /**
+                * Retrieve a pointer to the results of the signing operation
+                */
+               public SignResult* op_sign_result();
+
+               /**
+                * Sign the plaintext PLAIN and store the signature in SIG.
+                */
+               public GPGError.Error op_sign(Data plain, Data sig, SigMode mode);
+
+               /**
+                * Retrieve a pointer to the result of the verify operation
+                */
+               public VerifyResult* op_verify_result();
+
+               /**
+                * Verify that SIG is a valid signature for SIGNED_TEXT.
+                */
+               public GPGError.Error op_verify(Data sig, Data signed_text, Data? plaintext);
+
+               /**
+                * Retrieve a pointer to the result of the encrypt operation
+                */
+               public EncryptResult* op_encrypt_result();
+
+               /**
+                * Encrypt plaintext PLAIN for the recipients RECP and store the
+                * resulting ciphertext in CIPHER.
+                */
+               public GPGError.Error op_encrypt([CCode (array_length = false)] Key[] recp, EncryptFlags 
flags, Data plain, Data cipher);
+
+               /**
+                * Retrieve a pointer to the result of the decrypt operation
+                */
+               public DecryptResult* op_decrypt_result();
+
+               /**
+                * Decrypt ciphertext CIPHER and store the resulting plaintext
+                * in PLAIN.
+                */
+               public GPGError.Error op_decrypt(Data cipher, Data plain);
+
+               /**
+                * Export the keys found by PATTERN into KEYDATA. If PATTERN is
+                * NULL all keys will be exported.
+                */
+               public GPGError.Error op_export(string? pattern, ExportMode mode, Data keydata);
+
+               /**
+                * Import the keys in KEYDATA.
+                */
+               public GPGError.Error op_import(Data keydata);
+
+               /**
+                * Get result of last op_import.
+                */
+               public unowned ImportResult op_import_result();
+
+               /**
+                * Initiates a key listing operation. It sets everything up, so that
+                * subsequent invocations of op_keylist_next() return the keys in the list.
+                *
+                * If pattern is NULL, all available keys are returned. Otherwise, pattern
+                * contains an engine specific expression that is used to limit the list to
+                * all keys matching the pattern.
+                *
+                * If secret_only is not 0, the list is restricted to secret keys only.
+                *
+                * The context will be busy until either all keys are received (and
+                * op_keylist_next() returns GPG_ERR_EOF), or gpgme_op_keylist_end is called
+                * to finish the operation.
+                *
+                * The function returns the error code GPG_ERR_INV_VALUE if ctx is not a valid
+                * pointer, and passes through any errors that are reported by the crypto engine
+                * support routines.
+                */
+               public GPGError.Error op_keylist_start(string? pattern = null, int secret_only = 0);
+
+               /**
+                * returns the next key in the list created by a previous op_keylist_start()
+                * operation in the context ctx. The key will have one reference for the user.
+                *
+                * If the last key in the list has already been returned, op_keylist_next()
+                * returns GPG_ERR_EOF.
+                *
+                * The function returns the error code GPG_ERR_INV_VALUE if ctx or r_key is
+                * not a valid pointer, and GPG_ERR_ENOMEM if there is not enough memory for
+                * the operation.
+                */
+               public GPGError.Error op_keylist_next(out Key key);
+
+               /**
+                * ends a pending key list operation in the context.
+                *
+                * After the operation completed successfully, the result of the key listing
+                * operation can be retrieved with op_keylist_result().
+                *
+                * The function returns the error code GPG_ERR_INV_VALUE if ctx is not a valid
+                * pointer, and GPG_ERR_ENOMEM if at some time during the operation there was
+                * not enough memory available.
+                */
+               public GPGError.Error op_keylist_end();
+
+               /**
+                * The function op_keylist_result() returns a KeylistResult holding the result of
+                * a op_keylist_*() operation. The returned KeylistResult is only valid if the last
+                * operation on the context was a key listing operation, and if this operation
+                * finished successfully. The returned KeylistResult is only valid until the next
+                * operation is started on the context.
+                */
+               public KeylistResult op_keylist_result();
+       }
+
+       [Flags]
+       [CCode (cname="unsigned int")]
+       public enum ImportStatusFlags {
+               /**
+                * The key was new.
+                */
+               [CCode (cname = "GPGME_IMPORT_NEW")]
+               NEW,
+               /**
+                * The key contained new user IDs.
+                */
+               [CCode (cname = "GPGME_IMPORT_UID")]
+               UID,
+               /**
+                * The key contained new signatures.
+                */
+               [CCode (cname = "GPGME_IMPORT_SIG")]
+               SIG,
+               /**
+                * The key contained new sub keys.
+                */
+               [CCode (cname = "GPGME_IMPORT_SUBKEY")]
+               SUBKEY,
+               /**
+                * The key contained a secret key.
+                */
+               [CCode (cname = "GPGME_IMPORT_SECRET")]
+               SECRET
+       }
+
+       [Compact]
+       [CCode (cname = "struct _gpgme_import_status")]
+       public class ImportStatus {
+               /**
+                * This is a pointer to the next status structure in the linked list, or null
+                * if this is the last element.
+                */
+               public ImportStatus? next;
+
+               /**
+                * fingerprint of the key that was considered.
+                */
+               public string fpr;
+
+               /**
+                * If the import was not successful, this is the error value that caused the
+                * import to fail. Otherwise the error code is GPG_ERR_NO_ERROR.
+                */
+               public GPGError.Error result;
+
+               /**
+                * Flags what parts of the key have been imported. May be 0, if the key has
+                * already been known.
+                */
+               public ImportStatusFlags status;
+       }
+
+       [Compact]
+       [CCode (cname = "struct _gpgme_op_import_result")]
+       public class ImportResult {
+               /**
+                * The total number of considered keys.
+                */
+               public int considered;
+
+               /**
+                * The number of keys without user ID.
+                */
+               public int no_user_id;
+
+               /**
+                * The total number of imported keys.
+                */
+               public int imported;
+
+               /**
+                * The number of imported RSA keys.
+                */
+               public int imported_rsa;
+
+               /**
+                * The number of unchanged keys.
+                */
+               public int unchanged;
+
+               /**
+                * The number of new user IDs.
+                */
+               public int new_user_ids;
+
+               /**
+                * The number of new sub keys.
+                */
+               public int new_sub_keys;
+
+               /**
+                * The number of new signatures.
+                */
+               public int new_signatures;
+
+               /**
+                * The number of new revocations.
+                */
+               public int new_revocations;
+
+               /**
+                * The total number of secret keys read.
+                */
+               public int secret_read;
+
+               /**
+                * The number of imported secret keys.
+                */
+               public int secret_imported;
+
+               /**
+                * The number of unchanged secret keys.
+                */
+               public int secret_unchanged;
+
+               /**
+                * The number of keys not imported.
+                */
+               public int not_imported;
+
+               /*
+                * A linked list of ImportStatus objects which
+                * contains more information about the keys for
+                * which an import was attempted.
+                */
+               public ImportStatus imports;
+       }
+
+       [Compact]
+       [CCode (cname = "struct _gpgme_op_keylist_result")]
+       public class KeylistResult {
+               uint truncated;
+       }
+
+
+       /**
+        * Data Object, contains encrypted and/or unencrypted data
+        */
+       [Compact]
+       [CCode (cname = "struct gpgme_data", free_function = "gpgme_data_release", cprefix = "gpgme_data_")]
+       public class Data {
+               /**
+                * Create a new data buffer, returns Error Status Code.
+                */
+               [CCode (cname = "gpgme_data_new")]
+               public static GPGError.Error create(out Data d);
+
+               /**
+                * Create a new data buffer filled with SIZE bytes starting
+                * from BUFFER. If COPY is false, COPYING is delayed until
+                * necessary and the data is taken from the original location
+                * when needed. Returns Error Status Code.
+                */
+               [CCode (cname = "gpgme_data_new_from_mem")]
+               public static GPGError.Error create_from_memory(out Data d, uint8[] buffer, bool copy);
+
+               /**
+                * Create a new data buffer filled with the content of the file.
+                * COPY must be non-zero. For delayed read, please use
+                * create_from_fd or create_from stream instead.
+                */
+               [CCode (cname = "gpgme_data_new_from_file")]
+               public static GPGError.Error create_from_file(out Data d, string filename, int copy = 1);
+
+
+               /**
+                * Destroy the object and return a pointer to its content.
+                * It's size is returned in R_LEN.
+                */
+               [CCode (cname = "gpgme_data_release_and_get_mem")]
+               public string release_and_get_mem(out size_t len);
+
+               /**
+                * Read up to SIZE bytes into buffer BUFFER from the data object.
+                * Return the number of characters read, 0 on EOF and -1 on error.
+                * If an error occurs, errno is set.
+                */
+               public ssize_t read(uint8[] buf);
+
+               /**
+                * Write up to SIZE bytes from buffer BUFFER to the data object.
+                * Return the number of characters written, or -1 on error.
+                * If an error occurs, errno is set.
+                */
+               public ssize_t write(uint8[] buf);
+
+               /**
+                * Set the current position from where the next read or write
+                * starts in the data object to OFFSET, relativ to WHENCE.
+                */
+               public long seek(long offset, int whence=0);
+
+               /**
+                * Get the encoding attribute of the buffer
+                */
+               public DataEncoding *get_encoding();
+
+               /**
+                * Set the encoding attribute of the buffer to ENC
+                */
+               public GPGError.Error set_encoding(DataEncoding enc);
+       }
+
+       [CCode (cname = "gpgme_get_protocol_name")]
+       public unowned string get_protocol_name(Protocol p);
+
+       [CCode (cname = "gpgme_pubkey_algo_name")]
+       public unowned string get_public_key_algorithm_name(PublicKeyAlgorithm algo);
+
+       [CCode (cname = "gpgme_hash_algo_name")]
+       public unowned string get_hash_algorithm_name(HashAlgorithm algo);
+
+       [CCode (cname = "gpgme_passphrase_cb_t", has_target = false)]
+       public delegate GPGError.Error passphrase_callback(void* hook, string uid_hint, string 
passphrase_info, bool prev_was_bad, int fd);
+
+       /**
+        * Get version of libgpgme
+        * Always call this function before using gpgme, it initializes some stuff
+        */
+       [CCode (cname = "gpgme_check_version")]
+       public unowned string check_version(string? required_version = null);
+
+       /**
+        * Verify that the engine implementing proto is installed and
+        * available.
+        */
+       [CCode (cname = "gpgme_engine_check_version")]
+       public GPGError.Error engine_check_version(Protocol proto);
+
+       /**
+        * Get information about the configured engines. The returned data is valid
+        * until the next set_engine_info() call.
+        */
+       [CCode (cname = "gpgme_get_engine_info")]
+       public GPGError.Error get_engine_info(out EngineInfo? engine_info);
+
+       /**
+        * Return the error string for ERR in the user-supplied buffer BUF
+        * of size BUFLEN. This function is thread-safe, if a thread-safe
+        * strerror_r() function is provided by the system. If the function
+        * succeeds, 0 is returned and BUF contains the string describing
+        * the error. If the buffer was not large enough, ERANGE is returned
+        * and BUF contains as much of the beginning of the error string as
+        * fits into the buffer. Returns Error Status Code.
+        */
+       [CCode (cname = "gpgme_strerror_r")]
+       public int strerror_r(GPGError.Error err, uint8[] buf);
+
+       /**
+        * Like strerror_r, but returns a pointer to the string. This method
+        * is not thread safe!
+        */
+       [CCode (cname = "gpgme_strerror")]
+       public unowned string strerror(GPGError.Error err);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]