whisper: sym key management changed

This commit is contained in:
Vlad 2017-03-02 13:38:38 +01:00
parent 581841f74d
commit 8ac7104567
10 changed files with 336 additions and 149 deletions

View file

@ -46,7 +46,6 @@ import (
)
const quitCommand = "~Q"
const symKeyName = "da919ea33001b04dfc630522e33078ec0df11"
// singletons
var (
@ -288,8 +287,14 @@ func configureNode() {
}
}
shh.AddSymKey(symKeyName, []byte(symPass))
symKey = shh.GetSymKey(symKeyName)
symKeyID, err := shh.AddSymKeyFromPassword(symPass)
if err != nil {
utils.Fatalf("Failed to create symmetric key: %s", err)
}
symKey, err = shh.GetSymKey(symKeyID)
if err != nil {
utils.Fatalf("Failed to save symmetric key: %s", err)
}
if len(*argTopic) == 0 {
generateTopic([]byte(symPass))
}
@ -470,11 +475,14 @@ func requestExpiredMessagesLoop() {
var t string
var xt, empty whisper.TopicType
err := shh.AddSymKey(mailserver.MailServerKeyName, []byte(msPassword))
keyID, err := shh.AddSymKeyFromPassword(msPassword)
if err != nil {
utils.Fatalf("Failed to create symmetric key for mail request: %s", err)
}
key = shh.GetSymKey(mailserver.MailServerKeyName)
key, err = shh.GetSymKey(keyID)
if err != nil {
utils.Fatalf("Failed to save symmetric key for mail request: %s", err)
}
peerID = extractIdFromEnode(*argEnode)
shh.MarkPeerTrusted(peerID)

View file

@ -31,8 +31,6 @@ import (
"github.com/syndtr/goleveldb/leveldb/util"
)
const MailServerKeyName = "958e04ab302fb36ad2616a352cbac79d"
type WMailServer struct {
db *leveldb.DB
w *whisper.Whisper
@ -75,11 +73,14 @@ func (s *WMailServer) Init(shh *whisper.Whisper, path string, password string, p
s.w = shh
s.pow = pow
err = s.w.AddSymKey(MailServerKeyName, []byte(password))
MailServerKeyID, err := s.w.AddSymKeyFromPassword(password)
if err != nil {
utils.Fatalf("Failed to create symmetric key for MailServer: %s", err)
}
s.key = s.w.GetSymKey(MailServerKeyName)
s.key, err = s.w.GetSymKey(MailServerKeyID)
if err != nil {
utils.Fatalf("Failed to save symmetric key for MailServer")
}
}
func (s *WMailServer) Close() {

View file

@ -30,8 +30,8 @@ import (
)
const powRequirement = 0.00001
const keyName = "6d604bac5401ce9a6b995f1b45a4ab"
var keyID string
var shh *whisper.Whisper
var seed = time.Now().Unix()
@ -90,7 +90,7 @@ func TestMailServer(t *testing.T) {
server.Init(shh, dir, password, powRequirement)
defer server.Close()
err = shh.AddSymKey(keyName, []byte(password))
keyID, err = shh.AddSymKeyFromPassword(password)
if err != nil {
t.Fatalf("Failed to create symmetric key for mail request: %s", err)
}
@ -167,8 +167,13 @@ func createRequest(t *testing.T, p *ServerTestParams) *whisper.Envelope {
binary.BigEndian.PutUint32(data[4:], p.upp)
copy(data[8:], p.topic[:])
key, err := shh.GetSymKey(keyID)
if err != nil {
t.Fatalf("failed to retrieve sym key with seed %d: %s.", seed, err)
}
params := &whisper.MessageParams{
KeySym: shh.GetSymKey(keyName),
KeySym: key,
Topic: p.topic,
Payload: data,
PoW: powRequirement * 2,

View file

@ -134,40 +134,63 @@ func (api *PublicWhisperAPI) NewIdentity() (string, error) {
return common.ToHex(crypto.FromECDSAPub(&identity.PublicKey)), nil
}
// GenerateSymKey generates a random symmetric key and stores it under
// the 'name' id. Will be used in the future for session key exchange.
func (api *PublicWhisperAPI) GenerateSymKey(name string) error {
// todo: implement
//func (api *PublicWhisperAPI) GetPublicKey(id string) (bool, error) {
// if api.whisper == nil {
// return false, whisperOffLineErr
// }
// return api.whisper.HasIdentity(identity), nil
//}
// GenerateSymKey generates a random symmetric key and stores it under id,
// which is then returned. Will be used in the future for session key exchange.
func (api *PublicWhisperAPI) GenerateSymKey() (string, error) {
if api.whisper == nil {
return whisperOffLineErr
return "", whisperOffLineErr
}
return api.whisper.GenerateSymKey(name)
return api.whisper.GenerateSymKey()
}
// AddSymKey stores the key under the 'name' id.
func (api *PublicWhisperAPI) AddSymKey(name string, key hexutil.Bytes) error {
// AddSymKeyDirect stores the key, and returns its id.
func (api *PublicWhisperAPI) AddSymKeyDirect(key hexutil.Bytes) (string, error) {
if api.whisper == nil {
return whisperOffLineErr
return "", whisperOffLineErr
}
return api.whisper.AddSymKey(name, key)
return api.whisper.AddSymKeyDirect(key)
}
// HasSymKey returns true if there is a key associated with the name string.
// AddSymKeyFromPassword generates the key from password, stores it, and returns its id.
func (api *PublicWhisperAPI) AddSymKeyFromPassword(password string) (string, error) {
if api.whisper == nil {
return "", whisperOffLineErr
}
return api.whisper.AddSymKeyFromPassword(password)
}
// HasSymKey returns true if there is a key associated with the given id.
// Otherwise returns false.
func (api *PublicWhisperAPI) HasSymKey(name string) (bool, error) {
func (api *PublicWhisperAPI) HasSymKey(id string) (bool, error) {
if api.whisper == nil {
return false, whisperOffLineErr
}
res := api.whisper.HasSymKey(name)
res := api.whisper.HasSymKey(id)
return res, nil
}
// DeleteSymKey deletes the key associated with the name string if it exists.
func (api *PublicWhisperAPI) DeleteSymKey(name string) error {
func (api *PublicWhisperAPI) GetSymKey(name string) ([]byte, error) {
if api.whisper == nil {
return whisperOffLineErr
return nil, whisperOffLineErr
}
api.whisper.DeleteSymKey(name)
return nil
return api.whisper.GetSymKey(name)
}
// DeleteSymKey deletes the key associated with the name string if it exists.
func (api *PublicWhisperAPI) DeleteSymKey(name string) (bool, error) {
if api.whisper == nil {
return false, whisperOffLineErr
}
res := api.whisper.DeleteSymKey(name)
return res, nil
}
// NewWhisperFilter creates and registers a new message filter to watch for inbound whisper messages.
@ -177,9 +200,21 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (string, error) {
return "", whisperOffLineErr
}
var err error
var symKey []byte
if len(args.KeyName) > 0 {
symKey, err = api.whisper.GetSymKey(args.KeyName)
if err != nil {
info := "NewFilter: symmetric key ID does not exist: " + args.KeyName
log.Error(fmt.Sprintf(info))
return "", errors.New(info)
}
}
filter := Filter{
Src: crypto.ToECDSAPub(common.FromHex(args.From)),
KeySym: api.whisper.GetSymKey(args.KeyName),
KeySym: symKey,
PoW: args.PoW,
Messages: make(map[common.Hash]*ReceivedMessage),
AcceptP2P: args.AcceptP2P,
@ -195,12 +230,6 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (string, error) {
return "", errors.New(info)
}
if len(args.KeyName) != 0 && len(filter.KeySym) == 0 {
info := "NewFilter: key was not found by name: " + args.KeyName
log.Error(fmt.Sprintf(info))
return "", errors.New(info)
}
if len(args.To) == 0 && len(filter.KeySym) == 0 {
info := "NewFilter: filter must contain either symmetric or asymmetric key"
log.Error(fmt.Sprintf(info))
@ -275,10 +304,22 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
return whisperOffLineErr
}
var err error
var symKey []byte
if len(args.KeyName) > 0 {
symKey, err = api.whisper.GetSymKey(args.KeyName)
if err != nil {
info := "NewFilter: symmetric key ID does not exist: " + args.KeyName
log.Error(fmt.Sprintf(info))
return errors.New(info)
}
}
params := MessageParams{
TTL: args.TTL,
Dst: crypto.ToECDSAPub(common.FromHex(args.To)),
KeySym: api.whisper.GetSymKey(args.KeyName),
KeySym: symKey,
Topic: args.Topic,
Payload: args.Payload,
Padding: args.Padding,
@ -333,12 +374,6 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
}
// validate
if len(args.KeyName) != 0 && len(params.KeySym) == 0 {
info := "Post: key was not found by name: " + args.KeyName
log.Error(fmt.Sprintf(info))
return errors.New(info)
}
if len(args.To) == 0 && len(params.KeySym) == 0 {
info := "Post: message must be encrypted either symmetrically or asymmetrically"
log.Error(fmt.Sprintf(info))

View file

@ -106,7 +106,7 @@ func TestBasic(t *testing.T) {
t.Fatalf("failed HasSymKey: false positive.")
}
err = api.GenerateSymKey(id)
id, err = api.GenerateSymKey()
if err != nil {
t.Fatalf("failed GenerateSymKey: %s.", err)
}
@ -119,12 +119,13 @@ func TestBasic(t *testing.T) {
t.Fatalf("failed HasSymKey(): false negative.")
}
err = api.AddSymKey(id, []byte("some stuff here"))
if err == nil {
const password = "some stuff here"
id, err = api.AddSymKeyFromPassword(password)
if err != nil {
t.Fatalf("failed AddSymKey: %s.", err)
}
err = api.AddSymKey(id2, []byte("some stuff here"))
id2, err = api.AddSymKeyFromPassword(password)
if err != nil {
t.Fatalf("failed AddSymKey: %s.", err)
}
@ -137,10 +138,26 @@ func TestBasic(t *testing.T) {
t.Fatalf("failed HasSymKey(id2): false negative.")
}
err = api.DeleteSymKey(id)
k1, err := api.GetSymKey(id)
if err != nil {
t.Fatalf("failed GetSymKey(id): %s.", err)
}
k2, err := api.GetSymKey(id2)
if err != nil {
t.Fatalf("failed GetSymKey(id2): %s.", err)
}
if !bytes.Equal(k1, k2) {
t.Fatalf("installed keys are not equal")
}
exist, err = api.DeleteSymKey(id)
if err != nil {
t.Fatalf("failed DeleteSymKey(id): %s.", err)
}
if !exist {
t.Fatalf("failed DeleteSymKey(id): false negative.")
}
exist, err = api.HasSymKey(id)
if err != nil {
@ -384,8 +401,7 @@ func TestIntegrationSym(t *testing.T) {
api.Start()
defer api.Stop()
keyname := "schluessel"
err := api.GenerateSymKey(keyname)
keyID, err := api.GenerateSymKey()
if err != nil {
t.Fatalf("failed GenerateSymKey: %s.", err)
}
@ -410,7 +426,7 @@ func TestIntegrationSym(t *testing.T) {
topics[0] = TopicType{0x00, 0x7f, 0x80, 0xff}
topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79}
var f WhisperFilterArgs
f.KeyName = keyname
f.KeyName = keyID
f.Topics = topics[:]
f.PoW = 0.324
f.From = sig
@ -423,7 +439,7 @@ func TestIntegrationSym(t *testing.T) {
var p PostArgs
p.TTL = 1
p.KeyName = keyname
p.KeyName = keyID
p.From = f.From
p.Padding = []byte("test string")
p.Payload = []byte("extended test string")
@ -474,8 +490,7 @@ func TestIntegrationSymWithFilter(t *testing.T) {
api.Start()
defer api.Stop()
keyname := "schluessel"
err := api.GenerateSymKey(keyname)
keyID, err := api.GenerateSymKey()
if err != nil {
t.Fatalf("failed to GenerateSymKey: %s.", err)
}
@ -500,7 +515,7 @@ func TestIntegrationSymWithFilter(t *testing.T) {
topics[0] = TopicType{0x00, 0x7f, 0x80, 0xff}
topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79}
var f WhisperFilterArgs
f.KeyName = keyname
f.KeyName = keyID
f.Topics = topics[:]
f.PoW = 0.324
f.From = sig

View file

@ -54,6 +54,7 @@ const (
aesKeyLength = 32
saltLength = 12
AESNonceMaxLength = 12
keyIdSize = 32
DefaultMaxMessageLength = 1024 * 1024
DefaultMinimumPoW = 10.0 // todo: review after testing.

View file

@ -18,7 +18,6 @@ package whisperv5
import (
"crypto/ecdsa"
crand "crypto/rand"
"fmt"
"sync"
@ -52,40 +51,24 @@ func NewFilters(w *Whisper) *Filters {
}
}
func (fs *Filters) generateRandomID() (id string, err error) {
buf := make([]byte, 20)
for i := 0; i < 3; i++ {
_, err = crand.Read(buf)
if err != nil {
continue
}
if !validateSymmetricKey(buf) {
err = fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data")
continue
}
id = common.Bytes2Hex(buf)
if fs.watchers[id] != nil {
err = fmt.Errorf("error in generateRandomID: generated same ID twice")
continue
}
return id, err
}
return "", err
}
func (fs *Filters) Install(watcher *Filter) (string, error) {
if watcher.Messages == nil {
watcher.Messages = make(map[common.Hash]*ReceivedMessage)
}
id, err := GenerateRandomID()
if err != nil {
return "", err
}
fs.mutex.Lock()
defer fs.mutex.Unlock()
id, err := fs.generateRandomID()
if err == nil {
fs.watchers[id] = watcher
if fs.watchers[id] != nil {
return "", fmt.Errorf("failed to generate unique ID")
}
fs.watchers[id] = watcher
return id, err
}

View file

@ -108,7 +108,7 @@ func TestInstallFilters(t *testing.T) {
t.Fatalf("seed %d: failed to install filter: %s", seed, err)
}
tst[i].id = j
if len(j) != 40 {
if len(j) != keyIdSize*2 {
t.Fatalf("seed %d: wrong filter id size [%d]", seed, len(j))
}
}

View file

@ -48,6 +48,7 @@ type Whisper struct {
filters *Filters
privateKeys map[string]*ecdsa.PrivateKey
//identities map[string]*ecdsa.PrivateKey
symKeys map[string][]byte
keyMu sync.RWMutex
@ -76,6 +77,7 @@ type Whisper struct {
func New() *Whisper {
whisper := &Whisper{
privateKeys: make(map[string]*ecdsa.PrivateKey),
//identities: make(map[string]*ecdsa.PrivateKey),
symKeys: make(map[string][]byte),
envelopes: make(map[common.Hash]*Envelope),
expirations: make(map[uint32]*set.SetNonTS),
@ -231,72 +233,108 @@ func (w *Whisper) GetIdentity(pubKey string) *ecdsa.PrivateKey {
return w.privateKeys[pubKey]
}
func (w *Whisper) GenerateSymKey(name string) error {
func (w *Whisper) GenerateSymKey() (string, error) {
const size = aesKeyLength * 2
buf := make([]byte, size)
_, err := crand.Read(buf)
if err != nil {
return err
return "", err
} else if !validateSymmetricKey(buf) {
return fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data")
return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data")
}
key := buf[:aesKeyLength]
salt := buf[aesKeyLength:]
derived, err := DeriveOneTimeKey(key, salt, EnvelopeVersion)
if err != nil {
return err
return "", err
} else if !validateSymmetricKey(derived) {
return fmt.Errorf("failed to derive valid key")
return "", fmt.Errorf("failed to derive valid key")
}
w.keyMu.Lock()
defer w.keyMu.Unlock()
if w.symKeys[name] != nil {
return fmt.Errorf("Key with name [%s] already exists", name)
}
w.symKeys[name] = derived
return nil
}
func (w *Whisper) AddSymKey(name string, key []byte) error {
if w.HasSymKey(name) {
return fmt.Errorf("Key with name [%s] already exists", name)
}
derived, err := deriveKeyMaterial(key, EnvelopeVersion)
id, err := GenerateRandomID()
if err != nil {
return err
return "", fmt.Errorf("Failed to generate ID: %s", err)
}
w.keyMu.Lock()
defer w.keyMu.Unlock()
// double check is necessary, because deriveKeyMaterial() is slow
if w.symKeys[name] != nil {
return fmt.Errorf("Key with name [%s] already exists", name)
if w.symKeys[id] != nil {
return "", fmt.Errorf("Failed to generate unique ID")
}
w.symKeys[name] = derived
return nil
w.symKeys[id] = derived
return id, nil
}
func (w *Whisper) HasSymKey(name string) bool {
w.keyMu.RLock()
defer w.keyMu.RUnlock()
return w.symKeys[name] != nil
func (w *Whisper) AddSymKeyDirect(key []byte) (string, error) {
if len(key) != aesKeyLength {
return "", fmt.Errorf("Wrong key size: %d", len(key))
}
id, err := GenerateRandomID()
if err != nil {
return "", fmt.Errorf("Failed to generate ID: %s", err)
}
func (w *Whisper) DeleteSymKey(name string) {
w.keyMu.Lock()
defer w.keyMu.Unlock()
delete(w.symKeys, name)
if w.symKeys[id] != nil {
return "", fmt.Errorf("Failed to generate unique ID")
}
w.symKeys[id] = key
return id, nil
}
func (w *Whisper) GetSymKey(name string) []byte {
func (w *Whisper) AddSymKeyFromPassword(password string) (string, error) {
id, err := GenerateRandomID()
if err != nil {
return "", fmt.Errorf("Failed to generate ID: %s", err)
}
if w.HasSymKey(id) {
return "", fmt.Errorf("Failed to generate unique ID")
}
derived, err := deriveKeyMaterial([]byte(password), EnvelopeVersion)
if err != nil {
return "", err
}
w.keyMu.Lock()
defer w.keyMu.Unlock()
// double check is necessary, because deriveKeyMaterial() is very slow
if w.symKeys[id] != nil {
return "", fmt.Errorf("Severe error: failed to generate unique ID")
}
w.symKeys[id] = derived
return id, nil
}
func (w *Whisper) HasSymKey(id string) bool {
w.keyMu.RLock()
defer w.keyMu.RUnlock()
return w.symKeys[name]
return w.symKeys[id] != nil
}
func (w *Whisper) DeleteSymKey(id string) bool {
w.keyMu.Lock()
defer w.keyMu.Unlock()
if w.symKeys[id] != nil {
delete(w.symKeys, id)
return true
}
return false
}
func (w *Whisper) GetSymKey(id string) ([]byte, error) {
w.keyMu.RLock()
defer w.keyMu.RUnlock()
if w.symKeys[id] != nil {
return w.symKeys[id], nil
}
return nil, fmt.Errorf("non-existent ID")
}
// Watch installs a new message handler to run in case a matching packet arrives
@ -709,3 +747,16 @@ func deriveKeyMaterial(key []byte, version uint64) (derivedKey []byte, err error
return nil, unknownVersionError(version)
}
}
func GenerateRandomID() (id string, err error) {
buf := make([]byte, keyIdSize)
_, err = crand.Read(buf)
if err != nil {
return "", err
}
if !validateSymmetricKey(buf) {
return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data")
}
id = common.Bytes2Hex(buf)
return id, err
}

View file

@ -61,9 +61,12 @@ func TestWhisperBasic(t *testing.T) {
if exist {
t.Fatalf("failed HasSymKey.")
}
key := w.GetSymKey("non-existing")
key, err := w.GetSymKey("non-existing")
if err == nil {
t.Fatalf("failed GetSymKey(non-existing): false positive.")
}
if key != nil {
t.Fatalf("failed GetSymKey.")
t.Fatalf("failed GetSymKey: false positive.")
}
mail := w.Envelopes()
if len(mail) != 0 {
@ -79,7 +82,7 @@ func TestWhisperBasic(t *testing.T) {
if _, err := deriveKeyMaterial(peerID, ver); err != unknownVersionError(ver) {
t.Fatalf("failed deriveKeyMaterial with param = %v: %s.", peerID, err)
}
derived, err := deriveKeyMaterial(peerID, 0)
derived, err = deriveKeyMaterial(peerID, 0)
if err != nil {
t.Fatalf("failed second deriveKeyMaterial with param = %v: %s.", peerID, err)
}
@ -185,23 +188,30 @@ func TestWhisperIdentityManagement(t *testing.T) {
func TestWhisperSymKeyManagement(t *testing.T) {
InitSingleTest()
var err error
var k1, k2 []byte
w := New()
id1 := string("arbitrary-string-1")
id2 := string("arbitrary-string-2")
err := w.GenerateSymKey(id1)
id1, err = w.GenerateSymKey()
if err != nil {
t.Fatalf("failed GenerateSymKey with seed %d: %s.", seed, err)
}
k1 = w.GetSymKey(id1)
k2 = w.GetSymKey(id2)
k1, err = w.GetSymKey(id1)
if err != nil {
t.Fatalf("failed GetSymKey(id1).")
}
k2, err = w.GetSymKey(id2)
if err == nil {
t.Fatalf("failed GetSymKey(id2): false positive.")
}
if !w.HasSymKey(id1) {
t.Fatalf("failed HasSymKey(id1).")
}
if w.HasSymKey(id2) {
t.Fatalf("failed HasSymKey(id2).")
t.Fatalf("failed HasSymKey(id2): false positive.")
}
if k1 == nil {
t.Fatalf("first key does not exist.")
@ -210,38 +220,49 @@ func TestWhisperSymKeyManagement(t *testing.T) {
t.Fatalf("second key still exist.")
}
// add existing id, nothing should change
randomKey := make([]byte, 16)
randomKey := make([]byte, aesKeyLength)
randomize(randomKey)
err = w.AddSymKey(id1, randomKey)
if err == nil {
t.Fatalf("failed AddSymKey with seed %d.", seed)
id1, err = w.AddSymKeyDirect(randomKey)
if err != nil {
t.Fatalf("failed AddSymKey with seed %d: %s.", seed, err)
}
k1 = w.GetSymKey(id1)
k2 = w.GetSymKey(id2)
k1, err = w.GetSymKey(id1)
if err != nil {
t.Fatalf("failed w.GetSymKey(id1).")
}
k2, err = w.GetSymKey(id2)
if err == nil {
t.Fatalf("failed w.GetSymKey(id2): false positive.")
}
if !w.HasSymKey(id1) {
t.Fatalf("failed w.HasSymKey(id1).")
}
if w.HasSymKey(id2) {
t.Fatalf("failed w.HasSymKey(id2).")
t.Fatalf("failed w.HasSymKey(id2): false positive.")
}
if k1 == nil {
t.Fatalf("first key does not exist.")
}
if bytes.Equal(k1, randomKey) {
t.Fatalf("k1 == randomKey.")
if !bytes.Equal(k1, randomKey) {
t.Fatalf("k1 != randomKey.")
}
if k2 != nil {
t.Fatalf("second key already exist.")
}
err = w.AddSymKey(id2, randomKey) // add non-existing (yet)
id2, err = w.AddSymKeyDirect(randomKey)
if err != nil {
t.Fatalf("failed AddSymKey(id2) with seed %d: %s.", seed, err)
}
k1 = w.GetSymKey(id1)
k2 = w.GetSymKey(id2)
k1, err = w.GetSymKey(id1)
if err != nil {
t.Fatalf("failed w.GetSymKey(id1).")
}
k2, err = w.GetSymKey(id2)
if err != nil {
t.Fatalf("failed w.GetSymKey(id2).")
}
if !w.HasSymKey(id1) {
t.Fatalf("HasSymKey(id1) failed.")
}
@ -254,11 +275,11 @@ func TestWhisperSymKeyManagement(t *testing.T) {
if k2 == nil {
t.Fatalf("k2 does not exist.")
}
if bytes.Equal(k1, k2) {
t.Fatalf("k1 == k2.")
if !bytes.Equal(k1, k2) {
t.Fatalf("k1 != k2.")
}
if bytes.Equal(k1, randomKey) {
t.Fatalf("k1 == randomKey.")
if !bytes.Equal(k1, randomKey) {
t.Fatalf("k1 != randomKey.")
}
if len(k1) != aesKeyLength {
t.Fatalf("wrong length of k1.")
@ -268,8 +289,17 @@ func TestWhisperSymKeyManagement(t *testing.T) {
}
w.DeleteSymKey(id1)
k1 = w.GetSymKey(id1)
k2 = w.GetSymKey(id2)
k1, err = w.GetSymKey(id1)
if err == nil {
t.Fatalf("failed w.GetSymKey(id1): false positive.")
}
if k1 != nil {
t.Fatalf("failed GetSymKey(id1): false positive.")
}
k2, err = w.GetSymKey(id2)
if err != nil {
t.Fatalf("failed w.GetSymKey(id2).")
}
if w.HasSymKey(id1) {
t.Fatalf("failed to delete first key: still exist.")
}
@ -285,8 +315,17 @@ func TestWhisperSymKeyManagement(t *testing.T) {
w.DeleteSymKey(id1)
w.DeleteSymKey(id2)
k1 = w.GetSymKey(id1)
k2 = w.GetSymKey(id2)
k1, err = w.GetSymKey(id1)
if err == nil {
t.Fatalf("failed w.GetSymKey(id1): false positive.")
}
k2, err = w.GetSymKey(id2)
if err == nil {
t.Fatalf("failed w.GetSymKey(id2): false positive.")
}
if k1 != nil || k2 != nil {
t.Fatalf("k1 or k2 is not nil")
}
if w.HasSymKey(id1) {
t.Fatalf("failed to delete second key: first key exist.")
}
@ -299,6 +338,55 @@ func TestWhisperSymKeyManagement(t *testing.T) {
if k2 != nil {
t.Fatalf("failed to delete second key: second key is not nil.")
}
randomKey = make([]byte, aesKeyLength+1)
randomize(randomKey)
id1, err = w.AddSymKeyDirect(randomKey)
if err == nil {
t.Fatalf("added the key with wrong size, seed %d.", seed)
}
const password = "arbitrary data here"
id1, err = w.AddSymKeyFromPassword(password)
if err != nil {
t.Fatalf("failed AddSymKeyFromPassword(id1) with seed %d: %s.", seed, err)
}
id2, err = w.AddSymKeyFromPassword(password)
if err != nil {
t.Fatalf("failed AddSymKeyFromPassword(id2) with seed %d: %s.", seed, err)
}
k1, err = w.GetSymKey(id1)
if err != nil {
t.Fatalf("failed w.GetSymKey(id1).")
}
k2, err = w.GetSymKey(id2)
if err != nil {
t.Fatalf("failed w.GetSymKey(id2).")
}
if !w.HasSymKey(id1) {
t.Fatalf("HasSymKey(id1) failed.")
}
if !w.HasSymKey(id2) {
t.Fatalf("HasSymKey(id2) failed.")
}
if k1 == nil {
t.Fatalf("k1 does not exist.")
}
if k2 == nil {
t.Fatalf("k2 does not exist.")
}
if !bytes.Equal(k1, k2) {
t.Fatalf("k1 != k2.")
}
if len(k1) != aesKeyLength {
t.Fatalf("wrong length of k1.")
}
if len(k2) != aesKeyLength {
t.Fatalf("wrong length of k2.")
}
if !validateSymmetricKey(k2) {
t.Fatalf("key validation failed.")
}
}
func TestExpiry(t *testing.T) {