-
Notifications
You must be signed in to change notification settings - Fork 36
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 multiple RoT versions in the same repository #6586
base: main
Are you sure you want to change the base?
Conversation
Currently we require all versions of the RoT and bootloader for a particular type (sled, psc, switch) to have identical versions. This is a stricter requirement than what we actually care about: All images signed with the same key should be the same version. Relax this requirement for both the RoT and its bootloader
3749ff7
to
1497b2f
Compare
@@ -1351,12 +1351,16 @@ impl SpHandler for Handler { | |||
(SpComponent::ROT, b"NAME", _, _) => ROT_NAME, | |||
(SpComponent::ROT, b"VERS", 0, _) => ROT_VERS0, | |||
(SpComponent::ROT, b"VERS", 1, _) => ROT_VERS1, | |||
// gimlet staging/devel hash | |||
(SpComponent::ROT, b"SIGN", _, _) => &"11594bb5548a757e918e6fe056e2ad9e084297c9555417a025d8788eacf55daf".as_bytes(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will we need to keep these hashes in sync with upstream changes over time? ("need" here may not be the right word since this is the simulator and not relevant to production, but maybe it could affect a4x2 or other test envs in some way?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what kind of upstream changes you are thinking of. This hash should never change as it's the same one baked into the CMPA at manufacturing time. We could change it to simulate another set of signing keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't thinking of anything specific - mostly naivety! Just to confirm my understanding - the only way this changes is if we rotate our root manufacturing key?
@@ -32,7 +32,7 @@ pub enum Event { | |||
/// TUF repo artifacts unpacked by wicketd, and event reports | |||
ArtifactsAndEventReports { | |||
system_version: Option<SemverVersion>, | |||
artifacts: Vec<ArtifactId>, | |||
artifacts: Vec<(ArtifactId, Option<Vec<u8>>)>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the Option<Vec<u8>>
? Maybe worth converting this from a tuple to a struct so we can give it a name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The option is the sign vec. You are right that this should be clarified.
// of the bootloader is going to be identical to the RoT. | ||
pub fn rot_sign(&self) -> Option<Vec<u8>> { | ||
match self.rot_active_slot() { | ||
None => return None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tiny nit - I think we could remove the outer match via
match self.rot_active_slot()? {
RotSlot::A => ...
@@ -138,6 +138,13 @@ fn version_or_unknown(caboose: Option<&SpComponentCaboose>) -> String { | |||
caboose.map(|c| c.version.as_str()).unwrap_or("UNKNOWN").to_string() | |||
} | |||
|
|||
fn caboose_sign(caboose: Option<&SpComponentCaboose>) -> Option<Vec<u8>> { | |||
match caboose { | |||
None => None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style nit - I think I'd make this function take a non-optional &SpComponentCaboose
, since we can't do anything useful with None
. That would also make it clear from the signature that even from a non-optional caboose, we may or may not have a sign
value.
.entry(known) | ||
.and_modify(|x| x.push((id.version.clone(), s.clone()))) | ||
.or_insert(vec![(id.version.clone(), s.clone())]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit - I think this would be equivalent:
.entry(known) | |
.and_modify(|x| x.push((id.version.clone(), s.clone()))) | |
.or_insert(vec![(id.version.clone(), s.clone())]); | |
.entry(known) | |
.or_default() | |
.push((id.version.clone(), s.clone())); |
and not require repeating the tuple.
@@ -21,12 +21,14 @@ use std::collections::BTreeMap; | |||
use std::fmt::Display; | |||
use wicketd_client::types::{ArtifactId, SemverVersion}; | |||
|
|||
type ArtifactVersions = Vec<(SemverVersion, Option<Vec<u8>>)>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a map instead of a vec? Is it okay to have multiple identical versions with potentially-different Option<Vec<u8>>
values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to map the existing behavior of the map of artifact kind to one version to a map of artifact kind to a vec of all possible versions. I think this is the same issue with using a tuple instead of a named struct. I'll see if that makes it more obvious what's going on here.
@@ -1130,7 +1130,9 @@ fn append_caboose( | |||
git_commit, | |||
// Currently `name` is always the same as `board`, so we'll skip it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this comment still accurate? I know it's true for production images, but could this bit of code see non-prod builds with different names?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you are correct and it could be helpful to confirm this via wicket.
}; | ||
let cnt = v.len(); | ||
for (vers, sign) in v { | ||
match (sign, component.rot_sign()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the for
/match
here; it looks like it could return different values depending on the ordering of v
, maybe? E.g., if v has two entries, one with a sign and one without, and component.rot_sign()
is none, will we either return vers
(line 2455) if the "without a sign" is first or UNKNOWN (MISSING SIGN)
(line 2461) if the "with a sign" is first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assumption is that either all entries will have a SIGN
or none of them. This should be checked elsewhere or handled/documented better. This is also related to the type you pointed out in the Vec
which is very much a theme here and something I need to rework.
let sign = match caboose.sign() { | ||
Ok(sign) => sign, | ||
Err(error) => { | ||
return Err(RepositoryError::ReadHubrisCabooseBoard { id, error }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be
return Err(RepositoryError::ReadHubrisCabooseBoard { id, error }); | |
return Err(RepositoryError::ReadHubrisCabooseSign { id, error }); |
(or maybe something like ReadHubrisCabooseValue { id, error, key: "sign" }
)?
available_artifacts, | ||
available_artifacts_version, | ||
//available_artifacts, | ||
//available_artifacts_version, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple leftover dead fields here
No description provided.