mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
whisper: sym key management changed
This commit is contained in:
parent
581841f74d
commit
8ac7104567
10 changed files with 336 additions and 149 deletions
|
|
@ -46,7 +46,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const quitCommand = "~Q"
|
const quitCommand = "~Q"
|
||||||
const symKeyName = "da919ea33001b04dfc630522e33078ec0df11"
|
|
||||||
|
|
||||||
// singletons
|
// singletons
|
||||||
var (
|
var (
|
||||||
|
|
@ -288,8 +287,14 @@ func configureNode() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shh.AddSymKey(symKeyName, []byte(symPass))
|
symKeyID, err := shh.AddSymKeyFromPassword(symPass)
|
||||||
symKey = shh.GetSymKey(symKeyName)
|
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 {
|
if len(*argTopic) == 0 {
|
||||||
generateTopic([]byte(symPass))
|
generateTopic([]byte(symPass))
|
||||||
}
|
}
|
||||||
|
|
@ -470,11 +475,14 @@ func requestExpiredMessagesLoop() {
|
||||||
var t string
|
var t string
|
||||||
var xt, empty whisper.TopicType
|
var xt, empty whisper.TopicType
|
||||||
|
|
||||||
err := shh.AddSymKey(mailserver.MailServerKeyName, []byte(msPassword))
|
keyID, err := shh.AddSymKeyFromPassword(msPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to create symmetric key for mail request: %s", err)
|
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)
|
peerID = extractIdFromEnode(*argEnode)
|
||||||
shh.MarkPeerTrusted(peerID)
|
shh.MarkPeerTrusted(peerID)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,6 @@ import (
|
||||||
"github.com/syndtr/goleveldb/leveldb/util"
|
"github.com/syndtr/goleveldb/leveldb/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const MailServerKeyName = "958e04ab302fb36ad2616a352cbac79d"
|
|
||||||
|
|
||||||
type WMailServer struct {
|
type WMailServer struct {
|
||||||
db *leveldb.DB
|
db *leveldb.DB
|
||||||
w *whisper.Whisper
|
w *whisper.Whisper
|
||||||
|
|
@ -75,11 +73,14 @@ func (s *WMailServer) Init(shh *whisper.Whisper, path string, password string, p
|
||||||
s.w = shh
|
s.w = shh
|
||||||
s.pow = pow
|
s.pow = pow
|
||||||
|
|
||||||
err = s.w.AddSymKey(MailServerKeyName, []byte(password))
|
MailServerKeyID, err := s.w.AddSymKeyFromPassword(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to create symmetric key for MailServer: %s", err)
|
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() {
|
func (s *WMailServer) Close() {
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const powRequirement = 0.00001
|
const powRequirement = 0.00001
|
||||||
const keyName = "6d604bac5401ce9a6b995f1b45a4ab"
|
|
||||||
|
|
||||||
|
var keyID string
|
||||||
var shh *whisper.Whisper
|
var shh *whisper.Whisper
|
||||||
var seed = time.Now().Unix()
|
var seed = time.Now().Unix()
|
||||||
|
|
||||||
|
|
@ -90,7 +90,7 @@ func TestMailServer(t *testing.T) {
|
||||||
server.Init(shh, dir, password, powRequirement)
|
server.Init(shh, dir, password, powRequirement)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
err = shh.AddSymKey(keyName, []byte(password))
|
keyID, err = shh.AddSymKeyFromPassword(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create symmetric key for mail request: %s", err)
|
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)
|
binary.BigEndian.PutUint32(data[4:], p.upp)
|
||||||
copy(data[8:], p.topic[:])
|
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{
|
params := &whisper.MessageParams{
|
||||||
KeySym: shh.GetSymKey(keyName),
|
KeySym: key,
|
||||||
Topic: p.topic,
|
Topic: p.topic,
|
||||||
Payload: data,
|
Payload: data,
|
||||||
PoW: powRequirement * 2,
|
PoW: powRequirement * 2,
|
||||||
|
|
|
||||||
|
|
@ -134,40 +134,63 @@ func (api *PublicWhisperAPI) NewIdentity() (string, error) {
|
||||||
return common.ToHex(crypto.FromECDSAPub(&identity.PublicKey)), nil
|
return common.ToHex(crypto.FromECDSAPub(&identity.PublicKey)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateSymKey generates a random symmetric key and stores it under
|
// todo: implement
|
||||||
// the 'name' id. Will be used in the future for session key exchange.
|
//func (api *PublicWhisperAPI) GetPublicKey(id string) (bool, error) {
|
||||||
func (api *PublicWhisperAPI) GenerateSymKey(name string) 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 {
|
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.
|
// AddSymKeyDirect stores the key, and returns its id.
|
||||||
func (api *PublicWhisperAPI) AddSymKey(name string, key hexutil.Bytes) error {
|
func (api *PublicWhisperAPI) AddSymKeyDirect(key hexutil.Bytes) (string, error) {
|
||||||
if api.whisper == nil {
|
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.
|
// Otherwise returns false.
|
||||||
func (api *PublicWhisperAPI) HasSymKey(name string) (bool, error) {
|
func (api *PublicWhisperAPI) HasSymKey(id string) (bool, error) {
|
||||||
if api.whisper == nil {
|
if api.whisper == nil {
|
||||||
return false, whisperOffLineErr
|
return false, whisperOffLineErr
|
||||||
}
|
}
|
||||||
res := api.whisper.HasSymKey(name)
|
res := api.whisper.HasSymKey(id)
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteSymKey deletes the key associated with the name string if it exists.
|
func (api *PublicWhisperAPI) GetSymKey(name string) ([]byte, error) {
|
||||||
func (api *PublicWhisperAPI) DeleteSymKey(name string) error {
|
|
||||||
if api.whisper == nil {
|
if api.whisper == nil {
|
||||||
return whisperOffLineErr
|
return nil, whisperOffLineErr
|
||||||
}
|
}
|
||||||
api.whisper.DeleteSymKey(name)
|
return api.whisper.GetSymKey(name)
|
||||||
return nil
|
}
|
||||||
|
|
||||||
|
// 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.
|
// 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
|
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{
|
filter := Filter{
|
||||||
Src: crypto.ToECDSAPub(common.FromHex(args.From)),
|
Src: crypto.ToECDSAPub(common.FromHex(args.From)),
|
||||||
KeySym: api.whisper.GetSymKey(args.KeyName),
|
KeySym: symKey,
|
||||||
PoW: args.PoW,
|
PoW: args.PoW,
|
||||||
Messages: make(map[common.Hash]*ReceivedMessage),
|
Messages: make(map[common.Hash]*ReceivedMessage),
|
||||||
AcceptP2P: args.AcceptP2P,
|
AcceptP2P: args.AcceptP2P,
|
||||||
|
|
@ -195,12 +230,6 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (string, error) {
|
||||||
return "", errors.New(info)
|
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 {
|
if len(args.To) == 0 && len(filter.KeySym) == 0 {
|
||||||
info := "NewFilter: filter must contain either symmetric or asymmetric key"
|
info := "NewFilter: filter must contain either symmetric or asymmetric key"
|
||||||
log.Error(fmt.Sprintf(info))
|
log.Error(fmt.Sprintf(info))
|
||||||
|
|
@ -275,10 +304,22 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
|
||||||
return whisperOffLineErr
|
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{
|
params := MessageParams{
|
||||||
TTL: args.TTL,
|
TTL: args.TTL,
|
||||||
Dst: crypto.ToECDSAPub(common.FromHex(args.To)),
|
Dst: crypto.ToECDSAPub(common.FromHex(args.To)),
|
||||||
KeySym: api.whisper.GetSymKey(args.KeyName),
|
KeySym: symKey,
|
||||||
Topic: args.Topic,
|
Topic: args.Topic,
|
||||||
Payload: args.Payload,
|
Payload: args.Payload,
|
||||||
Padding: args.Padding,
|
Padding: args.Padding,
|
||||||
|
|
@ -333,12 +374,6 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate
|
// 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 {
|
if len(args.To) == 0 && len(params.KeySym) == 0 {
|
||||||
info := "Post: message must be encrypted either symmetrically or asymmetrically"
|
info := "Post: message must be encrypted either symmetrically or asymmetrically"
|
||||||
log.Error(fmt.Sprintf(info))
|
log.Error(fmt.Sprintf(info))
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ func TestBasic(t *testing.T) {
|
||||||
t.Fatalf("failed HasSymKey: false positive.")
|
t.Fatalf("failed HasSymKey: false positive.")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = api.GenerateSymKey(id)
|
id, err = api.GenerateSymKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed GenerateSymKey: %s.", err)
|
t.Fatalf("failed GenerateSymKey: %s.", err)
|
||||||
}
|
}
|
||||||
|
|
@ -119,12 +119,13 @@ func TestBasic(t *testing.T) {
|
||||||
t.Fatalf("failed HasSymKey(): false negative.")
|
t.Fatalf("failed HasSymKey(): false negative.")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = api.AddSymKey(id, []byte("some stuff here"))
|
const password = "some stuff here"
|
||||||
if err == nil {
|
id, err = api.AddSymKeyFromPassword(password)
|
||||||
|
if err != nil {
|
||||||
t.Fatalf("failed AddSymKey: %s.", err)
|
t.Fatalf("failed AddSymKey: %s.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = api.AddSymKey(id2, []byte("some stuff here"))
|
id2, err = api.AddSymKeyFromPassword(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed AddSymKey: %s.", err)
|
t.Fatalf("failed AddSymKey: %s.", err)
|
||||||
}
|
}
|
||||||
|
|
@ -137,10 +138,26 @@ func TestBasic(t *testing.T) {
|
||||||
t.Fatalf("failed HasSymKey(id2): false negative.")
|
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 {
|
if err != nil {
|
||||||
t.Fatalf("failed DeleteSymKey(id): %s.", err)
|
t.Fatalf("failed DeleteSymKey(id): %s.", err)
|
||||||
}
|
}
|
||||||
|
if !exist {
|
||||||
|
t.Fatalf("failed DeleteSymKey(id): false negative.")
|
||||||
|
}
|
||||||
|
|
||||||
exist, err = api.HasSymKey(id)
|
exist, err = api.HasSymKey(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -384,8 +401,7 @@ func TestIntegrationSym(t *testing.T) {
|
||||||
api.Start()
|
api.Start()
|
||||||
defer api.Stop()
|
defer api.Stop()
|
||||||
|
|
||||||
keyname := "schluessel"
|
keyID, err := api.GenerateSymKey()
|
||||||
err := api.GenerateSymKey(keyname)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed GenerateSymKey: %s.", err)
|
t.Fatalf("failed GenerateSymKey: %s.", err)
|
||||||
}
|
}
|
||||||
|
|
@ -410,7 +426,7 @@ func TestIntegrationSym(t *testing.T) {
|
||||||
topics[0] = TopicType{0x00, 0x7f, 0x80, 0xff}
|
topics[0] = TopicType{0x00, 0x7f, 0x80, 0xff}
|
||||||
topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79}
|
topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79}
|
||||||
var f WhisperFilterArgs
|
var f WhisperFilterArgs
|
||||||
f.KeyName = keyname
|
f.KeyName = keyID
|
||||||
f.Topics = topics[:]
|
f.Topics = topics[:]
|
||||||
f.PoW = 0.324
|
f.PoW = 0.324
|
||||||
f.From = sig
|
f.From = sig
|
||||||
|
|
@ -423,7 +439,7 @@ func TestIntegrationSym(t *testing.T) {
|
||||||
|
|
||||||
var p PostArgs
|
var p PostArgs
|
||||||
p.TTL = 1
|
p.TTL = 1
|
||||||
p.KeyName = keyname
|
p.KeyName = keyID
|
||||||
p.From = f.From
|
p.From = f.From
|
||||||
p.Padding = []byte("test string")
|
p.Padding = []byte("test string")
|
||||||
p.Payload = []byte("extended test string")
|
p.Payload = []byte("extended test string")
|
||||||
|
|
@ -474,8 +490,7 @@ func TestIntegrationSymWithFilter(t *testing.T) {
|
||||||
api.Start()
|
api.Start()
|
||||||
defer api.Stop()
|
defer api.Stop()
|
||||||
|
|
||||||
keyname := "schluessel"
|
keyID, err := api.GenerateSymKey()
|
||||||
err := api.GenerateSymKey(keyname)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to GenerateSymKey: %s.", err)
|
t.Fatalf("failed to GenerateSymKey: %s.", err)
|
||||||
}
|
}
|
||||||
|
|
@ -500,7 +515,7 @@ func TestIntegrationSymWithFilter(t *testing.T) {
|
||||||
topics[0] = TopicType{0x00, 0x7f, 0x80, 0xff}
|
topics[0] = TopicType{0x00, 0x7f, 0x80, 0xff}
|
||||||
topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79}
|
topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79}
|
||||||
var f WhisperFilterArgs
|
var f WhisperFilterArgs
|
||||||
f.KeyName = keyname
|
f.KeyName = keyID
|
||||||
f.Topics = topics[:]
|
f.Topics = topics[:]
|
||||||
f.PoW = 0.324
|
f.PoW = 0.324
|
||||||
f.From = sig
|
f.From = sig
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ const (
|
||||||
aesKeyLength = 32
|
aesKeyLength = 32
|
||||||
saltLength = 12
|
saltLength = 12
|
||||||
AESNonceMaxLength = 12
|
AESNonceMaxLength = 12
|
||||||
|
keyIdSize = 32
|
||||||
|
|
||||||
DefaultMaxMessageLength = 1024 * 1024
|
DefaultMaxMessageLength = 1024 * 1024
|
||||||
DefaultMinimumPoW = 10.0 // todo: review after testing.
|
DefaultMinimumPoW = 10.0 // todo: review after testing.
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ package whisperv5
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
crand "crypto/rand"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"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) {
|
func (fs *Filters) Install(watcher *Filter) (string, error) {
|
||||||
if watcher.Messages == nil {
|
if watcher.Messages == nil {
|
||||||
watcher.Messages = make(map[common.Hash]*ReceivedMessage)
|
watcher.Messages = make(map[common.Hash]*ReceivedMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id, err := GenerateRandomID()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
fs.mutex.Lock()
|
fs.mutex.Lock()
|
||||||
defer fs.mutex.Unlock()
|
defer fs.mutex.Unlock()
|
||||||
|
|
||||||
id, err := fs.generateRandomID()
|
if fs.watchers[id] != nil {
|
||||||
if err == nil {
|
return "", fmt.Errorf("failed to generate unique ID")
|
||||||
fs.watchers[id] = watcher
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs.watchers[id] = watcher
|
||||||
return id, err
|
return id, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ func TestInstallFilters(t *testing.T) {
|
||||||
t.Fatalf("seed %d: failed to install filter: %s", seed, err)
|
t.Fatalf("seed %d: failed to install filter: %s", seed, err)
|
||||||
}
|
}
|
||||||
tst[i].id = j
|
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))
|
t.Fatalf("seed %d: wrong filter id size [%d]", seed, len(j))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,9 @@ type Whisper struct {
|
||||||
filters *Filters
|
filters *Filters
|
||||||
|
|
||||||
privateKeys map[string]*ecdsa.PrivateKey
|
privateKeys map[string]*ecdsa.PrivateKey
|
||||||
symKeys map[string][]byte
|
//identities map[string]*ecdsa.PrivateKey
|
||||||
keyMu sync.RWMutex
|
symKeys map[string][]byte
|
||||||
|
keyMu sync.RWMutex
|
||||||
|
|
||||||
envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node
|
envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node
|
||||||
expirations map[uint32]*set.SetNonTS // Message expiration pool
|
expirations map[uint32]*set.SetNonTS // Message expiration pool
|
||||||
|
|
@ -75,7 +76,8 @@ type Whisper struct {
|
||||||
// Param s should be passed if you want to implement mail server, otherwise nil.
|
// Param s should be passed if you want to implement mail server, otherwise nil.
|
||||||
func New() *Whisper {
|
func New() *Whisper {
|
||||||
whisper := &Whisper{
|
whisper := &Whisper{
|
||||||
privateKeys: make(map[string]*ecdsa.PrivateKey),
|
privateKeys: make(map[string]*ecdsa.PrivateKey),
|
||||||
|
//identities: make(map[string]*ecdsa.PrivateKey),
|
||||||
symKeys: make(map[string][]byte),
|
symKeys: make(map[string][]byte),
|
||||||
envelopes: make(map[common.Hash]*Envelope),
|
envelopes: make(map[common.Hash]*Envelope),
|
||||||
expirations: make(map[uint32]*set.SetNonTS),
|
expirations: make(map[uint32]*set.SetNonTS),
|
||||||
|
|
@ -231,72 +233,108 @@ func (w *Whisper) GetIdentity(pubKey string) *ecdsa.PrivateKey {
|
||||||
return w.privateKeys[pubKey]
|
return w.privateKeys[pubKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Whisper) GenerateSymKey(name string) error {
|
func (w *Whisper) GenerateSymKey() (string, error) {
|
||||||
const size = aesKeyLength * 2
|
const size = aesKeyLength * 2
|
||||||
buf := make([]byte, size)
|
buf := make([]byte, size)
|
||||||
_, err := crand.Read(buf)
|
_, err := crand.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
} else if !validateSymmetricKey(buf) {
|
} 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]
|
key := buf[:aesKeyLength]
|
||||||
salt := buf[aesKeyLength:]
|
salt := buf[aesKeyLength:]
|
||||||
derived, err := DeriveOneTimeKey(key, salt, EnvelopeVersion)
|
derived, err := DeriveOneTimeKey(key, salt, EnvelopeVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
} else if !validateSymmetricKey(derived) {
|
} else if !validateSymmetricKey(derived) {
|
||||||
return fmt.Errorf("failed to derive valid key")
|
return "", fmt.Errorf("failed to derive valid key")
|
||||||
}
|
}
|
||||||
|
|
||||||
w.keyMu.Lock()
|
id, err := GenerateRandomID()
|
||||||
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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", fmt.Errorf("Failed to generate ID: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.keyMu.Lock()
|
w.keyMu.Lock()
|
||||||
defer w.keyMu.Unlock()
|
defer w.keyMu.Unlock()
|
||||||
|
|
||||||
// double check is necessary, because deriveKeyMaterial() is slow
|
if w.symKeys[id] != nil {
|
||||||
if w.symKeys[name] != nil {
|
return "", fmt.Errorf("Failed to generate unique ID")
|
||||||
return fmt.Errorf("Key with name [%s] already exists", name)
|
|
||||||
}
|
}
|
||||||
w.symKeys[name] = derived
|
w.symKeys[id] = derived
|
||||||
return nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Whisper) HasSymKey(name string) bool {
|
func (w *Whisper) AddSymKeyDirect(key []byte) (string, error) {
|
||||||
w.keyMu.RLock()
|
if len(key) != aesKeyLength {
|
||||||
defer w.keyMu.RUnlock()
|
return "", fmt.Errorf("Wrong key size: %d", len(key))
|
||||||
return w.symKeys[name] != nil
|
}
|
||||||
}
|
|
||||||
|
id, err := GenerateRandomID()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Failed to generate ID: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Whisper) DeleteSymKey(name string) {
|
|
||||||
w.keyMu.Lock()
|
w.keyMu.Lock()
|
||||||
defer w.keyMu.Unlock()
|
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()
|
w.keyMu.RLock()
|
||||||
defer w.keyMu.RUnlock()
|
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
|
// 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)
|
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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,12 @@ func TestWhisperBasic(t *testing.T) {
|
||||||
if exist {
|
if exist {
|
||||||
t.Fatalf("failed HasSymKey.")
|
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 {
|
if key != nil {
|
||||||
t.Fatalf("failed GetSymKey.")
|
t.Fatalf("failed GetSymKey: false positive.")
|
||||||
}
|
}
|
||||||
mail := w.Envelopes()
|
mail := w.Envelopes()
|
||||||
if len(mail) != 0 {
|
if len(mail) != 0 {
|
||||||
|
|
@ -79,7 +82,7 @@ func TestWhisperBasic(t *testing.T) {
|
||||||
if _, err := deriveKeyMaterial(peerID, ver); err != unknownVersionError(ver) {
|
if _, err := deriveKeyMaterial(peerID, ver); err != unknownVersionError(ver) {
|
||||||
t.Fatalf("failed deriveKeyMaterial with param = %v: %s.", peerID, err)
|
t.Fatalf("failed deriveKeyMaterial with param = %v: %s.", peerID, err)
|
||||||
}
|
}
|
||||||
derived, err := deriveKeyMaterial(peerID, 0)
|
derived, err = deriveKeyMaterial(peerID, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed second deriveKeyMaterial with param = %v: %s.", peerID, err)
|
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) {
|
func TestWhisperSymKeyManagement(t *testing.T) {
|
||||||
InitSingleTest()
|
InitSingleTest()
|
||||||
|
|
||||||
|
var err error
|
||||||
var k1, k2 []byte
|
var k1, k2 []byte
|
||||||
w := New()
|
w := New()
|
||||||
id1 := string("arbitrary-string-1")
|
id1 := string("arbitrary-string-1")
|
||||||
id2 := string("arbitrary-string-2")
|
id2 := string("arbitrary-string-2")
|
||||||
|
|
||||||
err := w.GenerateSymKey(id1)
|
id1, err = w.GenerateSymKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed GenerateSymKey with seed %d: %s.", seed, err)
|
t.Fatalf("failed GenerateSymKey with seed %d: %s.", seed, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
k1 = w.GetSymKey(id1)
|
k1, err = w.GetSymKey(id1)
|
||||||
k2 = w.GetSymKey(id2)
|
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) {
|
if !w.HasSymKey(id1) {
|
||||||
t.Fatalf("failed HasSymKey(id1).")
|
t.Fatalf("failed HasSymKey(id1).")
|
||||||
}
|
}
|
||||||
if w.HasSymKey(id2) {
|
if w.HasSymKey(id2) {
|
||||||
t.Fatalf("failed HasSymKey(id2).")
|
t.Fatalf("failed HasSymKey(id2): false positive.")
|
||||||
}
|
}
|
||||||
if k1 == nil {
|
if k1 == nil {
|
||||||
t.Fatalf("first key does not exist.")
|
t.Fatalf("first key does not exist.")
|
||||||
|
|
@ -210,38 +220,49 @@ func TestWhisperSymKeyManagement(t *testing.T) {
|
||||||
t.Fatalf("second key still exist.")
|
t.Fatalf("second key still exist.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// add existing id, nothing should change
|
randomKey := make([]byte, aesKeyLength)
|
||||||
randomKey := make([]byte, 16)
|
|
||||||
randomize(randomKey)
|
randomize(randomKey)
|
||||||
err = w.AddSymKey(id1, randomKey)
|
id1, err = w.AddSymKeyDirect(randomKey)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
t.Fatalf("failed AddSymKey with seed %d.", seed)
|
t.Fatalf("failed AddSymKey with seed %d: %s.", seed, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
k1 = w.GetSymKey(id1)
|
k1, err = w.GetSymKey(id1)
|
||||||
k2 = w.GetSymKey(id2)
|
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) {
|
if !w.HasSymKey(id1) {
|
||||||
t.Fatalf("failed w.HasSymKey(id1).")
|
t.Fatalf("failed w.HasSymKey(id1).")
|
||||||
}
|
}
|
||||||
if w.HasSymKey(id2) {
|
if w.HasSymKey(id2) {
|
||||||
t.Fatalf("failed w.HasSymKey(id2).")
|
t.Fatalf("failed w.HasSymKey(id2): false positive.")
|
||||||
}
|
}
|
||||||
if k1 == nil {
|
if k1 == nil {
|
||||||
t.Fatalf("first key does not exist.")
|
t.Fatalf("first key does not exist.")
|
||||||
}
|
}
|
||||||
if bytes.Equal(k1, randomKey) {
|
if !bytes.Equal(k1, randomKey) {
|
||||||
t.Fatalf("k1 == randomKey.")
|
t.Fatalf("k1 != randomKey.")
|
||||||
}
|
}
|
||||||
if k2 != nil {
|
if k2 != nil {
|
||||||
t.Fatalf("second key already exist.")
|
t.Fatalf("second key already exist.")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = w.AddSymKey(id2, randomKey) // add non-existing (yet)
|
id2, err = w.AddSymKeyDirect(randomKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed AddSymKey(id2) with seed %d: %s.", seed, err)
|
t.Fatalf("failed AddSymKey(id2) with seed %d: %s.", seed, err)
|
||||||
}
|
}
|
||||||
k1 = w.GetSymKey(id1)
|
k1, err = w.GetSymKey(id1)
|
||||||
k2 = w.GetSymKey(id2)
|
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) {
|
if !w.HasSymKey(id1) {
|
||||||
t.Fatalf("HasSymKey(id1) failed.")
|
t.Fatalf("HasSymKey(id1) failed.")
|
||||||
}
|
}
|
||||||
|
|
@ -254,11 +275,11 @@ func TestWhisperSymKeyManagement(t *testing.T) {
|
||||||
if k2 == nil {
|
if k2 == nil {
|
||||||
t.Fatalf("k2 does not exist.")
|
t.Fatalf("k2 does not exist.")
|
||||||
}
|
}
|
||||||
if bytes.Equal(k1, k2) {
|
if !bytes.Equal(k1, k2) {
|
||||||
t.Fatalf("k1 == k2.")
|
t.Fatalf("k1 != k2.")
|
||||||
}
|
}
|
||||||
if bytes.Equal(k1, randomKey) {
|
if !bytes.Equal(k1, randomKey) {
|
||||||
t.Fatalf("k1 == randomKey.")
|
t.Fatalf("k1 != randomKey.")
|
||||||
}
|
}
|
||||||
if len(k1) != aesKeyLength {
|
if len(k1) != aesKeyLength {
|
||||||
t.Fatalf("wrong length of k1.")
|
t.Fatalf("wrong length of k1.")
|
||||||
|
|
@ -268,8 +289,17 @@ func TestWhisperSymKeyManagement(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
w.DeleteSymKey(id1)
|
w.DeleteSymKey(id1)
|
||||||
k1 = w.GetSymKey(id1)
|
k1, err = w.GetSymKey(id1)
|
||||||
k2 = w.GetSymKey(id2)
|
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) {
|
if w.HasSymKey(id1) {
|
||||||
t.Fatalf("failed to delete first key: still exist.")
|
t.Fatalf("failed to delete first key: still exist.")
|
||||||
}
|
}
|
||||||
|
|
@ -285,8 +315,17 @@ func TestWhisperSymKeyManagement(t *testing.T) {
|
||||||
|
|
||||||
w.DeleteSymKey(id1)
|
w.DeleteSymKey(id1)
|
||||||
w.DeleteSymKey(id2)
|
w.DeleteSymKey(id2)
|
||||||
k1 = w.GetSymKey(id1)
|
k1, err = w.GetSymKey(id1)
|
||||||
k2 = w.GetSymKey(id2)
|
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) {
|
if w.HasSymKey(id1) {
|
||||||
t.Fatalf("failed to delete second key: first key exist.")
|
t.Fatalf("failed to delete second key: first key exist.")
|
||||||
}
|
}
|
||||||
|
|
@ -299,6 +338,55 @@ func TestWhisperSymKeyManagement(t *testing.T) {
|
||||||
if k2 != nil {
|
if k2 != nil {
|
||||||
t.Fatalf("failed to delete second key: second key is not 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) {
|
func TestExpiry(t *testing.T) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue