mirror of https://github.com/docker/docs.git
Add key import and export commands
This adds four commands: - notary keys export: export all keys, or keys for a particular GUN (with -g) - notary keys export-root: export root key by ID - notary keys import: import a zip file of keys - notary keys import-root: import a single root key Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
parent
17a0373eb3
commit
558f52530b
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"archive/zip"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
@ -10,6 +11,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/notary/keystoremanager"
|
"github.com/docker/notary/keystoremanager"
|
||||||
|
"github.com/docker/notary/pkg/passphrase"
|
||||||
"github.com/docker/notary/trustmanager"
|
"github.com/docker/notary/trustmanager"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -18,12 +20,18 @@ import (
|
||||||
func init() {
|
func init() {
|
||||||
cmdKeys.AddCommand(cmdKeysRemoveRootKey)
|
cmdKeys.AddCommand(cmdKeysRemoveRootKey)
|
||||||
cmdKeys.AddCommand(cmdKeysGenerateRootKey)
|
cmdKeys.AddCommand(cmdKeysGenerateRootKey)
|
||||||
|
|
||||||
|
cmdKeysExport.Flags().StringVarP(&keysExportGUN, "gun", "g", "", "Globally unique name to export keys for. A new password will be set for all the keys. Output format is a zip archive.")
|
||||||
|
cmdKeys.AddCommand(cmdKeysExport)
|
||||||
|
cmdKeys.AddCommand(cmdKeysExportRoot)
|
||||||
|
cmdKeys.AddCommand(cmdKeysImport)
|
||||||
|
cmdKeys.AddCommand(cmdKeysImportRoot)
|
||||||
}
|
}
|
||||||
|
|
||||||
var cmdKeys = &cobra.Command{
|
var cmdKeys = &cobra.Command{
|
||||||
Use: "keys",
|
Use: "keys",
|
||||||
Short: "Operates on root keys.",
|
Short: "Operates on keys.",
|
||||||
Long: "operations on private root keys.",
|
Long: "operations on private keys.",
|
||||||
Run: keysList,
|
Run: keysList,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +49,36 @@ var cmdKeysGenerateRootKey = &cobra.Command{
|
||||||
Run: keysGenerateRootKey,
|
Run: keysGenerateRootKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var keysExportGUN string
|
||||||
|
|
||||||
|
var cmdKeysExport = &cobra.Command{
|
||||||
|
Use: "export [ filename ]",
|
||||||
|
Short: "Exports keys to a ZIP file.",
|
||||||
|
Long: "exports a collection of keys. The keys are reencrypted with a new passphrase. The output is a ZIP file.",
|
||||||
|
Run: keysExport,
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdKeysExportRoot = &cobra.Command{
|
||||||
|
Use: "export-root [ keyID ] [ filename ]",
|
||||||
|
Short: "Exports given root key to a file.",
|
||||||
|
Long: "exports a root key, without reencrypting. The output is a PEM file.",
|
||||||
|
Run: keysExportRoot,
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdKeysImport = &cobra.Command{
|
||||||
|
Use: "import [ filename ]",
|
||||||
|
Short: "Imports keys from a ZIP file.",
|
||||||
|
Long: "imports one or more keys from a ZIP file.",
|
||||||
|
Run: keysImport,
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdKeysImportRoot = &cobra.Command{
|
||||||
|
Use: "import-root [ keyID ] [ filename ]",
|
||||||
|
Short: "Imports root key.",
|
||||||
|
Long: "imports a root key from a PEM file.",
|
||||||
|
Run: keysImportRoot,
|
||||||
|
}
|
||||||
|
|
||||||
// keysRemoveRootKey deletes a root private key based on ID
|
// keysRemoveRootKey deletes a root private key based on ID
|
||||||
func keysRemoveRootKey(cmd *cobra.Command, args []string) {
|
func keysRemoveRootKey(cmd *cobra.Command, args []string) {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
|
@ -141,6 +179,140 @@ func keysGenerateRootKey(cmd *cobra.Command, args []string) {
|
||||||
fmt.Printf("Generated new %s key with keyID: %s\n", algorithm, keyID)
|
fmt.Printf("Generated new %s key with keyID: %s\n", algorithm, keyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keysExport exports a collection of keys to a ZIP file
|
||||||
|
func keysExport(cmd *cobra.Command, args []string) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
cmd.Usage()
|
||||||
|
fatalf("must specify output filename for export")
|
||||||
|
}
|
||||||
|
|
||||||
|
exportFilename := args[0]
|
||||||
|
|
||||||
|
parseConfig()
|
||||||
|
|
||||||
|
keyStoreManager, err := keystoremanager.NewKeyStoreManager(trustDir, retriever)
|
||||||
|
if err != nil {
|
||||||
|
fatalf("failed to create a new truststore manager with directory: %s", trustDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
exportFile, err := os.Create(exportFilename)
|
||||||
|
if err != nil {
|
||||||
|
fatalf("error creating output file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must use a different passphrase retriever to avoid caching the
|
||||||
|
// unlocking passphrase and reusing that.
|
||||||
|
exportRetriever := passphrase.PromptRetriever()
|
||||||
|
if keysExportGUN != "" {
|
||||||
|
err = keyStoreManager.ExportKeysByGUN(exportFile, keysExportGUN, exportRetriever)
|
||||||
|
} else {
|
||||||
|
err = keyStoreManager.ExportAllKeys(exportFile, exportRetriever)
|
||||||
|
}
|
||||||
|
|
||||||
|
exportFile.Close()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fatalf("error exporting keys: %v", err)
|
||||||
|
os.Remove(exportFilename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// keysExportRoot exports a root key by ID to a PEM file
|
||||||
|
func keysExportRoot(cmd *cobra.Command, args []string) {
|
||||||
|
if len(args) < 2 {
|
||||||
|
cmd.Usage()
|
||||||
|
fatalf("must specify key ID and output filename for export")
|
||||||
|
}
|
||||||
|
|
||||||
|
keyID := args[0]
|
||||||
|
exportFilename := args[1]
|
||||||
|
|
||||||
|
if len(keyID) != 64 {
|
||||||
|
fatalf("please specify a valid root key ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
parseConfig()
|
||||||
|
|
||||||
|
keyStoreManager, err := keystoremanager.NewKeyStoreManager(trustDir, retriever)
|
||||||
|
if err != nil {
|
||||||
|
fatalf("failed to create a new truststore manager with directory: %s", trustDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
exportFile, err := os.Create(exportFilename)
|
||||||
|
if err != nil {
|
||||||
|
fatalf("error creating output file: %v", err)
|
||||||
|
}
|
||||||
|
err = keyStoreManager.ExportRootKey(exportFile, keyID)
|
||||||
|
exportFile.Close()
|
||||||
|
if err != nil {
|
||||||
|
fatalf("error exporting root key: %v", err)
|
||||||
|
os.Remove(exportFilename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// keysImport imports keys from a ZIP file
|
||||||
|
func keysImport(cmd *cobra.Command, args []string) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
cmd.Usage()
|
||||||
|
fatalf("must specify input filename for import")
|
||||||
|
}
|
||||||
|
|
||||||
|
importFilename := args[0]
|
||||||
|
|
||||||
|
parseConfig()
|
||||||
|
|
||||||
|
keyStoreManager, err := keystoremanager.NewKeyStoreManager(trustDir, retriever)
|
||||||
|
if err != nil {
|
||||||
|
fatalf("failed to create a new truststore manager with directory: %s", trustDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
zipReader, err := zip.OpenReader(importFilename)
|
||||||
|
if err != nil {
|
||||||
|
fatalf("opening file for import: %v", err)
|
||||||
|
}
|
||||||
|
defer zipReader.Close()
|
||||||
|
|
||||||
|
err = keyStoreManager.ImportKeysZip(zipReader.Reader)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fatalf("error importing keys: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// keysImportRoot imports a root key from a PEM file
|
||||||
|
func keysImportRoot(cmd *cobra.Command, args []string) {
|
||||||
|
if len(args) < 2 {
|
||||||
|
cmd.Usage()
|
||||||
|
fatalf("must specify key ID and input filename for import")
|
||||||
|
}
|
||||||
|
|
||||||
|
keyID := args[0]
|
||||||
|
importFilename := args[1]
|
||||||
|
|
||||||
|
if len(keyID) != 64 {
|
||||||
|
fatalf("please specify a valid root key ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
parseConfig()
|
||||||
|
|
||||||
|
keyStoreManager, err := keystoremanager.NewKeyStoreManager(trustDir, retriever)
|
||||||
|
if err != nil {
|
||||||
|
fatalf("failed to create a new truststore manager with directory: %s", trustDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
importFile, err := os.Open(importFilename)
|
||||||
|
if err != nil {
|
||||||
|
fatalf("opening file for import: %v", err)
|
||||||
|
}
|
||||||
|
defer importFile.Close()
|
||||||
|
|
||||||
|
err = keyStoreManager.ImportRootKey(importFile, keyID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fatalf("error importing root key: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func printCert(cert *x509.Certificate) {
|
func printCert(cert *x509.Certificate) {
|
||||||
timeDifference := cert.NotAfter.Sub(time.Now())
|
timeDifference := cert.NotAfter.Sub(time.Now())
|
||||||
certID, err := trustmanager.FingerprintCert(cert)
|
certID, err := trustmanager.FingerprintCert(cert)
|
||||||
|
|
Loading…
Reference in New Issue