From 1bfd3eb238d6084774380cac967cb091bfd6c074 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 25 Aug 2023 09:14:26 -0400 Subject: [PATCH 1/3] Run gofmt and commit changes. These are whitespace only changes, the result of running gofmt. Signed-off-by: Scott Moser --- cmd/trust/computepcr.go | 2 +- cmd/trust/extendpcr.go | 2 +- cmd/trust/main.go | 1 - cmd/trust/policygen.go | 4 ++-- cmd/trust/project.go | 2 +- cmd/trust/sign.go | 14 +++++++------- cmd/trust/sudi.go | 8 ++++---- cmd/trust/utils.go | 24 ++++++++++++------------ cmd/trust/verify.go | 10 +++++----- pkg/trust/artifacts.go | 4 ++-- pkg/trust/cert.go | 4 ++-- pkg/trust/computepcr7.go | 11 ++++++----- pkg/trust/tpm2.go | 39 +++++++++++++++++++++------------------ pkg/trust/tpmpolicy.go | 2 +- pkg/trust/utils.go | 12 ++++++------ 15 files changed, 71 insertions(+), 68 deletions(-) diff --git a/cmd/trust/computepcr.go b/cmd/trust/computepcr.go index 490f17e..165ad33 100644 --- a/cmd/trust/computepcr.go +++ b/cmd/trust/computepcr.go @@ -4,8 +4,8 @@ import ( "errors" "fmt" - "github.com/urfave/cli" "github.com/project-machine/trust/pkg/trust" + "github.com/urfave/cli" ) var computePCR7Cmd = cli.Command{ diff --git a/cmd/trust/extendpcr.go b/cmd/trust/extendpcr.go index e36b8ab..468579c 100644 --- a/cmd/trust/extendpcr.go +++ b/cmd/trust/extendpcr.go @@ -1,8 +1,8 @@ package main import ( - "github.com/urfave/cli" "github.com/project-machine/trust/pkg/trust" + "github.com/urfave/cli" ) var extendPCR7Cmd = cli.Command{ diff --git a/cmd/trust/main.go b/cmd/trust/main.go index b2eba66..1f6af64 100644 --- a/cmd/trust/main.go +++ b/cmd/trust/main.go @@ -39,7 +39,6 @@ func main() { // verify verifyCmd, - } app.Flags = []cli.Flag{ cli.BoolFlag{ diff --git a/cmd/trust/policygen.go b/cmd/trust/policygen.go index 6fa15ea..f4e5c97 100644 --- a/cmd/trust/policygen.go +++ b/cmd/trust/policygen.go @@ -1,11 +1,11 @@ package main import ( - "os" "errors" + "os" - "github.com/urfave/cli" "github.com/project-machine/trust/pkg/trust" + "github.com/urfave/cli" ) var tpmPolicyGenCmd = cli.Command{ diff --git a/cmd/trust/project.go b/cmd/trust/project.go index 85d9411..7ac962e 100644 --- a/cmd/trust/project.go +++ b/cmd/trust/project.go @@ -93,7 +93,7 @@ func doListProjects(ctx *cli.Context) error { return nil } - dirs, err := os.ReadDir(keysetPath) + dirs, err := os.ReadDir(keysetPath) if err != nil { return fmt.Errorf("Failed reading keys directory %q: %w", trustDir, err) } diff --git a/cmd/trust/sign.go b/cmd/trust/sign.go index d145bc0..1d865df 100644 --- a/cmd/trust/sign.go +++ b/cmd/trust/sign.go @@ -9,25 +9,25 @@ import ( ) var signCmd = cli.Command{ - Name: "sign", + Name: "sign", Usage: "Create Digital Signature", Subcommands: []cli.Command{ cli.Command{ - Name: "efi", - Action: doSignEFI, - Usage: "sign an efi binary", + Name: "efi", + Action: doSignEFI, + Usage: "sign an efi binary", ArgsUsage: "", Flags: []cli.Flag{ cli.StringFlag{ - Name: "key", + Name: "key", Usage: "The private key to sign the efi binary.", }, cli.StringFlag{ - Name: "cert", + Name: "cert", Usage: "The X509 certificate for creating signature.", }, cli.StringFlag{ - Name: "output", + Name: "output", Usage: "PathName for the signed efi binary.", }, }, diff --git a/cmd/trust/sudi.go b/cmd/trust/sudi.go index 49637ab..0eef5b5 100644 --- a/cmd/trust/sudi.go +++ b/cmd/trust/sudi.go @@ -35,8 +35,9 @@ var sudiCmd = cli.Command{ } // ~/.local/share/machine/trust/keys/ -// keyset1/manifest/project-name/{uuid,privkey.pem,cert.pem} -// keyset1/manifest/project-name/sudi/host-serial/{uuid,privkey.pem,cert.pem} +// +// keyset1/manifest/project-name/{uuid,privkey.pem,cert.pem} +// keyset1/manifest/project-name/sudi/host-serial/{uuid,privkey.pem,cert.pem} func doGenSudi(ctx *cli.Context) error { args := ctx.Args() if len(args) != 2 && len(args) != 3 { @@ -90,7 +91,6 @@ func doGenSudi(ctx *cli.Context) error { return errors.Wrapf(err, "Failed creating new SUDI directory") } - if err := SignCert(&certTmpl, caCert, caKey, snPath); err != nil { os.RemoveAll(snPath) return errors.Wrapf(err, "Failed creating new SUDI keypair") @@ -134,7 +134,7 @@ func doListSudi(ctx *cli.Context) error { } dir := filepath.Join(projPath, "sudi") - serials, err := os.ReadDir(dir) + serials, err := os.ReadDir(dir) if err != nil { return fmt.Errorf("Failed reading sudi directory %q: %w", dir, err) } diff --git a/cmd/trust/utils.go b/cmd/trust/utils.go index 5b46e3d..f2f4176 100644 --- a/cmd/trust/utils.go +++ b/cmd/trust/utils.go @@ -6,16 +6,16 @@ import ( "crypto/sha1" "crypto/x509" "crypto/x509/pkix" - "encoding/pem" "encoding/hex" "encoding/json" + "encoding/pem" "fmt" "io" "math/big" "os" "path/filepath" - "time" "strings" + "time" "github.com/google/uuid" "github.com/pkg/errors" @@ -490,9 +490,9 @@ func addPcr7data(keysetName string, pdata pcr7Data) error { var tpmpolAdminpubkey, tpmpolLukspubkey *rsa.PublicKey var jsonInfo []byte type PCR7info struct { - Key string `json:"key"` + Key string `json:"key"` KeyType string `json:"key_type"` - Date string `json:"est_date"` + Date string `json:"est_date"` Comment string `json:"comment"` } @@ -522,7 +522,7 @@ func addPcr7data(keysetName string, pdata pcr7Data) error { pcr7dataPath := filepath.Join(keysetPath, "pcr7data/policy-2") if !PathExists(pcr7dataPath) { err = os.MkdirAll(keysetPath, 0750) - if err != nil { + if err != nil { return err } } else { @@ -554,7 +554,7 @@ func addPcr7data(keysetName string, pdata pcr7Data) error { } tpmpolLukspubkey, err = extractPubkey(filepath.Join(keysetPath, "tpmpol-luks/cert.pem")) if err != nil { - return err + return err } err = savePubkeytoFile(tpmpolLukspubkey, filepath.Join(pcr7dataPubkeys, "luks-snakeoil.pem")) if err != nil { @@ -589,18 +589,18 @@ func addPcr7data(keysetName string, pdata pcr7Data) error { date := time.Now() formatted := date.Format("2006-01-02") timestamp := strings.ReplaceAll(formatted, "-", "") - info := &PCR7info{Key: keysetName, KeyType: pcr, Date: timestamp, Comment: "mos"+" "+keysetName} + info := &PCR7info{Key: keysetName, KeyType: pcr, Date: timestamp, Comment: "mos" + " " + keysetName} jsonInfo, err = json.Marshal(info) if err != nil { return err } if err = os.WriteFile(jsonFile, jsonInfo, 0644); err != nil { - return err + return err } // write out info switch pcr { - case "limited" : + case "limited": pcrFile := filepath.Join(indexdir, "pcr_limited.bin") if err = os.WriteFile(pcrFile, pdata.limited, 0644); err != nil { return err @@ -613,7 +613,7 @@ func addPcr7data(keysetName string, pdata pcr7Data) error { if err = os.WriteFile(pcrFile, pdata.production, 0644); err != nil { return err } - case "tpm" : + case "tpm": // Create policy file and Sign the policy policyFile := filepath.Join(indexdir, "tpm_passwd.policy.signed") if err = os.WriteFile(policyFile, pdata.passwdPolicyDigest, 0644); err != nil { @@ -623,7 +623,7 @@ func addPcr7data(keysetName string, pdata pcr7Data) error { if err = trust.Sign(policyFile, policyFile, signingKey); err != nil { return err } - case "production" : + case "production": // Sign the policy policyFile := filepath.Join(indexdir, "tpm_luks.policy.signed") if err = os.WriteFile(policyFile, pdata.luksPolicyDigest, 0644); err != nil { @@ -633,7 +633,7 @@ func addPcr7data(keysetName string, pdata pcr7Data) error { if err = trust.Sign(policyFile, policyFile, signingKey); err != nil { return err } - default : + default: return errors.New("Unrecognized uki key") } } diff --git a/cmd/trust/verify.go b/cmd/trust/verify.go index 5884631..bf037a1 100644 --- a/cmd/trust/verify.go +++ b/cmd/trust/verify.go @@ -9,17 +9,17 @@ import ( ) var verifyCmd = cli.Command{ - Name: "verify", + Name: "verify", Usage: "Verify a digital Signature", Subcommands: []cli.Command{ cli.Command{ - Name: "efi", - Action: doVerifyEFI, - Usage: "verify a signed efi binary", + Name: "efi", + Action: doVerifyEFI, + Usage: "verify a signed efi binary", ArgsUsage: "", Flags: []cli.Flag{ cli.StringFlag{ - Name: "cert", + Name: "cert", Usage: "The X509 certificate to verify signature.", }, }, diff --git a/pkg/trust/artifacts.go b/pkg/trust/artifacts.go index 11d01a3..98d7c41 100644 --- a/pkg/trust/artifacts.go +++ b/pkg/trust/artifacts.go @@ -307,7 +307,7 @@ func findSection(lines []string, which string) (int64, int64, bool) { } func extractObj(objdump []string, dir string, piece string) error { - outName := filepath.Join(dir, piece + ".out") + outName := filepath.Join(dir, piece+".out") offset, size, found := findSection(objdump, piece) if !found { return fmt.Errorf("Symbol %s not found", piece) @@ -387,7 +387,7 @@ func ReplaceManifestCert(dir, newCert string) (string, error) { } err := RunCommand("objcopy", - "--add-section=.initrd=" + initrdgz, + "--add-section=.initrd="+initrdgz, "--change-section-vma=.initrd=0x3000000", k2, kret) if err != nil { diff --git a/pkg/trust/cert.go b/pkg/trust/cert.go index 34faa62..83c4017 100644 --- a/pkg/trust/cert.go +++ b/pkg/trust/cert.go @@ -10,8 +10,8 @@ import ( "os" "github.com/foxboron/go-uefi/efi/pecoff" - "github.com/foxboron/go-uefi/efi/util" "github.com/foxboron/go-uefi/efi/pkcs7" + "github.com/foxboron/go-uefi/efi/util" ) // VerifyCert checks that the product cert was signed by the @@ -145,7 +145,7 @@ func SignEFI(sourcePath, signedPath, keyPath, certPath string) error { // Get the key to use for signing privkey, err := util.ReadKeyFromFile(keyPath) if err != nil { - return fmt.Errorf("Failed reading (%q): %w", keyPath, err) + return fmt.Errorf("Failed reading (%q): %w", keyPath, err) } cert, err := util.ReadCertFromFile(certPath) if err != nil { diff --git a/pkg/trust/computepcr7.go b/pkg/trust/computepcr7.go index c46860a..854e26e 100644 --- a/pkg/trust/computepcr7.go +++ b/pkg/trust/computepcr7.go @@ -18,6 +18,7 @@ import ( const ShimLockGUID = "605dab50-e046-4300-abb6-3dd810dd8b23" const ShimVendordbGUID = "00000000-0000-0000-0000-000000000000" const SBAT = "sbat,1,2021030218\012" + // Using DBX data from current ovmf_vars.fd in bootkit. // Revisit if ovmf or dbx changes. We need to eventually manage dbx. const DBX = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" @@ -49,7 +50,7 @@ func getCertGUID(guidfile string) (efi.GUID, error) { return efi.GUID{}, fmt.Errorf("Failed to read %q: (%w)", guidfile, err) } certGuid, err := efi.DecodeGUIDString(string(cGuid)) - if err != nil { + if err != nil { return efi.GUID{}, fmt.Errorf("Failed to decode the guid in %q: (%w)", guidfile, err) } @@ -183,14 +184,14 @@ func getHash(unicodeName string, varGuid efi.GUID, keysetPath string) ([]byte, e func ComputePCR7(keysetName string) ([]byte, []byte, []byte, error) { var pcr7Val = []byte{00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, - 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, - 00, 00, 00, 00, 00, 00, 00, 00, 00, 00} + 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, + 00, 00, 00, 00, 00, 00, 00, 00, 00, 00} // List of uefi Secure boot vars that get measured. // It includes certs that get measured at boot. UKI certs are measured // separately since we have 3 possible. Also measured in this order. - var uefiMeasured = []string{"SecureBoot", "PK", "KEK", "db", "dbx","separator", - "shim-cert", "SbatLevel", "MokListTrusted" } + var uefiMeasured = []string{"SecureBoot", "PK", "KEK", "db", "dbx", "separator", + "shim-cert", "SbatLevel", "MokListTrusted"} shimLockGuid, err := efi.DecodeGUIDString(ShimLockGUID) if err != nil { diff --git a/pkg/trust/tpm2.go b/pkg/trust/tpm2.go index c717c8a..3e962fe 100644 --- a/pkg/trust/tpm2.go +++ b/pkg/trust/tpm2.go @@ -40,16 +40,16 @@ func init() { } type tpm2V3Context struct { - dataDir string // our data directory under which we keep files - keyClass string // release, dev, or snakeoil - adminPwd string // provisioned tpm admin password - pubkeyName string // pubkeyname from tpm2_loadexternal - pubkeyContext string // pubkeycontext from tpm2_loadexternal - tmpDir string // directory for tpm2 sessions and other io - sessionFile string - Keyctx string // pathname to file from tpm2_createprimary - PlainPart *DiskPart // Disk partition with plaintext provisioned data - CryptPart *DiskPart // Disk partition with encrypted provisioned data + dataDir string // our data directory under which we keep files + keyClass string // release, dev, or snakeoil + adminPwd string // provisioned tpm admin password + pubkeyName string // pubkeyname from tpm2_loadexternal + pubkeyContext string // pubkeycontext from tpm2_loadexternal + tmpDir string // directory for tpm2 sessions and other io + sessionFile string + Keyctx string // pathname to file from tpm2_createprimary + PlainPart *DiskPart // Disk partition with plaintext provisioned data + CryptPart *DiskPart // Disk partition with encrypted provisioned data } type DiskPart struct { @@ -140,11 +140,13 @@ func getPoldir(pdir string) string { } // ChooseSignData: assumes that someone has placed the pcr7data -// under SignDataDir (/pcr7data). Finds the pcr7 data for the -// running host+shim+kernel. +// +// under SignDataDir (/pcr7data). Finds the pcr7 data for the +// running host+shim+kernel. +// // Returns: -// 1. the signdata directory name for this host's pcr7 value -// 2. the type of key this was signed by (e.g. "production") +// 1. the signdata directory name for this host's pcr7 value +// 2. the type of key this was signed by (e.g. "production") func ChooseSignData() (string, string, error) { polDir := getPoldir(SignDataDir) if polDir == "" { @@ -249,9 +251,9 @@ func NewTpm2() (*tpm2V3Context, error) { } t = &tpm2V3Context{ - dataDir: dataDir, - tmpDir: tmpd, - keyClass: keyClass, + dataDir: dataDir, + tmpDir: tmpd, + keyClass: keyClass, } return t, nil } @@ -306,7 +308,7 @@ func setupFactory() (string, error) { } err = os.Mkdir(dest, 0700) - if err != nil { + if err != nil { return dest, fmt.Errorf("Could not create %s on tmpfs: %w", dest, err) } return dest, nil @@ -322,6 +324,7 @@ func (t *tpm2V3Context) Close() { } type KeyType string + const ( limitedKey KeyType = "limited" productionKey KeyType = "production" diff --git a/pkg/trust/tpmpolicy.go b/pkg/trust/tpmpolicy.go index 71718e9..3cf1800 100644 --- a/pkg/trust/tpmpolicy.go +++ b/pkg/trust/tpmpolicy.go @@ -40,7 +40,7 @@ func GenLuksPolicy(prodPcr7 []byte, policyVersion string) ([]byte, error) { // Create a tpm2.NVPublic structure that resembles what we would have // done via an nvwrite of the policy version to the index. // Include TPMA_NV_WRITTEN attribute indicating the index has been written to. - nvpub := tpm2.NVPublic{Index: tpm2.Handle(TPM2IndexEAVersion), NameAlg: tpm2.HashAlgorithmSHA256, Attrs: tpm2.NVTypeOrdinary.WithAttrs(tpm2.AttrNVOwnerWrite|tpm2.AttrNVOwnerRead|tpm2.AttrNVAuthRead|tpm2.AttrNVWritten), Size: 4} + nvpub := tpm2.NVPublic{Index: tpm2.Handle(TPM2IndexEAVersion), NameAlg: tpm2.HashAlgorithmSHA256, Attrs: tpm2.NVTypeOrdinary.WithAttrs(tpm2.AttrNVOwnerWrite | tpm2.AttrNVOwnerRead | tpm2.AttrNVAuthRead | tpm2.AttrNVWritten), Size: 4} trial := util.ComputeAuthPolicy(tpm2.HashAlgorithmSHA256) trial.PolicyPCR(pcrDigest, tpm2.PCRSelectionList{{Hash: tpm2.HashAlgorithmSHA256, Select: []int{7}}}) diff --git a/pkg/trust/utils.go b/pkg/trust/utils.go index bd1205f..5782b8e 100644 --- a/pkg/trust/utils.go +++ b/pkg/trust/utils.go @@ -85,7 +85,7 @@ func genPassphrase(nchars int) (string, error) { // trust-. So if we want 39 or 40 characters, request (39-6)/2+1 = 17 // bytes, giving us 136 bits of randomness. - nbytes := (nchars - 6) / 2 + 1 + nbytes := (nchars-6)/2 + 1 rand, err := HWRNGRead(nbytes) if err != nil { return "", err @@ -157,11 +157,11 @@ func RunWithStdall(stdinString string, args ...string) (string, string, error) { // Run: run a command. Return the output and an error if any. func Run(args ...string) (string, error) { cmd := exec.Command(args[0], args[1:]...) - output, err := cmd.CombinedOutput() - if err != nil { - return string(output), errors.Wrapf(err, "Failed running %v", args) - } - return string(output), nil + output, err := cmd.CombinedOutput() + if err != nil { + return string(output), errors.Wrapf(err, "Failed running %v", args) + } + return string(output), nil } func RunCommand(args ...string) error { From 6f4fdedf8d4a8e386d242692839ca24b34590ecd Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 25 Aug 2023 09:08:11 -0400 Subject: [PATCH 2/3] Add a 'gofmt' target for make and call it as a trust dep and from c-i My editor automatically runs 'gofmt'. So its annoying to open a file, make a change and see a bunch of whitespace unrelated changes in place. Ok, maybe I should fix my editor, but really 'gofmt' code is the norm. The change here is to run gofmt and fail the build if it makes changes. That way those changes don't get checked in and don't pass c-i if it hasn't run. Signed-off-by: Scott Moser --- .github/workflows/build.yml | 3 +++ .gitignore | 1 + Makefile | 12 +++++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 25cc145..5404c47 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,6 +20,9 @@ jobs: libdevmapper-dev libacl1-dev libarchive-tools pip squashfs-tools \ sbsigntool pip install virt-firmware + - name: lint + run: | + make gofmt - name: build run: | make diff --git a/.gitignore b/.gitignore index e69de29..5430407 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +.made-gofmt diff --git a/Makefile b/Makefile index 72b6cc3..4c1c82b 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,20 @@ ifeq ($(MAIN_VERSION),$(filter $(MAIN_VERSION), "", no-git)) $(error "Bad value for MAIN_VERSION: '$(MAIN_VERSION)'") endif +GO_SRC_DIRS := pkg/ cmd/ +GO_SRC := $(shell find $(GO_SRC_DIRS) -name "*.go") + VERSION_LDFLAGS=-X github.com/project-machine/trust/pkg/trust.Version=$(MAIN_VERSION) -trust: cmd/trust/*.go pkg/trust/*.go pkg/printdirtree/*.go +trust: .made-gofmt $(GO_SRC) go build -buildvcs=false -ldflags "$(VERSION_LDFLAGS)" -o trust ./cmd/trust/ +.PHONY: gofmt +gofmt: .made-gofmt +.made-gofmt: $(GO_SRC) + o=$$(gofmt -l -w $(GO_SRC_DIRS) 2>&1) && [ -z "$$o" ] || \ + { echo "gofmt made changes: $$o" 1>&2; exit 1; } + @touch $@ + clean: rm -f trust From 8eecf3cbcc1de9d6264c140a880a4f11c4e4bbcb Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 25 Aug 2023 09:18:59 -0400 Subject: [PATCH 3/3] Reduce code in extractPubkey by using readCertificateFromFile. Less software in the world. Signed-off-by: Scott Moser --- cmd/trust/utils.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/cmd/trust/utils.go b/cmd/trust/utils.go index f2f4176..e1d1811 100644 --- a/cmd/trust/utils.go +++ b/cmd/trust/utils.go @@ -438,15 +438,7 @@ func createPCR7Index(pcr7Val []byte) (string, error) { } func extractPubkey(certPath string) (*rsa.PublicKey, error) { - certPEM, err := os.ReadFile(certPath) - if err != nil { - return nil, err - } - block, _ := pem.Decode([]byte(certPEM)) - if block == nil { - return nil, fmt.Errorf("Failed to decode the certificate (%q)", certPath) - } - parsedCert, err := x509.ParseCertificate(block.Bytes) + parsedCert, err := readCertificateFromFile(certPath) if err != nil { return nil, err }