failing FFI test

ffi
Avril 3 years ago
parent f7ea81344d
commit 6937dc5242
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -11,6 +11,19 @@ enum cc20_mode {
CC20_DECRYPT, CC20_DECRYPT,
}; };
typedef enum cc20_error {
CC20_ERR_PANIC = -1,
CC20_ERR_NONE = 0,
CC20_ERR_INVALID_FILE,
CC20_ERR_NULL_PTR,
CC20_ERR_SSL,
CC20_ERR_IO
} cc20_result_t;
#define CC20_OK(v) ((v)==CC20_ERR_NONE)
#define CC20_ERR(v) ((v)!=CC20_ERR_NONE)
typedef uint8_t cc20_key_t[KEY_SIZE]; typedef uint8_t cc20_key_t[KEY_SIZE];
typedef uint8_t cc20_iv_t[IV_SIZE]; typedef uint8_t cc20_iv_t[IV_SIZE];
@ -23,7 +36,10 @@ typedef struct cc20_metadata {
typedef struct cc20_sink cc20_sink_t; typedef struct cc20_sink cc20_sink_t;
int cc20_gen_meta(FILE* file, cc20_result_t cc20_keygen(cc20_key_t* restrict key,
cc20_iv_t* restrict iv);
cc20_result_t cc20_gen_meta(FILE* file,
const cc20_key_t* key, const cc20_key_t* key,
const cc20_iv_t* iv, const cc20_iv_t* iv,
enum cc20_mode mode, enum cc20_mode mode,
@ -43,7 +59,7 @@ FILE* cc20_wrap_full(FILE* file,
FILE* cc20_gen(const struct cc20_metadata* meta); FILE* cc20_gen(const struct cc20_metadata* meta);
int cc20_close_sink(cc20_sink_t* sink, cc20_result_t cc20_close_sink(cc20_sink_t* sink,
struct cc20_metadata* restrict meta); struct cc20_metadata* restrict meta);
FILE* cc20_wrap_sink(cc20_sink_t* sink); FILE* cc20_wrap_sink(cc20_sink_t* sink);

@ -58,6 +58,20 @@ mod cookie;
mod error; mod error;
pub use error::*; pub use error::*;
#[no_mangle] pub unsafe extern "C" fn cc20_keygen(key: *mut Key, iv: *mut IV) -> CErr
{
no_unwind!(ref {
if !key.is_null() {
*key = Key::new();
}
if !iv.is_null() {
*iv = IV::new();
}
CErr::Success
}).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, size: usize, nmemb: usize, sink: *mut CSink) -> usize
{ {
let mut output: usize = 0; let mut output: usize = 0;
@ -79,14 +93,22 @@ pub use error::*;
output output
} }
#[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) -> i32 #[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
{ {
no_unwind!({ no_unwind!({
if file.is_null() { if file.is_null() {
return CErr::InvalidFile; return CErr::InvalidFile;
} }
let key = nullchk!(move key); let key = if key.is_null() {
let iv = nullchk!(move iv); Key::new()
} else {
*key
};
let iv = if iv.is_null() {
IV::new()
} else {
*iv
};
let write = CPassthrough { let write = CPassthrough {
backing: file, backing: file,
key, key,
@ -96,7 +118,7 @@ pub use error::*;
nullchk!(output); nullchk!(output);
output.write(write); output.write(write);
CErr::Success CErr::Success
}).unwrap_or(CErr::Panic).into() }).unwrap_or(CErr::Panic)
} }
/// Create an encrypting `Sink` over a `FILE*` from this metadata struct. /// Create an encrypting `Sink` over a `FILE*` from this metadata struct.
@ -121,8 +143,8 @@ pub use error::*;
let meta = { let meta = {
// No need to `no_unwind` this, `cc20_gen_meta` already does it, and nothing else here can panic. // 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(); 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) { match cc20_gen_meta(file, key, iv, mode, &mut meta as *mut _ as *mut CPassthrough).into() {
0 => meta.assume_init(), 0i32 => meta.assume_init(),
_ => return ptr::null_mut(), _ => return ptr::null_mut(),
} }
}; };
@ -149,7 +171,7 @@ pub use error::*;
cc20_wrap_sink(csink) cc20_wrap_sink(csink)
} }
/// Closes and frees the wrapper `sink`, and writes inner metadata struct to `meta`, if `file` is non-null. /// 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) -> i32 #[no_mangle] pub unsafe extern "C" fn cc20_close_sink(sink: *mut CSink, meta: *mut CPassthrough) -> CErr
{ {
no_unwind!({ no_unwind!({
let sink = interop::take(nullchk!(sink)); let sink = interop::take(nullchk!(sink));
@ -158,7 +180,6 @@ pub use error::*;
} }
CErr::Success CErr::Success
}).unwrap_or(CErr::Panic) }).unwrap_or(CErr::Panic)
.into()
} }
/// Convert a `Sink` into a `FILE*`. /// Convert a `Sink` into a `FILE*`.

@ -0,0 +1,26 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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)
int main(int argc, char** argv)
{
cc20_meta_t meta;
cc20_result_t res;
FILE* output = argv[1] ? fopen(argv[1], "wb") : stdout;
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; }
fprintf(output, "Hello world!");
res = CC20_ERR_NONE;
fail:
if(output) fclose(output);
return (int)res;
}

@ -0,0 +1,5 @@
#!/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
Loading…
Cancel
Save