mirror of https://github.com/restic/restic.git
Rework key.go, add Comments
This commit is contained in:
parent
543c2c724c
commit
6003430eb9
45
key.go
45
key.go
|
@ -20,21 +20,24 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrUnauthenticated = errors.New("Ciphertext verification failed")
|
// ErrUnauthenticated is returned when ciphertext verification has failed.
|
||||||
ErrNoKeyFound = errors.New("No key could be found")
|
ErrUnauthenticated = errors.New("ciphertext verification failed")
|
||||||
|
// ErrNoKeyFound is returned when no key for the repository could be decrypted.
|
||||||
|
ErrNoKeyFound = errors.New("no key could be found")
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: figure out scrypt values on the fly depending on the current
|
// TODO: figure out scrypt values on the fly depending on the current
|
||||||
// hardware.
|
// hardware.
|
||||||
const (
|
const (
|
||||||
scrypt_N = 65536
|
scryptN = 65536
|
||||||
scrypt_r = 8
|
scryptR = 8
|
||||||
scrypt_p = 1
|
scryptP = 1
|
||||||
scrypt_saltsize = 64
|
scryptSaltsize = 64
|
||||||
aesKeysize = 32 // for AES256
|
aesKeysize = 32 // for AES256
|
||||||
hmacKeysize = 32 // for HMAC with SHA256
|
hmacKeysize = 32 // for HMAC with SHA256
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Key represents an encrypted master key for a repository.
|
||||||
type Key struct {
|
type Key struct {
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
|
@ -52,19 +55,22 @@ type Key struct {
|
||||||
master *keys
|
master *keys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keys is a JSON structure that holds signing and encryption keys.
|
||||||
type keys struct {
|
type keys struct {
|
||||||
Sign []byte
|
Sign []byte
|
||||||
Encrypt []byte
|
Encrypt []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateKey initializes a master key in the given backend and encrypts it with
|
||||||
|
// the password.
|
||||||
func CreateKey(be backend.Server, password string) (*Key, error) {
|
func CreateKey(be backend.Server, password string) (*Key, error) {
|
||||||
// fill meta data about key
|
// fill meta data about key
|
||||||
k := &Key{
|
k := &Key{
|
||||||
Created: time.Now(),
|
Created: time.Now(),
|
||||||
KDF: "scrypt",
|
KDF: "scrypt",
|
||||||
N: scrypt_N,
|
N: scryptN,
|
||||||
R: scrypt_r,
|
R: scryptR,
|
||||||
P: scrypt_p,
|
P: scryptP,
|
||||||
}
|
}
|
||||||
|
|
||||||
hn, err := os.Hostname()
|
hn, err := os.Hostname()
|
||||||
|
@ -78,9 +84,9 @@ func CreateKey(be backend.Server, password string) (*Key, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate random salt
|
// generate random salt
|
||||||
k.Salt = make([]byte, scrypt_saltsize)
|
k.Salt = make([]byte, scryptSaltsize)
|
||||||
n, err := rand.Read(k.Salt)
|
n, err := rand.Read(k.Salt)
|
||||||
if n != scrypt_saltsize || err != nil {
|
if n != scryptSaltsize || err != nil {
|
||||||
panic("unable to read enough random bytes for salt")
|
panic("unable to read enough random bytes for salt")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +125,7 @@ func CreateKey(be backend.Server, password string) (*Key, error) {
|
||||||
return k, nil
|
return k, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OpenKey tries do decrypt the key specified by id with the given password.
|
||||||
func OpenKey(be backend.Server, id backend.ID, password string) (*Key, error) {
|
func OpenKey(be backend.Server, id backend.ID, password string) (*Key, error) {
|
||||||
// extract data from repo
|
// extract data from repo
|
||||||
data, err := be.Get(backend.Key, id)
|
data, err := be.Get(backend.Key, id)
|
||||||
|
@ -160,6 +167,8 @@ func OpenKey(be backend.Server, id backend.ID, password string) (*Key, error) {
|
||||||
return k, nil
|
return k, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SearchKey tries to decrypt all keys in the backend with the given password.
|
||||||
|
// If none could be found, ErrNoKeyFound is returned.
|
||||||
func SearchKey(be backend.Server, password string) (*Key, error) {
|
func SearchKey(be backend.Server, password string) (*Key, error) {
|
||||||
// list all keys
|
// list all keys
|
||||||
ids, err := be.List(backend.Key)
|
ids, err := be.List(backend.Key)
|
||||||
|
@ -187,18 +196,18 @@ func (k *Key) scrypt(password string) (*keys, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
keybytes := hmacKeysize + aesKeysize
|
keybytes := hmacKeysize + aesKeysize
|
||||||
scrypt_keys, err := scrypt.Key([]byte(password), k.Salt, k.N, k.R, k.P, keybytes)
|
scryptKeys, err := scrypt.Key([]byte(password), k.Salt, k.N, k.R, k.P, keybytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error deriving keys from password: %v", err)
|
return nil, fmt.Errorf("error deriving keys from password: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(scrypt_keys) != keybytes {
|
if len(scryptKeys) != keybytes {
|
||||||
return nil, fmt.Errorf("invalid numbers of bytes expanded from scrypt(): %d", len(scrypt_keys))
|
return nil, fmt.Errorf("invalid numbers of bytes expanded from scrypt(): %d", len(scryptKeys))
|
||||||
}
|
}
|
||||||
|
|
||||||
ks := &keys{
|
ks := &keys{
|
||||||
Encrypt: scrypt_keys[:aesKeysize],
|
Encrypt: scryptKeys[:aesKeysize],
|
||||||
Sign: scrypt_keys[aesKeysize:],
|
Sign: scryptKeys[aesKeysize:],
|
||||||
}
|
}
|
||||||
return ks, nil
|
return ks, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue