// uploadSecrets encrypts and uploads the secrets to acd for safe keeping. func (a *acdb) uploadSecrets() error { a.Log(acd.DebugTrace, "[TRC] uploadSecrets") fmt.Printf("Cloud Drive does not have a copy of the secrets. Please enter " + "the password to encrypt the secrets. Loss of this password is " + "unrecoverable!\n") p, err := shared.PromptPassword(true) if err != nil { return err } defer func() { goutil.Zero(p) }() blob, err := a.keys.Encrypt(p, 32768, 16, 2) if err != nil { return err } asset, err := a.c.UploadJSON(a.metadataID, secretsName, blob) if err != nil { if e, ok := acd.IsCombinedError(err); ok { if e.StatusCode != http.StatusConflict { return fmt.Errorf("secrets appeared unexpectedly") } } } a.Log(acd.DebugTrace, "[TRC] uploadSecrets object: %v", asset.ID) return nil }
func (a *acdb) downloadSecrets() error { a.Log(acd.DebugTrace, "[TRC] downloadSecrets") asset, err := a.c.GetMetadataFS(metadataName + "/" + secretsName) if err != nil { if err == acd.ErrNotFound { return a.uploadSecrets() } return fmt.Errorf("remote object not found") } a.Log(acd.DebugTrace, "[TRC] found asset: %v -> %v\n", asset.ID, asset.Name) blob, err := a.c.DownloadJSON(asset.ID) if err != nil { return err } var p []byte defer func() { goutil.Zero(p) }() for { p, err = shared.ReadPassword() if err == nil { break } if !os.IsNotExist(err) { return err } fmt.Printf("There is no local password file. Please enter " + "password to verify the integrity of the remote " + "secrets.\n") p, err = shared.PromptPassword(false) if err != nil { return err } err = a.verifySecrets(p, blob) if err != nil { fmt.Printf("invalid password: %v\n", err) continue } return shared.WritePassword(p) } return a.verifySecrets(p, blob) }