Exemple #1
0
// NewKeyFileStore returns a new KeyFileStore creating a private directory to
// hold the keys.
func NewKeyFileStore(baseDir string, p notary.PassRetriever) (*GenericKeyStore, error) {
	fileStore, err := store.NewPrivateKeyFileStorage(baseDir, notary.KeyExtension)
	if err != nil {
		return nil, err
	}
	return NewGenericKeyStore(fileStore, p), nil
}
Exemple #2
0
func getImporters(baseDir string, _ notary.PassRetriever) ([]utils.Importer, error) {
	fileStore, err := store.NewPrivateKeyFileStorage(baseDir, notary.KeyExtension)
	if err != nil {
		return nil, err
	}
	return []utils.Importer{fileStore}, nil
}
Exemple #3
0
func TestExportKeysByID(t *testing.T) {
	setUp(t)
	tempBaseDir, err := ioutil.TempDir("", "notary-test-")
	require.NoError(t, err)
	defer os.RemoveAll(tempBaseDir)
	output, err := ioutil.TempFile("", "notary-test-import-")
	require.NoError(t, err)
	defer os.RemoveAll(output.Name())
	k := &keyCommander{
		configGetter: func() (*viper.Viper, error) {
			v := viper.New()
			v.SetDefault("trust_dir", tempBaseDir)
			return v, nil
		},
	}
	k.outFile = output.Name()
	err = output.Close() // close so export can open
	require.NoError(t, err)
	k.exportKeyIDs = []string{"one", "three"}

	b := &pem.Block{}
	b.Bytes = make([]byte, 1000)
	rand.Read(b.Bytes)

	b2 := &pem.Block{}
	b2.Bytes = make([]byte, 1000)
	rand.Read(b2.Bytes)

	c := &pem.Block{}
	c.Bytes = make([]byte, 1000)
	rand.Read(c.Bytes)

	bBytes := pem.EncodeToMemory(b)
	b2Bytes := pem.EncodeToMemory(b2)
	cBytes := pem.EncodeToMemory(c)

	fileStore, err := store.NewPrivateKeyFileStorage(tempBaseDir, notary.KeyExtension)
	require.NoError(t, err)
	err = fileStore.Set("one", bBytes)
	require.NoError(t, err)
	err = fileStore.Set("two", b2Bytes)
	require.NoError(t, err)
	err = fileStore.Set("three", cBytes)
	require.NoError(t, err)

	err = k.exportKeys(&cobra.Command{}, nil)
	require.NoError(t, err)

	outRes, err := ioutil.ReadFile(k.outFile)
	require.NoError(t, err)

	block, rest := pem.Decode(outRes)
	require.Equal(t, b.Bytes, block.Bytes)
	require.Equal(t, "one", block.Headers["path"])

	block, rest = pem.Decode(rest)
	require.Equal(t, c.Bytes, block.Bytes)
	require.Equal(t, "three", block.Headers["path"])
	require.Len(t, rest, 0)
}
Exemple #4
0
func (k *keyCommander) exportKeys(cmd *cobra.Command, args []string) error {
	var (
		out io.Writer
		err error
	)
	if len(args) > 0 {
		cmd.Usage()
		return fmt.Errorf("export does not take any positional arguments")
	}
	config, err := k.configGetter()
	if err != nil {
		return err
	}

	if k.outFile == "" {
		out = cmd.Out()
	} else {
		f, err := os.OpenFile(k.outFile, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, notary.PrivExecPerms)
		if err != nil {
			return err
		}
		defer f.Close()
		out = f
	}

	directory := config.GetString("trust_dir")
	fileStore, err := store.NewPrivateKeyFileStorage(directory, notary.KeyExtension)
	if err != nil {
		return err
	}
	if len(k.exportGUNs) > 0 {
		if len(k.exportKeyIDs) > 0 {
			return fmt.Errorf("Only the --gun or --key flag may be provided, not a mix of the two flags")
		}
		for _, gun := range k.exportGUNs {
			return utils.ExportKeysByGUN(out, fileStore, gun)
		}
	} else if len(k.exportKeyIDs) > 0 {
		return utils.ExportKeysByID(out, fileStore, k.exportKeyIDs)
	}
	// export everything
	keys := fileStore.ListFiles()
	for _, k := range keys {
		err := utils.ExportKeys(out, fileStore, k)
		if err != nil {
			return err
		}
	}
	return nil
}
Exemple #5
0
func getImporters(baseDir string, ret notary.PassRetriever) ([]utils.Importer, error) {

	var importers []utils.Importer
	if yubikey.IsAccessible() {
		yubiStore, err := getYubiStore(nil, ret)
		if err == nil {
			importers = append(
				importers,
				yubikey.NewImporter(yubiStore, ret),
			)
		}
	}
	fileStore, err := store.NewPrivateKeyFileStorage(baseDir, notary.KeyExtension)
	if err == nil {
		importers = append(
			importers,
			fileStore,
		)
	} else if len(importers) == 0 {
		return nil, err // couldn't initialize any stores
	}
	return importers, nil
}
Exemple #6
0
func TestImportWithYubikey(t *testing.T) {
	if !yubikey.IsAccessible() {
		t.Skip("Must have Yubikey access.")
	}
	setUp(t)
	tempBaseDir, err := ioutil.TempDir("", "notary-test-")
	require.NoError(t, err)
	defer os.RemoveAll(tempBaseDir)
	input, err := ioutil.TempFile("", "notary-test-import-")
	require.NoError(t, err)
	defer os.RemoveAll(input.Name())
	k := &keyCommander{
		configGetter: func() (*viper.Viper, error) {
			v := viper.New()
			v.SetDefault("trust_dir", tempBaseDir)
			return v, nil
		},
		getRetriever: func() notary.PassRetriever { return passphrase.ConstantRetriever("pass") },
	}

	memStore := store.NewMemoryStore(nil)
	ks := trustmanager.NewGenericKeyStore(memStore, k.getRetriever())
	cs := cryptoservice.NewCryptoService(ks)

	pubK, err := cs.Create(data.CanonicalRootRole, "ankh", data.ECDSAKey)
	require.NoError(t, err)
	bID := pubK.ID() // need to check presence in yubikey later
	bytes, err := memStore.Get(pubK.ID())
	require.NoError(t, err)
	b, _ := pem.Decode(bytes)
	b.Headers["path"] = "ankh"
	require.Equal(t, "root", b.Headers["role"])

	pubK, err = cs.Create(data.CanonicalTargetsRole, "morpork", data.ECDSAKey)
	require.NoError(t, err)
	cID := pubK.ID()
	bytes, err = memStore.Get(pubK.ID())
	require.NoError(t, err)
	c, _ := pem.Decode(bytes)
	c.Headers["path"] = "morpork"

	bBytes := pem.EncodeToMemory(b)
	cBytes := pem.EncodeToMemory(c)
	input.Write(bBytes)
	input.Write(cBytes)

	file := input.Name()
	err = input.Close() // close so import can open
	require.NoError(t, err)

	err = k.importKeys(&cobra.Command{}, []string{file})
	require.NoError(t, err)

	yks, err := yubikey.NewYubiStore(nil, k.getRetriever())
	require.NoError(t, err)
	_, _, err = yks.GetKey(bID)
	require.NoError(t, err)
	_, _, err = yks.GetKey(cID)
	require.Error(t, err) // c is non-root, should not be in yubikey

	fileStore, err := store.NewPrivateKeyFileStorage(tempBaseDir, notary.KeyExtension)
	require.NoError(t, err)
	_, err = fileStore.Get("ankh")
	require.Error(t, err) // b should only be in yubikey, not in filestore

	cResult, err := fileStore.Get("morpork")
	require.NoError(t, err)

	block, rest := pem.Decode(cResult)
	require.Equal(t, c.Bytes, block.Bytes)
	require.Len(t, rest, 0)
}
Exemple #7
0
func TestExportKeysByGUN(t *testing.T) {
	setUp(t)
	tempBaseDir, err := ioutil.TempDir("", "notary-test-")
	require.NoError(t, err)
	defer os.RemoveAll(tempBaseDir)
	output, err := ioutil.TempFile("", "notary-test-import-")
	require.NoError(t, err)
	defer os.RemoveAll(output.Name())
	k := &keyCommander{
		configGetter: func() (*viper.Viper, error) {
			v := viper.New()
			v.SetDefault("trust_dir", tempBaseDir)
			return v, nil
		},
	}
	k.outFile = output.Name()
	err = output.Close() // close so export can open
	require.NoError(t, err)
	k.exportGUNs = []string{"ankh"}

	keyHeaders := make(map[string]string)
	keyHeaders["gun"] = "ankh"
	keyHeaders["role"] = "snapshot"
	b := &pem.Block{
		Headers: keyHeaders,
	}
	b.Bytes = make([]byte, 1000)
	rand.Read(b.Bytes)

	b2 := &pem.Block{
		Headers: keyHeaders,
	}
	b2.Bytes = make([]byte, 1000)
	rand.Read(b2.Bytes)

	otherHeaders := make(map[string]string)
	otherHeaders["gun"] = "morpork"
	otherHeaders["role"] = "snapshot"
	c := &pem.Block{
		Headers: otherHeaders,
	}
	c.Bytes = make([]byte, 1000)
	rand.Read(c.Bytes)

	bBytes := pem.EncodeToMemory(b)
	b2Bytes := pem.EncodeToMemory(b2)
	cBytes := pem.EncodeToMemory(c)

	fileStore, err := store.NewPrivateKeyFileStorage(tempBaseDir, notary.KeyExtension)
	require.NoError(t, err)
	// we have to manually prepend the NonRootKeysSubdir because
	// KeyStore would be expected to do this for us.
	err = fileStore.Set(
		"12345",
		bBytes,
	)
	require.NoError(t, err)
	err = fileStore.Set(
		"23456",
		b2Bytes,
	)
	require.NoError(t, err)
	err = fileStore.Set(
		"34567",
		cBytes,
	)
	require.NoError(t, err)

	err = k.exportKeys(&cobra.Command{}, nil)
	require.NoError(t, err)

	outRes, err := ioutil.ReadFile(k.outFile)
	require.NoError(t, err)

	block, rest := pem.Decode(outRes)
	require.Equal(t, b.Bytes, block.Bytes)
	require.Equal(
		t,
		"12345",
		block.Headers["path"],
	)

	block, rest = pem.Decode(rest)
	require.Equal(t, b2.Bytes, block.Bytes)
	require.Equal(
		t,
		"23456",
		block.Headers["path"],
	)
	require.Len(t, rest, 0)
}
Exemple #8
0
func TestExportKeys(t *testing.T) {
	setUp(t)
	tempBaseDir, err := ioutil.TempDir("", "notary-test-")
	require.NoError(t, err)
	defer os.RemoveAll(tempBaseDir)
	output, err := ioutil.TempFile("", "notary-test-import-")
	require.NoError(t, err)
	defer os.RemoveAll(output.Name())
	k := &keyCommander{
		configGetter: func() (*viper.Viper, error) {
			v := viper.New()
			v.SetDefault("trust_dir", tempBaseDir)
			return v, nil
		},
	}
	k.outFile = output.Name()
	err = output.Close() // close so export can open
	require.NoError(t, err)

	keyHeaders := make(map[string]string)
	keyHeaders["gun"] = "discworld"
	b := &pem.Block{
		Headers: keyHeaders,
	}
	b.Bytes = make([]byte, 1000)
	rand.Read(b.Bytes)

	c := &pem.Block{
		Headers: keyHeaders,
	}
	c.Bytes = make([]byte, 1000)
	rand.Read(c.Bytes)

	bBytes := pem.EncodeToMemory(b)
	cBytes := pem.EncodeToMemory(c)
	require.NoError(t, err)

	fileStore, err := store.NewPrivateKeyFileStorage(tempBaseDir, notary.KeyExtension)
	require.NoError(t, err)
	err = fileStore.Set("ankh", bBytes)
	require.NoError(t, err)
	err = fileStore.Set("morpork", cBytes)
	require.NoError(t, err)

	err = k.exportKeys(&cobra.Command{}, nil)
	require.NoError(t, err)

	outRes, err := ioutil.ReadFile(k.outFile)
	require.NoError(t, err)

	block, rest := pem.Decode(outRes)
	require.Equal(t, b.Bytes, block.Bytes)
	require.Equal(t, "ankh", block.Headers["path"])
	require.Equal(t, "discworld", block.Headers["gun"])

	block, rest = pem.Decode(rest)
	require.Equal(t, c.Bytes, block.Bytes)
	require.Equal(t, "morpork", block.Headers["path"])
	require.Equal(t, "discworld", block.Headers["gun"])
	require.Len(t, rest, 0)

	// test no outFile uses stdout (or our replace buffer)
	k.outFile = ""
	cmd := &cobra.Command{}
	out := bytes.NewBuffer(make([]byte, 0, 3000))
	cmd.SetOutput(out)
	err = k.exportKeys(cmd, nil)
	require.NoError(t, err)

	bufOut, err := ioutil.ReadAll(out)
	require.NoError(t, err)
	require.Equal(t, outRes, bufOut) // should be identical output to file earlier
}
func TestExportImportKeysNoYubikey(t *testing.T) {
	setUp(t)
	exportTempDir, err := ioutil.TempDir("", "notary-test-")
	require.NoError(t, err)
	defer os.RemoveAll(exportTempDir)
	tempfile, err := ioutil.TempFile("", "notary-test-import-")
	require.NoError(t, err)
	tempfile.Close()
	defer os.RemoveAll(tempfile.Name())
	exportCommander := &keyCommander{
		configGetter: func() (*viper.Viper, error) {
			v := viper.New()
			v.SetDefault("trust_dir", exportTempDir)
			return v, nil
		},
		getRetriever: func() notary.PassRetriever { return passphrase.ConstantRetriever("pass") },
	}
	exportCommander.outFile = tempfile.Name()

	exportStore, err := store.NewPrivateKeyFileStorage(exportTempDir, notary.KeyExtension)
	require.NoError(t, err)
	ks := trustmanager.NewGenericKeyStore(exportStore, exportCommander.getRetriever())
	cs := cryptoservice.NewCryptoService(ks)

	pubK, err := cs.Create(data.CanonicalRootRole, "ankh", data.ECDSAKey)
	require.NoError(t, err)
	bID := pubK.ID()
	bOrigBytes, err := exportStore.Get(bID)
	require.NoError(t, err)
	bOrig, _ := pem.Decode(bOrigBytes)

	pubK, err = cs.Create(data.CanonicalTargetsRole, "morpork", data.ECDSAKey)
	require.NoError(t, err)
	cID := pubK.ID()
	cOrigBytes, err := exportStore.Get(cID)
	require.NoError(t, err)
	cOrig, _ := pem.Decode(cOrigBytes)

	exportCommander.exportKeys(&cobra.Command{}, nil)

	importTempDir, err := ioutil.TempDir("", "notary-test-")
	require.NoError(t, err)
	defer os.RemoveAll(importTempDir)
	importCommander := &keyCommander{
		configGetter: func() (*viper.Viper, error) {
			v := viper.New()
			v.SetDefault("trust_dir", importTempDir)
			return v, nil
		},
		getRetriever: func() notary.PassRetriever { return passphrase.ConstantRetriever("pass") },
	}

	err = importCommander.importKeys(&cobra.Command{}, []string{tempfile.Name()})
	require.NoError(t, err)

	importStore, err := store.NewPrivateKeyFileStorage(importTempDir, notary.KeyExtension)
	require.NoError(t, err)
	bResult, err := importStore.Get(bID)
	require.NoError(t, err)
	cResult, err := importStore.Get(cID)
	require.NoError(t, err)

	block, rest := pem.Decode(bResult)
	require.Equal(t, bOrig.Bytes, block.Bytes)
	require.Len(t, rest, 0)

	block, rest = pem.Decode(cResult)
	require.Equal(t, cOrig.Bytes, block.Bytes)
	require.Len(t, rest, 0)
}
func TestImportKeysNoYubikey(t *testing.T) {
	setUp(t)
	tempBaseDir, err := ioutil.TempDir("", "notary-test-")
	require.NoError(t, err)
	defer os.RemoveAll(tempBaseDir)
	input, err := ioutil.TempFile("", "notary-test-import-")
	require.NoError(t, err)
	defer os.RemoveAll(input.Name())
	k := &keyCommander{
		configGetter: func() (*viper.Viper, error) {
			v := viper.New()
			v.SetDefault("trust_dir", tempBaseDir)
			return v, nil
		},
		getRetriever: func() notary.PassRetriever { return passphrase.ConstantRetriever("pass") },
	}

	memStore := store.NewMemoryStore(nil)
	ks := trustmanager.NewGenericKeyStore(memStore, k.getRetriever())
	cs := cryptoservice.NewCryptoService(ks)

	pubK, err := cs.Create(data.CanonicalRootRole, "ankh", data.ECDSAKey)
	require.NoError(t, err)
	bytes, err := memStore.Get(pubK.ID())
	require.NoError(t, err)
	b, _ := pem.Decode(bytes)
	b.Headers["path"] = "ankh"

	pubK, err = cs.Create(data.CanonicalTargetsRole, "morpork", data.ECDSAKey)
	require.NoError(t, err)
	bytes, err = memStore.Get(pubK.ID())
	require.NoError(t, err)
	c, _ := pem.Decode(bytes)
	c.Headers["path"] = "morpork"

	bBytes := pem.EncodeToMemory(b)
	cBytes := pem.EncodeToMemory(c)
	input.Write(bBytes)
	input.Write(cBytes)

	file := input.Name()
	err = input.Close() // close so import can open
	require.NoError(t, err)

	err = k.importKeys(&cobra.Command{}, []string{file})
	require.NoError(t, err)

	fileStore, err := store.NewPrivateKeyFileStorage(tempBaseDir, notary.KeyExtension)
	require.NoError(t, err)
	bResult, err := fileStore.Get("ankh")
	require.NoError(t, err)
	cResult, err := fileStore.Get("morpork")
	require.NoError(t, err)

	block, rest := pem.Decode(bResult)
	require.Equal(t, b.Bytes, block.Bytes)
	require.Len(t, rest, 0)

	block, rest = pem.Decode(cResult)
	require.Equal(t, c.Bytes, block.Bytes)
	require.Len(t, rest, 0)
}