github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/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 "io/ioutil" 12 "log" 13 14 "github.com/u-root/u-root/pkg/mount" 15 slaunch "github.com/u-root/u-root/pkg/securelaunch" 16 "github.com/u-root/u-root/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 /* 26 * NewFileCollector extracts the "files" portion from the policy file. 27 * initializes a new FileCollector structure. 28 * returns error if unmarshalling of FileCollector fails 29 */ 30 func NewFileCollector(config []byte) (Collector, error) { 31 slaunch.Debug("New Files Collector initialized\n") 32 var fc = new(FileCollector) 33 err := json.Unmarshal(config, &fc) 34 if err != nil { 35 return nil, err 36 } 37 return fc, nil 38 } 39 40 // HashBytes extends PCR with a byte array and sends an event to sysfs. 41 // the sent event is described via eventDesc. 42 func HashBytes(b []byte, eventDesc string) error { 43 return tpm.ExtendPCRDebug(pcr, bytes.NewReader(b), eventDesc) 44 } 45 46 /* 47 * HashFile reads file input by user and calls TPM to measure it and store the hash. 48 * 49 * inputVal is of format <block device identifier>:<path> 50 * E.g sda:/path/to/file _OR UUID:/path/to/file 51 * Performs following actions 52 * 1. mount device 53 * 2. Read file on device into a byte slice. 54 * 3. Unmount device 55 * 4. Call tpm package which measures byte slice and stores it. 56 */ 57 func HashFile(inputVal string) error { 58 // inputVal is of type sda:path 59 mntFilePath, e := slaunch.GetMountedFilePath(inputVal, mount.MS_RDONLY) 60 if e != nil { 61 log.Printf("HashFile: GetMountedFilePath err=%v", e) 62 return fmt.Errorf("failed to get mount path, err=%v", e) 63 } 64 slaunch.Debug("File Collector: Reading file=%s", mntFilePath) 65 66 slaunch.Debug("File Collector: fileP=%s\n", mntFilePath) 67 d, err := ioutil.ReadFile(mntFilePath) 68 if err != nil { 69 return fmt.Errorf("failed to read target file: filePath=%s, inputVal=%s, err=%v", 70 mntFilePath, inputVal, err) 71 } 72 73 eventDesc := fmt.Sprintf("File Collector: measured %s", inputVal) 74 return tpm.ExtendPCRDebug(pcr, bytes.NewReader(d), eventDesc) 75 } 76 77 /* 78 * Collect satisfies Collector Interface. It loops over all file paths provided by user 79 * and for each file path, calls HashFile. HashFile measures each file on 80 * that path and stores the result in TPM. 81 */ 82 func (s *FileCollector) Collect() error { 83 for _, inputVal := range s.Paths { 84 // inputVal is of type sda:/path/to/file 85 err := HashFile(inputVal) 86 if err != nil { 87 log.Printf("File Collector: input=%s, err = %v", inputVal, err) 88 return err 89 } 90 } 91 92 return nil 93 }