Search in sources :

Example 6 with OtrCryptoEngineImpl

use of net.java.otr4j.crypto.OtrCryptoEngineImpl in project Conversations by siacs.

the class Account method getOtrFingerprint.

public String getOtrFingerprint() {
    if (this.otrFingerprint == null) {
        try {
            if (this.mOtrService == null) {
                return null;
            }
            final PublicKey publicKey = this.mOtrService.getPublicKey();
            if (publicKey == null || !(publicKey instanceof DSAPublicKey)) {
                return null;
            }
            this.otrFingerprint = new OtrCryptoEngineImpl().getFingerprint(publicKey).toLowerCase(Locale.US);
            return this.otrFingerprint;
        } catch (final OtrCryptoException ignored) {
            return null;
        }
    } else {
        return this.otrFingerprint;
    }
}
Also used : OtrCryptoException(net.java.otr4j.crypto.OtrCryptoException) PublicKey(java.security.PublicKey) DSAPublicKey(java.security.interfaces.DSAPublicKey) OtrCryptoEngineImpl(net.java.otr4j.crypto.OtrCryptoEngineImpl) DSAPublicKey(java.security.interfaces.DSAPublicKey)

Example 7 with OtrCryptoEngineImpl

use of net.java.otr4j.crypto.OtrCryptoEngineImpl 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)

Example 8 with OtrCryptoEngineImpl

use of net.java.otr4j.crypto.OtrCryptoEngineImpl in project Zom-Android by zom.

the class SessionImpl method handleDataMessage.

private synchronized String handleDataMessage(DataMessage data, List<TLV> tlvs) throws OtrException {
    if (DEBUG_ENABLED)
        Log.d(LOG_TAG, getSessionID().getLocalUserId() + " received a data message from " + getSessionID().getRemoteUserId() + ".");
    switch(this.getSessionStatus()) {
        case ENCRYPTED:
            if (DEBUG_ENABLED)
                Log.d(LOG_TAG, "Message state is ENCRYPTED. Trying to decrypt message.");
            // Find matching session keys.
            int senderKeyID = data.senderKeyID;
            int receipientKeyID = data.recipientKeyID;
            SessionKeys matchingKeys = this.getSessionKeysByID(receipientKeyID, senderKeyID);
            if (matchingKeys == null) {
                throw new OtrException("no matching keys found");
            }
            // Verify received MAC with a locally calculated MAC.
            if (DEBUG_ENABLED)
                Log.d(LOG_TAG, "Transforming T to byte[] to calculate it's HmacSHA1.");
            byte[] serializedT;
            try {
                serializedT = SerializationUtils.toByteArray(data.getT());
            } catch (IOException e) {
                throw new OtrException(e);
            }
            OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
            byte[] computedMAC = otrCryptoEngine.sha1Hmac(serializedT, matchingKeys.getReceivingMACKey(), SerializationConstants.TYPE_LEN_MAC);
            String decryptedMsgContent = null;
            if (!Arrays.equals(computedMAC, data.mac)) {
                // throw new OtrException("MAC verification failed, ignoring message");
                if (DEBUG_ENABLED)
                    Log.d(LOG_TAG, "MAC verification failed, ignoring message");
            } else {
                if (DEBUG_ENABLED)
                    Log.d(LOG_TAG, "Computed HmacSHA1 value matches sent one.");
                // Mark this MAC key as old to be revealed.
                matchingKeys.setIsUsedReceivingMACKey(true);
                matchingKeys.setReceivingCtr(data.ctr);
                byte[] dmc = otrCryptoEngine.aesDecrypt(matchingKeys.getReceivingAESKey(), matchingKeys.getReceivingCtr(), data.encryptedMessage);
                try {
                    // Expect bytes to be text encoded in UTF-8.
                    decryptedMsgContent = new String(dmc, "UTF-8");
                    if (DEBUG_ENABLED)
                        Log.d(LOG_TAG, "Decrypted message: \"" + decryptedMsgContent + "\"");
                    // Handle TLVs
                    if (tlvs == null) {
                        tlvs = new ArrayList<TLV>();
                    }
                    int tlvIndex = decryptedMsgContent.indexOf((char) 0x0);
                    if (tlvIndex > -1) {
                        decryptedMsgContent = decryptedMsgContent.substring(0, tlvIndex);
                        tlvIndex++;
                        byte[] tlvsb = new byte[dmc.length - tlvIndex];
                        System.arraycopy(dmc, tlvIndex, tlvsb, 0, tlvsb.length);
                        ByteArrayInputStream tin = new ByteArrayInputStream(tlvsb);
                        while (tin.available() > 0) {
                            int type;
                            byte[] tdata;
                            OtrInputStream eois = new OtrInputStream(tin);
                            try {
                                type = eois.readShort();
                                tdata = eois.readTlvData();
                                eois.close();
                            } catch (IOException e) {
                                throw new OtrException(e);
                            }
                            tlvs.add(new TLV(type, tdata));
                        }
                    }
                    if (tlvs.size() > 0) {
                        for (TLV tlv : tlvs) {
                            switch(tlv.getType()) {
                                case TLV.DISCONNECTED:
                                    this.setSessionStatus(SessionStatus.FINISHED);
                                    return null;
                                default:
                                    for (OtrTlvHandler handler : tlvHandlers) {
                                        handler.processTlv(tlv);
                                    }
                            }
                        }
                    }
                } catch (UnsupportedEncodingException e) {
                    // throw new OtrException(e);
                    if (DEBUG_ENABLED)
                        Log.e(LOG_TAG, "unsupported encoding exception", e);
                }
            }
            // Rotate keys if necessary.
            SessionKeys mostRecent = this.getMostRecentSessionKeys();
            if (mostRecent.getLocalKeyID() == receipientKeyID)
                this.rotateLocalSessionKeys();
            if (mostRecent.getRemoteKeyID() == senderKeyID)
                this.rotateRemoteSessionKeys(data.nextDH);
            return decryptedMsgContent;
        case FINISHED:
        case PLAINTEXT:
            showError("Unreadable encrypted message was received.");
            refreshSession();
            // "You sent me an unreadable encrypted message"));
            throw new OtrException("Unreadable encrypted message received");
    }
    return null;
}
Also used : OtrInputStream(net.java.otr4j.io.OtrInputStream) UnsupportedEncodingException(java.io.UnsupportedEncodingException) OtrException(net.java.otr4j.OtrException) IOException(java.io.IOException) OtrCryptoEngine(net.java.otr4j.crypto.OtrCryptoEngine) ByteArrayInputStream(java.io.ByteArrayInputStream) OtrTlvHandler(net.java.otr4j.crypto.OtrTlvHandler) OtrCryptoEngineImpl(net.java.otr4j.crypto.OtrCryptoEngineImpl)

