Skip to content

Commit

Permalink
Allow overriding the TA manifest number.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Bruijnzeels committed Dec 19, 2023
1 parent 46feb1e commit c345c66
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 53 deletions.
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
11 changes: 6 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 @@ -129,11 +129,12 @@ pub struct ImportTa {
pub ta_aia: uri::Rsync,
pub ta_uri: uri::Https,
pub ta_key_pem: Option<String>,
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

0 comments on commit c345c66

Please sign in to comment.