Search in sources :

Example 6 with IdentityKey

use of org.whispersystems.libaxolotl.IdentityKey in project Conversations by siacs.

the class XmppAxolotlSession method processReceiving.

@Nullable
public byte[] processReceiving(AxolotlKey encryptedKey) throws CryptoFailedException {
    byte[] plaintext;
    FingerprintStatus status = getTrust();
    if (!status.isCompromised()) {
        try {
            CiphertextMessage ciphertextMessage;
            try {
                ciphertextMessage = new PreKeyWhisperMessage(encryptedKey.key);
                Optional<Integer> optionalPreKeyId = ((PreKeyWhisperMessage) ciphertextMessage).getPreKeyId();
                IdentityKey identityKey = ((PreKeyWhisperMessage) ciphertextMessage).getIdentityKey();
                if (!optionalPreKeyId.isPresent()) {
                    throw new CryptoFailedException("PreKeyWhisperMessage did not contain a PreKeyId");
                }
                preKeyId = optionalPreKeyId.get();
                if (this.identityKey != null && !this.identityKey.equals(identityKey)) {
                    throw new CryptoFailedException("Received PreKeyWhisperMessage but preexisting identity key changed.");
                }
                this.identityKey = identityKey;
            } catch (InvalidVersionException | InvalidMessageException e) {
                ciphertextMessage = new WhisperMessage(encryptedKey.key);
            }
            if (ciphertextMessage instanceof PreKeyWhisperMessage) {
                plaintext = cipher.decrypt((PreKeyWhisperMessage) ciphertextMessage);
            } else {
                plaintext = cipher.decrypt((WhisperMessage) ciphertextMessage);
            }
        } catch (InvalidKeyException | LegacyMessageException | InvalidMessageException | DuplicateMessageException | NoSessionException | InvalidKeyIdException | UntrustedIdentityException e) {
            if (!(e instanceof DuplicateMessageException)) {
                e.printStackTrace();
            }
            throw new CryptoFailedException("Error decrypting WhisperMessage " + e.getClass().getSimpleName() + ": " + e.getMessage());
        }
        if (!status.isActive()) {
            setTrust(status.toActive());
        }
    } else {
        throw new CryptoFailedException("not encrypting omemo message from fingerprint " + getFingerprint() + " because it was marked as compromised");
    }
    return plaintext;
}
Also used : InvalidMessageException(org.whispersystems.libaxolotl.InvalidMessageException) IdentityKey(org.whispersystems.libaxolotl.IdentityKey) UntrustedIdentityException(org.whispersystems.libaxolotl.UntrustedIdentityException) PreKeyWhisperMessage(org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage) CiphertextMessage(org.whispersystems.libaxolotl.protocol.CiphertextMessage) InvalidVersionException(org.whispersystems.libaxolotl.InvalidVersionException) InvalidKeyException(org.whispersystems.libaxolotl.InvalidKeyException) NoSessionException(org.whispersystems.libaxolotl.NoSessionException) DuplicateMessageException(org.whispersystems.libaxolotl.DuplicateMessageException) InvalidKeyIdException(org.whispersystems.libaxolotl.InvalidKeyIdException) WhisperMessage(org.whispersystems.libaxolotl.protocol.WhisperMessage) PreKeyWhisperMessage(org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage) LegacyMessageException(org.whispersystems.libaxolotl.LegacyMessageException) Nullable(android.support.annotation.Nullable)

Example 7 with IdentityKey

use of org.whispersystems.libaxolotl.IdentityKey in project Conversations by siacs.

the class AxolotlService method publishDeviceVerificationAndBundle.

