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

preinstall: Add CheckResult and WithAutoTCGPCRProfile APIs #338

Conversation

chrisccoulson
Copy link
Collaborator

@chrisccoulson chrisccoulson commented Oct 4, 2024

CheckResult is returned from RunChecks on successful completion. It is
JSON serializable and intended to be supplied later on to
WithAutoTCGPCRProfile along with some user customization flags (defined
by PCRProfileOptionsFlags) in order to generate an option that can be
supplied to secboot_efi.AddPCRProfile.

Note that some user options don't work yet because of missing PCR
support, although these limitations will be addressed later. For now,
these will appear as failures in the CheckResult flags.

@chrisccoulson chrisccoulson force-pushed the preinstall-add-profile-and-results branch 2 times, most recently from 33a77f7 to 27fef9d Compare October 4, 2024 19:44
@chrisccoulson chrisccoulson force-pushed the preinstall-add-profile-and-results branch 5 times, most recently from 0bec84e to 878ee98 Compare October 17, 2024 10:11
@chrisccoulson chrisccoulson force-pushed the preinstall-add-profile-and-results branch 2 times, most recently from 5b74975 to 42dfed0 Compare November 13, 2024 18:45
@chrisccoulson chrisccoulson changed the title preinstall: Add CheckResult and WithAutoPCRProfile APIs preinstall: Add CheckResult and WithAutoTCGPCRProfile APIs Nov 15, 2024
CheckResult is returned from RunChecks on successful completion. It is
JSON serializable and intended to be supplied later on to
WithAutoTCGPCRProfile along with some user customization flags (defined
by PCRProfileOptionsFlags) in order to generate an option that can be
supplied to secboot_efi.AddPCRProfile.

Note that some user options don't work yet because of missing PCR
support, although these limitations will be addressed later. Even so,
some options may still fail depending on the CheckResult flags.
@chrisccoulson chrisccoulson force-pushed the preinstall-add-profile-and-results branch from 42dfed0 to 0c76820 Compare November 21, 2024 11:30
@chrisccoulson chrisccoulson marked this pull request as ready for review November 21, 2024 11:38
Copy link
Collaborator

@pedronis pedronis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did a first pass, probably a good idea for @valentindavid and maybe someone more from your side to look it, Mate?

br := bufio.NewReader(r)
for {
line, err := br.ReadString('\n')
fmt.Fprintf(w, "%*s%s", n, "", line)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we really do this print if line is "" and err is io.EOF ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've refactored this function a bit (it uses bufio.Scanner now and it's been renamed to make it clearer what its intended use is.

"startup-locality-not-protected": StartupLocalityNotProtected,
}

type x509CertificateIdJSON struct {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: I would split out the x509Id types to maybe their own x509id.go file

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved these types into their own file.

Comment on lines 518 to 523
if r.Warnings != nil && len(r.Warnings.Errs) > 0 {
fmt.Fprintf(w, "- Warnings:\n")
for i := 0; i < len(r.Warnings.Errs); i++ {
fmt.Fprintf(w, "%s\n", indentLines(2, "- "+r.Warnings.Errs[i].Error()))
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this bit of the code is not exercised

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a test for this now.

Copy link
Contributor

@valentindavid valentindavid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just minor comments.

w := new(bytes.Buffer)
fmt.Fprintf(w, "one or more errors detected:\n")
for _, err := range e.Errs {
fmt.Fprintf(w, "%s\n", indentLines(2, "- "+err.Error()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if we have errors err1-line1\nerr1-line2 and err2-line1\nerr2-line2, the output will look like:

  - err1-line1
  err1-line2
  - err2-line1
  err2-line2

I feel like the - should not be indented so that the lines match.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expected formatting in the example would be:

- err1-line1
  err1-line2
- err2-line1
  err2-line2

In any case, I've refactored indentLines now and called it something else (makeIndentedListItem) to make its purpose clearer. I've also added some formatting tests for code that makes use of it too.

// don't extend anything to the TPM, breaking the root-of-trust. This is true of the Microsoft UEFI CA 2011,
// and for now, we assume to be true of the 2023 UEFI CA unless Microsoft are more transparent about what is
// signed under this CA). It's also assumed to be true for any unrecognized CAs.
// This can be overridden with PCRProfileOptionsTrustCAsForBootCode.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/PCRProfileOptionsTrustCAsForBootCode/PCRProfileOptionTrustCAsForBootCode/

(Options -> Option)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've fixed this now.

// (ie, they may have signed code in the past that can defeat our security model. This is true of the Microsoft
// UEFI CA 2011, and for now, we assume to be true of the 2023 UEFI CA unless Microsoft are more transparent about
// what they sign under this CA). It's also assumed to be true for any unrecognized CAs.
// This can be overridden with PCRProfileOptionsTrustCAsForVARSuppliedDrivers.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this one.

Comment on lines +88 to +89
{internal_efi.MSUefiCA2011, 0},
{internal_efi.MSUefiCA2023, 0}, // be conservative here for now, but will we be able to set the authorityTrustDrivers flag for the MS2023 CA?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to make sure I understand here.

We do not really need to put anything with authorityTrust value 0 in this list, because all of those are not trusted. And any certificated not found in the authorityTrustDataSet will make trust &= certTrust be trust &= 0 which will be then distrust. The only use here for knownCAs is that maybe one day some CA certicates are trusted and we will add them in this list with a non 0 value for authorityTrust.

So here MSUefiCA2011 and MSUefiCA2023 are just explicitly distrusted, but if we removed them from the list, it would be the same.

Did I understand it correctly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be nice to have a test that uses a cert that is not in knownCAs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You understood correctly - these are both explicitly distrusted, as is any certificate that doesn't appear in this list. Eventually we'll get to the point where we want security features that will require our own CA, which will be added here with both trust flags set (because we know we'll never use it to sign drivers). It also remains to be seen whether Microsoft will be any more open wrt to their signing requirements with the new UEFI CA, particularly wrt the signing of option ROMs. If this improves, we might be able to change one flag for this CA, but right now, I don't think it's been used to sign anything.

Also fix the implementation of RunChecksErrors.Error().
This renames indentLines to makeIndentedListItem to make it clear that
it's used to help printing out lists of things (in this context, mostly
lists of errors).

It also refactors it to use bufio.Scanner.

Some additional test cases are added to test the formatting of
RunChecksErrors, both on its own and embedded as a warning inside of
CheckResult.
Copy link
Collaborator

@pedronis pedronis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

Copy link
Contributor

@valentindavid valentindavid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you.

@chrisccoulson chrisccoulson merged commit 1224447 into canonical:master Dec 4, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants