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

Add ability to parse db and dbx to return a Database usable for policies #126

Open
alexmwu opened this issue Jul 2, 2021 · 4 comments
Open

Comments

@alexmwu
Copy link
Contributor

alexmwu commented Jul 2, 2021

For db additions, this would look more like take an existing Database/empty Database and update with hashes and certificates.

  • AddCertificate, AddHash
    For dbx, we should support reading a dbx update file from https://uefi.org/revocationlistfile that then returns a corresponding Database containing the dbx hashes (and certs, if any). Currently, this is done manually using https://github.com/rhboot/dbxtool.
  • ParseDatabaseListFile(updateFile []bytes). This will return a Database object that corresponds to the file. Likely this will only be used for dbx files as I'm not aware of any db files that uses the same update format.

This will allow us to embed raw dbx updates and use them to build policy constants, as well as supply that ability to any users of the policy APIs.

@Foxboron
Copy link

For parsing efivarfs you can look at my library; https://github.com/Foxboron/go-uefi

There is also one from canonical: https://github.com/canonical/go-efilib

@alexmwu
Copy link
Contributor Author

alexmwu commented Dec 21, 2021

Thanks for the suggestion! I'm assuming ReadSignatureDatabase is what we want? https://github.com/Foxboron/go-uefi/blob/3d898a764ffd5107102e161c276a8cca63bcb41e/efi/signature/signature_database.go#L155
We're essentially looking for functionality like https://github.com/rhboot/dbxtool, as we want to pull it from a dbx update file like the ones above.

@Foxboron
Copy link

You don't really need to parse it unless you want to resign it. If you have the Microsoft Key Exchange Key enrolled you can do:

package main

import (
	"bytes"
	"io"
	"log"
	"net/http"

	"github.com/foxboron/go-uefi/efi"
	"github.com/foxboron/go-uefi/efi/attributes"
)

func main() {
	response, err := http.Get("https://uefi.org/sites/default/files/resources/dbxupdate_x64.bin")
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()

	buf := new(bytes.Buffer)
	io.Copy(buf, response.Body)

	attrs := efi.ValidAttributes["dbx"]
	if err := attributes.WriteEfivars("dbx", attrs|attributes.EFI_VARIABLE_APPEND_WRITE, buf.Bytes()); err != nil {
		log.Fatal(err)
	}
}

If you want to resign it you can do something like this

package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"

	"github.com/foxboron/go-uefi/efi"
	"github.com/foxboron/go-uefi/efi/attributes"
	"github.com/foxboron/go-uefi/efi/signature"
	"github.com/foxboron/go-uefi/efi/util"
)

func main() {
	key := flag.String("key", "", "Key")
	cert := flag.String("cert", "", "Certificate")
	if len(os.Args) == 1 {
		fmt.Println("rewritedbx: -key <key> -cert <cert> [dbx]")
	}
	response, err := http.Get("https://uefi.org/sites/default/files/resources/dbxupdate_x64.bin")
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()

	Cert, _ := util.ReadCertFromFile(*cert)
	Key, _ := util.ReadKeyFromFile(*key)

	buf := new(bytes.Buffer)
	io.Copy(buf, response.Body)

	// Remove the Authentication header
	signature.ReadEFIVariableAuthencation2(buf)

	// Get the default Attributes,
	// The dbxupdate binary also uses the APPEND_WRITE attribute, so we include that
	attrs := efi.ValidAttributes["dbx"] | attributes.EFI_VARIABLE_APPEND_WRITE

	// Sign variable
	signedBuf, err := efi.SignEFIVariableWithAttr(Key, Cert, "dbx", buf.Bytes(), attrs)
	if err != nil {
		log.Fatal(err)
	}

	// Write the variable
	if err := attributes.WriteEfivars("dbx", attrs, signedBuf); err != nil {
		log.Fatal(err)
	}
}

If you want to inspect the list and do any modification you can use ReadSignatureDatabase.

The API might not be perfect, but it works fairly well :)

@Foxboron
Copy link

Foxboron commented Dec 21, 2021

Right, I see now you want them for policy objects. The above examples might be a bit useless.

For an example parsing the data you can look at my little efianalyze binary: https://github.com/Foxboron/go-uefi/blob/master/cmd/efianalyze/main.go#L95

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

No branches or pull requests

2 participants