// Import a key file from pybitmessage or bmagent. func testImportKeyFile(t *testing.T, testID int, file string, addresses map[string]string) { // First load the test file. b, err := ioutil.ReadFile(file) if err != nil { t.Error(testID, err) return } // Create new key manager. seed := []byte(fmt.Sprintf("Another secure seed: %s", testID)) mgr, err := keymgr.New(seed) if err != nil { t.Error(testID, err) return } // Finally import the test file. keys := mgr.ImportKeys(b) if keys == nil { t.Error(testID, "could not read keys!") return } // Test that the expected values are there. for addr, name := range addresses { if n, ok := keys[addr]; !ok { if n != name { t.Error(testID, " for address ", addr, " found name ", n, " but expected ", name) } } else { t.Error(testID, " could not find key ", addr) } } }
// createDatabases prompts the user for information needed to generate a new // key file and data store and generates them accordingly. The new databases // will reside at the provided path. func createDatabases(cfg *Config) error { var keyfilePass, storePass []byte var err error var prompt string // Create default mailboxes and associated data. var username string if cfg.Username != "" { username = cfg.Username } else { // Prompt user for username. prompt = "\nEnter your username" username, err = promptUsername(prompt) if err != nil { return err } cfg.Username = username } // Ascertain the address generation seed. var seed []byte if cfg.Seed != "" { seed, err = hex.DecodeString(cfg.Seed) } else { seed, err = promptConsoleSeed() } if err != nil { return err } if cfg.NoPass { storePass = []byte{} } else { // Prompt for the private passphrase for the data store. prompt = "\nEnter passphrase for the data store" for { storePass, err = promptConsolePass(prompt, true) if err != nil { return err } if storePass != nil { break } } } // Intialize key manager with seed. kmgr, err := keymgr.New(seed) if err != nil { return err } // Create the data store. fmt.Println("Creating the data store...") load, err := store.Open(cfg.storePath) if err != nil { return fmt.Errorf("Failed to create data store: %v", err) } s, _, err := load.Construct(storePass) if err != nil { return fmt.Errorf("Failed to create data store: %v", err) } user, err := s.NewUser(username) if err != nil { return err } err = email.InitializeUser(user, kmgr, cfg.GenKeys) if err != nil { return err } fmt.Println("The data store has successfully been created with default mailboxes.") err = load.Close() if err != nil { return err } if cfg.NoPass { keyfilePass = []byte{} } else { // Prompt for the private passphrase for the key file. prompt = "Enter passphrase for the key file" for { keyfilePass, err = promptConsolePass(prompt, true) if err != nil { return err } if keyfilePass != nil { break } } } // Create the key file. fmt.Println("\nCreating the key file...") // Save key file to disk with the specified passphrase, if one was given. saveKeyfile(kmgr, cfg.keyfilePath, keyfilePass) fmt.Println("Keyfile saved.") return nil }
func TestOperation(t *testing.T) { // Initialize a new key manager. seed := []byte("a secure psuedorandom seed (clearly not)") mgr, err := keymgr.New(seed) if err != nil { t.Fatal(err) } // Check that everything is correctly zeroed. if n := mgr.NumDeterministic(); n != 0 { t.Errorf("invalid latestIDIndex for no identity, expected %d got %d", 0, n) } if n := mgr.NumImported(); n != 0 { t.Errorf("invalid numImported for no identity, expected %d got %d", 0, n) } // Generate first identity and check if everything works as expected. gen1 := mgr.NewHDIdentity(1, "Seven Anvil") if gen1.IsChan != false { t.Error("generated identity not a channel") } if n := mgr.NumDeterministic(); n != 1 { t.Errorf("invalid latestIDIndex for no identity, expected %d got %d", 1, n) } if n := mgr.NumImported(); n != 0 { t.Errorf("invalid numImported for no identity, expected %d got %d", 0, n) } // Generate second identity and check if everything works as expected. gen2 := mgr.NewHDIdentity(1, "Intelligent Glue") if gen2.IsChan != false { t.Error("generated identity not a channel") } if n := mgr.NumDeterministic(); n != 2 { t.Errorf("invalid latestIDIndex for no identity, expected %d got %d", 1, n) } if n := mgr.NumImported(); n != 0 { t.Errorf("invalid numImported for no identity, expected %d got %d", 0, n) } // Import a channel and check if it's imported as expected. ids, _ := identity.NewDeterministic("privacy", 1, 1) privacyChan := &keymgr.PrivateID{ Private: *ids[0], IsChan: true, Name: "Hyperluminous", } // Create an address (export fails without this). privacyChan.CreateAddress(4, 1) mgr.ImportIdentity(*privacyChan) if n := mgr.NumDeterministic(); n != 2 { t.Errorf("invalid latestIDIndex for no identity, expected %d got %d", 1, n) } if n := mgr.NumImported(); n != 1 { t.Errorf("invalid numImported for no identity, expected %d got %d", 1, n) } // Try to retrieve private identity from address. privacyAddr := privacyChan.Address() privacyRetrieved := mgr.LookupByAddress(privacyAddr) if privacyRetrieved == nil { t.Errorf("LookupByAddress returned nil address") } if !bytes.Equal(privacyRetrieved.Private.Address.Ripe[:], privacyChan.Private.Address.Ripe[:]) { t.Errorf("got different ripe, expected %v got %v", privacyChan.Private.Address.Ripe, privacyRetrieved.Private.Address.Ripe) } // Save and encrypt the private keys held by the key manager. pass := []byte("a very nice and secure password for my keyfile") encData, err := mgr.ExportEncrypted(pass) if err != nil { t.Fatal(err) } // Create a new key manager from the encrypted data and check if it's like // the original. mgr1, err := keymgr.FromEncrypted(encData, pass) if err != nil { t.Fatal(err) } if mgr.NumImported() != mgr1.NumImported() { t.Errorf("invalid number of imported keys, expected %d got %d", mgr.NumImported(), mgr1.NumImported()) } if mgr.NumDeterministic() != mgr1.NumDeterministic() { t.Errorf("invalid number of deterministic keys, expected %d got %d", mgr.NumDeterministic(), mgr1.NumDeterministic()) } // Remove an imported key and check if the operation is successful. /*mgr1.RemoveImported(privacyChan.Address()) if n := mgr1.NumImported(); n != 0 { t.Errorf("invalid numImported for no identity, expected %d got %d", 0, n) } err = mgr1.ForEach(func(id keymgr.PrivateID) error { if bytes.Equal(id.Tag(), privacyChan.Tag()) { return errors.New("should not happen") } return nil }) if err != nil { t.Error("imported key not removed from database") }*/ // Try to remove a key that doesn't exist in the database. // Should not crash the program. (function removed) //mgr1.RemoveImported(privacyChan.Address()) // Try to retrieve non-existant private identity from address. privacyRetrieved = mgr1.LookupByAddress("BM-2cUfDTJXLeMxAVe7pWXBEneBjDuQ783VSq") if privacyRetrieved != nil { t.Errorf("expected nil id") } }