Пример #1
0
// Generates a Manager in a temporary directory and returns the
// manager and certificates for two keys which have been added to the keystore.
// Also returns the temporary directory so it can be cleaned up.
func filestoreWithTwoCerts(t *testing.T, gun, keyAlg string) (
	string, *Manager, *cryptoservice.CryptoService, []*x509.Certificate) {
	tempBaseDir, err := ioutil.TempDir("", "notary-test-")
	assert.NoError(t, err, "failed to create a temporary directory: %s", err)

	fileKeyStore, err := trustmanager.NewKeyFileStore(tempBaseDir, passphraseRetriever)
	assert.NoError(t, err)

	cryptoService := cryptoservice.NewCryptoService(gun, fileKeyStore)

	// Create a Manager
	certManager, err := NewManager(tempBaseDir)
	assert.NoError(t, err)

	certificates := make([]*x509.Certificate, 2)
	for i := 0; i < 2; i++ {
		pubKey, err := cryptoService.Create("root", keyAlg)
		assert.NoError(t, err)

		key, _, err := fileKeyStore.GetKey(pubKey.ID())
		assert.NoError(t, err)

		cert, err := cryptoservice.GenerateTestingCertificate(key.CryptoSigner(), gun)
		assert.NoError(t, err)

		certificates[i] = cert
	}
	return tempBaseDir, certManager, cryptoService, certificates
}
Пример #2
0
func init() {
	pr = func(string, string, bool, int) (string, bool, error) { return "passphrase", false, nil }
	keyStore := trustmanager.NewKeyMemoryStore(pr)
	cryptoService := cryptoservice.NewCryptoService("", keyStore)
	cryptoServices := signer.CryptoServiceIndex{data.ED25519Key: cryptoService, data.RSAKey: cryptoService, data.ECDSAKey: cryptoService}
	void = &pb.Void{}

	fakeHealth := func() map[string]string {
		return health
	}

	//server setup
	kms := &api.KeyManagementServer{CryptoServices: cryptoServices,
		HealthChecker: fakeHealth}
	ss := &api.SignerServer{CryptoServices: cryptoServices,
		HealthChecker: fakeHealth}
	grpcServer = grpc.NewServer()
	pb.RegisterKeyManagementServer(grpcServer, kms)
	pb.RegisterSignerServer(grpcServer, ss)
	lis, err := net.Listen("tcp", "127.0.0.1:7899")
	if err != nil {
		log.Fatalf("failed to listen %v", err)
	}

	go grpcServer.Serve(lis)

	//client setup
	conn, err := grpc.Dial("127.0.0.1:7899", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("fail to dial: %v", err)
	}

	kmClient = pb.NewKeyManagementClient(conn)
	sClient = pb.NewSignerClient(conn)
}
Пример #3
0
func TestSoftwareSignHandler(t *testing.T) {
	keyStore := trustmanager.NewKeyMemoryStore(passphraseRetriever)
	cryptoService := cryptoservice.NewCryptoService("", keyStore)
	setup(signer.CryptoServiceIndex{data.ED25519Key: cryptoService, data.RSAKey: cryptoService, data.ECDSAKey: cryptoService})

	tufKey, err := cryptoService.Create("", data.ED25519Key)
	assert.Nil(t, err)

	sigRequest := &pb.SignatureRequest{KeyID: &pb.KeyID{ID: tufKey.ID()}, Content: make([]byte, 10)}
	requestJson, _ := json.Marshal(sigRequest)

	reader = strings.NewReader(string(requestJson))

	request, err := http.NewRequest("POST", signBaseURL, reader)

	assert.Nil(t, err)

	res, err := http.DefaultClient.Do(request)
	assert.Nil(t, err)

	assert.Equal(t, 200, res.StatusCode)

	jsonBlob, err := ioutil.ReadAll(res.Body)
	assert.Nil(t, err)

	var sig *pb.Signature
	err = json.Unmarshal(jsonBlob, &sig)
	assert.Nil(t, err)

	assert.Equal(t, tufKey.ID(), sig.KeyInfo.KeyID.ID)
}
Пример #4
0
func TestKeyInfoHandler(t *testing.T) {
	keyStore := trustmanager.NewKeyMemoryStore(passphraseRetriever)
	cryptoService := cryptoservice.NewCryptoService("", keyStore)
	setup(signer.CryptoServiceIndex{data.ED25519Key: cryptoService, data.RSAKey: cryptoService, data.ECDSAKey: cryptoService})

	tufKey, _ := cryptoService.Create("", data.ED25519Key)
	assert.NotNil(t, tufKey)

	keyInfoURL := fmt.Sprintf("%s/%s", keyInfoBaseURL, tufKey.ID())

	request, err := http.NewRequest("GET", keyInfoURL, nil)
	assert.Nil(t, err)

	res, err := http.DefaultClient.Do(request)
	assert.Nil(t, err)

	jsonBlob, err := ioutil.ReadAll(res.Body)
	assert.Nil(t, err)

	var pubKey *pb.PublicKey
	err = json.Unmarshal(jsonBlob, &pubKey)
	assert.Nil(t, err)

	assert.Equal(t, tufKey.ID(), pubKey.KeyInfo.KeyID.ID)
	assert.Equal(t, 200, res.StatusCode)
}
Пример #5
0
// NewNotaryRepository is a helper method that returns a new notary repository.
// It takes the base directory under where all the trust files will be stored
// (usually ~/.docker/trust/).
func NewNotaryRepository(baseDir, gun, baseURL string, rt http.RoundTripper,
	passphraseRetriever passphrase.Retriever) (*NotaryRepository, error) {

	keyStoreManager, err := keystoremanager.NewKeyStoreManager(baseDir, passphraseRetriever)
	if err != nil {
		return nil, err
	}

	cryptoService := cryptoservice.NewCryptoService(gun, keyStoreManager.NonRootKeyStore())

	nRepo := &NotaryRepository{
		gun:             gun,
		baseDir:         baseDir,
		baseURL:         baseURL,
		tufRepoPath:     filepath.Join(baseDir, tufDir, filepath.FromSlash(gun)),
		cryptoService:   cryptoService,
		roundTrip:       rt,
		KeyStoreManager: keyStoreManager,
	}

	fileStore, err := store.NewFilesystemStore(
		nRepo.tufRepoPath,
		"metadata",
		"json",
		"",
	)
	if err != nil {
		return nil, err
	}
	nRepo.fileStore = fileStore

	return nRepo, nil
}
Пример #6
0
// keysImportRoot imports a root key from a PEM file
func (k *keyCommander) keysImportRoot(cmd *cobra.Command, args []string) error {
	if len(args) != 1 {
		return fmt.Errorf("Must specify input filename for import")
	}

	config := k.configGetter()
	ks, err := k.getKeyStores(config, true)
	if err != nil {
		return err
	}
	cs := cryptoservice.NewCryptoService("", ks...)

	importFilename := args[0]

	importFile, err := os.Open(importFilename)
	if err != nil {
		return fmt.Errorf("Opening file for import: %v", err)
	}
	defer importFile.Close()

	err = cs.ImportRootKey(importFile)

	if err != nil {
		return fmt.Errorf("Error importing root key: %v", err)
	}
	return nil
}
Пример #7
0
// keysRestore imports keys from a ZIP file
func (k *keyCommander) keysRestore(cmd *cobra.Command, args []string) error {
	if len(args) < 1 {
		cmd.Usage()
		return fmt.Errorf("Must specify input filename for import")
	}

	importFilename := args[0]

	config, err := k.configGetter()
	if err != nil {
		return err
	}
	ks, err := k.getKeyStores(config, true, false)
	if err != nil {
		return err
	}
	cs := cryptoservice.NewCryptoService(ks...)

	zipReader, err := zip.OpenReader(importFilename)
	if err != nil {
		return fmt.Errorf("Opening file for import: %v", err)
	}
	defer zipReader.Close()

	err = cs.ImportKeysZip(zipReader.Reader, k.getRetriever())

	if err != nil {
		return fmt.Errorf("Error importing keys: %v", err)
	}
	return nil
}
Пример #8
0
// keysImportRoot imports a root key from a PEM file
func keysImportRoot(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		fatalf("Must specify input filename for import")
	}

	parseConfig()

	cs := cryptoservice.NewCryptoService(
		"",
		getKeyStores(cmd, mainViper.GetString("trust_dir"), retriever, true)...,
	)

	importFilename := args[0]

	importFile, err := os.Open(importFilename)
	if err != nil {
		fatalf("Opening file for import: %v", err)
	}
	defer importFile.Close()

	err = cs.ImportRootKey(importFile)

	if err != nil {
		fatalf("Error importing root key: %v", err)
	}
}
Пример #9
0
// initialize a repo with keys, so they can be rotated
func setUpRepo(t *testing.T, tempBaseDir, gun string, ret notary.PassRetriever) (
	*httptest.Server, map[string]string) {

	// Set up server
	ctx := context.WithValue(
		context.Background(), "metaStore", storage.NewMemStorage())

	// Do not pass one of the const KeyAlgorithms here as the value! Passing a
	// string is in itself good test that we are handling it correctly as we
	// will be receiving a string from the configuration.
	ctx = context.WithValue(ctx, "keyAlgorithm", "ecdsa")

	// Eat the logs instead of spewing them out
	l := logrus.New()
	l.Out = bytes.NewBuffer(nil)
	ctx = ctxu.WithLogger(ctx, logrus.NewEntry(l))

	cryptoService := cryptoservice.NewCryptoService(trustmanager.NewKeyMemoryStore(ret))
	ts := httptest.NewServer(server.RootHandler(nil, ctx, cryptoService, nil, nil, nil))

	repo, err := client.NewNotaryRepository(
		tempBaseDir, gun, ts.URL, http.DefaultTransport, ret, trustpinning.TrustPinConfig{})
	require.NoError(t, err, "error creating repo: %s", err)

	rootPubKey, err := repo.CryptoService.Create("root", "", data.ECDSAKey)
	require.NoError(t, err, "error generating root key: %s", err)

	err = repo.Initialize(rootPubKey.ID())
	require.NoError(t, err)

	return ts, repo.CryptoService.ListAllKeys()
}
Пример #10
0
// keysRestore imports keys from a ZIP file
func keysRestore(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		cmd.Usage()
		fatalf("Must specify input filename for import")
	}

	importFilename := args[0]

	parseConfig()

	cs := cryptoservice.NewCryptoService(
		"",
		getKeyStores(cmd, mainViper.GetString("trust_dir"), retriever, true)...,
	)

	zipReader, err := zip.OpenReader(importFilename)
	if err != nil {
		fatalf("Opening file for import: %v", err)
	}
	defer zipReader.Close()

	err = cs.ImportKeysZip(zipReader.Reader)

	if err != nil {
		fatalf("Error importing keys: %v", err)
	}
}
Пример #11
0
// keysBackup exports a collection of keys to a ZIP file
func keysBackup(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		cmd.Usage()
		fatalf("Must specify output filename for export")
	}

	parseConfig()
	exportFilename := args[0]

	cs := cryptoservice.NewCryptoService(
		"",
		getKeyStores(cmd, mainViper.GetString("trust_dir"), retriever, false)...,
	)

	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 := getRetriever()
	if keysExportGUN != "" {
		err = cs.ExportKeysByGUN(exportFile, keysExportGUN, exportRetriever)
	} else {
		err = cs.ExportAllKeys(exportFile, exportRetriever)
	}

	exportFile.Close()

	if err != nil {
		os.Remove(exportFilename)
		fatalf("Error exporting keys: %v", err)
	}
}
Пример #12
0
// repositoryFromKeystores is a helper function for NewNotaryRepository that
// takes some basic NotaryRepository parameters as well as keystores (in order
// of usage preference), and returns a NotaryRepository.
func repositoryFromKeystores(baseDir, gun, baseURL string, rt http.RoundTripper,
	keyStores []trustmanager.KeyStore) (*NotaryRepository, error) {

	certManager, err := certs.NewManager(baseDir)
	if err != nil {
		return nil, err
	}

	cryptoService := cryptoservice.NewCryptoService(gun, keyStores...)

	nRepo := &NotaryRepository{
		gun:           gun,
		baseDir:       baseDir,
		baseURL:       baseURL,
		tufRepoPath:   filepath.Join(baseDir, tufDir, filepath.FromSlash(gun)),
		CryptoService: cryptoService,
		roundTrip:     rt,
		CertManager:   certManager,
	}

	fileStore, err := store.NewFilesystemStore(
		nRepo.tufRepoPath,
		"metadata",
		"json",
		"",
	)
	if err != nil {
		return nil, err
	}
	nRepo.fileStore = fileStore

	return nRepo, nil
}
Пример #13
0
func TestSignRootOldKeyCertMissing(t *testing.T) {
	gun := "docker/test-sign-root"
	referenceTime := time.Now()

	cs := cryptoservice.NewCryptoService(trustmanager.NewKeyMemoryStore(
		passphrase.ConstantRetriever("password")))

	rootPublicKey, err := cs.Create(data.CanonicalRootRole, gun, data.ECDSAKey)
	require.NoError(t, err)
	rootPrivateKey, _, err := cs.GetPrivateKey(rootPublicKey.ID())
	require.NoError(t, err)
	oldRootCert, err := cryptoservice.GenerateCertificate(rootPrivateKey, gun, referenceTime.AddDate(-9, 0, 0),
		referenceTime.AddDate(1, 0, 0))
	require.NoError(t, err)
	oldRootCertKey := trustmanager.CertToKey(oldRootCert)

	repo := initRepoWithRoot(t, cs, oldRootCertKey)

	// Create a first signature, using the old key.
	signedRoot, err := repo.SignRoot(data.DefaultExpires(data.CanonicalRootRole))
	require.NoError(t, err)
	verifySignatureList(t, signedRoot, oldRootCertKey)
	err = verifyRootSignatureAgainstKey(t, signedRoot, oldRootCertKey)
	require.NoError(t, err)

	// Create a new certificate
	newRootCert, err := cryptoservice.GenerateCertificate(rootPrivateKey, gun, referenceTime, referenceTime.AddDate(10, 0, 0))
	require.NoError(t, err)
	newRootCertKey := trustmanager.CertToKey(newRootCert)
	require.NotEqual(t, oldRootCertKey.ID(), newRootCertKey.ID())

	// Only trust the new certificate
	err = repo.ReplaceBaseKeys(data.CanonicalRootRole, newRootCertKey)
	require.NoError(t, err)
	updatedRootRole, err := repo.GetBaseRole(data.CanonicalRootRole)
	require.NoError(t, err)
	updatedRootKeyIDs := updatedRootRole.ListKeyIDs()
	require.Equal(t, 1, len(updatedRootKeyIDs))
	require.Equal(t, newRootCertKey.ID(), updatedRootKeyIDs[0])

	// Now forget all about the old certificate: drop it from the Root carried keys
	delete(repo.Root.Signed.Keys, oldRootCertKey.ID())
	repo2 := NewRepo(cs)
	repo2.Root = repo.Root
	repo2.originalRootRole = updatedRootRole

	// Create a second signature
	signedRoot, err = repo2.SignRoot(data.DefaultExpires(data.CanonicalRootRole))
	require.NoError(t, err)
	verifySignatureList(t, signedRoot, newRootCertKey) // Without oldRootCertKey

	// Verify that the signature can be verified when trusting the new certificate
	err = verifyRootSignatureAgainstKey(t, signedRoot, newRootCertKey)
	require.NoError(t, err)
	err = verifyRootSignatureAgainstKey(t, signedRoot, oldRootCertKey)
	require.Error(t, err)
}
Пример #14
0
// GetRootCryptoService retreives a root key and a cryptoservice to use with it
func (km *KeyStoreManager) GetRootCryptoService(rootKeyID, passphrase string) (*cryptoservice.UnlockedCryptoService, error) {
	privKey, err := km.rootKeyStore.GetDecryptedKey(rootKeyID, passphrase)
	if err != nil {
		return nil, fmt.Errorf("could not get decrypted root key with keyID: %s, %v", rootKeyID, err)
	}

	cryptoService := cryptoservice.NewCryptoService("", km.rootKeyStore, passphrase)

	return cryptoservice.NewUnlockedCryptoService(privKey, cryptoService), nil
}
Пример #15
0
// CopyKeys copies keys of a particular role to a new cryptoservice, and returns that cryptoservice
func CopyKeys(t *testing.T, from signed.CryptoService, roles ...string) signed.CryptoService {
	memKeyStore := trustmanager.NewKeyMemoryStore(passphrase.ConstantRetriever("pass"))
	for _, role := range roles {
		for _, keyID := range from.ListKeys(role) {
			key, _, err := from.GetPrivateKey(keyID)
			require.NoError(t, err)
			memKeyStore.AddKey(trustmanager.KeyInfo{Role: role}, key)
		}
	}
	return cryptoservice.NewCryptoService(memKeyStore)
}
Пример #16
0
func testValidateSuccessfulRootRotation(t *testing.T, keyAlg, rootKeyType string) {
	// The gun to test
	gun := "docker.com/notary"

	tempBaseDir, keyStoreManager, certs := filestoreWithTwoCerts(t, gun, keyAlg)
	defer os.RemoveAll(tempBaseDir)
	origRootCert := certs[0]
	replRootCert := certs[1]

	// Add the old root cert part of trustedCertificates
	keyStoreManager.AddTrustedCert(origRootCert)

	// We need the PEM representation of the replacement key to put it into the TUF data
	origRootPEMCert := trustmanager.CertToPEM(origRootCert)
	replRootPEMCert := trustmanager.CertToPEM(replRootCert)

	// Tuf key with PEM-encoded x509 certificate
	origRootKey := data.NewPublicKey(rootKeyType, origRootPEMCert)
	replRootKey := data.NewPublicKey(rootKeyType, replRootPEMCert)

	rootRole, err := data.NewRole("root", 1, []string{replRootKey.ID()}, nil, nil)
	assert.NoError(t, err)

	testRoot, err := data.NewRoot(
		map[string]data.PublicKey{replRootKey.ID(): replRootKey},
		map[string]*data.RootRole{"root": &rootRole.RootRole},
		false,
	)
	assert.NoError(t, err, "Failed to create new root")

	signedTestRoot, err := testRoot.ToSigned()
	assert.NoError(t, err)

	cs := cryptoservice.NewCryptoService(gun, keyStoreManager.KeyStore)

	err = signed.Sign(cs, signedTestRoot, replRootKey)
	assert.NoError(t, err)

	err = signed.Sign(cs, signedTestRoot, origRootKey)
	assert.NoError(t, err)

	//
	// This call to ValidateRoot will succeed since we are using a valid PEM
	// encoded certificate, and have no other certificates for this CN
	//
	err = keyStoreManager.ValidateRoot(signedTestRoot, gun)
	assert.NoError(t, err)

	// Finally, validate the only trusted certificate that exists is the new one
	certs = keyStoreManager.trustedCertificateStore.GetCertificates()
	assert.Len(t, certs, 1)
	assert.Equal(t, certs[0], replRootCert)
}
Пример #17
0
// NewNotaryRepository is a helper method that returns a new notary repository.
// It takes the base directory under where all the trust files will be stored
// (usually ~/.docker/trust/).
func NewNotaryRepository(baseDir, gun, baseURL string, rt http.RoundTripper,
	retriever passphrase.Retriever) (*NotaryRepository, error) {

	fileKeyStore, err := trustmanager.NewKeyFileStore(baseDir, retriever)
	if err != nil {
		return nil, fmt.Errorf("failed to create private key store in directory: %s", baseDir)
	}

	keyStoreManager, err := keystoremanager.NewKeyStoreManager(baseDir)
	yubiKeyStore, _ := yubikey.NewYubiKeyStore(fileKeyStore, retriever)
	var cryptoService signed.CryptoService
	if yubiKeyStore == nil {
		cryptoService = cryptoservice.NewCryptoService(gun, fileKeyStore)
	} else {
		cryptoService = cryptoservice.NewCryptoService(gun, yubiKeyStore, fileKeyStore)
	}

	nRepo := &NotaryRepository{
		gun:             gun,
		baseDir:         baseDir,
		baseURL:         baseURL,
		tufRepoPath:     filepath.Join(baseDir, tufDir, filepath.FromSlash(gun)),
		CryptoService:   cryptoService,
		roundTrip:       rt,
		KeyStoreManager: keyStoreManager,
	}

	fileStore, err := store.NewFilesystemStore(
		nRepo.tufRepoPath,
		"metadata",
		"json",
		"",
	)
	if err != nil {
		return nil, err
	}
	nRepo.fileStore = fileStore

	return nRepo, nil
}
Пример #18
0
// keyPassphraseChange changes the passphrase for a root key's private key based on ID
func (k *keyCommander) keyPassphraseChange(cmd *cobra.Command, args []string) error {
	if len(args) < 1 {
		cmd.Usage()
		return fmt.Errorf("must specify the key ID of the key to change the passphrase of")
	}

	config, err := k.configGetter()
	if err != nil {
		return err
	}
	ks, err := k.getKeyStores(config, true)
	if err != nil {
		return err
	}

	keyID := args[0]

	// This is an invalid ID
	if len(keyID) != notary.Sha256HexSize {
		return fmt.Errorf("invalid key ID provided: %s", keyID)
	}

	// Find the key's GUN by ID, in case it is a non-root key
	var keyGUN string
	for _, store := range ks {
		for keypath := range store.ListKeys() {
			if filepath.Base(keypath) == keyID {
				keyGUN = filepath.Dir(keypath)
			}
		}
	}
	cs := cryptoservice.NewCryptoService(keyGUN, ks...)
	privKey, role, err := cs.GetPrivateKey(keyID)
	if err != nil {
		return fmt.Errorf("could not retrieve local key for key ID provided: %s", keyID)
	}

	// Must use a different passphrase retriever to avoid caching the
	// unlocking passphrase and reusing that.
	passChangeRetriever := k.getRetriever()
	keyStore, err := trustmanager.NewKeyFileStore(config.GetString("trust_dir"), passChangeRetriever)
	err = keyStore.AddKey(filepath.Join(keyGUN, keyID), role, privKey)
	if err != nil {
		return err
	}

	cmd.Println("")
	cmd.Printf("Successfully updated passphrase for key ID: %s", keyID)
	cmd.Println("")
	return nil
}
Пример #19
0
func setupServerHandler(metaStore storage.MetaStore) http.Handler {
	ctx := context.WithValue(context.Background(), "metaStore", metaStore)

	ctx = context.WithValue(ctx, "keyAlgorithm", data.ECDSAKey)

	// Eat the logs instead of spewing them out
	var b bytes.Buffer
	l := logrus.New()
	l.Out = &b
	ctx = ctxu.WithLogger(ctx, logrus.NewEntry(l))

	cryptoService := cryptoservice.NewCryptoService(trustmanager.NewKeyMemoryStore(passphrase.ConstantRetriever("pass")))
	return server.RootHandler(nil, ctx, cryptoService, nil, nil, nil)
}
Пример #20
0
// EmptyRepo creates an in memory crypto service
// and initializes a repo with no targets.  Delegations are only created
// if delegation roles are passed in.
func EmptyRepo(gun string, delegationRoles ...string) (*tuf.Repo, signed.CryptoService, error) {
	cs := cryptoservice.NewCryptoService(
		gun, trustmanager.NewKeyMemoryStore(passphrase.ConstantRetriever("")))
	r := tuf.NewRepo(cs)

	baseRoles := map[string]data.BaseRole{}
	for _, role := range data.BaseRoles {
		key, err := createKey(cs, gun, role)
		if err != nil {
			return nil, nil, err
		}
		baseRoles[role] = data.NewBaseRole(
			role,
			1,
			key,
		)
	}

	r.InitRoot(
		baseRoles[data.CanonicalRootRole],
		baseRoles[data.CanonicalTimestampRole],
		baseRoles[data.CanonicalSnapshotRole],
		baseRoles[data.CanonicalTargetsRole],
		false,
	)
	r.InitTargets(data.CanonicalTargetsRole)
	r.InitSnapshot()
	r.InitTimestamp()

	// sort the delegation roles so that we make sure to create the parents
	// first
	sort.Strings(delegationRoles)
	for _, delgName := range delegationRoles {
		// create a delegations key and a delegation in the tuf repo
		delgKey, err := createKey(cs, gun, delgName)
		if err != nil {
			return nil, nil, err
		}
		role, err := data.NewRole(delgName, 1, []string{}, []string{""})
		if err != nil {
			return nil, nil, err
		}
		if err := r.UpdateDelegations(role, []data.PublicKey{delgKey}); err != nil {
			return nil, nil, err
		}
	}

	return r, cs, nil
}
Пример #21
0
// keysExport exports a key by ID to a PEM file
func (k *keyCommander) keysExport(cmd *cobra.Command, args []string) error {
	if len(args) < 2 {
		cmd.Usage()
		return fmt.Errorf("Must specify key ID and output filename for export")
	}

	keyID := args[0]
	exportFilename := args[1]

	if len(keyID) != notary.Sha256HexSize {
		return fmt.Errorf("Please specify a valid key ID")
	}

	config, err := k.configGetter()
	if err != nil {
		return err
	}
	ks, err := k.getKeyStores(config, true, false)
	if err != nil {
		return err
	}

	cs := cryptoservice.NewCryptoService(ks...)
	keyInfo, err := cs.GetKeyInfo(keyID)
	if err != nil {
		return fmt.Errorf("Could not retrieve info for key %s", keyID)
	}

	exportFile, err := os.Create(exportFilename)
	if err != nil {
		return fmt.Errorf("Error creating output file: %v", err)
	}
	if k.keysExportChangePassphrase {
		// Must use a different passphrase retriever to avoid caching the
		// unlocking passphrase and reusing that.
		exportRetriever := k.getRetriever()
		err = cs.ExportKeyReencrypt(exportFile, keyID, exportRetriever)
	} else {
		err = cs.ExportKey(exportFile, keyID, keyInfo.Role)
	}
	exportFile.Close()
	if err != nil {
		os.Remove(exportFilename)
		return fmt.Errorf("Error exporting %s key: %v", keyInfo.Role, err)
	}
	return nil
}
Пример #22
0
// makes a testing notary-server
func setupServer() *httptest.Server {
	// Set up server
	ctx := context.WithValue(
		context.Background(), "metaStore", storage.NewMemStorage())

	ctx = context.WithValue(ctx, "keyAlgorithm", data.ECDSAKey)

	// Eat the logs instead of spewing them out
	var b bytes.Buffer
	l := logrus.New()
	l.Out = &b
	ctx = ctxu.WithLogger(ctx, logrus.NewEntry(l))

	cryptoService := cryptoservice.NewCryptoService(
		"", trustmanager.NewKeyMemoryStore(retriever))
	return httptest.NewServer(server.RootHandler(nil, ctx, cryptoService))
}
Пример #23
0
func TestKeyInfoHandlerReturns404WithNonexistentKey(t *testing.T) {
	// We associate both key types with this signing service to bypass the
	// ID -> keyType logic in the tests
	keyStore := trustmanager.NewKeyMemoryStore(passphraseRetriever)
	cryptoService := cryptoservice.NewCryptoService("", keyStore)
	setup(signer.CryptoServiceIndex{data.ED25519Key: cryptoService, data.RSAKey: cryptoService, data.ECDSAKey: cryptoService})

	fakeID := "c62e6d68851cef1f7e55a9d56e3b0c05f3359f16838cad43600f0554e7d3b54d"
	keyInfoURL := fmt.Sprintf("%s/%s", keyInfoBaseURL, fakeID)

	request, err := http.NewRequest("GET", keyInfoURL, nil)
	assert.Nil(t, err)

	res, err := http.DefaultClient.Do(request)
	assert.Nil(t, err)

	assert.Equal(t, 404, res.StatusCode)
}
Пример #24
0
func (k *keyCommander) keysGenerateRootKey(cmd *cobra.Command, args []string) error {
	// We require one or no arguments (since we have a default value), but if the
	// user passes in more than one argument, we error out.
	if len(args) > 1 {
		cmd.Usage()
		return fmt.Errorf(
			"Please provide only one Algorithm as an argument to generate (rsa, ecdsa)")
	}

	// If no param is given to generate, generates an ecdsa key by default
	algorithm := data.ECDSAKey

	// If we were provided an argument lets attempt to use it as an algorithm
	if len(args) > 0 {
		algorithm = args[0]
	}

	allowedCiphers := map[string]bool{
		data.ECDSAKey: true,
		data.RSAKey:   true,
	}

	if !allowedCiphers[strings.ToLower(algorithm)] {
		return fmt.Errorf("Algorithm not allowed, possible values are: RSA, ECDSA")
	}

	config, err := k.configGetter()
	if err != nil {
		return err
	}
	ks, err := k.getKeyStores(config, true, true)
	if err != nil {
		return err
	}
	cs := cryptoservice.NewCryptoService(ks...)

	pubKey, err := cs.Create(data.CanonicalRootRole, "", algorithm)
	if err != nil {
		return fmt.Errorf("Failed to create a new root key: %v", err)
	}

	cmd.Printf("Generated new %s root key with keyID: %s\n", algorithm, pubKey.ID())
	return nil
}
Пример #25
0
// repositoryFromKeystores is a helper function for NewNotaryRepository that
// takes some basic NotaryRepository parameters as well as keystores (in order
// of usage preference), and returns a NotaryRepository.
func repositoryFromKeystores(baseDir, gun, baseURL string, rt http.RoundTripper, cache store.MetadataStore,
	keyStores []trustmanager.KeyStore, trustPin trustpinning.TrustPinConfig) (*NotaryRepository, error) {

	cryptoService := cryptoservice.NewCryptoService(keyStores...)

	nRepo := &NotaryRepository{
		gun:           gun,
		baseDir:       baseDir,
		baseURL:       baseURL,
		tufRepoPath:   filepath.Join(baseDir, tufDir, filepath.FromSlash(gun)),
		CryptoService: cryptoService,
		roundTrip:     rt,
		trustPinning:  trustPin,
	}

	nRepo.cache = cache

	return nRepo, nil
}
Пример #26
0
// SignMetadataWithInvalidKey signs the metadata with the wrong key
func (m *MetadataSwizzler) SignMetadataWithInvalidKey(role string) error {
	signedThing, err := signedFromStore(m.MetadataCache, role)
	if err != nil {
		return err
	}

	// create an invalid key, but not in the existing CryptoService
	cs := cryptoservice.NewCryptoService(trustmanager.NewKeyMemoryStore(passphrase.ConstantRetriever("")))
	key, err := CreateKey(cs, m.Gun, role, data.ECDSAKey)
	if err != nil {
		return err
	}

	metaBytes, err := serializeMetadata(cs, signedThing, "root", key)
	if err != nil {
		return err
	}
	return m.MetadataCache.Set(role, metaBytes)
}
Пример #27
0
func TestDeleteKeyHandler(t *testing.T) {
	keyStore := trustmanager.NewKeyMemoryStore(passphraseRetriever)
	cryptoService := cryptoservice.NewCryptoService("", keyStore)
	setup(signer.CryptoServiceIndex{data.ED25519Key: cryptoService, data.RSAKey: cryptoService, data.ECDSAKey: cryptoService})

	tufKey, _ := cryptoService.Create("", data.ED25519Key)
	assert.NotNil(t, tufKey)

	requestJson, _ := json.Marshal(&pb.KeyID{ID: tufKey.ID()})
	reader = strings.NewReader(string(requestJson))

	request, err := http.NewRequest("POST", deleteKeyBaseURL, reader)
	assert.Nil(t, err)

	res, err := http.DefaultClient.Do(request)
	assert.Nil(t, err)

	assert.Equal(t, 200, res.StatusCode)
}
Пример #28
0
func TestDeleteKeyHandlerReturns404WithNonexistentKey(t *testing.T) {
	keyStore := trustmanager.NewKeyMemoryStore(passphraseRetriever)
	cryptoService := cryptoservice.NewCryptoService("", keyStore)
	setup(signer.CryptoServiceIndex{data.ED25519Key: cryptoService, data.RSAKey: cryptoService, data.ECDSAKey: cryptoService})

	fakeID := "c62e6d68851cef1f7e55a9d56e3b0c05f3359f16838cad43600f0554e7d3b54d"

	keyID := &pb.KeyID{ID: fakeID}
	requestJson, _ := json.Marshal(keyID)
	reader = strings.NewReader(string(requestJson))

	request, err := http.NewRequest("POST", deleteKeyBaseURL, reader)
	assert.Nil(t, err)

	res, err := http.DefaultClient.Do(request)
	assert.Nil(t, err)

	assert.Equal(t, 404, res.StatusCode)
}
Пример #29
0
func setUpSignerServer(t *testing.T, store trustmanager.KeyStore) *grpc.Server {
	cryptoService := cryptoservice.NewCryptoService(store)
	cryptoServices := signer.CryptoServiceIndex{
		data.ED25519Key: cryptoService,
		data.RSAKey:     cryptoService,
		data.ECDSAKey:   cryptoService,
	}

	//server setup
	grpcServer := grpc.NewServer()
	pb.RegisterKeyManagementServer(grpcServer, &api.KeyManagementServer{
		CryptoServices: cryptoServices,
	})
	pb.RegisterSignerServer(grpcServer, &api.SignerServer{
		CryptoServices: cryptoServices,
	})

	return grpcServer
}
Пример #30
0
func setUpSigner(t *testing.T, store trustmanager.KeyStore) NotarySigner {
	cryptoService := cryptoservice.NewCryptoService("", store)
	cryptoServices := signer.CryptoServiceIndex{
		data.ED25519Key: cryptoService,
		data.RSAKey:     cryptoService,
		data.ECDSAKey:   cryptoService,
	}

	fakeHealth := func() map[string]string { return map[string]string{} }

	client := StubClientFromServers{
		KeyManagementServer: api.KeyManagementServer{CryptoServices: cryptoServices,
			HealthChecker: fakeHealth},
		SignerServer: api.SignerServer{CryptoServices: cryptoServices,
			HealthChecker: fakeHealth},
	}

	return NotarySigner{kmClient: &client, sClient: &client}
}