// 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 }
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) }
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) }
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) }
// 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 }
// 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 }
// 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 }
// 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) } }
// 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() }
// 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) } }
// 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) } }
// 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 }
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) }
// 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 }
// 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) }
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) }
// 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 }
// 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 }
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) }
// 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 }
// 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 }
// 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)) }
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) }
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 }
// 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 }
// 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) }
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) }
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) }
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 }
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} }