예제 #1
0
def decodePublicKey(key):
    if len(key) != 33:
        raise WireFormatException(
            "The key field must contain 33 bytes of data.")

    try:
        key_type = ord(key[0])
    except TypeError:
        key_type = key[0]

    if key_type != KEY_TYPE_25519:
        raise WireFormatException("Unknown key type.")

    return key[1:]
예제 #2
0
    def messageFromWire(obj):
        # Due to the nature the mac is calculated by signal, the authentication
        # verification has to be done later in an additional step.

        # Remove the mac
        mac = obj[-MAC_SIZE:]
        obj = obj[:-MAC_SIZE]

        # Check and remove the version
        obj = checkVersion(obj)

        # Unpack the protobuf structure
        obj = wtp.SignalMessage.FromString(obj)

        if not (obj.HasField("dh_ratchet_key") and obj.HasField("n")
                and obj.HasField("ciphertext")):
            raise WireFormatException("Message incomplete.")

        return {
            "ciphertext":
            obj.ciphertext,
            "header":
            doubleratchet.Header(decodePublicKey(obj.dh_ratchet_key), obj.n,
                                 obj.pn),
            "additional":
            mac
        }
예제 #3
0
def checkVersion(data):
    try:
        version = ord(data[0])
    except TypeError:
        version = data[0]

    major_version = (version >> 4) & 0x0F
    minor_version = (version >> 0) & 0x0F

    if major_version < CURRENT_MAJOR_VERSION or minor_version < CURRENT_MINOR_VERSION:
        raise WireFormatException("Legacy version detected.")

    if major_version > CURRENT_MAJOR_VERSION or minor_version > CURRENT_MINOR_VERSION:
        raise WireFormatException("Newer/unknown version detected.")

    return data[1:]
예제 #4
0
    def finalizeMessageFromWire(obj, additional):
        dr_additional = additional["DoubleRatchet"]

        IK_own = dr_additional["ad"][:33]
        IK_other = dr_additional["ad"][33:]

        key = dr_additional["key"]
        mac = calculateMAC(obj[:-MAC_SIZE], key, IK_other, IK_own)

        if not additional["WireFormat"] == mac:
            raise WireFormatException("Message authentication failed.")
예제 #5
0
    def preKeyMessageFromWire(obj):
        obj = checkVersion(obj)

        obj = wtp.PreKeySignalMessage.FromString(obj)

        if not (obj.HasField("spk_id") and obj.HasField("ek")
                and obj.HasField("ik") and obj.HasField("signal_message")
                and obj.HasField("otpk_id")):
            raise WireFormatException("Pre key message incomplete.")

        return {
            "session_init_data": {
                "registration_id": obj.registration_id,
                "otpk_id": obj.otpk_id,
                "spk_id": obj.spk_id,
                "ek": decodePublicKey(obj.ek),
                "ik": decodePublicKey(obj.ik)
            },
            "message": obj.signal_message,
            "additional": None
        }