Skip to content

Commit

Permalink
Add docs for a few modules, nondestructively!
Browse files Browse the repository at this point in the history
- Add module docs for the `libsignal_protocol` crate!
- Add docs to the `device-transfer` crate!
- Add docs to `address`!

beef up the docs for `address` because this is an important struct!

respond to review comments

revert module visibility changes

de-clutter the docstring for `.device_id()`

add missing docs warning

fix uuid deps

add doctest for `ProtocolAddress::new()`!

avoid pulling in uuid into dev-dependencies
  • Loading branch information
cosmicexplorer committed May 5, 2021
1 parent bbc1a9a commit 9872e21
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 6 deletions.
12 changes: 11 additions & 1 deletion rust/device-transfer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
// SPDX-License-Identifier: AGPL-3.0-only
//

//! Support logic for Signal's device-to-device transfer feature.
#![deny(unsafe_code)]
#![warn(missing_docs)]

use chrono::{Datelike, Duration, Utc};
use picky::key::PrivateKey;
Expand All @@ -12,21 +15,25 @@ use picky::x509::{certificate::CertificateBuilder, date::UTCDate};
use picky::{hash::HashAlgorithm, signature::SignatureAlgorithm};
use std::fmt;

/// Error types for device transfer.
#[derive(Copy, Clone, Debug)]
pub enum Error {
/// Failure to decode some provided RSA private key.
KeyDecodingFailed,
/// Internal error in device transfer.
InternalError(&'static str),
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::KeyDecodingFailed => write!(f, "Decoding provided RSA private key failed"),
Error::InternalError(s) => write!(f, "Internal error in device tranfer ({})", s),
Error::InternalError(s) => write!(f, "Internal error in device transfer ({})", s),
}
}
}

/// Generate a private key of size `bits` and export to PKCS8 format.
pub fn create_rsa_private_key(bits: usize) -> Result<Vec<u8>, Error> {
let key = PrivateKey::generate_rsa(bits)
.map_err(|_| Error::InternalError("RSA key generation failed"))?;
Expand All @@ -35,6 +42,9 @@ pub fn create_rsa_private_key(bits: usize) -> Result<Vec<u8>, Error> {
.map_err(|_| Error::InternalError("Exporting to PKCS8 failed"))?)
}

/// Generate a self-signed certificate of name `name`, expiring in `days_to_expire`.
///
/// `rsa_key_pkcs8` should be the output of [create_rsa_private_key].
pub fn create_self_signed_cert(
rsa_key_pkcs8: &[u8],
name: &str,
Expand Down
49 changes: 45 additions & 4 deletions rust/protocol/src/address.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,67 @@
//
// Copyright 2020 Signal Messenger, LLC.
// Copyright 2020-2021 Signal Messenger, LLC.
// SPDX-License-Identifier: AGPL-3.0-only
//

#![warn(missing_docs)]

//! A normalized representation of an individual Signal client instance.
#[cfg(doc)]
use crate::SignalMessage;

use std::fmt;

/// The type used in memory to represent a *device*, i.e. a particular Signal client instance which
/// represents some user.
///
/// Used in [ProtocolAddress].
pub type DeviceId = u32;

/// Represents a unique Signal client instance as `(<user ID>, <device ID>)` pair.
#[derive(Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
pub struct ProtocolAddress {
name: String,
device_id: u32,
device_id: DeviceId,
}

impl ProtocolAddress {
pub fn new(name: String, device_id: u32) -> Self {
/// Create a new address.
///
/// - `name` defines a user's public identity, and therefore must be globally unique to that
/// user.
/// - Each Signal client instance then has its own `device_id`, which must be unique among
/// all clients for that user.
///
///```
/// use libsignal_protocol::{DeviceId, ProtocolAddress};
///
/// // This is a unique id for some user, typically a UUID.
/// let user_id: String = "04899A85-4C9E-44CC-8428-A02AB69335F1".to_string();
/// // Each client instance representing that user has a unique device id.
/// let device_id: DeviceId = 2_u32.into();
/// let address = ProtocolAddress::new(user_id.clone(), device_id);
///
/// assert!(address.name() == &user_id);
/// assert!(address.device_id() == device_id);
///```
pub fn new(name: String, device_id: DeviceId) -> Self {
ProtocolAddress { name, device_id }
}

/// A unique identifier for the target user. This is usually a UUID.
#[inline]
pub fn name(&self) -> &str {
&self.name
}

pub fn device_id(&self) -> u32 {
/// An identifier representing a particular Signal client instance to send to.
///
/// For example, if a user has set up Signal on both their phone and laptop, any [SignalMessage]
/// sent to the user will still only go to a single device. So when a user sends a message to
/// another user at all, they're actually sending a message to *every* device.
#[inline]
pub fn device_id(&self) -> DeviceId {
self.device_id
}
}
Expand Down
20 changes: 19 additions & 1 deletion rust/protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,27 @@
// SPDX-License-Identifier: AGPL-3.0-only
//

//! Rust implementation of the **[Signal Protocol]** for asynchronous
//! forward-secret public-key cryptography.
//!
//! In particular, this library implements operations conforming to the following specifications:
//! - the **[X3DH]** key agreement protocol,
//! - the **[Double Ratchet]** *(Axolotl)* messaging protocol,
//! - the **[Sesame]** session agreement protocol.
//!
//! [Signal Protocol]: https://signal.org/
//! [X3DH]: https://signal.org/docs/specifications/x3dh/
//! [Double Ratchet]: https://signal.org/docs/specifications/doubleratchet/
//! [Sesame]: https://signal.org/docs/specifications/sesame/
#![warn(clippy::unwrap_used)]
#![deny(unsafe_code)]

// TODO(https://github.com/signalapp/libsignal-client/issues/285): it should be an aspiration to
// eventually warn and then error for public members without docstrings. Also see
// https://doc.rust-lang.org/rustdoc/what-to-include.html for background.
// #![warn(missing_docs)]

mod address;
mod consts;
mod crypto;
Expand All @@ -29,7 +47,7 @@ mod utils;
use error::Result;

pub use {
address::ProtocolAddress,
address::{DeviceId, ProtocolAddress},
curve::{KeyPair, PrivateKey, PublicKey},
error::SignalProtocolError,
fingerprint::{DisplayableFingerprint, Fingerprint, ScannableFingerprint},
Expand Down

0 comments on commit 9872e21

Please sign in to comment.