2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-16 10:05:25 +00:00
restic/server/key.go

287 lines
6.7 KiB
Go
Raw Normal View History

2015-04-26 12:46:15 +00:00
package server
2014-09-23 20:39:12 +00:00
import (
"crypto/rand"
2015-03-28 10:50:23 +00:00
"crypto/sha256"
2014-09-23 20:39:12 +00:00
"encoding/json"
"errors"
"fmt"
"io"
"os"
"os/user"
"time"
2014-12-05 20:45:49 +00:00
"github.com/restic/restic/backend"
"github.com/restic/restic/chunker"
"github.com/restic/restic/crypto"
"github.com/restic/restic/debug"
2014-09-23 20:39:12 +00:00
)
var (
2014-11-15 16:17:24 +00:00
// ErrNoKeyFound is returned when no key for the repository could be decrypted.
ErrNoKeyFound = errors.New("no key could be found")
2014-09-23 20:39:12 +00:00
)
// TODO: figure out scrypt values on the fly depending on the current
// hardware.
const (
2014-11-15 16:17:24 +00:00
scryptN = 65536
scryptR = 8
scryptP = 1
scryptSaltsize = 64
2014-09-23 20:39:12 +00:00
)
2014-11-15 16:17:24 +00:00
// Key represents an encrypted master key for a repository.
2014-09-23 20:39:12 +00:00
type Key struct {
Created time.Time `json:"created"`
Username string `json:"username"`
Hostname string `json:"hostname"`
KDF string `json:"kdf"`
N int `json:"N"`
R int `json:"r"`
P int `json:"p"`
Salt []byte `json:"salt"`
Data []byte `json:"data"`
2015-04-12 07:41:47 +00:00
user *crypto.Key
master *crypto.Key
2014-11-25 22:18:02 +00:00
2015-03-28 10:50:23 +00:00
name string
2014-09-23 20:39:12 +00:00
}
2014-11-15 16:17:24 +00:00
// CreateKey initializes a master key in the given backend and encrypts it with
// the password.
2015-04-26 12:46:15 +00:00
func CreateKey(s *Server, password string) (*Key, error) {
return AddKey(s, password, nil)
2014-09-23 20:39:12 +00:00
}
2015-03-28 10:50:23 +00:00
// OpenKey tries do decrypt the key specified by name with the given password.
2015-04-26 12:46:15 +00:00
func OpenKey(s *Server, name string, password string) (*Key, error) {
2015-03-28 10:50:23 +00:00
k, err := LoadKey(s, name)
2014-09-23 20:39:12 +00:00
if err != nil {
return nil, err
}
// check KDF
if k.KDF != "scrypt" {
return nil, errors.New("only supported KDF is scrypt()")
}
// derive user key
k.user, err = crypto.KDF(k.N, k.R, k.P, k.Salt, password)
2014-09-23 20:39:12 +00:00
if err != nil {
return nil, err
}
// decrypt master keys
buf, err := crypto.Decrypt(k.user, []byte{}, k.Data)
2014-09-23 20:39:12 +00:00
if err != nil {
return nil, err
}
// restore json
2015-04-12 07:41:47 +00:00
k.master = &crypto.Key{}
2014-09-23 20:39:12 +00:00
err = json.Unmarshal(buf, k.master)
if err != nil {
return nil, err
}
2015-03-28 10:50:23 +00:00
k.name = name
2014-09-23 20:39:12 +00:00
if !k.Valid() {
return nil, errors.New("Invalid key for repository")
}
// test if the chunker polynomial is present in the master key
if k.master.ChunkerPolynomial == 0 {
return nil, errors.New("Polynomial for content defined chunking is zero")
}
debug.Log("OpenKey", "Master keys loaded, polynomial %v", k.master.ChunkerPolynomial)
2014-09-23 20:39:12 +00:00
return k, nil
}
2014-11-15 16:17:24 +00:00
// SearchKey tries to decrypt all keys in the backend with the given password.
// If none could be found, ErrNoKeyFound is returned.
2015-04-26 12:46:15 +00:00
func SearchKey(s *Server, password string) (*Key, error) {
2014-09-23 20:39:12 +00:00
// try all keys in repo
2015-03-28 10:50:23 +00:00
done := make(chan struct{})
defer close(done)
for name := range s.List(backend.Key, done) {
key, err := OpenKey(s, name, password)
2014-09-23 20:39:12 +00:00
if err != nil {
continue
}
return key, nil
}
return nil, ErrNoKeyFound
}
2015-02-17 22:05:23 +00:00
// LoadKey loads a key from the backend.
2015-04-26 12:46:15 +00:00
func LoadKey(s *Server, name string) (*Key, error) {
2015-02-17 22:05:23 +00:00
// extract data from repo
rd, err := s.be.Get(backend.Key, name)
2015-02-17 22:05:23 +00:00
if err != nil {
return nil, err
}
2015-03-28 10:50:23 +00:00
defer rd.Close()
2015-02-17 22:05:23 +00:00
// restore json
2015-03-28 10:50:23 +00:00
dec := json.NewDecoder(rd)
k := Key{}
err = dec.Decode(&k)
2015-02-17 22:05:23 +00:00
if err != nil {
return nil, err
}
2015-03-28 10:50:23 +00:00
return &k, nil
2015-02-17 22:05:23 +00:00
}
2014-11-25 22:07:00 +00:00
// AddKey adds a new key to an already existing repository.
2015-04-26 12:46:15 +00:00
func AddKey(s *Server, password string, template *Key) (*Key, error) {
2014-11-25 22:07:00 +00:00
// fill meta data about key
newkey := &Key{
Created: time.Now(),
KDF: "scrypt",
N: scryptN,
R: scryptR,
P: scryptP,
}
hn, err := os.Hostname()
if err == nil {
newkey.Hostname = hn
}
usr, err := user.Current()
if err == nil {
newkey.Username = usr.Username
}
// generate random salt
newkey.Salt = make([]byte, scryptSaltsize)
n, err := rand.Read(newkey.Salt)
if n != scryptSaltsize || err != nil {
panic("unable to read enough random bytes for salt")
}
Refactor crypto layer, switch HMAC for Poyl1305-AES HMAC-SHA256 calls SHA256() twice which is very expensive. Therefore, this commit uses Poly1305-AES instead of HMAC-SHA256. benchcmp: benchmark old ns/op new ns/op delta BenchmarkChunkEncrypt 261033772 195114818 -25.25% BenchmarkChunkEncryptParallel 260973195 195787368 -24.98% BenchmarkArchiveDirectory 1050500651 1002615884 -4.56% BenchmarkPreload 23544286 24994508 +6.16% BenchmarkLoadTree 350065 427665 +22.17% BenchmarkEncryptWriter 87789753 31069126 -64.61% BenchmarkEncrypt 88283197 38259043 -56.66% BenchmarkDecryptReader 90478843 40714818 -55.00% BenchmarkEncryptDecryptReader 179917626 81231730 -54.85% BenchmarkDecrypt 87871591 37784207 -57.00% BenchmarkSaveJSON 52481 56861 +8.35% BenchmarkSaveFrom 75404085 51108596 -32.22% BenchmarkLoadJSONID 90545437 82696805 -8.67% benchmark old MB/s new MB/s speedup BenchmarkChunkEncrypt 40.17 53.74 1.34x BenchmarkChunkEncryptParallel 40.18 53.56 1.33x BenchmarkEncryptWriter 95.55 270.00 2.83x BenchmarkEncrypt 95.02 219.26 2.31x BenchmarkDecryptReader 92.71 206.03 2.22x BenchmarkEncryptDecryptReader 46.62 103.27 2.22x BenchmarkDecrypt 95.46 222.01 2.33x BenchmarkSaveFrom 55.62 82.07 1.48x benchmark old allocs new allocs delta BenchmarkChunkEncrypt 112 110 -1.79% BenchmarkChunkEncryptParallel 103 100 -2.91% BenchmarkArchiveDirectory 383704 392083 +2.18% BenchmarkPreload 21765 21874 +0.50% BenchmarkLoadTree 341 436 +27.86% BenchmarkEncryptWriter 20 17 -15.00% BenchmarkEncrypt 14 13 -7.14% BenchmarkDecryptReader 18 15 -16.67% BenchmarkEncryptDecryptReader 46 39 -15.22% BenchmarkDecrypt 16 12 -25.00% BenchmarkSaveJSON 81 86 +6.17% BenchmarkSaveFrom 117 121 +3.42% BenchmarkLoadJSONID 80525 80264 -0.32% benchmark old bytes new bytes delta BenchmarkChunkEncrypt 118956 64697 -45.61% BenchmarkChunkEncryptParallel 118972 64681 -45.63% BenchmarkArchiveDirectory 160236600 177498232 +10.77% BenchmarkPreload 2772488 3302992 +19.13% BenchmarkLoadTree 49102 46484 -5.33% BenchmarkEncryptWriter 28927 8388146 +28897.64% BenchmarkEncrypt 2473 1950 -21.15% BenchmarkDecryptReader 527827 2774 -99.47% BenchmarkEncryptDecryptReader 4100875 1528036 -62.74% BenchmarkDecrypt 2509 2154 -14.15% BenchmarkSaveJSON 4971 5892 +18.53% BenchmarkSaveFrom 40117 31742 -20.88% BenchmarkLoadJSONID 9444217 9442106 -0.02% This closes #102.
2015-03-14 18:53:51 +00:00
// call KDF to derive user key
newkey.user, err = crypto.KDF(newkey.N, newkey.R, newkey.P, newkey.Salt, password)
2014-11-25 22:07:00 +00:00
if err != nil {
return nil, err
}
if template == nil {
// generate new random master keys
2015-04-30 02:28:34 +00:00
newkey.master = crypto.NewRandomKey()
// generate random polynomial for cdc
p, err := chunker.RandomPolynomial()
if err != nil {
debug.Log("AddKey", "error generating new polynomial for cdc: %v", err)
return nil, err
}
debug.Log("AddKey", "generated new polynomial for cdc: %v", p)
newkey.master.ChunkerPolynomial = p
} else {
// copy master keys from old key
newkey.master = template.master
}
2014-11-25 22:07:00 +00:00
// encrypt master keys (as json) with user key
buf, err := json.Marshal(newkey.master)
if err != nil {
return nil, err
}
2015-04-26 12:46:15 +00:00
newkey.Data, err = crypto.Encrypt(newkey.user, nil, buf)
2014-11-25 22:07:00 +00:00
// dump as json
buf, err = json.Marshal(newkey)
if err != nil {
return nil, err
}
// store in repository and return
blob, err := s.be.Create()
2014-11-25 22:07:00 +00:00
if err != nil {
return nil, err
}
2015-03-28 10:50:23 +00:00
plainhw := backend.NewHashingWriter(blob, sha256.New())
2015-03-28 10:50:23 +00:00
_, err = plainhw.Write(buf)
if err != nil {
return nil, err
}
2015-03-28 10:50:23 +00:00
name := backend.ID(plainhw.Sum(nil)).String()
err = blob.Finalize(backend.Key, name)
if err != nil {
return nil, err
}
2015-03-28 10:50:23 +00:00
newkey.name = name
2014-11-25 22:07:00 +00:00
return newkey, nil
2014-11-25 22:07:00 +00:00
}
2015-04-30 16:09:08 +00:00
// Encrypt encrypts and authenticates data with the master key. Stored in
// ciphertext is IV || Ciphertext || MAC. Returns the ciphertext, which is
// extended if necessary.
func (k *Key) Encrypt(ciphertext, plaintext []byte) ([]byte, error) {
return crypto.Encrypt(k.master, ciphertext, plaintext)
2015-02-15 17:13:42 +00:00
}
2015-04-30 16:09:08 +00:00
// EncryptTo encrypts and authenticates data with the master key. The returned
// io.Writer writes IV || Ciphertext || MAC.
2015-02-15 17:13:42 +00:00
func (k *Key) EncryptTo(wr io.Writer) io.WriteCloser {
return crypto.EncryptTo(k.master, wr)
2014-09-23 20:39:12 +00:00
}
// Decrypt verifes and decrypts the ciphertext with the master key. Ciphertext
Refactor crypto layer, switch HMAC for Poyl1305-AES HMAC-SHA256 calls SHA256() twice which is very expensive. Therefore, this commit uses Poly1305-AES instead of HMAC-SHA256. benchcmp: benchmark old ns/op new ns/op delta BenchmarkChunkEncrypt 261033772 195114818 -25.25% BenchmarkChunkEncryptParallel 260973195 195787368 -24.98% BenchmarkArchiveDirectory 1050500651 1002615884 -4.56% BenchmarkPreload 23544286 24994508 +6.16% BenchmarkLoadTree 350065 427665 +22.17% BenchmarkEncryptWriter 87789753 31069126 -64.61% BenchmarkEncrypt 88283197 38259043 -56.66% BenchmarkDecryptReader 90478843 40714818 -55.00% BenchmarkEncryptDecryptReader 179917626 81231730 -54.85% BenchmarkDecrypt 87871591 37784207 -57.00% BenchmarkSaveJSON 52481 56861 +8.35% BenchmarkSaveFrom 75404085 51108596 -32.22% BenchmarkLoadJSONID 90545437 82696805 -8.67% benchmark old MB/s new MB/s speedup BenchmarkChunkEncrypt 40.17 53.74 1.34x BenchmarkChunkEncryptParallel 40.18 53.56 1.33x BenchmarkEncryptWriter 95.55 270.00 2.83x BenchmarkEncrypt 95.02 219.26 2.31x BenchmarkDecryptReader 92.71 206.03 2.22x BenchmarkEncryptDecryptReader 46.62 103.27 2.22x BenchmarkDecrypt 95.46 222.01 2.33x BenchmarkSaveFrom 55.62 82.07 1.48x benchmark old allocs new allocs delta BenchmarkChunkEncrypt 112 110 -1.79% BenchmarkChunkEncryptParallel 103 100 -2.91% BenchmarkArchiveDirectory 383704 392083 +2.18% BenchmarkPreload 21765 21874 +0.50% BenchmarkLoadTree 341 436 +27.86% BenchmarkEncryptWriter 20 17 -15.00% BenchmarkEncrypt 14 13 -7.14% BenchmarkDecryptReader 18 15 -16.67% BenchmarkEncryptDecryptReader 46 39 -15.22% BenchmarkDecrypt 16 12 -25.00% BenchmarkSaveJSON 81 86 +6.17% BenchmarkSaveFrom 117 121 +3.42% BenchmarkLoadJSONID 80525 80264 -0.32% benchmark old bytes new bytes delta BenchmarkChunkEncrypt 118956 64697 -45.61% BenchmarkChunkEncryptParallel 118972 64681 -45.63% BenchmarkArchiveDirectory 160236600 177498232 +10.77% BenchmarkPreload 2772488 3302992 +19.13% BenchmarkLoadTree 49102 46484 -5.33% BenchmarkEncryptWriter 28927 8388146 +28897.64% BenchmarkEncrypt 2473 1950 -21.15% BenchmarkDecryptReader 527827 2774 -99.47% BenchmarkEncryptDecryptReader 4100875 1528036 -62.74% BenchmarkDecrypt 2509 2154 -14.15% BenchmarkSaveJSON 4971 5892 +18.53% BenchmarkSaveFrom 40117 31742 -20.88% BenchmarkLoadJSONID 9444217 9442106 -0.02% This closes #102.
2015-03-14 18:53:51 +00:00
// must be in the form IV || Ciphertext || MAC.
Add 'plaintext' parameter to key.Decrypt() % benchcmp /tmp/{before,after} benchmark old ns/op new ns/op delta BenchmarkChunkEncrypt 261144414 260252046 -0.34% BenchmarkChunkEncryptParallel 261201438 261267029 +0.03% BenchmarkArchiveDirectory 0.00 0.00 +0.00% BenchmarkEncryptWriter 88297245 87526529 -0.87% BenchmarkEncrypt 87406446 87917897 +0.59% BenchmarkDecryptReader 89948630 90042541 +0.10% BenchmarkEncryptDecryptReader 178374144 179477306 +0.62% BenchmarkDecrypt 88289705 87937073 -0.40% BenchmarkSaveJSON 213917 213571 -0.16% BenchmarkSaveFrom 74881361 75111148 +0.31% benchmark old MB/s new MB/s speedup BenchmarkChunkEncrypt 40.15 40.29 1.00x BenchmarkChunkEncryptParallel 40.14 40.13 1.00x BenchmarkEncryptWriter 95.00 95.84 1.01x BenchmarkEncrypt 95.97 95.41 0.99x BenchmarkDecryptReader 93.26 93.16 1.00x BenchmarkEncryptDecryptReader 47.03 46.74 0.99x BenchmarkDecrypt 95.01 95.39 1.00x BenchmarkSaveFrom 56.01 55.84 1.00x benchmark old allocs new allocs delta BenchmarkChunkEncrypt 113 112 -0.88% BenchmarkChunkEncryptParallel 104 103 -0.96% BenchmarkArchiveDirectory 0 0 +0.00% BenchmarkEncryptWriter 20 20 +0.00% BenchmarkEncrypt 14 14 +0.00% BenchmarkDecryptReader 18 18 +0.00% BenchmarkEncryptDecryptReader 40 45 +12.50% BenchmarkDecrypt 17 16 -5.88% BenchmarkSaveJSON 125 125 +0.00% BenchmarkSaveFrom 116 119 +2.59% benchmark old bytes new bytes delta BenchmarkChunkEncrypt 8515750 118956 -98.60% BenchmarkChunkEncryptParallel 8515766 118972 -98.60% BenchmarkArchiveDirectory 0 0 +0.00% BenchmarkEncryptWriter 28927 28927 +0.00% BenchmarkEncrypt 422313 2473 -99.41% BenchmarkDecryptReader 527827 527827 +0.00% BenchmarkEncryptDecryptReader 4100824 4100870 +0.00% BenchmarkDecrypt 8391127 2509 -99.97% BenchmarkSaveJSON 9208 9208 +0.00% BenchmarkSaveFrom 39694 40541 +2.13%
2015-02-17 20:09:54 +00:00
func (k *Key) Decrypt(plaintext, ciphertext []byte) ([]byte, error) {
return crypto.Decrypt(k.master, plaintext, ciphertext)
2015-02-11 17:36:31 +00:00
}
// DecryptFrom verifies and decrypts the ciphertext read from rd and makes it
// available on the returned Reader. Ciphertext must be in the form IV ||
Refactor crypto layer, switch HMAC for Poyl1305-AES HMAC-SHA256 calls SHA256() twice which is very expensive. Therefore, this commit uses Poly1305-AES instead of HMAC-SHA256. benchcmp: benchmark old ns/op new ns/op delta BenchmarkChunkEncrypt 261033772 195114818 -25.25% BenchmarkChunkEncryptParallel 260973195 195787368 -24.98% BenchmarkArchiveDirectory 1050500651 1002615884 -4.56% BenchmarkPreload 23544286 24994508 +6.16% BenchmarkLoadTree 350065 427665 +22.17% BenchmarkEncryptWriter 87789753 31069126 -64.61% BenchmarkEncrypt 88283197 38259043 -56.66% BenchmarkDecryptReader 90478843 40714818 -55.00% BenchmarkEncryptDecryptReader 179917626 81231730 -54.85% BenchmarkDecrypt 87871591 37784207 -57.00% BenchmarkSaveJSON 52481 56861 +8.35% BenchmarkSaveFrom 75404085 51108596 -32.22% BenchmarkLoadJSONID 90545437 82696805 -8.67% benchmark old MB/s new MB/s speedup BenchmarkChunkEncrypt 40.17 53.74 1.34x BenchmarkChunkEncryptParallel 40.18 53.56 1.33x BenchmarkEncryptWriter 95.55 270.00 2.83x BenchmarkEncrypt 95.02 219.26 2.31x BenchmarkDecryptReader 92.71 206.03 2.22x BenchmarkEncryptDecryptReader 46.62 103.27 2.22x BenchmarkDecrypt 95.46 222.01 2.33x BenchmarkSaveFrom 55.62 82.07 1.48x benchmark old allocs new allocs delta BenchmarkChunkEncrypt 112 110 -1.79% BenchmarkChunkEncryptParallel 103 100 -2.91% BenchmarkArchiveDirectory 383704 392083 +2.18% BenchmarkPreload 21765 21874 +0.50% BenchmarkLoadTree 341 436 +27.86% BenchmarkEncryptWriter 20 17 -15.00% BenchmarkEncrypt 14 13 -7.14% BenchmarkDecryptReader 18 15 -16.67% BenchmarkEncryptDecryptReader 46 39 -15.22% BenchmarkDecrypt 16 12 -25.00% BenchmarkSaveJSON 81 86 +6.17% BenchmarkSaveFrom 117 121 +3.42% BenchmarkLoadJSONID 80525 80264 -0.32% benchmark old bytes new bytes delta BenchmarkChunkEncrypt 118956 64697 -45.61% BenchmarkChunkEncryptParallel 118972 64681 -45.63% BenchmarkArchiveDirectory 160236600 177498232 +10.77% BenchmarkPreload 2772488 3302992 +19.13% BenchmarkLoadTree 49102 46484 -5.33% BenchmarkEncryptWriter 28927 8388146 +28897.64% BenchmarkEncrypt 2473 1950 -21.15% BenchmarkDecryptReader 527827 2774 -99.47% BenchmarkEncryptDecryptReader 4100875 1528036 -62.74% BenchmarkDecrypt 2509 2154 -14.15% BenchmarkSaveJSON 4971 5892 +18.53% BenchmarkSaveFrom 40117 31742 -20.88% BenchmarkLoadJSONID 9444217 9442106 -0.02% This closes #102.
2015-03-14 18:53:51 +00:00
// Ciphertext || MAC. In order to correctly verify the ciphertext, rd is
2015-02-11 17:36:31 +00:00
// drained, locally buffered and made available on the returned Reader
2015-04-30 16:09:08 +00:00
// afterwards. If a MAC verification failure is observed, it is returned
2015-02-11 17:36:31 +00:00
// immediately.
Reduce memory usage of decryptReader benchmark old ns/op new ns/op delta BenchmarkChunkEncrypt 260007360 261144414 +0.44% BenchmarkChunkEncryptParallel 262839697 261201438 -0.62% BenchmarkArchiveDirectory 0.00 0.00 +0.00% BenchmarkEncryptWriter 86994839 88297245 +1.50% BenchmarkEncrypt 87414849 87406446 -0.01% BenchmarkDecryptReader 90354651 89948630 -0.45% BenchmarkEncryptDecryptReader 184533845 178374144 -3.34% BenchmarkDecrypt 88153894 88289705 +0.15% BenchmarkSaveJSON 213906 213917 +0.01% BenchmarkSaveFrom 75263853 74881361 -0.51% benchmark old MB/s new MB/s speedup BenchmarkChunkEncrypt 40.33 40.15 1.00x BenchmarkChunkEncryptParallel 39.89 40.14 1.01x BenchmarkEncryptWriter 96.43 95.00 0.99x BenchmarkEncrypt 95.96 95.97 1.00x BenchmarkDecryptReader 92.84 93.26 1.00x BenchmarkEncryptDecryptReader 45.46 47.03 1.03x BenchmarkDecrypt 95.16 95.01 1.00x BenchmarkSaveFrom 55.73 56.01 1.01x benchmark old allocs new allocs delta BenchmarkChunkEncrypt 113 113 +0.00% BenchmarkChunkEncryptParallel 104 104 +0.00% BenchmarkArchiveDirectory 0 0 +0.00% BenchmarkEncryptWriter 20 20 +0.00% BenchmarkEncrypt 14 14 +0.00% BenchmarkDecryptReader 18 18 +0.00% BenchmarkEncryptDecryptReader 55 40 -27.27% BenchmarkDecrypt 17 17 +0.00% BenchmarkSaveJSON 125 125 +0.00% BenchmarkSaveFrom 119 116 -2.52% benchmark old bytes new bytes delta BenchmarkChunkEncrypt 8515750 8515750 +0.00% BenchmarkChunkEncryptParallel 8515766 8515766 +0.00% BenchmarkArchiveDirectory 0 0 +0.00% BenchmarkEncryptWriter 28927 28927 +0.00% BenchmarkEncrypt 422313 422313 +0.00% BenchmarkDecryptReader 527827 527827 +0.00% BenchmarkEncryptDecryptReader 35814894 4100824 -88.55% BenchmarkDecrypt 8391127 8391127 +0.00% BenchmarkSaveJSON 9208 9208 +0.00% BenchmarkSaveFrom 40541 39694 -2.09%
2015-02-17 17:14:39 +00:00
func (k *Key) DecryptFrom(rd io.Reader) (io.ReadCloser, error) {
return crypto.DecryptFrom(k.master, rd)
2015-02-11 17:36:31 +00:00
}
2015-05-02 14:22:43 +00:00
// Master returns the master keys for this repository. Only included for
// debug purposes.
2015-04-12 07:41:47 +00:00
func (k *Key) Master() *crypto.Key {
return k.master
}
2015-05-02 14:22:43 +00:00
// User returns the user keys for this key. Only included for debug purposes.
2015-04-12 07:41:47 +00:00
func (k *Key) User() *crypto.Key {
return k.user
}
2014-09-23 20:39:12 +00:00
func (k *Key) String() string {
if k == nil {
return "<Key nil>"
}
return fmt.Sprintf("<Key of %s@%s, created on %s>", k.Username, k.Hostname, k.Created)
}
2014-11-25 22:18:02 +00:00
2015-03-28 10:50:23 +00:00
func (k Key) Name() string {
return k.name
2014-11-25 22:18:02 +00:00
}
// Valid tests whether the mac and encryption keys are valid (i.e. not zero)
func (k *Key) Valid() bool {
return k.user.Valid() && k.master.Valid()
}