Example 9 with OtrCryptoEngineImpl

use of net.java.otr4j.crypto.OtrCryptoEngineImpl in project Zom-Android by zom.

the class SessionImpl method rotateLocalSessionKeys.

private void rotateLocalSessionKeys() throws OtrException {
    if (DEBUG_ENABLED)
        Log.d(LOG_TAG, "Rotating local keys.");
    SessionKeys sess1 = getSessionKeysByIndex(SessionKeys.Previous, SessionKeys.Current);
    if (sess1.getIsUsedReceivingMACKey()) {
        if (DEBUG_ENABLED)
            Log.d(LOG_TAG, "Detected used Receiving MAC key. Adding to old MAC keys to reveal it.");
        getOldMacKeys().add(sess1.getReceivingMACKey());
    }
    SessionKeys sess2 = getSessionKeysByIndex(SessionKeys.Previous, SessionKeys.Previous);
    if (sess2.getIsUsedReceivingMACKey()) {
        if (DEBUG_ENABLED)
            Log.d(LOG_TAG, "Detected used Receiving MAC key. Adding to old MAC keys to reveal it.");
        getOldMacKeys().add(sess2.getReceivingMACKey());
    }
    SessionKeys sess3 = getSessionKeysByIndex(SessionKeys.Current, SessionKeys.Current);
    sess1.setLocalPair(sess3.getLocalPair(), sess3.getLocalKeyID());
    SessionKeys sess4 = getSessionKeysByIndex(SessionKeys.Current, SessionKeys.Previous);
    sess2.setLocalPair(sess4.getLocalPair(), sess4.getLocalKeyID());
    KeyPair newPair = new OtrCryptoEngineImpl().generateDHKeyPair();
    sess3.setLocalPair(newPair, sess3.getLocalKeyID() + 1);
    sess4.setLocalPair(newPair, sess4.getLocalKeyID() + 1);
}
Also used : KeyPair(java.security.KeyPair) OtrCryptoEngineImpl(net.java.otr4j.crypto.OtrCryptoEngineImpl)

