summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--Cargo.toml1
-rw-r--r--Makefile4
-rw-r--r--ffi/Cargo.toml1
-rw-r--r--ffi/examples/.gitignore5
-rw-r--r--ffi/examples/Makefile4
-rw-r--r--ffi/include/sequoia.h2
-rw-r--r--ffi/include/sequoia/core.h80
-rw-r--r--ffi/lang/python/Makefile2
-rw-r--r--ffi/lang/python/sequoia/sequoia_build.py16
-rw-r--r--ffi/src/core.rs175
-rw-r--r--ffi/src/error.rs118
-rw-r--r--ffi/src/lib.rs242
-rw-r--r--ffi/tests/c-tests.rs1
-rw-r--r--openpgp-ffi/Cargo.toml35
-rw-r--r--openpgp-ffi/Makefile66
-rw-r--r--openpgp-ffi/examples/.gitignore5
-rw-r--r--openpgp-ffi/examples/Makefile17
-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.h83
-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.html4
-rw-r--r--openpgp-ffi/sequoia-openpgp.pc.in11
-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.rs173
-rw-r--r--openpgp-ffi/src/fingerprint.rs (renamed from ffi/src/openpgp/fingerprint.rs)0
-rw-r--r--openpgp-ffi/src/io.rs175
-rw-r--r--openpgp-ffi/src/keyid.rs (renamed from ffi/src/openpgp/keyid.rs)2
-rw-r--r--openpgp-ffi/src/lib.rs118
-rw-r--r--openpgp-ffi/src/mod.rs0
-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.rs303
41 files changed, 1292 insertions, 642 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 24442b0b..a330a5f8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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" }
diff --git a/Makefile b/Makefile
index 134ded7b..6d83e0e5 100644
--- a/Makefile
+++ b/Makefile
@@ -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.