public void publishDeviceVerificationAndBundle(final SignedPreKeyRecord signedPreKeyRecord, final Set<PreKeyRecord> preKeyRecords, final boolean announceAfter, final boolean wipe) {
    try {
        IdentityKey axolotlPublicKey = axolotlStore.getIdentityKeyPair().getPublicKey();
        PrivateKey x509PrivateKey = KeyChain.getPrivateKey(mXmppConnectionService, account.getPrivateKeyAlias());
        X509Certificate[] chain = KeyChain.getCertificateChain(mXmppConnectionService, account.getPrivateKeyAlias());
        Signature verifier = Signature.getInstance("sha256WithRSA");
        verifier.initSign(x509PrivateKey, mXmppConnectionService.getRNG());
        verifier.update(axolotlPublicKey.serialize());
        byte[] signature = verifier.sign();
        IqPacket packet = mXmppConnectionService.getIqGenerator().publishVerification(signature, chain, getOwnDeviceId());
        Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ": publish verification for device " + getOwnDeviceId());
        mXmppConnectionService.sendIqPacket(account, packet, new OnIqPacketReceived() {

            @Override
            public void onIqPacketReceived(final Account account, IqPacket packet) {
                String node = AxolotlService.PEP_VERIFICATION + ":" + getOwnDeviceId();
                Bundle pubsubOptions = new Bundle();
                pubsubOptions.putString("pubsub#access_model", "open");
                mXmppConnectionService.pushNodeConfiguration(account, account.getJid().toBareJid(), node, pubsubOptions, new XmppConnectionService.OnConfigurationPushed() {

                    @Override
                    public void onPushSucceeded() {
                        Log.d(Config.LOGTAG, getLogprefix(account) + "configured verification node to be world readable");
                        publishDeviceBundle(signedPreKeyRecord, preKeyRecords, announceAfter, wipe);
                    }

                    @Override
                    public void onPushFailed() {
                        Log.d(Config.LOGTAG, getLogprefix(account) + "unable to set access model on verification node");
                        publishDeviceBundle(signedPreKeyRecord, preKeyRecords, announceAfter, wipe);
                    }
                });
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : Account(eu.siacs.conversations.entities.Account) IdentityKey(org.whispersystems.libaxolotl.IdentityKey) PrivateKey(java.security.PrivateKey) OnIqPacketReceived(eu.siacs.conversations.xmpp.OnIqPacketReceived) Bundle(android.os.Bundle) PreKeyBundle(org.whispersystems.libaxolotl.state.PreKeyBundle) X509Certificate(java.security.cert.X509Certificate) InvalidJidException(eu.siacs.conversations.xmpp.jid.InvalidJidException) InvalidKeyException(org.whispersystems.libaxolotl.InvalidKeyException) InvalidKeyIdException(org.whispersystems.libaxolotl.InvalidKeyIdException) UntrustedIdentityException(org.whispersystems.libaxolotl.UntrustedIdentityException) IqPacket(eu.siacs.conversations.xmpp.stanzas.IqPacket) Signature(java.security.Signature)

Example 8 with IdentityKey

use of org.whispersystems.libaxolotl.IdentityKey in project Conversations by siacs.

the class AxolotlService method findDevicesWithoutSession.

public Set<AxolotlAddress> findDevicesWithoutSession(final Conversation conversation) {
    Set<AxolotlAddress> addresses = new HashSet<>();
    for (Jid jid : getCryptoTargets(conversation)) {
        Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Finding devices without session for " + jid);
        if (deviceIds.get(jid) != null) {
            for (Integer foreignId : this.deviceIds.get(jid)) {
                AxolotlAddress address = new AxolotlAddress(jid.toPreppedString(), foreignId);
                if (sessions.get(address) == null) {
                    IdentityKey identityKey = axolotlStore.loadSession(address).getSessionState().getRemoteIdentityKey();
                    if (identityKey != null) {
                        Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Already have session for " + address.toString() + ", adding to cache...");
                        XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address, identityKey);
                        sessions.put(address, session);
                    } else {
                        Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Found device " + jid + ":" + foreignId);
                        if (fetchStatusMap.get(address) != FetchStatus.ERROR) {
                            addresses.add(address);
                        } else {
                            Log.d(Config.LOGTAG, getLogprefix(account) + "skipping over " + address + " because it's broken");
                        }
                    }
                }
            }
        } else {
            Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Have no target devices in PEP!");
        }
    }
    if (deviceIds.get(account.getJid().toBareJid()) != null) {
        for (Integer ownId : this.deviceIds.get(account.getJid().toBareJid())) {
            AxolotlAddress address = new AxolotlAddress(account.getJid().toBareJid().toPreppedString(), ownId);
            if (sessions.get(address) == null) {
                IdentityKey identityKey = axolotlStore.loadSession(address).getSessionState().getRemoteIdentityKey();
                if (identityKey != null) {
                    Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Already have session for " + address.toString() + ", adding to cache...");
                    XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address, identityKey);
                    sessions.put(address, session);
                } else {
                    Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Found device " + account.getJid().toBareJid() + ":" + ownId);
                    if (fetchStatusMap.get(address) != FetchStatus.ERROR) {
                        addresses.add(address);
                    } else {
                        Log.d(Config.LOGTAG, getLogprefix(account) + "skipping over " + address + " because it's broken");
                    }
                }
            }
        }
    }
    return addresses;
}
Also used : IdentityKey(org.whispersystems.libaxolotl.IdentityKey) Jid(eu.siacs.conversations.xmpp.jid.Jid) AxolotlAddress(org.whispersystems.libaxolotl.AxolotlAddress) HashSet(java.util.HashSet)

Example 9 with IdentityKey

use of org.whispersystems.libaxolotl.IdentityKey in project Conversations by siacs.

the class TrustKeysActivity method reloadFingerprints.

private boolean reloadFingerprints() {
    List<Jid> acceptedTargets = mConversation == null ? new ArrayList<Jid>() : mConversation.getAcceptedCryptoTargets();
    ownKeysToTrust.clear();
    AxolotlService service = this.mAccount.getAxolotlService();
    Set<IdentityKey> ownKeysSet = service.getKeysWithTrust(FingerprintStatus.createActiveUndecided());
    for (final IdentityKey identityKey : ownKeysSet) {
        if (!ownKeysToTrust.containsKey(identityKey)) {
            ownKeysToTrust.put(identityKey.getFingerprint().replaceAll("\\s", ""), false);
        }
    }
    synchronized (this.foreignKeysToTrust) {
        foreignKeysToTrust.clear();
        for (Jid jid : contactJids) {
            Set<IdentityKey> foreignKeysSet = service.getKeysWithTrust(FingerprintStatus.createActiveUndecided(), jid);
            if (hasNoOtherTrustedKeys(jid) && ownKeysSet.size() == 0) {
                foreignKeysSet.addAll(service.getKeysWithTrust(FingerprintStatus.createActive(false), jid));
            }
            Map<String, Boolean> foreignFingerprints = new HashMap<>();
            for (final IdentityKey identityKey : foreignKeysSet) {
                if (!foreignFingerprints.containsKey(identityKey)) {
                    foreignFingerprints.put(identityKey.getFingerprint().replaceAll("\\s", ""), false);
                }
            }
            if (foreignFingerprints.size() > 0 || !acceptedTargets.contains(jid)) {
                foreignKeysToTrust.put(jid, foreignFingerprints);
            }
        }
    }
    return ownKeysSet.size() + foreignKeysToTrust.size() > 0;
}
Also used : AxolotlService(eu.siacs.conversations.crypto.axolotl.AxolotlService) IdentityKey(org.whispersystems.libaxolotl.IdentityKey) Jid(eu.siacs.conversations.xmpp.jid.Jid) HashMap(java.util.HashMap)

Aggregations

IdentityKey (org.whispersystems.libaxolotl.IdentityKey)9 InvalidKeyException (org.whispersystems.libaxolotl.InvalidKeyException)4 Jid (eu.siacs.conversations.xmpp.jid.Jid)3 InvalidKeyIdException (org.whispersystems.libaxolotl.InvalidKeyIdException)3 UntrustedIdentityException (org.whispersystems.libaxolotl.UntrustedIdentityException)3 PreKeyBundle (org.whispersystems.libaxolotl.state.PreKeyBundle)3 Bundle (android.os.Bundle)2 Account (eu.siacs.conversations.entities.Account)2 Element (eu.siacs.conversations.xml.Element)2 OnIqPacketReceived (eu.siacs.conversations.xmpp.OnIqPacketReceived)2 InvalidJidException (eu.siacs.conversations.xmpp.jid.InvalidJidException)2 IqPacket (eu.siacs.conversations.xmpp.stanzas.IqPacket)2 Signature (java.security.Signature)2 X509Certificate (java.security.cert.X509Certificate)2 HashSet (java.util.HashSet)2 AxolotlAddress (org.whispersystems.libaxolotl.AxolotlAddress)2 IdentityKeyPair (org.whispersystems.libaxolotl.IdentityKeyPair)2 Cursor (android.database.Cursor)1 Nullable (android.support.annotation.Nullable)1 Pair (android.util.Pair)1