diff --git a/teos/proto/teos/v2/tower_services.proto b/teos/proto/teos/v2/tower_services.proto index 92fa8810..5ea14b88 100644 --- a/teos/proto/teos/v2/tower_services.proto +++ b/teos/proto/teos/v2/tower_services.proto @@ -6,6 +6,7 @@ import "user.proto"; import "common/teos/v2/appointment.proto"; import "common/teos/v2/user.proto"; import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; message NetworkAddress { // Tower public API endpoint. @@ -46,5 +47,6 @@ service PrivateTowerServices { rpc get_tower_info(google.protobuf.Empty) returns (GetTowerInfoResponse) {} rpc get_users(google.protobuf.Empty) returns (GetUsersResponse) {} rpc get_user(GetUserRequest) returns (GetUserResponse) {} + rpc sign_message(google.protobuf.StringValue) returns (google.protobuf.StringValue) {} rpc stop(google.protobuf.Empty) returns (google.protobuf.Empty) {} } \ No newline at end of file diff --git a/teos/src/api/internal.rs b/teos/src/api/internal.rs index c6fa355d..7288a713 100644 --- a/teos/src/api/internal.rs +++ b/teos/src/api/internal.rs @@ -395,6 +395,13 @@ impl PrivateTowerServices for Arc { } } + /// Signs a message using the tower's signing key + async fn sign_message(&self, request: Request) -> Result, Status> { + Ok(Response::new( + self.watcher.sign_message(&request.into_inner()), + )) + } + /// Stop endpoint. Stops the tower daemon. Part of the private API. async fn stop(&self, request: Request<()>) -> Result, Status> { self.shutdown_trigger.trigger(); diff --git a/teos/src/cli.rs b/teos/src/cli.rs index dbc345df..8c022f47 100644 --- a/teos/src/cli.rs +++ b/teos/src/cli.rs @@ -112,6 +112,10 @@ async fn main() { Err(e) => println!("{e}"), }; } + Command::SignMessage(m) => { + let sig = client.sign_message(Request::new(m.message)).await; + println!("{}", sig.unwrap().into_inner()); + } Command::Stop => { println!("Shutting down tower"); client.stop(Request::new(())).await.unwrap(); diff --git a/teos/src/cli_config.rs b/teos/src/cli_config.rs index ba085b8d..df60da12 100644 --- a/teos/src/cli_config.rs +++ b/teos/src/cli_config.rs @@ -16,6 +16,8 @@ pub enum Command { GetUsers, /// Gets information about a specific user GetUser(GetUserData), + /// Signs a message using the tower's secret key + SignMessage(MessageToSign), /// Requests a graceful shutdown of the tower Stop, } @@ -33,6 +35,12 @@ pub struct GetAppointmentsData { pub locator: String, } +#[derive(Debug, StructOpt, Clone)] +pub struct MessageToSign { + /// The locator of the appointments (16-byte hexadecimal string). + pub message: String, +} + /// Holds all the command line options and commands. #[derive(StructOpt, Debug)] #[structopt(rename_all = "lowercase")] diff --git a/teos/src/watcher.rs b/teos/src/watcher.rs index ec2e7da5..74032e83 100644 --- a/teos/src/watcher.rs +++ b/teos/src/watcher.rs @@ -650,6 +650,11 @@ impl Watcher { Ok((subscription_info, locators)) } + + /// Signs a message using the tower's signing key + pub(crate) fn sign_message(&self, message: &str) -> String { + cryptography::sign(message.as_bytes(), &self.signing_key).unwrap() + } } /// Listen implementation by the [Watcher]. Handles monitoring and reorgs.