Skip to content

Allow enrolling custom db and KEK certs #217

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

Merged
merged 1 commit into from
May 14, 2023
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
26 changes: 24 additions & 2 deletions certs/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package certs
import (
"embed"
"fmt"
"os"
"path/filepath"

"github.com/foxboron/go-uefi/efi/signature"
Expand All @@ -17,6 +18,7 @@ var (
oemGUID = map[string]util.EFIGUID{
"microsoft": *util.StringToGUID("77fa9abd-0359-4d32-bd60-28f4e78f784b"),
"tpm-eventlog": *util.StringToGUID("4f52704f-494d-41736e-6e6f79696e6721"),
"custom": *util.StringToGUID("88a69775-5ad7-45d9-9f34-cec43e1f1989"),
}
)

Expand All @@ -29,7 +31,7 @@ func GetVendors() []string {
return oems
}

func GetCerts(oem string, variable string) (*signature.SignatureDatabase, error) {
func GetOEMCerts(oem string, variable string) (*signature.SignatureDatabase, error) {
GUID, ok := oemGUID[oem]
if !ok {
return nil, fmt.Errorf("invalid OEM")
Expand All @@ -49,10 +51,30 @@ func GetCerts(oem string, variable string) (*signature.SignatureDatabase, error)
return sigdb, nil
}

func GetCustomCerts(keydir string, variable string) (*signature.SignatureDatabase, error) {
GUID, ok := oemGUID["custom"]
if !ok {
return nil, fmt.Errorf("GUID for custom certs not found")
}
sigdb := signature.NewSignatureDatabase()
files, _ := os.ReadDir(filepath.Join(keydir, "custom", variable))
for _, file := range files {
path := filepath.Join(keydir, "custom", variable, file.Name())
if !file.Type().IsRegular() {
continue
}
buf, _ := os.ReadFile(path)
if err := sigdb.Append(signature.CERT_X509_GUID, GUID, buf); err != nil {
return nil, err
}
}
return sigdb, nil
}

func GetDefaultCerts(variable string) (*signature.SignatureDatabase, error) {
sigdb := signature.NewSignatureDatabase()
for _, oem := range defaultCerts {
db, err := GetCerts(oem, variable)
db, err := GetOEMCerts(oem, variable)
if err != nil {
return nil, err
}
Expand Down
12 changes: 6 additions & 6 deletions certs/certs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ func TestGetVendors(t *testing.T) {
}
}

func TestGetCertsDb(t *testing.T) {
db, _ := GetCerts("microsoft", "db")
func TestGetOEMCertsDb(t *testing.T) {
db, _ := GetOEMCerts("microsoft", "db")
if len(*db) != 2 {
t.Fatalf("GetCerts: not correct size, got %d, expected %d", len(*db), 2)
t.Fatalf("GetOEMCerts: not correct size, got %d, expected %d", len(*db), 2)
}
}

func TestGetCertsKek(t *testing.T) {
kek, _ := GetCerts("microsoft", "KEK")
func TestGetOEMCertsKek(t *testing.T) {
kek, _ := GetOEMCerts("microsoft", "KEK")
if len(*kek) != 1 {
t.Fatalf("GetCerts: not correct size, got %d, expected %d", len(*kek), 1)
t.Fatalf("GetOEMCerts: not correct size, got %d, expected %d", len(*kek), 1)
}
}

Expand Down
25 changes: 23 additions & 2 deletions cmd/sbctl/enroll-keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type EnrollKeysCmdOptions struct {
IgnoreImmutable bool
Force bool
TPMEventlogChecksums bool
Custom bool
}

var (
Expand Down Expand Up @@ -96,20 +97,36 @@ func KeySync(guid util.EFIGUID, keydir string, oems []string) error {
logging.Print("\nWith vendor keys from microsoft...")

// db
oemSigDb, err := certs.GetCerts(oem, "db")
oemSigDb, err := certs.GetOEMCerts(oem, "db")
if err != nil {
return fmt.Errorf("could not enroll db keys: %w", err)
}
sigdb.AppendDatabase(oemSigDb)

// KEK
oemSigKEK, err := certs.GetCerts(oem, "KEK")
oemSigKEK, err := certs.GetOEMCerts(oem, "KEK")
if err != nil {
return fmt.Errorf("could not enroll KEK keys: %w", err)
}
sigkek.AppendDatabase(oemSigKEK)

// We are not enrolling PK keys from Microsoft
case "custom":
logging.Print("\nWith custom keys...")

// db
customSigDb, err := certs.GetCustomCerts(keydir, "db")
if err != nil {
return fmt.Errorf("could not enroll custom db keys: %w", err)
}
sigdb.AppendDatabase(customSigDb)

// KEK
customSigKEK, err := certs.GetCustomCerts(keydir, "KEK")
if err != nil {
return fmt.Errorf("could not enroll custom KEK keys: %w", err)
}
sigkek.AppendDatabase(customSigKEK)
}
}
}
Expand Down Expand Up @@ -138,6 +155,9 @@ func RunEnrollKeys(cmd *cobra.Command, args []string) error {
if enrollKeysCmdOptions.TPMEventlogChecksums {
oems = append(oems, "tpm-eventlog")
}
if enrollKeysCmdOptions.Custom {
oems = append(oems, "custom")
}
if !enrollKeysCmdOptions.IgnoreImmutable {
if err := sbctl.CheckImmutable(); err != nil {
return err
Expand Down Expand Up @@ -166,6 +186,7 @@ func vendorFlags(cmd *cobra.Command) {
f := cmd.Flags()
f.BoolVarP(&enrollKeysCmdOptions.MicrosoftKeys, "microsoft", "m", false, "include microsoft keys into key enrollment")
f.BoolVarP(&enrollKeysCmdOptions.TPMEventlogChecksums, "tpm-eventlog", "t", false, "include TPM eventlog checksums into the db database")
f.BoolVarP(&enrollKeysCmdOptions.Custom, "custom", "c", false, "include custom db and KEK")
}

func enrollKeysCmdFlags(cmd *cobra.Command) {
Expand Down
14 changes: 13 additions & 1 deletion docs/sbctl.8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ EFI signing commands
database.
See **Option ROM***.

This feature is experimental.
This feature is experimental

*-c*, *--custom*;;
Enroll custom KEK and db certificates from "/usr/share/secureboot/keys/custom/KEK/"
and "/usr/share/secureboot/keys/custom/db/", respectively.

*--yes-this-might-brick-my-machine*, **--yolo**;;
Ignore the Option ROM error and continue enrolling keys into the
Expand Down Expand Up @@ -361,6 +365,14 @@ Files
**/usr/share/secureboot/keys/PK/PK.{pem,key}**::
Contains the Platform Key.

**/usr/share/secureboot/keys/custom/KEK/***::
Contains custom certificates which will be added to the firmware as
additional Key Exchange Keys.

**/usr/share/secureboot/keys/custom/db/***::
Contains custom certificates which will be added to the firmware
Signature Database.


See Also
--------
Expand Down