Example #1
0
func buildMessage(msg *outgoingMessage, devices []uint32) ([]jsonMessage, error) {
	paddedMessage, err := createMessage(msg)
	if err != nil {
		return nil, err
	}
	recid := recID(msg.tel)
	messages := []jsonMessage{}

	for _, devid := range devices {
		if !textSecureStore.ContainsSession(recid, devid) {
			pkb, err := makePreKeyBundle(msg.tel, devid)
			if err != nil {
				return nil, err
			}
			sb := axolotl.NewSessionBuilder(textSecureStore, textSecureStore, textSecureStore, textSecureStore, recid, pkb.DeviceID)
			err = sb.BuildSenderSession(pkb)
			if err != nil {
				return nil, err
			}
		}
		sc := axolotl.NewSessionCipher(textSecureStore, textSecureStore, textSecureStore, textSecureStore, recid, devid)
		encryptedMessage, messageType, err := sc.SessionEncryptMessage(paddedMessage)
		if err != nil {
			return nil, err
		}

		rrID, err := sc.GetRemoteRegistrationID()
		if err != nil {
			return nil, err
		}
		messages = append(messages, jsonMessage{
			Type:               messageType,
			DestDeviceID:       devid,
			DestRegistrationID: rrID,
			Body:               base64.StdEncoding.EncodeToString(encryptedMessage),
		})
	}

	return messages, nil
}
Example #2
0
// Authenticate and decrypt a received message
func handleReceivedMessage(msg []byte) error {
	macpos := len(msg) - 10
	tmac := msg[macpos:]
	aesKey := registrationInfo.signalingKey[:32]
	macKey := registrationInfo.signalingKey[32:]
	if !axolotl.ValidTruncMAC(msg[:macpos], tmac, macKey) {
		return errors.New("Invalid MAC for Incoming Message")
	}
	ciphertext := msg[1:macpos]

	plaintext, err := axolotl.Decrypt(aesKey, ciphertext)
	if err != nil {
		return err
	}
	env := &textsecure.Envelope{}
	err = proto.Unmarshal(plaintext, env)
	if err != nil {
		return err
	}

	recid := recID(env.GetSource())
	sc := axolotl.NewSessionCipher(textSecureStore, textSecureStore, textSecureStore, textSecureStore, recid, env.GetSourceDevice())
	switch *env.Type {
	case textsecure.Envelope_RECEIPT:
		handleReceipt(env)
		return nil
	case textsecure.Envelope_CIPHERTEXT:
		msg, legacy := getMessage(env)
		wm, err := axolotl.LoadWhisperMessage(msg)
		if err != nil {
			return err
		}
		b, err := sc.SessionDecryptWhisperMessage(wm)
		if err != nil {
			return err
		}
		err = handleMessage(env.GetSource(), env.GetTimestamp(), b, legacy)
		if err != nil {
			return err
		}

	case textsecure.Envelope_PREKEY_BUNDLE:
		msg, legacy := getMessage(env)
		pkwm, err := axolotl.LoadPreKeyWhisperMessage(msg)
		if err != nil {
			return err
		}
		b, err := sc.SessionDecryptPreKeyWhisperMessage(pkwm)
		if err != nil {
			return err
		}
		err = handleMessage(env.GetSource(), env.GetTimestamp(), b, legacy)
		if err != nil {
			return err
		}
	default:
		return fmt.Errorf("Not implemented %d", *env.Type)
	}

	return nil
}
// Authenticate and decrypt a received message
func handleReceivedMessage(msg []byte) error {
	macpos := len(msg) - 10
	tmac := msg[macpos:]
	aesKey := registrationInfo.signalingKey[:32]
	macKey := registrationInfo.signalingKey[32:]
	if !axolotl.ValidTruncMAC(msg[:macpos], tmac, macKey) {
		return ErrInvalidMACForMessage
	}
	ciphertext := msg[1:macpos]

	plaintext, err := axolotl.Decrypt(aesKey, ciphertext)
	if err != nil {
		return err
	}
	env := &textsecure.Envelope{}
	err = proto.Unmarshal(plaintext, env)
	if err != nil {
		return err
	}

	recid := recID(env.GetSource())
	sc := axolotl.NewSessionCipher(textSecureStore, textSecureStore, textSecureStore, textSecureStore, recid, env.GetSourceDevice())
	switch *env.Type {
	case textsecure.Envelope_RECEIPT:
		handleReceipt(env)
		return nil
	case textsecure.Envelope_CIPHERTEXT:
		msg, legacy := getMessage(env)
		wm, err := axolotl.LoadWhisperMessage(msg)
		if err != nil {
			return err
		}
		b, err := sc.SessionDecryptWhisperMessage(wm)
		if _, ok := err.(axolotl.DuplicateMessageError); ok {
			log.Infof("Incoming WhisperMessage %s. Ignoring.\n", err)
			return nil
		}
		if _, ok := err.(axolotl.InvalidMessageError); ok {
			log.Infof("Incoming WhisperMessage %s. Ignoring.\n", err)
			return nil
		}
		if err != nil {
			return err
		}
		err = handleMessage(env.GetSource(), env.GetTimestamp(), b, legacy)
		if err != nil {
			return err
		}

	case textsecure.Envelope_PREKEY_BUNDLE:
		msg, legacy := getMessage(env)
		pkwm, err := axolotl.LoadPreKeyWhisperMessage(msg)
		if err != nil {
			return err
		}
		b, err := sc.SessionDecryptPreKeyWhisperMessage(pkwm)
		if _, ok := err.(axolotl.DuplicateMessageError); ok {
			log.Infof("Incoming PreKeyWhisperMessage %s. Ignoring.\n", err)
			return nil
		}
		if _, ok := err.(axolotl.PreKeyNotFoundError); ok {
			log.Infof("Incoming PreKeyWhisperMessage %s. Ignoring.\n", err)
			return nil
		}
		if _, ok := err.(axolotl.InvalidMessageError); ok {
			log.Infof("Incoming PreKeyWhisperMessage %s. Ignoring.\n", err)
			return nil
		}
		if err != nil {
			return err
		}
		err = handleMessage(env.GetSource(), env.GetTimestamp(), b, legacy)
		if err != nil {
			return err
		}
	default:
		return MessageTypeNotImplementedError{uint32(*env.Type)}
	}

	return nil
}