1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package images
import (
"errors"
"fmt"
"github.com/containerd/containerd/cmd/ctr/commands"
"github.com/containerd/imgcrypt/cmd/ctr/commands/flags"
"github.com/containerd/imgcrypt/cmd/ctr/commands/img"
"github.com/containerd/imgcrypt/images/encryption/parsehelpers"
"github.com/urfave/cli"
)
var encryptCommand = cli.Command{
Name: "encrypt",
Usage: "encrypt an image locally",
ArgsUsage: "[flags] <local> <new name>",
Description: `Encrypt an image locally.
Encrypt an image using public keys.
The user must provide recpients who will be able to decrypt the image using
their RSA, EC, or GPG-managed private key. If GPG keys are used then the
user's GPG keyring must hold the public keys of the recipients.
The user has control over the individual layers and the platforms they are
associated with and can encrypt them separately. If no layers or platforms are
specified, all layers for all platforms will be encrypted.
This tool also allows management of the recipients of the image through changes
to the list of recipients.
Once the image has been encrypted it may be pushed to a registry.
Recipients are declared with the protocol prefix as follows:
- pgp:<email-address>
- jwe:<public-key-file-path>
- pkcs7:<x509-file-path>
`,
Flags: append(append(commands.RegistryFlags, cli.StringSliceFlag{
Name: "recipient",
Usage: "Recipient of the image is the person who can decrypt it in the form specified above (i.e. jwe:/path/to/key)",
}, cli.IntSliceFlag{
Name: "layer",
Usage: "The layer to encrypt; this must be either the layer number or a negative number starting with -1 for topmost layer",
}, cli.BoolFlag{
Name: "all-platforms",
Usage: "encrypt for all platforms; this is the default",
}, cli.StringSliceFlag{
Name: "platform",
Usage: "For which platform to encrypt; by default encrytion is done for all platforms",
}), flags.ImageDecryptionFlags...),
Action: func(context *cli.Context) error {
local := context.Args().First()
if local == "" {
return errors.New("please provide the name of an image to encrypt")
}
newName := context.Args().Get(1)
if newName != "" {
fmt.Printf("Encrypting %s to %s\n", local, newName)
} else {
fmt.Printf("Encrypting %s and replacing it with the encrypted image\n", local)
}
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {
return err
}
defer cancel()
recipients := context.StringSlice("recipient")
if len(recipients) == 0 {
return errors.New("no recipients given -- nothing to do")
}
layers32 := img.IntToInt32Array(context.IntSlice("layer"))
_, descs, err := getImageLayerInfos(client, ctx, local, layers32, context.StringSlice("platform"))
if err != nil {
return err
}
cc, err := parsehelpers.CreateCryptoConfig(ParseEncArgs(context), descs)
if err != nil {
return err
}
_, err = encryptImage(client, ctx, local, newName, &cc, layers32, context.StringSlice("platform"))
return err
},
}
|