From 9cc3c76a5ad393721baea1d026a048b52a56a12e Mon Sep 17 00:00:00 2001 From: Alex Carder Date: Sat, 20 Apr 2024 15:22:00 -0700 Subject: [PATCH] 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. --- command/ssh/certificate.go | 11 +++++++++-- command/ssh/login.go | 20 ++++++++++++++++---- flags/flags.go | 5 +++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/command/ssh/certificate.go b/command/ssh/certificate.go index 11c0ca642..659419206 100644 --- a/command/ssh/certificate.go +++ b/command/ssh/certificate.go @@ -41,7 +41,8 @@ func certificateCommand() cli.Command { [**--not-after**=] [**--token**=] [**--issuer**=] [**--no-password**] [**--insecure**] [**--force**] [**--x5c-cert**=] [**--x5c-key**=] [**--k8ssa-token-path**=] [**--no-agent**] -[**--ca-url**=] [**--root**=] [**--context**=]`, +[**--ca-url**=] [**--root**=] [**--context**=] +[**--comment**=]`, Description: `**step ssh certificate** command generates an SSH key pair and creates a certificate using [step certificates](https://github.com/smallstep/certificates). @@ -185,6 +186,7 @@ $ step ssh certificate --token $TOKEN mariano@work id_ecdsa flags.CaURL, flags.Root, flags.Context, + flags.Comment, }, } } @@ -202,6 +204,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") @@ -480,7 +487,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") diff --git a/command/ssh/login.go b/command/ssh/login.go index fda6063ec..e17f97ac3 100644 --- a/command/ssh/login.go +++ b/command/ssh/login.go @@ -29,7 +29,8 @@ func loginCommand() cli.Command { [**--principal**=] [**--not-before**=] [**--not-after**=] [**--set**=] [**--set-file**=] [**--force**] [**--offline**] [**--ca-config**=] -[**--ca-url**=] [**--root**=] [**--context**=]`, +[**--ca-url**=] [**--root**=] [**--context**=] +[**--comment**=]`, 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. @@ -64,6 +65,11 @@ $ 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 and set a custom comment in the agent +''' +$ step ssh login --comment my-custom-comment bob@smallstep.com '''`, Flags: []cli.Flag{ flags.Token, @@ -82,6 +88,7 @@ $ step ssh login --principal admin --principal bob bob@smallstep.com flags.CaURL, flags.Root, flags.Context, + flags.Comment, }, } } @@ -102,6 +109,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") @@ -140,7 +152,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 } @@ -248,7 +260,7 @@ 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") @@ -256,7 +268,7 @@ func loginAction(ctx *cli.Context) error { 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") diff --git a/flags/flags.go b/flags/flags.go index dccce4995..bf67a706d 100644 --- a/flags/flags.go +++ b/flags/flags.go @@ -462,6 +462,11 @@ flag exists so it can be configured in $STEPPATH/config/defaults.json.`, Name: "attestation-uri", Usage: "The KMS 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.