Skip to content

Commit

Permalink
Image encryption/decryption support in skopeo
Browse files Browse the repository at this point in the history
Signed-off-by: Harshal Patil <harshal.patil@in.ibm.com>
Signed-off-by: Brandon Lum <lumjjb@gmail.com>
  • Loading branch information
Harshal Patil committed Nov 26, 2019
1 parent 34ab4c4 commit b14b6dd
Show file tree
Hide file tree
Showing 201 changed files with 29,140 additions and 3,912 deletions.
50 changes: 50 additions & 0 deletions cmd/skopeo/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import (
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/transports"
"github.com/containers/image/v5/transports/alltransports"

encconfig "github.com/containers/ocicrypt/config"
enchelpers "github.com/containers/ocicrypt/helpers"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/urfave/cli"
)
Expand All @@ -25,6 +28,8 @@ type copyOptions struct {
format optionalString // Force conversion of the image to a specified format
quiet bool // Suppress output information when copying images
all bool // Copy all of the images if the source is a list
encryptionKeys cli.StringSlice // Keys needed to encrypt the image
decryptionKeys cli.StringSlice // Keys needed to decrypt the image
}

func copyCmd(global *globalOptions) cli.Command {
Expand Down Expand Up @@ -82,6 +87,16 @@ func copyCmd(global *globalOptions) cli.Command {
Usage: "`MANIFEST TYPE` (oci, v2s1, or v2s2) to use when saving image to directory using the 'dir:' transport (default is manifest type of source)",
Value: newOptionalStringValue(&opts.format),
},
cli.StringSliceFlag{
Name: "encryption-key",
Usage: "*Experimental* key with the encryption protocol to use needed to encrypt the image (e.g. jwe:/path/to/key.pem)",
Value: &opts.encryptionKeys,
},
cli.StringSliceFlag{
Name: "decryption-key",
Usage: "*Experimental* key needed to decrypt the image",
Value: &opts.decryptionKeys,
},
}, sharedFlags...), srcFlags...), destFlags...),
}
}
Expand Down Expand Up @@ -156,6 +171,38 @@ func (opts *copyOptions) run(args []string, stdout io.Writer) error {
if opts.all {
imageListSelection = copy.CopyAllImages
}

if len(opts.encryptionKeys.Value()) > 0 && len(opts.decryptionKeys.Value()) > 0 {
return fmt.Errorf("--encryption-key and --decryption-key cannot be specified together")
}

var encLayers *[]int
var encConfig *encconfig.EncryptConfig
var decConfig *encconfig.DecryptConfig

if len(opts.encryptionKeys.Value()) > 0 {
// encryption
encLayers = &[]int{}
encryptionKeys := opts.encryptionKeys.Value()
ecc, err := enchelpers.CreateCryptoConfig(encryptionKeys, []string{})
if err != nil {
return err
}
cc := encconfig.CombineCryptoConfigs([]encconfig.CryptoConfig{ecc})
encConfig = cc.EncryptConfig
}

if len(opts.decryptionKeys.Value()) > 0 {
// decryption
decryptionKeys := opts.decryptionKeys.Value()
dcc, err := enchelpers.CreateCryptoConfig([]string{}, decryptionKeys)
if err != nil {
return err
}
cc := encconfig.CombineCryptoConfigs([]encconfig.CryptoConfig{dcc})
decConfig = cc.DecryptConfig
}

_, err = copy.Image(ctx, policyContext, destRef, srcRef, &copy.Options{
RemoveSignatures: opts.removeSignatures,
SignBy: opts.signByFingerprint,
Expand All @@ -164,6 +211,9 @@ func (opts *copyOptions) run(args []string, stdout io.Writer) error {
DestinationCtx: destinationCtx,
ForceManifestMIMEType: manifestType,
ImageListSelection: imageListSelection,
OciDecryptConfig: decConfig,
OciEncryptLayers: encLayers,
OciEncryptConfig: encConfig,
})
return err
}
28 changes: 28 additions & 0 deletions docs/skopeo-copy.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ If the authorization state is not found there, $HOME/.docker/config.json is chec

**--sign-by=**_key-id_ add a signature using that key ID for an image name corresponding to _destination-image_

**--encryption-key** _Key_ a reference prefixed with the encryption protocol to use. e.g. jwe:/path/to/key.pem or pgp:admin@example.com or pkcs7:/path/to/x509-file. This feature is still *experimental*.

**--decryption-key** _Key_ a reference required to perform decryption of container images. This should point to files which represent keys and/or certificates that can be used for decryption. Decryption will be tried with all keys. This feature is still *experimental*.

**--src-creds** _username[:password]_ for accessing the source registry

**--dest-compress** _bool-value_ Compress tarball image layers when saving to directory using the 'dir' transport. (default is same compression type as source)
Expand Down Expand Up @@ -84,6 +88,30 @@ To copy and sign an image:
# skopeo copy --sign-by dev@example.com container-storage:example/busybox:streaming docker://example/busybox:gold
```

To encrypt an image:
```sh
skopeo copy docker://docker.io/library/nginx:latest oci:local_nginx:latest

openssl genrsa -out private.key 1024
openssl rsa -in private.key -pubout > public.key

skopeo copy --encryption-key jwe:./public.key oci:local_nginx:latest oci:try-encrypt:encrypted
```

To decrypt an image:
```sh
skopeo copy --decryption-key ./private.key oci:try-encrypt:encryted oci:try-decrypt:decrypted
```

To copy encrypted image without decryption:
```sh
skopeo copy oci:try-encrypt:encryted oci:try-encrypt-copy:encrypted
```

To decrypt an image that requires more than one key:
```sh
skopeo copy --decryption-key ./private1.key --decryption-key ./private2.key --decryption-key ./private3.key oci:try-encrypt:encrypted oci:try-decrypt:decrypted
```
## SEE ALSO
skopeo(1), podman-login(1), docker-login(1)

Expand Down
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ go 1.12
require (
github.com/containers/buildah v1.11.5
github.com/containers/image/v5 v5.0.0
github.com/containers/storage v1.13.5
github.com/containers/ocicrypt v0.0.0-20190930154801-b87a4a69c741
github.com/containers/storage v1.14.0
github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23
github.com/dsnet/compress v0.0.1 // indirect
github.com/go-check/check v0.0.0-20180628173108-788fd7840127
Expand All @@ -20,4 +21,7 @@ require (
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
github.com/urfave/cli v1.22.1
go4.org v0.0.0-20190218023631-ce4c26f7be8e // indirect
google.golang.org/appengine v1.4.0 // indirect
)

replace github.com/containers/image/v5 => github.com/lumjjb/image/v5 v5.0.0-20191125184705-a298da5c535d
Loading

0 comments on commit b14b6dd

Please sign in to comment.