package notify import "errors" var ( errClientSessionQueueUnavailable = errors.New("client session queue is unavailable") errServerSessionQueueUnavailable = errors.New("server session queue is unavailable") errTransportPayloadEncryptFailed = errors.New("transport payload encrypt failed") errTransportPayloadDecryptFailed = errors.New("transport payload decrypt failed") ) func (c *ClientCommon) encodeTransferMsg(msg TransferMsg) ([]byte, error) { data, err := c.sequenceEn(msg) if err != nil { return nil, err } data = c.msgEn(c.SecretKey, data) queue := c.clientQueueSnapshot() if queue == nil { return nil, errClientSessionQueueUnavailable } return queue.BuildMessage(data), nil } func (c *ClientCommon) decodeTransferMsg(data []byte) (TransferMsg, error) { msg, err := c.sequenceDe(c.msgDe(c.SecretKey, data)) if err != nil { return TransferMsg{}, err } transfer, ok := msg.(TransferMsg) if !ok { return TransferMsg{}, errors.New("invalid transfer message") } return transfer, nil } func (s *ServerCommon) encodeTransferMsg(c *ClientConn, msg TransferMsg) ([]byte, error) { data, err := s.sequenceEn(msg) if err != nil { return nil, err } msgEn := c.clientConnMsgEnSnapshot() secretKey := c.clientConnSecretKeySnapshot() data = msgEn(secretKey, data) queue := s.serverQueueSnapshot() if queue == nil { return nil, errServerSessionQueueUnavailable } return queue.BuildMessage(data), nil } func (s *ServerCommon) decodeTransferMsg(c *ClientConn, data []byte) (TransferMsg, error) { msgDe := c.clientConnMsgDeSnapshot() secretKey := c.clientConnSecretKeySnapshot() msg, err := s.sequenceDe(msgDe(secretKey, data)) if err != nil { return TransferMsg{}, err } transfer, ok := msg.(TransferMsg) if !ok { return TransferMsg{}, errors.New("invalid transfer message") } return transfer, nil } func (c *ClientCommon) encodeEnvelopePayload(env Envelope) ([]byte, error) { data, err := c.encodeEnvelopePlain(env) if err != nil { return nil, err } return c.encryptTransportPayload(data) } func (c *ClientCommon) encodeEnvelopePlain(env Envelope) ([]byte, error) { data, err := c.sequenceEn(env) if err != nil { return nil, err } return data, nil } func (c *ClientCommon) encryptTransportPayload(data []byte) ([]byte, error) { encoded := c.msgEn(c.SecretKey, data) if encoded == nil && len(data) != 0 { return nil, errTransportPayloadEncryptFailed } return encoded, nil } func (c *ClientCommon) encodeEnvelope(env Envelope) ([]byte, error) { data, err := c.encodeEnvelopePayload(env) if err != nil { return nil, err } queue := c.clientQueueSnapshot() if queue == nil { return nil, errClientSessionQueueUnavailable } return queue.BuildMessage(data), nil } func (c *ClientCommon) decodeEnvelope(data []byte) (Envelope, error) { plain, err := c.decryptTransportPayload(data) if err != nil { return Envelope{}, err } return c.decodeEnvelopePlain(plain) } func (c *ClientCommon) decryptTransportPayload(data []byte) ([]byte, error) { plain := c.msgDe(c.SecretKey, data) if plain == nil && len(data) != 0 { return nil, errTransportPayloadDecryptFailed } return plain, nil } func (c *ClientCommon) decodeEnvelopePlain(data []byte) (Envelope, error) { msg, err := c.sequenceDe(data) if err != nil { return Envelope{}, err } env, ok := msg.(Envelope) if ok { return env, nil } transfer, ok := msg.(TransferMsg) if !ok { return Envelope{}, errors.New("invalid envelope") } wrapped, err := wrapTransferMsgEnvelope(transfer, c.sequenceEn) if err != nil { return Envelope{}, err } return wrapped, nil } func (s *ServerCommon) encodeEnvelope(c *ClientConn, env Envelope) ([]byte, error) { return s.encodeEnvelopeLogical(logicalConnFromClient(c), env) } func (s *ServerCommon) encodeEnvelopePayloadLogical(logical *LogicalConn, env Envelope) ([]byte, error) { if logical == nil { return nil, errTransportDetached } data, err := s.encodeEnvelopePlain(env) if err != nil { return nil, err } return s.encryptTransportPayloadLogical(logical, data) } func (s *ServerCommon) encodeEnvelopePlain(env Envelope) ([]byte, error) { data, err := s.sequenceEn(env) if err != nil { return nil, err } return data, nil } func (s *ServerCommon) encryptTransportPayloadLogical(logical *LogicalConn, data []byte) ([]byte, error) { if logical == nil { return nil, errTransportDetached } msgEn := logical.msgEnSnapshot() secretKey := logical.secretKeySnapshot() if msgEn == nil { return nil, errTransportDetached } encoded := msgEn(secretKey, data) if encoded == nil && len(data) != 0 { return nil, errTransportPayloadEncryptFailed } return encoded, nil } func (s *ServerCommon) encodeEnvelopeLogical(logical *LogicalConn, env Envelope) ([]byte, error) { data, err := s.encodeEnvelopePayloadLogical(logical, env) if err != nil { return nil, err } queue := s.serverQueueSnapshot() if queue == nil { return nil, errServerSessionQueueUnavailable } return queue.BuildMessage(data), nil } func (s *ServerCommon) decodeEnvelope(c *ClientConn, data []byte) (Envelope, error) { return s.decodeEnvelopeLogical(logicalConnFromClient(c), data) } func (s *ServerCommon) decodeEnvelopeLogical(logical *LogicalConn, data []byte) (Envelope, error) { if logical == nil { return Envelope{}, errTransportDetached } plain, err := s.decryptTransportPayloadLogical(logical, data) if err != nil { return Envelope{}, err } return s.decodeEnvelopePlain(plain) } func (s *ServerCommon) decryptTransportPayloadLogical(logical *LogicalConn, data []byte) ([]byte, error) { if logical == nil { return nil, errTransportDetached } msgDe := logical.msgDeSnapshot() secretKey := logical.secretKeySnapshot() if msgDe == nil { return nil, errTransportDetached } plain := msgDe(secretKey, data) if plain == nil && len(data) != 0 { return nil, errTransportPayloadDecryptFailed } return plain, nil } func (s *ServerCommon) decodeEnvelopePlain(data []byte) (Envelope, error) { msg, err := s.sequenceDe(data) if err != nil { return Envelope{}, err } env, ok := msg.(Envelope) if ok { return env, nil } transfer, ok := msg.(TransferMsg) if !ok { return Envelope{}, errors.New("invalid envelope") } wrapped, err := wrapTransferMsgEnvelope(transfer, s.sequenceEn) if err != nil { return Envelope{}, err } return wrapped, nil }