Skip to content

Commit 52d9a4b

Browse files
committed
Add support for creating API tokens backed by KMS signer
1 parent 4f46e13 commit 52d9a4b

File tree

1 file changed

+52
-9
lines changed

1 file changed

+52
-9
lines changed

command/api/token/create.go

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package token
22

33
import (
44
"bytes"
5+
"crypto"
56
"crypto/tls"
67
"encoding/json"
78
"errors"
@@ -15,6 +16,9 @@ import (
1516

1617
"github.com/smallstep/cli-utils/errs"
1718
"github.com/smallstep/cli-utils/ui"
19+
"go.step.sm/crypto/pemutil"
20+
21+
"github.com/smallstep/cli/internal/cryptoutil"
1822
)
1923

2024
func createCommand() cli.Command {
@@ -73,27 +77,31 @@ func createAction(ctx *cli.Context) (err error) {
7377
return err
7478
}
7579

76-
args := ctx.Args()
77-
78-
teamID := args.Get(0)
79-
crtFile := args.Get(1)
80-
keyFile := args.Get(2)
80+
var (
81+
args = ctx.Args()
82+
teamID = args.Get(0)
83+
crtFile = args.Get(1)
84+
keyFile = args.Get(2)
85+
apiURLFlag = ctx.String("api-url")
86+
audience = ctx.String("audience")
87+
)
8188

82-
parsedURL, err := url.Parse(ctx.String("api-url"))
89+
parsedURL, err := url.Parse(apiURLFlag)
8390
if err != nil {
8491
return err
8592
}
8693
parsedURL.Path = path.Join(parsedURL.Path, "api/auth")
8794
apiURL := parsedURL.String()
8895

89-
clientCert, err := tls.LoadX509KeyPair(crtFile, keyFile)
96+
clientCert, err := createClientCertificate(crtFile, keyFile)
9097
if err != nil {
9198
return err
9299
}
100+
93101
b := &bytes.Buffer{}
94102
r := &createTokenReq{
95103
Bundle: clientCert.Certificate,
96-
Audience: ctx.String("audience"),
104+
Audience: audience,
97105
}
98106
if err := uuid.Validate(teamID); err != nil {
99107
r.TeamSlug = teamID
@@ -113,7 +121,7 @@ func createAction(ctx *cli.Context) (err error) {
113121
transport := http.DefaultTransport.(*http.Transport).Clone()
114122
transport.TLSClientConfig = &tls.Config{
115123
GetClientCertificate: func(*tls.CertificateRequestInfo) (*tls.Certificate, error) {
116-
return &clientCert, nil
124+
return clientCert, nil
117125
},
118126
MinVersion: tls.VersionTLS12,
119127
}
@@ -143,3 +151,38 @@ func createAction(ctx *cli.Context) (err error) {
143151

144152
return nil
145153
}
154+
155+
func createClientCertificate(crtFile, keyFile string) (*tls.Certificate, error) {
156+
certs, err := pemutil.ReadCertificateBundle(crtFile)
157+
if err != nil {
158+
return nil, fmt.Errorf("failed reading %q: %w", crtFile, err)
159+
}
160+
161+
var certificates = make([][]byte, len(certs))
162+
for i, c := range certs {
163+
certificates[i] = c.Raw
164+
}
165+
166+
var (
167+
v any
168+
signer crypto.Signer
169+
)
170+
if cryptoutil.IsKMS(keyFile) {
171+
signer, err = cryptoutil.CreateSigner(keyFile, keyFile)
172+
if err != nil {
173+
return nil, fmt.Errorf("failed creating signer: %w", err)
174+
}
175+
v = signer
176+
} else {
177+
v, err = pemutil.Read(keyFile)
178+
if err != nil {
179+
return nil, fmt.Errorf("failed reading %q: %w", keyFile, err)
180+
}
181+
}
182+
183+
return &tls.Certificate{
184+
Certificate: certificates,
185+
Leaf: certs[0],
186+
PrivateKey: v,
187+
}, nil
188+
}

0 commit comments

Comments
 (0)