aboutsummaryrefslogtreecommitdiffstats
path: root/g13/call-gpg.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2009-10-13 19:17:24 +0000
committerWerner Koch <[email protected]>2009-10-13 19:17:24 +0000
commit536b6ab09fa3e17f955c8b55e8469f3265a1936f (patch)
treea06fba4fb448cc70de12a470d7dde7f22c3eaf8f /g13/call-gpg.c
parentReplace C99 style vararg macro which was anyway not correct. (diff)
downloadgnupg-536b6ab09fa3e17f955c8b55e8469f3265a1936f.tar.gz
gnupg-536b6ab09fa3e17f955c8b55e8469f3265a1936f.zip
Keep on hacking on g13. A simple --create and --mount does now work.
A hacked up encfs is required.
Diffstat (limited to 'g13/call-gpg.c')
-rw-r--r--g13/call-gpg.c132
1 files changed, 131 insertions, 1 deletions
diff --git a/g13/call-gpg.c b/g13/call-gpg.c
index 2399058b0..dd519021e 100644
--- a/g13/call-gpg.c
+++ b/g13/call-gpg.c
@@ -43,7 +43,7 @@ start_gpg (ctrl_t ctrl, int input_fd, int output_fd, assuan_context_t *r_ctx)
gpg_error_t err;
assuan_context_t ctx = NULL;
const char *pgmname;
- const char *argv[6];
+ const char *argv[7];
int no_close_list[5];
int i;
char line[ASSUAN_LINELENGTH];
@@ -464,3 +464,133 @@ gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen,
}
+
+/* Call GPG to decrypt a block of data.
+
+
+ */
+gpg_error_t
+gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen,
+ void **r_plain, size_t *r_plainlen)
+{
+ gpg_error_t err;
+ assuan_context_t ctx;
+ int outbound_fds[2] = { -1, -1 };
+ int inbound_fds[2] = { -1, -1 };
+ pth_t writer_tid = NULL;
+ pth_t reader_tid = NULL;
+ gpg_error_t writer_err, reader_err;
+ membuf_t reader_mb;
+
+ *r_plain = NULL;
+ *r_plainlen = 0;
+
+ /* Init the memory buffer to receive the encrypted stuff. */
+ init_membuf_secure (&reader_mb, 1024);
+
+ /* Create two pipes. */
+ err = gnupg_create_outbound_pipe (outbound_fds);
+ if (!err)
+ err = gnupg_create_inbound_pipe (inbound_fds);
+ if (err)
+ {
+ log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
+ goto leave;
+ }
+
+ /* Start GPG and send the INPUT and OUTPUT commands. */
+ err = start_gpg (ctrl, outbound_fds[0], inbound_fds[1], &ctx);
+ if (err)
+ goto leave;
+ close (outbound_fds[0]); outbound_fds[0] = -1;
+ close (inbound_fds[1]); inbound_fds[1] = -1;
+
+ /* Start a writer thread to feed the INPUT command of the server. */
+ err = start_writer (outbound_fds[1], ciph, ciphlen,
+ &writer_tid, &writer_err);
+ if (err)
+ return err;
+ outbound_fds[1] = -1; /* The thread owns the FD now. */
+
+ /* Start a reader thread to eat from the OUTPUT command of the
+ server. */
+ err = start_reader (inbound_fds[0], &reader_mb,
+ &reader_tid, &reader_err);
+ if (err)
+ return err;
+ outbound_fds[0] = -1; /* The thread owns the FD now. */
+
+ /* Run the decryption. */
+ err = assuan_transact (ctx, "DECRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
+ if (err)
+ {
+ log_error ("the engine's DECRYPT command failed: %s <%s>\n",
+ gpg_strerror (err), gpg_strsource (err));
+ goto leave;
+ }
+
+ /* Wait for reader and return the data. */
+ if (!pth_join (reader_tid, NULL))
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+ reader_tid = NULL;
+ if (reader_err)
+ {
+ err = reader_err;
+ log_error ("read error in reader thread: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
+ /* Wait for the writer to catch a writer error. */
+ if (!pth_join (writer_tid, NULL))
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+ writer_tid = NULL;
+ if (writer_err)
+ {
+ err = writer_err;
+ log_error ("write error in writer thread: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
+ /* Return the data. */
+ *r_plain = get_membuf (&reader_mb, r_plainlen);
+ if (!*r_plain)
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("error while storing the data in the reader thread: %s\n",
+ gpg_strerror (err));
+ goto leave;
+ }
+
+ leave:
+ if (reader_tid)
+ {
+ pth_cancel (reader_tid);
+ pth_join (reader_tid, NULL);
+ }
+ if (writer_tid)
+ {
+ pth_cancel (writer_tid);
+ pth_join (writer_tid, NULL);
+ }
+ if (outbound_fds[0] != -1)
+ close (outbound_fds[0]);
+ if (outbound_fds[1] != -1)
+ close (outbound_fds[1]);
+ if (inbound_fds[0] != -1)
+ close (inbound_fds[0]);
+ if (inbound_fds[1] != -1)
+ close (inbound_fds[1]);
+ release_gpg (ctx);
+ xfree (get_membuf (&reader_mb, NULL));
+ return err;
+}
+
+