diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-01-17 11:11:27 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-01-17 16:48:28 +0100 |
commit | 3f58832474a4b270e136544016a401ef773ac065 (patch) | |
tree | c617160250c3040ca964c1b72ab5957cd872b82f /ffi | |
parent | 38b4108cc1eac851ac17932c5c33623dd535bebb (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 'ffi')
-rw-r--r-- | ffi/Cargo.toml | 1 | ||||
-rw-r--r-- | ffi/examples/.gitignore | 5 | ||||
-rw-r--r-- | ffi/examples/Makefile | 4 | ||||
-rw-r--r-- | ffi/examples/armor.c | 60 | ||||
-rw-r--r-- | ffi/examples/encrypt-for.c | 96 | ||||
-rw-r--r-- | ffi/examples/example.c | 45 | ||||
-rw-r--r-- | ffi/examples/parser.c | 93 | ||||
-rw-r--r-- | ffi/examples/reader.c | 48 | ||||
-rw-r--r-- | ffi/include/sequoia.h | 2 | ||||
-rw-r--r-- | ffi/include/sequoia/core.h | 80 | ||||
-rw-r--r-- | ffi/include/sequoia/error.h | 147 | ||||
-rw-r--r-- | ffi/include/sequoia/openpgp.h | 1658 | ||||
-rw-r--r-- | ffi/include/sequoia/openpgp/crypto.h | 50 | ||||
-rw-r--r-- | ffi/lang/python/Makefile | 2 | ||||
-rw-r--r-- | ffi/lang/python/sequoia/sequoia_build.py | 16 | ||||
-rw-r--r-- | ffi/src/core.rs | 175 | ||||
-rw-r--r-- | ffi/src/error.rs | 118 | ||||
-rw-r--r-- | ffi/src/lib.rs | 242 | ||||
-rw-r--r-- | ffi/src/openpgp/armor.rs | 347 | ||||
-rw-r--r-- | ffi/src/openpgp/crypto.rs | 54 | ||||
-rw-r--r-- | ffi/src/openpgp/fingerprint.rs | 110 | ||||
-rw-r--r-- | ffi/src/openpgp/keyid.rs | 99 | ||||
-rw-r--r-- | ffi/src/openpgp/mod.rs | 1637 | ||||
-rw-r--r-- | ffi/src/openpgp/packet_pile.rs | 93 | ||||
-rw-r--r-- | ffi/src/openpgp/tpk.rs | 698 | ||||
-rw-r--r-- | ffi/src/openpgp/tsk.rs | 76 | ||||
-rw-r--r-- | ffi/tests/c-tests.rs | 1 |
27 files changed, 31 insertions, 5926 deletions
diff --git a/ffi/Cargo.toml b/ffi/Cargo.toml index 80059a09..3e158d0c 100644 --- a/ffi/Cargo.toml +++ b/ffi/Cargo.toml @@ -23,6 +23,7 @@ maintenance = { status = "actively-developed" } [dependencies] sequoia-ffi-macros = { path = "../ffi-macros" } sequoia-openpgp = { path = "../openpgp" } +sequoia-openpgp-ffi = { path = "../openpgp-ffi" } sequoia-core = { path = "../core" } sequoia-store = { path = "../store" } sequoia-net = { path = "../net" } diff --git a/ffi/examples/.gitignore b/ffi/examples/.gitignore index 17a9b656..e72a3164 100644 --- a/ffi/examples/.gitignore +++ b/ffi/examples/.gitignore @@ -1,7 +1,2 @@ configure -example keyserver -reader -parser -encrypt-for -armor diff --git a/ffi/examples/Makefile b/ffi/examples/Makefile index 4ca01078..a8d2baa1 100644 --- a/ffi/examples/Makefile +++ b/ffi/examples/Makefile @@ -5,8 +5,8 @@ CARGO_TARGET_DIR ?= $(shell pwd)/../../target # We currently only support absolute paths. CARGO_TARGET_DIR := $(abspath $(CARGO_TARGET_DIR)) -TARGETS = example keyserver configure reader parser encrypt-for armor -CFLAGS = -I../include -O0 -g -Wall -Werror +TARGETS = keyserver configure +CFLAGS = -I../include -I../../openpgp-ffi/include -O0 -g -Wall -Werror LDFLAGS = -L$(CARGO_TARGET_DIR)/debug -lsequoia_ffi all: $(TARGETS) diff --git a/ffi/examples/armor.c b/ffi/examples/armor.c deleted file mode 100644 index 5a1b9339..00000000 --- a/ffi/examples/armor.c +++ /dev/null @@ -1,60 +0,0 @@ -#define _GNU_SOURCE -#include <assert.h> -#include <error.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <sequoia.h> - -const char *armored = - "-----BEGIN PGP ARMORED FILE-----\n" - "Key0: Value0\n" - "Key1: Value1\n" - "\n" - "SGVsbG8gd29ybGQh\n" - "=s4Gu\n" - "-----END PGP ARMORED FILE-----\n"; - -int -main (int argc, char **argv) -{ - sq_error_t err; - sq_reader_t bytes; - sq_reader_t armor; - sq_armor_kind_t kind; - char message[12]; - sq_armor_header_t *header; - size_t header_len; - - bytes = sq_reader_from_bytes ((uint8_t *) armored, strlen (armored)); - armor = sq_armor_reader_new (bytes, SQ_ARMOR_KIND_ANY); - - header = sq_armor_reader_headers (&err, armor, &header_len); - if (header == NULL) - error (1, 0, "Getting headers failed: %s", sq_error_string (err)); - - assert (header_len == 2); - assert (strcmp (header[0].key, "Key0") == 0 - && strcmp (header[0].value, "Value0") == 0); - assert (strcmp (header[1].key, "Key1") == 0 - && strcmp (header[1].value, "Value1") == 0); - for (size_t i = 0; i < header_len; i++) - { - free (header[i].key); - free (header[i].value); - } - free (header); - - kind = sq_armor_reader_kind (armor); - assert (kind == SQ_ARMOR_KIND_FILE); - - if (sq_reader_read (&err, armor, (uint8_t *) message, 12) < 0) - error (1, 0, "Reading failed: %s", sq_error_string (err)); - - assert (memcmp (message, "Hello world!", 12) == 0); - - sq_reader_free (armor); - sq_reader_free (bytes); - return 0; -} diff --git a/ffi/examples/encrypt-for.c b/ffi/examples/encrypt-for.c deleted file mode 100644 index f0c34449..00000000 --- a/ffi/examples/encrypt-for.c +++ /dev/null @@ -1,96 +0,0 @@ -/* 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; - 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; -} diff --git a/ffi/examples/example.c b/ffi/examples/example.c deleted file mode 100644 index 8636d011..00000000 --- a/ffi/examples/example.c +++ /dev/null @@ -1,45 +0,0 @@ -#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 <sequoia.h> - -int -main (int argc, char **argv) -{ - struct stat st; - int fd; - uint8_t *b; - sq_error_t err; - sq_tpk_t tpk; - - if (argc != 2) - error (1, 0, "Usage: %s <file>", 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); - 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_tpk_from_bytes: %s", sq_error_string (err)); - - sq_tpk_dump (tpk); - sq_tpk_free (tpk); - munmap (b, st.st_size); - close (fd); - return 0; -} diff --git a/ffi/examples/parser.c b/ffi/examples/parser.c deleted file mode 100644 index 8d953422..00000000 --- a/ffi/examples/parser.c +++ /dev/null @@ -1,93 +0,0 @@ -/* This example demonstrates how to use the packet parser from C. It - * also serves as a simple benchmark. */ - -#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_packet_parser_result_t ppr; - sq_packet_parser_t pp; - - if (argc != 2) - error (1, 0, "Usage: %s <file>", 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"); - - size_t n = 0; - time_t start = time (NULL); - time_t elapsed; - size_t tens_of_s = 0; - - ppr = sq_packet_parser_from_bytes (&err, b, st.st_size); - while (ppr && (pp = sq_packet_parser_result_packet_parser (ppr))) - { - // Get a reference to the packet that is currently being parsed. - sq_packet_t p = sq_packet_parser_packet (pp); - - if (sq_packet_tag(p) == SQ_TAG_LITERAL) - { - // Stream the packet here. - } - - // Finish parsing the current packet (returned in p), and read - // the header of the next packet (returned in ppr). - rc = sq_packet_parser_next (&err, pp, &p, &ppr); - if (rc) - error (1, 0, "sq_packet_parser_from_bytes: %s", - sq_error_string (err)); - - // We now own p. If we want, we can save it in some structure. - // This would be useful when collecting PKESK packets. Either - // way, we need to free it when we are done. - - n += 1; - - sq_packet_free (p); - - elapsed = time (NULL) - start; - if (elapsed % 10 == 0 && tens_of_s != elapsed / 10) - { - fprintf (stderr, - "Parsed %ld packets in %ld seconds, %.2f packets/s.\n", - n, elapsed, (double) n / (double) elapsed); - fflush (stderr); - tens_of_s = elapsed / 10; - } - } - if (ppr == NULL) - error (1, 0, "sq_packet_parser_from_bytes: %s", sq_error_string (err)); - - fprintf (stderr, "Parsed %ld packets in %ld seconds, %.2f packets/s.\n", - n, elapsed, (double) n / (double) elapsed); - - sq_packet_parser_result_free (ppr); - munmap (b, st.st_size); - return 0; -} diff --git a/ffi/examples/reader.c b/ffi/examples/reader.c deleted file mode 100644 index 8e458620..00000000 --- a/ffi/examples/reader.c +++ /dev/null @@ -1,48 +0,0 @@ -#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 <sequoia.h> - -int -main (int argc, char **argv) -{ - struct stat st; - int fd; - uint8_t *b; - sq_error_t err; - sq_reader_t reader; - sq_tpk_t tpk; - - if (argc != 2) - error (1, 0, "Usage: %s <file>", 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); - if (b == MAP_FAILED) - error (1, errno, "mmap"); - - reader = sq_reader_from_bytes (b, st.st_size); - tpk = sq_tpk_from_reader (&err, reader); - if (tpk == NULL) - error (1, 0, "sq_tpk_from_reader: %s", sq_error_string (err)); - - sq_tpk_dump (tpk); - sq_tpk_free (tpk); - sq_reader_free (reader); - munmap (b, st.st_size); - close (fd); - return 0; -} diff --git a/ffi/include/sequoia.h b/ffi/include/sequoia.h index 485b8cc3..8c62ba8f 100644 --- a/ffi/include/sequoia.h +++ b/ffi/include/sequoia.h @@ -1,7 +1,7 @@ #ifndef SEQUOIA_H #define SEQUOIA_H -#include <sequoia/error.h> +#include <sequoia/openpgp/error.h> #include <sequoia/core.h> #include <sequoia/openpgp.h> #include <sequoia/net.h> diff --git a/ffi/include/sequoia/core.h b/ffi/include/sequoia/core.h index 9d7d261b..0d2ea3cd 100644 --- a/ffi/include/sequoia/core.h +++ b/ffi/include/sequoia/core.h @@ -218,84 +218,4 @@ void sq_config_ipc_policy(sq_config_t cfg, sq_ipc_policy_t policy); /*/ void sq_config_ephemeral(sq_config_t cfg); - -/* Reader and writer. */ - -/*/ -/// A generic reader. -/*/ -typedef struct sq_reader *sq_reader_t; - -/*/ -/// Opens a file returning a reader. -/*/ -sq_reader_t sq_reader_from_file (sq_error_t *errp, const char *filename); - -/*/ -/// Opens a file descriptor returning a reader. -/*/ -sq_reader_t sq_reader_from_fd (int fd); - -/*/ -/// Creates a reader from a buffer. -/*/ -sq_reader_t sq_reader_from_bytes (const uint8_t *buf, size_t len); - -/*/ -/// Frees a reader. -/*/ -void sq_reader_free (sq_reader_t reader); - -/*/ -/// Reads up to `len` bytes into `buf`. -/*/ -ssize_t sq_reader_read (sq_error_t *errp, sq_reader_t reader, - uint8_t *buf, size_t len); - -/*/ -/// A generic writer. -/*/ -typedef struct sq_writer *sq_writer_t; - -/*/ -/// Opens a file returning a writer. -/// -/// The file will be created if it does not exist, or be truncated -/// otherwise. If you need more control, use `sq_writer_from_fd`. -/*/ -sq_writer_t sq_writer_from_file (sq_error_t *errp, const char *filename); - -/*/ -/// Opens a file descriptor returning a writer. -/*/ -sq_writer_t sq_writer_from_fd (int fd); - -/*/ -/// Creates a writer from a buffer. -/*/ -sq_writer_t sq_writer_from_bytes (uint8_t *buf, size_t len); - -/*/ -/// Creates an allocating writer. -/// -/// This writer allocates memory using `malloc`, and stores the -/// pointer to the memory and the number of bytes written to the given -/// locations `buf`, and `len`. Both must either be set to zero, or -/// reference a chunk of memory allocated using libc's heap allocator. -/// The caller is responsible to `free` it once the writer has been -/// destroyed. -/*/ -sq_writer_t sq_writer_alloc (void **buf, size_t *len); - -/*/ -/// Frees a writer. -/*/ -void sq_writer_free (sq_writer_t writer); - -/*/ -/// Writes up to `len` bytes of `buf` into `writer`. -/*/ -ssize_t sq_writer_write (sq_error_t *errp, sq_writer_t writer, - const uint8_t *buf, size_t len); - #endif diff --git a/ffi/include/sequoia/error.h b/ffi/include/sequoia/error.h deleted file mode 100644 index dd42753c..00000000 --- a/ffi/include/sequoia/error.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef SEQUOIA_ERRORS_H -#define SEQUOIA_ERRORS_H - -#include <stddef.h> -#include <stdint.h> -#include <limits.h> - -/* XXX: Reorder and name-space before release. */ -typedef enum sq_status { - /*/ - /// The operation was successful. - /*/ - SQ_STATUS_SUCCESS = 0, - - /*/ - /// An unknown error occurred. - /*/ - SQ_STATUS_UNKNOWN_ERROR = -1, - - /*/ - /// The network policy was violated by the given action. - /*/ - SQ_STATUS_NETWORK_POLICY_VIOLATION = -2, - - /*/ - /// An IO error occurred. - /*/ - SQ_STATUS_IO_ERROR = -3, - - /*/ - /// A given argument is invalid. - /*/ - SQ_STATUS_INVALID_ARGUMENT = -15, - - /*/ - /// The requested operation is invalid. - /*/ - SQ_STATUS_INVALID_OPERATION = -4, - - /*/ - /// The packet is malformed. - /*/ - SQ_STATUS_MALFORMED_PACKET = -5, - - /*/ - /// Unsupported hash algorithm. - /*/ - SQ_STATUS_UNSUPPORTED_HASH_ALGORITHM = -9, - - /*/ - /// Unsupported public key algorithm. - /*/ - SQ_STATUS_UNSUPPORTED_PUBLICKEY_ALGORITHM = -18, - - /*/ - /// Unsupported elliptic curve. - /*/ - SQ_STATUS_UNSUPPORTED_ELLIPTIC_CURVE = -21, - - /*/ - /// Unsupported symmetric algorithm. - /*/ - SQ_STATUS_UNSUPPORTED_SYMMETRIC_ALGORITHM = -10, - - /*/ - /// Unsupported AEAD algorithm. - /*/ - SQ_STATUS_UNSUPPORTED_AEAD_ALGORITHM = -26, - - /*/ - /// Unsupport signature type. - /*/ - SQ_STATUS_UNSUPPORTED_SIGNATURE_TYPE = -20, - - /*/ - /// Invalid password. - /*/ - SQ_STATUS_INVALID_PASSWORD = -11, - - /*/ - /// Invalid session key. - /*/ - SQ_STATUS_INVALID_SESSION_KEY = -12, - - /*/ - /// Missing session key. - /*/ - SQ_STATUS_MISSING_SESSION_KEY = -27, - - /*/ - /// Malformed TPK. - /*/ - SQ_STATUS_MALFORMED_TPK = -13, - - /*/ - /// Bad signature. - /*/ - SQ_STATUS_BAD_SIGNATURE = -19, - - /*/ - /// Message has been manipulated. - /*/ - SQ_STATUS_MANIPULATED_MESSAGE = -25, - - /*/ - /// Malformed message. - /*/ - SQ_STATUS_MALFORMED_MESSAGE = -22, - - /*/ - /// Index out of range. - /*/ - SQ_STATUS_INDEX_OUT_OF_RANGE = -23, - - /*/ - /// TPK not supported. - /*/ - SQ_STATUS_UNSUPPORTED_TPK = -24, - - /* Dummy value to make sure the enumeration has a defined size. Do - not use this value. */ - SQ_STATUS_FORCE_WIDTH = INT_MAX, -} sq_status_t; - -/*/ -/// Complex errors returned from Sequoia. -/*/ -typedef struct sq_error *sq_error_t; - -/*/ -/// Frees an error. -/*/ -void sq_error_free (sq_error_t error); - -/*/ -/// Returns the error message. -/// -/// The returned value must be freed with `free(3)`. -/*/ -char *sq_error_string (const sq_error_t err); - -/*/ -/// Returns the error status code. -/*/ -sq_status_t sq_error_status (const sq_error_t err); - -#endif diff --git a/ffi/include/sequoia/openpgp.h b/ffi/include/sequoia/openpgp.h deleted file mode 100644 index 2632a58a..00000000 --- a/ffi/include/sequoia/openpgp.h +++ /dev/null @@ -1,1658 +0,0 @@ -#ifndef SEQUOIA_OPENPGP_H -#define SEQUOIA_OPENPGP_H - -#include <sequoia/core.h> -#include <time.h> - -#include <sequoia/openpgp/crypto.h> - -/*/ -/// A low-level OpenPGP message parser. -/// -/// A `PacketParser` provides a low-level, iterator-like interface to -/// parse OpenPGP messages. -/// -/// For each iteration, the user is presented with a [`Packet`] -/// corresponding to the last packet, a `PacketParser` for the next -/// packet, and their positions within the message. -/// -/// Using the `PacketParser`, the user is able to configure how the -/// new packet will be parsed. For instance, it is possible to stream -/// the packet's contents (a `PacketParser` implements the -/// `std::io::Read` and the `BufferedReader` traits), buffer them -/// within the [`Packet`], or drop them. The user can also decide to -/// recurse into the packet, if it is a container, instead of getting -/// the following packet. -/*/ -typedef struct sq_packet_parser *sq_packet_parser_t; - -/*/ -/// Like an `Option<PacketParser>`, but the `None` variant -/// (`PacketParserEOF`) contains some summary information. -/*/ -typedef struct sq_packet_parser_result *sq_packet_parser_result_t; - -/*/ -/// The `None` variant of a `PacketParserResult`. -/*/ -typedef struct sq_packet_parser_eof *sq_packet_parser_eof_t; - -/* sequoia::openpgp::KeyID. */ - -/*/ -/// Holds a KeyID. -/*/ -typedef struct |