Skip to content

Commit 6a846d0

Browse files
committed
vtpm: Get the supported capabilities of swtpm and swtpm_setup
Call 'swtpm chardev --print-capabilities' to get the supported capabilites from swtpm. An JSON object is printed by swtpm that we unmarshal and we pick the 'features' part from it that is an array of strings indicating what this version of swtpm supports. This option was added in v0.2. For older versions of swtpm we return an empty array. Signed-off-by: Stefan Berger <[email protected]>
1 parent 9c2e246 commit 6a846d0

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

libcontainer/vtpm/vtpm.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package vtpm
44

55
import (
6+
"encoding/json"
67
"fmt"
78
"io/ioutil"
89
"os"
@@ -62,6 +63,12 @@ type VTPM struct {
6263

6364
// The AppArmor profile's full path
6465
aaprofile string
66+
67+
// swtpm_setup capabilities
68+
swtpmSetupCaps []string
69+
70+
// swtpm capabilities
71+
swtpmCaps []string
6572
}
6673

6774
// ioctl
@@ -121,6 +128,49 @@ func vtpmx_ioctl(cmd, msg uintptr) error {
121128
return nil
122129
}
123130

131+
// getCapabilities gets the capabilities map of an executable by invoking it with
132+
// --print-capabilities. It returns the array of feature strings.
133+
// This function returns an empty array if the executable does not support --print-capabilities.
134+
// Expected output looks like this:
135+
// { "type": "swtpm_setup", "features": [ "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd" ] }
136+
func getCapabilities(cmd *exec.Cmd) ([]string, error) {
137+
caps := make(map[string]interface{})
138+
139+
output, err := cmd.Output()
140+
if err != nil {
141+
return nil, nil
142+
}
143+
144+
err = json.Unmarshal([]byte(output), &caps)
145+
if err != nil {
146+
return nil, fmt.Errorf("Could not unmarshal output: %s: %v\n", output, err)
147+
}
148+
149+
features, _ := caps["features"].([]interface{})
150+
res := make([]string, 0)
151+
for _, f := range features {
152+
res = append(res, f.(string))
153+
}
154+
return res, nil
155+
}
156+
157+
func getSwtpmSetupCapabilities() ([]string, error) {
158+
return getCapabilities(exec.Command("swtpm_setup", "--print-capabilities"))
159+
}
160+
161+
func getSwtpmCapabilities() ([]string, error) {
162+
return getCapabilities(exec.Command("swtpm", "chardev", "--print-capabilities"))
163+
}
164+
165+
func hasCapability(capabilities []string, capability string) bool {
166+
for _, c := range capabilities {
167+
if capability == c {
168+
return true
169+
}
170+
}
171+
return false
172+
}
173+
124174
// Create a new VTPM object
125175
//
126176
// @statepath: directory where the vTPM's state will be written into
@@ -165,6 +215,15 @@ func NewVTPM(statepath string, statepathismanaged bool, vtpmversion string, crea
165215
}
166216
runas = usr.Uid
167217

218+
swtpmSetupCaps, err := getSwtpmSetupCapabilities()
219+
if err != nil {
220+
return nil, err
221+
}
222+
swtpmCaps, err := getSwtpmCapabilities()
223+
if err != nil {
224+
return nil, err
225+
}
226+
168227
return &VTPM{
169228
user: runas,
170229
StatePath: statepath,
@@ -174,6 +233,8 @@ func NewVTPM(statepath string, statepathismanaged bool, vtpmversion string, crea
174233
PcrBanks: pcrbanks,
175234
Tpm_dev_num: VTPM_DEV_NUM_INVALID,
176235
fd: ILLEGAL_FD,
236+
swtpmSetupCaps: swtpmSetupCaps,
237+
swtpmCaps: swtpmCaps,
177238
}, nil
178239
}
179240

0 commit comments

Comments
 (0)