github.com/status-im/status-go@v1.1.0/server/pairing/payload_encryptor.go (about)

     1  package pairing
     2  
     3  import (
     4  	"crypto/rand"
     5  
     6  	"github.com/status-im/status-go/protocol/common"
     7  )
     8  
     9  // EncryptionPayload represents the plain text and encrypted text of payload data
    10  type EncryptionPayload struct {
    11  	plain     []byte
    12  	encrypted []byte
    13  	locked    bool
    14  }
    15  
    16  func (ep *EncryptionPayload) lock() {
    17  	ep.locked = true
    18  }
    19  
    20  // PayloadEncryptor is responsible for encrypting and decrypting payload data
    21  type PayloadEncryptor struct {
    22  	aesKey  []byte
    23  	payload *EncryptionPayload
    24  }
    25  
    26  func NewPayloadEncryptor(aesKey []byte) *PayloadEncryptor {
    27  	return &PayloadEncryptor{
    28  		aesKey,
    29  		new(EncryptionPayload),
    30  	}
    31  }
    32  
    33  // Renew regenerates the whole PayloadEncryptor and returns the new instance, only the aesKey is preserved
    34  func (pem *PayloadEncryptor) Renew() *PayloadEncryptor {
    35  	return &PayloadEncryptor{
    36  		aesKey:  pem.aesKey,
    37  		payload: new(EncryptionPayload),
    38  	}
    39  }
    40  
    41  // encryptPlain encrypts any given plain text using the internal AES key and returns the encrypted value
    42  // This function is different to Encrypt as the internal EncryptionPayload.encrypted value is not set
    43  func (pem *PayloadEncryptor) encryptPlain(plaintext []byte) ([]byte, error) {
    44  	return common.Encrypt(plaintext, pem.aesKey, rand.Reader)
    45  }
    46  
    47  // decryptPlain decrypts any given plain text using the internal AES key and returns the encrypted value
    48  // This function is different to Decrypt as the internal EncryptionPayload.plain value is not set
    49  func (pem *PayloadEncryptor) decryptPlain(plaintext []byte) ([]byte, error) {
    50  	return common.Decrypt(plaintext, pem.aesKey)
    51  }
    52  
    53  func (pem *PayloadEncryptor) encrypt(data []byte) error {
    54  	ep, err := common.Encrypt(data, pem.aesKey, rand.Reader)
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	pem.payload.plain = data
    60  	pem.payload.encrypted = ep
    61  	return nil
    62  }
    63  
    64  func (pem *PayloadEncryptor) decrypt(data []byte) error {
    65  	pd, err := common.Decrypt(data, pem.aesKey)
    66  	if err != nil {
    67  		return err
    68  	}
    69  
    70  	pem.payload.encrypted = data
    71  	pem.payload.plain = pd
    72  	return nil
    73  }
    74  
    75  func (pem *PayloadEncryptor) getEncrypted() []byte {
    76  	if pem.payload.locked {
    77  		return nil
    78  	}
    79  	return pem.payload.encrypted
    80  }
    81  
    82  func (pem *PayloadEncryptor) getDecrypted() []byte {
    83  	if pem.payload.locked {
    84  		return nil
    85  	}
    86  	return pem.payload.plain
    87  }
    88  
    89  func (pem *PayloadEncryptor) lockPayload() {
    90  	pem.payload.lock()
    91  }
    92  
    93  // PayloadLockPayload Embeds a *PayloadEncryptor to give all embedding structs EncryptionPayload Locking
    94  type PayloadLockPayload struct {
    95  	*PayloadEncryptor
    96  }
    97  
    98  func (pl *PayloadLockPayload) LockPayload() {
    99  	pl.lockPayload()
   100  }
   101  
   102  // PayloadToSend Embeds a *PayloadEncryptor to give all embedding structs EncryptionPayload ToSend() functionality
   103  // Useful to securely implement the PayloadMounter interface
   104  type PayloadToSend struct {
   105  	*PayloadEncryptor
   106  }
   107  
   108  func (pts *PayloadToSend) ToSend() []byte {
   109  	return pts.getEncrypted()
   110  }
   111  
   112  // PayloadReceived Embeds a *PayloadEncryptor to give all embedding structs EncryptionPayload Received() functionality
   113  // Useful to securely implement the PayloadReceiver interface
   114  type PayloadReceived struct {
   115  	*PayloadEncryptor
   116  }
   117  
   118  func (pr *PayloadReceived) Received() []byte {
   119  	return pr.getDecrypted()
   120  }