Search in sources :

Example 21 with DHPublicKey

use of javax.crypto.interfaces.DHPublicKey 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 22 with DHPublicKey

use of javax.crypto.interfaces.DHPublicKey in project Zom-Android by zom.

the class IOTest method testIODHPublicKey.

public void testIODHPublicKey() throws Exception {
    KeyPair pair = new OtrCryptoEngineImpl().generateDHKeyPair();
    DHPublicKey source = (DHPublicKey) pair.getPublic();
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    OtrOutputStream oos = new OtrOutputStream(out);
    oos.writeDHPublicKey(source);
    oos.close();
    byte[] converted = out.toByteArray();
    ByteArrayInputStream bin = new ByteArrayInputStream(converted);
    OtrInputStream ois = new OtrInputStream(bin);
    DHPublicKey result = ois.readDHPublicKey();
    ois.close();
    assertTrue(source.getY().compareTo(result.getY()) == 0);
}
Also used : KeyPair(java.security.KeyPair) DHPublicKey(javax.crypto.interfaces.DHPublicKey) ByteArrayInputStream(java.io.ByteArrayInputStream) OtrInputStream(net.java.otr4j.io.OtrInputStream) OtrCryptoEngineImpl(net.java.otr4j.crypto.OtrCryptoEngineImpl) OtrOutputStream(net.java.otr4j.io.OtrOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream)

Example 23 with DHPublicKey

use of javax.crypto.interfaces.DHPublicKey in project Zom-Android by zom.

the class IOTest method testIOBigInt.

public void testIOBigInt() throws Exception {
    KeyPair pair = new OtrCryptoEngineImpl().generateDHKeyPair();
    BigInteger source = ((DHPublicKey) pair.getPublic()).getY();
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    OtrOutputStream oos = new OtrOutputStream(out);
    oos.writeBigInt(source);
    oos.close();
    byte[] converted = out.toByteArray();
    ByteArrayInputStream bin = new ByteArrayInputStream(converted);
    OtrInputStream ois = new OtrInputStream(bin);
    BigInteger result = ois.readBigInt();
    ois.close();
    assertTrue(source.compareTo(result) == 0);
}
Also used : KeyPair(java.security.KeyPair) DHPublicKey(javax.crypto.interfaces.DHPublicKey) ByteArrayInputStream(java.io.ByteArrayInputStream) OtrInputStream(net.java.otr4j.io.OtrInputStream) OtrCryptoEngineImpl(net.java.otr4j.crypto.OtrCryptoEngineImpl) BigInteger(java.math.BigInteger) OtrOutputStream(net.java.otr4j.io.OtrOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream)

Example 24 with DHPublicKey

use of javax.crypto.interfaces.DHPublicKey in project Zom-Android by zom.

the class AuthContextImpl method handleRevealSignatureMessage.

private void handleRevealSignatureMessage(RevealSignatureMessage m) throws OtrException {
    Session session = getSession();
    SessionID sessionID = session.getSessionID();
    logger.finest(sessionID.getLocalUserId() + " received a reveal signature message from " + sessionID.getRemoteUserId() + " throught " + sessionID.getProtocolName() + ".");
    if (!session.getSessionPolicy().getAllowV2()) {
        logger.finest("Policy does not allow OTRv2, ignoring message.");
        return;
    }
    switch(this.getAuthenticationState()) {
        case AWAITING_REVEALSIG:
            // Use the received value of r to decrypt the value of gx
            // received
            // in the D-H Commit Message, and verify the hash therein.
            // Decrypt
            // the encrypted signature, and verify the signature and the
            // MACs.
            // If everything checks out:
            // * Reply with a Signature Message.
            // * Transition authstate to AUTHSTATE_NONE.
            // * Transition msgstate to MSGSTATE_ENCRYPTED.
            // * TODO If there is a recent stored message, encrypt it and
            // send
            // it as a Data Message.
            OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
            // Uses r to decrypt the value of gx sent earlier
            byte[] remoteDHPublicKeyDecrypted = otrCryptoEngine.aesDecrypt(m.revealedKey, null, this.getRemoteDHPublicKeyEncrypted());
            // Verifies that HASH(gx) matches the value sent earlier
            byte[] remoteDHPublicKeyHash = otrCryptoEngine.sha256Hash(remoteDHPublicKeyDecrypted);
            if (!Arrays.equals(remoteDHPublicKeyHash, this.getRemoteDHPublicKeyHash())) {
                logger.finest("Hashes don't match, ignoring message.");
                return;
            }
            // Verifies that Bob's gx is a legal value (2 <= gx <=
            // modulus-2)
            BigInteger remoteDHPublicKeyMpi;
            try {
                remoteDHPublicKeyMpi = SerializationUtils.readMpi(remoteDHPublicKeyDecrypted);
            } catch (IOException e) {
                throw new OtrException(e);
            }
            this.setRemoteDHPublicKey(otrCryptoEngine.getDHPublicKey(remoteDHPublicKeyMpi));
            // Verify received Data.
            if (!m.verify(this.getM2())) {
                logger.finest("Signature MACs are not equal, ignoring message.");
                return;
            }
            // Decrypt X.
            byte[] remoteXDecrypted = m.decrypt(this.getC());
            SignatureX remoteX;
            try {
                remoteX = SerializationUtils.toMysteriousX(remoteXDecrypted);
            } catch (IOException e) {
                throw new OtrException(e);
            }
            // Compute signature.
            PublicKey remoteLongTermPublicKey = remoteX.longTermPublicKey;
            SignatureM remoteM = new SignatureM(this.getRemoteDHPublicKey(), (DHPublicKey) this.getLocalDHKeyPair().getPublic(), remoteLongTermPublicKey, remoteX.dhKeyID);
            // Verify signature.
            byte[] signature;
            try {
                signature = otrCryptoEngine.sha256Hmac(SerializationUtils.toByteArray(remoteM), this.getM1());
            } catch (IOException e) {
                throw new OtrException(e);
            }
            if (!otrCryptoEngine.verify(signature, remoteLongTermPublicKey, remoteX.signature)) {
                session.showWarning("Bad revealed signature");
                logger.finest("Signature verification failed.");
                return;
            }
            logger.finest("Signature verification succeeded.");
            this.setAuthenticationState(AuthContext.NONE);
            this.setIsSecure(true);
            this.setRemoteLongTermPublicKey(remoteLongTermPublicKey);
            getSession().injectMessage(messageFactory.getSignatureMessage());
            break;
        default:
            logger.finest("Ignoring message.");
            break;
    }
}
Also used : SignatureM(net.java.otr4j.io.messages.SignatureM) OtrCryptoEngine(net.java.otr4j.crypto.OtrCryptoEngine) PublicKey(java.security.PublicKey) DHPublicKey(javax.crypto.interfaces.DHPublicKey) OtrCryptoEngineImpl(net.java.otr4j.crypto.OtrCryptoEngineImpl) SignatureX(net.java.otr4j.io.messages.SignatureX) BigInteger(java.math.BigInteger) IOException(java.io.IOException) OtrException(net.java.otr4j.OtrException)

