Skip to content

Commit

Permalink
feat: add option to remove specific certs from db instead of an entir…
Browse files Browse the repository at this point in the history
…e reset

Signed-off-by: Fabian Wienand <fabian.wienand@9elements.com>
  • Loading branch information
Fabian Wienand committed Sep 14, 2023
1 parent ce1e15e commit fb65331
Showing 1 changed file with 77 additions and 15 deletions.
92 changes: 77 additions & 15 deletions cmd/sbctl/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@ import (
"errors"
"fmt"
"path/filepath"
"strings"
"syscall"

"github.com/foxboron/go-uefi/efi"
"github.com/foxboron/go-uefi/efi/signature"
"github.com/foxboron/go-uefi/efi/util"
"github.com/foxboron/sbctl"
"github.com/foxboron/sbctl/fs"
"github.com/foxboron/sbctl/logging"
"github.com/foxboron/sbctl/stringset"
"github.com/spf13/cobra"
)

type resetCmdOptions struct {
Partial stringset.StringSet
Partial stringset.StringSet
CertFiles string
}

var (
Expand All @@ -38,21 +42,27 @@ func resetKeys() error {
return nil
}

var paths []string

if resetCmdOpts.CertFiles != "" {
paths = strings.Split(resetCmdOpts.CertFiles, ";")
}

switch partial := resetCmdOpts.Partial.Value; partial {
case "db":
if err := resetDB(); err != nil {
if err := resetDB(paths...); err != nil {
return err
}
case "dbx":
if err := resetDBX(); err != nil {
if err := resetDBX(paths...); err != nil {
return err
}
case "KEK":
if err := resetKEK(); err != nil {
if err := resetKEK(paths...); err != nil {
return err
}
case "PK":
if err := resetPK(); err != nil {
if err := resetPK(paths...); err != nil {
return err
}
default:
Expand All @@ -62,11 +72,11 @@ func resetKeys() error {
return nil
}

func resetDB() error {
func resetDB(certPaths ...string) error {
KEKKey := filepath.Join(sbctl.KeysPath, "KEK", "KEK.key")
KEKPem := filepath.Join(sbctl.KeysPath, "KEK", "KEK.pem")

if err := resetDatabase(KEKKey, KEKPem, "db"); err != nil {
if err := resetDatabase(KEKKey, KEKPem, "db", certPaths...); err != nil {
return err
}

Expand All @@ -75,11 +85,11 @@ func resetDB() error {
return nil
}

func resetDBX() error {
func resetDBX(certPaths ...string) error {
KEKKey := filepath.Join(sbctl.KeysPath, "KEK", "KEK.key")
KEKPem := filepath.Join(sbctl.KeysPath, "KEK", "KEK.pem")

if err := resetDatabase(KEKKey, KEKPem, "dbx"); err != nil {
if err := resetDatabase(KEKKey, KEKPem, "dbx", certPaths...); err != nil {
return err
}

Expand All @@ -88,11 +98,11 @@ func resetDBX() error {
return nil
}

func resetKEK() error {
func resetKEK(certPaths ...string) error {
PKKey := filepath.Join(sbctl.KeysPath, "PK", "PK.key")
PKPem := filepath.Join(sbctl.KeysPath, "PK", "PK.pem")

if err := resetDatabase(PKKey, PKPem, "KEK"); err != nil {
if err := resetDatabase(PKKey, PKPem, "KEK", certPaths...); err != nil {
return err
}

Expand All @@ -101,11 +111,11 @@ func resetKEK() error {
return nil
}

func resetPK() error {
func resetPK(certPaths ...string) error {
PKKey := filepath.Join(sbctl.KeysPath, "PK", "PK.key")
PKPem := filepath.Join(sbctl.KeysPath, "PK", "PK.pem")

if err := resetDatabase(PKKey, PKPem, "PK"); err != nil {
if err := resetDatabase(PKKey, PKPem, "PK", certPaths...); err != nil {
return err
}

Expand All @@ -114,7 +124,9 @@ func resetPK() error {
return nil
}

func resetDatabase(signerKey, signerPem string, efivar string) error {
func resetDatabase(signerKey, signerPem string, efivar string, certPaths ...string) error {
var buf []byte

key, err := util.ReadKeyFromFile(signerKey)
if err != nil {
return err
Expand All @@ -125,7 +137,56 @@ func resetDatabase(signerKey, signerPem string, efivar string) error {
return err
}

signedBuf, err := efi.SignEFIVariable(key, crt, efivar, []byte{})
if len(certPaths) != 0 {
var (
db *signature.SignatureDatabase
err error
)

switch efivar {
case "db":
db, err = efi.Getdb()
case "dbx":
db, err = efi.Getdbx()
case "KEK":
db, err = efi.GetKEK()
case "PK":
db, err = efi.GetPK()
}

if err != nil {
return err
}

uuid, err := sbctl.GetGUID()
if err != nil {
return err
}

guid := util.StringToGUID(uuid.String())

for _, certPath := range certPaths {
buf, err := fs.ReadFile(certPath)
if err != nil {
return fmt.Errorf("can't read new certificate from path %s: %v", certPath, err)
}

cert, err := util.ReadCert(buf)
if err != nil {
return err
}
if err := db.Remove(signature.CERT_X509_GUID, *guid, cert.Raw); err != nil {
return err
}

}

buf = db.Bytes()
} else {
buf = []byte{}
}

signedBuf, err := efi.SignEFIVariable(key, crt, efivar, buf)
if err != nil {
return err
}
Expand All @@ -150,6 +211,7 @@ func RunReset(cmd *cobra.Command, args []string) error {
func resetKeysCmdFlags(cmd *cobra.Command) {
f := cmd.Flags()
f.VarPF(&resetCmdOpts.Partial, "partial", "p", "reset a partial set of keys")
f.StringVarP(&resetCmdOpts.CertFiles, "cert-files", "c", "", "optional paths to certificate file to remove from the hierachy (seperate individual paths by ';')")
}

func init() {
Expand Down

0 comments on commit fb65331

Please sign in to comment.