From 32ca4ddc4cb3a347fabed22aa09eb4dd3f256197 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 23 Feb 2022 12:24:30 +0100 Subject: [PATCH] Initial C API --- dgc/Cargo.toml | 4 +++ dgc/cbindgen.toml | 9 +++++ dgc/src/capi.rs | 83 +++++++++++++++++++++++++++++++++++++++++++++++ dgc/src/lib.rs | 4 +++ 4 files changed, 100 insertions(+) create mode 100644 dgc/cbindgen.toml create mode 100644 dgc/src/capi.rs diff --git a/dgc/Cargo.toml b/dgc/Cargo.toml index 2b8615d..8b28a62 100644 --- a/dgc/Cargo.toml +++ b/dgc/Cargo.toml @@ -10,6 +10,9 @@ repository = "https://github.com/rust-italia/dgc" readme = "README.md" license = "MIT" +[features] +capi = ["libc"] + [dependencies] base45 = "3.0.0" base64 = "0.13.0" @@ -22,6 +25,7 @@ serde = "1.0.130" serde_json = "1.0.64" thiserror = "1.0.30" x509-parser = { version = "0.12.0", features = ["verify"] } +libc = { version = "0.2", optional = true } [dev-dependencies] hex = "0.4.3" diff --git a/dgc/cbindgen.toml b/dgc/cbindgen.toml new file mode 100644 index 0000000..0c2ebd8 --- /dev/null +++ b/dgc/cbindgen.toml @@ -0,0 +1,9 @@ +include_guard = "DGC_H" +include_version = true +language = "C" +cpp_compat = true + +[export.rename] +"ParseError" = "DgcParseError" +"SignatureValidity" = "DgcValidity" +"TrustList" = "DgcTrustList" diff --git a/dgc/src/capi.rs b/dgc/src/capi.rs new file mode 100644 index 0000000..6196706 --- /dev/null +++ b/dgc/src/capi.rs @@ -0,0 +1,83 @@ +use crate::{DgcContainer, ParseError, SignatureValidity, TrustList}; + +/// Decodes the certificate and returns the [`DgcContainer`] data contained in it. +/// +/// This function is recommended when you don't want to validate the signature but you +/// are just interested in reading the content of the certificate. +#[no_mangle] +pub extern "C" fn dgc_decode( + data: *const u8, + len: usize, + container: *mut *mut DgcContainer, +) -> *const ParseError { + todo!() +} + +#[no_mangle] +pub extern "C" fn dgc_container_free(container: *mut *mut DgcContainer) { + todo!() +} + +#[no_mangle] +pub extern "C" fn dgc_trustlist_new() -> *mut TrustList { + todo!() +} + +#[no_mangle] +pub extern "C" fn dgc_trustlist_default() -> *mut TrustList { + todo!() +} + +#[no_mangle] +pub extern "C" fn dgc_trustlist_add_from_certificate( + list: *mut TrustList, + cert: *mut u8, + len: usize, +) -> bool { + todo!() +} + +#[no_mangle] +pub extern "C" fn dgc_trustlist_free(list: *mut *mut TrustList) { + todo!() +} + +/// Parses and validates a given certificate. +/// +/// This function is a high level helper that allows you to extract the data from a +/// certificate and at the same time it tries to validate the signature against a given +/// trustlist. +/// +/// This function will return an error if the certificate cannot be parsed or is invalid. +/// If the certificate can be parsed correctly, this function returns a tuple containing a +/// [`DgcContainer`] and a [`SignatureValidity`]. +/// +/// This design allows for permissive validation of the certificate signature. +/// In fact, `SignatureValidity` can be used to determine if the signature is valid and even if it is +/// invalid (or the validity cannot be assessed) you could still access all the information +/// in the certificate. +#[no_mangle] +pub extern "C" fn dgc_validate( + data: *const u8, + len: usize, + trustlist: *const TrustList, + container: *mut *mut DgcContainer, + validity: *mut *mut SignatureValidity, +) -> *const ParseError { + todo!() +} + +#[no_mangle] +pub extern "C" fn dgc_signature_is_valid(error: *const SignatureValidity) -> bool { + todo!() +} + +#[no_mangle] +pub extern "C" fn dgc_container_to_json(container: *const DgcContainer) -> *mut u8 { + todo!() +} + +#[no_mangle] +pub extern "C" fn dgc_json_free(json: *mut *mut u8) { + todo!() +} diff --git a/dgc/src/lib.rs b/dgc/src/lib.rs index a3e88be..448f534 100644 --- a/dgc/src/lib.rs +++ b/dgc/src/lib.rs @@ -10,6 +10,10 @@ mod test; mod trustlist; mod vaccination; mod valuesets; + +#[cfg(feature = "capi")] +mod capi; + pub use crate::dgc::*; pub use cwt::*; pub use dgc_container::*;