Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Shamir port] Implement greeting procedure #8995

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci-rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
TESTBED_SERVER: http://localhost:6777
services:
parsec-testbed-server:
image: ghcr.io/scille/parsec-cloud/parsec-testbed-server:3.2.1-a.0.dev.20053.312b36d
image: ghcr.io/scille/parsec-cloud/parsec-testbed-server:3.2.1-a.0.dev.20056.d8d9e29
ports:
- 6777:6777
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
# https://github.com/Scille/parsec-cloud/pkgs/container/parsec-cloud%2Fparsec-testbed-server
services:
parsec-testbed-server:
image: ghcr.io/scille/parsec-cloud/parsec-testbed-server:3.2.1-a.0.dev.20053.312b36d
image: ghcr.io/scille/parsec-cloud/parsec-testbed-server:3.2.1-a.0.dev.20056.d8d9e29
ports:
- 6777:6777
steps:
Expand Down
3 changes: 3 additions & 0 deletions cli/src/commands/invite/claim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ pub async fn main(args: Args) -> anyhow::Result<()> {
let ctx = step4_device(ctx).await?;
save_device(ctx, save_mode).await
}
UserOrDeviceClaimInitialCtx::ShamirRecovery(_) => {
panic!("Shamir recovery invitation is not supported")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return an error instead of panicing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's part of the todo list

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mark the PR as a draft then

}
}
}

Expand Down
7 changes: 7 additions & 0 deletions libparsec/crates/client/src/certif/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,13 @@ impl CertificateOps {
shamir_recovery_list::list_shamir_recoveries_for_others(self).await
}

pub async fn get_shamir_recovery_share_data(
&self,
user_id: UserID,
) -> Result<ShamirRecoveryShareData, CertifListShamirRecoveryError> {
shamir_recovery_list::get_shamir_recovery_share_data(self, user_id).await
}

pub async fn setup_shamir_recovery(
&self,
per_recipient_shares: HashMap<UserID, NonZeroU8>,
Expand Down
37 changes: 37 additions & 0 deletions libparsec/crates/client/src/certif/shamir_recovery_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,3 +331,40 @@ pub async fn list_shamir_recoveries_for_others(
})
.await?
}

pub async fn get_shamir_recovery_share_data(
ops: &CertificateOps,
user_id: UserID,
) -> Result<ShamirRecoveryShareData, CertifListShamirRecoveryError> {
ops.store
.for_read(|store| async move {
// TODO: check that the shamir is actually recoverable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meaning that enough recipient are still here / not revoked ?

let certificate = store
.get_last_shamir_recovery_share_certificate_for_recipient(
UpTo::Current,
user_id,
ops.device.user_id,
)
.await?;
let certificate = match certificate {
Some(certificate) => Ok(certificate),
None => Err(CertifListShamirRecoveryError::Internal(anyhow::anyhow!(
"No share data found for user {}",
user_id
))),
}?;
let author_verify_key = store
.get_device_verify_key(UpTo::Current, certificate.author)
.await
.map_err(|e| CertifListShamirRecoveryError::Internal(e.into()))?;
ShamirRecoveryShareData::decrypt_verify_and_load_for(
&certificate.ciphered_share,
&ops.device.private_key,
&author_verify_key,
certificate.author,
certificate.timestamp,
)
.map_err(|e| CertifListShamirRecoveryError::Internal(e.into()))
})
.await?
}
24 changes: 21 additions & 3 deletions libparsec/crates/client/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ use libparsec_platform_async::lock::Mutex as AsyncMutex;

use libparsec_types::prelude::*;
pub use recovery_device::{
import_recovery_device, ClientExportRecoveryDeviceError, ImportRecoveryDeviceError,
import_recovery_device, register_new_device, ClientExportRecoveryDeviceError,
ImportRecoveryDeviceError,
};

// Re-exposed for public API
Expand All @@ -72,7 +73,8 @@ pub use crate::invite::{
InvitationEmailSentStatus, InviteListItem, ListInvitationsError as ClientListInvitationsError,
NewDeviceInvitationError as ClientNewDeviceInvitationError,
NewShamirRecoveryInvitationError as ClientNewShamirRecoveryInvitationError,
NewUserInvitationError as ClientNewUserInvitationError, UserGreetInitialCtx,
NewUserInvitationError as ClientNewUserInvitationError, ShamirRecoveryGreetInitialCtx,
UserGreetInitialCtx,
};
pub use crate::workspace::WorkspaceOps;
pub use shamir_recovery_delete::ClientDeleteShamirRecoveryError;
Expand Down Expand Up @@ -548,6 +550,22 @@ impl Client {
)
}

pub async fn start_shamir_recovery_invitation_greet(
&self,
token: InvitationToken,
claimer: UserID,
) -> Result<ShamirRecoveryGreetInitialCtx, ClientListShamirRecoveryError> {
let share_data =
shamir_recovery_list::get_shamir_recovery_share_data(self, claimer).await?;
Ok(ShamirRecoveryGreetInitialCtx::new(
self.device.clone(),
self.cmds.clone(),
self.event_bus.clone(),
token,
share_data,
))
}

pub async fn get_self_shamir_recovery(
&self,
) -> Result<SelfShamirRecoveryInfo, ClientListShamirRecoveryError> {
Expand Down Expand Up @@ -591,4 +609,4 @@ impl Client {
#[cfg(test)]
#[path = "../../tests/unit/client/mod.rs"]
#[allow(clippy::unwrap_used)]
mod tests;
pub mod tests;
4 changes: 2 additions & 2 deletions libparsec/crates/client/src/client/recovery_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl From<SaveDeviceError> for ImportRecoveryDeviceError {
}
}

async fn register_new_device(
pub async fn register_new_device(
cmds: &AuthenticatedCmds,
new_device: &LocalDevice,
new_device_purpose: DevicePurpose,
Expand Down Expand Up @@ -242,7 +242,7 @@ pub(crate) fn generate_new_device_certificates(
}

#[derive(Debug, thiserror::Error)]
enum RegisterNewDeviceError {
pub enum RegisterNewDeviceError {
#[error("Component has stopped")]
Stopped,
#[error("Cannot reach the server")]
Expand Down
11 changes: 11 additions & 0 deletions libparsec/crates/client/src/client/shamir_recovery_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub use crate::certif::{
CertifListShamirRecoveryError as ClientListShamirRecoveryError, OtherShamirRecoveryInfo,
SelfShamirRecoveryInfo,
};
use libparsec_types::prelude::*;

use super::Client;

Expand All @@ -21,3 +22,13 @@ pub async fn list_shamir_recoveries_for_others(
.list_shamir_recoveries_for_others()
.await
}

pub async fn get_shamir_recovery_share_data(
client: &Client,
user_id: UserID,
) -> Result<ShamirRecoveryShareData, ClientListShamirRecoveryError> {
client
.certificates_ops
.get_shamir_recovery_share_data(user_id)
.await
}
Loading
Loading