github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/securelaunch/measurement/files.go (about) 1 // Copyright 2019 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package measurement 6 7 import ( 8 "bytes" 9 "encoding/json" 10 "fmt" 11 "log" 12 "os" 13 14 "github.com/mvdan/u-root-coreutils/pkg/mount" 15 slaunch "github.com/mvdan/u-root-coreutils/pkg/securelaunch" 16 "github.com/mvdan/u-root-coreutils/pkg/securelaunch/tpm" 17 ) 18 19 // Describes the "files" portion of policy file. 20 type FileCollector struct { 21 Type string `json:"type"` 22 Paths []string `json:"paths"` 23 } 24 25 // NewFileCollector extracts the "files" portion from the policy file and 26 // initializes a new FileCollector structure. 27 // It returns an error if unmarshalling of FileCollector fails. 28 func NewFileCollector(config []byte) (Collector, error) { 29 slaunch.Debug("New Files Collector initialized\n") 30 fc := new(FileCollector) 31 err := json.Unmarshal(config, &fc) 32 if err != nil { 33 return nil, err 34 } 35 return fc, nil 36 } 37 38 // HashBytes extends PCR with a byte array and sends an event to sysfs. 39 // the sent event is described via eventDesc. 40 func HashBytes(b []byte, eventDesc string) error { 41 return tpm.ExtendPCRDebug(pcr, bytes.NewReader(b), eventDesc) 42 } 43 44 // HashFile opens and reads the given file and measures it into the TPM. 45 // 46 // inputVal is of format <block device identifier>:<path> 47 // (e.g., `sda:/path/to/file` or `UUID:/path/to/file`). 48 func HashFile(inputVal string) error { 49 // inputVal is of type sda:path 50 mntFilePath, e := slaunch.GetMountedFilePath(inputVal, mount.MS_RDONLY) 51 if e != nil { 52 log.Printf("HashFile: GetMountedFilePath err=%v", e) 53 return fmt.Errorf("failed to get mount path, err=%v", e) 54 } 55 slaunch.Debug("File Collector: Reading file=%s", mntFilePath) 56 57 slaunch.Debug("File Collector: fileP=%s\n", mntFilePath) 58 d, err := os.ReadFile(mntFilePath) 59 if err != nil { 60 return fmt.Errorf("failed to read target file: filePath=%s, inputVal=%s, err=%v", 61 mntFilePath, inputVal, err) 62 } 63 64 eventDesc := fmt.Sprintf("File Collector: measured %s", inputVal) 65 return tpm.ExtendPCRDebug(pcr, bytes.NewReader(d), eventDesc) 66 } 67 68 // Collect loops over the given file paths and for each file path calls 69 // HashFile(), which measures a file into the TPM. 70 // 71 // It satisfies the Collector interface. 72 func (s *FileCollector) Collect() error { 73 for _, inputVal := range s.Paths { 74 // inputVal is of type sda:/path/to/file 75 err := HashFile(inputVal) 76 if err != nil { 77 log.Printf("File Collector: input=%s, err = %v", inputVal, err) 78 return err 79 } 80 } 81 82 return nil 83 }