cookie open creation

ffi
Avril 3 years ago
parent 860cf33b41
commit 9557d4e80b
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -42,6 +42,7 @@ smallvec = {version = "1.6", features=["union"], optional = true}
tokio = {version = "0.2", optional = true} tokio = {version = "0.2", optional = true}
[build-dependencies] [build-dependencies]
cc = "1.0.68"
rustc_version = "0.2" rustc_version = "0.2"
[dev-dependencies] [dev-dependencies]

@ -1,8 +1,35 @@
extern crate rustc_version; extern crate rustc_version;
extern crate cc;
use std::path::Path;
use rustc_version::{version, version_meta, Channel}; use rustc_version::{version, version_meta, Channel};
const FFI_SRC_DIR: &str = "src/ffi";
fn build_cookie_wrapper(floc: impl AsRef<Path>)
{
let mut builder = cc::Build::new();
// --std=c99 -W -Wall -Werror -pedantic -O3 -flto
builder.flag("--std=c11")
.flag("-W")
.flag("-Wall")
.flag_if_supported("-Wextra")
.flag("-Werror")
.flag("-pedantic")
.include("include/")
.opt_level(3)
.flag_if_supported("-flto")
// Not sure if we want these two. We can check the codegen later.
.pic(false)
.use_plt(false)
.file(Path::new(FFI_SRC_DIR).join(floc))
.compile("cwrapper");
}
fn main() { fn main() {
// Assert we haven't travelled back in time // Assert we haven't travelled back in time
assert!(version().unwrap().major >= 1); assert!(version().unwrap().major >= 1);
@ -22,4 +49,6 @@ fn main() {
println!("cargo:rustc-cfg=dev"); println!("cargo:rustc-cfg=dev");
} }
} }
build_cookie_wrapper("wrapper.c");
} }

@ -1,5 +1,7 @@
#ifndef _CC20_H #ifndef _CC20_H
#define _CC20_H #define _CC20_H
#include <stdint.h>
#include <stddef.h>
#define KEY_SIZE 32 #define KEY_SIZE 32
#define IV_SIZE 12 #define IV_SIZE 12
@ -12,12 +14,12 @@ enum cc20_mode {
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];
struct cc20_metadata { typedef struct cc20_metadata {
FILE* backing; FILE* backing;
cc20_key_t key; cc20_key_t key;
cc20_iv_t iv; cc20_iv_t iv;
enum cc20_mode mode; enum cc20_mode mode;
}; } cc20_meta_t;
typedef struct cc20_sink cc20_sink_t; typedef struct cc20_sink cc20_sink_t;
@ -28,14 +30,19 @@ int cc20_gen_meta(FILE* file,
struct cc20_metadata* restrict output); struct cc20_metadata* restrict output);
cc20_sink_t* cc20_gen_sink(const struct cc20_metadata* meta); cc20_sink_t* cc20_gen_sink(const struct cc20_metadata* meta);
cc20_sink_t* cc20_gen_sink_full(FILE* file, cc20_sink_t* cc20_gen_sink_full(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);
FILE* cc20_wrap(FILE* file,
FILE* cc20_wrap_full(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);
FILE* cc20_gen(const struct cc20_metadata* meta);
int cc20_close_sink(cc20_sink_t* sink, int cc20_close_sink(cc20_sink_t* sink,
struct cc20_metadata* restrict meta); struct cc20_metadata* restrict meta);

@ -53,6 +53,7 @@ pub enum CMode
} }
mod interop; mod interop;
mod cookie;
mod error; mod error;
pub use error::*; pub use error::*;
@ -127,8 +128,18 @@ pub use error::*;
}; };
cc20_gen_sink(&meta as *const _) cc20_gen_sink(&meta as *const _)
} }
#[no_mangle] pub unsafe extern "C" fn cc20_gen(meta: *const CPassthrough) -> *mut libc::FILE
{
let sink = cc20_gen_sink(meta);
if sink.is_null() {
return ptr::null_mut();
}
cc20_wrap_sink(sink)
}
/// Create a wrapper `FILE*` that acts as a `Sink` when written to. /// Create a wrapper `FILE*` that acts as a `Sink` when written to.
#[no_mangle] pub unsafe extern "C" fn cc20_wrap(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) -> *mut libc::FILE
{ {
// No need to `no_unwind` this, nothing here can panic. // No need to `no_unwind` this, nothing here can panic.
let csink = cc20_gen_sink_full(file, key, iv, mode); let csink = cc20_gen_sink_full(file, key, iv, mode);
@ -153,7 +164,8 @@ pub use error::*;
/// Convert a `Sink` into a `FILE*`. /// Convert a `Sink` into a `FILE*`.
#[no_mangle] pub unsafe extern "C" fn cc20_wrap_sink(sink: *mut CSink) -> *mut libc::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`.") //todo!("Create a Custom Stream in `wrapper.c` that allows creating a FILE* object from `sink`.")
cookie::create(sink)
} }
impl Write for CPassthrough impl Write for CPassthrough

@ -0,0 +1,12 @@
use super::*;
use libc::{c_void, FILE};
//FILE* _cc20c_create(cc20_sink_t* restrict sink)
extern "C" {
fn _cc20c_create(sink: *mut c_void) -> *mut FILE;
}
#[inline(always)] pub unsafe fn create(raw_sink: *mut CSink) -> *mut FILE
{
_cc20c_create(raw_sink as *mut c_void)
}

@ -0,0 +1,50 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cc20.h>
#define IGNORE(v) ((void)(v))
static ssize_t cc20c_read(void* cookie, char* buffer, size_t size)
{
IGNORE(cookie);
IGNORE(buffer);
IGNORE(size);
return -1;
}
static ssize_t cc20c_write(void* cookie, const char* buffer, size_t size)
{
return cc20_write(buffer, 1, size, cookie);
}
static int cc20c_seek(void* cookie, off64_t* pos, int w)
{
IGNORE(cookie);
IGNORE(pos);
IGNORE(w);
return -1;
}
static int cc20c_close(void* cookie)
{
struct cc20_metadata meta;
cc20_close_sink(cookie, &meta);
if(meta.backing) fclose(meta.backing);
else return 1;
return 0;
}
FILE* _cc20c_create(cc20_sink_t* restrict sink)
{
return fopencookie(sink, "wb", (cookie_io_functions_t){
.read = &cc20c_read,
.write = &cc20c_write,
.seek = &cc20c_seek,
.close = &cc20c_close,
});
}
Loading…
Cancel
Save