diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2018-07-20 15:30:38 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2018-07-20 17:41:55 +0200 |
commit | c344e85d2439b0ed1c4eb00640da911e904a7c60 (patch) | |
tree | 7c8e4a69f7e20c95176a117e128b718ba85e0b36 /ffi/examples | |
parent | 60754f9338e2913ddff0f16b1c6ad3626b0d9cfd (diff) |
ffi: New example.
Diffstat (limited to 'ffi/examples')
-rw-r--r-- | ffi/examples/Makefile | 2 | ||||
-rw-r--r-- | ffi/examples/encrypt-for.c | 116 |
2 files changed, 117 insertions, 1 deletions
diff --git a/ffi/examples/Makefile b/ffi/examples/Makefile index 5638d5f8..3b7b6794 100644 --- a/ffi/examples/Makefile +++ b/ffi/examples/Makefile @@ -1,6 +1,6 @@ # Makefile for examples written in C. -TARGETS = example keyserver configure reader parser +TARGETS = example keyserver configure reader parser encrypt-for CFLAGS = -I../include -O0 -g -Wall LDFLAGS = -L../../target/debug -lsequoia_ffi diff --git a/ffi/examples/encrypt-for.c b/ffi/examples/encrypt-for.c new file mode 100644 index 00000000..637585d4 --- /dev/null +++ b/ffi/examples/encrypt-for.c @@ -0,0 +1,116 @@ +/* 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.h> + +int +main (int argc, char **argv) +{ + struct stat st; + int fd; + uint8_t *b; + sq_status_t rc; + sq_error_t err; + sq_context_t ctx; + 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]); + + ctx = sq_context_new ("org.sequoia-pgp.example", &err); + if (ctx == NULL) + error (1, 0, "Initializing sequoia failed: %s", + sq_error_string (err)); + + 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 (ctx, b, st.st_size); + if (tpk == NULL) + { + err = sq_context_last_error (ctx); + 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 (sink, SQ_ARMOR_KIND_MESSAGE); + + writer = sq_writer_stack_wrap (sink); + writer = sq_encryptor_new (ctx, + writer, + NULL, 0, /* no passwords */ + &tpk, 1, + SQ_ENCRYPTION_MODE_FOR_TRANSPORT); + if (writer == NULL) + { + err = sq_context_last_error (ctx); + error (1, 0, "sq_encryptor_new: %s", sq_error_string (err)); + } + + writer = sq_literal_writer_new (ctx, writer); + if (writer == NULL) + { + err = sq_context_last_error (ctx); + 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 (ctx, writer, b, nread); + if (written < 0) + { + err = sq_context_last_error (ctx); + error (1, 0, "sq_writer_stack_write: %s", sq_error_string (err)); + } + b += written; + nread -= written; + } + } + + rc = sq_writer_stack_finalize (ctx, writer); + writer = NULL; + if (rc) + { + err = sq_context_last_error (ctx); + error (1, 0, "sq_writer_stack_write: %s", sq_error_string (err)); + } + + fwrite (cipher, 1, cipher_bytes, stdout); + + sq_context_free (ctx); + munmap (b, st.st_size); + return 0; +} |