mirror of
https://github.com/matter-labs/teepot.git
synced 2025-07-22 23:44:48 +02:00
feat: WIP new multisig threshold scheme
with a tree like structure allowing nested m of n schemes. Signed-off-by: Harald Hoyer <harald@matterlabs.dev>
This commit is contained in:
parent
8ce8f5bccb
commit
e2b64d5519
19 changed files with 1138 additions and 173 deletions
|
@ -21,3 +21,6 @@ tracing.workspace = true
|
|||
tracing-actix-web.workspace = true
|
||||
tracing-log.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
test-log.workspace = true
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (c) 2023 Matter Labs
|
||||
// Copyright (c) 2023-2024 Matter Labs
|
||||
|
||||
//! post commands
|
||||
|
||||
|
@ -14,7 +14,7 @@ use teepot::json::http::{
|
|||
VaultCommandRequest, VaultCommandResponse, VaultCommands, VaultCommandsResponse,
|
||||
};
|
||||
use teepot::json::secrets::{AdminConfig, AdminState};
|
||||
use teepot::server::{signatures::VerifySig, HttpResponseError, Status};
|
||||
use teepot::server::{HttpResponseError, Status};
|
||||
use tracing::instrument;
|
||||
|
||||
/// Post command
|
||||
|
@ -52,7 +52,9 @@ pub async fn post_command(
|
|||
.await?
|
||||
.context("empty admin config")
|
||||
.status(StatusCode::BAD_GATEWAY)?;
|
||||
admin_config.check_sigs(&item.signatures, item.commands.as_bytes())?;
|
||||
admin_config
|
||||
.policy
|
||||
.check_sigs(&item.signatures, item.commands.as_bytes())?;
|
||||
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(item.commands.as_bytes());
|
||||
|
|
|
@ -116,6 +116,7 @@ async fn main() -> Result<()> {
|
|||
mod tests {
|
||||
use serde_json::json;
|
||||
use teepot::json::http::{VaultCommand, VaultCommands};
|
||||
use test_log::test;
|
||||
|
||||
const TEST_DATA: &str = include_str!("../../../crates/teepot/tests/data/test.json");
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (c) 2023 Matter Labs
|
||||
// Copyright (c) 2023-2024 Matter Labs
|
||||
|
||||
//! post signing request
|
||||
|
||||
|
@ -12,7 +12,6 @@ use std::sync::Arc;
|
|||
use teepot::client::vault::VaultConnection;
|
||||
use teepot::json::http::{SignRequest, SignRequestData, SignResponse};
|
||||
use teepot::json::secrets::{AdminConfig, AdminState, SGXSigningKey};
|
||||
use teepot::server::signatures::VerifySig as _;
|
||||
use teepot::server::{HttpResponseError, Status};
|
||||
use teepot::sgx::sign::PrivateKey as _;
|
||||
use teepot::sgx::sign::{Author, Signature};
|
||||
|
@ -76,7 +75,9 @@ pub async fn post_sign(
|
|||
.await?
|
||||
.context("empty admin config")
|
||||
.status(StatusCode::BAD_GATEWAY)?;
|
||||
admin_config.check_sigs(&item.signatures, item.sign_request_data.as_bytes())?;
|
||||
admin_config
|
||||
.policy
|
||||
.check_sigs(&item.signatures, item.sign_request_data.as_bytes())?;
|
||||
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(item.sign_request_data.as_bytes());
|
||||
|
|
|
@ -2,14 +2,11 @@
|
|||
// Copyright (c) 2023-2024 Matter Labs
|
||||
|
||||
use crate::{get_vault_status, UnsealServerState, Worker};
|
||||
use actix_web::error::ErrorBadRequest;
|
||||
use actix_web::{web, HttpResponse};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use awc::http::StatusCode;
|
||||
use serde_json::json;
|
||||
use teepot::client::TeeConnection;
|
||||
use teepot::json::http::{Init, InitResponse, VaultInitRequest};
|
||||
use teepot::json::secrets::AdminConfig;
|
||||
use teepot::server::{HttpResponseError, Status};
|
||||
use tracing::{debug, error, info, instrument, trace};
|
||||
|
||||
|
@ -22,8 +19,7 @@ pub async fn post_init(
|
|||
pgp_keys,
|
||||
secret_shares,
|
||||
secret_threshold,
|
||||
admin_pgp_keys,
|
||||
admin_threshold,
|
||||
admin_config,
|
||||
admin_tee_mrenclave,
|
||||
} = init.into_inner();
|
||||
let conn = TeeConnection::new(&worker.vault_attestation);
|
||||
|
@ -36,17 +32,10 @@ pub async fn post_init(
|
|||
secret_threshold,
|
||||
};
|
||||
|
||||
if admin_threshold < 1 {
|
||||
return Ok(HttpResponse::from_error(ErrorBadRequest(
|
||||
json!({"error": "admin_threshold must be at least 1"}),
|
||||
)));
|
||||
}
|
||||
|
||||
if admin_threshold > admin_pgp_keys.len() {
|
||||
return Ok(HttpResponse::from_error(ErrorBadRequest(
|
||||
json!({"error": "admin_threshold must be less than or equal to the number of admin_pgp_keys"}),
|
||||
)));
|
||||
}
|
||||
admin_config
|
||||
.validate()
|
||||
.context("Invalid admin config")
|
||||
.status(StatusCode::BAD_REQUEST)?;
|
||||
|
||||
loop {
|
||||
let current_state = worker.state.read().unwrap().clone();
|
||||
|
@ -123,10 +112,7 @@ pub async fn post_init(
|
|||
*/
|
||||
|
||||
*worker.state.write().unwrap() = UnsealServerState::VaultInitialized {
|
||||
admin_config: AdminConfig {
|
||||
admin_pgp_keys,
|
||||
admin_threshold,
|
||||
},
|
||||
admin_config,
|
||||
admin_tee_mrenclave,
|
||||
root_token,
|
||||
};
|
||||
|
|
|
@ -9,7 +9,6 @@ repository.workspace = true
|
|||
[dependencies]
|
||||
actix-web.workspace = true
|
||||
anyhow.workspace = true
|
||||
base64.workspace = true
|
||||
clap.workspace = true
|
||||
serde_json.workspace = true
|
||||
teepot.workspace = true
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
// Copyright (c) 2023-2024 Matter Labs
|
||||
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use serde_json::Value;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use teepot::client::{AttestationArgs, TeeConnection};
|
||||
use teepot::json::http::{Init, InitResponse, Unseal};
|
||||
use teepot::json::secrets::AdminConfig;
|
||||
use tracing::{error, info, trace, warn};
|
||||
use tracing_log::LogTracer;
|
||||
use tracing_subscriber::Registry;
|
||||
|
@ -16,12 +16,9 @@ use tracing_subscriber::{fmt, prelude::*, EnvFilter};
|
|||
|
||||
#[derive(Args, Debug)]
|
||||
pub struct InitArgs {
|
||||
/// admin threshold
|
||||
#[arg(long)]
|
||||
admin_threshold: usize,
|
||||
/// PGP keys to sign commands for the admin tee
|
||||
#[arg(short, long)]
|
||||
admin_pgp_key_file: Vec<String>,
|
||||
admin_config_json: String,
|
||||
/// admin TEE mrenclave
|
||||
#[arg(long)]
|
||||
admin_tee_mrenclave: String,
|
||||
|
@ -78,17 +75,12 @@ async fn init(args: Arguments) -> Result<()> {
|
|||
unreachable!()
|
||||
};
|
||||
|
||||
if init_args.admin_threshold == 0 {
|
||||
bail!("admin threshold must be greater than 0");
|
||||
}
|
||||
|
||||
if init_args.unseal_threshold == 0 {
|
||||
bail!("unseal threshold must be greater than 0");
|
||||
}
|
||||
|
||||
if init_args.admin_threshold > init_args.admin_pgp_key_file.len() {
|
||||
bail!("admin threshold must be less than or equal to the number of admin pgp keys");
|
||||
}
|
||||
let admin_config: AdminConfig = serde_json::from_str(&init_args.admin_config_json)
|
||||
.context("failed to parse admin config")?;
|
||||
|
||||
if init_args.unseal_threshold > init_args.unseal_pgp_key_file.len() {
|
||||
bail!("unseal threshold must be less than or equal to the number of unseal pgp keys");
|
||||
|
@ -105,30 +97,11 @@ async fn init(args: Arguments) -> Result<()> {
|
|||
pgp_keys.push(key);
|
||||
}
|
||||
|
||||
let mut admin_pgp_keys = Vec::new();
|
||||
|
||||
for filename in init_args.admin_pgp_key_file {
|
||||
let mut file =
|
||||
File::open(&filename).context(format!("Failed to open pgp key file {}", &filename))?;
|
||||
// read all lines from file and concatenate them
|
||||
let mut key = String::new();
|
||||
file.read_to_string(&mut key)
|
||||
.context(format!("Failed to read pgp key file {}", &filename))?;
|
||||
key.retain(|c| !c.is_ascii_whitespace());
|
||||
|
||||
let bytes = general_purpose::STANDARD.decode(key).context(format!(
|
||||
"Failed to base64 decode pgp key file {}",
|
||||
&filename
|
||||
))?;
|
||||
admin_pgp_keys.push(bytes.into_boxed_slice());
|
||||
}
|
||||
|
||||
let init = Init {
|
||||
secret_shares: pgp_keys.len() as _,
|
||||
secret_threshold: init_args.unseal_threshold,
|
||||
admin_threshold: init_args.admin_threshold,
|
||||
admin_tee_mrenclave: init_args.admin_tee_mrenclave,
|
||||
admin_pgp_keys: admin_pgp_keys.into_boxed_slice(),
|
||||
admin_config,
|
||||
pgp_keys,
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue