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 }
// 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 }
// 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 }
// 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 }
func writeConfig(config *clientConfig) { _ = jsonutil.WriteFile(configPath, config) }