// MsgRead creates a Bitmessage object from an unencrypted wire.MsgMsg. func MsgRead(msg *cipher.Message, toAddress string, ofChan bool) (*Bmail, error) { data := msg.Bitmessage() object := msg.Object() header := object.Header() sign, _ := data.SigningKey.ToBtcec() encr, _ := data.EncryptionKey.ToBtcec() from := identity.NewPublic(sign, encr, data.Pow, data.FromAddressVersion, data.FromStreamNumber) fromAddress, err := from.Address.Encode() if err != nil { return nil, err } return &Bmail{ From: bmToEmail(fromAddress), To: bmToEmail(toAddress), Expiration: header.Expiration(), Ack: msg.Ack(), OfChannel: ofChan, Content: data.Content, object: object.MsgObject(), }, nil }
// newMessage is called when a new message is received by the RPC client. // Messages are guaranteed to be received in ascending order of counter value. func (s *server) newMessage(counter uint64, object []byte) { // Store counter value. atomic.StoreUint64(&s.msgCounter, counter) msg := &obj.Message{} err := msg.Decode(bytes.NewReader(object)) if err != nil { serverLog.Errorf("Failed to decode message #%d from bytes: %v", counter, err) return // Ignore message. } // Check if message is smaller than expected. // IV + Curve params/X/Y + 1 block + HMAC-256 if len(msg.Encrypted) <= aes.BlockSize+70+aes.BlockSize+sha256.Size { return } // Is this an ack message we are expecting? for _, user := range s.imapUser { err = user.DeliverAckReply(object) if err == nil { return } } // Contains the address of the identity used to decrypt the message. var address string // Whether the message was received from a channel. var ofChan bool var id uint32 var message *cipher.Message // Try decrypting with all available identities. for uid, user := range s.users { err = user.Keys.ForEach(func(id *keymgr.PrivateID) error { var decryptErr error message, decryptErr = cipher.TryDecryptAndVerifyMessage(msg, &id.Private) if decryptErr == nil { address = id.Address() ofChan = id.IsChan //id = uid return errSuccessCode } return nil }) if err != nil { id = uid // Decryption successful. break } } if message == nil { // Decryption unsuccessful. return } // Decryption was successful. Add message to store. // TODO Store public key of the sender in bmagent // Read message. bmsg, err := email.MsgRead(message, address, ofChan) if err != nil { log.Errorf("Failed to decode message #%d: %v", counter, err) return } rpccLog.Trace("Bitmessage received from " + bmsg.From + " to " + bmsg.To) err = s.imapUser[id].DeliverFromBMNet(bmsg) if err != nil { log.Errorf("Failed to save message #%d: %v", counter, err) return } // Check if length of Ack is correct and message isn't from a channel. if message.Ack() == nil || len(message.Ack()) < wire.MessageHeaderSize || ofChan { return } // Send out ack if necessary. ack := message.Ack()[wire.MessageHeaderSize:] err = (&wire.MsgObject{}).Decode(bytes.NewReader(ack)) if err != nil { // Can't send invalid Ack. return } _, err = s.bmd.SendObject(ack) if err != nil { log.Infof("Failed to send ack for message #%d: %v", counter, err) return } }