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

Allow overriding the TA manifest number. #1178

Merged
merged 2 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.cargo
.idea/
.locks
.vscode/
.DS_Store
data/
Expand Down
76 changes: 61 additions & 15 deletions src/cli/ta_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@ pub struct SignerCommand {
pub enum SignerCommandDetails {
Init(SignerInitInfo),
ShowInfo,
ProcessRequest(TrustAnchorSignedRequest),
ProcessRequest {
signed_request: TrustAnchorSignedRequest,
ta_mft_number_override: Option<u64>,
},
ShowLastResponse,
ShowExchanges,
}
Expand All @@ -160,6 +163,7 @@ pub struct SignerInitInfo {
tal_https: Vec<uri::Https>,
tal_rsync: uri::Rsync,
private_key_pem: Option<String>,
ta_mft_nr_override: Option<u64>,
}

impl TrustAnchorClientCommand {
Expand Down Expand Up @@ -405,6 +409,13 @@ impl TrustAnchorClientCommand {
.value_name("path")
.help("[OPTIONAL] Import an existing private key in PEM format")
.required(false),
)
.arg(
Arg::with_name("initial_manifest_number")
.long("initial_manifest_number")
.value_name("number")
.help("[OPTIONAL] Override the initial manifest number (defaults to 1)")
.required(false),
);

app.subcommand(sub)
Expand All @@ -422,15 +433,22 @@ impl TrustAnchorClientCommand {
sub = Self::add_config_arg(sub);
sub = Self::add_format_arg(sub);

sub = sub.arg(
Arg::with_name("request")
.long("request")
.short("r")
.value_name("file")
.help("Path to TA Proxy request file (JSON)")
.required(true),
);

sub = sub
.arg(
Arg::with_name("request")
.long("request")
.short("r")
.value_name("file")
.help("Path to TA Proxy request file (JSON)")
.required(true),
)
.arg(
Arg::with_name("ta_mft_number_override")
.long("ta_mft_number_override")
.value_name("number")
.help("[OPTIONAL] Override the next manifest number (defaults to last + 1)")
.required(false),
);
app.subcommand(sub)
}

Expand Down Expand Up @@ -727,6 +745,13 @@ impl TrustAnchorClientCommand {
.map_err(|_| TaClientError::Other(format!("Invalid rsync uri: {}", rsync_str)))?
};

let ta_mft_nr_override = if let Some(number) = matches.value_of("initial_manifest_number") {
let nr = u64::from_str(number).map_err(|_| TaClientError::other("Invalid manifest number, must be >1"))?;
Some(nr)
} else {
None
};

let private_key_pem = if let Some(path) = matches.value_of("private_key_pem") {
let bytes = Self::read_file_arg(path)?;
let pem = std::str::from_utf8(&bytes)
Expand All @@ -741,6 +766,7 @@ impl TrustAnchorClientCommand {
repo_info,
tal_https,
tal_rsync,
ta_mft_nr_override,
private_key_pem,
};
let details = SignerCommandDetails::Init(info);
Expand All @@ -766,12 +792,23 @@ impl TrustAnchorClientCommand {
fn parse_matches_signer_process(matches: &ArgMatches) -> Result<Self, TaClientError> {
let config = Self::parse_config(matches)?;
let format = Self::parse_format(matches)?;
let request = Self::read_json(matches.value_of("request").unwrap())?;
let signed_request = Self::read_json(matches.value_of("request").unwrap())?;

let ta_mft_number_override = if let Some(nr_str) = matches.value_of("ta_mft_number_override") {
let nr = u64::from_str(nr_str)
.map_err(|_| TaClientError::other("Invalid number for ta_mft_number_override, must be >1"))?;
Some(nr)
} else {
None
};

Ok(TrustAnchorClientCommand::Signer(SignerCommand {
config,
format,
details: SignerCommandDetails::ProcessRequest(request),
details: SignerCommandDetails::ProcessRequest {
signed_request,
ta_mft_number_override,
},
}))
}

Expand Down Expand Up @@ -877,7 +914,10 @@ impl TrustAnchorClient {
match signer_command.details {
SignerCommandDetails::Init(info) => signer_manager.init(info),
SignerCommandDetails::ShowInfo => signer_manager.show(),
SignerCommandDetails::ProcessRequest(request) => signer_manager.process(request),
SignerCommandDetails::ProcessRequest {
signed_request,
ta_mft_number_override,
} => signer_manager.process(signed_request, ta_mft_number_override),
SignerCommandDetails::ShowLastResponse => signer_manager.show_last_response(),
SignerCommandDetails::ShowExchanges => signer_manager.show_exchanges(),
}
Expand Down Expand Up @@ -1032,6 +1072,7 @@ impl TrustAnchorSignerManager {
tal_https: info.tal_https,
tal_rsync: info.tal_rsync,
private_key_pem: info.private_key_pem,
ta_mft_nr_override: info.ta_mft_nr_override,
timing: self.config.timing_config,
signer: self.signer.clone(),
},
Expand All @@ -1050,11 +1091,16 @@ impl TrustAnchorSignerManager {
Ok(TrustAnchorClientApiResponse::TrustAnchorProxySignerInfo(info))
}

fn process(&self, request: TrustAnchorSignedRequest) -> Result<TrustAnchorClientApiResponse, TaClientError> {
fn process(
&self,
signed_request: TrustAnchorSignedRequest,
ta_mft_number_override: Option<u64>,
) -> Result<TrustAnchorClientApiResponse, TaClientError> {
let cmd = TrustAnchorSignerCommand::make_process_request_command(
&self.ta_handle,
request,
signed_request,
self.config.timing_config,
ta_mft_number_override,
self.signer.clone(),
&self.actor,
);
Expand Down
13 changes: 8 additions & 5 deletions src/commons/api/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,18 @@ pub struct Structure {
}

impl Structure {
pub fn new(
pub fn for_testbed(
ta_aia: uri::Rsync,
ta_uri: uri::Https,
ta_key_pem: Option<String>,
publication_server_uris: PublicationServerUris,
cas: Vec<ImportCa>,
) -> Self {
Structure {
ta: Some(ImportTa {
ta_aia,
ta_uri,
ta_key_pem,
ta_key_pem: None,
ta_mft_nr_override: None,
}),
publication_server: Some(publication_server_uris),
cas,
Expand Down Expand Up @@ -128,12 +128,15 @@ where
pub struct ImportTa {
pub ta_aia: uri::Rsync,
pub ta_uri: uri::Https,
#[serde(skip_serializing_if = "Option::is_none")]
pub ta_key_pem: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ta_mft_nr_override: Option<u64>,
}

impl ImportTa {
pub fn unpack(self) -> (uri::Rsync, Vec<uri::Https>, Option<String>) {
(self.ta_aia, vec![self.ta_uri], self.ta_key_pem)
pub fn unpack(self) -> (uri::Rsync, Vec<uri::Https>, Option<String>, Option<u64>) {
(self.ta_aia, vec![self.ta_uri], self.ta_key_pem, self.ta_mft_nr_override)
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/daemon/ca/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ impl CaManager {
tal_https,
tal_rsync,
private_key_pem,
ta_mft_nr_override: None,
timing: self.config.ta_timing,
signer: self.signer.clone(),
};
Expand Down Expand Up @@ -1243,7 +1244,7 @@ impl CaManager {
}
}

/// Synchronise the Trust Anchor Proxy with the Signer - it the Signer is local.
/// Synchronise the Trust Anchor Proxy with the Signer - if the Signer is local.
pub async fn sync_ta_proxy_signer_if_possible(&self) -> KrillResult<()> {
let ta_handle = ta_handle();

Expand All @@ -1262,6 +1263,7 @@ impl CaManager {
&ta_handle,
signed_request,
self.config.ta_timing,
None, // do not override next manifest number
self.signer.clone(),
&self.system_actor,
);
Expand Down
10 changes: 7 additions & 3 deletions src/daemon/ca/publishing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,7 @@ impl KeyObjectSet {
self.revision.next_update.to_rfc3339()
);

self.revision.next(timing.publish_next());
self.revision.next(timing.publish_next(), None);

self.revocations.remove_expired();
let signing_key = self.signing_cert.key_identifier();
Expand Down Expand Up @@ -1101,8 +1101,12 @@ impl ObjectSetRevision {
}
}

pub fn next(&mut self, next_update: Time) {
self.number += 1;
pub fn next(&mut self, next_update: Time, mft_number_override: Option<u64>) {
if let Some(forced_next) = mft_number_override {
self.number = forced_next;
} else {
self.number += 1;
}
self.this_update = Time::five_minutes_ago();
self.next_update = next_update;
}
Expand Down
5 changes: 2 additions & 3 deletions src/daemon/krillserver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,9 @@ impl KrillServer {
}
}

let startup_structure = api::import::Structure::new(
let startup_structure = api::import::Structure::for_testbed(
testbed.ta_aia().clone(),
testbed.ta_uri().clone(),
None,
testbed.publication_server_uris(),
import_cas,
);
Expand Down Expand Up @@ -595,7 +594,7 @@ impl KrillServer {
if let Some(import_ta) = structure.ta.clone() {
if self.config.ta_proxy_enabled() && self.config.ta_signer_enabled() {
info!("Creating embedded Trust Anchor");
let (ta_aia, ta_uris, ta_key_pem) = import_ta.unpack();
let (ta_aia, ta_uris, ta_key_pem, _ta_mft_nr_override) = import_ta.unpack();
self.ca_manager
.ta_init_fully_embedded(ta_aia, ta_uris, ta_key_pem, &self.repo_manager, &actor)
.await?;
Expand Down
17 changes: 14 additions & 3 deletions src/ta/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,17 @@ pub struct TrustAnchorObjects {

impl TrustAnchorObjects {
/// Creates a new TrustAnchorObjects for the signing certificate.
pub fn create(signing_cert: &ReceivedCert, next_update_weeks: i64, signer: &KrillSigner) -> KrillResult<Self> {
let revision = ObjectSetRevision::new(1, Self::this_update(), Self::next_update(next_update_weeks));
pub fn create(
signing_cert: &ReceivedCert,
initial_number: u64,
next_update_weeks: i64,
signer: &KrillSigner,
) -> KrillResult<Self> {
let revision = ObjectSetRevision::new(
initial_number,
Self::this_update(),
Self::next_update(next_update_weeks),
);
let key_identifier = signing_cert.key_identifier();
let base_uri = signing_cert.ca_repository().clone();
let revocations = Revocations::default();
Expand Down Expand Up @@ -104,9 +113,11 @@ impl TrustAnchorObjects {
&mut self,
signing_cert: &ReceivedCert,
next_update_weeks: i64,
mft_number_override: Option<u64>,
signer: &KrillSigner,
) -> KrillResult<()> {
self.revision.next(Self::next_update(next_update_weeks));
self.revision
.next(Self::next_update(next_update_weeks), mft_number_override);

let signing_key = signing_cert.key_identifier();

Expand Down
10 changes: 6 additions & 4 deletions src/ta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ mod tests {
tal_https: tal_https.clone(),
tal_rsync: tal_rsync.clone(),
private_key_pem: Some(import_key_pem.to_string()),
ta_mft_nr_override: Some(42),
timing,
signer: signer.clone(),
},
Expand All @@ -119,9 +120,9 @@ mod tests {
proxy = ta_proxy_store.command(add_signer_cmd).unwrap();

// The initial signer starts off with a TA certificate
// and a CRL and manifest with revision number 1.
// and a CRL and manifest with revision number 42, as specified in the init.
let ta_objects = proxy.get_trust_anchor_objects().unwrap();
assert_eq!(ta_objects.revision().number(), 1);
assert_eq!(ta_objects.revision().number(), 42);

let ta_cert_details = proxy.get_ta_details().unwrap();
assert_eq!(ta_cert_details.tal().uris(), &tal_https);
Expand All @@ -139,6 +140,7 @@ mod tests {
&signer_handle,
signed_request,
timing,
Some(55), // override the next manifest number again
signer,
&actor,
);
Expand All @@ -153,9 +155,9 @@ mod tests {
.unwrap();

// The TA should have published again, the revision used for manifest and crl will
// have been updated.
// have been updated to the overridden number.
let ta_objects = proxy.get_trust_anchor_objects().unwrap();
assert_eq!(ta_objects.revision().number(), 2);
assert_eq!(ta_objects.revision().number(), 55);

// We still need to test some higher order functions:
// - add child
Expand Down
Loading
Loading