summaryrefslogtreecommitdiffstats
path: root/openpgp-ffi/examples/encrypt-for.c
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-01-17 11:11:27 +0100
committerJustus Winter <justus@sequoia-pgp.org>2019-01-17 16:48:28 +0100
commit3f58832474a4b270e136544016a401ef773ac065 (patch)
treec617160250c3040ca964c1b72ab5957cd872b82f /openpgp-ffi/examples/encrypt-for.c
parent38b4108cc1eac851ac17932c5c33623dd535bebb (diff)
openpgp-ffi: New crate.
- This creates a new crate, 'sequoia-openpgp-ffi', and moves a handful of functions from 'sequoia-ffi' to it. - The 'sequoia-ffi' crate is a superset of the 'sequoia-openpgp-ffi' crate. This is accomplished by some include! magic. - My first attempt involved having 'sequoia-ffi' depend on 'sequoia-openpgp-ffi', so that the former just re-exports the symbols. However, that turned out to be unreliable, and might be not what we want, because it could also duplicate parts of Rust's standard library. - Fixes #144.
Diffstat (limited to 'openpgp-ffi/examples/encrypt-for.c')
-rw-r--r--openpgp-ffi/examples/encrypt-for.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/openpgp-ffi/examples/encrypt-for.c b/openpgp-ffi/examples/encrypt-for.c
new file mode 100644
index 00000000..ab0943ba
--- /dev/null
+++ b/openpgp-ffi/examples/encrypt-for.c
@@ -0,0 +1,96 @@
+/* This example demonstrates how to use the low-level interface to
+ encrypt a file. */
+
+#define _GNU_SOURCE
+#include <error.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <sequoia/openpgp.h>
+
+int
+main (int argc, char **argv)
+{
+ struct stat st;
+ int fd;
+ uint8_t *b;
+ sq_status_t rc;
+ sq_error_t err;
+ int use_armor = 1;
+ sq_tpk_t tpk;
+ sq_writer_t sink;
+ sq_writer_stack_t writer = NULL;
+ void *cipher = NULL;
+ size_t cipher_bytes = 0;
+
+ if (argc != 2)
+ error (1, 0, "Usage: %s <keyfile> <plain >cipher", argv[0]);
+
+ if (stat (argv[1], &st))
+ error (1, errno, "%s", argv[1]);
+
+ fd = open (argv[1], O_RDONLY);
+ if (fd == -1)
+ error (1, errno, "%s", argv[1]);
+
+ b = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ close (fd);
+ if (b == MAP_FAILED)
+ error (1, errno, "mmap");
+
+ tpk = sq_tpk_from_bytes (&err, b, st.st_size);
+ if (tpk == NULL)
+ error (1, 0, "sq_packet_parser_from_bytes: %s", sq_error_string (err));
+
+ sink = sq_writer_alloc (&cipher, &cipher_bytes);
+
+ if (use_armor)
+ sink = sq_armor_writer_new (&err, sink, SQ_ARMOR_KIND_MESSAGE,
+ NULL, 0);
+
+ writer = sq_writer_stack_message (sink);
+ writer = sq_encryptor_new (&err,
+ writer,
+ NULL, 0, /* no passwords */
+ &tpk, 1,
+ SQ_ENCRYPTION_MODE_FOR_TRANSPORT);
+ if (writer == NULL)
+ error (1, 0, "sq_encryptor_new: %s", sq_error_string (err));
+
+ writer = sq_literal_writer_new (&err, writer);
+ if (writer == NULL)
+ error (1, 0, "sq_literal_writer_new: %s", sq_error_string (err));
+
+ size_t nread;
+ uint8_t buf[4096];
+ while ((nread = fread (buf, 1, sizeof buf, stdin)))
+ {
+ uint8_t *b = buf;
+ while (nread)
+ {
+ ssize_t written;
+ written = sq_writer_stack_write (&err, writer, b, nread);
+ if (written < 0)
+ error (1, 0, "sq_writer_stack_write: %s", sq_error_string (err));
+
+ b += written;
+ nread -= written;
+ }
+ }
+
+ rc = sq_writer_stack_finalize (&err, writer);
+ writer = NULL;
+ if (rc)
+ error (1, 0, "sq_writer_stack_write: %s", sq_error_string (err));
+
+ fwrite (cipher, 1, cipher_bytes, stdout);
+
+ munmap (b, st.st_size);
+ return 0;
+}