Skip to content

Commit 2862026

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

File tree

1 file changed

+59
-2
lines changed

1 file changed

+59
-2
lines changed

command/api/token/create.go

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

33
import (
44
"bytes"
5+
"crypto/ecdsa"
6+
"crypto/rsa"
57
"crypto/tls"
68
"encoding/json"
9+
"encoding/pem"
710
"errors"
811
"fmt"
912
"net/http"
1013
"net/url"
14+
"os"
1115
"path"
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"
1522

1623
"github.com/smallstep/cli-utils/errs"
1724
"github.com/smallstep/cli-utils/ui"
@@ -40,7 +47,7 @@ func createCommand() cli.Command {
4047
: File to read the certificate (PEM format). This certificate must be signed by a trusted root configured in the Smallstep dashboard.
4148
4249
<key-file>
43-
: File to read the private key (PEM format).
50+
: File to read the private key (PEM format, TSS2-wrapped keys are supported).
4451
4552
## EXAMPLES
4653
Use a certificate to get a new API token:
@@ -86,10 +93,57 @@ func createAction(ctx *cli.Context) (err error) {
8693
parsedURL.Path = path.Join(parsedURL.Path, "api/auth")
8794
apiURL := parsedURL.String()
8895

89-
clientCert, err := tls.LoadX509KeyPair(crtFile, keyFile)
96+
buf, err := os.ReadFile(keyFile)
9097
if err != nil {
9198
return err
9299
}
100+
pem, _ := pem.Decode(buf)
101+
102+
var (
103+
clientCert tls.Certificate
104+
)
105+
106+
switch pem.Type {
107+
case "TSS2 PRIVATE KEY":
108+
chain, err := pemutil.ReadCertificateBundle(crtFile)
109+
if err != nil {
110+
return err
111+
}
112+
113+
key, err := tss2.ParsePrivateKey(pem.Bytes)
114+
if err != nil {
115+
return err
116+
}
117+
118+
raw := make([][]byte, len(chain))
119+
for _, crt := range chain {
120+
raw = append(raw, crt.Raw)
121+
}
122+
123+
rw, err := tpm2.OpenTPM()
124+
if err != nil {
125+
return err
126+
}
127+
128+
defer rw.Close()
129+
130+
signer, err := tss2.CreateSigner(rw, key)
131+
if err != nil {
132+
return err
133+
}
134+
135+
clientCert = tls.Certificate{
136+
PrivateKey: signer,
137+
Leaf: chain[0],
138+
Certificate: raw,
139+
}
140+
default:
141+
clientCert, err = tls.LoadX509KeyPair(crtFile, keyFile)
142+
if err != nil {
143+
return err
144+
}
145+
}
146+
93147
b := &bytes.Buffer{}
94148
r := &createTokenReq{
95149
Bundle: clientCert.Certificate,
@@ -115,6 +169,9 @@ func createAction(ctx *cli.Context) (err error) {
115169
GetClientCertificate: func(*tls.CertificateRequestInfo) (*tls.Certificate, error) {
116170
return &clientCert, nil
117171
},
172+
CipherSuites: []uint16{
173+
tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
174+
},
118175
MinVersion: tls.VersionTLS12,
119176
}
120177
client := http.Client{

0 commit comments

Comments
 (0)