refactor: extract cert generation to core/
CI / format (push) Has been cancelled
CI / test (push) Has been cancelled
CI / packaging (push) Has been cancelled

This commit is contained in:
Tien Do Nam
2026-07-30 13:53:22 +02:00
parent 83e666c723
commit fb17512bdc
19 changed files with 414 additions and 223 deletions
+37 -3
View File
@@ -255,6 +255,15 @@ dependencies = [
"serde",
]
[[package]]
name = "bit-vec"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -666,7 +675,7 @@ dependencies = [
"portable-atomic",
"rand 0.9.5",
"rand_core 0.6.4",
"rcgen",
"rcgen 0.13.2",
"ring",
"rustls",
"sec1",
@@ -1477,6 +1486,7 @@ dependencies = [
"pem",
"percent-encoding",
"rand 0.9.5",
"rcgen 0.14.8",
"reqwest",
"rsa",
"rustls",
@@ -2005,7 +2015,21 @@ dependencies = [
"rustls-pki-types",
"time",
"x509-parser 0.16.0",
"yasna",
"yasna 0.5.2",
]
[[package]]
name = "rcgen"
version = "0.14.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57f6d249aad744e274e682777a50283a225a32705394ee6d5fcc01efa25e4055"
dependencies = [
"pem",
"ring",
"rustls-pki-types",
"time",
"x509-parser 0.18.1",
"yasna 0.6.0",
]
[[package]]
@@ -3194,7 +3218,7 @@ dependencies = [
"log",
"portable-atomic",
"rand 0.9.5",
"rcgen",
"rcgen 0.13.2",
"regex",
"ring",
"rtcp",
@@ -3630,6 +3654,16 @@ dependencies = [
"time",
]
[[package]]
name = "yasna"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5f6765e852b9b4dc8e2a76843e4d64d1cea8e79bcde0b6901aea8e7c7f08282"
dependencies = [
"bit-vec",
"time",
]
[[package]]
name = "yoke"
version = "0.8.3"
@@ -20,6 +20,26 @@ pub struct KeyPair {
pub public_key: String,
}
/// Generates a new device identity: an RSA-2048 key pair and a self-signed
/// certificate whose SHA-256 fingerprint identifies the device.
pub fn generate_security_context() -> anyhow::Result<SecurityContext> {
let cert = localsend::crypto::cert::generate_self_signed()?;
Ok(SecurityContext {
private_key: cert.private_key_pem,
public_key: cert.public_key_pem,
certificate: cert.certificate_pem,
certificate_hash: cert.fingerprint,
})
}
pub struct SecurityContext {
pub private_key: String,
pub public_key: String,
pub certificate: String,
pub certificate_hash: String,
}
/// Computes the SHA-256 checksum of a file, encoded as lowercase hex.
///
/// The file is read chunk by chunk, so it is never fully loaded into memory.
@@ -44,7 +44,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
default_rust_auto_opaque = RustAutoOpaqueMoi,
);
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.12.0";
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1795427439;
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -286605518;
// Section: executor
@@ -2638,6 +2638,40 @@ fn wire__crate__api__crypto__generate_key_pair_impl(
},
)
}
fn wire__crate__api__crypto__generate_security_context_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "generate_security_context",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
deserializer.end();
move |context| {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || {
let output_ok = crate::api::crypto::generate_security_context()?;
Ok(output_ok)
})(),
)
}
},
)
}
fn wire__crate__api__crypto__hash_file_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
@@ -4262,6 +4296,22 @@ impl SseDecode for crate::api::webrtc::RTCStatus {
}
}
impl SseDecode for crate::api::crypto::SecurityContext {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_privateKey = <String>::sse_decode(deserializer);
let mut var_publicKey = <String>::sse_decode(deserializer);
let mut var_certificate = <String>::sse_decode(deserializer);
let mut var_certificateHash = <String>::sse_decode(deserializer);
return crate::api::crypto::SecurityContext {
private_key: var_privateKey,
public_key: var_publicKey,
certificate: var_certificate,
certificate_hash: var_certificateHash,
};
}
}
impl SseDecode for crate::api::server::SessionEndReasonV2 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -4622,10 +4672,16 @@ fn pde_ffi_dispatcher_primary_impl(
wire__crate__api__logging__enable_debug_logging_impl(port, ptr, rust_vec_len, data_len)
}
44 => wire__crate__api__crypto__generate_key_pair_impl(port, ptr, rust_vec_len, data_len),
45 => wire__crate__api__crypto__hash_file_impl(port, ptr, rust_vec_len, data_len),
46 => wire__crate__api__multicast__start_multicast_impl(port, ptr, rust_vec_len, data_len),
47 => wire__crate__api__server__start_server_impl(port, ptr, rust_vec_len, data_len),
48 => wire__crate__api__crypto__verify_cert_impl(port, ptr, rust_vec_len, data_len),
45 => wire__crate__api__crypto__generate_security_context_impl(
port,
ptr,
rust_vec_len,
data_len,
),
46 => wire__crate__api__crypto__hash_file_impl(port, ptr, rust_vec_len, data_len),
47 => wire__crate__api__multicast__start_multicast_impl(port, ptr, rust_vec_len, data_len),
48 => wire__crate__api__server__start_server_impl(port, ptr, rust_vec_len, data_len),
49 => wire__crate__api__crypto__verify_cert_impl(port, ptr, rust_vec_len, data_len),
_ => unreachable!(),
}
}
@@ -5516,6 +5572,29 @@ impl flutter_rust_bridge::IntoIntoDart<FrbWrapper<crate::api::webrtc::RTCStatus>
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::api::crypto::SecurityContext {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.private_key.into_into_dart().into_dart(),
self.public_key.into_into_dart().into_dart(),
self.certificate.into_into_dart().into_dart(),
self.certificate_hash.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::api::crypto::SecurityContext
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::api::crypto::SecurityContext>
for crate::api::crypto::SecurityContext
{
fn into_into_dart(self) -> crate::api::crypto::SecurityContext {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for FrbWrapper<crate::api::server::SessionEndReasonV2> {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
match self.0 {
@@ -6669,6 +6748,16 @@ impl SseEncode for crate::api::webrtc::RTCStatus {
}
}
impl SseEncode for crate::api::crypto::SecurityContext {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(self.private_key, serializer);
<String>::sse_encode(self.public_key, serializer);
<String>::sse_encode(self.certificate, serializer);
<String>::sse_encode(self.certificate_hash, serializer);
}
}
impl SseEncode for crate::api::server::SessionEndReasonV2 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {