Search in sources :

Example 1 with DataMessage

use of net.java.otr4j.io.messages.DataMessage in project Zom-Android by zom.

the class SerializationUtils method toString.

// Message IO.
public static String toString(AbstractMessage m) throws IOException {
    StringWriter writer = new StringWriter();
    writer.write(SerializationConstants.HEAD);
    switch(m.messageType) {
        case AbstractMessage.MESSAGE_ERROR:
            ErrorMessage error = (ErrorMessage) m;
            writer.write(SerializationConstants.HEAD_ERROR);
            writer.write(error.error);
            break;
        case AbstractMessage.MESSAGE_PLAINTEXT:
            PlainTextMessage plaintxt = (PlainTextMessage) m;
            writer.write(plaintxt.cleanText);
            if (plaintxt.versions != null && plaintxt.versions.size() > 0) {
                writer.write(" \\t  \\t\\t\\t\\t \\t \\t \\t  ");
                for (int version : plaintxt.versions) {
                    if (version == 1)
                        writer.write("  \\t\\t  \\t ");
                    if (version == 2)
                        writer.write(" \\t \\t  \\t ");
                }
            }
            break;
        case AbstractMessage.MESSAGE_QUERY:
            QueryMessage query = (QueryMessage) m;
            if (query.versions.size() == 1 && query.versions.get(0) == 1) {
                writer.write(SerializationConstants.HEAD_QUERY_Q);
            } else {
                writer.write(SerializationConstants.HEAD_QUERY_V);
                for (int version : query.versions) writer.write(String.valueOf(version));
                writer.write(SerializationConstants.HEAD_QUERY_Q);
            }
            writer.write(OtrConstants.CommonRequest);
            break;
        case AbstractEncodedMessage.MESSAGE_DHKEY:
        case AbstractEncodedMessage.MESSAGE_REVEALSIG:
        case AbstractEncodedMessage.MESSAGE_SIGNATURE:
        case AbstractEncodedMessage.MESSAGE_DH_COMMIT:
        case AbstractEncodedMessage.MESSAGE_DATA:
            ByteArrayOutputStream o = new ByteArrayOutputStream();
            OtrOutputStream s = new OtrOutputStream(o);
            switch(m.messageType) {
                case AbstractEncodedMessage.MESSAGE_DHKEY:
                    DHKeyMessage dhkey = (DHKeyMessage) m;
                    s.writeShort(dhkey.protocolVersion);
                    s.writeByte(dhkey.messageType);
                    s.writeDHPublicKey(dhkey.dhPublicKey);
                    break;
                case AbstractEncodedMessage.MESSAGE_REVEALSIG:
                    RevealSignatureMessage revealsig = (RevealSignatureMessage) m;
                    s.writeShort(revealsig.protocolVersion);
                    s.writeByte(revealsig.messageType);
                    s.writeData(revealsig.revealedKey);
                    s.writeData(revealsig.xEncrypted);
                    s.writeMac(revealsig.xEncryptedMAC);
                    break;
                case AbstractEncodedMessage.MESSAGE_SIGNATURE:
                    SignatureMessage sig = (SignatureMessage) m;
                    s.writeShort(sig.protocolVersion);
                    s.writeByte(sig.messageType);
                    s.writeData(sig.xEncrypted);
                    s.writeMac(sig.xEncryptedMAC);
                    break;
                case AbstractEncodedMessage.MESSAGE_DH_COMMIT:
                    DHCommitMessage dhcommit = (DHCommitMessage) m;
                    s.writeShort(dhcommit.protocolVersion);
                    s.writeByte(dhcommit.messageType);
                    s.writeData(dhcommit.dhPublicKeyEncrypted);
                    s.writeData(dhcommit.dhPublicKeyHash);
                    break;
                case AbstractEncodedMessage.MESSAGE_DATA:
                    DataMessage data = (DataMessage) m;
                    s.writeShort(data.protocolVersion);
                    s.writeByte(data.messageType);
                    s.writeByte(data.flags);
                    s.writeInt(data.senderKeyID);
                    s.writeInt(data.recipientKeyID);
                    s.writeDHPublicKey(data.nextDH);
                    s.writeCtr(data.ctr);
                    s.writeData(data.encryptedMessage);
                    s.writeMac(data.mac);
                    s.writeData(data.oldMACKeys);
                    break;
            }
            writer.write(SerializationConstants.HEAD_ENCODED);
            writer.write(Base64.encodeToString(o.toByteArray(), Base64.NO_WRAP));
            writer.write(".");
            break;
        default:
            throw new IOException("Illegal message type.");
    }
    return writer.toString();
}
Also used : QueryMessage(net.java.otr4j.io.messages.QueryMessage) RevealSignatureMessage(net.java.otr4j.io.messages.RevealSignatureMessage) SignatureMessage(net.java.otr4j.io.messages.SignatureMessage) ByteArrayOutputStream(java.io.ByteArrayOutputStream) RevealSignatureMessage(net.java.otr4j.io.messages.RevealSignatureMessage) IOException(java.io.IOException) DHCommitMessage(net.java.otr4j.io.messages.DHCommitMessage) StringWriter(java.io.StringWriter) PlainTextMessage(net.java.otr4j.io.messages.PlainTextMessage) DataMessage(net.java.otr4j.io.messages.DataMessage) DHKeyMessage(net.java.otr4j.io.messages.DHKeyMessage) ErrorMessage(net.java.otr4j.io.messages.ErrorMessage)

Example 2 with DataMessage

use of net.java.otr4j.io.messages.DataMessage in project Zom-Android by zom.

the class SerializationUtils method toMessage.

public static AbstractMessage toMessage(String s) throws IOException {
    if (s == null || s.length() <= 1)
        return null;
    if (s.indexOf(SerializationConstants.HEAD) != 0 || s.length() <= SerializationConstants.HEAD.length()) {
        // Try to detect whitespace tag.
        final Matcher matcher = patternWhitespace.matcher(s);
        boolean v1 = false;
        boolean v2 = false;
        while (matcher.find()) {
            if (!v1 && matcher.start(2) > -1)
                v1 = true;
            if (!v2 && matcher.start(3) > -1)
                v2 = true;
            if (v1 && v2)
                break;
        }
        String cleanText = matcher.replaceAll("");
        List<Integer> versions;
        if (v1 && v2) {
            versions = new Vector<Integer>(2);
            versions.add(0, 1);
            versions.add(0, 2);
        } else if (v1) {
            versions = new Vector<Integer>(1);
            versions.add(0, 1);
        } else if (v2) {
            versions = new Vector<Integer>(1);
            versions.add(2);
        } else
            versions = null;
        return new PlainTextMessage(versions, cleanText);
    } else {
        char contentType = s.charAt(SerializationConstants.HEAD.length());
        String content = s.substring(SerializationConstants.HEAD.length() + 1);
        switch(contentType) {
            case SerializationConstants.HEAD_ENCODED:
                ByteArrayInputStream bin = new ByteArrayInputStream(Base64.decode(content, Base64.NO_WRAP));
                OtrInputStream otr = new OtrInputStream(bin);
                // We have an encoded message.
                int protocolVersion = otr.readShort();
                int messageType = otr.readByte();
                switch(messageType) {
                    case AbstractEncodedMessage.MESSAGE_DATA:
                        int flags = otr.readByte();
                        int senderKeyID = otr.readInt();
                        int recipientKeyID = otr.readInt();
                        DHPublicKey nextDH = otr.readDHPublicKey();
                        byte[] ctr = otr.readCtr();
                        byte[] encryptedMessage = otr.readData();
                        byte[] mac = otr.readMac();
                        byte[] oldMacKeys = otr.readMac();
                        return new DataMessage(protocolVersion, flags, senderKeyID, recipientKeyID, nextDH, ctr, encryptedMessage, mac, oldMacKeys);
                    case AbstractEncodedMessage.MESSAGE_DH_COMMIT:
                        byte[] dhPublicKeyEncrypted = otr.readData();
                        byte[] dhPublicKeyHash = otr.readData();
                        return new DHCommitMessage(protocolVersion, dhPublicKeyHash, dhPublicKeyEncrypted);
                    case AbstractEncodedMessage.MESSAGE_DHKEY:
                        DHPublicKey dhPublicKey = otr.readDHPublicKey();
                        return new DHKeyMessage(protocolVersion, dhPublicKey);
                    case AbstractEncodedMessage.MESSAGE_REVEALSIG:
                        {
                            byte[] revealedKey = otr.readData();
                            byte[] xEncrypted = otr.readData();
                            byte[] xEncryptedMac = otr.readMac();
                            return new RevealSignatureMessage(protocolVersion, xEncrypted, xEncryptedMac, revealedKey);
                        }
                    case AbstractEncodedMessage.MESSAGE_SIGNATURE:
                        {
                            byte[] xEncryted = otr.readData();
                            byte[] xEncryptedMac = otr.readMac();
                            return new SignatureMessage(protocolVersion, xEncryted, xEncryptedMac);
                        }
                    default:
                        throw new IOException("Illegal message type.");
                }
            case SerializationConstants.HEAD_MESSAGE:
                return new ErrorMessage(AbstractMessage.MESSAGE_ERROR, content);
            case SerializationConstants.HEAD_QUERY_V:
            case SerializationConstants.HEAD_QUERY_Q:
                List<Integer> versions = new Vector<Integer>();
                String versionString = null;
                if (SerializationConstants.HEAD_QUERY_Q == contentType) {
                    versions.add(1);
                    if (content.charAt(0) == 'v') {
                        versionString = content.substring(1, content.indexOf('?'));
                    }
                } else if (SerializationConstants.HEAD_QUERY_V == contentType) {
                    versionString = content.substring(0, content.indexOf('?'));
                }
                if (versionString != null) {
                    StringReader sr = new StringReader(versionString);
                    int c;
                    while ((c = sr.read()) != -1) if (!versions.contains(c))
                        versions.add(Integer.parseInt(String.valueOf((char) c)));
                }
                QueryMessage query = new QueryMessage(versions);
                return query;
            default:
                throw new IOException("Unknown message type.");
        }
    }
}
Also used : QueryMessage(net.java.otr4j.io.messages.QueryMessage) Matcher(java.util.regex.Matcher) DHPublicKey(javax.crypto.interfaces.DHPublicKey) RevealSignatureMessage(net.java.otr4j.io.messages.RevealSignatureMessage) SignatureMessage(net.java.otr4j.io.messages.SignatureMessage) RevealSignatureMessage(net.java.otr4j.io.messages.RevealSignatureMessage) IOException(java.io.IOException) BigInteger(java.math.BigInteger) DHCommitMessage(net.java.otr4j.io.messages.DHCommitMessage) ByteArrayInputStream(java.io.ByteArrayInputStream) PlainTextMessage(net.java.otr4j.io.messages.PlainTextMessage) DataMessage(net.java.otr4j.io.messages.DataMessage) StringReader(java.io.StringReader) DHKeyMessage(net.java.otr4j.io.messages.DHKeyMessage) ErrorMessage(net.java.otr4j.io.messages.ErrorMessage) Vector(java.util.Vector)

Example 3 with DataMessage

use of net.java.otr4j.io.messages.DataMessage in project Zom-Android by zom.

the class SessionImpl method transformSending.

// Retransmit last sent message. Spec document does not mention where or
// when that should happen, must check libotr code.
public String transformSending(String msgText, List<TLV> tlvs) throws OtrException {
    switch(this.getSessionStatus()) {
        case PLAINTEXT:
            if (getSessionPolicy().getRequireEncryption()) {
                lastSentMessage = msgText;
                doTransmitLastMessage = true;
                this.startSession();
                return null;
            } else
                // specification.
                return msgText;
        case ENCRYPTED:
            this.lastSentMessage = msgText;
            if (DEBUG_ENABLED)
                Log.d(LOG_TAG, getSessionID().getLocalUserId() + " sends an encrypted message to " + getSessionID().getRemoteUserId() + " through " + getSessionID().getProtocolName() + ".");
            // Get encryption keys.
            SessionKeys encryptionKeys = this.getEncryptionSessionKeys();
            int senderKeyID = encryptionKeys.getLocalKeyID();
            int receipientKeyID = encryptionKeys.getRemoteKeyID();
            // Increment CTR.
            encryptionKeys.incrementSendingCtr();
            byte[] ctr = encryptionKeys.getSendingCtr();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            if (msgText != null && msgText.length() > 0)
                try {
                    out.write(msgText.getBytes("UTF8"));
                } catch (IOException e) {
                    throw new OtrException(e);
                }
            // Append tlvs
            if (tlvs != null && tlvs.size() > 0) {
                out.write((byte) 0x00);
                OtrOutputStream eoos = new OtrOutputStream(out);
                for (TLV tlv : tlvs) {
                    try {
                        eoos.writeShort(tlv.type);
                        eoos.writeTlvData(tlv.value);
                        eoos.close();
                    } catch (IOException e) {
                        throw new OtrException(e);
                    }
                }
            }
            OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
            byte[] data = out.toByteArray();
            // Encrypt message.
            if (DEBUG_ENABLED)
                Log.d(LOG_TAG, "Encrypting message with keyids (localKeyID, remoteKeyID) = (" + senderKeyID + ", " + receipientKeyID + ")");
            byte[] encryptedMsg = otrCryptoEngine.aesEncrypt(encryptionKeys.getSendingAESKey(), ctr, data);
            // Get most recent keys to get the next D-H public key.
            SessionKeys mostRecentKeys = this.getMostRecentSessionKeys();
            DHPublicKey nextDH = (DHPublicKey) mostRecentKeys.getLocalPair().getPublic();
            // Calculate T.
            MysteriousT t = new MysteriousT(2, 0, senderKeyID, receipientKeyID, nextDH, ctr, encryptedMsg);
            // Calculate T hash.
            byte[] sendingMACKey = encryptionKeys.getSendingMACKey();
            if (DEBUG_ENABLED)
                Log.d(LOG_TAG, "Transforming T to byte[] to calculate it's HmacSHA1.");
            byte[] serializedT;
            try {
                serializedT = SerializationUtils.toByteArray(t);
            } catch (IOException e) {
                throw new OtrException(e);
            }
            byte[] mac = otrCryptoEngine.sha1Hmac(serializedT, sendingMACKey, SerializationConstants.TYPE_LEN_MAC);
            // Get old MAC keys to be revealed.
            byte[] oldKeys = this.collectOldMacKeys();
            DataMessage m = new DataMessage(t, mac, oldKeys);
            try {
                return SerializationUtils.toString(m);
            } catch (IOException e) {
                throw new OtrException(e);
            }
        case FINISHED:
            this.lastSentMessage = msgText;
            showError("Your message to " + sessionID.getRemoteUserId() + " was not sent.  Either end your private conversation, or restart it.");
            return null;
        default:
            if (DEBUG_ENABLED)
                Log.d(LOG_TAG, "Unknown message state, not processing.");
            return msgText;
    }
}
Also used : DHPublicKey(javax.crypto.interfaces.DHPublicKey) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) OtrException(net.java.otr4j.OtrException) OtrCryptoEngine(net.java.otr4j.crypto.OtrCryptoEngine) MysteriousT(net.java.otr4j.io.messages.MysteriousT) DataMessage(net.java.otr4j.io.messages.DataMessage) OtrCryptoEngineImpl(net.java.otr4j.crypto.OtrCryptoEngineImpl) OtrOutputStream(net.java.otr4j.io.OtrOutputStream)

Aggregations

IOException (java.io.IOException)3 DataMessage (net.java.otr4j.io.messages.DataMessage)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 DHPublicKey (javax.crypto.interfaces.DHPublicKey)2 DHCommitMessage (net.java.otr4j.io.messages.DHCommitMessage)2 DHKeyMessage (net.java.otr4j.io.messages.DHKeyMessage)2 ErrorMessage (net.java.otr4j.io.messages.ErrorMessage)2 PlainTextMessage (net.java.otr4j.io.messages.PlainTextMessage)2 QueryMessage (net.java.otr4j.io.messages.QueryMessage)2 RevealSignatureMessage (net.java.otr4j.io.messages.RevealSignatureMessage)2 SignatureMessage (net.java.otr4j.io.messages.SignatureMessage)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 StringReader (java.io.StringReader)1 StringWriter (java.io.StringWriter)1 BigInteger (java.math.BigInteger)1 Vector (java.util.Vector)1 Matcher (java.util.regex.Matcher)1 OtrException (net.java.otr4j.OtrException)1 OtrCryptoEngine (net.java.otr4j.crypto.OtrCryptoEngine)1 OtrCryptoEngineImpl (net.java.otr4j.crypto.OtrCryptoEngineImpl)1