parent
bfbb02019f
commit
9ce96baf5d
|
@ -83,10 +83,11 @@ type dbImpl interface {
|
||||||
|
|
||||||
// WMailServer whisper mailserver.
|
// WMailServer whisper mailserver.
|
||||||
type WMailServer struct {
|
type WMailServer struct {
|
||||||
db dbImpl
|
db dbImpl
|
||||||
w *whisper.Whisper
|
w *whisper.Whisper
|
||||||
pow float64
|
pow float64
|
||||||
filter *whisper.Filter
|
symFilter *whisper.Filter
|
||||||
|
asymFilter *whisper.Filter
|
||||||
|
|
||||||
muLimiter sync.RWMutex
|
muLimiter sync.RWMutex
|
||||||
limiter *limiter
|
limiter *limiter
|
||||||
|
@ -154,7 +155,8 @@ func (s *WMailServer) setupLimiter(limit time.Duration) {
|
||||||
// setupRequestMessageDecryptor setup a Whisper filter to decrypt
|
// setupRequestMessageDecryptor setup a Whisper filter to decrypt
|
||||||
// incoming Whisper requests.
|
// incoming Whisper requests.
|
||||||
func (s *WMailServer) setupRequestMessageDecryptor(config *params.WhisperConfig) error {
|
func (s *WMailServer) setupRequestMessageDecryptor(config *params.WhisperConfig) error {
|
||||||
var filter whisper.Filter
|
s.symFilter = nil
|
||||||
|
s.asymFilter = nil
|
||||||
|
|
||||||
if config.MailServerPassword != "" {
|
if config.MailServerPassword != "" {
|
||||||
keyID, err := s.w.AddSymKeyFromPassword(config.MailServerPassword)
|
keyID, err := s.w.AddSymKeyFromPassword(config.MailServerPassword)
|
||||||
|
@ -167,12 +169,12 @@ func (s *WMailServer) setupRequestMessageDecryptor(config *params.WhisperConfig)
|
||||||
return fmt.Errorf("save symmetric key: %v", err)
|
return fmt.Errorf("save symmetric key: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
filter = whisper.Filter{KeySym: symKey}
|
s.symFilter = &whisper.Filter{KeySym: symKey}
|
||||||
} else if config.MailServerAsymKey != nil {
|
|
||||||
filter = whisper.Filter{KeyAsym: config.MailServerAsymKey}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s.filter = &filter
|
if config.MailServerAsymKey != nil {
|
||||||
|
s.asymFilter = &whisper.Filter{KeyAsym: config.MailServerAsymKey}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -357,13 +359,29 @@ func (s *WMailServer) sendHistoricMessageResponse(peer *whisper.Peer, request *w
|
||||||
return s.w.SendHistoricMessageResponse(peer, payload)
|
return s.w.SendHistoricMessageResponse(peer, payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// openEnvelope tries to decrypt an envelope, first based on asymetric key (if
|
||||||
|
// provided) and second on the symetric key (if provided)
|
||||||
|
func (s *WMailServer) openEnvelope(request *whisper.Envelope) *whisper.ReceivedMessage {
|
||||||
|
if s.asymFilter != nil {
|
||||||
|
if d := request.Open(s.asymFilter); d != nil {
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if s.symFilter != nil {
|
||||||
|
if d := request.Open(s.symFilter); d != nil {
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// validateRequest runs different validations on the current request.
|
// validateRequest runs different validations on the current request.
|
||||||
func (s *WMailServer) validateRequest(peerID []byte, request *whisper.Envelope) (bool, uint32, uint32, []byte, uint32, cursorType) {
|
func (s *WMailServer) validateRequest(peerID []byte, request *whisper.Envelope) (bool, uint32, uint32, []byte, uint32, cursorType) {
|
||||||
if s.pow > 0.0 && request.PoW() < s.pow {
|
if s.pow > 0.0 && request.PoW() < s.pow {
|
||||||
return false, 0, 0, nil, 0, nil
|
return false, 0, 0, nil, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
decrypted := request.Open(s.filter)
|
decrypted := s.openEnvelope(request)
|
||||||
if decrypted == nil {
|
if decrypted == nil {
|
||||||
log.Warn("Failed to decrypt p2p request")
|
log.Warn("Failed to decrypt p2p request")
|
||||||
return false, 0, 0, nil, 0, nil
|
return false, 0, 0, nil, 0, nil
|
||||||
|
|
|
@ -39,6 +39,7 @@ const powRequirement = 0.00001
|
||||||
|
|
||||||
var keyID string
|
var keyID string
|
||||||
var seed = time.Now().Unix()
|
var seed = time.Now().Unix()
|
||||||
|
var testPayload = []byte("test payload")
|
||||||
|
|
||||||
type ServerTestParams struct {
|
type ServerTestParams struct {
|
||||||
topic whisper.TopicType
|
topic whisper.TopicType
|
||||||
|
@ -191,25 +192,66 @@ func (s *MailserverSuite) TestSetupRequestMessageDecryptor() {
|
||||||
config = *s.config
|
config = *s.config
|
||||||
s.NoError(config.ReadMailServerPasswordFile())
|
s.NoError(config.ReadMailServerPasswordFile())
|
||||||
s.NoError(s.server.Init(s.shh, &config))
|
s.NoError(s.server.Init(s.shh, &config))
|
||||||
s.NotNil(s.server.filter.KeySym)
|
s.Require().NotNil(s.server.symFilter)
|
||||||
s.Nil(s.server.filter.KeyAsym)
|
s.NotNil(s.server.symFilter.KeySym)
|
||||||
|
s.Nil(s.server.asymFilter)
|
||||||
s.server.Close()
|
s.server.Close()
|
||||||
|
|
||||||
// AsymKey can also be used
|
// AsymKey can also be used
|
||||||
config = *s.config
|
config = *s.config
|
||||||
s.NoError(config.ReadMailServerAsymKeyFile())
|
s.NoError(config.ReadMailServerAsymKeyFile())
|
||||||
s.NoError(s.server.Init(s.shh, &config))
|
s.NoError(s.server.Init(s.shh, &config))
|
||||||
s.Nil(s.server.filter.KeySym) // important: symmetric key should be nil
|
s.Nil(s.server.symFilter) // important: symmetric filter should be nil
|
||||||
s.Equal(config.MailServerAsymKey, s.server.filter.KeyAsym)
|
s.Require().NotNil(s.server.asymFilter)
|
||||||
|
s.Equal(config.MailServerAsymKey, s.server.asymFilter.KeyAsym)
|
||||||
s.server.Close()
|
s.server.Close()
|
||||||
|
|
||||||
// when both Password and AsymKey are set, Password has a preference
|
// when Password and AsymKey are set, both are supported
|
||||||
config = *s.config
|
config = *s.config
|
||||||
s.NoError(config.ReadMailServerPasswordFile())
|
s.NoError(config.ReadMailServerPasswordFile())
|
||||||
s.NoError(config.ReadMailServerAsymKeyFile())
|
s.NoError(config.ReadMailServerAsymKeyFile())
|
||||||
s.NoError(s.server.Init(s.shh, &config))
|
s.NoError(s.server.Init(s.shh, &config))
|
||||||
s.NotNil(s.server.filter.KeySym)
|
s.Require().NotNil(s.server.symFilter)
|
||||||
s.Nil(s.server.filter.KeyAsym)
|
s.NotNil(s.server.symFilter.KeySym)
|
||||||
|
s.NotNil(s.server.asymFilter.KeyAsym)
|
||||||
|
s.server.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MailserverSuite) TestOpenEnvelopeWithSymKey() {
|
||||||
|
// Setup the server with a sym key
|
||||||
|
config := *s.config
|
||||||
|
s.NoError(config.ReadMailServerPasswordFile())
|
||||||
|
s.NoError(s.server.Init(s.shh, &config))
|
||||||
|
|
||||||
|
// Prepare a valid envelope
|
||||||
|
s.Require().NotNil(s.server.symFilter)
|
||||||
|
symKey := s.server.symFilter.KeySym
|
||||||
|
env, err := generateEnvelopeWithKeys(time.Now(), symKey, nil)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// Test openEnvelope with a valid envelope
|
||||||
|
d := s.server.openEnvelope(env)
|
||||||
|
s.NotNil(d)
|
||||||
|
s.Equal(testPayload, d.Payload)
|
||||||
|
s.server.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MailserverSuite) TestOpenEnvelopeWithAsymKey() {
|
||||||
|
// Setup the server with an asymetric key
|
||||||
|
config := *s.config
|
||||||
|
s.NoError(config.ReadMailServerAsymKeyFile())
|
||||||
|
s.NoError(s.server.Init(s.shh, &config))
|
||||||
|
|
||||||
|
// Prepare a valid envelope
|
||||||
|
s.Require().NotNil(s.server.asymFilter)
|
||||||
|
pubKey := s.server.asymFilter.KeyAsym.PublicKey
|
||||||
|
env, err := generateEnvelopeWithKeys(time.Now(), nil, &pubKey)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// Test openEnvelope with a valid asymetric key
|
||||||
|
d := s.server.openEnvelope(env)
|
||||||
|
s.NotNil(d)
|
||||||
|
s.Equal(testPayload, d.Payload)
|
||||||
s.server.Close()
|
s.server.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,16 +580,20 @@ func (s *MailserverSuite) createRequest(p *ServerTestParams) *whisper.Envelope {
|
||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateEnvelope(sentTime time.Time) (*whisper.Envelope, error) {
|
func generateEnvelopeWithKeys(sentTime time.Time, keySym []byte, keyAsym *ecdsa.PublicKey) (*whisper.Envelope, error) {
|
||||||
h := crypto.Keccak256Hash([]byte("test sample data"))
|
|
||||||
params := &whisper.MessageParams{
|
params := &whisper.MessageParams{
|
||||||
KeySym: h[:],
|
|
||||||
Topic: whisper.TopicType{0x1F, 0x7E, 0xA1, 0x7F},
|
Topic: whisper.TopicType{0x1F, 0x7E, 0xA1, 0x7F},
|
||||||
Payload: []byte("test payload"),
|
Payload: testPayload,
|
||||||
PoW: powRequirement,
|
PoW: powRequirement,
|
||||||
WorkTime: 2,
|
WorkTime: 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(keySym) > 0 {
|
||||||
|
params.KeySym = keySym
|
||||||
|
} else if keyAsym != nil {
|
||||||
|
params.Dst = keyAsym
|
||||||
|
}
|
||||||
|
|
||||||
msg, err := whisper.NewSentMessage(params)
|
msg, err := whisper.NewSentMessage(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create new message with seed %d: %s", seed, err)
|
return nil, fmt.Errorf("failed to create new message with seed %d: %s", seed, err)
|
||||||
|
@ -559,3 +605,8 @@ func generateEnvelope(sentTime time.Time) (*whisper.Envelope, error) {
|
||||||
|
|
||||||
return env, nil
|
return env, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateEnvelope(sentTime time.Time) (*whisper.Envelope, error) {
|
||||||
|
h := crypto.Keccak256Hash([]byte("test sample data"))
|
||||||
|
return generateEnvelopeWithKeys(sentTime, h[:], nil)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue