Skip to content

Commit 9dde90d

Browse files
committed
Add support for TSS2 keys in 'api token create' command.
1 parent 2122975 commit 9dde90d

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

command/api/token/create.go

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,24 @@ package token
22

33
import (
44
"bytes"
5+
"context"
56
"crypto/tls"
67
"encoding/json"
8+
"encoding/pem"
79
"errors"
810
"fmt"
911
"net/http"
1012
"net/url"
13+
"os"
1114
"path"
15+
"time"
1216

17+
"github.com/google/go-tpm/legacy/tpm2"
1318
"github.com/google/uuid"
1419
"github.com/urfave/cli"
20+
"go.step.sm/crypto/pemutil"
21+
"go.step.sm/crypto/tpm/tss2"
22+
"go.step.sm/crypto/tpm"
1523

1624
"github.com/smallstep/cli-utils/errs"
1725
"github.com/smallstep/cli-utils/ui"
@@ -40,7 +48,7 @@ func createCommand() cli.Command {
4048
: File to read the certificate (PEM format). This certificate must be signed by a trusted root configured in the Smallstep dashboard.
4149
4250
<key-file>
43-
: File to read the private key (PEM format).
51+
: File to read the private key (PEM format, TSS2-wrapped keys are supported).
4452
4553
## EXAMPLES
4654
Use a certificate to get a new API token:
@@ -86,10 +94,60 @@ func createAction(ctx *cli.Context) (err error) {
8694
parsedURL.Path = path.Join(parsedURL.Path, "api/auth")
8795
apiURL := parsedURL.String()
8896

89-
clientCert, err := tls.LoadX509KeyPair(crtFile, keyFile)
97+
buf, err := os.ReadFile(keyFile)
9098
if err != nil {
9199
return err
92100
}
101+
pem, _ := pem.Decode(buf)
102+
103+
var clientCert tls.Certificate
104+
switch pem.Type {
105+
case "TSS2 PRIVATE KEY":
106+
chain, err := pemutil.ReadCertificateBundle(crtFile)
107+
if err != nil {
108+
return err
109+
}
110+
111+
key, err := tss2.ParsePrivateKey(pem.Bytes)
112+
if err != nil {
113+
return err
114+
}
115+
116+
raw := make([][]byte, len(chain))
117+
for _, crt := range chain {
118+
raw = append(raw, crt.Raw)
119+
}
120+
121+
rw, err := tpm2.OpenTPM()
122+
if err != nil {
123+
return err
124+
}
125+
126+
defer rw.Close()
127+
128+
t, err := tpm.New()
129+
if err != nil {
130+
return err
131+
}
132+
133+
134+
tpmCtx, cancel := context.WithTimeout(context.Background(), time.Second * 5)
135+
defer cancel()
136+
137+
signer, err := tpm.CreateTSS2Signer(tpmCtx, t, key)
138+
139+
clientCert = tls.Certificate{
140+
PrivateKey: signer,
141+
Leaf: chain[0],
142+
Certificate: raw,
143+
}
144+
default:
145+
clientCert, err = tls.LoadX509KeyPair(crtFile, keyFile)
146+
if err != nil {
147+
return err
148+
}
149+
}
150+
93151
b := &bytes.Buffer{}
94152
r := &createTokenReq{
95153
Bundle: clientCert.Certificate,

0 commit comments

Comments
 (0)