Skip to content

Commit

Permalink
feat(rust): add secure channel persistence
Browse files Browse the repository at this point in the history
  • Loading branch information
SanjoDeundiak committed May 28, 2024
1 parent 0805fca commit baafa1e
Show file tree
Hide file tree
Showing 29 changed files with 1,334 additions and 149 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use crate::authenticator::{
};
use ockam::identity::utils::now;
use ockam::identity::{
Identifier, Identities, SecureChannelListenerOptions, SecureChannels, TrustEveryonePolicy,
Identifier, Identities, SecureChannelListenerOptions, SecureChannelSqlxDatabase,
SecureChannels, TrustEveryonePolicy,
};
use ockam_core::compat::sync::Arc;
use ockam_core::env::get_env;
Expand Down Expand Up @@ -65,17 +66,20 @@ impl Authority {
debug!(?configuration, "creating the authority");

// create the database
let node_name = "authority";
let database_path = &configuration.database_path;
Self::create_ockam_directory_if_necessary(database_path)?;
let database = SqlxDatabase::create(database_path).await?;
let members = Arc::new(AuthorityMembersSqlxDatabase::new(database.clone()));
let tokens = Arc::new(AuthorityEnrollmentTokenSqlxDatabase::new(database.clone()));
let secure_channel_repository = Arc::new(SecureChannelSqlxDatabase::new(database.clone()));

Self::bootstrap_repository(members.clone(), configuration).await?;

let identities = Identities::create_with_node(database, "authority").build();
let identities = Identities::create_with_node(database, node_name).build();

let secure_channels = SecureChannels::from_identities(identities.clone());
let secure_channels =
SecureChannels::from_identities(identities.clone(), secure_channel_repository);

let identifier = configuration.identifier();
info!(identifier=%identifier, "retrieved the authority identifier");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::Arc;

use ockam::identity::{Identities, SecureChannels};
use ockam::identity::{Identities, SecureChannelSqlxDatabase, SecureChannels};

use crate::cli_state::CliState;
use crate::cli_state::Result;
Expand All @@ -12,6 +12,9 @@ impl CliState {
let identities = Identities::create_with_node(self.database(), node_name)
.with_vault(vault)
.build();
Ok(SecureChannels::from_identities(identities))
Ok(SecureChannels::from_identities(
identities,
Arc::new(SecureChannelSqlxDatabase::new(self.database())),
))
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::time::Duration;

use ockam::identity::models::CredentialAndPurposeKey;
use ockam::identity::TrustEveryonePolicy;
use ockam::identity::Vault;
use ockam::identity::{
Identifier, Identities, SecureChannelListenerOptions, SecureChannelOptions, SecureChannels,
TrustMultiIdentifiersPolicy,
};
use ockam::identity::{SecureChannel, SecureChannelListener};
use ockam::identity::{SecureChannelSqlxDatabase, TrustEveryonePolicy};
use ockam::{Address, Result, Route};
use ockam_core::api::{Error, Response};
use ockam_core::compat::sync::Arc;
Expand Down Expand Up @@ -453,6 +453,7 @@ impl NodeManager {
Ok(Arc::new(SecureChannels::new(
identities,
self.secure_channels.secure_channel_registry(),
Arc::new(SecureChannelSqlxDatabase::new(self.cli_state.database())),
)))
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use minicbor::bytes::ByteSlice;
use ockam::identity::identities;
use ockam::identity::models::CredentialAndPurposeKey;
use ockam::identity::utils::now;
use ockam::identity::{identities, SecureChannelSqlxDatabase};
use ockam::identity::{
Identities, SecureChannelListenerOptions, SecureChannelOptions, SecureChannels,
};
Expand Down Expand Up @@ -55,7 +55,10 @@ async fn credential(ctx: &mut Context) -> Result<()> {
.with_purpose_keys_repository(identities.purpose_keys_repository())
.with_cached_credential_repository(identities.cached_credentials_repository())
.build();
let secure_channels = SecureChannels::from_identities(identities.clone());
let secure_channels = SecureChannels::from_identities(
identities.clone(),
Arc::new(SecureChannelSqlxDatabase::create().await?),
);
let identities_verification = identities.identities_verification();

// Create the CredentialIssuer:
Expand Down
8 changes: 8 additions & 0 deletions implementations/rust/ockam/ockam_identity/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ pub enum IdentityError {
AddressIsNotSubscribedForThatCredentialRetriever,
/// Credential retriever couldn't return a credential
NoCredential,
/// Persistence is currently only supported for key exchange only channels
PersistentSupportIsLimited,
/// Secure Channel not found in the storage
PersistentSecureChannelNotFound,
/// Unknown Secure Channel Role value
UnknownRole,
/// Handshake ended up in an internal invalid state
HandshakeInternalError,
}

impl ockam_core::compat::error::Error for IdentityError {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::secure_channel::role::Role;
// and identity secure channel encryptor&decryptor.
// Now this logic is merged into one encryptor&decryptor pair, but for backwards
// compatibility each of them have more addresses to simulate old behaviour.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct Addresses {
// Used to send decrypted messages and secure channel creation completion notification
pub(crate) decryptor_internal: Address,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,29 @@ use crate::{

/// Interface for a state machine in a key exchange protocol
#[async_trait]
pub(super) trait StateMachine: Send + Sync + 'static {
pub(crate) trait StateMachine: Send + Sync + 'static {
async fn on_event(&mut self, event: Event) -> Result<Action>;
fn get_handshake_results(&self) -> Option<HandshakeResults>;
}

/// Events received by the state machine, either initializing the state machine
/// or receiving a message from the other party
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) enum Event {
pub(crate) enum Event {
Initialize,
ReceivedMessage(Vec<u8>),
}

/// Outcome of processing an event: either no action or a message to send to the other party
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) enum Action {
pub(crate) enum Action {
NoAction,
SendMessage(Vec<u8>),
}

/// List of possible states for the initiator or responder sides of the exchange
#[derive(Debug, Clone)]
pub(super) enum Status {
pub(crate) enum Status {
Initial,
WaitingForMessage1,
WaitingForMessage2,
Expand All @@ -49,15 +49,15 @@ pub(super) enum Status {

/// At the end of a successful handshake a pair of encryption/decryption keys is available
#[derive(Debug, Clone)]
pub(super) struct HandshakeKeys {
pub(crate) struct HandshakeKeys {
pub(super) encryption_key: AeadSecretKeyHandle,
pub(super) decryption_key: AeadSecretKeyHandle,
}

/// The end result of a handshake with identity/credentials exchange is
/// a pair of encryption/decryption keys + the identity of the other party
#[derive(Debug, Clone)]
pub(super) struct HandshakeResults {
pub(crate) struct HandshakeResults {
pub(super) handshake_keys: HandshakeKeys,
pub(super) their_identifier: Identifier,
pub(super) presented_credential: Option<CredentialAndPurposeKey>,
Expand Down
Loading

0 comments on commit baafa1e

Please sign in to comment.