Example 25 with DHPublicKey

use of javax.crypto.interfaces.DHPublicKey in project Zom-Android by zom.

the class AuthContextImpl method handleSignatureMessage.

private void handleSignatureMessage(SignatureMessage m) throws OtrException {
    Session session = getSession();
    SessionID sessionID = session.getSessionID();
    logger.finest(sessionID.getLocalUserId() + " received a signature message from " + sessionID.getRemoteUserId() + " throught " + sessionID.getProtocolName() + ".");
    if (!session.getSessionPolicy().getAllowV2()) {
        logger.finest("Policy does not allow OTRv2, ignoring message.");
        return;
    }
    switch(this.getAuthenticationState()) {
        case AWAITING_SIG:
            // Verify MAC.
            if (!m.verify(this.getM2p())) {
                logger.finest("Signature MACs are not equal, ignoring message.");
                return;
            }
            // Decrypt X.
            byte[] remoteXDecrypted = m.decrypt(this.getCp());
            SignatureX remoteX;
            try {
                remoteX = SerializationUtils.toMysteriousX(remoteXDecrypted);
            } catch (IOException e) {
                throw new OtrException(e);
            }
            // Compute signature.
            PublicKey remoteLongTermPublicKey = remoteX.longTermPublicKey;
            SignatureM remoteM = new SignatureM(this.getRemoteDHPublicKey(), (DHPublicKey) this.getLocalDHKeyPair().getPublic(), remoteLongTermPublicKey, remoteX.dhKeyID);
            OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
            // Verify signature.
            byte[] signature;
            try {
                signature = otrCryptoEngine.sha256Hmac(SerializationUtils.toByteArray(remoteM), this.getM1p());
            } catch (IOException e) {
                throw new OtrException(e);
            }
            if (!otrCryptoEngine.verify(signature, remoteLongTermPublicKey, remoteX.signature)) {
                session.showWarning("Bad signature");
                logger.finest("Signature verification failed.");
                return;
            }
            this.setIsSecure(true);
            this.setRemoteLongTermPublicKey(remoteLongTermPublicKey);
            break;
        default:
            logger.finest("We were not expecting a signature, ignoring message.");
            return;
    }
}
Also used : SignatureM(net.java.otr4j.io.messages.SignatureM) OtrCryptoEngine(net.java.otr4j.crypto.OtrCryptoEngine) PublicKey(java.security.PublicKey) DHPublicKey(javax.crypto.interfaces.DHPublicKey) SignatureX(net.java.otr4j.io.messages.SignatureX) OtrCryptoEngineImpl(net.java.otr4j.crypto.OtrCryptoEngineImpl) IOException(java.io.IOException) OtrException(net.java.otr4j.OtrException)

Aggregations

DHPublicKey (javax.crypto.interfaces.DHPublicKey)28 KeyPair (java.security.KeyPair)16 IOException (java.io.IOException)14 BigInteger (java.math.BigInteger)11 KeyPairGenerator (java.security.KeyPairGenerator)11 KeyFactory (java.security.KeyFactory)10 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)9 PublicKey (java.security.PublicKey)9 DHParameterSpec (javax.crypto.spec.DHParameterSpec)8 DHPublicKeySpec (javax.crypto.spec.DHPublicKeySpec)8 CertificateException (java.security.cert.CertificateException)6 DHPrivateKey (javax.crypto.interfaces.DHPrivateKey)6 Cipher (javax.crypto.Cipher)5 KeyAgreement (javax.crypto.KeyAgreement)5 OtrCryptoEngineImpl (net.java.otr4j.crypto.OtrCryptoEngineImpl)5 X509Certificate (java.security.cert.X509Certificate)4 RSAPublicKey (java.security.interfaces.RSAPublicKey)4 SSLHandshakeException (javax.net.ssl.SSLHandshakeException)4 X509ExtendedKeyManager (javax.net.ssl.X509ExtendedKeyManager)4 X509KeyManager (javax.net.ssl.X509KeyManager)4