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