Skip to content

Commit

Permalink
Update to libsignal 0.22.2 (#9)
Browse files Browse the repository at this point in the history
* Update libsignal dependency

* Update README

* Update protobuf and related structs
  • Loading branch information
tm-drtina authored Mar 19, 2023
1 parent 5ac7b31 commit 3360e5f
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 34 deletions.
11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
[package]
name = "signal-provisioning-api"
version = "0.5.0"
version = "0.6.0"
authors = ["Tomas Drtina <tm.drtina@gmail.com>"]
edition = "2021"
license = "AGPL-3.0-only"
repository = "https://github.com/tm-drtina/signal-provisioning-api"

[dependencies]
libsignal-protocol = { git = "https://github.com/signalapp/libsignal.git", tag = "v0.19.3" }
signal-crypto = { git = "https://github.com/signalapp/libsignal.git", tag = "v0.19.3" }
libsignal-protocol = { git = "https://github.com/signalapp/libsignal.git", tag = "v0.22.2" }
signal-crypto = { git = "https://github.com/signalapp/libsignal.git", tag = "v0.22.2" }

aes = "0.7.4"
subtle = "2.2.3"
subtle = "2.3"
block-modes = "0.8"
hkdf = "0.11"
sha2 = "0.9"
uuid = "1.1.2"

base64 = "0.13.0"
base64 = "0.21"
prost = "0.9"
rand = "0.7.3"

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ Example client implemantation is still under way, but for reference: https://git
| ------------------------ | ----------------- |
| 0.4.0 | 0.18.1 |
| 0.5.0 | 0.19.3 |
| 0.6.0 | 0.22.2 |
7 changes: 7 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use prost::DecodeError;
pub enum Error {
SignalProtocolError(SignalProtocolError),
SignalCryptoError(SignalCryptoError),
UuidParsingError(uuid::Error),
}

impl From<SignalCryptoError> for Error {
Expand All @@ -26,4 +27,10 @@ impl From<DecodeError> for Error {
}
}

impl From<uuid::Error> for Error {
fn from(err: uuid::Error) -> Self {
Self::UuidParsingError(err)
}
}

pub type Result<T> = std::result::Result<T, Error>;
18 changes: 11 additions & 7 deletions src/proto/device_messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ message ProvisionEnvelope {
}

message ProvisionMessage {
optional bytes identityKeyPrivate = 2;
optional string number = 3;
optional string uuid = 8;
optional string provisioningCode = 4;
optional string userAgent = 5;
optional bytes profileKey = 6;
optional bool readReceipts = 7;
optional bytes aciIdentityKeyPublic = 1;
optional bytes aciIdentityKeyPrivate = 2;
optional bytes pniIdentityKeyPublic = 11;
optional bytes pniIdentityKeyPrivate = 12;
optional string aci = 8;
optional string pni = 10;
optional string number = 3;
optional string provisioningCode = 4;
optional string userAgent = 5;
optional bytes profileKey = 6;
optional bool readReceipts = 7;
optional uint32 ProvisioningVersion = 9;
}

Expand Down
67 changes: 50 additions & 17 deletions src/provisioning/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,39 @@ use std::convert::TryFrom;

use libsignal_protocol::{IdentityKey, IdentityKeyPair, PrivateKey, SignalProtocolError};
use prost::Message;
use uuid::Uuid;

#[derive(Clone)]
pub struct ProvisionMessage {
identity_key_pair: IdentityKeyPair,
aci: Uuid,
aci_identity_key_pair: IdentityKeyPair,
pni: Uuid,
pni_identity_key_pair: IdentityKeyPair,
number: String,
provisioning_code: String,
uuid: Option<String>,
user_agent: Option<String>,
read_receipts: Option<bool>,
}

impl ProvisionMessage {
#[inline]
pub fn identity_key_pair(&self) -> &IdentityKeyPair {
&self.identity_key_pair
pub fn aci_identity_key_pair(&self) -> &IdentityKeyPair {
&self.aci_identity_key_pair
}

#[inline]
pub fn aci(&self) -> &Uuid {
&self.aci
}

#[inline]
pub fn pni_identity_key_pair(&self) -> &IdentityKeyPair {
&self.pni_identity_key_pair
}

#[inline]
pub fn pni(&self) -> &Uuid {
&self.pni
}

#[inline]
Expand All @@ -36,11 +54,6 @@ impl ProvisionMessage {
&self.provisioning_code
}

#[inline]
pub fn uuid(&self) -> &Option<String> {
&self.uuid
}

#[inline]
pub fn user_agent(&self) -> &Option<String> {
&self.user_agent
Expand All @@ -58,26 +71,46 @@ impl TryFrom<&[u8]> for ProvisionMessage {
fn try_from(value: &[u8]) -> Result<Self> {
let proto_structure = crate::proto::device_messages::ProvisionMessage::decode(value)?;

let private_key = proto_structure
.identity_key_private
let aci = proto_structure
.aci
.ok_or(SignalProtocolError::InvalidProtobufEncoding)?
.parse()?;
let aci_private_key = proto_structure
.aci_identity_key_private
.ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
let aci_private_key = PrivateKey::deserialize(aci_private_key.as_slice())?;
let aci_identity_key_pair = IdentityKeyPair::new(
IdentityKey::new(aci_private_key.public_key()?),
aci_private_key,
);

let pni = proto_structure
.pni
.ok_or(SignalProtocolError::InvalidProtobufEncoding)?
.parse()?;
let pni_private_key = proto_structure
.pni_identity_key_private
.ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
let private_key = PrivateKey::deserialize(private_key.as_slice())?;
let public_key = private_key.public_key()?;
let identity_key_pair = IdentityKeyPair::new(IdentityKey::new(public_key), private_key);
let pni_private_key = PrivateKey::deserialize(pni_private_key.as_slice())?;
let pni_identity_key_pair = IdentityKeyPair::new(
IdentityKey::new(pni_private_key.public_key()?),
pni_private_key,
);

let number = proto_structure
.number
.ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
let provisioning_code = proto_structure
.provisioning_code
.ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
let uuid = proto_structure.uuid.map(|x| x.to_lowercase());

Ok(ProvisionMessage {
identity_key_pair,
aci,
aci_identity_key_pair,
pni,
pni_identity_key_pair,
number,
provisioning_code,
uuid,
user_agent: proto_structure.user_agent,
read_receipts: proto_structure.read_receipts,
})
Expand Down
4 changes: 2 additions & 2 deletions src/provisioning/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
mod envelope;
mod message;
mod provisioning_uuid;
mod socket;
mod uuid;

use envelope::ProvisionEnvelope;
pub use message::ProvisionMessage;
use provisioning_uuid::ProvisioningUuid;
pub use socket::{ProvisioningSocket, ProvisioningState};
use uuid::ProvisioningUuid;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::error::{Error, Result};

use std::convert::TryFrom;

use base64::{engine::general_purpose, Engine as _};
use libsignal_protocol::{PublicKey, SignalProtocolError};
use prost::Message;

Expand All @@ -21,7 +22,7 @@ impl ProvisioningUuid {
}

pub fn provisioning_url(&self, ephemeral_pubkey: PublicKey) -> String {
let public_key_base64 = base64::encode(ephemeral_pubkey.serialize());
let public_key_base64 = general_purpose::STANDARD.encode(ephemeral_pubkey.serialize());
// We need to urlencode, but base64 has limited alphabet, so replace is enough
let public_key_base64 = public_key_base64.replace('+', "%2B").replace('/', "%2F");
format!(
Expand Down
4 changes: 2 additions & 2 deletions src/provisioning/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use super::{ProvisionEnvelope, ProvisionMessage, ProvisioningUuid};
pub enum ProvisioningState {
Init,
UuidReceived(ProvisioningUuid),
Provisioned(ProvisionMessage),
Provisioned(Box<ProvisionMessage>),
}

pub struct ProvisioningSocket {
Expand Down Expand Up @@ -111,7 +111,7 @@ impl ProvisioningSocket {
let plaintext = envelope.decrypt(self.ephemeral_key_pair.private_key)?;
let message = ProvisionMessage::try_from(plaintext.as_slice())?;

self.state = ProvisioningState::Provisioned(message);
self.state = ProvisioningState::Provisioned(Box::new(message));
Ok(Some(request_id))
} else {
Err(SignalProtocolError::InvalidProtobufEncoding.into())
Expand Down

0 comments on commit 3360e5f

Please sign in to comment.