123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- package fs
- import (
- "notabug.org/apiote/next-eeze/crypto"
- "notabug.org/apiote/next-eeze/password"
- "io/ioutil"
- "log"
- "os"
- "os/user"
- "path/filepath"
- "git.sr.ht/~sircmpwn/go-bare"
- )
- type EncryptedContent struct {
- Salt []byte
- CipherText []byte
- }
- type Credentials struct {
- Server string
- Username string
- Password string
- }
- type FidoCredential struct {
- Cdh []byte
- Salt []byte
- CredID []byte
- }
- func getDataLocation() string {
- usr, _ := user.Current()
- dir := usr.HomeDir
- path := filepath.Join(dir, "/.local/share/next-eeze/")
- return path
- }
- // todo memguard passwords, masterPassword
- func SaveBare(passwords []password.BarePassword, masterPassword string) error {
- salt := crypto.MakeSalt()
- // todo memguard
- key := crypto.DeriveKey(masterPassword, salt)
- result, err := os.Create(getDataLocation() + "/passwords.bare")
- if err != nil {
- log.Fatal("Error creating passwords file. ", err)
- return err
- }
- defer result.Close()
- // todo memguard
- bytes, err := bare.Marshal(&passwords)
- if err != nil {
- log.Fatal("Error marshalling passwords. ", err)
- return err
- }
- cipherText, err := crypto.Encrypt(bytes, key)
- if err != nil {
- log.Fatal("Error encrypting credentials. ", err)
- return err
- }
- enc := EncryptedContent{
- Salt: salt,
- CipherText: cipherText,
- }
- bytes, err = bare.Marshal(&enc)
- if err != nil {
- log.Fatal("Error marshalling encrypted credentials. ", err)
- return err
- }
- _, err = result.Write(bytes)
- if err != nil {
- log.Fatal("Error writing to file. ", err)
- return err
- }
- _, err = result.Write(bytes)
- if err != nil {
- log.Fatal("Error writing to file. ", err)
- return err
- }
- return nil
- }
- // todo memguard passwords, masterPassword
- func Save(passwords []password.NextPassword, masterPassword string) error {
- // todo memguard
- barePasswords := []password.BarePassword{}
- // todo memguard
- for _, p := range passwords {
- barePasswords = append(barePasswords, p.ToBarePassword())
- }
- err := SaveBare(barePasswords, masterPassword)
- return err
- }
- // todo memguard masterPassword
- func Read(masterPassword string) ([]password.BarePassword, error) {
- // todo memguard
- passwords := []password.BarePassword{}
- f, err := os.Open(getDataLocation() + "/passwords.bare")
- if err != nil {
- log.Fatal("Error opening. ", err)
- return passwords, err
- }
- defer f.Close()
- r := bare.NewReader(f)
- salt, err := r.ReadData()
- if err != nil {
- log.Fatal("Error reading salt. ", err)
- return passwords, err
- }
- cipher, err := r.ReadData()
- if err != nil {
- log.Fatal("Error reading cipher. ", err)
- return passwords, err
- }
- // todo memguard
- key := crypto.DeriveKey(masterPassword, salt)
- // todo memguard
- plaintext, err := crypto.Decrypt(cipher, key)
- if err != nil {
- log.Fatal("Error decrypting passwords. ", err)
- return passwords, err
- }
- err = bare.Unmarshal(plaintext, &passwords)
- if err != nil {
- log.Fatal("Error unmarshalling. ", err)
- return nil, err
- }
- return passwords, nil
- }
- // todo memguard credentials, masterPassword
- func SaveCredentials(credentials Credentials, masterPassword string) error {
- salt := crypto.MakeSalt()
- // todo memguard
- key := crypto.DeriveKey(masterPassword, salt)
- result, err := os.Create(getDataLocation() + "/credentials.bare")
- if err != nil {
- log.Fatal("Error creating credentials file. ", err)
- return err
- }
- defer result.Close()
- // todo memguard
- bytes, err := bare.Marshal(&credentials)
- if err != nil {
- log.Fatal("Error marshalling credentials. ", err)
- return err
- }
- cipherText, err := crypto.Encrypt(bytes, key)
- if err != nil {
- log.Fatal("Error encrypting credentials. ", err)
- return err
- }
- enc := EncryptedContent{
- Salt: salt,
- CipherText: cipherText,
- }
- bytes, err = bare.Marshal(&enc)
- if err != nil {
- log.Fatal("Error marshalling encrypted credentials. ", err)
- return err
- }
- _, err = result.Write(bytes)
- if err != nil {
- log.Fatal("Error writing to file. ", err)
- return err
- }
- return nil
- }
- // todo memguard masterPassword
- func ReadCredentials(masterPassword string) (Credentials, error) {
- enc := EncryptedContent{}
- // todo memguard
- credentials := Credentials{}
- content, err := ioutil.ReadFile(getDataLocation() + "/credentials.bare")
- if err != nil {
- log.Fatal("Error reading to file. ", err)
- return credentials, err
- }
- err = bare.Unmarshal(content, &enc)
- if err != nil {
- log.Fatal("Error unmarshalling encrypted. ", err)
- return credentials, err
- }
- // todo memguard
- key := crypto.DeriveKey(masterPassword, enc.Salt)
- // todo memguard
- plaintext, err := crypto.Decrypt(enc.CipherText, key)
- if err != nil {
- log.Fatal("Error decrypting credentials. ", err)
- return credentials, err
- }
- err = bare.Unmarshal(plaintext, &credentials)
- return credentials, nil
- }
- // todo memguards
- func SaveFidoCredential(c FidoCredential) error {
- bytes, err := bare.Marshal(&c)
- if err != nil {
- log.Fatal("Error creating credentials file. ", err)
- return err
- }
- result, err := os.Create(getDataLocation() + "/fido.bare")
- if err != nil {
- log.Fatal("Error creating credentials file. ", err)
- return err
- }
- defer result.Close()
- _, err = result.Write(bytes)
- if err != nil {
- log.Fatal("Error writing to file. ", err)
- return err
- }
- return nil
- }
- // todo memguards
- func ReadFidoCredential() (FidoCredential, error) {
- c := FidoCredential{}
- content, err := ioutil.ReadFile(getDataLocation() + "/fido.bare")
- if err != nil {
- log.Fatal("Error reading to file. ", err)
- return c, err
- }
- err = bare.Unmarshal(content, &c)
- if err != nil {
- log.Fatal("Error unmarshalling encrypted. ", err)
- return c, err
- }
- return c, nil
- }
- func RemoveFidoCredential() error {
- err := os.Remove(getDataLocation() + "/fido.bare")
- if err != nil && os.IsNotExist(err) {
- return nil
- } else {
- return err
- }
- }
- func IsFidoCredentialPresent() (bool, error) {
- _, err := os.Stat(getDataLocation() + "/fido.bare")
- if err != nil {
- if os.IsNotExist(err) {
- return false, nil
- } else {
- return false, err
- }
- }
- return true, nil
- }
|