Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions cmd/kms/crypto/crypto.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package crypto

import (
"github.com/exoscale/cli/cmd/kms"
"github.com/spf13/cobra"
)

var cryptoCmd = &cobra.Command{
Use: "crypto",
Short: "KMS key cryptographic operations",
}

func init() {
kms.KMSCmd.AddCommand(cryptoCmd)
}
97 changes: 97 additions & 0 deletions cmd/kms/crypto/crypto_decrypt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package crypto

import (
"encoding/base64"
"os"

exocmd "github.com/exoscale/cli/cmd"
"github.com/exoscale/cli/pkg/globalstate"
"github.com/exoscale/cli/pkg/output"
"github.com/exoscale/cli/table"
v3 "github.com/exoscale/egoscale/v3"
"github.com/spf13/cobra"
)

type cryptoDecryptOutput struct {
Plaintext string `json:"plaintext"`
}

func (o *cryptoDecryptOutput) ToJSON() { output.JSON(o) }
func (o *cryptoDecryptOutput) ToText() { output.Text(o) }
func (o *cryptoDecryptOutput) ToTable() {
t := table.NewTable(os.Stdout)
defer t.Render()

t.SetHeader([]string{
"PLAINTEXT",
})

t.Append([]string{
o.Plaintext,
})
}

type cryptoDecryptCmd struct {
exocmd.CliCommandSettings `cli-cmd:"-"`

_ bool `cli-cmd:"decrypt"`

Key string `cli-arg:"#" cli-usage:"ID"`
Ciphertext string `cli-arg:"#" cli-usage:"CIPHERTEXT"`

EncryptionContext string `cli-short:"e" cli-flag:"encryption-context" cli-usage:"encryption context to use for decryption"`
Zone v3.ZoneName `cli-short:"z" cli-flag:"zone" cli-usage:"crypto zone"`
}

func (c *cryptoDecryptCmd) CmdAliases() []string { return nil }

func (c *cryptoDecryptCmd) CmdShort() string {
return "Decrypts data using a KMS key."
}

func (c *cryptoDecryptCmd) CmdLong() string {
return "Decrypts data using a KMS key."
}

func (c *cryptoDecryptCmd) CmdPreRun(cmd *cobra.Command, args []string) error {
exocmd.CmdSetZoneFlagFromDefault(cmd)
return exocmd.CliCommandDefaultPreRun(c, cmd, args)
}

func (c *cryptoDecryptCmd) CmdRun(_ *cobra.Command, _ []string) error {
ctx := exocmd.GContext
client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, c.Zone)
if err != nil {
return err
}

ec := []byte(c.EncryptionContext)
decoded, err := base64.StdEncoding.DecodeString(c.Ciphertext)
if err != nil {
return err
}
req := v3.DecryptRequest{
Ciphertext: decoded,
EncryptionContext: &ec,
}

resp, err := client.Decrypt(ctx, v3.UUID(c.Key), req)
if err != nil {
return err
}

if !globalstate.Quiet {
out := cryptoDecryptOutput{
Plaintext: base64.StdEncoding.EncodeToString(resp.Plaintext),
}
return c.OutputFunc(&out, nil)
}

return nil
}

func init() {
cobra.CheckErr(exocmd.RegisterCLICommand(cryptoCmd, &cryptoDecryptCmd{
CliCommandSettings: exocmd.DefaultCLICmdSettings(),
}))
}
93 changes: 93 additions & 0 deletions cmd/kms/crypto/crypto_encrypt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package crypto

import (
"encoding/base64"
"os"

exocmd "github.com/exoscale/cli/cmd"
"github.com/exoscale/cli/pkg/globalstate"
"github.com/exoscale/cli/pkg/output"
"github.com/exoscale/cli/table"
v3 "github.com/exoscale/egoscale/v3"
"github.com/spf13/cobra"
)

type cryptoEncryptOutput struct {
Ciphertext string `json:"ciphertext"`
}

func (o *cryptoEncryptOutput) ToJSON() { output.JSON(o) }
func (o *cryptoEncryptOutput) ToText() { output.Text(o) }
func (o *cryptoEncryptOutput) ToTable() {
t := table.NewTable(os.Stdout)
defer t.Render()

t.SetHeader([]string{
"CIPHERTEXT",
})

t.Append([]string{
o.Ciphertext,
})
}

type cryptoEncryptCmd struct {
exocmd.CliCommandSettings `cli-cmd:"-"`

_ bool `cli-cmd:"encrypt"`

Key string `cli-arg:"#" cli-usage:"ID"`
Plaintext string `cli-arg:"#" cli-usage:"PLAINTEXT"`

EncryptionContext string `cli-short:"e" cli-flag:"encryption-context" cli-usage:"encryption context to use for encryption"`
Zone v3.ZoneName `cli-short:"z" cli-flag:"zone" cli-usage:"key zone"`
}

func (c *cryptoEncryptCmd) CmdAliases() []string { return nil }

func (c *cryptoEncryptCmd) CmdShort() string {
return "Encrypts data using a KMS key."
}

func (c *cryptoEncryptCmd) CmdLong() string {
return "Encrypts data using a KMS key."
}

func (c *cryptoEncryptCmd) CmdPreRun(cmd *cobra.Command, args []string) error {
exocmd.CmdSetZoneFlagFromDefault(cmd)
return exocmd.CliCommandDefaultPreRun(c, cmd, args)
}

func (c *cryptoEncryptCmd) CmdRun(_ *cobra.Command, _ []string) error {
ctx := exocmd.GContext
client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, c.Zone)
if err != nil {
return err
}

ec := []byte(c.EncryptionContext)
req := v3.EncryptRequest{
Plaintext: []byte(c.Plaintext),
EncryptionContext: &ec,
}

resp, err := client.Encrypt(ctx, v3.UUID(c.Key), req)
if err != nil {
return err
}

if !globalstate.Quiet {
out := cryptoEncryptOutput{
Ciphertext: base64.StdEncoding.EncodeToString(resp.Ciphertext),
}
return c.OutputFunc(&out, nil)
}

return nil
}

func init() {
cobra.CheckErr(exocmd.RegisterCLICommand(cryptoCmd, &cryptoEncryptCmd{
CliCommandSettings: exocmd.DefaultCLICmdSettings(),
}))
}
109 changes: 109 additions & 0 deletions cmd/kms/crypto/crypto_generate_data_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package crypto

import (
"encoding/base64"
"os"
"strconv"

exocmd "github.com/exoscale/cli/cmd"
"github.com/exoscale/cli/pkg/globalstate"
"github.com/exoscale/cli/pkg/output"
"github.com/exoscale/cli/table"
v3 "github.com/exoscale/egoscale/v3"
"github.com/spf13/cobra"
)

type cryptoGenerateDataKeyOutput struct {
Plaintext string `json:"plaintext"`
Ciphertext string `json:"ciphertext"`
}

func (o *cryptoGenerateDataKeyOutput) ToJSON() { output.JSON(o) }
func (o *cryptoGenerateDataKeyOutput) ToText() { output.Text(o) }
func (o *cryptoGenerateDataKeyOutput) ToTable() {
t := table.NewTable(os.Stdout)
defer t.Render()

t.SetHeader([]string{
"PLAINTEXT",
"CIPHERTEXT",
})

t.Append([]string{
o.Plaintext,
o.Ciphertext,
})
}

type cryptoGenerateDataKeyCmd struct {
exocmd.CliCommandSettings `cli-cmd:"-"`

_ bool `cli-cmd:"generate-data-key"`

Key string `cli-arg:"#" cli-usage:"ID"`

KeySpec v3.GenerateDataKeyRequestKeySpec `cli-short:"s" cli-flag:"key-spec" cli-usage:"key spec for DEK [AES_256]"`
BytesCount string `cli-short:"b" cli-flag:"bytes-count" cli-usage:"number of bytes for DEK (1 - 1024)"`
EncryptionContext string `cli-short:"e" cli-flag:"encryption-context" cli-usage:"encryption context to use for DEK generation"`
Zone v3.ZoneName `cli-short:"z" cli-flag:"zone" cli-usage:"key zone"`
}

func (c *cryptoGenerateDataKeyCmd) CmdAliases() []string { return nil }

func (c *cryptoGenerateDataKeyCmd) CmdShort() string {
return "Generates a data encryption key using a KMS key."
}

func (c *cryptoGenerateDataKeyCmd) CmdLong() string {
return "Generates a data encryption key using a KMS key."
}

func (c *cryptoGenerateDataKeyCmd) CmdPreRun(cmd *cobra.Command, args []string) error {
exocmd.CmdSetZoneFlagFromDefault(cmd)
return exocmd.CliCommandDefaultPreRun(c, cmd, args)
}

func (c *cryptoGenerateDataKeyCmd) CmdRun(_ *cobra.Command, _ []string) error {
ctx := exocmd.GContext
client, err := exocmd.SwitchClientZoneV3(ctx, globalstate.EgoscaleV3Client, c.Zone)
if err != nil {
return err
}

ec := []byte(c.EncryptionContext)

var bytecount int
if c.BytesCount != "" {
n, err := strconv.Atoi(c.BytesCount)
if err != nil {
return err
}
bytecount = n
}

req := v3.GenerateDataKeyRequest{
KeySpec: c.KeySpec,
BytesCount: bytecount,
EncryptionContext: &ec,
}

resp, err := client.GenerateDataKey(ctx, v3.UUID(c.Key), req)
if err != nil {
return err
}

if !globalstate.Quiet {
out := cryptoGenerateDataKeyOutput{
Ciphertext: base64.StdEncoding.EncodeToString(resp.Ciphertext),
Plaintext: base64.StdEncoding.EncodeToString(resp.Plaintext),
}
return c.OutputFunc(&out, nil)
}
return nil
}

func init() {
cobra.CheckErr(exocmd.RegisterCLICommand(cryptoCmd, &cryptoGenerateDataKeyCmd{
CliCommandSettings: exocmd.DefaultCLICmdSettings(),
}))
}
Loading
Loading