tests passing. static linking failing, not sure why

ffi
Avril 4 years ago
parent 65ad649519
commit e76499c166
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -24,8 +24,8 @@ fn build_cookie_wrapper(floc: impl AsRef<Path>)
.flag_if_supported("-flto")
// Not sure if we want these two. We can check the codegen later.
.pic(false)
.use_plt(false)
//.pic(false)
//.use_plt(false)
.file(Path::new(FFI_SRC_DIR).join(floc))
.compile("cwrapper");
@ -52,4 +52,6 @@ fn main() {
}
build_cookie_wrapper("wrapper.c");
//println!("cargo:rustc-link-lib={}", link);
}

@ -36,6 +36,9 @@ typedef struct cc20_metadata {
typedef struct cc20_sink cc20_sink_t;
// Functions //
#define _cc20_OUT *restrict
cc20_result_t cc20_keygen(cc20_key_t* restrict key,
cc20_iv_t* restrict iv);
@ -43,27 +46,31 @@ cc20_result_t cc20_gen_meta(FILE* file,
const cc20_key_t* key,
const cc20_iv_t* iv,
enum cc20_mode mode,
struct cc20_metadata* restrict output);
struct cc20_metadata _cc20_OUT output);
cc20_result_t cc20_gen_sink(const struct cc20_metadata* meta, cc20_sink_t* _cc20_OUT output);
cc20_sink_t* cc20_gen_sink(const struct cc20_metadata* meta);
cc20_sink_t* cc20_gen_sink_full(FILE* file,
cc20_result_t cc20_gen_sink_full(FILE* file,
const cc20_key_t* key,
const cc20_iv_t* iv,
enum cc20_mode mode);
enum cc20_mode mode,
cc20_sink_t* _cc20_OUT output);
FILE* cc20_wrap_full(FILE* file,
cc20_result_t cc20_wrap_full(FILE* file,
const cc20_key_t* key,
const cc20_iv_t* iv,
enum cc20_mode mode);
enum cc20_mode mode,
FILE* _cc20_OUT output);
FILE* cc20_gen(const struct cc20_metadata* meta);
cc20_result_t cc20_gen(const struct cc20_metadata* meta,
FILE* _cc20_OUT output);
cc20_result_t cc20_close_sink(cc20_sink_t* sink,
struct cc20_metadata* restrict meta);
FILE* cc20_wrap_sink(cc20_sink_t* sink);
size_t cc20_write(const void* ptr, size_t size, size_t nmemb, cc20_sink_t* restrict sink);
cc20_result_t cc20_write(const void* ptr, size_t * restrict bytes, cc20_sink_t* restrict sink);
#endif /* _CC20_H */

