Created
January 9, 2025 23:23
-
-
Save cornfeedhobo/c15735331210c7923323372aa09aa5bd to your computer and use it in GitHub Desktop.
quick and dirty cli to pull objects that were client side encrypted
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"fmt" | |
"io" | |
"net/url" | |
"os" | |
"strings" | |
"github.com/aws/amazon-s3-encryption-client-go/v3/client" | |
"github.com/aws/amazon-s3-encryption-client-go/v3/materials" | |
"github.com/aws/aws-sdk-go-v2/config" | |
"github.com/aws/aws-sdk-go-v2/service/kms" | |
"github.com/aws/aws-sdk-go-v2/service/s3" | |
"github.com/aws/aws-sdk-go/aws" | |
"github.com/urfave/cli/v3" | |
) | |
func main() { | |
ctx := context.Background() | |
if err := (&cli.Command{ | |
Name: "s3-encryption-client-cli", | |
Usage: "quick and dirty cli to pull objects that were client side encrypted", | |
ArgsUsage: "<s3 uri> <kms alias name>", | |
Action: cmd, | |
}).Run(ctx, os.Args); err != nil { | |
fmt.Fprintf(os.Stderr, "%v\n", err) | |
} | |
} | |
func cmd(ctx context.Context, cmd *cli.Command) error { | |
uri := cmd.Args().Get(0) | |
kmsAlias := cmd.Args().Get(1) | |
url, err := url.Parse(uri) | |
if err != nil { | |
return fmt.Errorf("failed to parse provided url, %w", err) | |
} | |
bucket := url.Host | |
fmt.Printf("Bucket: %s\n", bucket) | |
key := strings.TrimPrefix(url.Path, "/") | |
fmt.Printf("Key: %s\n", key) | |
// Using the SDK's default configuration, loading additional config | |
// and credentials values from the environment variables, shared | |
// credentials, and shared configuration files | |
cfg, err := config.LoadDefaultConfig(ctx) | |
if err != nil { | |
return fmt.Errorf("unable to load SDK config, %w", err) | |
} | |
s3Client := s3.NewFromConfig(cfg) | |
// head (stat?) object | |
_, err = s3Client.HeadObject(ctx, &s3.HeadObjectInput{Bucket: &bucket, Key: &key}) | |
if err != nil { | |
return fmt.Errorf("failed to list s3 object, %w", err) | |
} | |
kmsClient := kms.NewFromConfig(cfg) | |
kmsAliases, err := kmsClient.ListAliases(ctx, &kms.ListAliasesInput{}) | |
if err != nil { | |
return fmt.Errorf("failed to list aliases, %w", err) | |
} | |
// Find the alias and print the Key ARN | |
var kmsKeyArn string | |
for _, alias := range kmsAliases.Aliases { | |
if strings.HasSuffix(*alias.AliasName, kmsAlias) { | |
kmsKeyArn = *alias.TargetKeyId | |
break | |
} | |
} | |
if kmsKeyArn == "" { | |
return fmt.Errorf("kms alias `%v` not found", kmsAlias) | |
} | |
fmt.Printf("KMS Key ARN: %s\n", kmsKeyArn) | |
// Create the keyring and &CMM-long; (&CMM-short;) | |
cmm, err := materials.NewCryptographicMaterialsManager( | |
materials.NewKmsKeyring( | |
kmsClient, | |
kmsKeyArn, | |
func(options *materials.KeyringOptions) { | |
options.EnableLegacyWrappingAlgorithms = true | |
}, | |
), | |
) | |
if err != nil { | |
return fmt.Errorf("error while creating new CMM") | |
} | |
s3EncryptionClient, err := client.New(s3Client, cmm) | |
if err != nil { | |
return fmt.Errorf("error creating encryption client, %w", err) | |
} | |
out, err := s3EncryptionClient.GetObject(ctx, &s3.GetObjectInput{ | |
Bucket: aws.String(bucket), | |
Key: aws.String(key), | |
}) | |
if err != nil { | |
return fmt.Errorf("error calling getObject, %w", err) | |
} | |
content, err := io.ReadAll(out.Body) | |
if err != nil { | |
return fmt.Errorf("error reading object bytes, %w", err) | |
} | |
fmt.Printf("%s\n", content) | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment