diff --git a/Cargo.lock b/Cargo.lock index 17e48e0..8e22028 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -260,7 +260,6 @@ dependencies = [ "hkdf", "rand 0.9.3", "rand_core 0.6.4", - "safer-ffi", "serde", "storage", "tempfile", diff --git a/core/double-ratchets/Cargo.toml b/core/double-ratchets/Cargo.toml index 747718b..4d9ea08 100644 --- a/core/double-ratchets/Cargo.toml +++ b/core/double-ratchets/Cargo.toml @@ -6,10 +6,6 @@ edition = "2024" [lib] crate-type = ["rlib", "cdylib"] -[[bin]] -name = "generate-headers" -required-features = ["headers"] - [dependencies] x25519-dalek = { version="2.0.1", features=["static_secrets"] } chacha20poly1305 = "0.10.1" @@ -18,14 +14,10 @@ rand = "0.9.3" hkdf = "0.12.4" thiserror = "2" blake2 = "0.10.6" -safer-ffi = "0.1.13" zeroize = "1.8.2" storage = { workspace = true } serde = "1.0" -[features] -headers = ["safer-ffi/headers"] - [dev-dependencies] sqlite = { package = "chat-sqlite", path = "../sqlite" } tempfile = "3" diff --git a/core/double-ratchets/ffi-nim-example/ffi_nim_example.nimble b/core/double-ratchets/ffi-nim-example/ffi_nim_example.nimble deleted file mode 100644 index a89d2a5..0000000 --- a/core/double-ratchets/ffi-nim-example/ffi_nim_example.nimble +++ /dev/null @@ -1,13 +0,0 @@ -# Package - -version = "0.1.0" -author = "kaichaosun" -description = "A new awesome nimble package" -license = "MIT" -srcDir = "src" -bin = @["ffi_nim_example"] - - -# Dependencies - -requires "nim >= 2.2.4" diff --git a/core/double-ratchets/ffi-nim-example/src/ffi_nim_example.nim b/core/double-ratchets/ffi-nim-example/src/ffi_nim_example.nim deleted file mode 100644 index 2437c43..0000000 --- a/core/double-ratchets/ffi-nim-example/src/ffi_nim_example.nim +++ /dev/null @@ -1,144 +0,0 @@ -when defined(macosx): - {.passL: "-Wl,-rpath,@executable_path/../../target/release".} -when defined(linux): - {.passL: "-Wl,-rpath,'$ORIGIN/../../target/release'".} - -# Portable dynlib name with override capability (-d:RLN_LIB:"...") -when defined(macosx): - const DR_LIB* {.strdefine.} = "libdouble_ratchets.dylib" -elif defined(linux): - const DR_LIB* {.strdefine.} = "libdouble_ratchets.so" -elif defined(windows): - const DR_LIB* {.strdefine.} = "double_ratchets.dll" -else: - const DR_LIB* {.strdefine.} = "double_ratchets" - -type FFIRatchetState* = object - -type FFIEncryptResult* = object - -type FFIInstallationKeyPair* = object - -type CSize* = csize_t - -type Vec_uint8* = object - dataPtr*: ptr uint8 - len*: CSize - cap*: CSize - -type Array_uint8_32* {.bycopy.} = object - idx*: array[32, uint8] - -type CResult_Vec_uint8_Vec_uint8* {.bycopy.} = object ## - ok*: Vec_uint8 - err*: Vec_uint8 - -proc double_ratchet_init_receiver*( - shared_secret: Array_uint8_32, keypair: ptr FFIInstallationKeyPair -): ptr FFIRatchetState {.importc, dynlib: DR_LIB.} - -proc double_ratchet_init_sender*( - shared_secret: Array_uint8_32, remote_pub: Array_uint8_32 -): ptr FFIRatchetState {.importc, dynlib: DR_LIB.} - -proc double_ratchet_encrypt_message*( - state: ptr FFIRatchetState, plaintext: ptr Vec_uint8 -): ptr FFIEncryptResult {.importc, dynlib: DR_LIB.} - -proc double_ratchet_descrypt_message*( - state: ptr FFIRatchetState, encrypted: ptr FFIEncryptResult -): CResult_Vec_uint8_Vec_uint8 {.importc, dynlib: DR_LIB.} - -proc ratchet_state_destroy*(state: ptr FFIRatchetState) {.importc, dynlib: DR_LIB.} - -proc encrypt_result_destroy*(result: ptr FFIEncryptResult) {.importc, dynlib: DR_LIB.} - -proc installation_key_pair_generate*(): ptr FFIInstallationKeyPair {. - importc, dynlib: DR_LIB -.} - -proc installation_key_pair_public*( - keypair: ptr FFIInstallationKeyPair -): Array_uint8_32 {.importc, dynlib: DR_LIB.} - -proc installation_key_pair_destroy*( - keypair: ptr FFIInstallationKeyPair -) {.importc, dynlib: DR_LIB.} - -proc ffi_c_string_free*(s: Vec_uint8) {.importc, cdecl, dynlib: DR_LIB.} - -proc asString*(v: Vec_uint8): string = - if v.dataPtr.isNil or v.len == 0: - return "" - result = newString(v.len.int) - copyMem(addr result[0], v.dataPtr, v.len.int) - -when isMainModule: - echo("start run") - - # === Shared secret (like X3DH) === - var sharedSecret: Array_uint8_32 - for i in 0 .. 31: - sharedSecret.idx[i] = 42'u8 - - # === Bob generates DH keypair === - let bobKey = installation_key_pair_generate() - let bobPub = installation_key_pair_public(bobKey) - echo("bob public key:", bobPub) - - # === Alice initializes as sender === - let alice = double_ratchet_init_sender(sharedSecret, bobPub) - # # === Bob initializes as receiver === - let bob = double_ratchet_init_receiver(sharedSecret, bobKey) - - # # === Alice sends message to Bob === - var msg1: array[3, uint8] = [11'u8, 12, 13] - var msg1Vec = Vec_uint8( - dataPtr: cast[ptr uint8](addr msg1[0]), len: CSize(msg1.len), cap: CSize(msg1.len) - ) - - let enc1 = double_ratchet_encrypt_message(alice, addr msg1Vec) - let dec1 = double_ratchet_descrypt_message(bob, enc1) - - encrypt_result_destroy(enc1) - - if dec1.err.dataPtr != nil: - echo "Bob failed to decrypt: ", asString(dec1.err) - ffi_c_string_free(dec1.err) - ratchet_state_destroy(alice) - ratchet_state_destroy(bob) - installation_key_pair_destroy(bobKey) - quit 1 - let res1 = dec1.ok - var plaintext1: array[3, uint8] - copyMem(addr plaintext1[0], res1.dataPtr, res1.len.int) - echo "Bob received: ", plaintext1 - - # # === Bob replies (triggers DH ratchet) === - var msg2: array[3, uint8] = [1'u8, 2, 3] - var msg2Vec = Vec_uint8( - dataPtr: cast[ptr uint8](addr msg2[0]), len: CSize(msg1.len), cap: CSize(msg1.len) - ) - let enc2 = double_ratchet_encrypt_message(bob, addr msg2Vec) - let dec2 = double_ratchet_descrypt_message(alice, enc2) - - encrypt_result_destroy(enc2) - - if dec2.err.dataPtr != nil: - echo "Alice failed to decrypt: ", asString(dec2.err) - ffi_c_string_free(dec2.err) - ratchet_state_destroy(alice) - ratchet_state_destroy(bob) - installation_key_pair_destroy(bobKey) - quit 1 - let res2 = dec2.ok - var plaintext2: array[3, uint8] - copyMem(addr plaintext2[0], res2.dataPtr, res2.len.int) - echo "Alice received: ", plaintext2 - - # # === Cleanup === - ratchet_state_destroy(alice) - ratchet_state_destroy(bob) - installation_key_pair_destroy(bobKey) - - echo("==end==\n") diff --git a/core/double-ratchets/src/bin/generate-headers.rs b/core/double-ratchets/src/bin/generate-headers.rs deleted file mode 100644 index 4c853ea..0000000 --- a/core/double-ratchets/src/bin/generate-headers.rs +++ /dev/null @@ -1,5 +0,0 @@ -use double_ratchets::ffi; - -fn main() -> std::io::Result<()> { - ffi::generate_headers() -} diff --git a/core/double-ratchets/src/ffi/doubleratchet.rs b/core/double-ratchets/src/ffi/doubleratchet.rs deleted file mode 100644 index e09cebd..0000000 --- a/core/double-ratchets/src/ffi/doubleratchet.rs +++ /dev/null @@ -1,81 +0,0 @@ -use safer_ffi::prelude::*; -use x25519_dalek::PublicKey; - -use crate::{ - Header, RatchetState, - ffi::{key::FFIInstallationKeyPair, utils::CResult}, -}; - -#[derive_ReprC] -#[repr(opaque)] -pub struct FFIRatchetState(pub(crate) RatchetState); - -#[derive_ReprC] -#[repr(opaque)] -pub struct FFIEncryptResult { - pub ciphertext: Vec, - pub header: Header, -} - -#[ffi_export] -fn double_ratchet_init_sender( - shared_secret: [u8; 32], - remote_pub: [u8; 32], -) -> repr_c::Box { - let state = RatchetState::init_sender(shared_secret, PublicKey::from(remote_pub)); - Box::new(FFIRatchetState(state)).into() -} - -#[ffi_export] -fn double_ratchet_init_receiver( - shared_secret: [u8; 32], - keypair: &FFIInstallationKeyPair, -) -> repr_c::Box { - let state = RatchetState::init_receiver(shared_secret, keypair.0.clone()); - Box::new(FFIRatchetState(state)).into() -} - -#[ffi_export] -fn double_ratchet_encrypt_message( - state: &mut FFIRatchetState, - plaintext: &repr_c::Vec, -) -> repr_c::Box { - let encrypted = state.0.encrypt_message(plaintext); - let result = FFIEncryptResult { - ciphertext: encrypted.0, - header: encrypted.1, - }; - Box::new(result).into() -} - -//TODO rename decrypt -#[ffi_export] -fn double_ratchet_descrypt_message( - state: &mut FFIRatchetState, - encrypted: &FFIEncryptResult, -) -> CResult, repr_c::String> { - let decrypted = state - .0 - .decrypt_message(&encrypted.ciphertext, encrypted.header.clone()); - - match decrypted { - Ok(plaintext) => CResult { - ok: Some(plaintext.into()), - err: None, - }, - Err(err) => CResult { - ok: None, - err: Some(err.to_string().into()), - }, - } -} - -#[ffi_export] -fn ratchet_state_destroy(state: repr_c::Box) { - drop(state) -} - -#[ffi_export] -fn encrypt_result_destroy(result: repr_c::Box) { - drop(result) -} diff --git a/core/double-ratchets/src/ffi/key.rs b/core/double-ratchets/src/ffi/key.rs deleted file mode 100644 index ee8a496..0000000 --- a/core/double-ratchets/src/ffi/key.rs +++ /dev/null @@ -1,22 +0,0 @@ -use safer_ffi::prelude::*; - -use crate::InstallationKeyPair; - -#[derive_ReprC] -#[repr(opaque)] -pub struct FFIInstallationKeyPair(pub(crate) InstallationKeyPair); - -#[ffi_export] -fn installation_key_pair_generate() -> repr_c::Box { - Box::new(FFIInstallationKeyPair(InstallationKeyPair::generate())).into() -} - -#[ffi_export] -fn installation_key_pair_public(keypair: &FFIInstallationKeyPair) -> [u8; 32] { - keypair.0.public().clone().to_bytes() -} - -#[ffi_export] -fn installation_key_pair_destroy(keypair: repr_c::Box) { - drop(keypair) -} diff --git a/core/double-ratchets/src/ffi/mod.rs b/core/double-ratchets/src/ffi/mod.rs deleted file mode 100644 index f67b19a..0000000 --- a/core/double-ratchets/src/ffi/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod doubleratchet; -pub mod key; -pub mod utils; - -#[cfg(feature = "headers")] -pub fn generate_headers() -> std::io::Result<()> { - safer_ffi::headers::builder() - .to_file("double_ratchet.h")? - .generate() -} diff --git a/core/double-ratchets/src/ffi/utils.rs b/core/double-ratchets/src/ffi/utils.rs deleted file mode 100644 index f50033f..0000000 --- a/core/double-ratchets/src/ffi/utils.rs +++ /dev/null @@ -1,13 +0,0 @@ -use safer_ffi::prelude::*; - -#[derive_ReprC] -#[repr(C)] -pub struct CResult { - pub ok: Option, - pub err: Option, -} - -#[ffi_export] -pub fn ffi_c_string_free(s: repr_c::String) { - drop(s); -} diff --git a/core/double-ratchets/src/lib.rs b/core/double-ratchets/src/lib.rs index b8778fc..b04cb77 100644 --- a/core/double-ratchets/src/lib.rs +++ b/core/double-ratchets/src/lib.rs @@ -1,6 +1,5 @@ pub mod aead; pub mod errors; -pub mod ffi; pub mod hkdf; pub mod keypair; pub mod reader; @@ -11,5 +10,5 @@ pub mod types; pub use keypair::InstallationKeyPair; pub use state::{Header, RatchetState, SkippedKey}; pub use storage::{ - RatchetSession, SessionError, restore_ratchet_state, to_ratchet_record, to_skipped_key_records, + restore_ratchet_state, to_ratchet_record, to_skipped_key_records, RatchetSession, SessionError, };