/
keygen.go
93 lines (81 loc) · 2.13 KB
/
keygen.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package main
import (
"io/ioutil"
"os"
"github.com/folbricht/tpmk"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
type keygenOptions struct {
device string
password string
attr string
}
func newKeyGenCommand() *cobra.Command {
var opt keygenOptions
cmd := &cobra.Command{
Use: "generate <handle> <public-key>",
Short: "Generate a key and make it persistent",
Long: `Generate a primary key in the TPM and make it persistent.
Key attributes determine how the generated key can be used.
The default attributes allow it to be used for signing and
decryption. Refer to the TPM 2.0 specification, Part 2,
Section 8.3 for a detailed description of the attributes.
Available attributes:
fixedtpm
fixedparent
sensitivedataorigin
userwithauth
adminwithpolicy
noda
restricted
decrypt
sign
Use '-' to write the key to STDOUT.`,
Example: ` tpmk key generate 0x81000000 public.pem`,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
return runKeyGen(opt, args)
},
SilenceUsage: true,
}
flags := cmd.Flags()
flags.StringVarP(&opt.device, "device", "d", "/dev/tpmrm0", "TPM device, 'sim' for simulator")
flags.StringVarP(&opt.password, "password", "p", "", "Password")
flags.StringVarP(&opt.attr, "attributes", "a", "sign|decrypt|userwithauth|sensitivedataorigin", "Key attributes")
return cmd
}
func runKeyGen(opt keygenOptions, args []string) error {
// Parse arguments
handle, err := parseHandle(args[0])
if err != nil {
return err
}
output := args[1]
attr, err := parseKeyAttributes(opt.attr)
if err != nil {
return errors.Wrap(err, "key attributes")
}
// Open device or simulator
dev, err := tpmk.OpenDevice(opt.device)
if err != nil {
return err
}
defer dev.Close()
// Generate the key
pub, err := tpmk.GenRSAPrimaryKey(dev, handle, opt.password, opt.password, attr)
if err != nil {
return err
}
// Encode the public key
pem, err := tpmk.PubKeyToPEM(pub)
if err != nil {
return err
}
// Write the public portion to file or STDOUT
if output == "-" {
_, err = os.Stdout.Write(pem)
return err
}
return ioutil.WriteFile(output, pem, 0755)
}