Skip to content

Commit

Permalink
Allow users to define certificate comment in agent (#1158)
Browse files Browse the repository at this point in the history
* Allow users to define certificate comment in agent

Added a comment flag which allows users to set the comment for a
certificate when it gets added to an agent. It defaults to current
behavior if not set, which is it uses the subject as the comment.
This allows users who interact with mutliple CAs with the same
identity (email) to have multiple certificates in the agent. It
also allows for use cases when users generate SSH certs with different
extensions to load multiple certificates in their agent.
  • Loading branch information
redrac committed May 14, 2024
1 parent aeee3d0 commit 32bdf40
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 13 deletions.
20 changes: 13 additions & 7 deletions command/ssh/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ func certificateCommand() cli.Command {
UsageText: `**step ssh certificate** <key-id> <key-file>
[**--host**] [--**host-id**] [**--sign**] [**--principal**=<string>]
[**--password-file**=<file>] [**--provisioner-password-file**=<file>]
[**--add-user**] [**--not-before**=<time|duration>]
[**--add-user**] [**--not-before**=<time|duration>] [**--comment**=<comment>]
[**--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>]
[**--kty**=<key-type>] [**--curve**=<curve>] [**--size**=<size>]`,
[**--kty**=<key-type>] [**--curve**=<curve>] [**--size**=<size>]
[**--ca-url**=<uri>] [**--root**=<file>] [**--context**=<name>]`,

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 @@ -184,6 +184,10 @@ $ step ssh certificate --kty OKP --curve Ed25519 mariano@work id_ed25519
sshPrivateKeyFlag,
sshProvisionerPasswordFlag,
sshSignFlag,
flags.KTY,
flags.Curve,
flags.Size,
flags.Comment,
flags.KMSUri,
flags.X5cCert,
flags.X5cKey,
Expand All @@ -199,9 +203,6 @@ $ step ssh certificate --kty OKP --curve Ed25519 mariano@work id_ed25519
flags.CaURL,
flags.Root,
flags.Context,
flags.KTY,
flags.Curve,
flags.Size,
},
}
}
Expand All @@ -219,6 +220,11 @@ func certificateAction(ctx *cli.Context) error {
pubFile := baseName + ".pub"
crtFile := baseName + "-cert.pub"

comment := ctx.String("comment")
if comment == "" {
comment = subject
}

// Flags
token := ctx.String("token")
isHost := ctx.Bool("host")
Expand Down Expand Up @@ -502,7 +508,7 @@ func certificateAction(ctx *cli.Context) error {
ui.Printf(`{{ "%s" | red }} {{ "SSH Agent:" | bold }} %v`+"\n", ui.IconBad, err)
} else {
defer agent.Close()
if err := agent.AddCertificate(subject, resp.Certificate.Certificate, priv); err != nil {
if err := agent.AddCertificate(comment, resp.Certificate.Certificate, priv); err != nil {
ui.Printf(`{{ "%s" | red }} {{ "SSH Agent:" | bold }} %v`+"\n", ui.IconBad, err)
} else {
ui.PrintSelected("SSH Agent", "yes")
Expand Down
22 changes: 16 additions & 6 deletions command/ssh/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +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>]
[**--kty**=<key-type>] [**--curve**=<curve>] [**--size**=<size>] [**--comment**=<comment>]
[**--set**=<key=value>] [**--set-file**=<file>] [**--force**] [**--insecure**]
[**--offline**] [**--ca-config**=<file>]
[**--ca-url**=<uri>] [**--root**=<file>] [**--context**=<name>]
[**--kty**=<key-type>] [**--curve**=<curve>] [**--size**=<size>]`,
[**--ca-url**=<uri>] [**--root**=<file>] [**--context**=<name>]`,
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 @@ -68,13 +68,17 @@ Request a new SSH certificate with multiple principals:
$ step ssh login --principal admin --principal bob bob@smallstep.com
'''
Request a new SSH certificate and set a custom comment in the agent
'''
$ step ssh login --comment my-custom-comment 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
'''`,
Expand All @@ -95,6 +99,7 @@ $ step ssh certificate --kty OKP --curve Ed25519 mariano@work id_ed25519
flags.CaURL,
flags.Root,
flags.Context,
flags.Comment,
flags.KTY,
flags.Curve,
flags.Size,
Expand All @@ -119,6 +124,11 @@ func loginAction(ctx *cli.Context) error {
principals = []string{subject}
}

comment := ctx.String("comment")
if comment == "" {
comment = subject
}

// Flags
token := ctx.String("token")
isAddUser := ctx.Bool("add-user")
Expand Down Expand Up @@ -163,7 +173,7 @@ func loginAction(ctx *cli.Context) error {
}

// Just return if key is present
if key, err := agent.GetKey(subject, opts...); err == nil {
if key, err := agent.GetKey(comment, opts...); err == nil {
ui.Printf("The key %s is already present in the SSH agent.\n", key.String())
return nil
}
Expand Down Expand Up @@ -270,15 +280,15 @@ func loginAction(ctx *cli.Context) error {
}

// Attempt to add key to agent if private key defined.
if err := agent.AddCertificate(subject, resp.Certificate.Certificate, priv); err != nil {
if err := agent.AddCertificate(comment, resp.Certificate.Certificate, priv); err != nil {
ui.Printf(`{{ "%s" | red }} {{ "SSH Agent:" | bold }} %v`+"\n", ui.IconBad, err)
} else {
ui.PrintSelected("SSH Agent", "yes")
}
if isAddUser {
if resp.AddUserCertificate == nil {
ui.Printf(`{{ "%s" | red }} {{ "Add User Certificate:" | bold }} failed to create a provisioner certificate`+"\n", ui.IconBad)
} else if err := agent.AddCertificate(subject, resp.AddUserCertificate.Certificate, auPriv); err != nil {
} else if err := agent.AddCertificate(comment, resp.AddUserCertificate.Certificate, auPriv); err != nil {
ui.Printf(`{{ "%s" | red }} {{ "Add User Certificate:" | bold }} %v`+"\n", ui.IconBad, err)
} else {
ui.PrintSelected("Add User Certificate", "yes")
Expand Down
5 changes: 5 additions & 0 deletions flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,11 @@ flag exists so it can be configured in $STEPPATH/config/defaults.json.`,
Name: "attestation-uri",
Usage: "The KMS <uri> used for attestation.",
}

Comment = cli.StringFlag{
Name: "comment",
Usage: "The comment used when adding the certificate to an agent. Defaults to the subject if not provided.",
}
)

// FingerprintFormatFlag returns a flag for configuring the fingerprint format.
Expand Down

0 comments on commit 32bdf40

Please sign in to comment.