121 lines
3.0 KiB
Go
121 lines
3.0 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
|
|
}
|
|
|
|
// 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()
|
|
}
|
|
|
|
// PayloadLockPayload Embeds a *PayloadEncryptor to give all embedding structs EncryptionPayload Locking
|
|
type PayloadLockPayload struct {
|
|
*PayloadEncryptor
|
|
}
|
|
|
|
func (pl *PayloadLockPayload) LockPayload() {
|
|
pl.lockPayload()
|
|
}
|
|
|
|
// PayloadToSend Embeds a *PayloadEncryptor to give all embedding structs EncryptionPayload ToSend() functionality
|
|
// Useful to securely implement the PayloadMounter interface
|
|
type PayloadToSend struct {
|
|
*PayloadEncryptor
|
|
}
|
|
|
|
func (pts *PayloadToSend) ToSend() []byte {
|
|
return pts.getEncrypted()
|
|
}
|
|
|
|
// PayloadReceived Embeds a *PayloadEncryptor to give all embedding structs EncryptionPayload Received() functionality
|
|
// Useful to securely implement the PayloadReceiver interface
|
|
type PayloadReceived struct {
|
|
*PayloadEncryptor
|
|
}
|
|
|
|
func (pr *PayloadReceived) Received() []byte {
|
|
return pr.getDecrypted()
|
|
}
|