Example 10 with OtrCryptoEngineImpl

use of net.java.otr4j.crypto.OtrCryptoEngineImpl in project Zom-Android by zom.

the class SessionImpl method setSessionStatus.

private void setSessionStatus(SessionStatus sessionStatusNew) throws OtrException {
    boolean sessionStatusChanged = (sessionStatus != sessionStatusNew);
    sessionStatus = sessionStatusNew;
    switch(sessionStatus) {
        case ENCRYPTED:
            AuthContext auth = this.getAuthContext(false);
            ess = auth.getS();
            if (DEBUG_ENABLED)
                Log.d(LOG_TAG, "Setting most recent session keys from auth.");
            for (int i = 0; i < this.getSessionKeys()[0].length; i++) {
                SessionKeys current = getSessionKeysByIndex(0, i);
                current.setLocalPair(auth.getLocalDHKeyPair(), 1);
                current.setRemoteDHPublicKey(auth.getRemoteDHPublicKey(), 1);
                current.setS(auth.getS());
            }
            KeyPair nextDH = new OtrCryptoEngineImpl().generateDHKeyPair();
            for (int i = 0; i < this.getSessionKeys()[1].length; i++) {
                SessionKeys current = getSessionKeysByIndex(1, i);
                current.setRemoteDHPublicKey(auth.getRemoteDHPublicKey(), 1);
                current.setLocalPair(nextDH, 2);
            }
            this.setRemotePublicKey(auth.getRemoteLongTermPublicKey());
            auth.reset();
            break;
        case PLAINTEXT:
            // nothing here
            break;
        default:
    }
    if (sessionStatus == SessionStatus.ENCRYPTED && doTransmitLastMessage && lastSentMessage != null) {
        // String retransmit = (isLastMessageRetransmit ? "[resent] " : "");
        String msg = transformSending(lastSentMessage, null);
        getHost().injectMessage(getSessionID(), msg);
        sessionStatusChanged = true;
    }
    doTransmitLastMessage = false;
    isLastMessageRetransmit = false;
    lastSentMessage = null;
    if (sessionStatusChanged) {
        for (OtrEngineListener l : this.listeners) l.sessionStatusChanged(getSessionID());
    }
}
Also used : KeyPair(java.security.KeyPair) OtrCryptoEngineImpl(net.java.otr4j.crypto.OtrCryptoEngineImpl) OtrEngineListener(net.java.otr4j.OtrEngineListener)

Aggregations

OtrCryptoEngineImpl (net.java.otr4j.crypto.OtrCryptoEngineImpl)19 PublicKey (java.security.PublicKey)8 OtrException (net.java.otr4j.OtrException)8 KeyPair (java.security.KeyPair)7 OtrCryptoException (net.java.otr4j.crypto.OtrCryptoException)7 IOException (java.io.IOException)6 DHPublicKey (javax.crypto.interfaces.DHPublicKey)5 OtrCryptoEngine (net.java.otr4j.crypto.OtrCryptoEngine)5 ByteArrayInputStream (java.io.ByteArrayInputStream)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 OtrInputStream (net.java.otr4j.io.OtrInputStream)3 OtrOutputStream (net.java.otr4j.io.OtrOutputStream)3 BigInteger (java.math.BigInteger)2 ByteBuffer (java.nio.ByteBuffer)2 DSAPublicKey (java.security.interfaces.DSAPublicKey)2 SignatureM (net.java.otr4j.io.messages.SignatureM)2 SignatureX (net.java.otr4j.io.messages.SignatureX)2 AbstractChat (com.xabber.android.data.message.AbstractChat)1 RegularChat (com.xabber.android.data.message.RegularChat)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1