gxt_c/
lib.rs

1use std::ffi::{CStr, CString};
2use std::os::raw::c_char;
3
4const E_RUST_TO_C_STRING: &str = "Could not convert rust string to C string";
5const E_C_TO_RUST_STRING: &str = "Could not convert C string to rust string";
6
7/// Creates a new key and returns it as hex string.
8///
9/// # Safety
10/// - Returned string must be freed with [`gxt_free_string`] after use.
11///
12/// # Panics
13/// - Currently panics on error.
14#[unsafe(no_mangle)]
15pub extern "C" fn gxt_make_key() -> *mut c_char {
16    let cstr = CString::new(gxt::make_key()).expect(E_RUST_TO_C_STRING);
17    cstr.into_raw()
18}
19
20/// Creates a new id card from a key and returns it as gxt message.
21///
22/// # Safety
23/// - Returned string must be freed with [`gxt_free_string`] after use.
24///
25/// # Panics
26/// - Currently panics on error.
27#[unsafe(no_mangle)]
28pub unsafe extern "C" fn gxt_make_id_card(key: *const c_char, meta: *const c_char) -> *mut c_char {
29    let key = unsafe { CStr::from_ptr(key) };
30    let meta = unsafe { CStr::from_ptr(meta) };
31    let id = gxt::make_id_card(
32        key.to_str().expect(E_C_TO_RUST_STRING),
33        meta.to_str().expect(E_C_TO_RUST_STRING),
34    )
35    .expect("Failed to make identity");
36    let cstr = CString::new(id).expect(E_RUST_TO_C_STRING);
37    cstr.into_raw()
38}
39
40/// Verifies a message and returns the contents as JSON string on success.
41///
42/// # Safety
43/// - Returned string must be freed with [`gxt_free_string`] after use.
44///
45/// # Panics
46/// - Currently panics on error.
47#[unsafe(no_mangle)]
48pub unsafe extern "C" fn gxt_verify_message(msg: *const c_char) -> *mut c_char {
49    let msg = unsafe { CStr::from_ptr(msg) };
50    let rec = gxt::verify_message(msg.to_str().expect(E_C_TO_RUST_STRING))
51        .expect("Failed to verify message");
52    let cstr = CString::new(serde_json::to_string(&rec).expect("Could not serialize output"))
53        .expect(E_RUST_TO_C_STRING);
54    cstr.into_raw()
55}
56
57/// Encrypts the payload and returns the gxt message containing the encrypted data.
58///
59/// # Safety
60/// - Returned string must be freed with [`gxt_free_string`] after use.
61///
62/// # Panics
63/// - Currently panics on error.
64#[unsafe(no_mangle)]
65pub unsafe extern "C" fn gxt_encrypt_message(
66    key: *const c_char,
67    id_card: *const c_char,
68    body: *const c_char,
69) -> *mut c_char {
70    let key = unsafe { CStr::from_ptr(key) };
71    let id_card = unsafe { CStr::from_ptr(id_card) };
72    let body = unsafe { CStr::from_ptr(body) };
73    let msg = gxt::encrypt_message(
74        key.to_str().expect(E_C_TO_RUST_STRING),
75        id_card.to_str().expect(E_C_TO_RUST_STRING),
76        body.to_str().expect(E_C_TO_RUST_STRING),
77        None,
78    )
79    .expect("Failed to verify message");
80    let cstr = CString::new(msg).expect(E_RUST_TO_C_STRING);
81    cstr.into_raw()
82}
83
84/// Encrypts the payload and returns the gxt message containing the encrypted data and a parent reference.
85///
86/// # Safety
87/// - Returned string must be freed with [`gxt_free_string`] after use.
88///
89/// # Panics
90/// - Currently panics on error.
91#[unsafe(no_mangle)]
92pub unsafe extern "C" fn gxt_encrypt_message_with_parent(
93    key: *const c_char,
94    id_card: *const c_char,
95    body: *const c_char,
96    parent: *const c_char,
97) -> *mut c_char {
98    let key = unsafe { CStr::from_ptr(key) };
99    let id_card = unsafe { CStr::from_ptr(id_card) };
100    let body = unsafe { CStr::from_ptr(body) };
101    let parent = unsafe { CStr::from_ptr(parent) };
102    let msg = gxt::encrypt_message(
103        key.to_str().expect(E_C_TO_RUST_STRING),
104        id_card.to_str().expect(E_C_TO_RUST_STRING),
105        body.to_str().expect(E_C_TO_RUST_STRING),
106        Some(parent.to_str().expect(E_C_TO_RUST_STRING).to_string()),
107    )
108    .expect("Failed to verify message");
109    let cstr = CString::new(msg).expect(E_RUST_TO_C_STRING);
110    cstr.into_raw()
111}
112
113/// Verifies and decrypts the payload inside a gxt message and returns it as a json string.
114///
115/// # Safety
116/// - Returned string must be freed with [`gxt_free_string`] after use.
117///
118/// # Panics
119/// - Currently panics on error.
120#[unsafe(no_mangle)]
121pub unsafe extern "C" fn gxt_decrypt_message(
122    msg: *const c_char,
123    key: *const c_char,
124) -> *mut c_char {
125    let msg = unsafe { CStr::from_ptr(msg) };
126    let key = unsafe { CStr::from_ptr(key) };
127    let rec = gxt::decrypt_message(
128        msg.to_str().expect(E_C_TO_RUST_STRING),
129        key.to_str().expect(E_C_TO_RUST_STRING),
130    )
131    .expect("Failed to verify message");
132    let cstr = CString::new(serde_json::to_string(&rec).expect("Could not serialize output"))
133        .expect(E_RUST_TO_C_STRING);
134    cstr.into_raw()
135}
136
137/// This function must be used to free returned strings after they are used.
138///
139/// # Safety
140/// - Only pass strings that have been returned by rust into this function
141#[unsafe(no_mangle)]
142pub unsafe extern "C" fn gxt_free_string(s: *mut c_char) {
143    if s.is_null() {
144        return;
145    }
146    unsafe {
147        let _ = CString::from_raw(s);
148    }
149}