status-go/server/pairing/payload_encryptor.go
Samuel Hawksby-Robinson 7cd7430d31
Improved Local Pairing Separation of Concerns (#3248)
* Moved all configs into config.go

* Completed build out of new config structures

* Completed SenderClient process flow

* Completed sync data Mounter and client integration

* Completed installation data Mounter and client integration

* House keeping, small refactor to match conventions.

PayloadEncryptor is passed by value and used as a pointer to the instance value and not a shared pointer.

* Reintroduced explicit Mounter field type

* Completed ReceiverClient structs and flows

* Finished BaseClient function parity with old acc

* Integrated new Clients into tests

Solved some test breaks caused by encryptors sharing pointers to their managed payloads

* Built out SenderServer and ReceiverServer structs

With all associated functions and integrated with endpoints.

* Updated tests to handle new Server types

* Added docs and additional refinement

* Renamed some files to better match the content of those files

* Added json tags to config fields that were missing explicit tags.

* fix tests relating to payload locking

* Addressing feedback from @ilmotta

* Addressed feedback from @qfrank
2023-03-23 11:44:15 +00:00

95 lines
2.4 KiB
Go

package pairing
import (
"crypto/rand"
"github.com/status-im/status-go/protocol/common"
)
// EncryptionPayload represents the plain text and encrypted text of payload data
type EncryptionPayload struct {
plain []byte
encrypted []byte
locked bool
}
func (ep *EncryptionPayload) lock() {
ep.locked = true
}
// TODO resolve the many cases of other structs simply wrapping their encryptor rather than embedding the functionality
// https://github.com/status-im/status-go/issues/3302
// PayloadEncryptor is responsible for encrypting and decrypting payload data
type PayloadEncryptor struct {
aesKey []byte
payload *EncryptionPayload
}
func NewPayloadEncryptor(aesKey []byte) *PayloadEncryptor {
return &PayloadEncryptor{
aesKey,
new(EncryptionPayload),
}
}
// Renew regenerates the whole PayloadEncryptor and returns the new instance, only the aesKey is preserved
func (pem *PayloadEncryptor) Renew() *PayloadEncryptor {
return &PayloadEncryptor{
aesKey: pem.aesKey,
payload: new(EncryptionPayload),
}
}
// encryptPlain encrypts any given plain text using the internal AES key and returns the encrypted value
// This function is different to Encrypt as the internal EncryptionPayload.encrypted value is not set
func (pem *PayloadEncryptor) encryptPlain(plaintext []byte) ([]byte, error) {
return common.Encrypt(plaintext, pem.aesKey, rand.Reader)
}
// decryptPlain decrypts any given plain text using the internal AES key and returns the encrypted value
// This function is different to Decrypt as the internal EncryptionPayload.plain value is not set
func (pem *PayloadEncryptor) decryptPlain(plaintext []byte) ([]byte, error) {
return common.Decrypt(plaintext, pem.aesKey)
}
func (pem *PayloadEncryptor) encrypt(data []byte) error {
ep, err := common.Encrypt(data, pem.aesKey, rand.Reader)
if err != nil {
return err
}
pem.payload.plain = data
pem.payload.encrypted = ep
return nil
}
func (pem *PayloadEncryptor) decrypt(data []byte) error {
pd, err := common.Decrypt(data, pem.aesKey)
if err != nil {
return err
}
pem.payload.encrypted = data
pem.payload.plain = pd
return nil
}
func (pem *PayloadEncryptor) getEncrypted() []byte {
if pem.payload.locked {
return nil
}
return pem.payload.encrypted
}
func (pem *PayloadEncryptor) getDecrypted() []byte {
if pem.payload.locked {
return nil
}
return pem.payload.plain
}
func (pem *PayloadEncryptor) lockPayload() {
pem.payload.lock()
}