github.com/status-im/status-go@v1.1.0/protocol/identity_images.go (about) 1 package protocol 2 3 import ( 4 "crypto/ecdsa" 5 crand "crypto/rand" 6 "errors" 7 8 "github.com/status-im/status-go/protocol/common" 9 "github.com/status-im/status-go/protocol/protobuf" 10 ) 11 12 var ErrCipherMessageAutentificationFailed = "cipher: message authentication failed" 13 14 func EncryptIdentityImagesWithContactPubKeys(iis map[string]*protobuf.IdentityImage, m *Messenger) (err error) { 15 // Make AES key 16 AESKey := make([]byte, 32) 17 _, err = crand.Read(AESKey) 18 if err != nil { 19 return err 20 } 21 22 for _, ii := range iis { 23 // Encrypt image payload with the AES key 24 var encryptedPayload []byte 25 encryptedPayload, err = common.Encrypt(ii.Payload, AESKey, crand.Reader) 26 if err != nil { 27 return err 28 } 29 30 // Overwrite the unencrypted payload with the newly encrypted payload 31 ii.Payload = encryptedPayload 32 ii.Encrypted = true 33 m.allContacts.Range(func(contactID string, contact *Contact) (shouldContinue bool) { 34 if !contact.added() { 35 return true 36 } 37 var pubK *ecdsa.PublicKey 38 var sharedKey []byte 39 var eAESKey []byte 40 41 pubK, err = contact.PublicKey() 42 if err != nil { 43 return false 44 } 45 // Generate a Diffie-Helman (DH) between the sender private key and the recipient's public key 46 sharedKey, err = common.MakeECDHSharedKey(m.identity, pubK) 47 if err != nil { 48 return false 49 } 50 51 // Encrypt the main AES key with AES encryption using the DH key 52 eAESKey, err = common.Encrypt(AESKey, sharedKey, crand.Reader) 53 if err != nil { 54 return false 55 } 56 57 // Append the the encrypted main AES key to the IdentityImage's EncryptionKeys slice. 58 ii.EncryptionKeys = append(ii.EncryptionKeys, eAESKey) 59 return true 60 }) 61 if err != nil { 62 return err 63 } 64 } 65 66 return nil 67 } 68 69 func DecryptIdentityImagesWithIdentityPrivateKey(iis map[string]*protobuf.IdentityImage, recipientIdentity *ecdsa.PrivateKey, senderPubKey *ecdsa.PublicKey) error { 70 image: 71 for _, ii := range iis { 72 for _, empk := range ii.EncryptionKeys { 73 // Generate a Diffie-Helman (DH) between the recipient's private key and the sender's public key 74 sharedKey, err := common.MakeECDHSharedKey(recipientIdentity, senderPubKey) 75 if err != nil { 76 return err 77 } 78 79 // Decrypt the main encryption AES key with AES encryption using the DH key 80 dAESKey, err := common.Decrypt(empk, sharedKey) 81 if err != nil { 82 if err.Error() == ErrCipherMessageAutentificationFailed { 83 continue 84 } 85 return err 86 } 87 if dAESKey == nil { 88 return errors.New("decrypting the payload encryption key resulted in no error and a nil key") 89 } 90 91 // Decrypt the payload with the newly decrypted main encryption AES key 92 payload, err := common.Decrypt(ii.Payload, dAESKey) 93 if err != nil { 94 return err 95 } 96 if payload == nil { 97 // TODO should this be a logger warn? A payload could theoretically be validly empty 98 return errors.New("decrypting the payload resulted in no error and a nil payload") 99 } 100 101 // Overwrite the payload with the decrypted data 102 ii.Payload = payload 103 ii.Encrypted = false 104 continue image 105 } 106 } 107 108 return nil 109 }