@ -61,25 +61,24 @@ pub use error::*;
}).unwrap_or(CErr::Panic)
}
#[no_mangle] pub unsafe extern "C" fn cc20_write(ptr: *const c_void, size: usize, nmemb: usize, sink: *mut CSink) -> usize
#[no_mangle] pub unsafe extern "C" fn cc20_write(ptr: *const c_void, bytes: *mut usize, sink: *mut CSink) -> CErr
{
let mut output: usize = 0;
let _er = no_unwind!(ref {
no_unwind!({
let sink = nullchk!(ref mut sink);
let bytes = size * nmemb;
let nbytes = nullchk!(move bytes);
let slice = if ptr.is_null() {
return CErr::NullPointer;
} else {
std::slice::from_raw_parts(ptr as *const u8, bytes)
std::slice::from_raw_parts(ptr as *const u8, nbytes)
};
match sink.sink.write(&slice[..]) {
Err(_) => return CErr::IO,
Ok(v) => output = v,
Ok(v) => *bytes = v,
}
CErr::Success
}).unwrap_or(CErr::Panic);
//TODO: Write `er` into an error flag for `sink` (parallel to `ferror`/`feof`).
output
})
.unwrap_or(CErr::Panic)
}
#[no_mangle] pub unsafe extern "C" fn cc20_gen_meta(file: *mut libc::FILE, key: *const Key, iv: *const IV, mode: CMode, output: *mut CPassthrough) -> CErr
@ -111,10 +110,11 @@ pub use error::*;
}
/// Create an encrypting `Sink` over a `FILE*` from this metadata struct.
#[no_mangle] pub unsafe extern "C" fn cc20_gen_sink(meta: *const CPassthrough) -> *mut CSink
#[no_mangle] pub unsafe extern "C" fn cc20_gen_sink(meta: *const CPassthrough, output: *mut *mut CSink) -> CErr
{
no_unwind!({
let meta = nullchk!(ref meta);
let output = nullchk!(ref mut output);
let sink = CSink {
sink: match meta.mode {
@ -122,42 +122,41 @@ pub use error::*;
CMode::Decrypt => Sink::decrypt(meta.clone(), meta.key, meta.iv).map_err(|_| CErr::SslError).unwrap(),
},
};
interop::give(sink)
}).unwrap_or(ptr::null_mut())
*output = interop::give(sink);
CErr::Success
}).unwrap_or(CErr::Panic)
}
/// Create an encrypting `Sink` over a `FILE*` with these options.
#[no_mangle] pub unsafe extern "C" fn cc20_gen_sink_full(file: *mut libc::FILE, key: *const Key, iv: *const IV, mode: CMode) -> *mut CSink
#[no_mangle] pub unsafe extern "C" fn cc20_gen_sink_full(file: *mut libc::FILE, key: *const Key, iv: *const IV, mode: CMode, output: *mut *mut CSink) -> CErr
{
let meta = {
// No need to `no_unwind` this, `cc20_gen_meta` already does it, and nothing else here can panic.
let mut meta: std::mem::MaybeUninit<CPassthrough> = std::mem::MaybeUninit::uninit();
match cc20_gen_meta(file, key, iv, mode, &mut meta as *mut _ as *mut CPassthrough).into() {
0i32 => meta.assume_init(),
_ => return ptr::null_mut(),
match cc20_gen_meta(file, key, iv, mode, &mut meta as *mut _ as *mut CPassthrough) {
CErr::Success => meta.assume_init(),
x => return x,
}
};
cc20_gen_sink(&meta as *const _)
cc20_gen_sink(&meta as *const _, output)
}
#[no_mangle] pub unsafe extern "C" fn cc20_gen(meta: *const CPassthrough) -> *mut libc::FILE
#[no_mangle] pub unsafe extern "C" fn cc20_gen(meta: *const CPassthrough, output: *mut *mut libc::FILE) -> CErr
{
let sink = cc20_gen_sink(meta);
if sink.is_null() {
return ptr::null_mut();
}
cc20_wrap_sink(sink)
let mut sink: *mut CSink = ptr::null_mut();
errchk!(cc20_gen_sink(meta, &mut sink as *mut *mut CSink));
*output = cc20_wrap_sink(sink);
CErr::Success
}
/// Create a wrapper `FILE*` that acts as a `Sink` when written to.
#[no_mangle] pub unsafe extern "C" fn cc20_wrap_full(file: *mut libc::FILE, key: *const Key, iv: *const IV, mode: CMode) -> *mut libc::FILE
#[no_mangle] pub unsafe extern "C" fn cc20_wrap_full(file: *mut libc::FILE, key: *const Key, iv: *const IV, mode: CMode, output: &mut *mut libc::FILE) -> CErr
{
// No need to `no_unwind` this, nothing here can panic.
let csink = cc20_gen_sink_full(file, key, iv, mode);
if csink.is_null() {
return ptr::null_mut();
}
cc20_wrap_sink(csink)
let mut csink: *mut CSink = ptr::null_mut();
errchk!(cc20_gen_sink_full(file, key, iv, mode, &mut csink as *mut *mut CSink));
*output = cc20_wrap_sink(csink);
CErr::Success
}
/// Closes and frees the wrapper `sink`, and writes inner metadata struct to `meta`, if `file` is non-null.
#[no_mangle] pub unsafe extern "C" fn cc20_close_sink(sink: *mut CSink, meta: *mut CPassthrough) -> CErr
@ -174,7 +173,9 @@ pub use error::*;
/// Convert a `Sink` into a `FILE*`.
#[no_mangle] pub unsafe extern "C" fn cc20_wrap_sink(sink: *mut CSink) -> *mut libc::FILE
{
//todo!("Create a Custom Stream in `wrapper.c` that allows creating a FILE* object from `sink`.")
if sink.is_null() {
return ptr::null_mut();
}
cookie::create(sink)
}

@ -2,6 +2,15 @@
use super::*;
#[macro_export] macro_rules! errchk {
($expr:expr) => {
match CErr::from($expr) {
CErr::Success => (),
x => return x,
}
};
}
//TODO: Rework the error handling/reporting here.
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)]
#[repr(C)]

@ -18,8 +18,9 @@ static ssize_t cc20c_read(void* cookie, char* buffer, size_t size)
static ssize_t cc20c_write(void* cookie, const char* buffer, size_t size)
{
register int c = cc20_write(buffer, 1, size, cookie);
return c < 0 ? 0 : c;
cc20_result_t res = cc20_write(buffer, &size, cookie);
IGNORE(res); // TODO: set an error flag `res` in `cookie` (i.e. `CSink`)
return (ssize_t) size;
}
static int cc20c_seek(void* cookie, off64_t* pos, int w)

@ -4,7 +4,9 @@
#include <cc20.h>
#define TRY(expr) do { if(CC20_ERR(res = (expr))) fprintf(stderr, "cc20 error %d: " #expr "\n", (int)res); goto fail; } while(0)
#define TRY(expr) do { if(CC20_ERR(res = (expr))) { fprintf(stderr, "cc20 error %d: " #expr "\n", (int)res); goto fail; } } while(0)
const char write_string[] = "Hello world?";
int main(int argc, char** argv)
{
@ -15,9 +17,11 @@ int main(int argc, char** argv)
if(!output) { perror("failed to open output"); return -1; }
TRY(cc20_gen_meta(output, NULL, NULL, CC20_ENCRYPT, &meta));
if(! (output = cc20_gen(&meta)) ) { perror("failed to open encrypted output"); fclose(meta.backing); return -1; }
TRY(cc20_gen(&meta, &output));
printf("written %lu bytes\n", fwrite(write_string, 1, strlen(write_string), output));
fprintf(output, "Hello world!");
//fprintf(output, "Hello world!");
res = CC20_ERR_NONE;
fail:

@ -1,5 +1,7 @@
#!/bin/bash
gcc test.c -Iinclude -Wall --std=gnu11 -pedantic -Wextra -O3 -o test-ffi -l:target/debug/libchacha20stream.so || exit
./test-ffi
rm -f test-ffi
gcc test.c -Iinclude -Wall --std=gnu11 -pedantic -Wextra -O3 -o test-ffi -l:target/release/libchacha20stream.so || exit
#-lssl -lcrypto -lpthread -ldl || exit
valgrind ./test-ffi test-ffi-output
hexview test-ffi-output
rm -f test-ffi{,-output}

Loading…
Cancel
Save