Skip to content

Commit

Permalink
Merge pull request #285 from whisperfish/aci-pni
Browse files Browse the repository at this point in the history
Implement PNI
  • Loading branch information
rubdos committed Mar 29, 2024
2 parents c072491 + 4255520 commit 93c23cf
Show file tree
Hide file tree
Showing 18 changed files with 1,080 additions and 281 deletions.
1 change: 1 addition & 0 deletions libsignal-service-actix/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ async-trait = "0.1"
phonenumber = "0.3"

[dev-dependencies]
chrono = "0.4"
image = { version = "0.23", default-features = false, features = ["png"] }
opener = "0.5"
qrcode = "0.12"
Expand Down
18 changes: 15 additions & 3 deletions libsignal-service-actix/examples/registering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ use libsignal_service::push_service::{
AccountAttributes, DeviceCapabilities, PushService, RegistrationMethod,
VerificationTransport,
};
use libsignal_service::USER_AGENT;
use libsignal_service::{AccountManager, USER_AGENT};
use libsignal_service_actix::prelude::AwcPushService;
use rand::RngCore;
use structopt::StructOpt;

#[path = "../../libsignal-service/examples/storage.rs"]
mod storage;

#[actix_rt::main]
async fn main() -> Result<(), Error> {
let client = "libsignal-service-hyper-example";
Expand Down Expand Up @@ -136,8 +139,15 @@ async fn main() -> Result<(), Error> {
rand::thread_rng().fill_bytes(&mut profile_key);
let profile_key = ProfileKey::create(profile_key);
let skip_device_transfer = false;
let _registration_data = push_service
.submit_registration_request(

// Create the prekeys storage
let mut aci_store = storage::ExampleStore::new();
let mut pni_store = storage::ExampleStore::new();

let mut account_manager = AccountManager::new(push_service, None);
let _registration_data = account_manager
.register_account(
&mut rand::thread_rng(),
RegistrationMethod::SessionId(&session.id),
AccountAttributes {
signaling_key: Some(signaling_key.to_vec()),
Expand All @@ -156,6 +166,8 @@ async fn main() -> Result<(), Error> {
name: Some("libsignal-service-hyper test".into()),
capabilities: DeviceCapabilities::default(),
},
&mut aci_store,
&mut pni_store,
skip_device_transfer,
)
.await;
Expand Down
1 change: 1 addition & 0 deletions libsignal-service-hyper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ tokio-rustls = "0.25"
rustls-pemfile = "2.0"

[dev-dependencies]
chrono = "0.4"
rand = "0.8"
tokio = { version = "1.0", features = ["rt-multi-thread"] }

Expand Down
18 changes: 15 additions & 3 deletions libsignal-service-hyper/examples/registering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ use libsignal_service::push_service::{
AccountAttributes, DeviceCapabilities, PushService, RegistrationMethod,
VerificationTransport,
};
use libsignal_service::USER_AGENT;
use libsignal_service::{AccountManager, USER_AGENT};

use libsignal_service_hyper::prelude::HyperPushService;

use rand::RngCore;

#[path = "../../libsignal-service/examples/storage.rs"]
mod storage;

#[tokio::main]
async fn main() {
let client = "libsignal-service-hyper-example";
Expand Down Expand Up @@ -104,8 +107,15 @@ async fn main() {
rand::thread_rng().fill_bytes(&mut profile_key);
let profile_key = ProfileKey::create(profile_key);
let skip_device_transfer = false;
let _registration_data = push_service
.submit_registration_request(

// Create the prekeys storage
let mut aci_store = storage::ExampleStore::new();
let mut pni_store = storage::ExampleStore::new();

let mut account_manager = AccountManager::new(push_service, None);
let _registration_data = account_manager
.register_account(
&mut rand::thread_rng(),
RegistrationMethod::SessionId(&session.id),
AccountAttributes {
signaling_key: Some(signaling_key.to_vec()),
Expand All @@ -124,6 +134,8 @@ async fn main() {
name: Some("libsignal-service-hyper test".into()),
capabilities: DeviceCapabilities::default(),
},
&mut aci_store,
&mut pni_store,
skip_device_transfer,
)
.await;
Expand Down
235 changes: 235 additions & 0 deletions libsignal-service/examples/storage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
use libsignal_service::pre_keys::{PreKeysStore, ServiceKyberPreKeyStore};
use libsignal_service::protocol::{
Direction, IdentityKey, IdentityKeyPair, IdentityKeyStore, KyberPreKeyId,
KyberPreKeyRecord, KyberPreKeyStore, PreKeyId, PreKeyRecord, PreKeyStore,
ProtocolAddress, SignalProtocolError, SignedPreKeyId, SignedPreKeyRecord,
SignedPreKeyStore,
};

pub struct ExampleStore {}

impl ExampleStore {
pub fn new() -> Self {
Self {}
}
}

#[async_trait::async_trait(?Send)]
impl PreKeyStore for ExampleStore {
/// Look up the pre-key corresponding to `prekey_id`.
async fn get_pre_key(
&self,
_prekey_id: PreKeyId,
) -> Result<PreKeyRecord, SignalProtocolError> {
todo!()
}

/// Set the entry for `prekey_id` to the value of `record`.
async fn save_pre_key(
&mut self,
_prekey_id: PreKeyId,
_record: &PreKeyRecord,
) -> Result<(), SignalProtocolError> {
todo!()
}

/// Remove the entry for `prekey_id`.
async fn remove_pre_key(
&mut self,
_prekey_id: PreKeyId,
) -> Result<(), SignalProtocolError> {
todo!()
}
}

#[async_trait::async_trait(?Send)]
impl KyberPreKeyStore for ExampleStore {
/// Look up the signed kyber pre-key corresponding to `kyber_prekey_id`.
async fn get_kyber_pre_key(
&self,
_kyber_prekey_id: KyberPreKeyId,
) -> Result<KyberPreKeyRecord, SignalProtocolError> {
todo!()
}

/// Set the entry for `kyber_prekey_id` to the value of `record`.
async fn save_kyber_pre_key(
&mut self,
_kyber_prekey_id: KyberPreKeyId,
_record: &KyberPreKeyRecord,
) -> Result<(), SignalProtocolError> {
todo!()
}

/// Mark the entry for `kyber_prekey_id` as "used".
/// This would mean different things for one-time and last-resort Kyber keys.
async fn mark_kyber_pre_key_used(
&mut self,
_kyber_prekey_id: KyberPreKeyId,
) -> Result<(), SignalProtocolError> {
todo!()
}
}

#[async_trait::async_trait(?Send)]
impl SignedPreKeyStore for ExampleStore {
/// Look up the signed pre-key corresponding to `signed_prekey_id`.
async fn get_signed_pre_key(
&self,
_signed_prekey_id: SignedPreKeyId,
) -> Result<SignedPreKeyRecord, SignalProtocolError> {
todo!()
}

/// Set the entry for `signed_prekey_id` to the value of `record`.
async fn save_signed_pre_key(
&mut self,
_signed_prekey_id: SignedPreKeyId,
_record: &SignedPreKeyRecord,
) -> Result<(), SignalProtocolError> {
todo!()
}
}

#[async_trait::async_trait(?Send)]
impl ServiceKyberPreKeyStore for ExampleStore {
async fn store_last_resort_kyber_pre_key(
&mut self,
_kyber_prekey_id: KyberPreKeyId,
_record: &KyberPreKeyRecord,
) -> Result<(), SignalProtocolError> {
todo!()
}

async fn load_last_resort_kyber_pre_keys(
&self,
) -> Result<Vec<KyberPreKeyRecord>, SignalProtocolError> {
todo!()
}

async fn remove_kyber_pre_key(
&mut self,
_kyber_prekey_id: KyberPreKeyId,
) -> Result<(), SignalProtocolError> {
todo!()
}

/// Analogous to markAllOneTimeKyberPreKeysStaleIfNecessary
async fn mark_all_one_time_kyber_pre_keys_stale_if_necessary(
&mut self,
_stale_time: chrono::DateTime<chrono::Utc>,
) -> Result<(), SignalProtocolError> {
todo!()
}

/// Analogue of deleteAllStaleOneTimeKyberPreKeys
async fn delete_all_stale_one_time_kyber_pre_keys(
&mut self,
_threshold: chrono::DateTime<chrono::Utc>,
_min_count: usize,
) -> Result<(), SignalProtocolError> {
todo!()
}
}

#[async_trait::async_trait(?Send)]
impl IdentityKeyStore for ExampleStore {
/// Return the single specific identity the store is assumed to represent, with private key.
async fn get_identity_key_pair(
&self,
) -> Result<IdentityKeyPair, SignalProtocolError> {
todo!()
}

/// Return a [u32] specific to this store instance.
///
/// This local registration id is separate from the per-device identifier used in
/// [ProtocolAddress] and should not change run over run.
///
/// If the same *device* is unregistered, then registers again, the [ProtocolAddress::device_id]
/// may be the same, but the store registration id returned by this method should
/// be regenerated.
async fn get_local_registration_id(
&self,
) -> Result<u32, SignalProtocolError> {
todo!()
}

// TODO: make this into an enum instead of a bool!
/// Record an identity into the store. The identity is then considered "trusted".
///
/// The return value represents whether an existing identity was replaced (`Ok(true)`). If it is
/// new or hasn't changed, the return value should be `Ok(false)`.
async fn save_identity(
&mut self,
_address: &ProtocolAddress,
_identity: &IdentityKey,
) -> Result<bool, SignalProtocolError> {
todo!()
}

/// Return whether an identity is trusted for the role specified by `direction`.
async fn is_trusted_identity(
&self,
_address: &ProtocolAddress,
_identity: &IdentityKey,
_direction: Direction,
) -> Result<bool, SignalProtocolError> {
todo!()
}

/// Return the public identity for the given `address`, if known.
async fn get_identity(
&self,
_address: &ProtocolAddress,
) -> Result<Option<IdentityKey>, SignalProtocolError> {
todo!()
}
}

#[async_trait::async_trait(?Send)]
impl PreKeysStore for ExampleStore {
/// ID of the next pre key
async fn next_pre_key_id(&self) -> Result<u32, SignalProtocolError> {
todo!()
}

/// ID of the next signed pre key
async fn next_signed_pre_key_id(&self) -> Result<u32, SignalProtocolError> {
todo!()
}

/// ID of the next PQ pre key
async fn next_pq_pre_key_id(&self) -> Result<u32, SignalProtocolError> {
todo!()
}

/// set the ID of the next pre key
async fn set_next_pre_key_id(
&mut self,
_id: u32,
) -> Result<(), SignalProtocolError> {
todo!()
}

/// set the ID of the next signed pre key
async fn set_next_signed_pre_key_id(
&mut self,
_id: u32,
) -> Result<(), SignalProtocolError> {
todo!()
}

/// set the ID of the next PQ pre key
async fn set_next_pq_pre_key_id(
&mut self,
_id: u32,
) -> Result<(), SignalProtocolError> {
todo!()
}
}

#[allow(dead_code)]
fn main() {
let _ = ExampleStore::new();
}
4 changes: 2 additions & 2 deletions libsignal-service/protobuf/Groups.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ message Member {
bytes userId = 1;
Role role = 2;
bytes profileKey = 3;
bytes presentation = 4;
bytes presentation = 4; // Only set when sending to server
uint32 joinedAtRevision = 5;
}

Expand All @@ -41,7 +41,7 @@ message PendingMember {
message RequestingMember {
bytes userId = 1;
bytes profileKey = 2;
bytes presentation = 3;
bytes presentation = 3; // Only set when sending to server
uint64 timestamp = 4;
}

Expand Down
3 changes: 2 additions & 1 deletion libsignal-service/protobuf/Provisioning.proto
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ message ProvisionMessage {
optional bytes profileKey = 6;
optional bool readReceipts = 7;
optional uint32 provisioningVersion = 9;
// NEXT ID: 13
optional bytes masterKey = 13;
// NEXT ID: 14
}

enum ProvisioningVersion {
Expand Down

0 comments on commit 93c23cf

Please sign in to comment.