Example #1
0
File: vault.go Project: gaku/1pass
func saveEncryptionKeys(dataDir string, keyList encryptionKeys) (err error) {
	err = jsonutil.WriteFile(dataDir+"/encryptionKeys.js", keyList)
	if err != nil {
		return
	}
	err = writePlistFile(dataDir+"/1password.keys", keyList)
	return
}
Example #2
0
File: vault.go Project: gaku/1pass
// Save item to the vault. The item's UpdatedAt
// timestamp is updated to the current time and
// CreatedAt is also set to the current time if
// it was not previously set.
func (item *Item) Save() error {
	if len(item.Encrypted) == 0 {
		return fmt.Errorf("Item content not set")
	}

	item.UpdatedAt = uint64(time.Now().Unix())
	if item.CreatedAt == 0 {
		item.CreatedAt = item.UpdatedAt
	}

	// save item to .1password file
	itemPath := item.Path()
	err := jsonutil.WriteFile(itemPath, item)
	if err != nil {
		return fmt.Errorf("Failed to save item %s: %v", item.Title, err)
	}

	// update contents.js entry
	contentsFilePath := item.vault.DataDir() + "/contents.js"
	var contentsEntries [][]interface{}
	err = jsonutil.ReadFile(contentsFilePath, &contentsEntries)
	if err != nil {
		return fmt.Errorf("Failed to read contents.js: %v", err)
	}
	foundExisting := false
	for i, entry := range contentsEntries {
		tmpItem := readContentsEntry(entry)
		if tmpItem.Uuid == item.Uuid {
			contentsEntries[i] = item.contentsEntry()
			foundExisting = true
			break
		}
	}
	if !foundExisting {
		contentsEntries = append(contentsEntries, item.contentsEntry())
	}
	err = jsonutil.WriteFile(contentsFilePath, contentsEntries)
	if err != nil {
		return fmt.Errorf("Failed to update contents.js: %v", err)
	}

	return nil
}
Example #3
0
File: vault.go Project: gaku/1pass
// Creates a new vault in 'vaultPath' and a random master key, encrypted
// with 'masterPwd'
//
// The returned vault is initially locked
func NewVault(vaultPath string, security VaultSecurity) (Vault, error) {
	if !strings.HasSuffix(vaultPath, ".agilekeychain") {
		return Vault{}, fmt.Errorf("vault folder name must end with .agilekeychain")
	}

	// number of iterations used by current version of 1Password
	// iOS app
	const defaultPbkdfIterations = 17094
	if security.Iterations == 0 {
		security.Iterations = defaultPbkdfIterations
	}

	_, err := os.Stat(vaultPath)
	if !os.IsNotExist(err) {
		return Vault{}, fmt.Errorf("Vault %s already exists", vaultPath)
	}

	dataDir := vaultDataDir(vaultPath)
	err = os.MkdirAll(dataDir, os.ModeDir|0755)
	if err != nil {
		return Vault{}, err
	}

	// create empty contents.js file
	err = jsonutil.WriteFile(dataDir+"/contents.js", []string{})
	if err != nil {
		return Vault{}, fmt.Errorf("Failed to create contents.js file")
	}

	// create encryptionKeys.js file
	randomKey := randomBytes(1024)
	salt := randomBytes(8)
	encryptedKey, validation, err := encryptKey([]byte(security.MasterPwd), randomKey, salt, security.Iterations)
	if err != nil {
		return Vault{}, fmt.Errorf("Failed to generate encryption key")
	}

	mainKey := encKeyEntry{
		Data:       []byte(fmt.Sprintf("Salted__%s%s", salt, encryptedKey)),
		Identifier: newItemId(),
		Iterations: security.Iterations,
		Level:      "SL5",
		Validation: validation,
	}

	keyList := encryptionKeys{
		List: []encKeyEntry{mainKey},
		SL5:  mainKey.Identifier,
	}
	err = saveEncryptionKeys(dataDir, keyList)
	return Vault{
		Path: vaultPath,
	}, nil
}
Example #4
0
File: vault.go Project: gaku/1pass
// Remove the item's data files from the vault
func (item *Item) removeDataFiles() error {
	itemDataFile := item.Path()

	// remove contents.js entry
	contentsFilePath := item.vault.DataDir() + "/contents.js"
	var contentsEntries [][]interface{}
	err := jsonutil.ReadFile(contentsFilePath, &contentsEntries)
	if err != nil {
		return fmt.Errorf("Failed to read contents.js: %v", err)
	}

	foundExisting := false
	newContentsEntries := [][]interface{}{}
	for _, entry := range contentsEntries {
		tmpItem := readContentsEntry(entry)
		if tmpItem.Uuid == item.Uuid {
			foundExisting = true
		} else {
			newContentsEntries = append(newContentsEntries, entry)
		}
	}
	if !foundExisting {
		return fmt.Errorf("Entry '%s' (ID: %s) not found", item.Title, item.Uuid)
	}

	err = jsonutil.WriteFile(contentsFilePath, newContentsEntries)
	if err != nil {
		return fmt.Errorf("Failed to update contents.js: %v", err)
	}

	// remove .1password data file
	err = os.Remove(itemDataFile)
	if err != nil {
		return fmt.Errorf("Failed to remove item data file: %s: %v", itemDataFile, err)
	}

	return nil
}
Example #5
0
File: client.go Project: gaku/1pass
func writeConfig(config *clientConfig) {
	_ = jsonutil.WriteFile(configPath, config)
}