@@ -2,16 +2,23 @@ package token
22
33import (
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
4653Use a certificate to get a new API token:
@@ -86,10 +93,54 @@ 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 clientCert tls.Certificate
103+ switch pem .Type {
104+ case "TSS2 PRIVATE KEY" :
105+ chain , err := pemutil .ReadCertificateBundle (crtFile )
106+ if err != nil {
107+ return err
108+ }
109+
110+ key , err := tss2 .ParsePrivateKey (pem .Bytes )
111+ if err != nil {
112+ return err
113+ }
114+
115+ raw := make ([][]byte , len (chain ))
116+ for _ , crt := range chain {
117+ raw = append (raw , crt .Raw )
118+ }
119+
120+ rw , err := tpm2 .OpenTPM ()
121+ if err != nil {
122+ return err
123+ }
124+
125+ defer rw .Close ()
126+
127+ signer , err := tss2 .CreateSigner (rw , key )
128+ if err != nil {
129+ return err
130+ }
131+
132+ clientCert = tls.Certificate {
133+ PrivateKey : signer ,
134+ Leaf : chain [0 ],
135+ Certificate : raw ,
136+ }
137+ default :
138+ clientCert , err = tls .LoadX509KeyPair (crtFile , keyFile )
139+ if err != nil {
140+ return err
141+ }
142+ }
143+
93144 b := & bytes.Buffer {}
94145 r := & createTokenReq {
95146 Bundle : clientCert .Certificate ,
0 commit comments