diff options
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-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/include/sequoia.h | 2 | ||||
-rw-r--r-- | ffi/include/sequoia/core.h | 80 | ||||
-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/tests/c-tests.rs | 1 | ||||
-rw-r--r-- | openpgp-ffi/Cargo.toml | 35 | ||||
-rw-r--r-- | openpgp-ffi/Makefile | 66 | ||||
-rw-r--r-- | openpgp-ffi/examples/.gitignore | 5 | ||||
-rw-r--r-- | openpgp-ffi/examples/Makefile | 17 | ||||
-rw-r--r-- | openpgp-ffi/examples/armor.c (renamed from ffi/examples/armor.c) | 2 | ||||
-rw-r--r-- | openpgp-ffi/examples/encrypt-for.c (renamed from ffi/examples/encrypt-for.c) | 2 | ||||
-rw-r--r-- | openpgp-ffi/examples/example.c (renamed from ffi/examples/example.c) | 2 | ||||
-rw-r--r-- | openpgp-ffi/examples/parser.c (renamed from ffi/examples/parser.c) | 2 | ||||
-rw-r--r-- | openpgp-ffi/examples/reader.c (renamed from ffi/examples/reader.c) | 2 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/io.h | 83 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp.h (renamed from ffi/include/sequoia/openpgp.h) | 7 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp/crypto.h (renamed from ffi/include/sequoia/openpgp/crypto.h) | 0 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp/error.h (renamed from ffi/include/sequoia/error.h) | 0 | ||||
-rw-r--r-- | openpgp-ffi/rustdoc.head.html | 4 | ||||
-rw-r--r-- | openpgp-ffi/sequoia-openpgp.pc.in | 11 | ||||
-rw-r--r-- | openpgp-ffi/src/armor.rs (renamed from ffi/src/openpgp/armor.rs) | 4 | ||||
-rw-r--r-- | openpgp-ffi/src/common.rs (renamed from ffi/src/openpgp/mod.rs) | 264 | ||||
-rw-r--r-- | openpgp-ffi/src/crypto.rs (renamed from ffi/src/openpgp/crypto.rs) | 0 | ||||
-rw-r--r-- | openpgp-ffi/src/error.rs | 173 | ||||
-rw-r--r-- | openpgp-ffi/src/fingerprint.rs (renamed from ffi/src/openpgp/fingerprint.rs) | 0 | ||||
-rw-r--r-- | openpgp-ffi/src/io.rs | 175 | ||||
-rw-r--r-- | openpgp-ffi/src/keyid.rs (renamed from ffi/src/openpgp/keyid.rs) | 2 | ||||
-rw-r--r-- | openpgp-ffi/src/lib.rs | 118 | ||||
-rw-r--r-- | openpgp-ffi/src/mod.rs | 0 | ||||
-rw-r--r-- | openpgp-ffi/src/packet_pile.rs (renamed from ffi/src/openpgp/packet_pile.rs) | 0 | ||||
-rw-r--r-- | openpgp-ffi/src/tpk.rs (renamed from ffi/src/openpgp/tpk.rs) | 6 | ||||
-rw-r--r-- | openpgp-ffi/src/tsk.rs (renamed from ffi/src/openpgp/tsk.rs) | 0 | ||||
-rw-r--r-- | openpgp-ffi/tests/c-tests.rs | 303 |
41 files changed, 1292 insertions, 642 deletions
@@ -24,6 +24,7 @@ maintenance = { status = "actively-developed" } [dependencies] buffered-reader = { path = "buffered-reader", version = "0.3.0" } sequoia-openpgp = { path = "openpgp", version = "0.3.0" } +sequoia-openpgp-ffi = { path = "openpgp-ffi", version = "0.3.0" } sequoia-core = { path = "core", version = "0.3.0" } sequoia-ffi = { path = "ffi", version = "0.3.0" } sequoia-ffi-macros = { path = "ffi-macros", version = "0.3.0" } @@ -66,7 +66,9 @@ doc: $(CARGO) doc $(CARGO_FLAGS) --no-deps --all env RUSTDOCFLAGS="$(FFI_RUSTDOCFLAGS)" \ CARGO_TARGET_DIR=$(CARGO_TARGET_DIR) \ - $(CARGO) doc $(CARGO_FLAGS) --no-deps --package sequoia-ffi + $(CARGO) doc $(CARGO_FLAGS) --no-deps \ + --package sequoia-ffi \ + --package sequoia-openpgp-ffi .PHONY: deploy-doc deploy-doc: doc 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/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/lang/python/Makefile b/ffi/lang/python/Makefile index e73d3bd0..78a9481e 100644 --- a/ffi/lang/python/Makefile +++ b/ffi/lang/python/Makefile @@ -3,7 +3,7 @@ # Configuration. PREFIX ?= /usr/local DESTDIR ?= -CFLAGS += -I../../include +CFLAGS += -I../../include -I../../../openpgp-ffi/include # Tools. PYTHON ?= python3 diff --git a/ffi/lang/python/sequoia/sequoia_build.py b/ffi/lang/python/sequoia/sequoia_build.py index 07dd5bb6..ea0ad9df 100644 --- a/ffi/lang/python/sequoia/sequoia_build.py +++ b/ffi/lang/python/sequoia/sequoia_build.py @@ -2,14 +2,16 @@ from os.path import join, dirname from cffi import FFI, error from itertools import chain -inc = join(dirname(__file__), '../../../include/sequoia') +sq_inc = join(dirname(__file__), '../../../include/sequoia') +pgp_inc = join(dirname(__file__), '../../../../openpgp-ffi/include/sequoia') defs = "".join(l - for l in chain(open(join(inc, "error.h")).readlines(), - open(join(inc, "core.h")).readlines(), - open(join(inc, "openpgp/crypto.h")).readlines(), - open(join(inc, "openpgp.h")).readlines(), - open(join(inc, "net.h")).readlines(), - open(join(inc, "store.h")).readlines()) + for l in chain(open(join(pgp_inc, "openpgp/error.h")).readlines(), + open(join(pgp_inc, "io.h")).readlines(), + open(join(pgp_inc, "openpgp/crypto.h")).readlines(), + open(join(pgp_inc, "openpgp.h")).readlines(), + open(join(sq_inc, "core.h")).readlines(), + open(join(sq_inc, "net.h")).readlines(), + open(join(sq_inc, "store.h")).readlines()) if not l.startswith('#')) defs = defs.replace("INT_MAX", "{}".format(1<<31)) diff --git a/ffi/src/core.rs b/ffi/src/core.rs index 915dcffc..f644dc4b 100644 --- a/ffi/src/core.rs +++ b/ffi/src/core.rs @@ -39,15 +39,8 @@ //! ``` use failure; -use std::fs::File; -use std::io::{self, Read, Write, Cursor}; -use std::path::Path; use std::ptr; -use std::slice; -use libc::{uint8_t, c_void, c_char, c_int, size_t, ssize_t, realloc}; - -#[cfg(unix)] -use std::os::unix::io::FromRawFd; +use libc::{uint8_t, c_char, c_int}; use sequoia_core as core; use sequoia_core::Config; @@ -225,169 +218,3 @@ pub extern "system" fn sq_config_ephemeral(cfg: *mut Config) { let cfg = ffi_param_ref_mut!(cfg); cfg.set_ephemeral(); } - -/* Reader and writer. */ - -/// Opens a file returning a reader. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_reader_from_file(errp: Option<&mut *mut failure::Error>, - filename: *const c_char) - -> *mut Box<Read> { - ffi_make_fry_from_errp!(errp); - let filename = ffi_param_cstr!(filename).to_string_lossy().into_owned(); - ffi_try_box!(File::open(Path::new(&filename)) - .map(|r| Box::new(r)) - .map_err(|e| e.into())) -} - -/// Opens a file descriptor returning a reader. -#[cfg(unix)] -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_reader_from_fd(fd: c_int) - -> *mut Box<Read> { - box_raw!(Box::new(unsafe { File::from_raw_fd(fd) })) -} - -/// Creates a reader from a buffer. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_reader_from_bytes(buf: *const uint8_t, - len: size_t) - -> *mut Box<Read> { - assert!(!buf.is_null()); - let buf = unsafe { - slice::from_raw_parts(buf, len as usize) - }; - box_raw!(Box::new(Cursor::new(buf))) -} - -/// Frees a reader. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_reader_free(reader: Option<&mut Box<Read>>) { - ffi_free!(reader) -} - -/// Reads up to `len` bytes into `buf`. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_reader_read(errp: Option<&mut *mut failure::Error>, - reader: *mut Box<Read>, - buf: *mut uint8_t, len: size_t) - -> ssize_t { - ffi_make_fry_from_errp!(errp); - let reader = ffi_param_ref_mut!(reader); - assert!(!buf.is_null()); - let buf = unsafe { - slice::from_raw_parts_mut(buf, len as usize) - }; - ffi_try_or!(reader.read(buf).map_err(|e| e.into()), -1) as ssize_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`. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_from_file(errp: Option<&mut *mut failure::Error>, - filename: *const c_char) - -> *mut Box<Write> { - ffi_make_fry_from_errp!(errp); - let filename = ffi_param_cstr!(filename).to_string_lossy().into_owned(); - ffi_try_box!(File::create(Path::new(&filename)) - .map(|r| Box::new(r)) - .map_err(|e| e.into())) -} - -/// Opens a file descriptor returning a writer. -#[cfg(unix)] -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_from_fd(fd: c_int) - -> *mut Box<Write> { - box_raw!(Box::new(unsafe { File::from_raw_fd(fd) })) -} - -/// Creates a writer from a buffer. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_from_bytes(buf: *mut uint8_t, - len: size_t) - -> *mut Box<Write> { - assert!(!buf.is_null()); - let buf = unsafe { - slice::from_raw_parts_mut(buf, len as usize) - }; - box_raw!(Box::new(Cursor::new(buf))) -} - -/// 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. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_alloc(buf: *mut *mut c_void, - len: *mut size_t) - -> *mut Box<Write> { - let buf = ffi_param_ref_mut!(buf); - let len = ffi_param_ref_mut!(len); - - box_raw!(Box::new(WriterAlloc { - buf: buf, - len: len, - })) -} - -struct WriterAlloc { - buf: &'static mut *mut c_void, - len: &'static mut size_t, -} - -impl Write for WriterAlloc { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - let old_len = *self.len; - let new_len = old_len + buf.len(); - - let new = unsafe { - realloc(*self.buf, new_len) - }; - if new.is_null() { - return Err(io::Error::new(io::ErrorKind::Other, "out of memory")); - } - - *self.buf = new; - *self.len = new_len; - - let sl = unsafe { - slice::from_raw_parts_mut(new as *mut u8, new_len) - }; - &mut sl[old_len..].copy_from_slice(buf); - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - // Do nothing. - Ok(()) - } -} - -/// Frees a writer. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_free(writer: Option<&mut Box<Write>>) { - ffi_free!(writer) -} - -/// Writes up to `len` bytes of `buf` into `writer`. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_writer_write(errp: Option<&mut *mut failure::Error>, - writer: *mut Box<Write>, - buf: *const uint8_t, len: size_t) - -> ssize_t { - ffi_make_fry_from_errp!(errp); - let writer = ffi_param_ref_mut!(writer); - assert!(!buf.is_null()); - let buf = unsafe { - slice::from_raw_parts(buf, len as usize) - }; - ffi_try_or!(writer.write(buf).map_err(|e| e.into()), -1) as ssize_t -} diff --git a/ffi/src/error.rs b/ffi/src/error.rs index 369cbb25..d9fb2c21 100644 --- a/ffi/src/error.rs +++ b/ffi/src/error.rs @@ -2,125 +2,17 @@ use failure; use std::io; -use libc::c_char; extern crate sequoia_openpgp as openpgp; use sequoia_core as core; +pub use openpgp::error::Status; -/// Frees an error. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_error_free(error: Option<&mut failure::Error>) { - ffi_free!(error) +trait FromSequoiaError<'a> { + fn from_sequoia_error(&'a failure::Error) -> Status; } -/// Returns the error message. -/// -/// The returned value must be freed with `free(3)`. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_error_string(error: *const failure::Error) - -> *mut c_char { - let error = ffi_param_ref!(error); - ffi_return_string!(&format!("{}", error)) -} - -/// Returns the error status code. -#[::ffi_catch_abort] #[no_mangle] -pub extern "system" fn sq_error_status(error: *const failure::Error) - -> Status { - let error = ffi_param_ref!(error); - error.into() -} - -/// XXX: Reorder and name-space before release. -#[derive(PartialEq, Debug)] -#[repr(C)] -pub enum Status { - /// The operation was successful. - Success = 0, - - /// An unknown error occurred. - UnknownError = -1, - - /// The network policy was violated by the given action. - NetworkPolicyViolation = -2, - - /// An IO error occurred. - IoError = -3, - - /// A given argument is invalid. - InvalidArgument = -15, - - /// The requested operation is invalid. - InvalidOperation = -4, - - /// The packet is malformed. - MalformedPacket = -5, - - /// Unsupported hash algorithm. - UnsupportedHashAlgorithm = -9, - - /// Unsupported public key algorithm. - UnsupportedPublicKeyAlgorithm = -18, - - /// Unsupported elliptic curve. - UnsupportedEllipticCurve = -21, - - /// Unsupported symmetric algorithm. - UnsupportedSymmetricAlgorithm = -10, - - /// Unsupported AEAD algorithm. - UnsupportedAEADAlgorithm = -26, - - /// Unsupport signature type. - UnsupportedSignatureType = -20, - - /// Invalid password. - InvalidPassword = -11, - - /// Invalid session key. - InvalidSessionKey = -12, - - /// Missing session key. - MissingSessionKey = -27, - - /// Malformed TPK. - MalformedTPK = -13, - - // XXX: -14 was UserIDNotFound. - - // XXX: Skipping InvalidArgument = -15. - - /// Malformed MPI. - MalformedMPI = -16, - - // XXX: Skipping UnknownPublicKeyAlgorithm = -17. - // XXX: Skipping UnsupportedPublicKeyAlgorithm = -18 - - /// Bad signature. - BadSignature = -19, - - /// Message has been manipulated. - ManipulatedMessage = -25, - - // XXX: Skipping UnsupportedSignatureType = -20 - // XXX: Skipping UnsupportedEllipticCurve = -21 - - /// Malformed message. - MalformedMessage = -22, - - /// Index out of range. - IndexOutOfRange = -23, - - /// TPK not supported. - UnsupportedTPK = -24, - - // XXX: Skipping ManipulatedMessage = -25 - // XXX: Skipping UnsupportedAEADAlgorithm = -26 - // XXX: Skipping MissingSessionKey = -27 -} - -impl<'a> From<&'a failure::Error> for Status { - fn from(e: &'a failure::Error) -> Self { +impl<'a> FromSequoiaError<'a> for Status { + fn from_sequoia_error(e: &'a failure::Error) -> Self { if let Some(e) = e.downcast_ref::<core::Error>() { return match e { &core::Error::NetworkPolicyViolation(_) => diff -- |