Skip to content

Commit

Permalink
Add support for setting ssh key types
Browse files Browse the repository at this point in the history
Add --kty, --curve, and --size to ssh commands (login, certificate)

Implements PR #477
  • Loading branch information
redrac authored and maraino committed May 14, 2024
1 parent bf70d3e commit aeee3d0
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 8 deletions.
28 changes: 25 additions & 3 deletions command/ssh/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ func certificateCommand() cli.Command {
[**--not-after**=<time|duration>] [**--token**=<token>] [**--issuer**=<name>]
[**--no-password**] [**--insecure**] [**--force**] [**--x5c-cert**=<file>]
[**--x5c-key**=<file>] [**--k8ssa-token-path**=<file>] [**--no-agent**]
[**--ca-url**=<uri>] [**--root**=<file>] [**--context**=<name>]`,
[**--ca-url**=<uri>] [**--root**=<file>] [**--context**=<name>]
[**--kty**=<key-type>] [**--curve**=<curve>] [**--size**=<size>]`,

Description: `**step ssh certificate** command generates an SSH key pair and creates a
certificate using [step certificates](https://github.com/smallstep/certificates).
Expand Down Expand Up @@ -150,7 +151,20 @@ $ step ssh certificate --principal max --principal mariano --sign \
Generate a new key pair and a certificate using a given token:
'''
$ step ssh certificate --token $TOKEN mariano@work id_ecdsa
'''
Create an EC pair with curve P-521 and certificate:
'''
$ step ssh certificate --kty EC --curve "P-521" mariano@work id_ecdsa
'''
Create an Octet Key Pair with curve Ed25519 and certificate:
'''
$ step ssh certificate --kty OKP --curve Ed25519 mariano@work id_ed25519
'''`,

Flags: []cli.Flag{
flags.Force,
flags.Insecure,
Expand Down Expand Up @@ -185,6 +199,9 @@ $ step ssh certificate --token $TOKEN mariano@work id_ecdsa
flags.CaURL,
flags.Root,
flags.Context,
flags.KTY,
flags.Curve,
flags.Size,
},
}
}
Expand Down Expand Up @@ -223,6 +240,11 @@ func certificateAction(ctx *cli.Context) error {
return err
}

kty, curve, size, err := utils.GetKeyDetailsFromCLI(ctx, insecure, "kty", "curve", "size")
if err != nil {
return err
}

// Validation
switch {
case noPassword && !insecure:
Expand Down Expand Up @@ -374,7 +396,7 @@ func certificateAction(ctx *cli.Context) error {
}
} else {
// Generate keypair
pub, priv, err = keyutil.GenerateDefaultKeyPair()
pub, priv, err = keyutil.GenerateKeyPair(kty, curve, size)
if err != nil {
return err
}
Expand All @@ -389,7 +411,7 @@ func certificateAction(ctx *cli.Context) error {
var sshAuPubBytes []byte
var auPub, auPriv interface{}
if isAddUser {
auPub, auPriv, err = keyutil.GenerateDefaultKeyPair()
auPub, auPriv, err = keyutil.GenerateKeyPair(kty, curve, size)
if err != nil {
return err
}
Expand Down
32 changes: 27 additions & 5 deletions command/ssh/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/smallstep/certificates/ca"
"github.com/smallstep/cli/flags"
"github.com/smallstep/cli/internal/sshutil"
"github.com/smallstep/cli/utils"
"github.com/smallstep/cli/utils/cautils"
"github.com/urfave/cli"
"go.step.sm/cli-utils/command"
Expand All @@ -27,9 +28,10 @@ func loginCommand() cli.Command {
UsageText: `**step ssh login** [<identity>]
[**--token**=<token>] [**--provisioner**=<name>] [**--provisioner-password-file**=<file>]
[**--principal**=<string>] [**--not-before**=<time|duration>] [**--not-after**=<time|duration>]
[**--set**=<key=value>] [**--set-file**=<file>] [**--force**]
[**--set**=<key=value>] [**--set-file**=<file>] [**--force**] [**--insecure**]
[**--offline**] [**--ca-config**=<file>]
[**--ca-url**=<uri>] [**--root**=<file>] [**--context**=<name>]`,
[**--ca-url**=<uri>] [**--root**=<file>] [**--context**=<name>]
[**--kty**=<key-type>] [**--curve**=<curve>] [**--size**=<size>]`,
Description: `**step ssh login** generates a new SSH key pair and send a request to [step
certificates](https://github.com/smallstep/certificates) to sign a user
certificate. This certificate will be automatically added to the SSH agent.
Expand Down Expand Up @@ -64,6 +66,17 @@ $ step ssh login --not-after 1h alice
Request a new SSH certificate with multiple principals:
'''
$ step ssh login --principal admin --principal bob bob@smallstep.com
'''
Request a new SSH certificate with an EC key and P-521 curve:
'''
$ step ssh certificate --kty EC --curve "P-521" mariano@work id_ecdsa
'''
Request a new SSH certificate with an Octet Key Pair and Ed25519 curve:
'''
$ step ssh certificate --kty OKP --curve Ed25519 mariano@work id_ed25519
'''`,
Flags: []cli.Flag{
flags.Token,
Expand All @@ -82,6 +95,10 @@ $ step ssh login --principal admin --principal bob bob@smallstep.com
flags.CaURL,
flags.Root,
flags.Context,
flags.KTY,
flags.Curve,
flags.Size,
flags.Insecure,
},
}
}
Expand All @@ -106,6 +123,7 @@ func loginAction(ctx *cli.Context) error {
token := ctx.String("token")
isAddUser := ctx.Bool("add-user")
force := ctx.Bool("force")
insecure := ctx.Bool("insecure")
validAfter, validBefore, err := flags.ParseTimeDuration(ctx)
if err != nil {
return err
Expand All @@ -115,6 +133,11 @@ func loginAction(ctx *cli.Context) error {
return err
}

kty, curve, size, err := utils.GetKeyDetailsFromCLI(ctx, insecure, "kty", "curve", "size")
if err != nil {
return err
}

// Connect to the SSH agent.
// step ssh login requires an ssh agent.
agent, err := sshutil.DialAgent()
Expand Down Expand Up @@ -169,8 +192,7 @@ func loginAction(ctx *cli.Context) error {
return err
}

// Generate keypair
pub, priv, err := keyutil.GenerateDefaultKeyPair()
pub, priv, err := keyutil.GenerateKeyPair(kty, curve, size)
if err != nil {
return err
}
Expand All @@ -184,7 +206,7 @@ func loginAction(ctx *cli.Context) error {
var sshAuPubBytes []byte
var auPub, auPriv interface{}
if isAddUser {
auPub, auPriv, err = keyutil.GenerateDefaultKeyPair()
auPub, auPriv, err = keyutil.GenerateKeyPair(kty, curve, size)
if err != nil {
return err
}
Expand Down

0 comments on commit aeee3d0

Please sign in to comment.