Esempio n. 1
0
func TestLoad(t *testing.T) {
	backendConfig := backends.Config{
		Type: backends.ConfigTypeMock,
	}
	backendClient := backends.NewMockBackend()
	for i, cryptoConfig := range safeCryptoConfigs {
		cryptoClient, err := crypto.New(&cryptoConfig)
		if err != nil {
			t.Fatalf("#%d: failed to create crypto client: %s", i, err.Error())
		}
		conf := &config.Config{
			Encryption: cryptoConfig,
			Storage:    backendConfig,
		}
		for j, data := range safeData {
			backendClient.Data = []byte(data)
			s, err := safe.Load([]byte(password), backendClient, cryptoClient, conf)
			if err != nil {
				t.Fatalf("#%d.#%d: failed to load safe: %s", i, j, err.Error())
			}
			if _, err := s.Get("foo"); err != nil {
				t.Fatalf("#%d.#%d: failed to get 'foo' safe account: %s", i, j, err.Error())
			}
		}
	}
}
Esempio n. 2
0
func createTestSafe() (*Safe, error) {
	err := ioutil.WriteFile(testSafeName, []byte(testSafeContent), 0600)
	if err != nil {
		return nil, err
	}

	backendConfig := backends.Config{
		Type: backends.ConfigTypeFile,
		Settings: map[string]interface{}{
			"path": testSafeName,
		},
	}
	backendClient, err := backends.New(&backendConfig)
	if err != nil {
		return nil, err
	}

	cryptoConfig := crypto.Config{
		Type: crypto.ConfigTypeOpenPGP,
		OpenPGPSettings: &crypto.OpenPGPSettings{
			Cipher:   "aes128",
			S2KCount: 1024,
		},
	}

	cryptoClient, err := crypto.New(&cryptoConfig)
	if err != nil {
		return nil, err
	}

	config := &config.Config{
		Encryption: cryptoConfig,
		Storage:    backendConfig,
		Version:    "1.2.3 test",
	}

	return Load(
		testSafePassword,
		backendClient,
		cryptoClient,
		config,
	)
}
Esempio n. 3
0
File: load.go Progetto: bndw/pick
func Load(password []byte, backend backends.Client, encryptionClient crypto.Client, config *config.Config) (*Safe, error) {
	s := Safe{
		backend:  backend,
		crypto:   encryptionClient,
		password: password,
		Config:   config,
	}

	data, err := s.backend.Load()
	if err != nil {
		if _, ok := err.(*errors.SafeNotFound); ok {
			s.Accounts = make(map[string]Account)
			return &s, nil
		}
		return nil, err
	}

	safeDTO := safeDTO{}
	if err := json.Unmarshal(data, &safeDTO); err == nil {
		// Unmarshalling did succeed -> Safe uses new format
		// Do nothing
	} else {
		safeDTO.Ciphertext = data
		// If we don't have a config, use OpenPGP for backwards-compatibility
		defaultOpenPGPConfig := crypto.NewDefaultConfigWithType(crypto.ConfigTypeOpenPGP)
		safeDTO.Config = &defaultOpenPGPConfig
	}

	upgradeNeeded := false
	plaintext, err := s.crypto.Decrypt(safeDTO.Ciphertext, password)
	if err != nil {
		// Wasn't able to decrypt the safe with the default / user-provided config.
		// Now use config from the safe. If this doesn't work, then the password
		// is _definitely_ incorrect. If however decryption works now, we need
		// to upgrade the safe to use the default / user-provided config.
		userCrypto := s.crypto
		s.crypto, err = crypto.New(safeDTO.Config)
		if err != nil {
			return nil, err
		}
		plaintext, err = s.crypto.Decrypt(safeDTO.Ciphertext, password)
		if err != nil {
			return nil, err
		}
		// Safe upgrade is needed, restore default / user-provided config
		upgradeNeeded = true
		s.crypto = userCrypto
	}

	var tmp Safe

	if err := json.Unmarshal(plaintext, &tmp); err != nil {
		return nil, &errors.SafeCorrupt{}
	}

	s.Accounts = tmp.Accounts

	// We still need to compare the default / user-provided config with the safe config.
	// If they differ -> Upgrade safe
	// This check is required for the OpenPGP mode, as it gets its config from the ciphertext.
	if upgradeNeeded || !reflect.DeepEqual(*safeDTO.Config, s.Config.Encryption) {
		fmt.Println("Upgrading safe")
		if err := s.save(); err != nil {
			fmt.Println("Error", err.Error())
		}
	}

	return &s, err
}
Esempio n. 4
0
File: util.go Progetto: bndw/pick
func newCryptoClient() (crypto.Client, error) {
	return crypto.New(&config.Encryption)
}