2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-28 15:56:37 +00:00

Reduce code duplication in key handling

This commit is contained in:
Alexander Neumann 2014-12-21 18:16:22 +01:00
parent ef41a77aff
commit 5431b025a3
2 changed files with 15 additions and 70 deletions

View File

@ -62,7 +62,7 @@ func add_key(s restic.Server) error {
return errors.New("passwords do not match") return errors.New("passwords do not match")
} }
id, err := s.Key().AddKey(s, pw) id, err := restic.AddKey(s, pw, s.Key())
if err != nil { if err != nil {
return fmt.Errorf("creating new key failed: %v\n", err) return fmt.Errorf("creating new key failed: %v\n", err)
} }
@ -95,7 +95,7 @@ func change_password(s restic.Server) error {
} }
// add new key // add new key
id, err := s.Key().AddKey(s, pw) id, err := restic.AddKey(s, pw, s.Key())
if err != nil { if err != nil {
return fmt.Errorf("creating new key failed: %v\n", err) return fmt.Errorf("creating new key failed: %v\n", err)
} }

81
key.go
View File

@ -76,70 +76,7 @@ type keys struct {
// CreateKey initializes a master key in the given backend and encrypts it with // CreateKey initializes a master key in the given backend and encrypts it with
// the password. // the password.
func CreateKey(s Server, password string) (*Key, error) { func CreateKey(s Server, password string) (*Key, error) {
// fill meta data about key return AddKey(s, password, nil)
k := &Key{
Created: time.Now(),
KDF: "scrypt",
N: scryptN,
R: scryptR,
P: scryptP,
}
hn, err := os.Hostname()
if err == nil {
k.Hostname = hn
}
usr, err := user.Current()
if err == nil {
k.Username = usr.Username
}
// generate random salt
k.Salt = make([]byte, scryptSaltsize)
n, err := rand.Read(k.Salt)
if n != scryptSaltsize || err != nil {
panic("unable to read enough random bytes for salt")
}
// call scrypt() to derive user key
k.user, err = k.scrypt(password)
if err != nil {
return nil, err
}
// generate new random master keys
k.master, err = k.newKeys()
if err != nil {
return nil, err
}
// encrypt master keys (as json) with user key
buf, err := json.Marshal(k.master)
if err != nil {
return nil, err
}
k.Data = GetChunkBuf("key")
n, err = k.EncryptUser(k.Data, buf)
k.Data = k.Data[:n]
// dump as json
buf, err = json.Marshal(k)
if err != nil {
return nil, err
}
// store in repository and return
id, err := s.Create(backend.Key, buf)
if err != nil {
return nil, err
}
k.id = id
FreeChunkBuf("key", k.Data)
return k, nil
} }
// OpenKey tries do decrypt the key specified by id with the given password. // OpenKey tries do decrypt the key specified by id with the given password.
@ -209,7 +146,7 @@ func SearchKey(s Server, password string) (*Key, error) {
} }
// AddKey adds a new key to an already existing repository. // AddKey adds a new key to an already existing repository.
func (oldkey *Key) AddKey(s Server, password string) (backend.ID, error) { func AddKey(s Server, password string, template *Key) (*Key, error) {
// fill meta data about key // fill meta data about key
newkey := &Key{ newkey := &Key{
Created: time.Now(), Created: time.Now(),
@ -242,8 +179,16 @@ func (oldkey *Key) AddKey(s Server, password string) (backend.ID, error) {
return nil, err return nil, err
} }
// copy master keys from oldkey if template == nil {
newkey.master = oldkey.master // generate new random master keys
newkey.master, err = newkey.newKeys()
if err != nil {
return nil, err
}
} else {
// copy master keys from old key
newkey.master = template.master
}
// encrypt master keys (as json) with user key // encrypt master keys (as json) with user key
buf, err := json.Marshal(newkey.master) buf, err := json.Marshal(newkey.master)
@ -270,7 +215,7 @@ func (oldkey *Key) AddKey(s Server, password string) (backend.ID, error) {
FreeChunkBuf("key", newkey.Data) FreeChunkBuf("key", newkey.Data)
return id, nil return newkey, nil
} }
func (k *Key) scrypt(password string) (*keys, error) { func (k *Key) scrypt(password string) (*keys, error) {